aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngenic <ftp.ingenic.cn/3sw/01linux/02kernel/linux-2.6.31>2020-10-30 01:31:33 +0100
committerLubomir Rintel <lkundrak@v3.sk>2020-10-30 01:46:26 +0100
commit8155bc8f16a1f2e61f51a5bdc0918109383de34d (patch)
tree66ddebcfc3d71fba22a7291ddd21b1eb2b1faf2c
parent18dcc300098ed8517d46b3e4b01f79d5b1bb2acc (diff)
downloadlinux-jz47xx-8155bc8f16a1f2e61f51a5bdc0918109383de34d.tar.gz
linux-2.6.31.3-20100724.patch.bz2
* Fixed start/stop UHC routines on JZ4740. * Added gadget controller number for JZ4750D. * Remarked old power leagcy API. * Added support of i2c bus driver for jz4750/jz4750d. * Removed pcm_natvie.c. * Fixed a bug when a block cache is allocated for every partition which works over mtdblock-jz, and disable nand suspend/resume. * Fixed an IO coherent bug in __do_fault path. * Shutdown the board by poweroff command and remove poweroff interface in sysfs. * Enable JZ47XX RTC driver and modified for Mplayer running on JZSOC. * Correct GPIO_USB_DETE -> GPIOC15 in apus. * New simple I2C driver & Userspace driver & examples for JZ4750. * Fixed NAND LB Cache enable/flush/control bugs. * Corrected 2 bugs when 512-byte pagesize nand using yaffs1. * Fixed wake up problems in userspace sleep()/nanosleep(). * Added MEMPAGEWRITE ioctl to support nandwrite_mlc utils. * Fixed kernel bug. Do not call tty_flip_buffer_push() in tasklet context, We use workqueue instead. * Fixed MTD partition size calculation error. * Added IPU MM support option. * Defaut input_touchscreen is y, deleted JZ_TPANEL under char/jzchar. * Fixed missing spin_unlock_irq when rtc is busy. * Added the Ingenic NFTL source code. * revert yaffs_ecc.c * Clean Files: poweroff.c: Poweroff routines should be handled by APP. sensor.c: An simple i2c interface used to control sensor. Replaced by Simple I2C Driver. udc_hotplug.c: Replaced by drivers/usb/gadget/udc_hotplug.c cim.c cim.h: Replaced by drivers/media/jz47xx_cim.* * add REG_MSC_RDTO(MSC_ID) = 0xffff * Add new version of JZ475X LCD Driver * Support JZ4755 * All DACs should be powered on when using SVIDEO * DMA Descriptor should be writebacked and invailded. * Add enable_delay_in_ms. * Remove PM IRQ routines. * Add GPIO PM Key Driver. * Add framebuffer common routines. * Add RGB->YUV Routines. * Add CPUFREQ options. * Add MUSB OTG Driver. * Add OTG ID PIN Routines. * add support for JZ4760. * added 4760 boot from MMC/SD support. * add jz_pm_hibernate * added Write enable patter register * change apus_defconfig to support SDIO by default * Modify Dynamic change i2c speed support. * wake up msc driver when the card is removed * Use 800x480 LCD config for lepus board
-rw-r--r--arch/mips/Kconfig74
-rw-r--r--arch/mips/Makefile16
-rw-r--r--arch/mips/configs/apus_defconfig5
-rw-r--r--arch/mips/configs/cygnus_defconfig1254
-rw-r--r--arch/mips/configs/f4760_defconfig907
-rw-r--r--arch/mips/configs/f4810_defconfig955
-rw-r--r--arch/mips/configs/lepus_defconfig1437
-rw-r--r--arch/mips/include/asm/bootinfo.h2
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_controller.h42
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_dma.h39
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_gpio.h33
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_host.h104
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_msc.h33
-rw-r--r--arch/mips/include/asm/jzmmc/jz_mmc_platform_data.h56
-rw-r--r--arch/mips/include/asm/jzsoc.h20
-rw-r--r--arch/mips/include/asm/mach-jz4750/ops.h29
-rw-r--r--arch/mips/include/asm/mach-jz4750/regs.h334
-rw-r--r--arch/mips/include/asm/mach-jz4750d/i2c.h70
-rw-r--r--arch/mips/include/asm/mach-jz4750d/jz4750d.h1
-rw-r--r--arch/mips/include/asm/mach-jz4750d/regs.h333
-rw-r--r--arch/mips/include/asm/mach-jz4760/board-altair.h216
-rw-r--r--arch/mips/include/asm/mach-jz4760/board-cygnus.h193
-rw-r--r--arch/mips/include/asm/mach-jz4760/board-f4760.h93
-rw-r--r--arch/mips/include/asm/mach-jz4760/board-lepus.h267
-rw-r--r--arch/mips/include/asm/mach-jz4760/clock.h268
-rw-r--r--arch/mips/include/asm/mach-jz4760/dma.h329
-rw-r--r--arch/mips/include/asm/mach-jz4760/irq.h21
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760.h93
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760aic.h817
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760bch.h207
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760bdma.h297
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760cim.h350
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760cpm.h646
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760ddrc.h345
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760dmac.h373
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760emc.h213
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760gpio.h826
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760i2c.h217
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760intc.h114
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760ipu.h328
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760lcdc.h1074
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760mc.h128
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760mdma.h209
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760me.h93
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760misc.h91
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760msc.h325
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760nemc.h58
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760ost.h64
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760otg.h135
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760otp.h97
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760owi.h82
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760pcm.h218
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760rtc.h172
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760sadc.h182
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760scc.h191
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760ssi.h350
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760tcu.h305
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760tssi.h105
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760tve.h396
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760uart.h280
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760wdt.h70
-rw-r--r--arch/mips/include/asm/mach-jz4760/jz4760xxx.h18
-rw-r--r--arch/mips/include/asm/mach-jz4760/misc.h44
-rw-r--r--arch/mips/include/asm/mach-jz4760/regs.h42
-rw-r--r--arch/mips/include/asm/mach-jz4760/serial.h30
-rw-r--r--arch/mips/include/asm/mach-jz4760/war.h26
-rw-r--r--arch/mips/include/asm/mach-jz4810/board-f4810.h93
-rw-r--r--arch/mips/include/asm/mach-jz4810/clock.h267
-rw-r--r--arch/mips/include/asm/mach-jz4810/dma.h329
-rw-r--r--arch/mips/include/asm/mach-jz4810/irq.h21
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810.h77
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810aic.h817
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810bch.h207
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810bdma.h297
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810cim.h351
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810cpm.h559
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810dbg.c30
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810ddrc.h345
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810dmac.h373
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810emc.h213
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810gpio.h1134
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810i2c.h217
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810intc.h112
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810ipu.h328
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810lcdc.h866
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810mc.h135
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810mdma.h209
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810me.h69
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810misc.h28
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810msc.h325
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810nemc.h58
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810otg.h135
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810otp.h97
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810owi.h120
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810pcm.h202
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810rtc.h141
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810sadc.h116
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810scc.h191
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810ssi.h350
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810tcu.h427
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810tssi.h225
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810tve.h396
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810uart.h293
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810wdt.h80
-rw-r--r--arch/mips/include/asm/mach-jz4810/jz4810xxx.h18
-rw-r--r--arch/mips/include/asm/mach-jz4810/misc.h44
-rw-r--r--arch/mips/include/asm/mach-jz4810/regs.h43
-rw-r--r--arch/mips/include/asm/mach-jz4810/serial.h30
-rw-r--r--arch/mips/include/asm/mach-jz4810/war.h26
-rw-r--r--arch/mips/jz4750/board-apus.c170
-rw-r--r--arch/mips/jz4750/i2c.c549
-rw-r--r--arch/mips/jz4750/platform.c96
-rw-r--r--arch/mips/jz4750/pm.c29
-rw-r--r--arch/mips/jz4750/time.c36
-rw-r--r--arch/mips/jz4750d/i2c.c661
-rw-r--r--arch/mips/jz4750d/pm.c36
-rw-r--r--arch/mips/jz4750d/time.c104
-rw-r--r--arch/mips/jz4760/Makefile29
-rw-r--r--arch/mips/jz4760/board-altair.c557
-rw-r--r--arch/mips/jz4760/board-cygnus.c451
-rw-r--r--arch/mips/jz4760/board-f4760.c352
-rw-r--r--arch/mips/jz4760/board-lepus.c466
-rw-r--r--arch/mips/jz4760/cpm.c517
-rw-r--r--arch/mips/jz4760/cpufreq.c598
-rw-r--r--arch/mips/jz4760/dma.c852
-rw-r--r--arch/mips/jz4760/fpu.c143
-rw-r--r--arch/mips/jz4760/gpiolib.c208
-rw-r--r--arch/mips/jz4760/i2c.c273
-rw-r--r--arch/mips/jz4760/i2c_intr_debug.c254
-rw-r--r--arch/mips/jz4760/i2c_pio_debug.c255
-rw-r--r--arch/mips/jz4760/irq.c484
-rw-r--r--arch/mips/jz4760/platform.c332
-rw-r--r--arch/mips/jz4760/pm.c335
-rw-r--r--arch/mips/jz4760/proc.c955
-rw-r--r--arch/mips/jz4760/prom.c198
-rw-r--r--arch/mips/jz4760/reset.c46
-rw-r--r--arch/mips/jz4760/setup.c221
-rw-r--r--arch/mips/jz4760/sleep.S330
-rw-r--r--arch/mips/jz4760/time.c218
-rw-r--r--arch/mips/jz4810/Makefile25
-rw-r--r--arch/mips/jz4810/board-f4810.c90
-rw-r--r--arch/mips/jz4810/cpufreq.c598
-rw-r--r--arch/mips/jz4810/dma.c848
-rw-r--r--arch/mips/jz4810/fpu.c143
-rw-r--r--arch/mips/jz4810/gpiolib.c205
-rw-r--r--arch/mips/jz4810/i2c.c255
-rw-r--r--arch/mips/jz4810/i2c_intr_debug.c254
-rw-r--r--arch/mips/jz4810/irq.c465
-rw-r--r--arch/mips/jz4810/platform.c364
-rw-r--r--arch/mips/jz4810/pm.c518
-rw-r--r--arch/mips/jz4810/proc.c916
-rw-r--r--arch/mips/jz4810/prom.c198
-rw-r--r--arch/mips/jz4810/reset.c46
-rw-r--r--arch/mips/jz4810/setup.c326
-rw-r--r--arch/mips/jz4810/sleep.S311
-rw-r--r--arch/mips/jz4810/time.c219
-rw-r--r--arch/mips/kernel/cpu-probe.c22
-rw-r--r--arch/mips/kernel/irq.c7
-rw-r--r--arch/mips/mm/c-r4k.c4
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/jzchar/Kconfig28
-rw-r--r--drivers/char/jzchar/Makefile15
-rw-r--r--drivers/char/jzchar/cim.c366
-rw-r--r--drivers/char/jzchar/cim.h36
-rw-r--r--drivers/char/jzchar/i_gpio_pm_key.c307
-rw-r--r--drivers/char/jzchar/poweroff.c410
-rw-r--r--drivers/char/jzchar/sensor.c182
-rw-r--r--drivers/char/jzchar/udc_hotplug.c451
-rw-r--r--drivers/char/rtc-jz4760.c470
-rw-r--r--drivers/i2c/busses/Kconfig14
-rw-r--r--drivers/i2c/busses/Makefile2
-rw-r--r--drivers/i2c/busses/i2c-jz4760.c634
-rw-r--r--drivers/i2c/busses/i2c-jz4760.h20
-rw-r--r--drivers/i2c/i2c-dev.c5
-rw-r--r--drivers/input/keyboard/Kconfig15
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/jz_gpio_keypad.c399
-rw-r--r--drivers/input/touchscreen/Kconfig10
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/jz4760_ts.c816
-rw-r--r--drivers/misc/Kconfig32
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/i2c_simulate.c508
-rw-r--r--drivers/misc/jz_cim/Makefile18
-rw-r--r--drivers/misc/jz_cim/camera_source/cm3511/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.c570
-rw-r--r--drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.h26
-rw-r--r--drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.c595
-rw-r--r--drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.h32
-rw-r--r--drivers/misc/jz_cim/camera_source/fake/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/fake/fake_camera.c312
-rw-r--r--drivers/misc/jz_cim/camera_source/fake/fake_camera.h62
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/camera_ifc.h449
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/data.h2887
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/isp.c5046
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/isp.h3373
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/isp_camera.c464
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/isp_camera.h59
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/readme6
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/tran_databin0 -> 9410 bytes
-rw-r--r--drivers/misc/jz_cim/camera_source/isp/tran_data.code22
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2640/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2640/camera.c73
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2640/camera.h56
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.c383
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.h37
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.c718
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.h14
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.c185
-rw-r--r--drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.h32
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.c617
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.h56
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.c198
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.h50
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.c645
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.h16
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.c263
-rw-r--r--drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.h32
-rw-r--r--drivers/misc/jz_cim/camera_source/ov7690/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.c497
-rw-r--r--drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.h56
-rw-r--r--drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.c334
-rw-r--r--drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.h43
-rw-r--r--drivers/misc/jz_cim/camera_source/ov9650/Makefile3
-rw-r--r--drivers/misc/jz_cim/camera_source/ov9650/camera.c72
-rw-r--r--drivers/misc/jz_cim/camera_source/ov9650/camera.h55
-rw-r--r--drivers/misc/jz_cim/jz_cim_board_altair.c17
-rw-r--r--drivers/misc/jz_cim/jz_cim_board_apus.c16
-rw-r--r--drivers/misc/jz_cim/jz_cim_board_aquila.c26
-rw-r--r--drivers/misc/jz_cim/jz_cim_board_lepus.c17
-rw-r--r--drivers/misc/jz_cim/jz_cim_board_pt701.c17
-rw-r--r--drivers/misc/jz_cim/jz_cim_core.c1601
-rw-r--r--drivers/misc/jz_cim/jz_cim_core.h346
-rw-r--r--drivers/misc/jz_cim/jz_sensor.c180
-rw-r--r--drivers/misc/jz_cim/jz_sensor.h23
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/core/sd.c4
-rw-r--r--drivers/mmc/host/Kconfig146
-rw-r--r--drivers/mmc/host/Makefile4
-rw-r--r--drivers/mmc/host/jz4750_mmc.c1037
-rw-r--r--drivers/mmc/host/jz4750_mmc.h88
-rw-r--r--drivers/mmc/host/jzmmc/Makefile6
-rw-r--r--drivers/mmc/host/jzmmc/controller/Makefile6
-rw-r--r--drivers/mmc/host/jzmmc/controller/dma/Makefile6
-rw-r--r--drivers/mmc/host/jzmmc/controller/dma/jz_mmc_dma.c241
-rw-r--r--drivers/mmc/host/jzmmc/controller/gpio/Makefile6
-rw-r--r--drivers/mmc/host/jzmmc/controller/gpio/jz_mmc_gpio.c183
-rw-r--r--drivers/mmc/host/jzmmc/controller/jz_mmc_controller.c126
-rw-r--r--drivers/mmc/host/jzmmc/controller/msc/Makefile6
-rw-r--r--drivers/mmc/host/jzmmc/controller/msc/jz_mmc_msc.c836
-rw-r--r--drivers/mmc/host/jzmmc/jz_mmc_main.c385
-rw-r--r--drivers/mtd/nand/Kconfig65
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/jz4760_nand.c2001
-rw-r--r--drivers/net/Kconfig12
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/jz4760_eth.c1970
-rw-r--r--drivers/net/jz4760_eth.h1054
-rw-r--r--drivers/net/jzcs8900a.c32
-rw-r--r--drivers/usb/gadget/u_serial.h67
-rw-r--r--drivers/usb/host/ohci-jz.c34
-rw-r--r--drivers/usb/musb/Kconfig11
-rw-r--r--drivers/usb/musb/Makefile4
-rw-r--r--drivers/usb/musb/jz4760.c293
-rw-r--r--drivers/usb/musb/musb_core.c39
-rw-r--r--drivers/usb/musb/musb_core.h1
-rw-r--r--drivers/usb/musb/musb_dma.h6
-rw-r--r--drivers/usb/musb/musb_gadget.c80
-rw-r--r--drivers/usb/musb/musb_io.h2
-rw-r--r--drivers/usb/musb/musbhsdma.c75
-rw-r--r--drivers/usb/musb/vbus_hotplug.c782
-rw-r--r--drivers/video/Kconfig170
-rw-r--r--drivers/video/Makefile6
-rw-r--r--drivers/video/jz4750_lcd.c428
-rw-r--r--drivers/video/jz475x/Makefile1
-rw-r--r--drivers/video/jz475x/abi.h114
-rw-r--r--drivers/video/jz475x/common.c33
-rw-r--r--drivers/video/jz475x/config.h104
-rw-r--r--drivers/video/jz475x/core/desc.c346
-rw-r--r--drivers/video/jz475x/core/framebuffer.c356
-rw-r--r--drivers/video/jz475x/core/hw.c632
-rw-r--r--drivers/video/jz475x/core/ot.c167
-rw-r--r--drivers/video/jz475x/core/win.c179
-rw-r--r--drivers/video/jz475x/drv/ctrl-drv.c122
-rw-r--r--drivers/video/jz475x/drv/fb-drv.c303
-rw-r--r--drivers/video/jz475x/jz-fb.c305
-rw-r--r--drivers/video/jz475x/jz-fb.h237
-rw-r--r--drivers/video/jz475x/output/config.c75
-rw-r--r--drivers/video/jz475x/output/control.c100
-rw-r--r--drivers/video/jz475x/output/lcd/auo-a043fl01v2.c169
-rw-r--r--drivers/video/jz475x/output/lcd/lcd-control.c73
-rw-r--r--drivers/video/jz475x/output/lcd/lcd-output.c193
-rw-r--r--drivers/video/jz475x/output/output.c38
-rw-r--r--drivers/video/jz475x/output/tve/tve-common.c169
-rw-r--r--drivers/video/jz475x/output/tve/tve-control.c64
-rw-r--r--drivers/video/jz475x/output/tve/tve-hw.c272
-rw-r--r--drivers/video/jz475x/output/tve/tve-ntsc-output.c99
-rw-r--r--drivers/video/jz475x/output/tve/tve-pal-output.c98
-rw-r--r--drivers/video/jz475x/test/Makefile23
-rw-r--r--drivers/video/jz475x/test/fb_common.c88
-rw-r--r--drivers/video/jz475x/test/fb_fill.c76
-rw-r--r--drivers/video/jz475x/test/fb_h_colorbar.c138
-rw-r--r--drivers/video/jz475x/test/fb_info.c126
-rw-r--r--drivers/video/jz475x/test/fb_v_colorbar.c163
-rw-r--r--drivers/video/jz475x/test/lcd_ot_ctrl.c167
-rw-r--r--drivers/video/jz475x/test/tve_ntsc_ot_ctrl.c189
-rw-r--r--drivers/video/jz475x/test/tve_pal_ot_ctrl.c189
-rw-r--r--drivers/video/jz475x/userspace-config.h22
-rw-r--r--drivers/video/jz4760_epd.c3079
-rw-r--r--drivers/video/jz4760_epd.h252
-rw-r--r--drivers/video/jz4760_lcd.c2454
-rw-r--r--drivers/video/jz4760_lcd.h747
-rw-r--r--drivers/video/jz4760_tve.c104
-rw-r--r--drivers/video/jz4760_tve.h45
-rw-r--r--drivers/video/jzepd.c2155
-rw-r--r--fs/yaffs2/devextras.h4
-rw-r--r--include/linux/i2c-dev.h2
-rw-r--r--include/linux/i2c.h2
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/mtd/mtd-abi.h2
-rw-r--r--include/mtd/types.h100
-rw-r--r--sound/oss/Kconfig8
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/jz4760_dlv.c1009
-rw-r--r--sound/oss/jz4760_dlv.h126
-rw-r--r--sound/oss/jz4760_i2s.c3068
-rw-r--r--sound/oss/jz_audio.h136
-rw-r--r--sound/oss/jz_codec.h75
-rw-r--r--sound/oss/jz_i2s.c93
-rw-r--r--sound/oss/jz_i2s_dbg.h135
-rw-r--r--sound/oss/jzdlv.c25
336 files changed, 93570 insertions, 3760 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 645498ecfc6..6c25c366342 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -112,6 +112,53 @@ config JZ4750L_F4750L
select SOC_JZ4750L
select JZ_FPGA
+config JZ4760_F4760
+ bool "Ingenic JZ4760 FPGA board"
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SOC_JZ4760
+ select JZ_FPGA
+
+config JZ4760_CYGNUS
+ bool "Ingenic JZ4760 CYGNUS board"
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SOC_JZ4760
+
+config JZ4760_ALTAIR
+ bool "Ingenic JZ4760 ALTAIR board"
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SOC_JZ4760
+
+config JZ4760_LEPUS
+ bool "Ingenic JZ4760 LEPUS board"
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SOC_JZ4760
+
+config JZ4810_F4810
+ bool "Ingenic JZ4810 FPGA board"
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SOC_JZ4810
+ select JZ_FPGA
+
+
config MACH_ALCHEMY
bool "Alchemy processor based machines"
@@ -796,6 +843,14 @@ config SOC_JZ4750L
bool
select JZSOC
+config SOC_JZ4760
+ bool
+ select JZSOC
+
+config SOC_JZ4810
+ bool
+ select JZSOC
+
config JZ_FPGA
bool
@@ -943,7 +998,7 @@ config EARLY_PRINTK
unless you want to debug such a crash.
config SYS_HAS_EARLY_PRINTK
- bool
+ bool "early printk"
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
@@ -2308,6 +2363,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
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 5fdaa4f9289..5c7183d25ac 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -212,6 +212,22 @@ cflags-$(CONFIG_SOC_JZ4750L) += -I$(srctree)/arch/mips/include/asm/mach-jz4750l
load-$(CONFIG_SOC_JZ4750L) += 0xffffffff80010000
#
+# Commond Ingenic JZ4760 series
+#
+
+core-$(CONFIG_SOC_JZ4760) += arch/mips/jz4760/
+cflags-$(CONFIG_SOC_JZ4760) += -I$(srctree)/arch/mips/include/asm/mach-jz4760
+load-$(CONFIG_SOC_JZ4760) += 0xffffffff80010000
+
+#
+# Commond Ingenic JZ4810 series
+#
+
+core-$(CONFIG_SOC_JZ4810) += arch/mips/jz4810/
+cflags-$(CONFIG_SOC_JZ4810) += -I$(srctree)/arch/mips/include/asm/mach-jz4810
+load-$(CONFIG_SOC_JZ4810) += 0xffffffff80010000
+
+#
# Texas Instruments AR7
#
core-$(CONFIG_AR7) += arch/mips/ar7/
diff --git a/arch/mips/configs/apus_defconfig b/arch/mips/configs/apus_defconfig
index 4afc450ac0b..0cdeb1ce732 100644
--- a/arch/mips/configs/apus_defconfig
+++ b/arch/mips/configs/apus_defconfig
@@ -1049,10 +1049,11 @@ CONFIG_MMC_BLOCK_BOUNCE=y
#
# MMC/SD/SDIO Host Controller Drivers
#
-CONFIG_MSC0_JZ4750=y
+CONFIG_JZ_MSC0=y
# CONFIG_JZ4750_MSC0_BUS_1 is not set
-CONFIG_JZ4750_MSC0_BUS_4=y
+CONFIG_JZ_MSC0_BUS_4=y
# CONFIG_JZ4750_MSC0_BUS_8 is not set
+CONFIG_JZ_MSC0_SDIO_SUPPORT=y
# CONFIG_MSC1_JZ4750 is not set
# CONFIG_JZ4750_BOOT_FROM_MSC0 is not set
# CONFIG_MMC_SDHCI is not set
diff --git a/arch/mips/configs/cygnus_defconfig b/arch/mips/configs/cygnus_defconfig
new file mode 100644
index 00000000000..7ca7993207c
--- /dev/null
+++ b/arch/mips/configs/cygnus_defconfig
@@ -0,0 +1,1254 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31.3
+# Wed May 19 11:25:42 2010
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_JZ4730_PMP is not set
+# CONFIG_JZ4740_PAVO is not set
+# CONFIG_JZ4740_LEO is not set
+# CONFIG_JZ4740_LYRA is not set
+# CONFIG_JZ4725_DIPPER is not set
+# CONFIG_JZ4720_VIRGO is not set
+# CONFIG_JZ4750_FUWA is not set
+# CONFIG_JZ4750D_FUWA1 is not set
+# CONFIG_JZ4750_APUS is not set
+# CONFIG_JZ4750D_CETUS is not set
+# CONFIG_JZ4750L_F4750L is not set
+# CONFIG_JZ4760_F4760 is not set
+CONFIG_JZ4760_CYGNUS=y
+# CONFIG_JZ4760_ALTAIR is not set
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# 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_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_SOC_JZ4760=y
+CONFIG_JZSOC=y
+CONFIG_JZRISC=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+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_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX 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_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ_JZ is not set
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_JZ4760=y
+# CONFIG_MTD_NAND_CS2 is not set
+# CONFIG_MTD_NAND_CS3 is not set
+# CONFIG_MTD_NAND_CS4 is not set
+CONFIG_MTD_NAND_MULTI_PLANE=y
+CONFIG_MTD_NAND_BUS_WIDTH_8=y
+# CONFIG_MTD_NAND_BUS_WIDTH_16 is not set
+# CONFIG_MTD_HW_HM_ECC is not set
+# CONFIG_MTD_SW_HM_ECC is not set
+# CONFIG_MTD_HW_RS_ECC is not set
+CONFIG_MTD_HW_BCH_ECC=y
+# CONFIG_MTD_HW_BCH_4BIT is not set
+CONFIG_MTD_HW_BCH_8BIT=y
+# CONFIG_MTD_HW_BCH_12BIT is not set
+# CONFIG_MTD_HW_BCH_16BIT is not set
+# CONFIG_MTD_HW_BCH_20BIT is not set
+# CONFIG_MTD_HW_BCH_24BIT is not set
+# CONFIG_MTD_NAND_DMA is not set
+# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set
+# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set
+CONFIG_MTD_OOB_COPIES=3
+CONFIG_MTD_BADBLOCK_FLAG_PAGE=127
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_JZCS8900=y
+# CONFIG_JZ4760_ETH is not set
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC_PCF8563 is not set
+CONFIG_RTC_JZ=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_JZSOC is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# Ingenic OTG USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_JZ4740 is not set
+# CONFIG_USB_GADGET_JZ4750 is not set
+# CONFIG_USB_GADGET_JZ4750D is not set
+# CONFIG_USB_GADGET_JZ4750L is not set
+# CONFIG_USB_GADGET_JZ4730 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X 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_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_JZ_UDC_HOTPLUG is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Yaffs2 Filesystems
+#
+# CONFIG_YAFFS_FS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/f4760_defconfig b/arch/mips/configs/f4760_defconfig
new file mode 100644
index 00000000000..a0bca5c9e92
--- /dev/null
+++ b/arch/mips/configs/f4760_defconfig
@@ -0,0 +1,907 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27
+# Wed Dec 23 11:23:16 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_JZ4730_PMP is not set
+# CONFIG_JZ4740_PAVO is not set
+# CONFIG_JZ4740_LEO is not set
+# CONFIG_JZ4740_LYRA is not set
+# CONFIG_JZ4725_DIPPER is not set
+# CONFIG_JZ4720_VIRGO is not set
+# CONFIG_JZ4750_FUWA is not set
+# CONFIG_JZ4750_APUS is not set
+# CONFIG_JZ4750_AQUILA is not set
+# CONFIG_JZ4750D_CETUS is not set
+CONFIG_JZ4760_F4760=y
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# 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_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+CONFIG_SOC_JZ4760=y
+CONFIG_JZ_FPGA=y
+CONFIG_JZSOC=y
+CONFIG_JZRISC=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+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_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_HIGHMEM is not set
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_ASHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ_JZ is not set
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_JZ_ETH is not set
+CONFIG_JZ4760_ETH=y
+# CONFIG_AX88796 is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_JZ_GPIO is not set
+# CONFIG_KEYBOARD_JZ is not set
+# CONFIG_KEYBOARD_JZ_5x5 is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_JZ is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_INGENIC is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SND is not set
+CONFIG_SOUND_PRIME=y
+CONFIG_OSS_OBSOLETE=y
+# CONFIG_SOUND_JZ_AC97 is not set
+CONFIG_SOUND_JZ_I2S=y
+# CONFIG_SOUND_JZ_SPDIF is not set
+# CONFIG_I2S_AK4642EN is not set
+# CONFIG_I2S_ICODEC is not set
+# CONFIG_I2S_DLV is not set
+CONFIG_I2S_DLV_4760=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_SWITCH is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/f4810_defconfig b/arch/mips/configs/f4810_defconfig
new file mode 100644
index 00000000000..8f83253bc76
--- /dev/null
+++ b/arch/mips/configs/f4810_defconfig
@@ -0,0 +1,955 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31.3
+# Sat Jun 19 16:47:21 2010
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_JZ4730_PMP is not set
+# CONFIG_JZ4740_PAVO is not set
+# CONFIG_JZ4740_LEO is not set
+# CONFIG_JZ4740_LYRA is not set
+# CONFIG_JZ4725_DIPPER is not set
+# CONFIG_JZ4720_VIRGO is not set
+# CONFIG_JZ4750_FUWA is not set
+# CONFIG_JZ4750D_FUWA1 is not set
+# CONFIG_JZ4750_APUS is not set
+# CONFIG_JZ4750D_CETUS is not set
+# CONFIG_JZ4750L_F4750L is not set
+# CONFIG_JZ4760_F4760 is not set
+# CONFIG_JZ4760_CYGNUS is not set
+# CONFIG_JZ4760_ALTAIR is not set
+CONFIG_JZ4810_F4810=y
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# 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_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_SOC_JZ4810=y
+CONFIG_JZ_FPGA=y
+CONFIG_JZSOC=y
+CONFIG_JZRISC=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+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_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX 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_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ_JZ is not set
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_JZ_ETH is not set
+# CONFIG_JZCS8900 is not set
+CONFIG_JZ4760_ETH=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC_PCF8563 is not set
+# CONFIG_RTC_JZ is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Yaffs2 Filesystems
+#
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/lepus_defconfig b/arch/mips/configs/lepus_defconfig
new file mode 100644
index 00000000000..2e9ae9593a8
--- /dev/null
+++ b/arch/mips/configs/lepus_defconfig
@@ -0,0 +1,1437 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31.3
+# Wed Jul 21 15:48:25 2010
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_JZ4730_PMP is not set
+# CONFIG_JZ4740_PAVO is not set
+# CONFIG_JZ4740_LEO is not set
+# CONFIG_JZ4740_LYRA is not set
+# CONFIG_JZ4725_DIPPER is not set
+# CONFIG_JZ4720_VIRGO is not set
+# CONFIG_JZ4750_FUWA is not set
+# CONFIG_JZ4750D_FUWA1 is not set
+# CONFIG_JZ4750_APUS is not set
+# CONFIG_JZ4750D_CETUS is not set
+# CONFIG_JZ4750L_F4750L is not set
+# CONFIG_JZ4760_F4760 is not set
+# CONFIG_JZ4760_CYGNUS is not set
+# CONFIG_JZ4760_ALTAIR is not set
+CONFIG_JZ4760_LEPUS=y
+# CONFIG_JZ4810_F4810 is not set
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# 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_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_SOC_JZ4760=y
+CONFIG_JZSOC=y
+CONFIG_JZRISC=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_NO_IOPORT is not set
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+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_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX 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_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_128 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ_JZ is not set
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_JZ4760=y
+# CONFIG_MTD_NAND_CS2 is not set
+# CONFIG_MTD_NAND_CS3 is not set
+# CONFIG_MTD_NAND_CS4 is not set
+# CONFIG_MTD_NAND_MULTI_PLANE is not set
+CONFIG_MTD_NAND_BUS_WIDTH_8=y
+# CONFIG_MTD_NAND_BUS_WIDTH_16 is not set
+# CONFIG_MTD_HW_HM_ECC is not set
+# CONFIG_MTD_SW_HM_ECC is not set
+# CONFIG_MTD_HW_RS_ECC is not set
+CONFIG_MTD_HW_BCH_ECC=y
+# CONFIG_MTD_HW_BCH_4BIT is not set
+CONFIG_MTD_HW_BCH_8BIT=y
+# CONFIG_MTD_HW_BCH_12BIT is not set
+# CONFIG_MTD_HW_BCH_16BIT is not set
+# CONFIG_MTD_HW_BCH_20BIT is not set
+# CONFIG_MTD_HW_BCH_24BIT is not set
+CONFIG_MTD_NAND_DMA=y
+# CONFIG_MTD_NAND_DMABUF is not set
+# CONFIG_ALLOCATE_MTDBLOCK_JZ_EARLY is not set
+# CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE is not set
+CONFIG_MTD_OOB_COPIES=3
+CONFIG_MTD_BADBLOCK_FLAG_PAGE=127
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_JZCS8900=y
+# CONFIG_JZ4760_ETH is not set
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC_PCF8563 is not set
+CONFIG_RTC_JZ4760=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+
+#
+# JZSOC char device support
+#
+CONFIG_JZCHAR=y
+CONFIG_JZ_TCSM=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_JZ47XX is not set
+CONFIG_I2C0_JZ4760=y
+CONFIG_I2C1_JZ4760=y
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_JZSOC=y
+CONFIG_FB_JZ4760_LCD=y
+# CONFIG_FB_JZ4760_LCD_USE_2LAYER_FRAMEBUFFER is not set
+# CONFIG_FB_JZ4760_TVE is not set
+# CONFIG_JZ4760_IPU_MM is not set
+# CONFIG_FB_JZ4760_SLCD is not set
+# CONFIG_JZ4760_LCD_SAMSUNG_LTP400WQF01 is not set
+# CONFIG_JZ4760_LCD_SAMSUNG_LTP400WQF02 is not set
+# CONFIG_JZ4760_LCD_AUO_A043FL01V2 is not set
+# CONFIG_JZ4760_LCD_FOXCONN_PT035TN01 is not set
+# CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL is not set
+# CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA is not set
+CONFIG_JZ4760_LCD_TOPPOLY_TD043MGEB1=y
+# CONFIG_JZ4760_LCD_TRULY_TFTG320240DTSW_18BIT is not set
+# CONFIG_JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W is not set
+# CONFIG_JZ4760_SLCD_KGM701A3_TFT_SPFD5420A is not set
+# CONFIG_JZ4760_VGA_DISPLAY is not set
+# CONFIG_FB_JZ4760_EPD is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_CURSOR_FLASH is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+# CONFIG_SND is not set
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_JZ_AC97 is not set
+CONFIG_SOUND_JZ_I2S=y
+# CONFIG_I2S_AK4642EN is not set
+# CONFIG_I2S_ICODEC is not set
+# CONFIG_I2S_DLV is not set
+CONFIG_I2S_DLV_4760=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# Ingenic OTG USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_JZ4740 is not set
+# CONFIG_USB_GADGET_JZ4750 is not set
+# CONFIG_USB_GADGET_JZ4750D is not set
+# CONFIG_USB_GADGET_JZ4750L is not set
+# CONFIG_USB_GADGET_JZ4730 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X 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_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_JZ_UDC_HOTPLUG is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_JZ_MSC0=y
+# CONFIG_JZ_MSC0_BUS_1 is not set
+CONFIG_JZ_MSC0_BUS_4=y
+# CONFIG_JZ_MSC0_BUS_8 is not set
+# CONFIG_JZ_MSC0_SDIO_SUPPORT is not set
+CONFIG_JZ_MSC1=y
+# CONFIG_JZ_MSC1_BUS_1 is not set
+CONFIG_JZ_MSC1_BUS_4=y
+# CONFIG_JZ_MSC1_BUS_8 is not set
+# CONFIG_JZ_MSC1_SDIO_SUPPORT is not set
+# CONFIG_JZ_MSC2 is not set
+# CONFIG_JZ_BOOT_FROM_MSC0 is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Yaffs2 Filesystems
+#
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=y
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index cbd25a2f9b5..14217998dfb 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -206,6 +206,8 @@
#define MACH_INGENIC_JZ4750 2 /* JZ4750 SOC */
#define MACH_INGENIC_JZ4750D 3 /* JZ4750D SOC */
#define MACH_INGENIC_JZ4750L 4 /* JZ4750L SOC */
+#define MACH_INGENIC_JZ4760 5 /* JZ4760 SOC */
+#define MACH_INGENIC_JZ4810 6 /* JZ4810 SOC */
#define CL_SIZE COMMAND_LINE_SIZE
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_controller.h b/arch/mips/include/asm/jzmmc/jz_mmc_controller.h
new file mode 100644
index 00000000000..b45d9286633
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_controller.h
@@ -0,0 +1,42 @@
+/*
+ * drivers/mmc/host/jz_mmc_controller.h
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_MMC_CONTROLLER_H__
+#define __JZ_MMC_CONTROLLER_H__
+
+#include <asm/jzmmc/jz_mmc_host.h>
+#include <asm/jzmmc/jz_mmc_gpio.h>
+#include <asm/jzmmc/jz_mmc_msc.h>
+#include <asm/jzmmc/jz_mmc_dma.h>
+
+struct jz_mmc_functions {
+ void (*deinit) (struct jz_mmc_host *, struct platform_device *);
+ int (*transmit_data) (struct jz_mmc_host *);
+ void (*execute_cmd) (struct jz_mmc_host *, struct mmc_command *, unsigned int);
+ void (*set_clock) (struct jz_mmc_host *, int);
+ void (*msc_deinit) (struct jz_mmc_host *);
+ void (*gpio_deinit) (struct jz_mmc_host *, struct platform_device *);
+ void (*dma_deinit) (struct jz_mmc_host *);
+};
+
+struct jz_mmc_controller {
+
+ struct jz_mmc_msc msc; // msc
+ struct jz_mmc_dma dma; // dma
+ struct jz_mmc_gpio gpio; // gpio
+
+ int (*init) (struct jz_mmc_controller *, struct jz_mmc_host *,
+ struct platform_device *);
+ struct jz_mmc_functions functions;
+};
+
+int controller_register(struct jz_mmc_controller *, struct jz_mmc_host *);
+
+#endif /* __JZ_MMC_CONTROLLER_H__ */
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_dma.h b/arch/mips/include/asm/jzmmc/jz_mmc_dma.h
new file mode 100644
index 00000000000..8899d9c6635
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_dma.h
@@ -0,0 +1,39 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/dma/jz_mmc_dma.h
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_MMC_DMA_H__
+#define __JZ_MMC_DMA_H__
+
+#include <asm/jzmmc/jz_mmc_host.h>
+
+#define DMA_TS 32 // ONLY BYTE
+
+// No 64 byte in jz4760dmac.h
+#define DMAC_DCMD_DS_64BYTE (5 << DMAC_DCMD_DS_BIT)
+
+#define DMAC_DCMD_DS(x) (x == 32? DMAC_DCMD_DS_32BYTE:DMAC_DCMD_DS_64BYTE)
+
+struct jz_mmc_dma {
+
+ int (*init) (struct jz_mmc_host *);
+ void (*deinit) (struct jz_mmc_host *);
+};
+
+int jz_mmc_dma_register(struct jz_mmc_dma *dma);
+
+void jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode, int ts);
+
+void jz_mmc_send_dma(struct jz_mmc_host *host, int chan, unsigned long srcaddr,
+ unsigned long taraddr, int al_count, int unal_count);
+
+void jz_mmc_receive_dma(struct jz_mmc_host *host, int chan, unsigned long srcaddr,
+ unsigned long taraddr, int al_count, int unal_count);
+
+#endif /* __JZ_MMC_DMA_H__ */
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_gpio.h b/arch/mips/include/asm/jzmmc/jz_mmc_gpio.h
new file mode 100644
index 00000000000..2814a58a080
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_gpio.h
@@ -0,0 +1,33 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/gpio/jz_mmc_gpio.h
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_MMC_GPIO_H__
+#define __JZ_MMC_GPIO_H__
+
+#include <asm/jzmmc/jz_mmc_host.h>
+#include <linux/platform_device.h>
+
+#ifndef __JZ_MMC_HOST_H__
+#error "!!!!!!!!!!!!!"
+#endif
+
+//struct jz_mmc_host test;
+//int t = test.dma.len;
+
+struct jz_mmc_gpio {
+
+ int (*init) (struct jz_mmc_host *, struct platform_device *);
+ void (*deinit) (struct jz_mmc_host *, struct platform_device *);
+};
+
+int jz_mmc_gpio_register(struct jz_mmc_gpio *);
+
+#endif /* __JZ_MMC_GPIO_H__ */
+
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_host.h b/arch/mips/include/asm/jzmmc/jz_mmc_host.h
new file mode 100644
index 00000000000..dbedcbc19b1
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_host.h
@@ -0,0 +1,104 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/jz_mmc_host.h
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_MMC_HOST_H__
+#define __JZ_MMC_HOST_H__
+
+#include <asm/jzmmc/jz_mmc_platform_data.h>
+#include <asm/jzsoc.h>
+
+#define USE_DMA
+
+#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
+#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
+#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
+#define SD_CLOCK_HIGH 24000000 /* 24 MHz for SD Cards */
+#define MMC_NO_ERROR 0
+
+#define NR_SG 1
+
+#define MSC_1BIT_BUS 0
+#define MSC_4BIT_BUS 1
+#define MSC_8BIT_BUS 2
+
+#define SZ_4K 0x00001000
+
+typedef struct jzsoc_dma_desc {
+ volatile u32 ddadr; /* Points to the next descriptor + flags */
+ volatile u32 dsadr; /* DSADR value for the current transfer */
+ volatile u32 dtadr; /* DTADR value for the current transfer */
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+} jzsoc_dma_desc;
+
+struct jz_mmc_curr_req {
+ struct mmc_request *mrq;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+ int r_type;
+};
+
+struct jz_mmc_host {
+ struct mmc_host *mmc;
+ spinlock_t lock;
+ struct {
+ int len;
+ int dir;
+ int rxchannel;
+ int txchannel;
+ } dma;
+ struct {
+ int index;
+ int offset;
+ int len;
+ } pio;
+ unsigned int clkrt;
+ unsigned int cmdat;
+ unsigned int imask;
+ unsigned int power_mode;
+ unsigned int eject;
+ unsigned int oldstat;
+ unsigned int pdev_id;
+ void __iomem *base;
+
+ struct resource *irqres;
+ struct resource *memres;
+ struct resource *dmares;
+
+ struct jz_mmc_platform_data *plat;
+ struct jz_mmc_curr_req curr;
+ dma_addr_t sg_dma;
+ struct jzsoc_dma_desc *sg_cpu;
+ unsigned int dma_len;
+ unsigned int dma_dir;
+ int dma_ts;
+ int msc_ack;
+ int flag_cp;
+ unsigned int *dma_buf;
+ jz_dma_desc *ua_desc;
+ dma_addr_t dma_desc_phys_addr;
+ struct work_struct gpio_jiq_work;
+ struct work_struct msc_jiq_work;
+ struct workqueue_struct *msc_work_queue;
+ wait_queue_head_t msc_wait_queue;
+};
+
+#if 0
+struct jz_mmc_functions {
+ void (*deinit) (struct jz_mmc_host *, struct platform_device *);
+ int (*transmit_data) (struct jz_mmc_host *);
+ void (*execute_cmd) (struct jz_mmc_host *, struct mmc_command *, unsigned int);
+ void (*set_clock) (struct jz_mmc_host *, int);
+ void (*msc_deinit) (struct jz_mmc_host *);
+ int (*gpio_deinit) (struct jz_mmc_host *, struct platform_device *);
+ void (*dma_deinit) (struct jz_mmc_host *);
+};
+#endif
+
+#endif /* __JZ_MMC_HOST_H__ */
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_msc.h b/arch/mips/include/asm/jzmmc/jz_mmc_msc.h
new file mode 100644
index 00000000000..69db5ea8adf
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_msc.h
@@ -0,0 +1,33 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/msc/jz_mmc_msc.c
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_MMC_MSC_H__
+#define __JZ_MMC_MSC_H__
+
+#include <asm/jzmmc/jz_mmc_host.h>
+#include <asm/jzmmc/jz_mmc_dma.h>
+
+#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
+
+struct jz_mmc_msc {
+
+ int (*init) (struct jz_mmc_host *);
+ void (*deinit) (struct jz_mmc_host *);
+ void (*set_clock) (struct jz_mmc_host *, int);
+ void (*execute_cmd) (struct jz_mmc_host *, struct mmc_command *, unsigned int);
+};
+
+int jz_mmc_msc_register(struct jz_mmc_msc *msc);
+
+#ifdef USE_DMA
+void jz_mmc_data_start(struct jz_mmc_host *host);
+#endif
+
+#endif /* __JZ_MMC_MSC_H__ */
diff --git a/arch/mips/include/asm/jzmmc/jz_mmc_platform_data.h b/arch/mips/include/asm/jzmmc/jz_mmc_platform_data.h
new file mode 100644
index 00000000000..f5b0e190ded
--- /dev/null
+++ b/arch/mips/include/asm/jzmmc/jz_mmc_platform_data.h
@@ -0,0 +1,56 @@
+/*
+ * arch/mips/include/asm/mach-jz4750/jz_platform_data.h
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_PLATFORM_DATA_H__
+#define __JZ_PLATFORM_DATA_H__
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+#define CARD_INSERTED 1
+#define CARD_REMOVED 0
+
+struct jz_mmc_platform_data {
+ unsigned int ocr_mask; /* available voltages */
+ unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */
+ unsigned char status_irq;
+ unsigned char support_sdio;
+ unsigned char bus_width;
+ unsigned int max_bus_width;
+ unsigned int detect_pin;
+
+ unsigned char msc_irq;
+ unsigned char dma_rxid;
+ unsigned char dma_txid;
+
+ void *driver_data;
+
+ void (*init) (struct device *);
+ void (*power_on) (struct device *);
+ void (*power_off) (struct device *);
+ void (*cpm_start) (struct device *);
+ unsigned int (*status) (struct device *);
+ unsigned int (*write_protect) (struct device *);
+ void (*plug_change) (int);
+ int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+
+
+/*
+ int (*init)(struct device *, irq_handler_t , void *);
+ int (*get_ro)(struct device *);
+ void (*setpower)(struct device *, unsigned int);
+ void (*exit)(struct device *, void *);
+*/
+
+
+};
+
+#endif
diff --git a/arch/mips/include/asm/jzsoc.h b/arch/mips/include/asm/jzsoc.h
index 0da2887148a..d950ad58e7d 100644
--- a/arch/mips/include/asm/jzsoc.h
+++ b/arch/mips/include/asm/jzsoc.h
@@ -39,6 +39,26 @@
#include <asm/mach-jz4750l/jz4750l.h>
#endif
+#ifdef CONFIG_SOC_JZ4760
+#include <asm/mach-jz4760/jz4760.h>
+#endif
+
+#ifdef CONFIG_SOC_JZ4810
+#include <asm/mach-jz4810/jz4810.h>
+#endif
+
+#ifdef CONFIG_MFD_WM831X
+#include <linux/mfd/wm831x/core.h>
+#include <asm/jzpm/jz_wm831x.h>
+
+#endif
+/*
+#else
+
+#include <asm/jzpm/jz.h>
+#endif
+*/
+
/*
* Generic I/O routines
*/
diff --git a/arch/mips/include/asm/mach-jz4750/ops.h b/arch/mips/include/asm/mach-jz4750/ops.h
index a7ebb97cd5a..a463bbb4ca3 100644
--- a/arch/mips/include/asm/mach-jz4750/ops.h
+++ b/arch/mips/include/asm/mach-jz4750/ops.h
@@ -270,7 +270,7 @@
//
//////////////////////////////////////////////////////////
-/*
+/*
* p is the port number (0,1,2,3,4,5)
* o is the pin offset (0-31) inside the port
* n is the absolute number of a pin (0-191), regardless of the port
@@ -298,7 +298,7 @@ do { \
} while (0)
/*
- * D0 ~ D31, A0 ~ A14, DCS0#, RAS#, CAS#,
+ * D0 ~ D31, A0 ~ A14, DCS0#, RAS#, CAS#,
* RDWE#, WE0#, WE1#, WE2#, WE3#, CKO#, CKE#
*/
#define __gpio_as_sdram_32bit() \
@@ -312,7 +312,7 @@ do { \
} while (0)
/*
- * D0 ~ D15, A0 ~ A14, DCS0#, RAS#, CAS#,
+ * D0 ~ D15, A0 ~ A14, DCS0#, RAS#, CAS#,
* RDWE#, WE0#, WE1#, WE2#, WE3#, CKO#, CKE#
*/
#define __gpio_as_sdram_16bit() \
@@ -641,7 +641,7 @@ do { \
REG_GPIO_PXPES(4) = 0x00000fff; \
} while (0)
-/*
+/*
* SDATO, SDATI, BCLK, SYNC, SCLK_RSTN(gpio sepc) or
* SDATA_OUT, SDATA_IN, BIT_CLK, SYNC, SCLK_RESET(aic spec)
*/
@@ -1632,7 +1632,7 @@ do { \
REG_AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT; \
} while(0)
-/* In fact, only stereo is support now. */
+/* In fact, only stereo is support now. */
#define __ac97_set_rs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK )
#define __ac97_set_rs_mono() \
do { \
@@ -1738,7 +1738,7 @@ do { \
#define __aic_write_tfifo(v) ( REG_AIC_DR = (v) )
#define __aic_read_rfifo() ( REG_AIC_DR )
-#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC )
+#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC )
#define __aic_external_codec() ( REG_AIC_FR &= ~AIC_FR_ICDC )
//
@@ -1918,7 +1918,7 @@ do { \
/* sysclk(cpm_pcm_sysclk) Hz is created by cpm logic, and pcmclk Hz is the pcm in/out clock wanted */
#define __pcm_set_clk_rate(sysclk, pcmclk) \
-__pcm_set_clk_div(((sysclk) / (pcmclk) - 1))
+__pcm_set_clk_div(((sysclk) / (pcmclk) - 1))
#define __pcm_set_sync_div(n) \
( REG_PCM_DIV = (REG_PCM_DIV & ~PCM_DIV_SYNDIV_MASK) | ((n) << PCM_DIV_SYNDIV_BIT) )
@@ -1986,6 +1986,9 @@ do { \
#define __i2c_check_drf() ( REG_I2C_SR & I2C_SR_DRF )
#define __i2c_received_ack() ( !(REG_I2C_SR & I2C_SR_ACKF) )
+#define __i2c_ack_is_nack() (REG_I2C_SR & I2C_SR_ACKF)
+#define __i2c_ack_is_ack() (!(REG_I2C_SR & I2C_SR_ACKF))
+
#define __i2c_is_busy() ( REG_I2C_SR & I2C_SR_BUSY )
#define __i2c_transmit_ended() ( REG_I2C_SR & I2C_SR_TEND )
@@ -2259,7 +2262,7 @@ do { \
/* frmhl,endian,mcom,flen,pha,pol MASK */
#define SSICR1_MISC_MASK \
( SSI_CR1_FRMHL_MASK | SSI_CR1_LFST | SSI_CR1_MCOM_MASK \
- | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL )
+ | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL )
#define __ssi_spi_set_misc(n,frmhl,endian,flen,mcom,pha,pol) \
do { \
@@ -2274,7 +2277,7 @@ do { \
#define __ssi_set_lsb(n) ( REG_SSI_CR1(n) |= SSI_CR1_LFST )
#define __ssi_set_frame_length(n, m) \
- REG_SSI_CR1(n) = (REG_SSI_CR1(n) & ~SSI_CR1_FLEN_MASK) | (((m) - 2) << 4)
+ REG_SSI_CR1(n) = (REG_SSI_CR1(n) & ~SSI_CR1_FLEN_MASK) | (((m) - 2) << 4)
/* m = 1 - 16 */
#define __ssi_set_microwire_command_length(n,m) \
@@ -2638,8 +2641,8 @@ do { \
#define __lcd_set_24_tftpnl() ( REG_LCD_CFG |= LCD_CFG_MODE_TFT_24BIT )
-/*
- * n=1,2,4,8 for single mono-STN
+/*
+ * n=1,2,4,8 for single mono-STN
* n=4,8 for dual mono-STN
*/
#define __lcd_set_panel_datawidth(n) \
@@ -3251,7 +3254,7 @@ do { \
#define __owi_disable_byte_interrupt() ( REG_OWI_CTL &= ~OWI_CTL_EBYTE )
#define __owi_enable_bit_interrupt() ( REG_OWI_CTL |= OWI_CTL_EBIT )
#define __owi_disable_bit_interrupt() ( REG_OWI_CTL &= ~OWI_CTL_EBIT )
-#define __owi_enable_rst_interrupt() ( REG_OWI_CTL |= OWI_CTL_ERST )
+#define __owi_enable_rst_interrupt() ( REG_OWI_CTL |= OWI_CTL_ERST )
#define __owi_disable_rst_interrupt() ( REG_OWI_CTL &=~OWI_CTL_ERST )
/* OW configure register ops */
@@ -3349,7 +3352,7 @@ do { \
#define __tssi_disable_ovrn_irq() ( REG_TSSI_CTRL |= TSSI_CTRL_OVRNM )
#define __tssi_enable_trig_irq() ( REG_TSSI_CTRL &= ~TSSI_CTRL_TRIGM )
-#define __tssi_disable_trig_irq() ( REG_TSSI_CTRL |= TSSI_CTRL_TRIGM )
+#define __tssi_disable_trig_irq() ( REG_TSSI_CTRL |= TSSI_CTRL_TRIGM )
#define __tssi_state_is_overrun() ( REG_TSSI_STAT & TSSI_STAT_OVRN )
#define __tssi_state_trigger_meet() ( REG_TSSI_STAT & TSSI_STAT_TRIG )
diff --git a/arch/mips/include/asm/mach-jz4750/regs.h b/arch/mips/include/asm/mach-jz4750/regs.h
index 29db7fbe8c7..0fcc11edc2e 100644
--- a/arch/mips/include/asm/mach-jz4750/regs.h
+++ b/arch/mips/include/asm/mach-jz4750/regs.h
@@ -3271,145 +3271,201 @@
/*************************************************************************
* IPU (Image Processing Unit)
*************************************************************************/
-#define IPU_V_BASE 0xB3080000
-#define IPU_P_BASE 0x13080000
-
-/* Register offset */
-#define REG_CTRL 0x0 /* IPU Control Register */
-#define REG_STATUS 0x4 /* IPU Status Register */
-#define REG_D_FMT 0x8 /* Data Format Register */
-#define REG_Y_ADDR 0xc /* Input Y or YUV422 Packaged Data Address Register */
-#define REG_U_ADDR 0x10 /* Input U Data Address Register */
-#define REG_V_ADDR 0x14 /* Input V Data Address Register */
-#define REG_IN_FM_GS 0x18 /* Input Geometric Size Register */
-#define REG_Y_STRIDE 0x1c /* Input Y Data Line Stride Register */
-#define REG_UV_STRIDE 0x20 /* Input UV Data Line Stride Register */
-#define REG_OUT_ADDR 0x24 /* Output Frame Start Address Register */
-#define REG_OUT_GS 0x28 /* Output Geometric Size Register */
-#define REG_OUT_STRIDE 0x2c /* Output Data Line Stride Register */
-#define REG_RSZ_COEF_INDEX 0x30 /* Resize Coefficients Table Index Register */
-#define REG_CSC_CO_COEF 0x34 /* CSC C0 Coefficient Register */
-#define REG_CSC_C1_COEF 0x38 /* CSC C1 Coefficient Register */
-#define REG_CSC_C2_COEF 0x3c /* CSC C2 Coefficient Register */
-#define REG_CSC_C3_COEF 0x40 /* CSC C3 Coefficient Register */
-#define REG_CSC_C4_COEF 0x44 /* CSC C4 Coefficient Register */
-#define HRSZ_LUT_BASE 0x48 /* Horizontal Resize Coefficients Look Up Table Register group */
-#define VRSZ_LUT_BASE 0x4c /* Virtical Resize Coefficients Look Up Table Register group */
-#define REG_CSC_OFSET_PARA 0x50 /* CSC Offset Parameter Register */
-#define REG_Y_PHY_T_ADDR 0x54 /* Input Y Physical Table Address Register */
-#define REG_U_PHY_T_ADDR 0x58 /* Input U Physical Table Address Register */
-#define REG_V_PHY_T_ADDR 0x5c /* Input V Physical Table Address Register */
-#define REG_OUT_PHY_T_ADDR 0x60 /* Output Physical Table Address Register */
-
-/* REG_CTRL: IPU Control Register */
-#define IPU_CE_SFT 0x0
-#define IPU_CE_MSK 0x1
-#define IPU_RUN_SFT 0x1
-#define IPU_RUN_MSK 0x1
-#define HRSZ_EN_SFT 0x2
-#define HRSZ_EN_MSK 0x1
-#define VRSZ_EN_SFT 0x3
-#define VRSZ_EN_MSK 0x1
-#define CSC_EN_SFT 0x4
-#define CSC_EN_MSK 0x1
-#define FM_IRQ_EN_SFT 0x5
-#define FM_IRQ_EN_MSK 0x1
-#define IPU_RST_SFT 0x6
-#define IPU_RST_MSK 0x1
-#define H_SCALE_SFT 0x8
-#define H_SCALE_MSK 0x1
-#define V_SCALE_SFT 0x9
-#define V_SCALE_MSK 0x1
-#define PKG_SEL_SFT 0xA
-#define PKG_SEL_MSK 0x1
-#define LCDC_SEL_SFT 0xB
-#define LCDC_SEL_MSK 0x1
-#define SPAGE_MAP_SFT 0xC
-#define SPAGE_MAP_MSK 0x1
-#define DPAGE_SEL_SFT 0xD
-#define DPAGE_SEL_MSK 0x1
-#define DISP_SEL_SFT 0xE
-#define DISP_SEL_MSK 0x1
-#define FIELD_CONF_EN_SFT 15
-#define FIELD_CONF_EN_MSK 1
-#define FIELD_SEL_SFT 16
-#define FIELD_SEL_MSK 1
-#define DFIX_SEL_SFT 17
-#define DFIX_SEL_MSK 1
-
-/* REG_STATUS: IPU Status Register */
-#define OUT_END_SFT 0x0
-#define OUT_END_MSK 0x1
-#define FMT_ERR_SFT 0x1
-#define FMT_ERR_MSK 0x1
-#define SIZE_ERR_SFT 0x2
-#define SIZE_ERR_MSK 0x1
-
-/* D_FMT: Data Format Register */
-#define IN_FMT_SFT 0x0
-#define IN_FMT_MSK 0x3
-#define IN_OFT_SFT 0x2
-#define IN_OFT_MSK 0x3
-#define YUV_PKG_OUT_SFT 0x10
-#define YUV_PKG_OUT_MSK 0x7
-#define OUT_FMT_SFT 0x13
-#define OUT_FMT_MSK 0x3
-#define RGB_OUT_OFT_SFT 0x15
-#define RGB_OUT_OFT_MSK 0x7
-#define RGB888_FMT_SFT 0x18
-#define RGB888_FMT_MSK 0x1
-
-/* IN_FM_GS: Input Geometric Size Register */
-#define IN_FM_H_SFT 0x0
-#define IN_FM_H_MSK 0xFFF
-#define IN_FM_W_SFT 0x10
-#define IN_FM_W_MSK 0xFFF
-
-/* Y_STRIDE: Input Y Data Line Stride Register */
-#define Y_S_SFT 0x0
-#define Y_S_MSK 0x3FFF
-
-/* UV_STRIDE: Input UV Data Line Stride Register */
-#define V_S_SFT 0x0
-#define V_S_MSK 0x1FFF
-#define U_S_SFT 0x10
-#define U_S_MSK 0x1FFF
-
-/* OUT_GS: Output Geometric Size Register */
-#define OUT_FM_H_SFT 0x0
-#define OUT_FM_H_MSK 0x1FFF
-#define OUT_FM_W_SFT 0x10
-#define OUT_FM_W_MSK 0x7FFF
-
-/* OUT_STRIDE: Output Data Line Stride Register */
-#define OUT_S_SFT 0x0
-#define OUT_S_MSK 0xFFFF
-
-/* RSZ_COEF_INDEX: Resize Coefficients Table Index Register */
-#define VE_IDX_SFT 0x0
-#define VE_IDX_MSK 0x1F
-#define HE_IDX_SFT 0x10
-#define HE_IDX_MSK 0x1F
-
-/* CSC_CX_COEF: CSC CX Coefficient Register */
-#define CX_COEF_SFT 0x0
-#define CX_COEF_MSK 0xFFF
-
-/* HRSZ_LUT_BASE, VRSZ_LUT_BASE: Resize Coefficients Look Up Table Register group */
-#define LUT_LEN 20
-
-#define OUT_N_SFT 0x0
-#define OUT_N_MSK 0x1
-#define IN_N_SFT 0x1
-#define IN_N_MSK 0x1
-#define W_COEF_SFT 0x2
-#define W_COEF_MSK 0x3FF
-
-/* CSC_OFSET_PARA: CSC Offset Parameter Register */
-#define CHROM_OF_SFT 0x10
-#define CHROM_OF_MSK 0xFF
-#define LUMA_OF_SFT 0x00
-#define LUMA_OF_MSK 0xFF
+/* IPU Control Register */
+#define REG_IPU_CTRL (IPU_BASE + 0x0)
+
+/* IPU Status Register */
+#define REG_IPU_STATUS (IPU_BASE + 0x4)
+
+/* Data Format Register */
+#define REG_IPU_D_FMT (IPU_BASE + 0x8)
+
+/* Input Y or YUV422 Packaged Data Address Register */
+#define REG_IPU_Y_ADDR (IPU_BASE + 0xc)
+
+/* Input U Data Address Register */
+#define REG_IPU_U_ADDR (IPU_BASE + 0x10)
+
+/* Input V Data Address Register */
+#define REG_IPU_V_ADDR (IPU_BASE + 0x14)
+
+/* Input Geometric Size Register */
+#define REG_IPU_IN_FM_GS (IPU_BASE + 0x18)
+
+/* Input Y Data Line Stride Register */
+#define REG_IPU_Y_STRIDE (IPU_BASE + 0x1c)
+
+/* Input UV Data Line Stride Register */
+#define REG_IPU_UV_STRIDE (IPU_BASE + 0x20)
+
+/* Output Frame Start Address Register */
+#define REG_IPU_OUT_ADDR (IPU_BASE + 0x24)
+
+/* Output Geometric Size Register */
+#define REG_IPU_OUT_GS (IPU_BASE + 0x28)
+
+/* Output Data Line Stride Register */
+#define REG_IPU_OUT_STRIDE (IPU_BASE + 0x2c)
+
+/* Resize Coefficients Table Index Register */
+#define REG_IPU_RSZ_COEF_INDEX (IPU_BASE + 0x30)
+
+/* CSC C0 Coefficient Register */
+#define REG_IPU_CSC_CO_COEF (IPU_BASE + 0x34)
+
+/* CSC C1 Coefficient Register */
+#define REG_IPU_CSC_C1_COEF (IPU_BASE + 0x38)
+
+/* CSC C2 Coefficient Register */
+#define REG_IPU_CSC_C2_COEF (IPU_BASE + 0x3c)
+
+/* CSC C3 Coefficient Register */
+#define REG_IPU_CSC_C3_COEF (IPU_BASE + 0x40)
+
+/* CSC C4 Coefficient Register */
+#define REG_IPU_CSC_C4_COEF (IPU_BASE + 0x44)
+
+/* Horizontal Resize Coefficients Look Up Table Register group */
+#define REG_IPU_HRSZ_LUT_BASE (IPU_BASE + 0x48)
+
+/* Virtical Resize Coefficients Look Up Table Register group */
+#define REG_IPU_VRSZ_LUT_BASE (IPU_BASE + 0x4c)
+
+/* CSC Offset Parameter Register */
+#define REG_IPU_CSC_OFSET_PARA (IPU_BASE + 0x50)
+
+/* Input Y Physical Table Address Register */
+#define REG_IPU_Y_PHY_T_ADDR (IPU_BASE + 0x54)
+
+/* Input U Physical Table Address Register */
+#define REG_IPU_U_PHY_T_ADDR (IPU_BASE + 0x58)
+
+/* Input V Physical Table Address Register */
+#define REG_IPU_V_PHY_T_ADDR (IPU_BASE + 0x5c)
+
+/* Output Physical Table Address Register */
+#define REG_IPU_OUT_PHY_T_ADDR (IPU_BASE + 0x60)
+
+/* IPU Control */
+#define IPU_CTRL_DFIX_SEL (1 << 17)
+#define IPU_CTRL_FIELD_SEL (1 << 16)
+#define IPU_CTRL_FIELD_CONF_EN (1 << 15)
+#define IPU_CTRL_DISP_SEL (1 << 14)
+#define IPU_CTRL_DPAGE_MAP (1 << 13)
+#define IPU_CTRL_SPAGE_MAP (1 << 12)
+#define IPU_CTRL_LCDC_SEL (1 << 11)
+#define IPU_CTRL_SPKG_SEL (1 << 10)
+#define IPU_CTRL_V_SCALE (1 << 9)
+#define IPU_CTRL_H_SCALE (1 << 8)
+#define IPU_CTRL_IPU_RST (1 << 6)
+#define IPU_CTRL_FM_IRQ_EN (1 << 5)
+#define IPU_CTRL_CSC_EN (1 << 4)
+#define IPU_CTRL_VRSZ_EN (1 << 3)
+#define IPU_CTRL_HRSZ_EN (1 << 2)
+#define IPU_CTRL_IPU_RUN (1 << 1)
+#define IPU_CTRL_CHIP_EN (1 << 0)
+
+/* IPU Status */
+#define IPU_STAT_SIZE_ERR (1 << 2)
+#define IPU_STAT_FMT_ERR (1 << 1)
+#define IPU_STAT_OUT_END (1 << 0)
+
+/* IPU Data Format */
+
+#define IPU_D_FMT_RGB_OUT_888_FMT (1 << 24)
+
+#define IPU_D_FMT_RGB_OUT_OFT_MASK (0x7 << 21)
+
+#define IPU_D_FMT_RGB_OUT_OFT_RGB (0 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_RBG (1 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_GBR (2 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_GRB (3 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_BRG (4 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_BGR (5 << 21)
+
+#define IPU_D_FMT_OUT_FMT_MASK (0x3 << 19)
+
+#define IPU_D_FMT_OUT_FMT_RGB555 (0 << 19)
+#define IPU_D_FMT_OUT_FMT_RGB565 (1 << 19)
+#define IPU_D_FMT_OUT_FMT_RGB888 (2 << 19)
+#define IPU_D_FMT_OUT_FMT_YUV422 (3 << 19)
+
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_MASK (0x7 << 16)
+
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y1UY0V (0 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y1VY0U (1 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_UY1VY0 (2 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_VY1UY0 (3 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y0UY1V (4 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y0VY1U (5 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_UY0VY1 (6 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_VY0UY1 (7 << 16)
+
+#define IPU_D_FMT_IN_OFT_MASK (0x3 << 2)
+
+#define IPU_D_FMT_IN_OFT_Y1UY0V (0 << 2)
+#define IPU_D_FMT_IN_OFT_Y1VY0U (1 << 2)
+#define IPU_D_FMT_IN_OFT_UY1VY0 (2 << 2)
+#define IPU_D_FMT_IN_OFT_VY1UY0 (3 << 2)
+
+#define IPU_D_FMT_IN_FMT_MASK (0x3 << 0)
+
+#define IPU_D_FMT_IN_FMT_YUV420 (0 << 0)
+#define IPU_D_FMT_IN_FMT_YUV422 (1 << 0)
+#define IPU_D_FMT_IN_FMT_YUV444 (2 << 0)
+#define IPU_D_FMT_IN_FMT_YUV411 (3 << 0)
+
+/* Input Geometric Size Register */
+#define IPU_IN_FM_GS_W_MASK (0xFFF)
+#define IPU_IN_FM_GS_W(n) ((n) << 16)
+
+#define IPU_IN_FM_GS_H_MASK (0xFFF)
+#define IPU_IN_FM_GS_H(n) ((n) << 0)
+
+/* Input UV Data Line Stride Register */
+#define IPU_UV_STRIDE_U_S_MASK (0x1FFF)
+#define IPU_UV_STRIDE_U_S(n) ((n) << 16)
+
+#define IPU_UV_STRIDE_V_S_MASK (0x1FFF)
+#define IPU_UV_STRIDE_V_S(n) ((n) << 0)
+
+/* Output Geometric Size Register */
+#define IPU_OUT_GS_W_MASK (0x7FFF)
+#define IPU_OUT_GS_W(n) ((n) << 16)
+
+#define IPU_OUT_GS_H_MASK (0x1FFF)
+#define IPU_OUT_GS_H(n) ((n) << 0)
+
+/* Resize Coefficients Table Index Register */
+#define IPU_RSZ_COEF_INDEX_HE_IDX_MASK (0x1F)
+#define IPU_RSZ_COEF_INDEX_HE_IDX(n) ((n) << 16)
+
+#define IPU_RSZ_COEF_INDEX_VE_IDX_MASK (0x1F)
+#define IPU_RSZ_COEF_INDEX_VE_IDX(n) ((n) << 0)
+
+/* Resize Coefficients Look Up Table Register group */
+#define IPU_HRSZ_COEF_LUT_START (1 << 12)
+
+#define IPU_HRSZ_COEF_LUT_W_COEF_MASK (0x3FF)
+#define IPU_HRSZ_COEF_LUT_W_COEF(n) ((n) << 2)
+
+#define IPU_HRSZ_COEF_LUT_IN_EN (1 << 1)
+#define IPU_HRSZ_COEF_LUT_OUT_EN (1 << 0)
+
+#define IPU_VRSZ_COEF_LUT_START (1 << 12)
+
+#define IPU_VRSZ_COEF_LUT_W_COEF_MASK (0x3FF)
+#define IPU_VRSZ_COEF_LUT_W_COEF(n) ((n) << 2)
+
+#define IPU_VRSZ_COEF_LUT_IN_EN (1 << 1)
+#define IPU_VRSZ_COEF_LUT_OUT_EN (1 << 0)
+
+/* CSC Offset Parameter Register */
+#define IPU_CSC_OFFSET_PARA_CHROM_OF_MASK (0xFF)
+#define IPU_CSC_OFFSET_PARA_CHROM_OF(n) ((n) << 16)
+
+#define IPU_CSC_OFFSET_LUMA_OF_MASK (0xFF)
+#define IPU_CSC_OFFSET_LUMA_OF(n) ((n) << 0)
#endif /* __JZ4750_REGS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4750d/i2c.h b/arch/mips/include/asm/mach-jz4750d/i2c.h
new file mode 100644
index 00000000000..c80297eb290
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4750d/i2c.h
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/mips/jz4750/i2c.c
+ *
+ * JZ4750 I2C Simple Driver.
+ *
+ * Copyright (c) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River <zwang@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 __I_I2C_H__
+#define __I_I2C_H__
+
+enum {
+ I_I2C_IO_DIR_READ = 0,
+ I_I2C_IO_DIR_WRITE,
+};
+
+enum {
+ I_I2C_CAP_SEQ_READ = (1 << 0),
+ I_I2C_CAP_SEQ_WRITE = (1 << 1),
+ I_I2C_CAP_16BIT_OFFSET_MSB = (1 << 2),
+ I_I2C_CAP_16BIT_OFFSET_LSB = (1 << 3),
+};
+
+enum {
+ I_I2C_FLAG_STOP_BEFORE_RESTART = (1 << 0),
+};
+
+struct i_i2c_timing {
+ int id;
+
+ unsigned long clk;
+ unsigned long timeout;
+
+ unsigned long t_wr;
+};
+
+struct i_i2c_dev {
+ int id;
+
+ char *name;
+
+ unsigned int address;
+
+ spinlock_t lock;
+
+ unsigned long cap;
+ unsigned long flags;
+
+ unsigned long size;
+
+ unsigned int read_size;
+ unsigned int write_size;
+
+ int timing_id;
+ struct i_i2c_timing *timing;
+};
+
+int i_i2c_read_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count);
+
+int i_i2c_write_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count);
+
+int i_i2c_init_dev(struct i_i2c_dev *dev);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4750d/jz4750d.h b/arch/mips/include/asm/mach-jz4750d/jz4750d.h
index 8eff7037e02..5b842567f38 100644
--- a/arch/mips/include/asm/mach-jz4750d/jz4750d.h
+++ b/arch/mips/include/asm/mach-jz4750d/jz4750d.h
@@ -41,5 +41,6 @@
#include <asm/mach-jz4750d/clock.h>
#include <asm/mach-jz4750d/serial.h>
+#include <asm/mach-jz4750d/i2c.h>
#endif /* __ASM_JZ4750_H__ */
diff --git a/arch/mips/include/asm/mach-jz4750d/regs.h b/arch/mips/include/asm/mach-jz4750d/regs.h
index fd8e46c99ba..f612aa9b208 100644
--- a/arch/mips/include/asm/mach-jz4750d/regs.h
+++ b/arch/mips/include/asm/mach-jz4750d/regs.h
@@ -3256,145 +3256,200 @@
/*************************************************************************
* IPU (Image Processing Unit)
*************************************************************************/
-#define IPU_V_BASE 0xB3080000
-#define IPU_P_BASE 0x13080000
-
-/* Register offset */
-#define REG_CTRL 0x0 /* IPU Control Register */
-#define REG_STATUS 0x4 /* IPU Status Register */
-#define REG_D_FMT 0x8 /* Data Format Register */
-#define REG_Y_ADDR 0xc /* Input Y or YUV422 Packaged Data Address Register */
-#define REG_U_ADDR 0x10 /* Input U Data Address Register */
-#define REG_V_ADDR 0x14 /* Input V Data Address Register */
-#define REG_IN_FM_GS 0x18 /* Input Geometric Size Register */
-#define REG_Y_STRIDE 0x1c /* Input Y Data Line Stride Register */
-#define REG_UV_STRIDE 0x20 /* Input UV Data Line Stride Register */
-#define REG_OUT_ADDR 0x24 /* Output Frame Start Address Register */
-#define REG_OUT_GS 0x28 /* Output Geometric Size Register */
-#define REG_OUT_STRIDE 0x2c /* Output Data Line Stride Register */
-#define REG_RSZ_COEF_INDEX 0x30 /* Resize Coefficients Table Index Register */
-#define REG_CSC_CO_COEF 0x34 /* CSC C0 Coefficient Register */
-#define REG_CSC_C1_COEF 0x38 /* CSC C1 Coefficient Register */
-#define REG_CSC_C2_COEF 0x3c /* CSC C2 Coefficient Register */
-#define REG_CSC_C3_COEF 0x40 /* CSC C3 Coefficient Register */
-#define REG_CSC_C4_COEF 0x44 /* CSC C4 Coefficient Register */
-#define HRSZ_LUT_BASE 0x48 /* Horizontal Resize Coefficients Look Up Table Register group */
-#define VRSZ_LUT_BASE 0x4c /* Virtical Resize Coefficients Look Up Table Register group */
-#define REG_CSC_OFSET_PARA 0x50 /* CSC Offset Parameter Register */
-#define REG_Y_PHY_T_ADDR 0x54 /* Input Y Physical Table Address Register */
-#define REG_U_PHY_T_ADDR 0x58 /* Input U Physical Table Address Register */
-#define REG_V_PHY_T_ADDR 0x5c /* Input V Physical Table Address Register */
-#define REG_OUT_PHY_T_ADDR 0x60 /* Output Physical Table Address Register */
-
-/* REG_CTRL: IPU Control Register */
-#define IPU_CE_SFT 0x0
-#define IPU_CE_MSK 0x1
-#define IPU_RUN_SFT 0x1
-#define IPU_RUN_MSK 0x1
-#define HRSZ_EN_SFT 0x2
-#define HRSZ_EN_MSK 0x1
-#define VRSZ_EN_SFT 0x3
-#define VRSZ_EN_MSK 0x1
-#define CSC_EN_SFT 0x4
-#define CSC_EN_MSK 0x1
-#define FM_IRQ_EN_SFT 0x5
-#define FM_IRQ_EN_MSK 0x1
-#define IPU_RST_SFT 0x6
-#define IPU_RST_MSK 0x1
-#define H_SCALE_SFT 0x8
-#define H_SCALE_MSK 0x1
-#define V_SCALE_SFT 0x9
-#define V_SCALE_MSK 0x1
-#define PKG_SEL_SFT 0xA
-#define PKG_SEL_MSK 0x1
-#define LCDC_SEL_SFT 0xB
-#define LCDC_SEL_MSK 0x1
-#define SPAGE_MAP_SFT 0xC
-#define SPAGE_MAP_MSK 0x1
-#define DPAGE_SEL_SFT 0xD
-#define DPAGE_SEL_MSK 0x1
-#define DISP_SEL_SFT 0xE
-#define DISP_SEL_MSK 0x1
-#define FIELD_CONF_EN_SFT 15
-#define FIELD_CONF_EN_MSK 1
-#define FIELD_SEL_SFT 16
-#define FIELD_SEL_MSK 1
-#define DFIX_SEL_SFT 17
-#define DFIX_SEL_MSK 1
-
-/* REG_STATUS: IPU Status Register */
-#define OUT_END_SFT 0x0
-#define OUT_END_MSK 0x1
-#define FMT_ERR_SFT 0x1
-#define FMT_ERR_MSK 0x1
-#define SIZE_ERR_SFT 0x2
-#define SIZE_ERR_MSK 0x1
-
-/* D_FMT: Data Format Register */
-#define IN_FMT_SFT 0x0
-#define IN_FMT_MSK 0x3
-#define IN_OFT_SFT 0x2
-#define IN_OFT_MSK 0x3
-#define YUV_PKG_OUT_SFT 0x10
-#define YUV_PKG_OUT_MSK 0x7
-#define OUT_FMT_SFT 0x13
-#define OUT_FMT_MSK 0x3
-#define RGB_OUT_OFT_SFT 0x15
-#define RGB_OUT_OFT_MSK 0x7
-#define RGB888_FMT_SFT 0x18
-#define RGB888_FMT_MSK 0x1
-
-/* IN_FM_GS: Input Geometric Size Register */
-#define IN_FM_H_SFT 0x0
-#define IN_FM_H_MSK 0xFFF
-#define IN_FM_W_SFT 0x10
-#define IN_FM_W_MSK 0xFFF
-
-/* Y_STRIDE: Input Y Data Line Stride Register */
-#define Y_S_SFT 0x0
-#define Y_S_MSK 0x3FFF
-
-/* UV_STRIDE: Input UV Data Line Stride Register */
-#define V_S_SFT 0x0
-#define V_S_MSK 0x1FFF
-#define U_S_SFT 0x10
-#define U_S_MSK 0x1FFF
-
-/* OUT_GS: Output Geometric Size Register */
-#define OUT_FM_H_SFT 0x0
-#define OUT_FM_H_MSK 0x1FFF
-#define OUT_FM_W_SFT 0x10
-#define OUT_FM_W_MSK 0x7FFF
-
-/* OUT_STRIDE: Output Data Line Stride Register */
-#define OUT_S_SFT 0x0
-#define OUT_S_MSK 0xFFFF
-
-/* RSZ_COEF_INDEX: Resize Coefficients Table Index Register */
-#define VE_IDX_SFT 0x0
-#define VE_IDX_MSK 0x1F
-#define HE_IDX_SFT 0x10
-#define HE_IDX_MSK 0x1F
-
-/* CSC_CX_COEF: CSC CX Coefficient Register */
-#define CX_COEF_SFT 0x0
-#define CX_COEF_MSK 0xFFF
-
-/* HRSZ_LUT_BASE, VRSZ_LUT_BASE: Resize Coefficients Look Up Table Register group */
-#define LUT_LEN 20
-
-#define OUT_N_SFT 0x0
-#define OUT_N_MSK 0x1
-#define IN_N_SFT 0x1
-#define IN_N_MSK 0x1
-#define W_COEF_SFT 0x2
-#define W_COEF_MSK 0x3FF
-
-/* CSC_OFSET_PARA: CSC Offset Parameter Register */
-#define CHROM_OF_SFT 0x10
-#define CHROM_OF_MSK 0xFF
-#define LUMA_OF_SFT 0x00
-#define LUMA_OF_MSK 0xFF
+/* IPU Control Register */
+#define REG_IPU_CTRL (IPU_BASE + 0x0)
+
+/* IPU Status Register */
+#define REG_IPU_STATUS (IPU_BASE + 0x4)
+
+/* Data Format Register */
+#define REG_IPU_D_FMT (IPU_BASE + 0x8)
+
+/* Input Y or YUV422 Packaged Data Address Register */
+#define REG_IPU_Y_ADDR (IPU_BASE + 0xc)
+
+/* Input U Data Address Register */
+#define REG_IPU_U_ADDR (IPU_BASE + 0x10)
+
+/* Input V Data Address Register */
+#define REG_IPU_V_ADDR (IPU_BASE + 0x14)
+
+/* Input Geometric Size Register */
+#define REG_IPU_IN_FM_GS (IPU_BASE + 0x18)
+
+/* Input Y Data Line Stride Register */
+#define REG_IPU_Y_STRIDE (IPU_BASE + 0x1c)
+
+/* Input UV Data Line Stride Register */
+#define REG_IPU_UV_STRIDE (IPU_BASE + 0x20)
+
+/* Output Frame Start Address Register */
+#define REG_IPU_OUT_ADDR (IPU_BASE + 0x24)
+
+/* Output Geometric Size Register */
+#define REG_IPU_OUT_GS (IPU_BASE + 0x28)
+
+/* Output Data Line Stride Register */
+#define REG_IPU_OUT_STRIDE (IPU_BASE + 0x2c)
+
+/* Resize Coefficients Table Index Register */
+#define REG_IPU_RSZ_COEF_INDEX (IPU_BASE + 0x30)
+
+/* CSC C0 Coefficient Register */
+#define REG_IPU_CSC_CO_COEF (IPU_BASE + 0x34)
+
+/* CSC C1 Coefficient Register */
+#define REG_IPU_CSC_C1_COEF (IPU_BASE + 0x38)
+
+/* CSC C2 Coefficient Register */
+#define REG_IPU_CSC_C2_COEF (IPU_BASE + 0x3c)
+
+/* CSC C3 Coefficient Register */
+#define REG_IPU_CSC_C3_COEF (IPU_BASE + 0x40)
+
+/* CSC C4 Coefficient Register */
+#define REG_IPU_CSC_C4_COEF (IPU_BASE + 0x44)
+
+/* Horizontal Resize Coefficients Look Up Table Register group */
+#define REG_IPU_HRSZ_LUT_BASE (IPU_BASE + 0x48)
+
+/* Virtical Resize Coefficients Look Up Table Register group */
+#define REG_IPU_VRSZ_LUT_BASE (IPU_BASE + 0x4c)
+
+/* CSC Offset Parameter Register */
+#define REG_IPU_CSC_OFSET_PARA (IPU_BASE + 0x50)
+
+/* Input Y Physical Table Address Register */
+#define REG_IPU_Y_PHY_T_ADDR (IPU_BASE + 0x54)
+
+/* Input U Physical Table Address Register */
+#define REG_IPU_U_PHY_T_ADDR (IPU_BASE + 0x58)
+
+/* Input V Physical Table Address Register */
+#define REG_IPU_V_PHY_T_ADDR (IPU_BASE + 0x5c)
+
+/* Output Physical Table Address Register */
+#define REG_IPU_OUT_PHY_T_ADDR (IPU_BASE + 0x60)
+
+/* IPU Control */
+#define IPU_CTRL_DFIX_SEL (1 << 17)
+#define IPU_CTRL_FIELD_SEL (1 << 16)
+#define IPU_CTRL_FIELD_CONF_EN (1 << 15)
+#define IPU_CTRL_DISP_SEL (1 << 14)
+#define IPU_CTRL_DPAGE_MAP (1 << 13)
+#define IPU_CTRL_SPAGE_MAP (1 << 12)
+#define IPU_CTRL_LCDC_SEL (1 << 11)
+#define IPU_CTRL_SPKG_SEL (1 << 10)
+#define IPU_CTRL_V_SCALE (1 << 9)
+#define IPU_CTRL_H_SCALE (1 << 8)
+#define IPU_CTRL_IPU_RST (1 << 6)
+#define IPU_CTRL_FM_IRQ_EN (1 << 5)
+#define IPU_CTRL_CSC_EN (1 << 4)
+#define IPU_CTRL_VRSZ_EN (1 << 3)
+#define IPU_CTRL_HRSZ_EN (1 << 2)
+#define IPU_CTRL_IPU_RUN (1 << 1)
+#define IPU_CTRL_CHIP_EN (1 << 0)
+
+/* IPU Status */
+#define IPU_STAT_SIZE_ERR (1 << 2)
+#define IPU_STAT_FMT_ERR (1 << 1)
+#define IPU_STAT_OUT_END (1 << 0)
+
+/* IPU Data Format */
+#define IPU_D_FMT_RGB_OUT_888_FMT (1 << 24)
+
+#define IPU_D_FMT_RGB_OUT_OFT_MASK (0x7 << 21)
+
+#define IPU_D_FMT_RGB_OUT_OFT_RGB (0 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_RBG (1 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_GBR (2 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_GRB (3 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_BRG (4 << 21)
+#define IPU_D_FMT_RGB_OUT_OFT_BGR (5 << 21)
+
+#define IPU_D_FMT_OUT_FMT_MASK (0x3 << 19)
+
+#define IPU_D_FMT_OUT_FMT_RGB555 (0 << 19)
+#define IPU_D_FMT_OUT_FMT_RGB565 (1 << 19)
+#define IPU_D_FMT_OUT_FMT_RGB888 (2 << 19)
+#define IPU_D_FMT_OUT_FMT_YUV422 (3 << 19)
+
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_MASK (0x7 << 16)
+
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y1UY0V (0 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y1VY0U (1 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_UY1VY0 (2 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_VY1UY0 (3 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y0UY1V (4 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_Y0VY1U (5 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_UY0VY1 (6 << 16)
+#define IPU_D_FMT_YUV_PKG_OUT_OFT_VY0UY1 (7 << 16)
+
+#define IPU_D_FMT_IN_OFT_MASK (0x3 << 2)
+
+#define IPU_D_FMT_IN_OFT_Y1UY0V (0 << 2)
+#define IPU_D_FMT_IN_OFT_Y1VY0U (1 << 2)
+#define IPU_D_FMT_IN_OFT_UY1VY0 (2 << 2)
+#define IPU_D_FMT_IN_OFT_VY1UY0 (3 << 2)
+
+#define IPU_D_FMT_IN_FMT_MASK (0x3 << 0)
+
+#define IPU_D_FMT_IN_FMT_YUV420 (0 << 0)
+#define IPU_D_FMT_IN_FMT_YUV422 (1 << 0)
+#define IPU_D_FMT_IN_FMT_YUV444 (2 << 0)
+#define IPU_D_FMT_IN_FMT_YUV411 (3 << 0)
+
+/* Input Geometric Size Register */
+#define IPU_IN_FM_GS_W_MASK (0xFFF)
+#define IPU_IN_FM_GS_W(n) ((n) << 16)
+
+#define IPU_IN_FM_GS_H_MASK (0xFFF)
+#define IPU_IN_FM_GS_H(n) ((n) << 0)
+
+/* Input UV Data Line Stride Register */
+#define IPU_UV_STRIDE_U_S_MASK (0x1FFF)
+#define IPU_UV_STRIDE_U_S(n) ((n) << 16)
+
+#define IPU_UV_STRIDE_V_S_MASK (0x1FFF)
+#define IPU_UV_STRIDE_V_S(n) ((n) << 0)
+
+/* Output Geometric Size Register */
+#define IPU_OUT_GS_W_MASK (0x7FFF)
+#define IPU_OUT_GS_W(n) ((n) << 16)
+
+#define IPU_OUT_GS_H_MASK (0x1FFF)
+#define IPU_OUT_GS_H(n) ((n) << 0)
+
+/* Resize Coefficients Table Index Register */
+#define IPU_RSZ_COEF_INDEX_HE_IDX_MASK (0x1F)
+#define IPU_RSZ_COEF_INDEX_HE_IDX(n) ((n) << 16)
+
+#define IPU_RSZ_COEF_INDEX_VE_IDX_MASK (0x1F)
+#define IPU_RSZ_COEF_INDEX_VE_IDX(n) ((n) << 0)
+
+/* Resize Coefficients Look Up Table Register group */
+#define IPU_HRSZ_COEF_LUT_START (1 << 12)
+
+#define IPU_HRSZ_COEF_LUT_W_COEF_MASK (0x3FF)
+#define IPU_HRSZ_COEF_LUT_W_COEF(n) ((n) << 2)
+
+#define IPU_HRSZ_COEF_LUT_IN_EN (1 << 1)
+#define IPU_HRSZ_COEF_LUT_OUT_EN (1 << 0)
+
+#define IPU_VRSZ_COEF_LUT_START (1 << 12)
+
+#define IPU_VRSZ_COEF_LUT_W_COEF_MASK (0x3FF)
+#define IPU_VRSZ_COEF_LUT_W_COEF(n) ((n) << 2)
+
+#define IPU_VRSZ_COEF_LUT_IN_EN (1 << 1)
+#define IPU_VRSZ_COEF_LUT_OUT_EN (1 << 0)
+
+/* CSC Offset Parameter Register */
+#define IPU_CSC_OFFSET_PARA_CHROM_OF_MASK (0xFF)
+#define IPU_CSC_OFFSET_PARA_CHROM_OF(n) ((n) << 16)
+
+#define IPU_CSC_OFFSET_LUMA_OF_MASK (0xFF)
+#define IPU_CSC_OFFSET_LUMA_OF(n) ((n) << 0)
#endif /* __JZ4750D_REGS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/board-altair.h b/arch/mips/include/asm/mach-jz4760/board-altair.h
new file mode 100644
index 00000000000..f7f5f4a00a3
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/board-altair.h
@@ -0,0 +1,216 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/board-altair.h
+ *
+ * JZ4760-based ALTAIR board definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Inc.
+ *
+ * Author: Jason<xwang@ingenic.cn>
+ * Based on board-aquila.h
+ *
+ * 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_JZ4760_ALTAIR_H__
+#define __ASM_JZ4760_ALTAIR_H__
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 12000000 /* Main extal freq: 24 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+
+#define __GPIO(p, n) (32 * (p - 'A') + n)
+
+/*======================================================================
+ * SYSTEM GPIO
+ */
+#define GPIO_DISP_OFF_N (32 * 3 + 17) /* GPD17 */
+
+#define GPIO_SD0_VCC_EN_N (32 * 1 + 22) /* GPB22 */
+#define GPIO_SD0_WP_N (32 * 1 + 23) /* GPB23 */
+#define GPIO_SD0_CD_N (32 * 1 + 24) /* GPB24 */
+
+#define GPIO_SD1_VCC_EN_N (32 * 1 + 2) /* GPB02 */
+#define GPIO_SD1_CD_N (32 * 1 + 3) /* GPB03 */
+
+#define GPIO_USB_DETE __GPIO('B', 4)
+
+#define GPIO_LCD_PWM (32 * 4 + 1) /* GPE01 */
+
+#define GPIO_AMPEN_N (32 * 4 + 11) /* GPE11 */
+
+#define GPIO_BOOT_SEL0 (32 * 3 + 17) /* GPD17 */
+#define GPIO_BOOT_SEL1 (32 * 3 + 18) /* GPD18 */
+#define GPIO_BOOT_SEL2 (32 * 3 + 19) /* GPD19 */
+
+#define GPIO_WM831x_DETECT (32 * 1 + 5) /* GPB5 */
+
+/*====================================================================
+ * KEYPAD
+ */
+#define KEY_C0 (32 * 4 + 8) //GPE08
+#define KEY_C1 (32 * 4 + 9) //GPE09
+#define KEY_C2 (32 * 5 + 4) //GPF04
+#define KEY_C3 (32 * 5 + 5) //GPF05
+#define KEY_C4 (32 * 5 + 6) //GPF06
+
+#define KEY_R0 (32 * 5 + 7) //GPF07
+#define KEY_R1 (32 * 5 + 8) //GPF08
+#define KEY_R2 (32 * 5 + 9) //GPF09
+#define KEY_R3 (32 * 5 + 10) //GPF10
+#define KEY_R4 (32 * 5 + 11) //GPF11
+
+//keycode for android
+#define KEY_CENTER 232
+#define KEY_CALL 231
+#define KEY_POUND 228
+#define KEY_STAR 227
+
+/*======================================================================
+ * Analog input for VBAT is the battery voltage divided by CFG_PBAT_DIV.
+ */
+//#define CFG_PBAT_DIV 4
+
+/*
+ * M-T4D touchscreen
+ */
+#define LCD_INT (32 * 0 + 16) /* GPA16 interrupt pin */
+#define LCD_INT_IRQ (IRQ_GPIO_0 + LCD_INT)
+
+/*
+ * E-Compass and G-Sensor
+ */
+#define COMPASS_RSTN (32*3+5) /* GPD5 */
+#define COMPASS_INTR (32*3+4) /* GPD4 */
+#define COMPASS_INT_IRQ (IRQ_GPIO_0 + COMPASS_INTR) /* irq number */
+
+#define SENSOR_INT1 (32*4+26) /* GPE26 */
+#define SENSOR_INT2 (32*4+27) /* GPE27 */
+#define SENSOR_INT1_IRQ (IRQ_GPIO_0 + SENSOR_INT1) /* irq number */
+
+/*
+ * Used for GPIO-based bitbanging I2C
+ */
+#define IOSWITCH_EN (32*4+6) /* GPE6 */
+#define CIM_I2C_SCK (32*5+2) /* GPF2 */
+#define CIM_I2C_SDA (32*5+1) /* GPF1 */
+
+
+/*======================================================================
+ * MMC/SD
+ */
+#define MSC1_HOTPLUG_PIN GPIO_SD1_CD_N
+#define MSC1_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD1_CD_N)
+
+/*======================================================================
+ * Modem
+ */
+#if defined(CONFIG_GSM_IW368)
+#define GPIO_GSM_ONOFF (32 * 1 + 25)
+#define GPIO_GSM_PWR_STATUS (32 * 0 + 28)
+#define GPIO_GSM_RI (32 * 3 + 8) /* GPD08, waking cpu from sleep when a call comes in. */
+#define GPIO_GSM_RI_ACK (32 * 0 + 29) /* GPA29, notify baseband not to send data to cpu when cpu is sleeping. */
+#define GPIO_GSM_WAKE (32 * 1 + 27) /* GPB27 */
+#define GPIO_GSM_WAKE_ACK (32 * 1 + 30) /* GPB30 */
+#endif
+
+#if defined(CONFIG_TDSCDMA_LC6311)
+#define GPIO_TD_POWERON (32 * 3 + 9)
+#define GPIO_TD_RESET (32 * 3 + 19) /* shared with boot_sel2 */
+#endif
+
+/*======================================================================
+ * LCD backlight
+ */
+#define LCD_PWM_CHN 4 /* pwm channel */
+#define LCD_PWM_FULL 256
+#define PWM_BACKLIGHT_CHIP 0 /*0: digital pusle; 1: PWM*/
+
+#if 1 // temporarily
+#if PWM_BACKLIGHT_CHIP
+
+#define __lcd_init_backlight(n) \
+do { \
+} while (0)
+
+/* 100 level: 0,1,...,100 */
+#define __lcd_set_backlight_level(n) \
+do { \
+ __gpio_as_pwm(4); \
+ __tcu_disable_pwm_output(LCD_PWM_CHN); \
+ __tcu_stop_counter(LCD_PWM_CHN); \
+ __tcu_init_pwm_output_high(LCD_PWM_CHN); \
+ __tcu_set_pwm_output_shutdown_abrupt(LCD_PWM_CHN); \
+ __tcu_select_clk_div1(LCD_PWM_CHN); \
+ __tcu_mask_full_match_irq(LCD_PWM_CHN); \
+ __tcu_mask_half_match_irq(LCD_PWM_CHN); \
+ __tcu_set_count(LCD_PWM_CHN,0); \
+ __tcu_set_full_data(LCD_PWM_CHN, __cpm_get_extalclk() / 30000);\
+ __tcu_set_half_data(LCD_PWM_CHN, __cpm_get_extalclk() / 30000 * n / (LCD_PWM_FULL - 1));\
+ __tcu_enable_pwm_output(LCD_PWM_CHN); \
+ __tcu_select_extalclk(LCD_PWM_CHN); \
+ __tcu_start_counter(LCD_PWM_CHN); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#else /* PWM_BACKLIGHT_CHIP */
+
+#define __send_low_pulse(n) \
+do { \
+ unsigned int i; \
+ for (i = n; i > 0; i--) { \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+ udelay(1); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(3); \
+ } \
+} while (0)
+
+#define MAX_BRIGHTNESS_STEP 16 /* RT9365 supports 16 brightness step */
+#define CONVERT_FACTOR (256/MAX_BRIGHTNESS_STEP) /* System support 256 brightness step */
+
+#define __lcd_init_backlight(n) \
+do { \
+ unsigned int tmp = (n)/CONVERT_FACTOR + 1; \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(30); \
+ __send_low_pulse(MAX_BRIGHTNESS_STEP-tmp); \
+} while (0)
+
+#define __lcd_set_backlight_level(n) \
+do { \
+ unsigned int last = lcd_backlight_level / CONVERT_FACTOR + 1; \
+ unsigned int tmp = (n) / CONVERT_FACTOR + 1; \
+ if (tmp <= last) { \
+ __send_low_pulse(last-tmp); \
+ } else { \
+ __send_low_pulse(last + MAX_BRIGHTNESS_STEP - tmp); \
+ } \
+ udelay(30); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#endif /*PWM_BACKLIGHT_CHIP*/
+#endif // if 0
+
+/*
+ * The key interrupt pin is low voltage or fall edge acitve
+ */
+#define ACTIVE_LOW_MSC0_CD 1 /* work when GPIO_SD1_CD_N is low */
+#define ACTIVE_LOW_MSC1_CD 0 /* work when GPIO_SD1_CD_N is low */
+
+#endif /* __ASM_JZ4760_ALTAIR_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/board-cygnus.h b/arch/mips/include/asm/mach-jz4760/board-cygnus.h
new file mode 100644
index 00000000000..eec766d750f
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/board-cygnus.h
@@ -0,0 +1,193 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/board-cygnus.h
+ *
+ * JZ4760-based CYGNUS board ver 1.0 definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Inc.
+ *
+ * Author: Jason<xwang@ingenic.cn>
+ * Based on board-f4760.h
+ *
+ * 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_JZ4760_CYGNUS_H__
+#define __ASM_JZ4760_CYGNUS_H__
+
+#define CYGNUS_CPU_V1_0 0
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+
+/*======================================================================
+ * SYSTEM GPIO
+ */
+#define GPIO_DISP_OFF_N (32 * 4 + 11) /* GPE11 */ //???
+
+#define GPIO_SD0_VCC_EN_N (32 * 4 + 2) /* GPE02 */
+#define GPIO_SD0_CD_N (32 * 5 + 6) /* GPF06 */
+#define GPIO_SD0_WP_N (32 * 1 + 8) /* GPB08 */
+#define GPIO_SD1_VCC_EN_N (32 * 1 + 16) /* GPB16 */
+#define GPIO_SD1_CD_N (32 * 1 + 15) /* GPB15 */
+#define GPIO_SD1_WP_N (32 * 1 + 6) /* GPB06 */
+
+#define GPIO_USB_DETE (32 * 4 + 19) /* GPE19 */
+
+#define GPIO_LCD_PWM (32 * 4 + 1) /* GPE01 */
+//#define GPIO_LCD_VCC_EN_N (32 * 1 + 31) /* GPB31 */
+
+#define GPIO_BOOT_SEL0 (32 * 3 + 17) /* GPD17 */
+#define GPIO_BOOT_SEL1 (32 * 3 + 18) /* GPD18 */
+#define GPIO_BOOT_SEL2 (32 * 3 + 19) /* GPD19 */
+
+/* Ethernet: WE#, RD#, CS5# */
+#define GPIO_NET_INT (32 * 5 + 5) /* GPF5 */
+
+#define GPIO_GSM_RI (32 * 3 + 8) /* GPD08, waking cpu from sleep when a call comes in. */
+#define GPIO_GSM_RI_ACK (32 * 0 + 29) /* GPA29, notify baseband not to send data to cpu when cpu is sleeping. */
+#define GPIO_GSM_WAKE (32 * 1 + 27) /* GPB27 */
+#define GPIO_GSM_WAKE_ACK (32 * 1 + 30) /* GPB30 */
+
+#define GPIO_WM831x_DETECT (32 * 1 + 5) /* GPB5 */
+
+/*====================================================================
+ * KEYPAD
+ */
+#define KEY_C0 (32 * 4 + 8) //GPE08
+#define KEY_C1 (32 * 4 + 9) //GPE09
+#define KEY_C2 (32 * 5 + 4) //GPF04
+#define KEY_C3 (32 * 5 + 5) //GPF05
+#define KEY_C4 (32 * 5 + 6) //GPF06
+
+#define KEY_R0 (32 * 5 + 7) //GPF07
+#define KEY_R1 (32 * 5 + 8) //GPF08
+#define KEY_R2 (32 * 5 + 9) //GPF09
+#define KEY_R3 (32 * 5 + 10) //GPF10
+#define KEY_R4 (32 * 5 + 11) //GPF11
+
+//keycode for android
+#define KEY_CENTER 232
+#define KEY_CALL 231
+#define KEY_POUND 228
+#define KEY_STAR 227
+
+/*======================================================================
+ * Analog input for VBAT is the battery voltage divided by CFG_PBAT_DIV.
+ */
+//#define CFG_PBAT_DIV 4
+
+/*
+ * M-T4D touchscreen
+ */
+//#define LCD_INT (32*2+20) /* WAIT_N GPC20 interrupt pin */
+//#define IOSWITCH (32*5+23) /* GPF23 */
+
+
+/*======================================================================
+ * MMC/SD
+ */
+#define MSC0_WP_PIN GPIO_SD0_WP_N
+#define MSC0_HOTPLUG_PIN GPIO_SD0_CD_N
+#define MSC0_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD0_CD_N)
+
+#define MSC1_WP_PIN GPIO_SD1_WP_N
+#define MSC1_HOTPLUG_PIN GPIO_SD1_CD_N
+#define MSC1_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD1_CD_N)
+
+/*======================================================================
+ * LCD backlight
+ */
+#define LCD_PWM_CHN 4 /* pwm channel */
+#define LCD_PWM_FULL 256
+#define PWM_BACKLIGHT_CHIP 0 /*0: digital pusle; 1: PWM*/
+
+#if 1
+#if PWM_BACKLIGHT_CHIP
+
+#define __lcd_init_backlight(n) \
+do { \
+} while (0)
+
+/* 100 level: 0,1,...,100 */
+#define __lcd_set_backlight_level(n) \
+do { \
+ __gpio_as_pwm(4); \
+ __tcu_disable_pwm_output(LCD_PWM_CHN); \
+ __tcu_stop_counter(LCD_PWM_CHN); \
+ __tcu_init_pwm_output_high(LCD_PWM_CHN); \
+ __tcu_set_pwm_output_shutdown_abrupt(LCD_PWM_CHN); \
+ __tcu_select_clk_div1(LCD_PWM_CHN); \
+ __tcu_mask_full_match_irq(LCD_PWM_CHN); \
+ __tcu_mask_half_match_irq(LCD_PWM_CHN); \
+ __tcu_set_count(LCD_PWM_CHN,0); \
+ __tcu_set_full_data(LCD_PWM_CHN, __cpm_get_extalclk() / 30000);\
+ __tcu_set_half_data(LCD_PWM_CHN, __cpm_get_extalclk() / 30000 * n / (LCD_PWM_FULL - 1));\
+ __tcu_enable_pwm_output(LCD_PWM_CHN); \
+ __tcu_select_extalclk(LCD_PWM_CHN); \
+ __tcu_start_counter(LCD_PWM_CHN); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#else /* PWM_BACKLIGHT_CHIP */
+
+#define __send_low_pulse(n) \
+do { \
+ unsigned int i; \
+ for (i = n; i > 0; i--) { \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+ udelay(1); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(3); \
+ } \
+} while (0)
+
+#define MAX_BRIGHTNESS_STEP 16 /* RT9365 supports 16 brightness step */
+#define CONVERT_FACTOR (256/MAX_BRIGHTNESS_STEP) /* System support 256 brightness step */
+
+#define __lcd_init_backlight(n) \
+do { \
+ unsigned int tmp = (n)/CONVERT_FACTOR + 1; \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(30); \
+ __send_low_pulse(MAX_BRIGHTNESS_STEP-tmp); \
+} while (0)
+
+#define __lcd_set_backlight_level(n) \
+do { \
+ unsigned int last = lcd_backlight_level / CONVERT_FACTOR + 1; \
+ unsigned int tmp = (n) / CONVERT_FACTOR + 1; \
+ if (tmp <= last) { \
+ __send_low_pulse(last-tmp); \
+ } else { \
+ __send_low_pulse(last + MAX_BRIGHTNESS_STEP - tmp); \
+ } \
+ udelay(30); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#endif /*PWM_BACKLIGHT_CHIP*/
+#endif // if 0
+
+/*
+ * The key interrupt pin is low voltage or fall edge acitve
+ */
+#define ACTIVE_LOW_MSC0_CD 1 /* work when GPIO_SD1_CD_N is low */
+#define ACTIVE_LOW_MSC1_CD 0 /* work when GPIO_SD1_CD_N is low */
+
+#endif /* __ASM_JZ4760_CYGNUS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/board-f4760.h b/arch/mips/include/asm/mach-jz4760/board-f4760.h
new file mode 100644
index 00000000000..f58e9a69af0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/board-f4760.h
@@ -0,0 +1,93 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/board-f4760.h
+ *
+ * JZ4760-based F4760 board ver 1.x definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4760_F4760_H__
+#define __ASM_JZ4760_F4760_H__
+
+#define CONFIG_FPGA /* fuwa is an FPGA board */
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 24000000 /* Main extal freq: 12 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+#define CFG_DIV 2 /* cpu/extclk; only for FPGA */
+
+/*======================================================================
+ * GPIO
+ */
+#define GPIO_SD_VCC_EN_N 113 /* GPD17 */
+#define GPIO_SD_CD_N 110 /* GPD14 */
+#define GPIO_SD_WP 112 /* GPD16 */
+#define GPIO_USB_DETE 102 /* GPD6 */
+#define GPIO_DC_DETE_N 103 /* GPD7 */
+#define GPIO_CHARG_STAT_N 111 /* GPD15 */
+#define GPIO_DISP_OFF_N 121 /* GPD25, LCD_REV */
+//#define GPIO_LED_EN 124 /* GPD28 */
+
+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE
+
+/*======================================================================
+ * LCD backlight
+ */
+#define GPIO_LCD_PWM (32*4+4) /* GPE4 PWM4 */
+
+#define LCD_PWM_CHN 4 /* pwm channel */
+#define LCD_PWM_FULL 101
+/* 100 level: 0,1,...,100 */
+#define __lcd_set_backlight_level(n) \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+/*======================================================================
+ * MMC/SD
+ */
+
+#define MSC_WP_PIN GPIO_SD_WP
+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N
+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N)
+
+#define __msc_init_io() \
+do { \
+ __gpio_as_output(GPIO_SD_VCC_EN_N); \
+ __gpio_as_input(GPIO_SD_CD_N); \
+} while (0)
+
+#define __msc_enable_power() \
+do { \
+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_disable_power() \
+do { \
+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_card_detected(s) \
+({ \
+ int detected = 1; \
+ if (__gpio_get_pin(GPIO_SD_CD_N)) \
+ detected = 0; \
+ detected; \
+})
+
+#endif /* __ASM_JZ4760_F4760_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/board-lepus.h b/arch/mips/include/asm/mach-jz4760/board-lepus.h
new file mode 100644
index 00000000000..3db15a6cc9f
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/board-lepus.h
@@ -0,0 +1,267 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/board-lepus.h
+ *
+ * JZ4760-based LEPUS board ver 1.0 definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Inc.
+ *
+ * Author: James<ljia@ingenic.cn>
+ * Based on board-cygnus.h
+ *
+ * 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_JZ4760_LEPUS_H__
+#define __ASM_JZ4760_LEPUS_H__
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 12000000 /* Main extal freq: 12 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+
+/*======================================================================
+ * SYSTEM GPIO
+ */
+#define GPIO_DISP_OFF_N (32 * 5 + 6) /* GPF6 */ //???
+
+#define GPIO_SD0_VCC_EN_N (32 * 5 + 9) /* GPF9 */
+#define GPIO_SD0_CD_N (32 * 1 + 22) /* GPB22 */
+#define GPIO_SD0_WP_N (32 * 5 + 4) /* GPF4 */
+#define GPIO_SD1_VCC_EN_N (32 * 4 + 9) /* GPE9 */
+#define GPIO_SD1_CD_N (32 * 0 + 28) /* GPA28 */
+
+#define GPIO_USB_DETE (32 * 4 + 19) /* GPE19 */
+
+#define GPIO_LCD_PWM (32 * 4 + 1) /* GPE01 */
+#define GPIO_LCD_VCC_EN_N (32 * 1 + 31) /* GPB31 */
+
+#define GPIO_BOOT_SEL0 (32 * 3 + 17) /* GPD17 */
+#define GPIO_BOOT_SEL1 (32 * 3 + 18) /* GPD18 */
+#define GPIO_BOOT_SEL2 (32 * 3 + 19) /* GPD19 */
+
+/* Ethernet: WE#, RD#, CS5# */
+#define GPIO_NET_INT (32 * 5 + 5) /* GPF5 */
+
+#define GPIO_GSM_RI (32 * 3 + 8) /* GPD08, waking cpu from sleep when a call comes in. */
+#define GPIO_GSM_RI_ACK (32 * 0 + 29) /* GPA29, notify baseband not to send data to cpu when cpu is sleeping. */
+#define GPIO_GSM_WAKE (32 * 1 + 27) /* GPB27 */
+#define GPIO_GSM_WAKE_ACK (32 * 1 + 30) /* GPB30 */
+
+#define GPIO_POWER_ON (32 * 0 + 30) /* GPA30 */
+
+/*====================================================================
+ * GPIO KEYS and ADKEYS (GPIO_WAKEUP used for end call)
+ */
+#define GPIO_HOME (32 * 2 + 29) // SW3-GPC29
+#define GPIO_MENU (32 * 3 + 19) // SW6-boot_sel2-GPD19
+#define GPIO_CALL (32 * 2 + 31) // SW1-GPC31
+#define GPIO_BACK (32 * 3 + 27) // SW4-GPD27
+#define GPIO_ENDCALL (32 * 0 + 30) // WAKEUP-GPA30
+#define GPIO_VOLUMEDOWN (32 * 3 + 18) // SW7-boot_sel1-GPD18
+#define GPIO_VOLUMEUP (32 * 3 + 17) // SW8-boot_sel0-GPD17
+
+#define GPIO_ADKEY_INT (32 * 4 + 8) // GPE8
+
+/*====================================================================
+ * ADKEYS LEVEL
+ */
+#define DPAD_LEFT_LEVEL 186 //0.15V, 186=0.15/3.3*4096
+#define DPAD_DOWN_LEVEL 2482 //2.0V
+#define DPAD_UP_LEVEL 1985 //1.6V
+#define DPAD_CENTER_LEVEL 1489 //1.2V
+#define DPAD_RIGHT_LEVEL 868 //0.7V
+
+/*======================================================================
+ * Analog input for VBAT is the battery voltage divided by CFG_PBAT_DIV.
+ */
+//#define CFG_PBAT_DIV 4
+
+/*
+ * M-T4D touchscreen
+ */
+//#define LCD_INT (32*2+20) /* WAIT_N GPC20 interrupt pin */
+//#define IOSWITCH (32*5+23) /* GPF23 */
+
+
+/*======================================================================
+ * MMC/SD
+ */
+#define MSC0_WP_PIN GPIO_SD0_WP_N
+#define MSC0_HOTPLUG_PIN GPIO_SD0_CD_N
+#define MSC0_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD0_CD_N)
+
+#define MSC1_WP_PIN GPIO_SD1_WP_N
+#define MSC1_HOTPLUG_PIN GPIO_SD1_CD_N
+#define MSC1_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD1_CD_N)
+
+#define __msc0_init_io() \
+do { \
+ __gpio_as_output(GPIO_SD0_VCC_EN_N); \
+ __gpio_as_input(GPIO_SD0_CD_N); \
+} while (0)
+
+#define __msc0_enable_power() \
+do { \
+ __gpio_clear_pin(GPIO_SD0_VCC_EN_N); \
+} while (0)
+
+#define __msc0_disable_power() \
+do { \
+ __gpio_set_pin(GPIO_SD0_VCC_EN_N); \
+} while (0)
+
+#define __msc0_card_detected(s) \
+({ \
+ int detected = 1; \
+ if (__gpio_get_pin(GPIO_SD0_CD_N)) \
+ detected = 0; \
+ detected; \
+})
+
+#define __msc1_init_io() \
+do { \
+ __gpio_as_output(GPIO_SD1_VCC_EN_N); \
+ __gpio_as_input(GPIO_SD1_CD_N); \
+} while (0)
+
+#define __msc1_enable_power() \
+do { \
+ __gpio_clear_pin(GPIO_SD1_VCC_EN_N); \
+} while (0)
+
+#define __msc1_disable_power() \
+do { \
+ __gpio_set_pin(GPIO_SD1_VCC_EN_N); \
+} while (0)
+
+#define __msc1_card_detected(s) \
+({ \
+ int detected = 1; \
+ if (__gpio_get_pin(GPIO_SD1_CD_N)) \
+ detected = 0; \
+ detected; \
+})
+
+/*======================================================================
+ * LCD backlight
+ */
+#define LCD_PWM_CHN 1 /* pwm channel */
+#define LCD_PWM_FULL 256
+#define PWM_BACKLIGHT_CHIP 0 /*0: digital pusle; 1: PWM*/
+#define LCD_DEFAULT_BACKLIGHT 80
+#define LCD_MAX_BACKLIGHT 100
+#define LCD_MIN_BACKLIGHT 1
+
+#if 1
+#if PWM_BACKLIGHT_CHIP
+
+#define __lcd_init_backlight(n) \
+do { \
+ __lcd_set_backlight_level(n); \
+} while (0)
+
+/* 100 level: 0,1,...,100 */
+#define __lcd_set_backlight_level(n) \
+do { \
+ __gpio_as_pwm(1); \
+ __tcu_disable_pwm_output(LCD_PWM_CHN); \
+ __tcu_stop_counter(LCD_PWM_CHN); \
+ __tcu_init_pwm_output_high(LCD_PWM_CHN); \
+ __tcu_set_pwm_output_shutdown_abrupt(LCD_PWM_CHN); \
+ __tcu_select_clk_div1(LCD_PWM_CHN); \
+ __tcu_mask_full_match_irq(LCD_PWM_CHN); \
+ __tcu_mask_half_match_irq(LCD_PWM_CHN); \
+ __tcu_clear_counter_to_zero(LCD_PWM_CHN); \
+ __tcu_set_full_data(LCD_PWM_CHN, JZ_EXTAL / 30000); \
+ __tcu_set_half_data(LCD_PWM_CHN, JZ_EXTAL / 30000 * n / LCD_PWM_FULL); \
+ __tcu_enable_pwm_output(LCD_PWM_CHN); \
+ __tcu_select_extalclk(LCD_PWM_CHN); \
+ __tcu_start_counter(LCD_PWM_CHN); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#else /* PWM_BACKLIGHT_CHIP */
+
+#define __send_low_pulse(n) \
+do { \
+ unsigned int i; \
+ for (i = n; i > 0; i--) { \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+ udelay(1); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(3); \
+ } \
+} while (0)
+
+#define MAX_BRIGHTNESS_STEP 16 /* RT9365 supports 16 brightness step */
+#define CONVERT_FACTOR (256/MAX_BRIGHTNESS_STEP) /* System support 256 brightness step */
+
+#define __lcd_init_backlight(n) \
+do { \
+ unsigned int tmp = (n)/CONVERT_FACTOR + 1; \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+ udelay(30); \
+ __send_low_pulse(MAX_BRIGHTNESS_STEP-tmp); \
+} while (0)
+
+#define __lcd_set_backlight_level(n) \
+do { \
+ unsigned int last = lcd_backlight_level / CONVERT_FACTOR + 1; \
+ unsigned int tmp = (n) / CONVERT_FACTOR + 1; \
+ if (tmp <= last) { \
+ __send_low_pulse(last-tmp); \
+ } else { \
+ __send_low_pulse(last + MAX_BRIGHTNESS_STEP - tmp); \
+ } \
+ udelay(30); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#endif /*PWM_BACKLIGHT_CHIP*/
+#endif // if 0
+
+/*
+ * The key interrupt pin is low voltage or fall edge acitve
+ */
+#define ACTIVE_LOW_HOME 1
+#define ACTIVE_LOW_MENU 1
+#define ACTIVE_LOW_BACK 1
+#define ACTIVE_LOW_CALL 1
+#define ACTIVE_LOW_ENDCALL 1
+#define ACTIVE_LOW_VOLUMEDOWN 1
+#define ACTIVE_LOW_VOLUMEUP 1
+#define ACTIVE_LOW_ADKEY 1
+#define ACTIVE_WAKE_UP 1
+#define ACTIVE_LOW_MSC0_CD 1
+#define ACTIVE_LOW_MSC1_CD 1
+
+/* mplayer keys */
+#define GPIO_MP_VOLUMEUP (32 * 2 + 29) // SW3-GPC29
+#define GPIO_MP_VOLUMEDOWN (32 * 2 + 31) // SW1-GPC31
+#define GPIO_MP_MUTE (32 * 3 + 19) // SW6-boot_sel2-GPD19
+#define GPIO_MP_PAUSE (32 * 3 + 27) // SW4-GPD27
+#define GPIO_MP_PLAY (32 * 0 + 30) // SW9-WAKEUP-GPA30
+#define GPIO_MP_REWIND (32 * 3 + 18) // SW7-boot_sel1-GPD18
+#define GPIO_MP_FORWARD (32 * 3 + 17) // SW8-boot_sel0-GPD17
+
+#define ACTIVE_LOW_MUTE 1
+#define ACTIVE_LOW_PUASE 1
+#define ACTIVE_LOW_PLAY 1
+#define ACTIVE_LOW_REWIND 1
+#define ACTIVE_LOW_FORWARD 1
+
+#endif /* __ASM_JZ4760_LEPUS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/clock.h b/arch/mips/include/asm/mach-jz4760/clock.h
new file mode 100644
index 00000000000..56cd10021fe
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/clock.h
@@ -0,0 +1,268 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/clock.h
+ *
+ * JZ4760 clocks definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4760_CLOCK_H__
+#define __ASM_JZ4760_CLOCK_H__
+
+#ifndef JZ_EXTAL
+#define JZ_EXTAL 12000000 /* 3.6864 MHz */
+#endif
+#ifndef JZ_EXTAL2
+#define JZ_EXTAL2 32768 /* 32.768 KHz */
+#endif
+
+/*
+ * JZ4760 clocks structure
+ */
+typedef struct {
+ unsigned int cclk; /* CPU clock */
+ unsigned int hclk; /* System bus clock: AHB0,AHB1 */
+ unsigned int h1clk; /* For compatible, the same as h1clk */
+ unsigned int h2clk; /* System bus clock: AHB2 */
+ unsigned int pclk; /* Peripheral bus clock */
+ unsigned int mclk; /* EMC or DDR controller clock */
+ unsigned int sclk; /* NEMC controller clock */
+ unsigned int cko; /* SDRAM or DDR clock */
+ unsigned int pixclk; /* LCD pixel clock */
+ unsigned int tveclk; /* TV encoder 27M clock */
+ unsigned int cimmclk; /* Clock output from CIM module */
+ unsigned int cimpclk; /* Clock input to CIM module */
+ unsigned int gpuclk; /* GPU clock */
+ unsigned int gpsclk; /* GPS clock */
+ unsigned int i2sclk; /* I2S codec clock */
+ unsigned int bitclk; /* AC97 bit clock */
+ unsigned int pcmclk; /* PCM clock */
+ unsigned int mscclk; /* MSC clock */
+ unsigned int ssiclk; /* SSI clock */
+ unsigned int tssiclk; /* TSSI clock */
+ unsigned int otgclk; /* USB OTG clock */
+ unsigned int uhcclk; /* USB UHCI clock */
+ unsigned int extalclk; /* EXTAL clock for
+ UART,I2C,TCU,USB2.0-PHY,AUDIO CODEC */
+ 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)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL*CFG_DIV;
+#else
+ unsigned long m, n, no, pllout;
+ unsigned long cppcr = REG_CPM_CPPCR;
+ unsigned long od[4] = {1, 2, 4, 8};
+ if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
+ m = __cpm_get_pllm() << 1;
+ n = __cpm_get_plln();
+ no = od[__cpm_get_pllod()];
+ pllout = ((JZ_EXTAL) / (n * no)) * m;
+ } else
+ pllout = JZ_EXTAL;
+ return pllout;
+#endif
+}
+
+/* PLL output frequency / 2 */
+static __inline__ unsigned int __cpm_get_pllout2(void)
+{
+#if defined(CONFIG_FPGA)
+ return __cpm_get_pllout();
+#else
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
+ return __cpm_get_pllout();
+ else
+ return __cpm_get_pllout()/2;
+#endif
+}
+
+/* CPU core clock */
+static __inline__ unsigned int __cpm_get_cclk(void)
+{
+
+#if defined(CONFIG_FGPA)
+ return JZ_EXTAL * CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+ return __cpm_get_pllout() / div[__cpm_get_cdiv()];
+#endif
+}
+
+/* AHB0, AHB1 clock */
+static __inline__ unsigned int __cpm_get_hclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_hdiv()];
+#endif
+
+}
+
+#define __cpm_get_h0clk(void) __cpm_get_hclk()
+#define __cpm_get_h1clk(void) __cpm_get_hclk()
+
+
+/* AHB2 clock */
+static __inline__ unsigned int __cpm_get_h2clk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_h2div()];
+#endif
+
+}
+
+/* Memory bus clock */
+static __inline__ unsigned int __cpm_get_mclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL/CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_mdiv()];
+#endif
+}
+
+/* APB peripheral bus clock */
+static __inline__ unsigned int __cpm_get_pclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL/CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_pdiv()];
+#endif
+}
+
+/* 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_I2SCDR & CPM_I2SCDR_I2CS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_i2sdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* USB OTG clock */
+static __inline__ unsigned int __cpm_get_otgclk(void)
+{
+ if (REG_CPM_USBCDR & CPM_USBCDR_UCS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_otgdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_otgdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* MSC clock */
+static __inline__ unsigned int __cpm_get_mscclk(int n)
+{
+ if (REG_CPM_MSCCDR & CPM_MSCCDR_MCS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_mscdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* EXTAL clock */
+static __inline__ unsigned int __cpm_get_extalclk0(void)
+{
+ return JZ_EXTAL;
+}
+
+/* EXTAL clock for UART,I2C,SSI,SADC,USB-PHY */
+static __inline__ unsigned int __cpm_get_extalclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return __cpm_get_extalclk0() / CFG_DIV;
+#else
+ if (REG_CPM_CPCCR & CPM_CPCCR_ECS)
+ return __cpm_get_extalclk0() / 2;
+ else
+ return __cpm_get_extalclk0();
+#endif
+
+}
+
+/* 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.
+ * @n: the index of MMC/SD controller
+ */
+static inline void __cpm_select_msc_clk(int n, 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;
+ // REG_CPM_MSCCDR |= CPM_MSCCDR_MCS;
+ REG_CPM_CPCCR |= CPM_CPCCR_CE;
+}
+
+/*
+ * Output 48MHz for high speed card.
+ */
+static inline void __cpm_select_msc_clk_high(int n, int sd)
+{
+ unsigned int pllout2 = __cpm_get_pllout2();
+ unsigned int div = 0;
+
+ div = pllout2 / 48000000;
+
+ REG_CPM_MSCCDR = div - 1;
+ REG_CPM_CPCCR |= CPM_CPCCR_CE;
+}
+
+#endif /* __ASM_JZ4760_CLOCK_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/dma.h b/arch/mips/include/asm/mach-jz4760/dma.h
new file mode 100644
index 00000000000..e341dda084c
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/dma.h
@@ -0,0 +1,329 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/dma.h
+ *
+ * JZ4760 DMA definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4760_DMA_H__
+#define __ASM_JZ4760_DMA_H__
+
+#include <linux/interrupt.h>
+#include <asm/io.h> /* need byte IO */
+#include <linux/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+/*
+ * Descriptor structure for JZ4760 DMA engine
+ * Note: this structure must always be aligned to a 16-bytes boundary.
+ */
+
+/* old descriptor 4-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 ddadr; /* Points to the next descriptor + transfer count */
+} jz_dma_desc;
+
+/* new descriptor 8-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 ddadr; /* Points to the next descriptor + transfer count */
+ volatile u32 dstrd; /* DMA source and target stride address */
+ volatile u32 dreqt; /* DMA request type for current transfer */
+ volatile u32 reserved0; /* Reserved */
+ volatile u32 reserved1; /* Reserved */
+} jz_dma_desc_8word;
+
+/* new descriptor 8-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 dcnt; /* transfer count */
+ volatile u32 dstrd; /* DMA source and target stride address */
+ volatile u32 dreqt; /* DMA request type for current transfer */
+ volatile u32 dnt; /* NAND detect timer enable(15) and value(0~5), and Tail counter(22~16)*/
+ volatile u32 ddadr; /* Next descriptor address(31~4) */
+} jz_bdma_desc_8word;
+
+/* DMA Device ID's follow */
+enum {
+ DMA_ID_EXT = 0, /* External request with DREQn */
+ DMA_ID_NAND, /* NAND DMA request */
+ DMA_ID_BCH_ENC, /* BCH Encoding DMA request */
+ DMA_ID_BCH_DEC, /* BCH Decoding DMA request */
+ DMA_ID_AUTO, /* Auto-request */
+// DMA_ID_TSSI_RX, /* TSSI receive fifo full request */
+ DMA_ID_UART3_TX, /* UART3 transmit-fifo-empty request */
+ DMA_ID_UART3_RX, /* UART3 receve-fifo-full request */
+ DMA_ID_UART2_TX, /* UART2 transmit-fifo-empty request */
+ DMA_ID_UART2_RX, /* UART2 receve-fifo-full request */
+ DMA_ID_UART1_TX, /* UART1 transmit-fifo-empty request */
+ DMA_ID_UART1_RX, /* UART1 receve-fifo-full request */
+ DMA_ID_UART0_TX, /* UART0 transmit-fifo-empty request */
+ DMA_ID_UART0_RX, /* UART0 receve-fifo-full request */
+ DMA_ID_SSI0_TX, /* SSI0 transmit-fifo-full request */
+ DMA_ID_SSI0_RX, /* SSI0 receive-fifo-empty request */
+ DMA_ID_AIC_TX, /* AIC transmit-fifo-full request */
+ DMA_ID_AIC_RX, /* AIC receive-fifo-empty request */
+ DMA_ID_MSC0_TX, /* MSC0 transmit-fifo-full request */
+ DMA_ID_MSC0_RX, /* MSC0 receive-fifo-empty request */
+ DMA_ID_TCU_OVERFLOW, /* TCU channel n overflow interrupt */
+ DMA_ID_SADC, /* SADC transfer request */
+ DMA_ID_MSC1_TX, /* MSC1 transmit-fifo-full request */
+ DMA_ID_MSC1_RX, /* MSC1 receive-fifo-empty request */
+ DMA_ID_SSI1_TX, /* SSI1 transmit-fifo-full request */
+ DMA_ID_SSI1_RX, /* SSI1 receive-fifo-empty request */
+ DMA_ID_PCM_TX, /* PM transmit-fifo-full request */
+ DMA_ID_PCM_RX, /* PM receive-fifo-empty request */
+ DMA_ID_RAW_SET,
+ DMA_ID_MAX
+};
+
+/* DMA modes, simulated by sw */
+#define DMA_MODE_READ 0x0 /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x1 /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_AUTOINIT 0x2
+#define DMA_MODE_MASK 0x3
+
+struct jz_dma_chan {
+ int dev_id; /* DMA ID: this channel is allocated if >=0, free otherwise */
+ unsigned int io; /* DMA channel number */
+ const char *dev_str; /* string describes the DMA channel */
+ int irq; /* DMA irq number */
+ void *irq_dev; /* DMA private device structure */
+ unsigned int fifo_addr; /* physical fifo address of the requested device */
+ unsigned int cntl; /* DMA controll */
+ unsigned int mode; /* DMA configuration */
+ unsigned int source; /* DMA request source */
+};
+
+extern struct jz_dma_chan jz_dma_table[];
+
+
+#define DMA_8BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_8BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_32_32BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+#define DMA_AIC_32_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_32_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_TX_CMD_UC \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_TX_CMD_UNPACK \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_TX_CMD_PACK \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+extern int jz_request_dma(int dev_id,
+ const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags,
+ void *irq_dev_id);
+extern void jz_free_dma(unsigned int dmanr);
+
+extern int jz_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data);
+extern void dump_jz_dma_channel(unsigned int dmanr);
+extern void dump_jz_bdma_channel(unsigned int dmanr);
+
+extern void enable_dma(unsigned int dmanr);
+extern void disable_dma(unsigned int dmanr);
+extern void set_dma_addr(unsigned int dmanr, unsigned int phyaddr);
+extern void set_dma_count(unsigned int dmanr, unsigned int bytecnt);
+extern void set_dma_mode(unsigned int dmanr, unsigned int mode);
+extern void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt);
+extern void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt);
+extern void jz_set_dma_src_width(int dmanr, int nbit);
+extern void jz_set_dma_dest_width(int dmanr, int nbit);
+extern void jz_set_dma_block_size(int dmanr, int nbyte);
+extern unsigned int get_dma_residue(unsigned int dmanr);
+extern spinlock_t dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ */
+#define clear_dma_ff(channel)
+
+static __inline__ struct jz_dma_chan *get_dma_chan(unsigned int dmanr)
+{
+ if (dmanr > MAX_DMA_NUM
+ || jz_dma_table[dmanr].dev_id < 0)
+ return NULL;
+ return &jz_dma_table[dmanr];
+}
+
+static __inline__ int dma_halted(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 1;
+ return __dmac_channel_transmit_halt_detected(dmanr) ? 1 : 0;
+}
+
+static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+ return chan->mode;
+}
+
+static __inline__ void clear_dma_done(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+}
+
+static __inline__ void clear_dma_halt(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT);
+ REG_DMAC_DMACR((chan->io)/HALF_DMA_NUM) &= ~(DMAC_DMACR_HLT);
+}
+
+static __inline__ void clear_dma_flag(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+ REG_DMAC_DMACR((chan->io)/HALF_DMA_NUM) &= ~(DMAC_DMACR_HLT | DMAC_DMACR_AR);
+}
+
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+}
+
+static __inline__ unsigned int get_dma_done_status(unsigned int dmanr)
+{
+ unsigned long dccsr;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+ dccsr = REG_DMAC_DCCSR(chan->io);
+ return dccsr & (DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+}
+
+static __inline__ int get_dma_done_irq(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return -1;
+ return chan->irq;
+}
+
+#endif /* __ASM_JZ4760_DMA_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/irq.h b/arch/mips/include/asm/mach-jz4760/irq.h
new file mode 100644
index 00000000000..59d0935b86b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/irq.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/mips/include/asm/mach-jz4760/irq.h
+ *
+ * JZ4760 IRQ definition.
+ *
+ * Copyright (C) 2010 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_JZ4760_IRQ_H__
+#define __ASM_JZ4760_IRQ_H__
+
+/* we need 256 irq levels at least */
+#define NR_IRQS 256
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760.h b/arch/mips/include/asm/mach-jz4760/jz4760.h
new file mode 100644
index 00000000000..5c12b81c788
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760.h
@@ -0,0 +1,93 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760.h
+ *
+ * JZ4760 common definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4760_H__
+#define __ASM_JZ4760_H__
+
+#include <asm/mach-jz4760/regs.h>
+
+#include <asm/mach-jz4760/jz4760misc.h>
+#include <asm/mach-jz4760/jz4760gpio.h>
+#include <asm/mach-jz4760/jz4760dmac.h>
+#include <asm/mach-jz4760/jz4760intc.h>
+#include <asm/mach-jz4760/jz4760aic.h>
+#include <asm/mach-jz4760/jz4760bch.h>
+#include <asm/mach-jz4760/jz4760bdma.h>
+#include <asm/mach-jz4760/jz4760cim.h>
+#include <asm/mach-jz4760/jz4760cpm.h>
+#include <asm/mach-jz4760/jz4760ddrc.h>
+#include <asm/mach-jz4760/jz4760emc.h>
+#include <asm/mach-jz4760/jz4760i2c.h>
+#include <asm/mach-jz4760/jz4760ipu.h>
+#include <asm/mach-jz4760/jz4760lcdc.h>
+#include <asm/mach-jz4760/jz4760mc.h>
+#include <asm/mach-jz4760/jz4760mdma.h>
+#include <asm/mach-jz4760/jz4760me.h>
+#include <asm/mach-jz4760/jz4760msc.h>
+#include <asm/mach-jz4760/jz4760nemc.h>
+#include <asm/mach-jz4760/jz4760otg.h>
+#include <asm/mach-jz4760/jz4760otp.h>
+#include <asm/mach-jz4760/jz4760owi.h>
+#include <asm/mach-jz4760/jz4760pcm.h>
+#include <asm/mach-jz4760/jz4760rtc.h>
+#include <asm/mach-jz4760/jz4760sadc.h>
+#include <asm/mach-jz4760/jz4760scc.h>
+#include <asm/mach-jz4760/jz4760ssi.h>
+#include <asm/mach-jz4760/jz4760tcu.h>
+#include <asm/mach-jz4760/jz4760tssi.h>
+#include <asm/mach-jz4760/jz4760tve.h>
+#include <asm/mach-jz4760/jz4760uart.h>
+#include <asm/mach-jz4760/jz4760wdt.h>
+#include <asm/mach-jz4760/jz4760ost.h>
+
+#include <asm/mach-jz4760/dma.h>
+#include <asm/mach-jz4760/misc.h>
+
+/*------------------------------------------------------------------
+ * Platform definitions
+ */
+
+#define JZ_SOC_NAME "JZ4760"
+
+#ifdef CONFIG_JZ4750_FUWA
+#include <asm/mach-jz4750/board-fuwa.h>
+#endif
+
+#ifdef CONFIG_JZ4760_F4760
+#include <asm/mach-jz4760/board-f4760.h>
+#endif
+
+#ifdef CONFIG_JZ4760_CYGNUS
+#include <asm/mach-jz4760/board-cygnus.h>
+#endif
+
+#ifdef CONFIG_JZ4760_LEPUS
+#include <asm/mach-jz4760/board-lepus.h>
+#endif
+
+#ifdef CONFIG_JZ4760_ALTAIR
+#include <asm/mach-jz4760/board-altair.h>
+#endif
+
+/* Add other platform definition here ... */
+
+
+/*------------------------------------------------------------------
+ * Follows are related to platform definitions
+ */
+
+//#include <asm/mach-jz4760/clock.h>
+#include <asm/mach-jz4760/serial.h>
+
+#endif /* __ASM_JZ4760_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760aic.h b/arch/mips/include/asm/mach-jz4760/jz4760aic.h
new file mode 100644
index 00000000000..ea47d4cfe7f
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760aic.h
@@ -0,0 +1,817 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760aic.h
+ *
+ * JZ4760 AIC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760AIC_H__
+#define __JZ4760AIC_H__
+
+
+#define AIC_BASE 0xB0020000
+#define ICDC_BASE 0xB0020000
+
+
+/*************************************************************************
+ * AIC (AC97/I2S Controller)
+ *************************************************************************/
+#define AIC_FR (AIC_BASE + 0x000)
+#define AIC_CR (AIC_BASE + 0x004)
+#define AIC_ACCR1 (AIC_BASE + 0x008)
+#define AIC_ACCR2 (AIC_BASE + 0x00C)
+#define AIC_I2SCR (AIC_BASE + 0x010)
+#define AIC_SR (AIC_BASE + 0x014)
+#define AIC_ACSR (AIC_BASE + 0x018)
+#define AIC_I2SSR (AIC_BASE + 0x01C)
+#define AIC_ACCAR (AIC_BASE + 0x020)
+#define AIC_ACCDR (AIC_BASE + 0x024)
+#define AIC_ACSAR (AIC_BASE + 0x028)
+#define AIC_ACSDR (AIC_BASE + 0x02C)
+#define AIC_I2SDIV (AIC_BASE + 0x030)
+#define AIC_DR (AIC_BASE + 0x034)
+
+#define REG_AIC_FR REG32(AIC_FR)
+#define REG_AIC_CR REG32(AIC_CR)
+#define REG_AIC_ACCR1 REG32(AIC_ACCR1)
+#define REG_AIC_ACCR2 REG32(AIC_ACCR2)
+#define REG_AIC_I2SCR REG32(AIC_I2SCR)
+#define REG_AIC_SR REG32(AIC_SR)
+#define REG_AIC_ACSR REG32(AIC_ACSR)
+#define REG_AIC_I2SSR REG32(AIC_I2SSR)
+#define REG_AIC_ACCAR REG32(AIC_ACCAR)
+#define REG_AIC_ACCDR REG32(AIC_ACCDR)
+#define REG_AIC_ACSAR REG32(AIC_ACSAR)
+#define REG_AIC_ACSDR REG32(AIC_ACSDR)
+#define REG_AIC_I2SDIV REG32(AIC_I2SDIV)
+#define REG_AIC_DR REG32(AIC_DR)
+
+/* AIC Controller Configuration Register (AIC_FR) */
+
+#define AIC_FR_RFTH_BIT 24 /* Receive FIFO Threshold */
+#define AIC_FR_RFTH_MASK (0xf << AIC_FR_RFTH_BIT)
+#define AIC_FR_TFTH_BIT 16 /* Transmit FIFO Threshold */
+#define AIC_FR_TFTH_MASK (0x1f << AIC_FR_TFTH_BIT)
+#define AIC_FR_LSMP (1 << 6) /* Play Zero sample or last sample */
+#define AIC_FR_ICDC (1 << 5) /* External(0) or Internal CODEC(1) */
+#define AIC_FR_AUSEL (1 << 4) /* AC97(0) or I2S/MSB-justified(1) */
+#define AIC_FR_RST (1 << 3) /* AIC registers reset */
+#define AIC_FR_BCKD (1 << 2) /* I2S BIT_CLK direction, 0:input,1:output */
+#define AIC_FR_SYNCD (1 << 1) /* I2S SYNC direction, 0:input,1:output */
+#define AIC_FR_ENB (1 << 0) /* AIC enable bit */
+
+/* AIC Controller Common Control Register (AIC_CR) */
+
+#define AIC_CR_EN2OLD (1 << 29) /* Enable old style */
+#define AIC_CR_PACK16 (1 << 28) /* Output Sample data 16bit packed mode select */
+#define AIC_CR_CHANNEL_BIT 24 /* Output Channel Number Select */
+#define AIC_CR_CHANNEL_MASK (0x7 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_MONO (0x0 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_STEREO (0x1 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_4CHNL (0x3 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_6CHNL (0x5 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_8CHNL (0x7 << AIC_CR_CHANNEL_BIT)
+
+#define AIC_CR_OSS_BIT 19 /* Output Sample Size from memory (AIC V2 only) */
+#define AIC_CR_OSS_MASK (0x7 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_8BIT (0x0 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_16BIT (0x1 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_18BIT (0x2 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_20BIT (0x3 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_24BIT (0x4 << AIC_CR_OSS_BIT)
+#define AIC_CR_ISS_BIT 16 /* Input Sample Size from memory (AIC V2 only) */
+#define AIC_CR_ISS_MASK (0x7 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_8BIT (0x0 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_16BIT (0x1 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_18BIT (0x2 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_20BIT (0x3 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_24BIT (0x4 << AIC_CR_ISS_BIT)
+#define AIC_CR_RDMS (1 << 15) /* Receive DMA enable */
+#define AIC_CR_TDMS (1 << 14) /* Transmit DMA enable */
+#define AIC_CR_M2S (1 << 11) /* Mono to Stereo enable */
+#define AIC_CR_ENDSW (1 << 10) /* Endian switch enable */
+#define AIC_CR_AVSTSU (1 << 9) /* Signed <-> Unsigned toggle enable */
+#define AIC_CR_TFLUSH (1 << 8) /* Flush TFIFO */
+#define AIC_CR_RFLUSH (1 << 7) /* Flush RFIFO */
+#define AIC_CR_EROR (1 << 6) /* Enable ROR interrupt */
+#define AIC_CR_ETUR (1 << 5) /* Enable TUR interrupt */
+#define AIC_CR_ERFS (1 << 4) /* Enable RFS interrupt */
+#define AIC_CR_ETFS (1 << 3) /* Enable TFS interrupt */
+#define AIC_CR_ENLBF (1 << 2) /* Enable Loopback Function */
+#define AIC_CR_ERPL (1 << 1) /* Enable Playback Function */
+#define AIC_CR_EREC (1 << 0) /* Enable Record Function */
+
+/* AIC Controller AC-link Control Register 1 (AIC_ACCR1) */
+
+#define AIC_ACCR1_RS_BIT 16 /* Receive Valid Slots */
+#define AIC_ACCR1_RS_MASK (0x3ff << AIC_ACCR1_RS_BIT)
+ #define AIC_ACCR1_RS_SLOT12 (1 << 25) /* Slot 12 valid bit */
+ #define AIC_ACCR1_RS_SLOT11 (1 << 24) /* Slot 11 valid bit */
+ #define AIC_ACCR1_RS_SLOT10 (1 << 23) /* Slot 10 valid bit */
+ #define AIC_ACCR1_RS_SLOT9 (1 << 22) /* Slot 9 valid bit, LFE */
+ #define AIC_ACCR1_RS_SLOT8 (1 << 21) /* Slot 8 valid bit, Surround Right */
+ #define AIC_ACCR1_RS_SLOT7 (1 << 20) /* Slot 7 valid bit, Surround Left */
+ #define AIC_ACCR1_RS_SLOT6 (1 << 19) /* Slot 6 valid bit, PCM Center */
+ #define AIC_ACCR1_RS_SLOT5 (1 << 18) /* Slot 5 valid bit */
+ #define AIC_ACCR1_RS_SLOT4 (1 << 17) /* Slot 4 valid bit, PCM Right */
+ #define AIC_ACCR1_RS_SLOT3 (1 << 16) /* Slot 3 valid bit, PCM Left */
+#define AIC_ACCR1_XS_BIT 0 /* Transmit Valid Slots */
+#define AIC_ACCR1_XS_MASK (0x3ff << AIC_ACCR1_XS_BIT)
+ #define AIC_ACCR1_XS_SLOT12 (1 << 9) /* Slot 12 valid bit */
+ #define AIC_ACCR1_XS_SLOT11 (1 << 8) /* Slot 11 valid bit */
+ #define AIC_ACCR1_XS_SLOT10 (1 << 7) /* Slot 10 valid bit */
+ #define AIC_ACCR1_XS_SLOT9 (1 << 6) /* Slot 9 valid bit, LFE */
+ #define AIC_ACCR1_XS_SLOT8 (1 << 5) /* Slot 8 valid bit, Surround Right */
+ #define AIC_ACCR1_XS_SLOT7 (1 << 4) /* Slot 7 valid bit, Surround Left */
+ #define AIC_ACCR1_XS_SLOT6 (1 << 3) /* Slot 6 valid bit, PCM Center */
+ #define AIC_ACCR1_XS_SLOT5 (1 << 2) /* Slot 5 valid bit */
+ #define AIC_ACCR1_XS_SLOT4 (1 << 1) /* Slot 4 valid bit, PCM Right */
+ #define AIC_ACCR1_XS_SLOT3 (1 << 0) /* Slot 3 valid bit, PCM Left */
+
+/* AIC Controller AC-link Control Register 2 (AIC_ACCR2) */
+
+#define AIC_ACCR2_ERSTO (1 << 18) /* Enable RSTO interrupt */
+#define AIC_ACCR2_ESADR (1 << 17) /* Enable SADR interrupt */
+#define AIC_ACCR2_ECADT (1 << 16) /* Enable CADT interrupt */
+#define AIC_ACCR2_OASS_BIT 8 /* Output Sample Size for AC-link */
+#define AIC_ACCR2_OASS_MASK (0x3 << AIC_ACCR2_OASS_BIT)
+ #define AIC_ACCR2_OASS_20BIT (0 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 20-bit */
+ #define AIC_ACCR2_OASS_18BIT (1 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 18-bit */
+ #define AIC_ACCR2_OASS_16BIT (2 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 16-bit */
+ #define AIC_ACCR2_OASS_8BIT (3 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 8-bit */
+#define AIC_ACCR2_IASS_BIT 6 /* Output Sample Size for AC-link */
+#define AIC_ACCR2_IASS_MASK (0x3 << AIC_ACCR2_IASS_BIT)
+ #define AIC_ACCR2_IASS_20BIT (0 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 20-bit */
+ #define AIC_ACCR2_IASS_18BIT (1 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 18-bit */
+ #define AIC_ACCR2_IASS_16BIT (2 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 16-bit */
+ #define AIC_ACCR2_IASS_8BIT (3 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 8-bit */
+#define AIC_ACCR2_SO (1 << 3) /* SDATA_OUT output value */
+#define AIC_ACCR2_SR (1 << 2) /* RESET# pin level */
+#define AIC_ACCR2_SS (1 << 1) /* SYNC pin level */
+#define AIC_ACCR2_SA (1 << 0) /* SYNC and SDATA_OUT alternation */
+
+/* AIC Controller I2S/MSB-justified Control Register (AIC_I2SCR) */
+
+#define AIC_I2SCR_RFIRST (1 << 17) /* Send R channel first in stereo mode */
+#define AIC_I2SCR_SWLH (1 << 16) /* Switch LR channel in 16bit-packed stereo mode */
+#define AIC_I2SCR_STPBK (1 << 12) /* Stop BIT_CLK for I2S/MSB-justified */
+#define AIC_I2SCR_WL_BIT 1 /* Input/Output Sample Size for I2S/MSB-justified */
+#define AIC_I2SCR_WL_MASK (0x7 << AIC_I2SCR_WL_BIT)
+ #define AIC_I2SCR_WL_24BIT (0 << AIC_I2SCR_WL_BIT) /* Word Length is 24 bit */
+ #define AIC_I2SCR_WL_20BIT (1 << AIC_I2SCR_WL_BIT) /* Word Length is 20 bit */
+ #define AIC_I2SCR_WL_18BIT (2 << AIC_I2SCR_WL_BIT) /* Word Length is 18 bit */
+ #define AIC_I2SCR_WL_16BIT (3 << AIC_I2SCR_WL_BIT) /* Word Length is 16 bit */
+ #define AIC_I2SCR_WL_8BIT (4 << AIC_I2SCR_WL_BIT) /* Word Length is 8 bit */
+
+#define AIC_I2SCR_ESCLK (1 << 4)
+
+#define AIC_I2SCR_AMSL (1 << 0) /* 0:I2S, 1:MSB-justified */
+
+/* AIC Controller FIFO Status Register (AIC_SR) */
+
+#define AIC_SR_RFL_BIT 24 /* Receive FIFO Level */
+#define AIC_SR_RFL_MASK (0x3f << AIC_SR_RFL_BIT)
+#define AIC_SR_TFL_BIT 8 /* Transmit FIFO level */
+#define AIC_SR_TFL_MASK (0x3f << AIC_SR_TFL_BIT)
+#define AIC_SR_ROR (1 << 6) /* Receive FIFO Overrun */
+#define AIC_SR_TUR (1 << 5) /* Transmit FIFO Underrun */
+#define AIC_SR_RFS (1 << 4) /* Receive FIFO Service Request */
+#define AIC_SR_TFS (1 << 3) /* Transmit FIFO Service Request */
+
+/* AIC Controller AC-link Status Register (AIC_ACSR) */
+
+#define AIC_ACSR_SLTERR (1 << 21) /* Slot Error Flag */
+#define AIC_ACSR_CRDY (1 << 20) /* External CODEC Ready Flag */
+#define AIC_ACSR_CLPM (1 << 19) /* External CODEC low power mode flag */
+#define AIC_ACSR_RSTO (1 << 18) /* External CODEC regs read status timeout */
+#define AIC_ACSR_SADR (1 << 17) /* External CODEC regs status addr and data received */
+#define AIC_ACSR_CADT (1 << 16) /* Command Address and Data Transmitted */
+
+/* AIC Controller I2S/MSB-justified Status Register (AIC_I2SSR) */
+
+#define AIC_I2SSR_BSY (1 << 2) /* AIC Busy in I2S/MSB-justified format */
+
+/* AIC Controller AC97 codec Command Address Register (AIC_ACCAR) */
+
+#define AIC_ACCAR_CAR_BIT 0
+#define AIC_ACCAR_CAR_MASK (0xfffff << AIC_ACCAR_CAR_BIT)
+
+/* AIC Controller AC97 codec Command Data Register (AIC_ACCDR) */
+
+#define AIC_ACCDR_CDR_BIT 0
+#define AIC_ACCDR_CDR_MASK (0xfffff << AIC_ACCDR_CDR_BIT)
+
+/* AIC Controller AC97 codec Status Address Register (AIC_ACSAR) */
+
+#define AIC_ACSAR_SAR_BIT 0
+#define AIC_ACSAR_SAR_MASK (0xfffff << AIC_ACSAR_SAR_BIT)
+
+/* AIC Controller AC97 codec Status Data Register (AIC_ACSDR) */
+
+#define AIC_ACSDR_SDR_BIT 0
+#define AIC_ACSDR_SDR_MASK (0xfffff << AIC_ACSDR_SDR_BIT)
+
+/* AIC Controller I2S/MSB-justified Clock Divider Register (AIC_I2SDIV) */
+
+#define AIC_I2SDIV_DIV_BIT 0
+#define AIC_I2SDIV_DIV_MASK (0x7f << AIC_I2SDIV_DIV_BIT)
+ #define AIC_I2SDIV_BITCLK_3072KHZ (0x0C << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 3.072MHz */
+ #define AIC_I2SDIV_BITCLK_2836KHZ (0x0D << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 2.836MHz */
+ #define AIC_I2SDIV_BITCLK_1418KHZ (0x1A << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.418MHz */
+ #define AIC_I2SDIV_BITCLK_1024KHZ (0x24 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.024MHz */
+ #define AIC_I2SDIV_BITCLK_7089KHZ (0x34 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 708.92KHz */
+ #define AIC_I2SDIV_BITCLK_512KHZ (0x48 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 512.00KHz */
+
+
+
+/*************************************************************************
+ * ICDC (Internal CODEC)
+ *************************************************************************/
+
+#define ICDC_CKCFG (ICDC_BASE + 0x00a0) /* Clock Configure Register */
+#define ICDC_RGADW (ICDC_BASE + 0x00a4) /* internal register access control */
+#define ICDC_RGDATA (ICDC_BASE + 0x00a8) /* internal register data output */
+
+#define REG_ICDC_CKCFG REG32(ICDC_CKCFG)
+#define REG_ICDC_RGADW REG32(ICDC_RGADW)
+#define REG_ICDC_RGDATA REG32(ICDC_RGDATA)
+
+/* ICDC Clock Configure Register */
+#define ICDC_CKCFG_CKRDY (1 << 1)
+#define ICDC_CKCFG_SELAD (1 << 0)
+
+/* ICDC internal register access control Register */
+#define ICDC_RGADW_RGWR (1 << 16)
+#define ICDC_RGADW_RGADDR_BIT 8
+#define ICDC_RGADW_RGADDR_MASK (0x7f << ICDC_RGADW_RGADDR_BIT)
+#define ICDC_RGADW_RGDIN_BIT 0
+#define ICDC_RGADW_RGDIN_MASK (0xff << ICDC_RGADW_RGDIN_BIT)
+
+/* ICDC internal register data output Register */
+#define ICDC_RGDATA_IRQ (1 << 8)
+#define ICDC_RGDATA_RGDOUT_BIT 0
+#define ICDC_RGDATA_RGDOUT_MASK (0xff << ICDC_RGDATA_RGDOUT_BIT)
+
+/*************************************************************************
+ * SPDIF INTERFACE in AIC Controller
+ *************************************************************************/
+
+#define SPDIF_ENA (AIC_BASE + 0x080)
+#define SPDIF_CTRL (AIC_BASE + 0x084)
+#define SPDIF_STATE (AIC_BASE + 0x088)
+#define SPDIF_CFG1 (AIC_BASE + 0x08c)
+#define SPDIF_CFG2 (AIC_BASE + 0x090)
+#define SPDIF_FIFO (AIC_BASE + 0x094)
+
+#define REG_SPDIF_ENA REG32(SPDIF_ENA)
+#define REG_SPDIF_CTRL REG32(SPDIF_CTRL)
+#define REG_SPDIF_STATE REG32(SPDIF_STATE)
+#define REG_SPDIF_CFG1 REG32(SPDIF_CFG1)
+#define REG_SPDIF_CFG2 REG32(SPDIF_CFG2)
+#define REG_SPDIF_FIFO REG32(SPDIF_FIFO)
+
+/* SPDIF Enable Register (SPDIF_ENA) */
+
+#define SPDIF_ENA_SPEN (1 << 0) /* Enable or disable the SPDIF transmitter */
+
+/* SPDIF Control Register (SPDIF_CTRL) */
+
+#define SPDIF_CTRL_DMAEN (1 << 15)
+#define SPDIF_CTRL_DTYPE (1 << 14)
+#define SPDIF_CTRL_SIGN (1 << 13)
+#define SPDIF_CTRL_INVALID (1 << 12)
+#define SPDIF_CTRL_RST (1 << 11)
+#define SPDIF_CTRL_SPDIFI2S (1 << 10)
+#define SPDIF_CTRL_MTRIG (1 << 1)
+#define SPDIF_CTRL_MFFUR (1 << 0)
+
+/* SPDIF Configure 1 Register (SPDIF_CFG1) */
+
+#define SPDIF_CFG1_INITLVL (1 << 17)
+#define SPDIF_CFG1_ZROVLD (1 << 16)
+
+#define SPDIF_CFG1_TRIG_BIT 12
+#define SPDIF_CFG1_TRIG_MASK (0x3 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_4 (0x0 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_8 (0x1 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_16 (0x2 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_32 (0x3 << SPDIF_CFG1_TRIG_BIT)
+
+#define SPDIF_CFG1_SRCNUM_BIT 8
+#define SPDIF_CFG1_SRCNUM_MASK (0xf << SPDIF_CFG1_SRCNUM_BIT)
+
+#define SPDIF_CFG1_CH1NUM_BIT 4
+#define SPDIF_CFG1_CH1NUM_MASK (0xf << SPDIF_CFG1_CH1NUM_BIT)
+
+#define SPDIF_CFG1_CH2NUM_BIT 0
+#define SPDIF_CFG1_CH2NUM_MASK (0xf << SPDIF_CFG1_CH2NUM_BIT)
+
+/* SPDIF Configure 2 Register (SPDIF_CFG2) */
+
+#define SPDIF_CFG2_FS_BIT 26
+#define SPDIF_CFG2_FS_MASK (0xf << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_44K (0x0 << SPDIF_CFG2_FS_BIT) /* 44.1kHz */
+ #define SPDIF_CFG2_FS_48K (0x2 << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_32K (0x3 << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_96K (0xa << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_192K (0xe << SPDIF_CFG2_FS_BIT)
+
+#define SPDIF_CFG2_ORGFRQ_BIT 22
+#define SPDIF_CFG2_ORGFRQ_MASK (0xf << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_44K (0xf << SPDIF_CFG2_ORGFRQ_BIT) /* 44.1kHz */
+ #define SPDIF_CFG2_ORGFRQ_48K (0xd << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_32K (0xc << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_96K (0x5 << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_192K (0x1 << SPDIF_CFG2_ORGFRQ_BIT)
+
+#define SPDIF_CFG2_SAMWL_BIT 19
+#define SPDIF_CFG2_SAMWL_MASK (0x7 << SPDIF_CFG2_SAMWL_BIT)
+
+#define SPDIF_CFG2_MAXWL (1 << 18)
+
+#define SPDIF_CFG2_CLKACU_BIT 16
+#define SPDIF_CFG2_CLKACU_MASK (0x3 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL2 (0x0 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL1 (0x1 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL3 (0x2 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_NOTMAT (0x3 << SPDIF_CFG2_CLKACU_BIT)
+
+#define SPDIF_CFG2_CATCODE_BIT 8
+#define SPDIF_CFG2_CATCODE_MASK (0xff << SPDIF_CFG2_CATCODE_BIT)
+
+#define SPDIF_CFG2_CHMD_BIT 6
+#define SPDIF_CFG2_CHMD_MASK (0x3 << SPDIF_CFG2_CHMD_BIT)
+ #define SPDIF_CFG2_CHMD_MOD0 (0x0 << SPDIF_CFG2_CHMD_BIT)
+
+#define SPDIF_CFG2_PRE (1 << 3)
+#define SPDIF_CFG2_COPYN (1 << 2)
+#define SPDIF_CFG2_AUDION (1 << 1)
+#define SPDIF_CFG2_CONPRO (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * AIC (AC'97 & I2S Controller)
+ ***************************************************************************/
+
+#define __aic_enable() ( REG_AIC_FR |= AIC_FR_ENB )
+#define __aic_disable() ( REG_AIC_FR &= ~AIC_FR_ENB )
+
+#define __aic_select_ac97() ( REG_AIC_FR &= ~AIC_FR_AUSEL )
+#define __aic_select_i2s() ( REG_AIC_FR |= AIC_FR_AUSEL )
+
+#define __aic_play_zero() ( REG_AIC_FR &= ~AIC_FR_LSMP )
+#define __aic_play_lastsample() ( REG_AIC_FR |= AIC_FR_LSMP )
+
+#define __i2s_as_master() ( REG_AIC_FR |= AIC_FR_BCKD | AIC_FR_SYNCD )
+#define __i2s_as_slave() ( REG_AIC_FR &= ~(AIC_FR_BCKD | AIC_FR_SYNCD) )
+#define __aic_reset_status() ( REG_AIC_FR & AIC_FR_RST )
+
+#define __aic_reset() \
+do { \
+ REG_AIC_FR |= AIC_FR_RST; \
+} while(0)
+
+
+#define __aic_set_transmit_trigger(n) \
+do { \
+ REG_AIC_FR &= ~AIC_FR_TFTH_MASK; \
+ REG_AIC_FR |= ((n) << AIC_FR_TFTH_BIT); \
+} while(0)
+
+#define __aic_set_receive_trigger(n) \
+do { \
+ REG_AIC_FR &= ~AIC_FR_RFTH_MASK; \
+ REG_AIC_FR |= ((n) << AIC_FR_RFTH_BIT); \
+} while(0)
+
+#define __aic_enable_oldstyle() ( REG_AIC_CR |= AIC_CR_EN2OLD )
+#define __aic_enable_newstyle() ( REG_AIC_CR &= ~AIC_CR_EN2OLD )
+#define __aic_enable_pack16() ( REG_AIC_CR |= AIC_CR_PACK16 )
+#define __aic_enable_unpack16() ( REG_AIC_CR &= ~AIC_CR_PACK16)
+
+/* n = AIC_CR_CHANNEL_MONO,AIC_CR_CHANNEL_STEREO ... */
+#define __aic_out_channel_select(n) \
+do { \
+ REG_AIC_CR &= ~AIC_CR_CHANNEL_MASK; \
+ REG_AIC_CR |= ((n) << AIC_CR_CHANNEL_BIT ); \
+} while(0)
+
+#define __aic_enable_record() ( REG_AIC_CR |= AIC_CR_EREC )
+#define __aic_disable_record() ( REG_AIC_CR &= ~AIC_CR_EREC )
+#define __aic_enable_replay() ( REG_AIC_CR |= AIC_CR_ERPL )
+#define __aic_disable_replay() ( REG_AIC_CR &= ~AIC_CR_ERPL )
+#define __aic_enable_loopback() ( REG_AIC_CR |= AIC_CR_ENLBF )
+#define __aic_disable_loopback() ( REG_AIC_CR &= ~AIC_CR_ENLBF )
+
+#define __aic_flush_tfifo() ( REG_AIC_CR |= AIC_CR_TFLUSH )
+#define __aic_unflush_tfifo() ( REG_AIC_CR &= ~AIC_CR_TFLUSH )
+#define __aic_flush_rfifo() ( REG_AIC_CR |= AIC_CR_RFLUSH )
+#define __aic_unflush_rfifo() ( REG_AIC_CR &= ~AIC_CR_RFLUSH )
+
+#define __aic_enable_transmit_intr() \
+ ( REG_AIC_CR |= (AIC_CR_ETFS | AIC_CR_ETUR) )
+#define __aic_disable_transmit_intr() \
+ ( REG_AIC_CR &= ~(AIC_CR_ETFS | AIC_CR_ETUR) )
+#define __aic_enable_receive_intr() \
+ ( REG_AIC_CR |= (AIC_CR_ERFS | AIC_CR_EROR) )
+#define __aic_disable_receive_intr() \
+ ( REG_AIC_CR &= ~(AIC_CR_ERFS | AIC_CR_EROR) )
+
+#define __aic_enable_transmit_dma() ( REG_AIC_CR |= AIC_CR_TDMS )
+#define __aic_disable_transmit_dma() ( REG_AIC_CR &= ~AIC_CR_TDMS )
+#define __aic_enable_receive_dma() ( REG_AIC_CR |= AIC_CR_RDMS )
+#define __aic_disable_receive_dma() ( REG_AIC_CR &= ~AIC_CR_RDMS )
+
+#define __aic_enable_mono2stereo() ( REG_AIC_CR |= AIC_CR_M2S )
+#define __aic_disable_mono2stereo() ( REG_AIC_CR &= ~AIC_CR_M2S )
+#define __aic_enable_byteswap() ( REG_AIC_CR |= AIC_CR_ENDSW )
+#define __aic_disable_byteswap() ( REG_AIC_CR &= ~AIC_CR_ENDSW )
+#define __aic_enable_unsignadj() ( REG_AIC_CR |= AIC_CR_AVSTSU )
+#define __aic_disable_unsignadj() ( REG_AIC_CR &= ~AIC_CR_AVSTSU )
+
+#define AC97_PCM_XS_L_FRONT AIC_ACCR1_XS_SLOT3
+#define AC97_PCM_XS_R_FRONT AIC_ACCR1_XS_SLOT4
+#define AC97_PCM_XS_CENTER AIC_ACCR1_XS_SLOT6
+#define AC97_PCM_XS_L_SURR AIC_ACCR1_XS_SLOT7
+#define AC97_PCM_XS_R_SURR AIC_ACCR1_XS_SLOT8
+#define AC97_PCM_XS_LFE AIC_ACCR1_XS_SLOT9
+
+#define AC97_PCM_RS_L_FRONT AIC_ACCR1_RS_SLOT3
+#define AC97_PCM_RS_R_FRONT AIC_ACCR1_RS_SLOT4
+#define AC97_PCM_RS_CENTER AIC_ACCR1_RS_SLOT6
+#define AC97_PCM_RS_L_SURR AIC_ACCR1_RS_SLOT7
+#define AC97_PCM_RS_R_SURR AIC_ACCR1_RS_SLOT8
+#define AC97_PCM_RS_LFE AIC_ACCR1_RS_SLOT9
+
+#define __ac97_set_xs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK )
+#define __ac97_set_xs_mono() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_XS_R_FRONT; \
+} while(0)
+#define __ac97_set_xs_stereo() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT; \
+} while(0)
+
+/* In fact, only stereo is support now. */
+#define __ac97_set_rs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK )
+#define __ac97_set_rs_mono() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_RS_R_FRONT; \
+} while(0)
+#define __ac97_set_rs_stereo() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_RS_L_FRONT | AC97_PCM_RS_R_FRONT; \
+} while(0)
+
+#define __ac97_warm_reset_codec() \
+ do { \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SA; \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SS; \
+ udelay(2); \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SS; \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SA; \
+ } while (0)
+
+#define __ac97_cold_reset_codec() \
+ do { \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SR; \
+ udelay(2); \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SR; \
+ } while (0)
+
+/* n=8,16,18,20 */
+#define __ac97_set_iass(n) \
+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_IASS_MASK) | AIC_ACCR2_IASS_##n##BIT )
+#define __ac97_set_oass(n) \
+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_OASS_MASK) | AIC_ACCR2_OASS_##n##BIT )
+
+/* This bit should only be set in 2 channels configuration */
+#define __i2s_send_rfirst() ( REG_AIC_I2SCR |= AIC_I2SCR_RFIRST ) /* RL */
+#define __i2s_send_lfirst() ( REG_AIC_I2SCR &= ~AIC_I2SCR_RFIRST ) /* LR */
+
+/* This bit should only be set in 2 channels configuration and 16bit-packed mode */
+#define __i2s_switch_lr() ( REG_AIC_I2SCR |= AIC_I2SCR_SWLH )
+#define __i2s_unswitch_lr() ( REG_AIC_I2SCR &= ~AIC_I2SCR_SWLH )
+
+#define __i2s_select_i2s() ( REG_AIC_I2SCR &= ~AIC_I2SCR_AMSL )
+#define __i2s_select_msbjustified() ( REG_AIC_I2SCR |= AIC_I2SCR_AMSL )
+
+/* n=8,16,18,20,24 */
+/*#define __i2s_set_sample_size(n) \
+ ( REG_AIC_I2SCR |= (REG_AIC_I2SCR & ~AIC_I2SCR_WL_MASK) | AIC_I2SCR_WL_##n##BIT )*/
+
+#define __i2s_out_channel_select(n) __aic_out_channel_select(n)
+
+#define __i2s_set_oss_sample_size(n) \
+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_OSS_MASK) | AIC_CR_OSS_##n##BIT )
+#define __i2s_set_iss_sample_size(n) \
+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_ISS_MASK) | AIC_CR_ISS_##n##BIT )
+
+#define __i2s_stop_bitclk() ( REG_AIC_I2SCR |= AIC_I2SCR_STPBK )
+#define __i2s_start_bitclk() ( REG_AIC_I2SCR &= ~AIC_I2SCR_STPBK )
+
+#define __aic_transmit_request() ( REG_AIC_SR & AIC_SR_TFS )
+#define __aic_receive_request() ( REG_AIC_SR & AIC_SR_RFS )
+#define __aic_transmit_underrun() ( REG_AIC_SR & AIC_SR_TUR )
+#define __aic_receive_overrun() ( REG_AIC_SR & AIC_SR_ROR )
+
+#define __aic_clear_errors() ( REG_AIC_SR &= ~(AIC_SR_TUR | AIC_SR_ROR) )
+
+#define __aic_get_transmit_resident() \
+ ( (REG_AIC_SR & AIC_SR_TFL_MASK) >> AIC_SR_TFL_BIT )
+#define __aic_get_receive_count() \
+ ( (REG_AIC_SR & AIC_SR_RFL_MASK) >> AIC_SR_RFL_BIT )
+
+#define __ac97_command_transmitted() ( REG_AIC_ACSR & AIC_ACSR_CADT )
+#define __ac97_status_received() ( REG_AIC_ACSR & AIC_ACSR_SADR )
+#define __ac97_status_receive_timeout() ( REG_AIC_ACSR & AIC_ACSR_RSTO )
+#define __ac97_codec_is_low_power_mode() ( REG_AIC_ACSR & AIC_ACSR_CLPM )
+#define __ac97_codec_is_ready() ( REG_AIC_ACSR & AIC_ACSR_CRDY )
+#define __ac97_slot_error_detected() ( REG_AIC_ACSR & AIC_ACSR_SLTERR )
+#define __ac97_clear_slot_error() ( REG_AIC_ACSR &= ~AIC_ACSR_SLTERR )
+
+#define __i2s_is_busy() ( REG_AIC_I2SSR & AIC_I2SSR_BSY )
+
+#define CODEC_READ_CMD (1 << 19)
+#define CODEC_WRITE_CMD (0 << 19)
+#define CODEC_REG_INDEX_BIT 12
+#define CODEC_REG_INDEX_MASK (0x7f << CODEC_REG_INDEX_BIT) /* 18:12 */
+#define CODEC_REG_DATA_BIT 4
+#define CODEC_REG_DATA_MASK (0x0ffff << 4) /* 19:4 */
+
+#define __ac97_out_rcmd_addr(reg) \
+do { \
+ REG_AIC_ACCAR = CODEC_READ_CMD | ((reg) << CODEC_REG_INDEX_BIT); \
+} while (0)
+
+#define __ac97_out_wcmd_addr(reg) \
+do { \
+ REG_AIC_ACCAR = CODEC_WRITE_CMD | ((reg) << CODEC_REG_INDEX_BIT); \
+} while (0)
+
+#define __ac97_out_data(value) \
+do { \
+ REG_AIC_ACCDR = ((value) << CODEC_REG_DATA_BIT); \
+} while (0)
+
+#define __ac97_in_data() \
+ ( (REG_AIC_ACSDR & CODEC_REG_DATA_MASK) >> CODEC_REG_DATA_BIT )
+
+#define __ac97_in_status_addr() \
+ ( (REG_AIC_ACSAR & CODEC_REG_INDEX_MASK) >> CODEC_REG_INDEX_BIT )
+
+#define __i2s_set_sample_rate(i2sclk, sync) \
+ ( REG_AIC_I2SDIV = ((i2sclk) / (4*64)) / (sync) )
+
+#define __aic_write_tfifo(v) ( REG_AIC_DR = (v) )
+#define __aic_read_rfifo() ( REG_AIC_DR )
+
+#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC )
+#define __aic_external_codec() ( REG_AIC_FR &= ~AIC_FR_ICDC )
+
+//
+// Define next ops for AC97 compatible
+//
+
+#define AC97_ACSR AIC_ACSR
+
+#define __ac97_enable() __aic_enable(); __aic_select_ac97()
+#define __ac97_disable() __aic_disable()
+#define __ac97_reset() __aic_reset()
+
+#define __ac97_set_transmit_trigger(n) __aic_set_transmit_trigger(n)
+#define __ac97_set_receive_trigger(n) __aic_set_receive_trigger(n)
+
+#define __ac97_enable_record() __aic_enable_record()
+#define __ac97_disable_record() __aic_disable_record()
+#define __ac97_enable_replay() __aic_enable_replay()
+#define __ac97_disable_replay() __aic_disable_replay()
+#define __ac97_enable_loopback() __aic_enable_loopback()
+#define __ac97_disable_loopback() __aic_disable_loopback()
+
+#define __ac97_enable_transmit_dma() __aic_enable_transmit_dma()
+#define __ac97_disable_transmit_dma() __aic_disable_transmit_dma()
+#define __ac97_enable_receive_dma() __aic_enable_receive_dma()
+#define __ac97_disable_receive_dma() __aic_disable_receive_dma()
+
+#define __ac97_transmit_request() __aic_transmit_request()
+#define __ac97_receive_request() __aic_receive_request()
+#define __ac97_transmit_underrun() __aic_transmit_underrun()
+#define __ac97_receive_overrun() __aic_receive_overrun()
+
+#define __ac97_clear_errors() __aic_clear_errors()
+
+#define __ac97_get_transmit_resident() __aic_get_transmit_resident()
+#define __ac97_get_receive_count() __aic_get_receive_count()
+
+#define __ac97_enable_transmit_intr() __aic_enable_transmit_intr()
+#define __ac97_disable_transmit_intr() __aic_disable_transmit_intr()
+#define __ac97_enable_receive_intr() __aic_enable_receive_intr()
+#define __ac97_disable_receive_intr() __aic_disable_receive_intr()
+
+#define __ac97_write_tfifo(v) __aic_write_tfifo(v)
+#define __ac97_read_rfifo() __aic_read_rfifo()
+
+//
+// Define next ops for I2S compatible
+//
+
+#define I2S_ACSR AIC_I2SSR
+
+#define __i2s_enable() __aic_enable(); __aic_select_i2s()
+#define __i2s_disable() __aic_disable()
+#define __i2s_reset() __aic_reset()
+
+#define __i2s_set_transmit_trigger(n) __aic_set_transmit_trigger(n)
+#define __i2s_set_receive_trigger(n) __aic_set_receive_trigger(n)
+
+#define __i2s_enable_record() __aic_enable_record()
+#define __i2s_disable_record() __aic_disable_record()
+#define __i2s_enable_replay() __aic_enable_replay()
+#define __i2s_disable_replay() __aic_disable_replay()
+#define __i2s_enable_loopback() __aic_enable_loopback()
+#define __i2s_disable_loopback() __aic_disable_loopback()
+
+#define __i2s_enable_transmit_dma() __aic_enable_transmit_dma()
+#define __i2s_disable_transmit_dma() __aic_disable_transmit_dma()
+#define __i2s_enable_receive_dma() __aic_enable_receive_dma()
+#define __i2s_disable_receive_dma() __aic_disable_receive_dma()
+
+#define __i2s_transmit_request() __aic_transmit_request()
+#define __i2s_receive_request() __aic_receive_request()
+#define __i2s_transmit_underrun() __aic_transmit_underrun()
+#define __i2s_receive_overrun() __aic_receive_overrun()
+
+#define __i2s_clear_errors() __aic_clear_errors()
+
+#define __i2s_get_transmit_resident() __aic_get_transmit_resident()
+#define __i2s_get_receive_count() __aic_get_receive_count()
+
+#define __i2s_enable_transmit_intr() __aic_enable_transmit_intr()
+#define __i2s_disable_transmit_intr() __aic_disable_transmit_intr()
+#define __i2s_enable_receive_intr() __aic_enable_receive_intr()
+#define __i2s_disable_receive_intr() __aic_disable_receive_intr()
+
+#define __i2s_write_tfifo(v) __aic_write_tfifo(v)
+#define __i2s_read_rfifo() __aic_read_rfifo()
+
+#define __i2s_reset_codec() \
+ do { \
+ } while (0)
+
+
+/*************************************************************************
+ * SPDIF INTERFACE in AIC Controller
+ *************************************************************************/
+
+#define __spdif_enable() ( REG_SPDIF_ENA |= SPDIF_ENA_SPEN )
+#define __spdif_disable() ( REG_SPDIF_ENA &= ~SPDIF_ENA_SPEN )
+
+#define __spdif_enable_transmit_dma() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DMAEN )
+#define __spdif_disable_transmit_dma() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DMAEN )
+#define __spdif_enable_dtype() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DTYPE )
+#define __spdif_disable_dtype() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DTYPE )
+#define __spdif_enable_sign() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SIGN )
+#define __spdif_disable_sign() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SIGN )
+#define __spdif_enable_invalid() ( REG_SPDIF_CTRL |= SPDIF_CTRL_INVALID )
+#define __spdif_disable_invalid() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_INVALID )
+#define __spdif_enable_reset() ( REG_SPDIF_CTRL |= SPDIF_CTRL_RST )
+#define __spdif_select_spdif() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SPDIFI2S )
+#define __spdif_select_i2s() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SPDIFI2S )
+#define __spdif_enable_MTRIGmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MTRIG )
+#define __spdif_disable_MTRIGmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MTRIG )
+#define __spdif_enable_MFFURmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MFFUR )
+#define __spdif_disable_MFFURmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MFFUR )
+
+#define __spdif_enable_initlvl_high() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_INITLVL )
+#define __spdif_enable_initlvl_low() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_INITLVL )
+#define __spdif_enable_zrovld_invald() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_ZROVLD )
+#define __spdif_enable_zrovld_vald() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_ZROVLD )
+
+/* 0, 1, 2, 3 */
+#define __spdif_set_transmit_trigger(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_TRIG_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_TRIG_BIT ); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_srcnum(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_SRCNUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_SRCNUM_BIT); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_ch1num(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH1NUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH1NUM_BIT); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_ch2num(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH2NUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH2NUM_BIT); \
+} while(0)
+
+/* 0x0, 0x2, 0x3, 0xa, 0xe */
+#define __spdif_set_fs(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_FS_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_FS_BIT); \
+} while(0)
+
+/* 0xd, 0xc, 0x5, 0x1 */
+#define __spdif_set_orgfrq(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_ORGFRQ_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_ORGFRQ_BIT); \
+} while(0)
+
+/* 0x1, 0x6, 0x2, 0x4, 0x5 */
+#define __spdif_set_samwl(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_SAMWL_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_SAMWL_BIT); \
+} while(0)
+
+#define __spdif_enable_samwl_24() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_MAXWL )
+#define __spdif_enable_samwl_20() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG2_MAXWL )
+
+/* 0x1, 0x1, 0x2, 0x3 */
+#define __spdif_set_clkacu(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CLKACU_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CLKACU_BIT); \
+} while(0)
+
+/* see IEC60958-3 */
+#define __spdif_set_catcode(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CATCODE_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CATCODE_BIT); \
+} while(0)
+
+/* n = 0x0, */
+#define __spdif_set_chmode(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CHMD_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CHMD_BIT); \
+} while(0)
+
+#define __spdif_enable_pre() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_PRE )
+#define __spdif_disable_pre() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_PRE )
+#define __spdif_enable_copyn() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_COPYN )
+#define __spdif_disable_copyn() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_COPYN )
+/* audio sample word represents linear PCM samples */
+#define __spdif_enable_audion() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_AUDION )
+/* udio sample word used for other purpose */
+#define __spdif_disable_audion() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_AUDION )
+#define __spdif_enable_conpro() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CONPRO )
+#define __spdif_disable_conpro() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_CONPRO )
+
+/***************************************************************************
+ * ICDC
+ ***************************************************************************/
+#define __i2s_internal_codec() __aic_internal_codec()
+#define __i2s_external_codec() __aic_external_codec()
+
+#define __icdc_clk_ready() ( REG_ICDC_CKCFG & ICDC_CKCFG_CKRDY )
+#define __icdc_sel_adc() ( REG_ICDC_CKCFG |= ICDC_CKCFG_SELAD )
+#define __icdc_sel_dac() ( REG_ICDC_CKCFG &= ~ICDC_CKCFG_SELAD )
+
+#define __icdc_set_rgwr() ( REG_ICDC_RGADW |= ICDC_RGADW_RGWR )
+#define __icdc_clear_rgwr() ( REG_ICDC_RGADW &= ~ICDC_RGADW_RGWR )
+#define __icdc_rgwr_ready() ( REG_ICDC_RGADW & ICDC_RGADW_RGWR )
+
+#define __icdc_set_addr(n) \
+do { \
+ REG_ICDC_RGADW &= ~ICDC_RGADW_RGADDR_MASK; \
+ REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGADDR_BIT; \
+} while(0)
+
+#define __icdc_set_cmd(n) \
+do { \
+ REG_ICDC_RGADW &= ~ICDC_RGADW_RGDIN_MASK; \
+ REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGDIN_BIT; \
+} while(0)
+
+#define __icdc_irq_pending() ( REG_ICDC_RGDATA & ICDC_RGDATA_IRQ )
+#define __icdc_get_value() ( REG_ICDC_RGDATA & ICDC_RGDATA_RGDOUT_MASK )
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760AIC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760bch.h b/arch/mips/include/asm/mach-jz4760/jz4760bch.h
new file mode 100644
index 00000000000..3657069b0be
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760bch.h
@@ -0,0 +1,207 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760bch.h
+ *
+ * JZ4760 bch register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760BCH_H__
+#define __JZ4760BCH_H__
+
+
+#define BCH_BASE 0xB34D0000
+
+/*************************************************************************
+ * BCH
+ *************************************************************************/
+#define BCH_CR (BCH_BASE + 0x00) /* BCH Control register */
+#define BCH_CRS (BCH_BASE + 0x04) /* BCH Control Set register */
+#define BCH_CRC (BCH_BASE + 0x08) /* BCH Control Clear register */
+#define BCH_CNT (BCH_BASE + 0x0C) /* BCH ENC/DEC Count register */
+#define BCH_DR (BCH_BASE + 0x10) /* BCH data register */
+#define BCH_PAR0 (BCH_BASE + 0x14) /* BCH Parity 0 register */
+#define BCH_PAR1 (BCH_BASE + 0x18) /* BCH Parity 1 register */
+#define BCH_PAR2 (BCH_BASE + 0x1C) /* BCH Parity 2 register */
+#define BCH_PAR3 (BCH_BASE + 0x20) /* BCH Parity 3 register */
+#define BCH_PAR4 (BCH_BASE + 0x24) /* BCH Parity 4 register */
+#define BCH_PAR5 (BCH_BASE + 0x28) /* BCH Parity 5 register */
+#define BCH_PAR6 (BCH_BASE + 0x2C) /* BCH Parity 6 register */
+#define BCH_PAR7 (BCH_BASE + 0x30) /* BCH Parity 7 register */
+#define BCH_PAR8 (BCH_BASE + 0x34) /* BCH Parity 8 register */
+#define BCH_PAR9 (BCH_BASE + 0x38) /* BCH Parity 9 register */
+#define BCH_ERR0 (BCH_BASE + 0x3C) /* BCH Error Report 0 register */
+#define BCH_ERR1 (BCH_BASE + 0x40) /* BCH Error Report 1 register */
+#define BCH_ERR2 (BCH_BASE + 0x44) /* BCH Error Report 2 register */
+#define BCH_ERR3 (BCH_BASE + 0x48) /* BCH Error Report 3 register */
+#define BCH_ERR4 (BCH_BASE + 0x4C) /* BCH Error Report 4 register */
+#define BCH_ERR5 (BCH_BASE + 0x50) /* BCH Error Report 5 register */
+#define BCH_ERR6 (BCH_BASE + 0x54) /* BCH Error Report 6 register */
+#define BCH_ERR7 (BCH_BASE + 0x58) /* BCH Error Report 7 register */
+#define BCH_ERR8 (BCH_BASE + 0x5C) /* BCH Error Report 8 register */
+#define BCH_ERR9 (BCH_BASE + 0x60) /* BCH Error Report 9 register */
+#define BCH_ERR10 (BCH_BASE + 0x64) /* BCH Error Report 10 register */
+#define BCH_ERR11 (BCH_BASE + 0x68) /* BCH Error Report 11 register */
+#define BCH_INTS (BCH_BASE + 0x6C) /* BCH Interrupt Status register */
+#define BCH_INTES (BCH_BASE + 0x70) /* BCH Interrupt Enable register */
+#define BCH_INTEC (BCH_BASE + 0x74) /* BCH Interrupt Set register */
+#define BCH_INTE (BCH_BASE + 0x78) /* BCH Interrupt Clear register */
+
+#define REG_BCH_CR REG32(BCH_CR)
+#define REG_BCH_CRS REG32(BCH_CRS)
+#define REG_BCH_CRC REG32(BCH_CRC)
+#define REG_BCH_CNT REG32(BCH_CNT)
+#define REG_BCH_DR REG8(BCH_DR)
+#define REG_BCH_PAR0 REG32(BCH_PAR0)
+#define REG_BCH_PAR1 REG32(BCH_PAR1)
+#define REG_BCH_PAR2 REG32(BCH_PAR2)
+#define REG_BCH_PAR3 REG32(BCH_PAR3)
+#define REG_BCH_PAR4 REG32(BCH_PAR4)
+#define REG_BCH_PAR5 REG32(BCH_PAR5)
+#define REG_BCH_PAR6 REG32(BCH_PAR6)
+#define REG_BCH_PAR7 REG32(BCH_PAR7)
+#define REG_BCH_PAR8 REG32(BCH_PAR8)
+#define REG_BCH_PAR9 REG32(BCH_PAR9)
+#define REG_BCH_ERR0 REG32(BCH_ERR0)
+#define REG_BCH_ERR1 REG32(BCH_ERR1)
+#define REG_BCH_ERR2 REG32(BCH_ERR2)
+#define REG_BCH_ERR3 REG32(BCH_ERR3)
+#define REG_BCH_ERR4 REG32(BCH_ERR4)
+#define REG_BCH_ERR5 REG32(BCH_ERR5)
+#define REG_BCH_ERR6 REG32(BCH_ERR6)
+#define REG_BCH_ERR7 REG32(BCH_ERR7)
+#define REG_BCH_ERR8 REG32(BCH_ERR8)
+#define REG_BCH_ERR9 REG32(BCH_ERR9)
+#define REG_BCH_ERR10 REG32(BCH_ERR10)
+#define REG_BCH_ERR11 REG32(BCH_ERR11)
+#define REG_BCH_INTS REG32(BCH_INTS)
+#define REG_BCH_INTE REG32(BCH_INTE)
+#define REG_BCH_INTEC REG32(BCH_INTEC)
+#define REG_BCH_INTES REG32(BCH_INTES)
+
+/* BCH Control Register*/
+#define BCH_CR_DMAE (1 << 7) /* BCH DMA Enable */
+#define BCH_CR_BSEL_BIT 3
+#define BCH_CR_BSEL_MASK (0x3 << BCH_CR_BSEL_BIT)
+ #define BCH_CR_BSEL_4 (0x0 << BCH_CR_BSEL_BIT) /* 4 Bit BCH Select */
+ #define BCH_CR_BSEL_8 (0x1 << BCH_CR_BSEL_BIT) /* 8 Bit BCH Select */
+ #define BCH_CR_BSEL_12 (0x2 << BCH_CR_BSEL_BIT) /* 12 Bit BCH Select */
+ #define BCH_CR_BSEL_16 (0x3 << BCH_CR_BSEL_BIT) /* 16 Bit BCH Select */
+ #define BCH_CR_BSEL_20 (0x4 << BCH_CR_BSEL_BIT) /* 20 Bit BCH Select */
+ #define BCH_CR_BSEL_24 (0x5 << BCH_CR_BSEL_BIT) /* 24 Bit BCH Select */
+#define BCH_CR_ENCE (1 << 2) /* BCH Encoding Select */
+#define BCH_CR_DECE (0 << 2) /* BCH Decoding Select */
+#define BCH_CR_BRST (1 << 1) /* BCH Reset */
+#define BCH_CR_BCHE (1 << 0) /* BCH Enable */
+
+/* BCH Interrupt Status Register */
+#define BCH_INTS_ERRC_BIT 27
+#define BCH_INTS_ERRC_MASK (0x1f << BCH_INTS_ERRC_BIT)
+#define BCH_INTS_ALL0 (1 << 5)
+#define BCH_INTS_ALLf (1 << 4)
+#define BCH_INTS_DECF (1 << 3)
+#define BCH_INTS_ENCF (1 << 2)
+#define BCH_INTS_UNCOR (1 << 1)
+#define BCH_INTS_ERR (1 << 0)
+
+/* BCH ENC/DEC Count Register */
+#define BCH_CNT_DEC_BIT 16
+#define BCH_CNT_DEC_MASK (0x7ff << BCH_CNT_DEC_BIT)
+#define BCH_CNT_ENC_BIT 0
+#define BCH_CNT_ENC_MASK (0x7ff << BCH_CNT_ENC_BIT)
+
+/* BCH Error Report Register */
+#define BCH_ERR_INDEX_ODD_BIT 0
+#define BCH_ERR_INDEX_ODD_MASK (0x1fff << BCH_ERR_INDEX_ODD_BIT)
+#define BCH_ERR_INDEX_EVEN_BIT 16
+#define BCH_ERR_INDEX_EVEN_MASK (0x1fff << BCH_ERR_INDEX_EVEN_BIT)
+#define BCH_ERR_INDEX_MASK 0x1fff
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * BCH
+ *************************************************************************/
+#define __ecc_encoding_4bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_4 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_4 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_4bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_4 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_4 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_8bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_8 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_8 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_8bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_8 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_8 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_12bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_12 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_12 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_12bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_12 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_12 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_16bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_16 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_16 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_16bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_16 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_16 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_20bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_20 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_20 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_20bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_20 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_20 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_24bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_24 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_24 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_24bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_24 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_24 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_dma_enable() ( REG_BCH_CRS = BCH_CR_DMAE )
+#define __ecc_dma_disable() ( REG_BCH_CRC = BCH_CR_DMAE )
+#define __ecc_disable() ( REG_BCH_CRC = BCH_CR_BCHE )
+#define __ecc_encode_sync() while (!(REG_BCH_INTS & BCH_INTS_ENCF))
+#define __ecc_decode_sync() while (!(REG_BCH_INTS & BCH_INTS_DECF))
+
+#define __ecc_cnt_dec(n) \
+do { \
+ REG_BCH_CNT &= ~BCH_CNT_DEC_MASK; \
+ REG_BCH_CNT |= (n) << BCH_CNT_DEC_BIT; \
+} while(0)
+#define __ecc_cnt_enc(n) \
+do { \
+ REG_BCH_CNT &= ~BCH_CNT_ENC_MASK; \
+ REG_BCH_CNT |= (n) << BCH_CNT_ENC_BIT; \
+} while(0)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760BCH_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760bdma.h b/arch/mips/include/asm/mach-jz4760/jz4760bdma.h
new file mode 100644
index 00000000000..0669c09138a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760bdma.h
@@ -0,0 +1,297 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760bdma.h
+ *
+ * JZ4760 BDMA register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760BDMA_H__
+#define __JZ4760BDMA_H__
+
+
+#define BDMAC_BASE 0xB3450000
+
+
+/*************************************************************************
+ * BDMAC (BCH & NAND DMA Controller)
+ *************************************************************************/
+
+/* n is the DMA channel index (0 - 2) */
+#define BDMAC_DSAR(n) (BDMAC_BASE + (0x00 + (n) * 0x20)) /* DMA source address */
+#define BDMAC_DTAR(n) (BDMAC_BASE + (0x04 + (n) * 0x20)) /* DMA target address */
+#define BDMAC_DTCR(n) (BDMAC_BASE + (0x08 + (n) * 0x20)) /* DMA transfer count */
+#define BDMAC_DRSR(n) (BDMAC_BASE + (0x0c + (n) * 0x20)) /* DMA request source */
+#define BDMAC_DCCSR(n) (BDMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */
+#define BDMAC_DCMD(n) (BDMAC_BASE + (0x14 + (n) * 0x20)) /* DMA command */
+#define BDMAC_DDA(n) (BDMAC_BASE + (0x18 + (n) * 0x20)) /* DMA descriptor address */
+#define BDMAC_DSD(n) (BDMAC_BASE + (0x1c + (n) * 0x20)) /* DMA Stride Address */
+#define BDMAC_DNT(n) (BDMAC_BASE + (0xc0 + (n) * 0x04)) /* NAND Detect Timer */
+
+#define BDMAC_DMACR (BDMAC_BASE + 0x0300) /* DMA control register */
+#define BDMAC_DMAIPR (BDMAC_BASE + 0x0304) /* DMA interrupt pending */
+#define BDMAC_DMADBR (BDMAC_BASE + 0x0308) /* DMA doorbell */
+#define BDMAC_DMADBSR (BDMAC_BASE + 0x030C) /* DMA doorbell set */
+#define BDMAC_DMACKE (BDMAC_BASE + 0x0310)
+
+#define REG_BDMAC_DSAR(n) REG32(BDMAC_DSAR((n)))
+#define REG_BDMAC_DTAR(n) REG32(BDMAC_DTAR((n)))
+#define REG_BDMAC_DTCR(n) REG32(BDMAC_DTCR((n)))
+#define REG_BDMAC_DRSR(n) REG32(BDMAC_DRSR((n)))
+#define REG_BDMAC_DCCSR(n) REG32(BDMAC_DCCSR((n)))
+#define REG_BDMAC_DCMD(n) REG32(BDMAC_DCMD((n)))
+#define REG_BDMAC_DDA(n) REG32(BDMAC_DDA((n)))
+#define REG_BDMAC_DSD(n) REG32(BDMAC_DSD(n))
+#define REG_BDMAC_DNT(n) REG32(BDMAC_DNT(n))
+
+#define REG_BDMAC_DMACR REG32(BDMAC_DMACR)
+#define REG_BDMAC_DMAIPR REG32(BDMAC_DMAIPR)
+#define REG_BDMAC_DMADBR REG32(BDMAC_DMADBR)
+#define REG_BDMAC_DMADBSR REG32(BDMAC_DMADBSR)
+#define REG_BDMAC_DMACKE REG32(BDMAC_DMACKE)
+
+// BDMA request source register
+#define BDMAC_DRSR_RS_BIT 0
+ #define BDMAC_DRSR_RS_MASK (0x3f << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_NAND (1 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_BCH_ENC (2 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_BCH_DEC (3 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_EXT (12 << DMAC_DRSR_RS_BIT)
+
+// BDMA channel control/status register
+#define BDMAC_DCCSR_NDES (1 << 31) /* descriptor (0) or not (1) ? */
+#define BDMAC_DCCSR_DES8 (1 << 30) /* Descriptor 8 Word */
+#define BDMAC_DCCSR_DES4 (0 << 30) /* Descriptor 4 Word */
+#define BDMAC_DCCSR_CDOA_BIT 16 /* copy of DMA offset address */
+ #define BDMAC_DCCSR_CDOA_MASK (0xff << BDMACC_DCCSR_CDOA_BIT)
+#define BDMAC_DCCSR_BERR (1 << 7) /* BCH error within this transfer, Only for channel 0 */
+#define BDMAC_DCCSR_AR (1 << 4) /* address error */
+#define BDMAC_DCCSR_TT (1 << 3) /* transfer terminated */
+#define BDMAC_DCCSR_HLT (1 << 2) /* DMA halted */
+#define BDMAC_DCCSR_EN (1 << 0) /* channel enable bit */
+
+// BDMA channel command register
+#define BDMAC_DCMD_EACKS_LOW (1 << 31) /* External DACK Output Level Select, active low */
+#define BDMAC_DCMD_EACKS_HIGH (0 << 31) /* External DACK Output Level Select, active high */
+#define BDMAC_DCMD_EACKM_WRITE (1 << 30) /* External DACK Output Mode Select, output in write cycle */
+#define BDMAC_DCMD_EACKM_READ (0 << 30) /* External DACK Output Mode Select, output in read cycle */
+#define BDMAC_DCMD_ERDM_BIT 28 /* External DREQ Detection Mode Select */
+ #define BDMAC_DCMD_ERDM_MASK (0x03 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_LOW (0 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_FALL (1 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_HIGH (2 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_RISE (3 << BDMAC_DCMD_ERDM_BIT)
+#define BDMAC_DCMD_BLAST (1 << 25) /* BCH last */
+#define BDMAC_DCMD_SAI (1 << 23) /* source address increment */
+#define BDMAC_DCMD_DAI (1 << 22) /* dest address increment */
+#define BDMAC_DCMD_SWDH_BIT 14 /* source port width */
+ #define BDMAC_DCMD_SWDH_MASK (0x03 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_32 (0 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_8 (1 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_16 (2 << BDMAC_DCMD_SWDH_BIT)
+#define BDMAC_DCMD_DWDH_BIT 12 /* dest port width */
+ #define BDMAC_DCMD_DWDH_MASK (0x03 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_32 (0 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_8 (1 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_16 (2 << BDMAC_DCMD_DWDH_BIT)
+#define BDMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */
+ #define BDMAC_DCMD_DS_MASK (0x07 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_32BIT (0 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_8BIT (1 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_16BIT (2 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_16BYTE (3 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_32BYTE (4 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_64BYTE (5 << BDMAC_DCMD_DS_BIT)
+#define BDMAC_DCMD_NRD (1 << 7) /* NAND direct read */
+#define BDMAC_DCMD_NWR (1 << 6) /* NAND direct write */
+#define BDMAC_DCMD_NAC (1 << 5) /* NAND AL/CL enable */
+#define BDMAC_DCMD_STDE (1 << 2) /* Stride Disable/Enable */
+#define BDMAC_DCMD_TIE (1 << 1) /* DMA transfer interrupt enable */
+#define BDMAC_DCMD_LINK (1 << 0) /* descriptor link enable */
+
+// BDMA descriptor address register
+#define BDMAC_DDA_BASE_BIT 12 /* descriptor base address */
+ #define BDMAC_DDA_BASE_MASK (0x0fffff << BDMAC_DDA_BASE_BIT)
+#define BDMAC_DDA_OFFSET_BIT 4 /* descriptor offset address */
+ #define BDMAC_DDA_OFFSET_MASK (0x0ff << BDMAC_DDA_OFFSET_BIT)
+
+// BDMA stride address register
+#define BDMAC_DSD_TSD_BIT 16 /* target stride address */
+ #define BDMAC_DSD_TSD_MASK (0xffff << BDMAC_DSD_TSD_BIT)
+#define BDMAC_DSD_SSD_BIT 0 /* source stride address */
+ #define BDMAC_DSD_SSD_MASK (0xffff << BDMAC_DSD_SSD_BIT)
+
+// BDMA NAND Detect timer register
+#define BDMAC_NDTCTIMER_EN (1 << 15) /* enable detect timer */
+#define BDMAC_TAILCNT_BIT 16
+
+// BDMA control register
+#define BDMAC_DMACR_PR_BIT 8 /* channel priority mode */
+ #define BDMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_01_2 (0 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_12_0 (1 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_20_1 (2 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_012 (3 << BDMAC_DMACR_PR_BIT)
+#define BDMAC_DMACR_HLT (1 << 3) /* DMA halt flag */
+#define BDMAC_DMACR_AR (1 << 2) /* address error flag */
+#define BDMAC_DMACR_DMAE (1 << 0) /* DMA enable bit */
+
+// BDMA interrupt pending register
+#define BDMAC_DMAIPR_CIRQ2 (1 << 2) /* irq pending status for channel 2 */
+#define BDMAC_DMAIPR_CIRQ1 (1 << 1) /* irq pending status for channel 1 */
+#define BDMAC_DMAIPR_CIRQ0 (1 << 0) /* irq pending status for channel 0 */
+
+// BDMA doorbell register
+#define BDMAC_DMADBR_DB2 (1 << 2) /* doorbell for channel 2 */
+#define BDMAC_DMADBR_DB1 (1 << 1) /* doorbell for channel 1 */
+#define BDMAC_DMADBR_DB0 (1 << 0) /* doorbell for channel 0 */
+
+// BDMA doorbell set register
+#define BDMAC_DMADBSR_DBS2 (1 << 2) /* enable doorbell for channel 2 */
+#define BDMAC_DMADBSR_DBS1 (1 << 1) /* enable doorbell for channel 1 */
+#define BDMAC_DMADBSR_DBS0 (1 << 0) /* enable doorbell for channel 0 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * BCH & NAND DMAC
+ ***************************************************************************/
+
+/* n is the DMA channel index (0 - 2) */
+
+#define __bdmac_test_halt_error ( REG_BDMAC_DMACR & BDMAC_DMACR_HLT )
+#define __bdmac_test_addr_error ( REG_BDMAC_DMACR & BDMAC_DMACR_AR )
+
+#define __bdmac_channel_enable_clk(n) \
+ REG_BDMAC_DMACKE |= 1 << (n);
+
+#define __bdmac_enable_descriptor(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_NDES )
+#define __bdmac_disable_descriptor(n) \
+ ( REG_BDMAC_DCCSR((n)) |= BDMAC_DCCSR_NDES )
+
+#define __bdmac_enable_channel(n) \
+do { \
+ REG_BDMAC_DCCSR((n)) |= BDMAC_DCCSR_EN; \
+} while (0)
+#define __bdmac_disable_channel(n) \
+do { \
+ REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_EN; \
+} while (0)
+
+#define __bdmac_channel_enable_irq(n) \
+ ( REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_TIE )
+#define __bdmac_channel_disable_irq(n) \
+ ( REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_TIE )
+
+#define __bdmac_channel_transmit_halt_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_HLT )
+#define __bdmac_channel_transmit_end_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_TT )
+#define __bdmac_channel_address_error_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_AR )
+#define __bdmac_channel_count_terminated_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_CT )
+#define __bdmac_channel_descriptor_invalid_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_INV )
+#define __bdmac_BCH_error_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_BERR )
+
+#define __bdmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_HLT; \
+ REG_BDMAC_DMACR &= ~BDMAC_DMACR_HLT; \
+ } while (0)
+#define __bdmac_channel_clear_transmit_end(n) \
+ ( REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_TT )
+#define __bdmac_channel_clear_address_error(n) \
+ do { \
+ REG_BDMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_BDMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_BDMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_AR; \
+ REG_BDMAC_DMACR &= ~BDMAC_DMACR_AR; \
+ } while (0)
+#define __bdmac_channel_clear_count_terminated(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_CT )
+#define __bdmac_channel_clear_descriptor_invalid(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_INV )
+
+#define __bdmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __bdmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DWDH_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __bdmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_SWDH_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_SWDH_##w; \
+} while (0)
+
+#define __bdmac_channel_dest_addr_fixed(n) \
+ (REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DAI)
+#define __bdmac_channel_dest_addr_increment(n) \
+ (REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DAI)
+
+#define __bdmac_channel_src_addr_fixed(n) \
+ (REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_SAI)
+#define __bdmac_channel_src_addr_increment(n) \
+ (REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_SAI)
+
+#define __bdmac_channel_set_doorbell(n) \
+ (REG_BDMAC_DMADBSR = (1 << (n)))
+
+#define __bdmac_channel_irq_detected(n) (REG_BDMAC_DMAIPR & (1 << (n)))
+#define __bdmac_channel_ack_irq(n) (REG_BDMAC_DMAIPR &= ~(1 <<(n)))
+
+static __inline__ int __bdmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_BDMA_NUM; i++)
+ if (__bdmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760BDMA_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760cim.h b/arch/mips/include/asm/mach-jz4760/jz4760cim.h
new file mode 100644
index 00000000000..14c56f1471a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760cim.h
@@ -0,0 +1,350 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760cim.h
+ *
+ * JZ4760 CIM register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760CIM_H__
+#define __JZ4760CIM_H__
+
+
+#define CIM_BASE 0xB3060000
+
+/*************************************************************************
+ * CIM
+ *************************************************************************/
+#define CIM_CFG (CIM_BASE + 0x0000)
+#define CIM_CTRL (CIM_BASE + 0x0004)
+#define CIM_STATE (CIM_BASE + 0x0008)
+#define CIM_IID (CIM_BASE + 0x000C)
+#define CIM_RXFIFO (CIM_BASE + 0x0010)
+#define CIM_DA (CIM_BASE + 0x0020)
+#define CIM_FA (CIM_BASE + 0x0024)
+#define CIM_FID (CIM_BASE + 0x0028)
+#define CIM_CMD (CIM_BASE + 0x002C)
+#define CIM_SIZE (CIM_BASE + 0x0030)
+#define CIM_OFFSET (CIM_BASE + 0x0034)
+#define CIM_RAM_ADDR (CIM_BASE + 0x1000)
+
+#define REG_CIM_CFG REG32(CIM_CFG)
+#define REG_CIM_CTRL REG32(CIM_CTRL)
+#define REG_CIM_STATE REG32(CIM_STATE)
+#define REG_CIM_IID REG32(CIM_IID)
+#define REG_CIM_RXFIFO REG32(CIM_RXFIFO)
+#define REG_CIM_DA REG32(CIM_DA)
+#define REG_CIM_FA REG32(CIM_FA)
+#define REG_CIM_FID REG32(CIM_FID)
+#define REG_CIM_CMD REG32(CIM_CMD)
+#define REG_CIM_SIZE REG32(CIM_SIZE)
+#define REG_CIM_OFFSET REG32(CIM_OFFSET)
+
+#define CIM_CFG_ORDER_BIT 18
+#define CIM_CFG_ORDER_MASK (0x3 << CIM_CFG_ORDER_BIT)
+ #define CIM_CFG_ORDER_0 (0x0 << CIM_CFG_ORDER_BIT) /* Y0CbY1Cr; YCbCr */
+ #define CIM_CFG_ORDER_1 (0x1 << CIM_CFG_ORDER_BIT) /* Y0CrY1Cb; YCrCb */
+ #define CIM_CFG_ORDER_2 (0x2 << CIM_CFG_ORDER_BIT) /* CbY0CrY1; CbCrY */
+ #define CIM_CFG_ORDER_3 (0x3 << CIM_CFG_ORDER_BIT) /* CrY0CbY1; CrCbY */
+#define CIM_CFG_DF_BIT 16
+#define CIM_CFG_DF_MASK (0x3 << CIM_CFG_DF_BIT)
+ #define CIM_CFG_DF_YUV444 (0x1 << CIM_CFG_DF_BIT) /* YCbCr444 */
+ #define CIM_CFG_DF_YUV422 (0x2 << CIM_CFG_DF_BIT) /* YCbCr422 */
+ #define CIM_CFG_DF_ITU656 (0x3 << CIM_CFG_DF_BIT) /* ITU656 YCbCr422 */
+#define CIM_CFG_INV_DAT (1 << 15)
+#define CIM_CFG_VSP (1 << 14) /* VSYNC Polarity:0-rising edge active,1-falling edge active */
+#define CIM_CFG_HSP (1 << 13) /* HSYNC Polarity:0-rising edge active,1-falling edge active */
+#define CIM_CFG_PCP (1 << 12) /* PCLK working edge: 0-rising, 1-falling */
+#define CIM_CFG_DMA_BURST_TYPE_BIT 10
+#define CIM_CFG_DMA_BURST_TYPE_MASK (0x3 << CIM_CFG_DMA_BURST_TYPE_BIT)
+ #define CIM_CFG_DMA_BURST_INCR4 (0 << CIM_CFG_DMA_BURST_TYPE_BIT)
+ #define CIM_CFG_DMA_BURST_INCR8 (1 << CIM_CFG_DMA_BURST_TYPE_BIT) /* Suggested */
+ #define CIM_CFG_DMA_BURST_INCR16 (2 << CIM_CFG_DMA_BURST_TYPE_BIT) /* Suggested High speed AHB*/
+#define CIM_CFG_DUMMY_ZERO (1 << 9)
+#define CIM_CFG_EXT_VSYNC (1 << 8) /* Only for ITU656 Progressive mode */
+#define CIM_CFG_PACK_BIT 4
+#define CIM_CFG_PACK_MASK (0x7 << CIM_CFG_PACK_BIT)
+ #define CIM_CFG_PACK_0 (0 << CIM_CFG_PACK_BIT) /* 11 22 33 44 0xY0CbY1Cr */
+ #define CIM_CFG_PACK_1 (1 << CIM_CFG_PACK_BIT) /* 22 33 44 11 0xCbY1CrY0 */
+ #define CIM_CFG_PACK_2 (2 << CIM_CFG_PACK_BIT) /* 33 44 11 22 0xY1CrY0Cb */
+ #define CIM_CFG_PACK_3 (3 << CIM_CFG_PACK_BIT) /* 44 11 22 33 0xCrY0CbY1 */
+ #define CIM_CFG_PACK_4 (4 << CIM_CFG_PACK_BIT) /* 44 33 22 11 0xCrY1CbY0 */
+ #define CIM_CFG_PACK_5 (5 << CIM_CFG_PACK_BIT) /* 33 22 11 44 0xY1CbY0Cr */
+ #define CIM_CFG_PACK_6 (6 << CIM_CFG_PACK_BIT) /* 22 11 44 33 0xCbY0CrY1 */
+ #define CIM_CFG_PACK_7 (7 << CIM_CFG_PACK_BIT) /* 11 44 33 22 0xY0CrY1Cb */
+#define CIM_CFG_BYPASS_BIT 2
+#define CIM_CFG_BYPASS_MASK (1 << CIM_CFG_BYPASS_BIT)
+ #define CIM_CFG_BYPASS (1 << CIM_CFG_BYPASS_BIT)
+#define CIM_CFG_DSM_BIT 0
+#define CIM_CFG_DSM_MASK (0x3 << CIM_CFG_DSM_BIT)
+ #define CIM_CFG_DSM_CPM (0 << CIM_CFG_DSM_BIT) /* CCIR656 Progressive Mode */
+ #define CIM_CFG_DSM_CIM (1 << CIM_CFG_DSM_BIT) /* CCIR656 Interlace Mode */
+ #define CIM_CFG_DSM_GCM (2 << CIM_CFG_DSM_BIT) /* Gated Clock Mode */
+
+/* CIM Control Register (CIM_CTRL) */
+#define CIM_CTRL_EEOF_LINE_BIT 20
+#define CIM_CTRL_EEOF_LINE_MASK (0xfff << CIM_CTRL_EEOF_LINE_BIT)
+#define CIM_CTRL_FRC_BIT 16
+#define CIM_CTRL_FRC_MASK (0xf << CIM_CTRL_FRC_BIT)
+ #define CIM_CTRL_FRC_1 (0x0 << CIM_CTRL_FRC_BIT) /* Sample every frame */
+ #define CIM_CTRL_FRC_2 (0x1 << CIM_CTRL_FRC_BIT) /* Sample 1/2 frame */
+ #define CIM_CTRL_FRC_3 (0x2 << CIM_CTRL_FRC_BIT) /* Sample 1/3 frame */
+ #define CIM_CTRL_FRC_4 (0x3 << CIM_CTRL_FRC_BIT) /* Sample 1/4 frame */
+ #define CIM_CTRL_FRC_5 (0x4 << CIM_CTRL_FRC_BIT) /* Sample 1/5 frame */
+ #define CIM_CTRL_FRC_6 (0x5 << CIM_CTRL_FRC_BIT) /* Sample 1/6 frame */
+ #define CIM_CTRL_FRC_7 (0x6 << CIM_CTRL_FRC_BIT) /* Sample 1/7 frame */
+ #define CIM_CTRL_FRC_8 (0x7 << CIM_CTRL_FRC_BIT) /* Sample 1/8 frame */
+ #define CIM_CTRL_FRC_9 (0x8 << CIM_CTRL_FRC_BIT) /* Sample 1/9 frame */
+ #define CIM_CTRL_FRC_10 (0x9 << CIM_CTRL_FRC_BIT) /* Sample 1/10 frame */
+ #define CIM_CTRL_FRC_11 (0xA << CIM_CTRL_FRC_BIT) /* Sample 1/11 frame */
+ #define CIM_CTRL_FRC_12 (0xB << CIM_CTRL_FRC_BIT) /* Sample 1/12 frame */
+ #define CIM_CTRL_FRC_13 (0xC << CIM_CTRL_FRC_BIT) /* Sample 1/13 frame */
+ #define CIM_CTRL_FRC_14 (0xD << CIM_CTRL_FRC_BIT) /* Sample 1/14 frame */
+ #define CIM_CTRL_FRC_15 (0xE << CIM_CTRL_FRC_BIT) /* Sample 1/15 frame */
+ #define CIM_CTRL_FRC_16 (0xF << CIM_CTRL_FRC_BIT) /* Sample 1/16 frame */
+
+#define CIM_CTRL_DMA_EEOF (1 << 15) /* Enable EEOF interrupt */
+#define CIM_CTRL_WIN_EN (1 << 14)
+#define CIM_CTRL_VDDM (1 << 13) /* VDD interrupt enable */
+#define CIM_CTRL_DMA_SOFM (1 << 12)
+#define CIM_CTRL_DMA_EOFM (1 << 11)
+#define CIM_CTRL_DMA_STOPM (1 << 10)
+#define CIM_CTRL_RXF_TRIGM (1 << 9)
+#define CIM_CTRL_RXF_OFM (1 << 8)
+#define CIM_CTRL_DMA_SYNC (1 << 7) /*when change DA, do frame sync */
+#define CIM_CTRL_RXF_TRIG_BIT 3
+#define CIM_CTRL_RXF_TRIG_MASK (0xf << CIM_CTRL_RXF_TRIG_BIT) /* trigger value = (n+1)*burst_type */
+
+#define CIM_CTRL_DMA_EN (1 << 2) /* Enable DMA */
+#define CIM_CTRL_RXF_RST (1 << 1) /* RxFIFO reset */
+#define CIM_CTRL_ENA (1 << 0) /* Enable CIM */
+
+/* CIM State Register (CIM_STATE) */
+#define CIM_STATE_DMA_EEOF (1 << 7) /* DMA Line EEOf irq */
+#define CIM_STATE_DMA_SOF (1 << 6) /* DMA start irq */
+#define CIM_STATE_DMA_EOF (1 << 5) /* DMA end irq */
+#define CIM_STATE_DMA_STOP (1 << 4) /* DMA stop irq */
+#define CIM_STATE_RXF_OF (1 << 3) /* RXFIFO over flow irq */
+#define CIM_STATE_RXF_TRIG (1 << 2) /* RXFIFO triger meet irq */
+#define CIM_STATE_RXF_EMPTY (1 << 1) /* RXFIFO empty irq */
+#define CIM_STATE_VDD (1 << 0) /* CIM disabled irq */
+
+/* CIM DMA Command Register (CIM_CMD) */
+
+#define CIM_CMD_SOFINT (1 << 31) /* enable DMA start irq */
+#define CIM_CMD_EOFINT (1 << 30) /* enable DMA end irq */
+#define CIM_CMD_EEOFINT (1 << 29) /* enable DMA EEOF irq */
+#define CIM_CMD_STOP (1 << 28) /* enable DMA stop irq */
+#define CIM_CMD_OFRCV (1 << 27) /* enable recovery when TXFiFo overflow */
+#define CIM_CMD_LEN_BIT 0
+#define CIM_CMD_LEN_MASK (0xffffff << CIM_CMD_LEN_BIT)
+
+/* CIM Window-Image Size Register (CIM_SIZE) */
+#define CIM_SIZE_LPF_BIT 16 /* Lines per freame for csc output image */
+#define CIM_SIZE_LPF_MASK (0x1fff << CIM_SIZE_LPF_BIT)
+#define CIM_SIZE_PPL_BIT 0 /* Pixels per line for csc output image, should be an even number */
+#define CIM_SIZE_PPL_MASK (0x1fff << CIM_SIZE_PPL_BIT)
+
+/* CIM Image Offset Register (CIM_OFFSET) */
+#define CIM_OFFSET_V_BIT 16 /* Vertical offset */
+#define CIM_OFFSET_V_MASK (0xfff << CIM_OFFSET_V_BIT)
+#define CIM_OFFSET_H_BIT 0 /* Horizontal offset, should be an enen number */
+#define CIM_OFFSET_H_MASK (0xfff << CIM_OFFSET_H_BIT) /*OFFSET_H should be even number*/
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * CIM
+ ***************************************************************************/
+
+#define __cim_enable() ( REG_CIM_CTRL |= CIM_CTRL_ENA )
+#define __cim_disable() ( REG_CIM_CTRL &= ~CIM_CTRL_ENA )
+
+/* n = 0, 1, 2, 3 */
+#define __cim_set_input_data_stream_order(n) \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_ORDER_MASK; \
+ REG_CIM_CFG |= ((n)<<CIM_CFG_ORDER_BIT)&CIM_CFG_ORDER_MASK; \
+ } while (0)
+
+#define __cim_input_data_format_select_RGB() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_RGB; \
+ } while (0)
+
+#define __cim_input_data_format_select_YUV444() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_YUV444; \
+ } while (0)
+
+#define __cim_input_data_format_select_YUV422() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_YUV422; \
+ } while (0)
+
+#define __cim_input_data_format_select_ITU656() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_ITU656; \
+ } while (0)
+
+#define __cim_input_data_inverse() ( REG_CIM_CFG |= CIM_CFG_INV_DAT )
+#define __cim_input_data_normal() ( REG_CIM_CFG &= ~CIM_CFG_INV_DAT )
+
+#define __cim_vsync_active_low() ( REG_CIM_CFG |= CIM_CFG_VSP )
+#define __cim_vsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_VSP )
+
+#define __cim_hsync_active_low() ( REG_CIM_CFG |= CIM_CFG_HSP )
+#define __cim_hsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_HSP )
+
+#define __cim_sample_data_at_pclk_falling_edge() \
+ ( REG_CIM_CFG |= CIM_CFG_PCP )
+#define __cim_sample_data_at_pclk_rising_edge() \
+ ( REG_CIM_CFG &= ~CIM_CFG_PCP )
+
+#define __cim_enable_dummy_zero() ( REG_CIM_CFG |= CIM_CFG_DUMMY_ZERO )
+#define __cim_disable_dummy_zero() ( REG_CIM_CFG &= ~CIM_CFG_DUMMY_ZERO )
+
+#define __cim_select_external_vsync() ( REG_CIM_CFG |= CIM_CFG_EXT_VSYNC )
+#define __cim_select_internal_vsync() ( REG_CIM_CFG &= ~CIM_CFG_EXT_VSYNC )
+
+/* n=0-7 */
+#define __cim_set_data_packing_mode(n) \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_PACK_MASK; \
+ REG_CIM_CFG |= (CIM_CFG_PACK_##n); \
+} while (0)
+
+#define __cim_enable_bypass_func() (REG_CIM_CFG |= CIM_CFG_BYPASS)
+#define __cim_disable_bypass_func() (REG_CIM_CFG &= ~CIM_CFG_BYPASS_MASK)
+
+#define __cim_enable_ccir656_progressive_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_CPM; \
+} while (0)
+
+#define __cim_enable_ccir656_interlace_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_CIM; \
+} while (0)
+
+#define __cim_enable_gated_clock_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_GCM; \
+} while (0)
+
+#define __cim_enable_nongated_clock_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_NGCM; \
+} while (0)
+
+/* sclk:system bus clock
+ * mclk: CIM master clock
+ */
+#define __cim_set_master_clk(sclk, mclk) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_MCLKDIV_MASK; \
+ REG_CIM_CTRL |= (((sclk)/(mclk) - 1) << CIM_CTRL_MCLKDIV_BIT); \
+} while (0)
+/* n=1-16 */
+#define __cim_set_frame_rate(n) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_FRC_MASK; \
+ REG_CIM_CTRL |= CIM_CTRL_FRC_##n; \
+} while (0)
+
+#define __cim_enable_size_func() \
+ ( REG_CIM_CTRL |= CIM_CTRL_WIN_EN)
+#define __cim_disable_size_func() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_WIN_EN )
+
+#define __cim_enable_vdd_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_VDDM )
+#define __cim_disable_vdd_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_VDDM )
+
+#define __cim_enable_sof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_SOFM )
+#define __cim_disable_sof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_SOFM )
+
+#define __cim_enable_eof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_EOFM )
+#define __cim_disable_eof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EOFM )
+
+#define __cim_enable_eeof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_EEOFM )
+#define __cim_disable_eeof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EEOFM )
+
+#define __cim_enable_stop_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_STOPM )
+#define __cim_disable_stop_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_STOPM )
+
+#define __cim_enable_trig_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_TRIGM )
+#define __cim_disable_trig_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIGM )
+
+#define __cim_enable_rxfifo_overflow_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_OFM )
+#define __cim_disable_rxfifo_overflow_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_OFM )
+
+/* n=4,8,12,16,20,24,28,32 */
+#define __cim_set_rxfifo_trigger(n) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIG_MASK; \
+ REG_CIM_CTRL |= CIM_CTRL_RXF_TRIG_##n; \
+} while (0)
+#define __cim_enable_fast_mode() ( REG_CIM_CTRL |= CIM_CTRL_FAST_MODE )
+#define __cim_disable_fast_mode() ( REG_CIM_CTRL &= ~CIM_CTRL_FAST_MODE )
+#define __cim_use_normal_mode() __cim_disable_fast_mode()
+#define __cim_enable_dma() ( REG_CIM_CTRL |= CIM_CTRL_DMA_EN )
+#define __cim_disable_dma() ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EN )
+#define __cim_reset_rxfifo() ( REG_CIM_CTRL |= CIM_CTRL_RXF_RST )
+#define __cim_unreset_rxfifo() ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_RST )
+
+#define __cim_clear_state() ( REG_CIM_STATE = 0 )
+
+#define __cim_disable_done() ( REG_CIM_STATE & CIM_STATE_VDD )
+#define __cim_rxfifo_empty() ( REG_CIM_STATE & CIM_STATE_RXF_EMPTY )
+#define __cim_rxfifo_reach_trigger() ( REG_CIM_STATE & CIM_STATE_RXF_TRIG )
+#define __cim_rxfifo_overflow() ( REG_CIM_STATE & CIM_STATE_RXF_OF )
+#define __cim_clear_rxfifo_overflow() ( REG_CIM_STATE &= ~CIM_STATE_RXF_OF )
+#define __cim_dma_stop() ( REG_CIM_STATE & CIM_STATE_DMA_STOP )
+#define __cim_dma_eof() ( REG_CIM_STATE & CIM_STATE_DMA_EOF )
+#define __cim_dma_sof() ( REG_CIM_STATE & CIM_STATE_DMA_SOF )
+
+#define __cim_get_iid() ( REG_CIM_IID )
+#define __cim_get_fid() ( REG_CIM_FID )
+#define __cim_get_image_data() ( REG_CIM_RXFIFO )
+#define __cim_get_dma_cmd() ( REG_CIM_CMD )
+
+#define __cim_set_da(a) ( REG_CIM_DA = (a) )
+
+#define __cim_set_line(a) ( REG_CIM_SIZE = (REG_CIM_SIZE&(~CIM_SIZE_LPF_MASK))|((a)<<CIM_SIZE_LPF_BIT) )
+#define __cim_set_pixel(a) ( REG_CIM_SIZE = (REG_CIM_SIZE&(~CIM_SIZE_PPL_MASK))|((a)<<CIM_SIZE_PPL_BIT) )
+#define __cim_get_line() ((REG_CIM_SIZE&CIM_SIZE_LPF_MASK)>>CIM_SIZE_LPF_BIT)
+#define __cim_get_pixel() ((REG_CIM_SIZE&CIM_SIZE_PPL_MASK)>>CIM_SIZE_PPL_BIT)
+
+#define __cim_set_v_offset(a) ( REG_CIM_OFFSET = (REG_CIM_OFFSET&(~CIM_OFFSET_V_MASK)) | ((a)<<CIM_OFFSET_V_BIT) )
+#define __cim_set_h_offset(a) ( REG_CIM_OFFSET = (REG_CIM_OFFSET&(~CIM_OFFSET_H_MASK)) | ((a)<<CIM_OFFSET_H_BIT) )
+#define __cim_get_v_offset() ((REG_CIM_OFFSET&CIM_OFFSET_V_MASK)>>CIM_OFFSET_V_BIT)
+#define __cim_get_h_offset() ((REG_CIM_OFFSET&CIM_OFFSET_H_MASK)>>CIM_OFFSET_H_BIT)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760CIM_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760cpm.h b/arch/mips/include/asm/mach-jz4760/jz4760cpm.h
new file mode 100644
index 00000000000..54b8ba2b744
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760cpm.h
@@ -0,0 +1,646 @@
+/*
+ * jz4760cpm.h
+ * JZ4760 CPM register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760CPM_H__
+#define __JZ4760CPM_H__
+
+#ifndef JZ_EXTAL
+#define JZ_EXTAL 12000000 /* 3.6864 MHz */
+#endif
+#ifndef JZ_EXTAL2
+#define JZ_EXTAL2 32768 /* 32.768 KHz */
+#endif
+
+/*
+ * Clock reset and power controller module(CPM) address definition
+ */
+#define CPM_BASE 0xb0000000
+
+
+/*
+ * CPM registers offset address definition
+ */
+#define CPM_CPCCR_OFFSET (0x00) /* rw, 32, 0x01011100 */
+#define CPM_LCR_OFFSET (0x04) /* rw, 32, 0x000000f8 */
+#define CPM_RSR_OFFSET (0x08) /* rw, 32, 0x???????? */
+#define CPM_CPPCR0_OFFSET (0x10) /* rw, 32, 0x28080011 */
+#define CPM_CPPSR_OFFSET (0x14) /* rw, 32, 0x80000000 */
+#define CPM_CLKGR0_OFFSET (0x20) /* rw, 32, 0x3fffffe0 */
+#define CPM_OPCR_OFFSET (0x24) /* rw, 32, 0x00001570 */
+#define CPM_CLKGR1_OFFSET (0x28) /* rw, 32, 0x0000017f */
+#define CPM_CPPCR1_OFFSET (0x30) /* rw, 32, 0x28080002 */
+#define CPM_CPSPR_OFFSET (0x34) /* rw, 32, 0x???????? */
+#define CPM_CPSPPR_OFFSET (0x38) /* rw, 32, 0x0000a5a5 */
+#define CPM_USBPCR_OFFSET (0x3c) /* rw, 32, 0x42992198 */
+#define CPM_USBRDT_OFFSET (0x40) /* rw, 32, 0x00000096 */
+#define CPM_USBVBFIL_OFFSET (0x44) /* rw, 32, 0x00000080 */
+#define CPM_USBCDR_OFFSET (0x50) /* rw, 32, 0x00000000 */
+#define CPM_I2SCDR_OFFSET (0x60) /* rw, 32, 0x00000000 */
+#define CPM_LPCDR_OFFSET (0x64) /* rw, 32, 0x00000000 */
+#define CPM_MSCCDR_OFFSET (0x68) /* rw, 32, 0x00000000 */
+#define CPM_UHCCDR_OFFSET (0x6c) /* rw, 32, 0x00000000 */
+#define CPM_SSICDR_OFFSET (0x74) /* rw, 32, 0x00000000 */
+#define CPM_CIMCDR_OFFSET (0x7c) /* rw, 32, 0x00000000 */
+#define CPM_GPSCDR_OFFSET (0x80) /* rw, 32, 0x00000000 */
+#define CPM_PCMCDR_OFFSET (0x84) /* rw, 32, 0x00000000 */
+#define CPM_GPUCDR_OFFSET (0x88) /* rw, 32, 0x00000000 */
+#define CPM_PSWC0ST_OFFSET (0x90) /* rw, 32, 0x00000000 */
+#define CPM_PSWC1ST_OFFSET (0x94) /* rw, 32, 0x00000000 */
+#define CPM_PSWC2ST_OFFSET (0x98) /* rw, 32, 0x00000000 */
+#define CPM_PSWC3ST_OFFSET (0x9c) /* rw, 32, 0x00000000 */
+
+
+/*
+ * CPM registers address definition
+ */
+#define CPM_CPCCR (CPM_BASE + CPM_CPCCR_OFFSET)
+#define CPM_LCR (CPM_BASE + CPM_LCR_OFFSET)
+#define CPM_RSR (CPM_BASE + CPM_RSR_OFFSET)
+#define CPM_CPPCR0 (CPM_BASE + CPM_CPPCR0_OFFSET)
+#define CPM_CPPSR (CPM_BASE + CPM_CPPSR_OFFSET)
+#define CPM_CLKGR0 (CPM_BASE + CPM_CLKGR0_OFFSET)
+#define CPM_OPCR (CPM_BASE + CPM_OPCR_OFFSET)
+#define CPM_CLKGR1 (CPM_BASE + CPM_CLKGR1_OFFSET)
+#define CPM_CPPCR1 (CPM_BASE + CPM_CPPCR1_OFFSET)
+#define CPM_CPSPR (CPM_BASE + CPM_CPSPR_OFFSET)
+#define CPM_CPSPPR (CPM_BASE + CPM_CPSPPR_OFFSET)
+#define CPM_USBPCR (CPM_BASE + CPM_USBPCR_OFFSET)
+#define CPM_USBRDT (CPM_BASE + CPM_USBRDT_OFFSET)
+#define CPM_USBVBFIL (CPM_BASE + CPM_USBVBFIL_OFFSET)
+#define CPM_USBCDR (CPM_BASE + CPM_USBCDR_OFFSET)
+#define CPM_I2SCDR (CPM_BASE + CPM_I2SCDR_OFFSET)
+#define CPM_LPCDR (CPM_BASE + CPM_LPCDR_OFFSET)
+#define CPM_MSCCDR (CPM_BASE + CPM_MSCCDR_OFFSET)
+#define CPM_UHCCDR (CPM_BASE + CPM_UHCCDR_OFFSET)
+#define CPM_SSICDR (CPM_BASE + CPM_SSICDR_OFFSET)
+#define CPM_CIMCDR (CPM_BASE + CPM_CIMCDR_OFFSET)
+#define CPM_GPSCDR (CPM_BASE + CPM_GPSCDR_OFFSET)
+#define CPM_PCMCDR (CPM_BASE + CPM_PCMCDR_OFFSET)
+#define CPM_GPUCDR (CPM_BASE + CPM_GPUCDR_OFFSET)
+#define CPM_PSWC0ST (CPM_BASE + CPM_PSWC0ST_OFFSET)
+#define CPM_PSWC1ST (CPM_BASE + CPM_PSWC1ST_OFFSET)
+#define CPM_PSWC2ST (CPM_BASE + CPM_PSWC2ST_OFFSET)
+#define CPM_PSWC3ST (CPM_BASE + CPM_PSWC3ST_OFFSET)
+
+
+/*
+ * CPM registers common define
+ */
+
+/* Clock control register(CPCCR) */
+#define CPCCR_ECS BIT31
+#define CPCCR_MEM BIT30
+#define CPCCR_CE BIT22
+#define CPCCR_PCS BIT21
+
+#define CPCCR_SDIV_LSB 24
+#define CPCCR_SDIV_MASK BITS_H2L(27, CPCCR_SDIV_LSB)
+
+#define CPCCR_H2DIV_LSB 16
+#define CPCCR_H2DIV_MASK BITS_H2L(19, CPCCR_H2DIV_LSB)
+
+#define CPCCR_MDIV_LSB 12
+#define CPCCR_MDIV_MASK BITS_H2L(15, CPCCR_MDIV_LSB)
+
+#define CPCCR_PDIV_LSB 8
+#define CPCCR_PDIV_MASK BITS_H2L(11, CPCCR_PDIV_LSB)
+
+#define CPCCR_HDIV_LSB 4
+#define CPCCR_HDIV_MASK BITS_H2L(7, CPCCR_HDIV_LSB)
+
+#define CPCCR_CDIV_LSB 0
+#define CPCCR_CDIV_MASK BITS_H2L(3, CPCCR_CDIV_LSB)
+
+/* Low power control register(LCR) */
+#define LCR_PDAHB1 BIT30
+#define LCR_VBATIR BIT29
+#define LCR_PDGPS BIT28
+#define LCR_PDAHB1S BIT26
+#define LCR_PDGPSS BIT24
+#define LCR_DOZE BIT2
+
+#define LCR_PST_LSB 8
+#define LCR_PST_MASK BITS_H2L(19, LCR_PST_LSB)
+
+#define LCR_DUTY_LSB 3
+#define LCR_DUTY_MASK BITS_H2L(7, LCR_DUTY_LSB)
+
+#define LCR_LPM_LSB 0
+#define LCR_LPM_MASK BITS_H2L(1, LCR_LPM_LSB)
+#define LCR_LPM_IDLE (0x0 << LCR_LPM_LSB)
+#define LCR_LPM_SLEEP (0x1 << LCR_LPM_LSB)
+
+/* Reset status register(RSR) */
+#define RSR_P0R BIT2
+#define RSR_WR BIT1
+#define RSR_PR BIT0
+
+/* PLL control register 0(CPPCR0) */
+#define CPPCR0_LOCK BIT15 /* LOCK0 bit */
+#define CPPCR0_ENLOCK BIT14
+#define CPPCR0_PLLS BIT10
+#define CPPCR0_PLLBP BIT9
+#define CPPCR0_PLLEN BIT8
+
+#define CPPCR0_PLLM_LSB 24
+#define CPPCR0_PLLM_MASK BITS_H2L(30, CPPCR0_PLLM_LSB)
+
+#define CPPCR0_PLLN_LSB 18
+#define CPPCR0_PLLN_MASK BITS_H2L(21, CPPCR0_PLLN_LSB)
+
+#define CPPCR0_PLLOD_LSB 16
+#define CPPCR0_PLLOD_MASK BITS_H2L(17, CPPCR0_PLLOD_LSB)
+
+#define CPPCR0_PLLST_LSB 0
+#define CPPCR0_PLLST_MASK BITS_H2L(7, CPPCR0_PLLST_LSB)
+
+/* PLL switch and status register(CPPSR) */
+#define CPPSR_PLLOFF BIT31
+#define CPPSR_PLLBP BIT30
+#define CPPSR_PLLON BIT29
+#define CPPSR_PS BIT28
+#define CPPSR_FS BIT27
+#define CPPSR_CS BIT26
+#define CPPSR_SM BIT2
+#define CPPSR_PM BIT1
+#define CPPSR_FM BIT0
+
+/* Clock gate register 0(CGR0) */
+#define CLKGR0_EMC BIT31
+#define CLKGR0_DDR BIT30
+#define CLKGR0_IPU BIT29
+#define CLKGR0_LCD BIT28
+#define CLKGR0_TVE BIT27
+#define CLKGR0_CIM BIT26
+#define CLKGR0_MDMA BIT25
+#define CLKGR0_UHC BIT24
+#define CLKGR0_MAC BIT23
+#define CLKGR0_GPS BIT22
+#define CLKGR0_DMAC BIT21
+#define CLKGR0_SSI2 BIT20
+#define CLKGR0_SSI1 BIT19
+#define CLKGR0_UART3 BIT18
+#define CLKGR0_UART2 BIT17
+#define CLKGR0_UART1 BIT16
+#define CLKGR0_UART0 BIT15
+#define CLKGR0_SADC BIT14
+#define CLKGR0_KBC BIT13
+#define CLKGR0_MSC2 BIT12
+#define CLKGR0_MSC1 BIT11
+#define CLKGR0_OWI BIT10
+#define CLKGR0_TSSI BIT9
+#define CLKGR0_AIC BIT8
+#define CLKGR0_SCC BIT7
+#define CLKGR0_I2C1 BIT6
+#define CLKGR0_I2C0 BIT5
+#define CLKGR0_SSI0 BIT4
+#define CLKGR0_MSC0 BIT3
+#define CLKGR0_OTG BIT2
+#define CLKGR0_BCH BIT1
+#define CLKGR0_NEMC BIT0
+
+/* Oscillator and power control register(OPCR) */
+#define OPCR_OTGPHY_ENABLE BIT7 /* SPENDN bit */
+#define OPCR_GPSEN BIT6
+#define OPCR_UHCPHY_DISABLE BIT5 /* SPENDH bit */
+#define OPCR_O1SE BIT4
+#define OPCR_PD BIT3
+#define OPCR_ERCS BIT2
+
+#define OPCR_O1ST_LSB 8
+#define OPCR_O1ST_MASK BITS_H2L(15, OPCR_O1ST_LSB)
+
+/* Clock gate register 1(CGR1) */
+#define CLKGR1_GPU BIT9
+#define CLKGR1_PCM BIT8
+#define CLKGR1_AHB1 BIT7
+#define CLKGR1_CABAC BIT6
+#define CLKGR1_SRAM BIT5
+#define CLKGR1_DCT BIT4
+#define CLKGR1_ME BIT3
+#define CLKGR1_DBLK BIT2
+#define CLKGR1_MC BIT1
+#define CLKGR1_BDMA BIT0
+
+/* PLL control register 1(CPPCR1) */
+#define CPPCR1_P1SCS BIT15
+#define CPPCR1_PLL1EN BIT7
+#define CPPCR1_PLL1S BIT6
+#define CPPCR1_LOCK BIT2 /* LOCK1 bit */
+#define CPPCR1_PLL1OFF BIT1
+#define CPPCR1_PLL1ON BIT0
+
+#define CPPCR1_PLL1M_LSB 24
+#define CPPCR1_PLL1M_MASK BITS_H2L(30, CPPCR1_PLL1M_LSB)
+
+#define CPPCR1_PLL1N_LSB 18
+#define CPPCR1_PLL1N_MASK BITS_H2L(21, CPPCR1_PLL1N_LSB)
+
+#define CPPCR1_PLL1OD_LSB 16
+#define CPPCR1_PLL1OD_MASK BITS_H2L(17, CPPCR1_PLL1OD_LSB)
+
+#define CPPCR1_P1SDIV_LSB 9
+#define CPPCR1_P1SDIV_MASK BITS_H2L(14, CPPCR1_P1SDIV_LSB)
+
+/* CPM scratch pad protected register(CPSPPR) */
+#define CPSPPR_CPSPR_WRITABLE (0x00005a5a)
+
+/* OTG parameter control register(USBPCR) */
+#define USBPCR_USB_MODE BIT31
+#define USBPCR_AVLD_REG BIT30
+#define USBPCR_INCRM BIT27 /* INCR_MASK bit */
+#define USBPCR_CLK12_EN BIT26
+#define USBPCR_COMMONONN BIT25
+#define USBPCR_VBUSVLDEXT BIT24
+#define USBPCR_VBUSVLDEXTSEL BIT23
+#define USBPCR_POR BIT22
+#define USBPCR_SIDDQ BIT21
+#define USBPCR_OTG_DISABLE BIT20
+#define USBPCR_TXPREEMPHTUNE BIT6
+
+#define USBPCR_IDPULLUP_LSB 28 /* IDPULLUP_MASK bit */
+#define USBPCR_IDPULLUP_MASK BITS_H2L(29, USBPCR_USBPCR_IDPULLUP_LSB)
+
+#define USBPCR_COMPDISTUNE_LSB 17
+#define USBPCR_COMPDISTUNE_MASK BITS_H2L(19, USBPCR_COMPDISTUNE_LSB)
+
+#define USBPCR_OTGTUNE_LSB 14
+#define USBPCR_OTGTUNE_MASK BITS_H2L(16, USBPCR_OTGTUNE_LSB)
+
+#define USBPCR_SQRXTUNE_LSB 11
+#define USBPCR_SQRXTUNE_MASK BITS_H2L(13, USBPCR_SQRXTUNE_LSB)
+
+#define USBPCR_TXFSLSTUNE_LSB 7
+#define USBPCR_TXFSLSTUNE_MASK BITS_H2L(10, USBPCR_TXFSLSTUNE_LSB)
+
+#define USBPCR_TXRISETUNE_LSB 4
+#define USBPCR_TXRISETUNE_MASK BITS_H2L(5, USBPCR_TXRISETUNE_LSB)
+
+#define USBPCR_TXVREFTUNE_LSB 0
+#define USBPCR_TXVREFTUNE_MASK BITS_H2L(3, USBPCR_TXVREFTUNE_LSB)
+
+/* OTG reset detect timer register(USBRDT) */
+#define USBRDT_VBFIL_LD_EN BIT25
+#define USBRDT_IDDIG_EN BIT24
+#define USBRDT_IDDIG_REG BIT23
+
+#define USBRDT_USBRDT_LSB 0
+#define USBRDT_USBRDT_MASK BITS_H2L(22, USBRDT_USBRDT_LSB)
+
+/* OTG PHY clock divider register(USBCDR) */
+#define USBCDR_UCS BIT31
+#define USBCDR_UPCS BIT30
+
+#define USBCDR_OTGDIV_LSB 0 /* USBCDR bit */
+#define USBCDR_OTGDIV_MASK BITS_H2L(5, USBCDR_OTGDIV_LSB)
+
+/* I2S device clock divider register(I2SCDR) */
+#define I2SCDR_I2CS BIT31
+#define I2SCDR_I2PCS BIT30
+
+#define I2SCDR_I2SDIV_LSB 0 /* I2SCDR bit */
+#define I2SCDR_I2SDIV_MASK BITS_H2L(8, I2SCDR_I2SDIV_LSB)
+
+/* LCD pix clock divider register(LPCDR) */
+#define LPCDR_LSCS BIT31
+#define LPCDR_LTCS BIT30
+#define LPCDR_LPCS BIT29
+
+#define LPCDR_PIXDIV_LSB 0 /* LPCDR bit */
+#define LPCDR_PIXDIV_MASK BITS_H2L(10, LPCDR_PIXDIV_LSB)
+
+/* MSC clock divider register(MSCCDR) */
+#define MSCCDR_MCS BIT31
+
+#define MSCCDR_MSCDIV_LSB 0 /* MSCCDR bit */
+#define MSCCDR_MSCDIV_MASK BITS_H2L(5, MSCCDR_MSCDIV_LSB)
+
+/* UHC device clock divider register(UHCCDR) */
+#define UHCCDR_UHPCS BIT31
+
+#define UHCCDR_UHCDIV_LSB 0 /* UHCCDR bit */
+#define UHCCDR_UHCDIV_MASK BITS_H2L(3, UHCCDR_UHCDIV_LSB)
+
+/* SSI clock divider register(SSICDR) */
+#define SSICDR_SCS BIT31
+
+#define SSICDR_SSIDIV_LSB 0 /* SSICDR bit */
+#define SSICDR_SSIDIV_MASK BITS_H2L(5, SSICDR_SSIDIV_LSB)
+
+/* CIM mclk clock divider register(CIMCDR) */
+#define CIMCDR_CIMDIV_LSB 0 /* CIMCDR bit */
+#define CIMCDR_CIMDIV_MASK BITS_H2L(7, CIMCDR_CIMDIV_LSB)
+
+/* GPS clock divider register(GPSCDR) */
+#define GPSCDR_GPCS BIT31
+
+#define GPSCDR_GPSDIV_LSB 0 /* GPSCDR bit */
+#define GSPCDR_GPSDIV_MASK BITS_H2L(3, GPSCDR_GPSDIV_LSB)
+
+/* PCM device clock divider register(PCMCDR) */
+#define PCMCDR_PCMS BIT31
+#define PCMCDR_PCMPCS BIT30
+
+#define PCMCDR_PCMDIV_LSB 0 /* PCMCDR bit */
+#define PCMCDR_PCMDIV_MASK BITS_H2L(8, PCMCDR_PCMDIV_LSB)
+
+/* GPU clock divider register */
+#define GPUCDR_GPCS BIT31
+#define GPUCDR_GPUDIV_LSB 0 /* GPUCDR bit */
+#define GPUCDR_GPUDIV_MASK BITS_H2L(2, GPUCDR_GPUDIV_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_CPM_CPCCR REG32(CPM_CPCCR)
+#define REG_CPM_RSR REG32(CPM_RSR)
+#define REG_CPM_CPPCR0 REG32(CPM_CPPCR0)
+#define REG_CPM_CPPSR REG32(CPM_CPPSR)
+#define REG_CPM_CPPCR1 REG32(CPM_CPPCR1)
+#define REG_CPM_CPSPR REG32(CPM_CPSPR)
+#define REG_CPM_CPSPPR REG32(CPM_CPSPPR)
+#define REG_CPM_USBPCR REG32(CPM_USBPCR)
+#define REG_CPM_USBRDT REG32(CPM_USBRDT)
+#define REG_CPM_USBVBFIL REG32(CPM_USBVBFIL)
+#define REG_CPM_USBCDR REG32(CPM_USBCDR)
+#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_CIMCDR REG32(CPM_CIMCDR)
+#define REG_CPM_GPSCDR REG32(CPM_GPSCDR)
+#define REG_CPM_PCMCDR REG32(CPM_PCMCDR)
+#define REG_CPM_GPUCDR REG32(CPM_GPUCDR)
+
+#define REG_CPM_PSWC0ST REG32(CPM_PSWC0ST)
+#define REG_CPM_PSWC1ST REG32(CPM_PSWC1ST)
+#define REG_CPM_PSWC2ST REG32(CPM_PSWC2ST)
+#define REG_CPM_PSWC3ST REG32(CPM_PSWC3ST)
+
+#define REG_CPM_LCR REG32(CPM_LCR)
+#define REG_CPM_CLKGR0 REG32(CPM_CLKGR0)
+#define REG_CPM_OPCR REG32(CPM_OPCR)
+#define REG_CPM_CLKGR1 REG32(CPM_CLKGR1)
+#define REG_CPM_CLKGR REG32(CPM_CLKGR0)
+
+typedef enum {
+ CGM_NEMC = 0,
+ CGM_BCH = 1,
+ CGM_OTG = 2,
+ CGM_MSC0 = 3,
+ CGM_SSI0 = 4,
+ CGM_I2C0 = 5,
+ CGM_I2C1 = 6,
+ CGM_SCC = 7,
+ CGM_AIC = 8,
+ CGM_TSSI = 9,
+ CGM_OWI = 10,
+ CGM_MSC1 = 11,
+ CGM_MSC2 = 12,
+ CGM_KBC = 13,
+ CGM_SADC = 14,
+ CGM_UART0 = 15,
+ CGM_UART1 = 16,
+ CGM_UART2 = 17,
+ CGM_UART3 = 18,
+ CGM_SSI1 = 19,
+ CGM_SSI2 = 20,
+ CGM_DMAC = 21,
+ CGM_GPS = 22,
+ CGM_MAC = 23,
+ CGM_UHC = 24,
+ CGM_MDMA = 25,
+ CGM_CIM = 26,
+ CGM_TVE = 27,
+ CGM_LCD = 28,
+ CGM_IPU = 29,
+ CGM_DDR = 30,
+ CGM_EMC = 31,
+ CGM_BDMA = 32 + 0,
+ CGM_MC = 32 + 1,
+ CGM_DBLK = 32 + 2,
+ CGM_ME = 32 + 3,
+ CGM_DCT = 32 + 4,
+ CGM_SRAM = 32 + 5,
+ CGM_CABAC = 32 + 6,
+ CGM_AHB1 = 32 + 7,
+ CGM_PCM = 32 + 8,
+ CGM_GPU = 32 + 9,
+ CGM_ALL_MODULE,
+} clock_gate_module;
+
+
+#define __CGU_CLOCK_BASE__ 0x1000
+
+typedef enum {
+ /* Clock source is pll0 */
+ CGU_CCLK = __CGU_CLOCK_BASE__ + 0,
+ CGU_HCLK,
+ CGU_PCLK,
+ CGU_MCLK,
+ CGU_H2CLK,
+ CGU_SCLK,
+
+ /* Clock source is exclk, pll0 or pll0/2 */
+ CGU_MSCCLK,
+ CGU_SSICLK,
+
+ /* Clock source is pll0 or pll0/2 */
+ CGU_CIMCLK,
+
+ /* Clock source is exclk, pll0, pll0/2 or pll1 */
+ CGU_TVECLK,
+
+ /* Clock source is pll0 */
+ CGU_LPCLK,
+
+ /* Clock source is exclk, exclk/2, pll0, pll0/2 or pll1 */
+ CGU_I2SCLK,
+ CGU_PCMCLK,
+ CGU_OTGCLK,
+
+ /* Clock source is pll0, pll0/2 or pll1 */
+ CGU_UHCCLK,
+ CGU_GPSCLK,
+ CGU_GPUCLK,
+
+ /* Clock source is exclk or exclk/2 */
+ CGU_UARTCLK,
+ CGU_SADCCLK,
+
+ /* Clock source is exclk */
+ CGU_TCUCLK,
+
+ /* Clock source is external rtc clock */
+ CGU_RTCCLK,
+
+ CGU_CLOCK_MAX,
+} cgu_clock;
+
+/*
+ * JZ4760 clocks structure
+ */
+typedef struct {
+ unsigned int cclk; /* CPU clock */
+ unsigned int hclk; /* System bus clock: AHB0,AHB1 */
+ unsigned int h1clk; /* For compatible, the same as h1clk */
+ unsigned int h2clk; /* System bus clock: AHB2 */
+ unsigned int pclk; /* Peripheral bus clock */
+ unsigned int mclk; /* EMC or DDR controller clock */
+ unsigned int sclk; /* NEMC controller clock */
+ unsigned int cko; /* SDRAM or DDR clock */
+ unsigned int pixclk; /* LCD pixel clock */
+ unsigned int tveclk; /* TV encoder 27M clock */
+ unsigned int cimmclk; /* Clock output from CIM module */
+ unsigned int cimpclk; /* Clock input to CIM module */
+ unsigned int gpuclk; /* GPU clock */
+ unsigned int gpsclk; /* GPS clock */
+ unsigned int i2sclk; /* I2S codec clock */
+ unsigned int bitclk; /* AC97 bit clock */
+ unsigned int pcmclk; /* PCM clock */
+ unsigned int mscclk; /* MSC clock */
+ unsigned int ssiclk; /* SSI clock */
+ unsigned int tssiclk; /* TSSI clock */
+ unsigned int otgclk; /* USB OTG clock */
+ unsigned int uhcclk; /* USB UHCI clock */
+ unsigned int extalclk; /* EXTAL clock for
+ UART,I2C,TCU,USB2.0-PHY,AUDIO CODEC */
+ unsigned int rtcclk; /* RTC clock for CPM,INTC,RTC,TCU,WDT */
+} jz_clocks_t;
+
+void cpm_start_clock(clock_gate_module module_name);
+void cpm_stop_clock(clock_gate_module module_name);
+
+unsigned int cpm_set_clock(cgu_clock clock_name, unsigned int clock_hz);
+unsigned int cpm_get_clock(cgu_clock clock_name);
+unsigned int cpm_get_pllout(void);
+
+void cpm_uhc_phy(unsigned int en);
+
+/**************remove me if android's kernel support these operations********start********* */
+#define __cpm_stop_lcd() (REG_CPM_CLKGR0 |= CLKGR0_LCD)
+#define __cpm_start_lcd() (REG_CPM_CLKGR0 &= ~CLKGR0_LCD)
+#define __cpm_set_pixdiv(v) \
+ (REG_CPM_LPCDR = (REG_CPM_LPCDR & ~LPCDR_PIXDIV_MASK) | ((v) << (LPCDR_PIXDIV_LSB)))
+
+#define __cpm_get_pixdiv() \
+ ((REG_CPM_LPCDR & LPCDR_PIXDIV_MASK) >> LPCDR_PIXDIV_LSB)
+
+#define __cpm_select_pixclk_tve() (REG_CPM_LPCDR |= LPCDR_LTCS)
+
+static __inline__ unsigned int __cpm_get_pllout2(void)
+{
+#if defined(CONFIG_FPGA)
+ return cpm_get_pllout();
+#else
+ if (REG_CPM_CPCCR & CPCCR_PCS)
+ return cpm_get_pllout();
+ else
+ return cpm_get_pllout()/2;
+#endif
+}
+
+static __inline__ unsigned int __cpm_get_pixclk(void)
+{
+ return __cpm_get_pllout2() / (__cpm_get_pixdiv() + 1);
+}
+
+/* EXTAL clock */
+static __inline__ unsigned int __cpm_get_extalclk0(void)
+{
+ return JZ_EXTAL;
+}
+
+/* EXTAL clock for UART,I2C,SSI,SADC,USB-PHY */
+static __inline__ unsigned int __cpm_get_extalclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return __cpm_get_extalclk0() / CFG_DIV;
+#else
+ if (REG_CPM_CPCCR & CPCCR_ECS)
+ return __cpm_get_extalclk0() / 2;
+ else
+ return __cpm_get_extalclk0();
+#endif
+
+}
+
+/* RTC clock for CPM,INTC,RTC,TCU,WDT */
+static __inline__ unsigned int __cpm_get_rtcclk(void)
+{
+ return JZ_EXTAL2;
+}
+
+extern jz_clocks_t jz_clocks;
+
+#define __cpm_select_i2sclk_exclk() (REG_CPM_I2SCDR &= ~I2SCDR_I2CS)
+#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPCCR_CE)
+
+#define __cpm_suspend_otg_phy() (REG_CPM_OPCR &= ~OPCR_OTGPHY_ENABLE)
+#define __cpm_enable_otg_phy() (REG_CPM_OPCR |= OPCR_OTGPHY_ENABLE)
+
+#define __cpm_suspend_uhc_phy() (REG_CPM_OPCR |= OPCR_UHCPHY_DISABLE)
+#define __cpm_enable_uhc_phy() (REG_CPM_OPCR &= ~OPCR_UHCPHY_DISABLE)
+#define __cpm_suspend_gps() (REG_CPM_OPCR &= ~OPCR_GPSEN)
+#define __cpm_disable_osc_in_sleep() (REG_CPM_OPCR &= ~OPCR_O1SE)
+#define __cpm_select_rtcclk_rtc() (REG_CPM_OPCR |= OPCR_ERCS)
+
+#define __cpm_get_pllm() \
+ ((REG_CPM_CPPCR0 & CPPCR0_PLLM_MASK) >> CPPCR0_PLLM_LSB)
+#define __cpm_get_plln() \
+ ((REG_CPM_CPPCR0 & CPPCR0_PLLN_MASK) >> CPPCR0_PLLN_LSB)
+#define __cpm_get_pllod() \
+ ((REG_CPM_CPPCR0 & CPPCR0_PLLOD_MASK) >> CPPCR0_PLLOD_LSB)
+
+#define __cpm_get_pll1m() \
+ ((REG_CPM_CPPCR1 & CPPCR1_PLL1M_MASK) >> CPPCR1_PLL1M_LSB)
+#define __cpm_get_pll1n() \
+ ((REG_CPM_CPPCR1 & CPPCR1_PLL1N_MASK) >> CPPCR1_PLL1N_LSB)
+#define __cpm_get_pll1od() \
+ ((REG_CPM_CPPCR1 & CPPCR1_PLL1OD_MASK) >> CPPCR1_PLL1OD_LSB)
+
+#define __cpm_get_cdiv() \
+ ((REG_CPM_CPCCR & CPCCR_CDIV_MASK) >> CPCCR_CDIV_LSB)
+#define __cpm_get_hdiv() \
+ ((REG_CPM_CPCCR & CPCCR_HDIV_MASK) >> CPCCR_HDIV_LSB)
+#define __cpm_get_h2div() \
+ ((REG_CPM_CPCCR & CPCCR_H2DIV_MASK) >> CPCCR_H2DIV_LSB)
+#define __cpm_get_otgdiv() \
+ ((REG_CPM_USBCDR & USBCDR_OTGDIV_MASK) >> USBCDR_OTGDIV_LSB)
+#define __cpm_get_pdiv() \
+ ((REG_CPM_CPCCR & CPCCR_PDIV_MASK) >> CPCCR_PDIV_LSB)
+#define __cpm_get_mdiv() \
+ ((REG_CPM_CPCCR & CPCCR_MDIV_MASK) >> CPCCR_MDIV_LSB)
+#define __cpm_get_sdiv() \
+ ((REG_CPM_CPCCR & CPCCR_SDIV_MASK) >> CPCCR_SDIV_LSB)
+#define __cpm_get_i2sdiv() \
+ ((REG_CPM_I2SCDR & I2SCDR_I2SDIV_MASK) >> I2SCDR_I2SDIV_LSB)
+#define __cpm_get_pixdiv() \
+ ((REG_CPM_LPCDR & LPCDR_PIXDIV_MASK) >> LPCDR_PIXDIV_LSB)
+#define __cpm_get_mscdiv() \
+ ((REG_CPM_MSCCDR & MSCCDR_MSCDIV_MASK) >> MSCCDR_MSCDIV_LSB)
+
+/*
+#define __cpm_get_mscdiv(n) \
+ ((REG_CPM_MSCCDR(n) & MSCCDR_MSCDIV_MASK) >> MSCCDR_MSCDIV_LSB)
+*/
+#define __cpm_get_ssidiv() \
+ ((REG_CPM_SSICCDR & SSICDR_SSICDIV_MASK) >> SSICDR_SSIDIV_LSB)
+#define __cpm_get_pcmdiv() \
+ ((REG_CPM_PCMCDR & PCMCDR_PCMCD_MASK) >> PCMCDR_PCMCD_LSB)
+#define __cpm_get_pll1div() \
+ ((REG_CPM_CPPCR1 & CPCCR1_P1SDIV_MASK) >> CPCCR1_P1SDIV_LSB)
+
+/**************remove me if android's kernel support these operations********end********* */
+
+extern int jz_pm_init(void);
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760CPM_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760ddrc.h b/arch/mips/include/asm/mach-jz4760/jz4760ddrc.h
new file mode 100644
index 00000000000..27c91f5a012
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760ddrc.h
@@ -0,0 +1,345 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760ddrc.h
+ *
+ * JZ4760 DDRC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760DDRC_H__
+#define __JZ4760DDRC_H__
+
+
+#define DDRC_BASE 0xB3020000
+
+/*************************************************************************
+ * DDRC (DDR Controller)
+ *************************************************************************/
+#define DDRC_ST (DDRC_BASE + 0x0) /* DDR Status Register */
+#define DDRC_CFG (DDRC_BASE + 0x4) /* DDR Configure Register */
+#define DDRC_CTRL (DDRC_BASE + 0x8) /* DDR Control Register */
+#define DDRC_LMR (DDRC_BASE + 0xc) /* DDR Load-Mode-Register */
+#define DDRC_TIMING1 (DDRC_BASE + 0x10) /* DDR Timing Config Register 1 */
+#define DDRC_TIMING2 (DDRC_BASE + 0x14) /* DDR Timing Config Register 2 */
+#define DDRC_REFCNT (DDRC_BASE + 0x18) /* DDR Auto-Refresh Counter */
+#define DDRC_DQS (DDRC_BASE + 0x1c) /* DDR DQS Delay Control Register */
+#define DDRC_DQS_ADJ (DDRC_BASE + 0x20) /* DDR DQS Delay Adjust Register */
+#define DDRC_MMAP0 (DDRC_BASE + 0x24) /* DDR Memory Map Config Register */
+#define DDRC_MMAP1 (DDRC_BASE + 0x28) /* DDR Memory Map Config Register */
+
+/* DDRC Register */
+#define REG_DDRC_ST REG32(DDRC_ST)
+#define REG_DDRC_CFG REG32(DDRC_CFG)
+#define REG_DDRC_CTRL REG32(DDRC_CTRL)
+#define REG_DDRC_LMR REG32(DDRC_LMR)
+#define REG_DDRC_TIMING1 REG32(DDRC_TIMING1)
+#define REG_DDRC_TIMING2 REG32(DDRC_TIMING2)
+#define REG_DDRC_REFCNT REG32(DDRC_REFCNT)
+#define REG_DDRC_DQS REG32(DDRC_DQS)
+#define REG_DDRC_DQS_ADJ REG32(DDRC_DQS_ADJ)
+#define REG_DDRC_MMAP0 REG32(DDRC_MMAP0)
+#define REG_DDRC_MMAP1 REG32(DDRC_MMAP1)
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN (1 << 7) /* 0 Little data endian
+ 1 Big data endian */
+#define DDRC_ST_DPDN (1 << 5) /* 0 DDR memory is NOT in deep-power-down state
+ 1 DDR memory is in deep-power-down state */
+#define DDRC_ST_PDN (1 << 4) /* 0 DDR memory is NOT in power-down state
+ 1 DDR memory is in power-down state */
+#define DDRC_ST_AREF (1 << 3) /* 0 DDR memory is NOT in auto-refresh state
+ 1 DDR memory is in auto-refresh state */
+#define DDRC_ST_SREF (1 << 2) /* 0 DDR memory is NOT in self-refresh state
+ 1 DDR memory is in self-refresh state */
+#define DDRC_ST_CKE1 (1 << 1) /* 0 CKE1 Pin is low
+ 1 CKE1 Pin is high */
+#define DDRC_ST_CKE0 (1 << 0) /* 0 CKE0 Pin is low
+ 1 CKE0 Pin is high */
+
+/* DDRC Configure Register */
+#define DDRC_CFG_MSEL_BIT 16 /* Mask delay select */
+#define DDRC_CFG_MSEL_MASK (0x3 << DDRC_CFG_MSEL_BIT)
+ #define DDRC_CFG_MSEL_0 (0 << DDRC_CFG_MSEL_BIT) /* 00 No delay */
+ #define DDRC_CFG_MSEL_1 (1 << DDRC_CFG_MSEL_BIT) /* 01 delay 1 tCK */
+ #define DDRC_CFG_MSEL_2 (2 << DDRC_CFG_MSEL_BIT) /* 10 delay 2 tCK */
+ #define DDRC_CFG_MSEL_3 (3 << DDRC_CFG_MSEL_BIT) /* 11 delay 3 tCK */
+
+#define DDRC_CFG_HL (1 << 15) /* 0: no extra delay 1: one extra half tCK delay */
+
+#define DDRC_CFG_ROW1_BIT 27 /* Row Address width. */
+#define DDRC_CFG_COL1_BIT 25 /* Row Address width. */
+#define DDRC_CFG_BA1_BIT (1 << 24)
+#define DDRC_CFG_IMBA_BIT (1 << 23)
+#define DDRC_CFG_BTRUN (1 << 21)
+
+#define DDRC_CFG_TYPE_BIT 12
+#define DDRC_CFG_TYPE_MASK (0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1 (2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR (3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2 (4 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ROW_BIT 10 /* Row Address width. */
+#define DDRC_CFG_ROW_MASK (0x3 << DDRC_CFG_ROW_BIT)
+ #define DDRC_CFG_ROW_13 (0 << DDRC_CFG_ROW_BIT) /* 13-bit row address is used */
+ #define DDRC_CFG_ROW_14 (1 << DDRC_CFG_ROW_BIT) /* 14-bit row address is used */
+
+#define DDRC_CFG_COL_BIT 8 /* Column Address width.
+ Specify the Column address width of external DDR. */
+#define DDRC_CFG_COL_MASK (0x3 << DDRC_CFG_COL_BIT)
+ #define DDRC_CFG_COL_9 (0 << DDRC_CFG_COL_BIT) /* 9-bit Column address is used */
+ #define DDRC_CFG_COL_10 (1 << DDRC_CFG_COL_BIT) /* 10-bit Column address is used */
+
+#define DDRC_CFG_CS1EN (1 << 7) /* 0 DDR Pin CS1 un-used
+ 1 There're DDR memory connected to CS1 */
+#define DDRC_CFG_CS0EN (1 << 6) /* 0 DDR Pin CS0 un-used
+ 1 There're DDR memory connected to CS0 */
+
+#define DDRC_CFG_TSEL_BIT 18 /* Read delay select */
+#define DDRC_CFG_TSEL_MASK (0x3 << DDRC_CFG_TSEL_BIT)
+#define DDRC_CFG_TSEL_0 (0 << DDRC_CFG_TSEL_BIT) /* No delay */
+#define DDRC_CFG_TSEL_1 (1 << DDRC_CFG_TSEL_BIT) /* delay 1 tCK */
+#define DDRC_CFG_TSEL_2 (2 << DDRC_CFG_TSEL_BIT) /* delay 2 tCK */
+#define DDRC_CFG_TSEL_3 (3 << DDRC_CFG_TSEL_BIT) /* delay 3 tCK */
+
+#define DDRC_CFG_CL_BIT 2 /* CAS Latency */
+#define DDRC_CFG_CL_MASK (0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3 (0 << DDRC_CFG_CL_BIT) /* CL = 3 tCK */
+#define DDRC_CFG_CL_4 (1 << DDRC_CFG_CL_BIT) /* CL = 4 tCK */
+#define DDRC_CFG_CL_5 (2 << DDRC_CFG_CL_BIT) /* CL = 5 tCK */
+#define DDRC_CFG_CL_6 (3 << DDRC_CFG_CL_BIT) /* CL = 6 tCK */
+
+#define DDRC_CFG_BA (1 << 1) /* 0 4 bank device, Pin ba[1:0] valid, ba[2] un-used
+ 1 8 bank device, Pin ba[2:0] valid*/
+#define DDRC_CFG_DW (1 << 0) /*0 External memory data width is 16-bit
+ 1 External memory data width is 32-bit */
+
+/* DDRC Control Register */
+#define DDRC_CTRL_ACTPD (1 << 15) /* 0 Precharge all banks before entering power-down
+ 1 Do not precharge banks before entering power-down */
+#define DDRC_CTRL_PDT_BIT 12 /* Power-Down Timer */
+#define DDRC_CTRL_PDT_MASK (0x7 << DDRC_CTRL_PDT_BIT)
+ #define DDRC_CTRL_PDT_DIS (0 << DDRC_CTRL_PDT_BIT) /* power-down disabled */
+ #define DDRC_CTRL_PDT_8 (1 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 8 tCK idle */
+ #define DDRC_CTRL_PDT_16 (2 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 16 tCK idle */
+ #define DDRC_CTRL_PDT_32 (3 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 32 tCK idle */
+ #define DDRC_CTRL_PDT_64 (4 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 64 tCK idle */
+ #define DDRC_CTRL_PDT_128 (5 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 128 tCK idle */
+
+#define DDRC_CTRL_PRET_BIT 8 /* Precharge Timer */
+#define DDRC_CTRL_PRET_MASK (0x7 << DDRC_CTRL_PRET_BIT) /* */
+ #define DDRC_CTRL_PRET_DIS (0 << DDRC_CTRL_PRET_BIT) /* PRET function Disabled */
+ #define DDRC_CTRL_PRET_8 (1 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 8 tCK idle */
+ #define DDRC_CTRL_PRET_16 (2 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 16 tCK idle */
+ #define DDRC_CTRL_PRET_32 (3 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 32 tCK idle */
+ #define DDRC_CTRL_PRET_64 (4 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 64 tCK idle */
+ #define DDRC_CTRL_PRET_128 (5 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 128 tCK idle */
+
+#define DDRC_CTRL_SR (1 << 5) /* 1 Drive external DDR device entering self-refresh mode
+ 0 Drive external DDR device exiting self-refresh mode */
+#define DDRC_CTRL_UNALIGN (1 << 4) /* 0 Disable unaligned transfer on AXI BUS
+ 1 Enable unaligned transfer on AXI BUS */
+#define DDRC_CTRL_ALH (1 << 3) /* Advanced Latency Hiding:
+ 0 Disable ALH
+ 1 Enable ALH */
+#define DDRC_CTRL_RDC (1 << 2) /* 0 dclk clock frequency is lower than 60MHz
+ 1 dclk clock frequency is higher than 60MHz */
+#define DDRC_CTRL_CKE (1 << 1) /* 0 Not set CKE Pin High
+ 1 Set CKE Pin HIGH */
+#define DDRC_CTRL_RESET (1 << 0) /* 0 End resetting ddrc_controller
+ 1 Resetting ddrc_controller */
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT 16 /* When performing a DDR command, DDRC_ADDR[13:0]
+ corresponding to external DDR address Pin A[13:0] */
+#define DDRC_LMR_DDR_ADDR_MASK (0xff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT 8 /* When performing a DDR command, BA[2:0]
+ corresponding to external DDR address Pin BA[2:0]. */
+#define DDRC_LMR_BA_MASK (0x7 << DDRC_LMR_BA_BIT)
+ /* For DDR2 */
+ #define DDRC_LMR_BA_MRS (0 << DDRC_LMR_BA_BIT) /* Mode Register set */
+ #define DDRC_LMR_BA_EMRS1 (1 << DDRC_LMR_BA_BIT) /* Extended Mode Register1 set */
+ #define DDRC_LMR_BA_EMRS2 (2 << DDRC_LMR_BA_BIT) /* Extended Mode Register2 set */
+ #define DDRC_LMR_BA_EMRS3 (3 << DDRC_LMR_BA_BIT) /* Extended Mode Register3 set */
+ /* For mobile DDR */
+ #define DDRC_LMR_BA_M_MRS (0 << DDRC_LMR_BA_BIT) /* Mode Register set */
+ #define DDRC_LMR_BA_M_EMRS (2 << DDRC_LMR_BA_BIT) /* Extended Mode Register set */
+ #define DDRC_LMR_BA_M_SR (1 << DDRC_LMR_BA_BIT) /* Status Register set */
+
+#define DDRC_LMR_CMD_BIT 4
+#define DDRC_LMR_CMD_MASK (0x3 << DDRC_LMR_CMD_BIT)
+ #define DDRC_LMR_CMD_PREC (0 << DDRC_LMR_CMD_BIT)/* Precharge one bank/All banks */
+ #define DDRC_LMR_CMD_AUREF (1 << DDRC_LMR_CMD_BIT)/* Auto-Refresh */
+ #define DDRC_LMR_CMD_LMR (2 << DDRC_LMR_CMD_BIT)/* Load Mode Register */
+
+#define DDRC_LMR_START (1 << 0) /* 0 No command is performed
+ 1 On the posedge of START, perform a command
+ defined by CMD field */
+
+/* DDRC Mode Register Set */
+#define DDR_MRS_PD_BIT (1 << 10) /* Active power down exit time */
+#define DDR_MRS_PD_MASK (1 << DDR_MRS_PD_BIT)
+ #define DDR_MRS_PD_FAST_EXIT (0 << 10)
+ #define DDR_MRS_PD_SLOW_EXIT (1 << 10)
+#define DDR_MRS_WR_BIT (1 << 9) /* Write Recovery for autoprecharge */
+#define DDR_MRS_WR_MASK (7 << DDR_MRS_WR_BIT)
+#define DDR_MRS_DLL_RST (1 << 8) /* DLL Reset */
+#define DDR_MRS_TM_BIT 7 /* Operating Mode */
+#define DDR_MRS_TM_MASK (1 << DDR_MRS_OM_BIT)
+ #define DDR_MRS_TM_NORMAL (0 << DDR_MRS_OM_BIT)
+ #define DDR_MRS_TM_TEST (1 << DDR_MRS_OM_BIT)
+#define DDR_MRS_CAS_BIT 4 /* CAS Latency */
+#define DDR_MRS_CAS_MASK (7 << DDR_MRS_CAS_BIT)
+#define DDR_MRS_BT_BIT 3 /* Burst Type */
+#define DDR_MRS_BT_MASK (1 << DDR_MRS_BT_BIT)
+ #define DDR_MRS_BT_SEQ (0 << DDR_MRS_BT_BIT) /* Sequential */
+ #define DDR_MRS_BT_INT (1 << DDR_MRS_BT_BIT) /* Interleave */
+#define DDR_MRS_BL_BIT 0 /* Burst Length */
+#define DDR_MRS_BL_MASK (7 << DDR_MRS_BL_BIT)
+ #define DDR_MRS_BL_4 (2 << DDR_MRS_BL_BIT)
+ #define DDR_MRS_BL_8 (3 << DDR_MRS_BL_BIT)
+
+/* DDRC Extended Mode Register1 Set */
+#define DDR_EMRS1_QOFF (1<<12) /* 0 Output buffer enabled
+ 1 Output buffer disabled */
+#define DDR_EMRS1_RDQS_EN (1<<11) /* 0 Disable
+ 1 Enable */
+#define DDR_EMRS1_DQS_DIS (1<<10) /* 0 Enable
+ 1 Disable */
+#define DDR_EMRS1_OCD_BIT 7 /* Additive Latency 0 -> 6 */
+#define DDR_EMRS1_OCD_MASK (0x7 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_EXIT (0 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_D0 (1 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_D1 (2 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_ADJ (4 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_DFLT (7 << DDR_EMRS1_OCD_BIT)
+#define DDR_EMRS1_AL_BIT 3 /* Additive Latency 0 -> 6 */
+#define DDR_EMRS1_AL_MASK (7 << DDR_EMRS1_AL_BIT)
+#define DDR_EMRS1_RTT_BIT 2 /* */
+#define DDR_EMRS1_RTT_MASK (0x11 << DDR_EMRS1_DIC_BIT) /* Bit 6, Bit 2 */
+#define DDR_EMRS1_DIC_BIT 1 /* Output Driver Impedence Control */
+#define DDR_EMRS1_DIC_MASK (1 << DDR_EMRS1_DIC_BIT) /* 100% */
+ #define DDR_EMRS1_DIC_NORMAL (0 << DDR_EMRS1_DIC_BIT) /* 60% */
+ #define DDR_EMRS1_DIC_HALF (1 << DDR_EMRS1_DIC_BIT)
+#define DDR_EMRS1_DLL_BIT 0 /* DLL Enable */
+#define DDR_EMRS1_DLL_MASK (1 << DDR_EMRS1_DLL_BIT)
+ #define DDR_EMRS1_DLL_EN (0 << DDR_EMRS1_DLL_BIT)
+ #define DDR_EMRS1_DLL_DIS (1 << DDR_EMRS1_DLL_BIT)
+
+/* Mobile SDRAM Extended Mode Register */
+#define DDR_EMRS_DS_BIT 5 /* Driver strength */
+#define DDR_EMRS_DS_MASK (7 << DDR_EMRS_DS_BIT)
+ #define DDR_EMRS_DS_FULL (0 << DDR_EMRS_DS_BIT) /*Full*/
+ #define DDR_EMRS_DS_HALF (1 << DDR_EMRS_DS_BIT) /*1/2 Strength*/
+ #define DDR_EMRS_DS_QUTR (2 << DDR_EMRS_DS_BIT) /*1/4 Strength*/
+ #define DDR_EMRS_DS_OCTANT (3 << DDR_EMRS_DS_BIT) /*1/8 Strength*/
+ #define DDR_EMRS_DS_QUTR3 (4 << DDR_EMRS_DS_BIT) /*3/4 Strength*/
+
+#define DDR_EMRS_PRSR_BIT 0 /* Partial Array Self Refresh */
+#define DDR_EMRS_PRSR_MASK (7 << DDR_EMRS_PRSR_BIT)
+ #define DDR_EMRS_PRSR_ALL (0 << DDR_EMRS_PRSR_BIT) /*All Banks*/
+ #define DDR_EMRS_PRSR_HALF_TL (1 << DDR_EMRS_PRSR_BIT) /*Half of Total Bank*/
+ #define DDR_EMRS_PRSR_QUTR_TL (2 << DDR_EMRS_PRSR_BIT) /*Quarter of Total Bank*/
+ #define DDR_EMRS_PRSR_HALF_B0 (5 << DDR_EMRS_PRSR_BIT) /*Half of Bank0*/
+ #define DDR_EMRS_PRSR_QUTR_B0 (6 << DDR_EMRS_PRSR_BIT) /*Quarter of Bank0*/
+
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRAS_BIT 28 /* ACTIVE to PRECHARGE command period (2 * tRAS + 1) */
+#define DDRC_TIMING1_TRAS_MASK (0xf << DDRC_TIMING1_TRAS_BIT)
+
+
+#define DDRC_TIMING1_TRTP_BIT 24 /* READ to PRECHARGE command period. */
+#define DDRC_TIMING1_TRTP_MASK (0x3 << DDRC_TIMING1_TRTP_BIT)
+
+#define DDRC_TIMING1_TRP_BIT 20 /* PRECHARGE command period. */
+#define DDRC_TIMING1_TRP_MASK (0x7 << DDRC_TIMING1_TRP_BIT)
+
+#define DDRC_TIMING1_TRCD_BIT 16 /* ACTIVE to READ or WRITE command period. */
+#define DDRC_TIMING1_TRCD_MASK (0x7 << DDRC_TIMING1_TRCD_BIT)
+
+#define DDRC_TIMING1_TRC_BIT 12 /* ACTIVE to ACTIVE command period. */
+#define DDRC_TIMING1_TRC_MASK (0xf << DDRC_TIMING1_TRC_BIT)
+
+#define DDRC_TIMING1_TRRD_BIT 8 /* ACTIVE bank A to ACTIVE bank B command period. */
+#define DDRC_TIMING1_TRRD_MASK (0x3 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_DISABLE (0 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_2 (1 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_3 (2 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_4 (3 << DDRC_TIMING1_TRRD_BIT)
+
+#define DDRC_TIMING1_TWR_BIT 4 /* WRITE Recovery Time defined by register MR of DDR2 memory */
+#define DDRC_TIMING1_TWR_MASK (0x7 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_1 (0 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_2 (1 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_3 (2 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_4 (3 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_5 (4 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_6 (5 << DDRC_TIMING1_TWR_BIT)
+
+#define DDRC_TIMING1_TWTR_BIT 0 /* WRITE to READ command delay. */
+#define DDRC_TIMING1_TWTR_MASK (0x3 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_1 (0 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_2 (1 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_3 (2 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_4 (3 << DDRC_TIMING1_TWTR_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TRFC_BIT 12 /* AUTO-REFRESH command period. */
+#define DDRC_TIMING2_TRFC_MASK (0xf << DDRC_TIMING2_TRFC_BIT)
+#define DDRC_TIMING2_TMINSR_BIT 8 /* Minimum Self-Refresh / Deep-Power-Down time */
+#define DDRC_TIMING2_TMINSR_MASK (0xf << DDRC_TIMING2_TMINSR_BIT)
+#define DDRC_TIMING2_TXP_BIT 4 /* EXIT-POWER-DOWN to next valid command period. */
+#define DDRC_TIMING2_TXP_MASK (0x7 << DDRC_TIMING2_TXP_BIT)
+#define DDRC_TIMING2_TMRD_BIT 0 /* Load-Mode-Register to next valid command period. */
+#define DDRC_TIMING2_TMRD_MASK (0x3 << DDRC_TIMING2_TMRD_BIT)
+
+/* DDRC Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT 16 /* Constant value used to compare with CNT value. */
+#define DDRC_REFCNT_CON_MASK (0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT 8 /* 8-bit counter */
+#define DDRC_REFCNT_CNT_MASK (0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT 1 /* Clock Divider for auto-refresh counter. */
+#define DDRC_REFCNT_CLKDIV_MASK (0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN (1 << 0) /* Enable Refresh Counter */
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR (1 << 29) /* ahb_clk Delay Detect ERROR, read-only. */
+#define DDRC_DQS_READY (1 << 28) /* ahb_clk Delay Detect READY, read-only. */
+#define DDRC_DQS_AUTO (1 << 23) /* Hardware auto-detect & set delay line */
+#define DDRC_DQS_DET (1 << 24) /* Start delay detecting. */
+#define DDRC_DQS_CLKD_BIT 16 /* CLKD is reference value for setting WDQS and RDQS.*/
+#define DDRC_DQS_CLKD_MASK (0x7f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT 8 /* Set delay element number to write DQS delay-line. */
+#define DDRC_DQS_WDQS_MASK (0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT 0 /* Set delay element number to read DQS delay-line. */
+#define DDRC_DQS_RDQS_MASK (0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT 8 /* The adjust value for WRITE DQS delay */
+#define DDRC_DQS_ADJWDQS_MASK (0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT 0 /* The adjust value for READ DQS delay */
+#define DDRC_DQS_ADJRDQS_MASK (0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT 8 /* base address */
+#define DDRC_MMAP_BASE_MASK (0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT 0 /* address mask */
+#define DDRC_MMAP_MASK_MASK (0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE (0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M (0x24 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+#define DDRC_MMAP1_BASE_128M (0x28 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+#define DDRC_MMAP1_BASE_256M (0x30 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+
+#define DDRC_MMAP_MASK_64_64 (0xfc << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+#define DDRC_MMAP_MASK_128_128 (0xf8 << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+#define DDRC_MMAP_MASK_256_256 (0xf0 << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760DDRC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760dmac.h b/arch/mips/include/asm/mach-jz4760/jz4760dmac.h
new file mode 100644
index 00000000000..7fd23dc644d
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760dmac.h
@@ -0,0 +1,373 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760dmac.h
+ *
+ * JZ4760 DMAC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760DMAC_H__
+#define __JZ4760DMAC_H__
+
+
+#define DMAC_BASE 0xB3420000
+
+
+/*************************************************************************
+ * DMAC (DMA Controller)
+ *************************************************************************/
+
+#define MAX_DMA_NUM 12 /* max 12 channels */
+#define MAX_MDMA_NUM 3 /* max 3 channels */
+#define MAX_BDMA_NUM 3 /* max 3 channels */
+#define HALF_DMA_NUM 6 /* the number of one dma controller's channels */
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define DMAC_DSAR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x00 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA source address */
+#define DMAC_DTAR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x04 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA target address */
+#define DMAC_DTCR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x08 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA transfer count */
+#define DMAC_DRSR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x0c + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA request source */
+#define DMAC_DCCSR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x10 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA control/status */
+#define DMAC_DCMD(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x14 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA command */
+#define DMAC_DDA(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x18 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA descriptor address */
+#define DMAC_DSD(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0xc0 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x04)) /* DMA Stride Address */
+
+#define DMAC_DMACR(m) (DMAC_BASE + 0x0300 + 0x100 * (m)) /* DMA control register */
+#define DMAC_DMAIPR(m) (DMAC_BASE + 0x0304 + 0x100 * (m)) /* DMA interrupt pending */
+#define DMAC_DMADBR(m) (DMAC_BASE + 0x0308 + 0x100 * (m)) /* DMA doorbell */
+#define DMAC_DMADBSR(m) (DMAC_BASE + 0x030C + 0x100 * (m)) /* DMA doorbell set */
+#define DMAC_DMACKE(m) (DMAC_BASE + 0x0310 + 0x100 * (m))
+
+#define REG_DMAC_DSAR(n) REG32(DMAC_DSAR((n)))
+#define REG_DMAC_DTAR(n) REG32(DMAC_DTAR((n)))
+#define REG_DMAC_DTCR(n) REG32(DMAC_DTCR((n)))
+#define REG_DMAC_DRSR(n) REG32(DMAC_DRSR((n)))
+#define REG_DMAC_DCCSR(n) REG32(DMAC_DCCSR((n)))
+#define REG_DMAC_DCMD(n) REG32(DMAC_DCMD((n)))
+#define REG_DMAC_DDA(n) REG32(DMAC_DDA((n)))
+#define REG_DMAC_DSD(n) REG32(DMAC_DSD(n))
+#define REG_DMAC_DMACR(m) REG32(DMAC_DMACR(m))
+#define REG_DMAC_DMAIPR(m) REG32(DMAC_DMAIPR(m))
+#define REG_DMAC_DMADBR(m) REG32(DMAC_DMADBR(m))
+#define REG_DMAC_DMADBSR(m) REG32(DMAC_DMADBSR(m))
+#define REG_DMAC_DMACKE(m) REG32(DMAC_DMACKE(m))
+
+// DMA request source register
+#define DMAC_DRSR_RS_BIT 0
+#define DMAC_DRSR_RS_MASK (0x3f << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_EXT (0 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_NAND (1 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_BCH_ENC (2 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_BCH_DEC (3 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_TSSIIN (9 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART3OUT (14 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART3IN (15 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART2OUT (16 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART2IN (17 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART1OUT (18 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART1IN (19 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART0OUT (20 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART0IN (21 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI0OUT (22 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI0IN (23 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AICOUT (24 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AICIN (25 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC0OUT (26 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC0IN (27 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_TCU (28 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SADC (29 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC1OUT (30 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC1IN (31 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI1OUT (32 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI1IN (33 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_PMOUT (34 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_PMIN (35 << DMAC_DRSR_RS_BIT)
+
+// DMA channel control/status register
+#define DMAC_DCCSR_NDES (1 << 31) /* descriptor (0) or not (1) ? */
+#define DMAC_DCCSR_DES8 (1 << 30) /* Descriptor 8 Word */
+#define DMAC_DCCSR_DES4 (0 << 30) /* Descriptor 4 Word */
+#define DMAC_DCCSR_CDOA_BIT 16 /* copy of DMA offset address */
+#define DMAC_DCCSR_CDOA_MASK (0xff << DMAC_DCCSR_CDOA_BIT)
+#define DMAC_DCCSR_BERR (1 << 7) /* BCH error within this transfer, Only for channel 0 */
+#define DMAC_DCCSR_INV (1 << 6) /* descriptor invalid */
+#define DMAC_DCCSR_AR (1 << 4) /* address error */
+#define DMAC_DCCSR_TT (1 << 3) /* transfer terminated */
+#define DMAC_DCCSR_HLT (1 << 2) /* DMA halted */
+#define DMAC_DCCSR_CT (1 << 1) /* count terminated */
+#define DMAC_DCCSR_EN (1 << 0) /* channel enable bit */
+
+// DMA channel command register
+#define DMAC_DCMD_EACKS_LOW (1 << 31) /* External DACK Output Level Select, active low */
+#define DMAC_DCMD_EACKS_HIGH (0 << 31) /* External DACK Output Level Select, active high */
+#define DMAC_DCMD_EACKM_WRITE (1 << 30) /* External DACK Output Mode Select, output in write cycle */
+#define DMAC_DCMD_EACKM_READ (0 << 30) /* External DACK Output Mode Select, output in read cycle */
+#define DMAC_DCMD_ERDM_BIT 28 /* External DREQ Detection Mode Select */
+#define DMAC_DCMD_ERDM_MASK (0x03 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_LOW (0 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_FALL (1 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_HIGH (2 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_RISE (3 << DMAC_DCMD_ERDM_BIT)
+#define DMAC_DCMD_BLAST (1 << 25) /* BCH last */
+#define DMAC_DCMD_SAI (1 << 23) /* source address increment */
+#define DMAC_DCMD_DAI (1 << 22) /* dest address increment */
+#define DMAC_DCMD_RDIL_BIT 16 /* request detection interval length */
+#define DMAC_DCMD_RDIL_MASK (0x0f << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_IGN (0 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_2 (1 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_4 (2 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_8 (3 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_12 (4 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_16 (5 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_20 (6 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_24 (7 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_28 (8 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_32 (9 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_48 (10 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_60 (11 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_64 (12 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_124 (13 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_128 (14 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_200 (15 << DMAC_DCMD_RDIL_BIT)
+#define DMAC_DCMD_SWDH_BIT 14 /* source port width */
+#define DMAC_DCMD_SWDH_MASK (0x03 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_32 (0 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_8 (1 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_16 (2 << DMAC_DCMD_SWDH_BIT)
+#define DMAC_DCMD_DWDH_BIT 12 /* dest port width */
+#define DMAC_DCMD_DWDH_MASK (0x03 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_32 (0 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_8 (1 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_16 (2 << DMAC_DCMD_DWDH_BIT)
+#define DMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */
+#define DMAC_DCMD_DS_MASK (0x07 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_32BIT (0 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_8BIT (1 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_16BIT (2 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_16BYTE (3 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_32BYTE (4 << DMAC_DCMD_DS_BIT)
+#define DMAC_DCMD_STDE (1 << 5) /* Stride Disable/Enable */
+#define DMAC_DCMD_DES_V (1 << 4) /* descriptor valid flag */
+#define DMAC_DCMD_DES_VM (1 << 3) /* descriptor valid mask: 1:support V-bit */
+#define DMAC_DCMD_DES_VIE (1 << 2) /* DMA valid error interrupt enable */
+#define DMAC_DCMD_TIE (1 << 1) /* DMA transfer interrupt enable */
+#define DMAC_DCMD_LINK (1 << 0) /* descriptor link enable */
+
+// DMA descriptor address register
+#define DMAC_DDA_BASE_BIT 12 /* descriptor base address */
+#define DMAC_DDA_BASE_MASK (0x0fffff << DMAC_DDA_BASE_BIT)
+#define DMAC_DDA_OFFSET_BIT 4 /* descriptor offset address */
+#define DMAC_DDA_OFFSET_MASK (0x0ff << DMAC_DDA_OFFSET_BIT)
+
+// DMA stride address register
+#define DMAC_DSD_TSD_BIT 16 /* target stride address */
+#define DMAC_DSD_TSD_MASK (0xffff << DMAC_DSD_TSD_BIT)
+#define DMAC_DSD_SSD_BIT 0 /* source stride address */
+#define DMAC_DSD_SSD_MASK (0xffff << DMAC_DSD_SSD_BIT)
+
+// DMA control register
+#define DMAC_DMACR_FMSC (1 << 31) /* MSC Fast DMA mode */
+#define DMAC_DMACR_FSSI (1 << 30) /* SSI Fast DMA mode */
+#define DMAC_DMACR_FTSSI (1 << 29) /* TSSI Fast DMA mode */
+#define DMAC_DMACR_FUART (1 << 28) /* UART Fast DMA mode */
+#define DMAC_DMACR_FAIC (1 << 27) /* AIC Fast DMA mode */
+#define DMAC_DMACR_PR_BIT 8 /* channel priority mode */
+#define DMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_012345 (0 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_120345 (1 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_230145 (2 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_340125 (3 << DMAC_DMACR_PR_BIT)
+#define DMAC_DMACR_HLT (1 << 3) /* DMA halt flag */
+#define DMAC_DMACR_AR (1 << 2) /* address error flag */
+#define DMAC_DMACR_DMAE (1 << 0) /* DMA enable bit */
+
+// DMA doorbell register
+#define DMAC_DMADBR_DB5 (1 << 5) /* doorbell for channel 5 */
+#define DMAC_DMADBR_DB4 (1 << 4) /* doorbell for channel 4 */
+#define DMAC_DMADBR_DB3 (1 << 3) /* doorbell for channel 3 */
+#define DMAC_DMADBR_DB2 (1 << 2) /* doorbell for channel 2 */
+#define DMAC_DMADBR_DB1 (1 << 1) /* doorbell for channel 1 */
+#define DMAC_DMADBR_DB0 (1 << 0) /* doorbell for channel 0 */
+
+// DMA doorbell set register
+#define DMAC_DMADBSR_DBS5 (1 << 5) /* enable doorbell for channel 5 */
+#define DMAC_DMADBSR_DBS4 (1 << 4) /* enable doorbell for channel 4 */
+#define DMAC_DMADBSR_DBS3 (1 << 3) /* enable doorbell for channel 3 */
+#define DMAC_DMADBSR_DBS2 (1 << 2) /* enable doorbell for channel 2 */
+#define DMAC_DMADBSR_DBS1 (1 << 1) /* enable doorbell for channel 1 */
+#define DMAC_DMADBSR_DBS0 (1 << 0) /* enable doorbell for channel 0 */
+
+// DMA interrupt pending register
+#define DMAC_DMAIPR_CIRQ5 (1 << 5) /* irq pending status for channel 5 */
+#define DMAC_DMAIPR_CIRQ4 (1 << 4) /* irq pending status for channel 4 */
+#define DMAC_DMAIPR_CIRQ3 (1 << 3) /* irq pending status for channel 3 */
+#define DMAC_DMAIPR_CIRQ2 (1 << 2) /* irq pending status for channel 2 */
+#define DMAC_DMAIPR_CIRQ1 (1 << 1) /* irq pending status for channel 1 */
+#define DMAC_DMAIPR_CIRQ0 (1 << 0) /* irq pending status for channel 0 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * DMAC
+ ***************************************************************************/
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define __dmac_enable_module(m) \
+ ( REG_DMAC_DMACR(m) |= DMAC_DMACR_DMAE | DMAC_DMACR_PR_012345 )
+#define __dmac_disable_module(m) \
+ ( REG_DMAC_DMACR(m) &= ~DMAC_DMACR_DMAE )
+
+/* p=0,1,2,3 */
+#define __dmac_set_priority(m,p) \
+do { \
+ REG_DMAC_DMACR(m) &= ~DMAC_DMACR_PR_MASK; \
+ REG_DMAC_DMACR(m) |= ((p) << DMAC_DMACR_PR_BIT); \
+} while (0)
+
+#define __dmac_test_halt_error(m) ( REG_DMAC_DMACR(m) & DMAC_DMACR_HLT )
+#define __dmac_test_addr_error(m) ( REG_DMAC_DMACR(m) & DMAC_DMACR_AR )
+
+#define __dmac_channel_enable_clk(n) \
+ REG_DMAC_DMACKE((n)/HALF_DMA_NUM) |= 1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM);
+
+#define __dmac_enable_descriptor(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES )
+#define __dmac_disable_descriptor(n) \
+ ( REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_NDES )
+
+#define __dmac_enable_channel(n) \
+do { \
+ REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_EN; \
+} while (0)
+#define __dmac_disable_channel(n) \
+do { \
+ REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN; \
+} while (0)
+#define __dmac_channel_enabled(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_EN )
+
+#define __dmac_channel_enable_irq(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_TIE )
+#define __dmac_channel_disable_irq(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE )
+
+#define __dmac_channel_transmit_halt_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_HLT )
+#define __dmac_channel_transmit_end_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_TT )
+#define __dmac_channel_address_error_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_AR )
+#define __dmac_channel_count_terminated_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_CT )
+#define __dmac_channel_descriptor_invalid_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_INV )
+
+#define __dmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT; \
+ REG_DMAC_DMACR(n/HALF_DMA_NUM) &= ~DMAC_DMACR_HLT; \
+ } while (0)
+#define __dmac_channel_clear_transmit_end(n) \
+ ( REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_TT )
+#define __dmac_channel_clear_address_error(n) \
+ do { \
+ REG_DMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_DMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_DMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_AR; \
+ REG_DMAC_DMACR(n/HALF_DMA_NUM) &= ~DMAC_DMACR_AR; \
+ } while (0)
+#define __dmac_channel_clear_count_terminated(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT )
+#define __dmac_channel_clear_descriptor_invalid(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV )
+
+#define __dmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __dmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __dmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; \
+} while (0)
+
+/* v=0-15 */
+#define __dmac_channel_set_rdil(n,v) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK; \
+ REG_DMAC_DCMD((n) |= ((v) << DMAC_DCMD_RDIL_BIT); \
+} while (0)
+
+#define __dmac_channel_dest_addr_fixed(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DAI )
+#define __dmac_channel_dest_addr_increment(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_DAI )
+
+#define __dmac_channel_src_addr_fixed(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SAI )
+#define __dmac_channel_src_addr_increment(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_SAI )
+
+#define __dmac_channel_set_doorbell(n) \
+ ( REG_DMAC_DMADBSR((n)/HALF_DMA_NUM) = (1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+
+#define __dmac_channel_irq_detected(n) ( REG_DMAC_DMAIPR((n)/HALF_DMA_NUM) & (1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+#define __dmac_channel_ack_irq(n) ( REG_DMAC_DMAIPR((n)/HALF_DMA_NUM) &= ~(1 <<((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+
+static __inline__ int __dmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_DMA_NUM; i++)
+ if (__dmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760DMAC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760emc.h b/arch/mips/include/asm/mach-jz4760/jz4760emc.h
new file mode 100644
index 00000000000..83d75dacb78
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760emc.h
@@ -0,0 +1,213 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760emc.h
+ *
+ * JZ4760 EMC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760EMC_H__
+#define __JZ4760EMC_H__
+
+
+#define EMC_BASE 0xB3010000
+
+
+/*************************************************************************
+ * EMC (External Memory Controller)
+ *************************************************************************/
+#define EMC_BCR (EMC_BASE + 0x00) /* Bus Control Register */
+#define EMC_PMEMBS1 (EMC_BASE + 0x6004)
+#define EMC_PMEMBS0 (EMC_BASE + 0x6008)
+#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_SMCR5 (EMC_BASE + 0x24) /* Static Memory Control Register 5 */
+#define EMC_SMCR6 (EMC_BASE + 0x28) /* Static Memory Control Register 6 */
+#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_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_DMAR1 (EMC_BASE + 0x94) /* SDRAM Bank 1 Addr Config Register */
+#define EMC_SDMR0 (EMC_BASE + 0xa000) /* Mode Register of SDRAM bank 0 */
+
+#define REG_EMC_BCR REG32(EMC_BCR)
+#define REG_EMC_PMEMBS1 REG32(EMC_PMEMBS1)
+#define REG_EMC_PMEMBS0 REG32(EMC_PMEMBS0)
+#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_SMCR5 REG32(EMC_SMCR5)
+#define REG_EMC_SMCR6 REG32(EMC_SMCR6)
+#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_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)
+#define REG_EMC_DMAR1 REG32(EMC_DMAR1)
+
+/* Bus Control Register */
+#define EMC_BCR_BT_SEL_BIT 30
+#define EMC_BCR_BT_SEL_MASK (0x3 << EMC_BCR_BT_SEL_BIT)
+#define EMC_BCR_PK_SEL (1 << 24)
+#define EMC_BCR_BSR_MASK (1 << 2) /* Nand and SDRAM Bus Share Select: 0, share; 1, unshare */
+ #define EMC_BCR_BSR_SHARE (0 << 2)
+ #define EMC_BCR_BSR_UNSHARE (1 << 2)
+#define EMC_BCR_BRE (1 << 1)
+#define EMC_BCR_ENDIAN (1 << 0)
+
+/* 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)
+
+/* 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_MBSEL (1 << 16)
+#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_SFR (1 << 8) /* self refresh flag */
+#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)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760EMC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760gpio.h b/arch/mips/include/asm/mach-jz4760/jz4760gpio.h
new file mode 100644
index 00000000000..ed7a699bc1b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760gpio.h
@@ -0,0 +1,826 @@
+/*
+ * jz4760gpio.h
+ * JZ4760 GPIO register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760GPIO_H__
+#define __JZ4760GPIO_H__
+
+
+/*
+ * General purpose I/O port module(GPIO) address definition
+ */
+#define GPIO_BASE 0xb0010000
+
+/* GPIO group offset */
+#define GPIO_GOS 0x100
+
+/* Each group address */
+#define GPIO_BASEA (GPIO_BASE + (0) * GPIO_GOS)
+#define GPIO_BASEB (GPIO_BASE + (1) * GPIO_GOS)
+#define GPIO_BASEC (GPIO_BASE + (2) * GPIO_GOS)
+#define GPIO_BASED (GPIO_BASE + (3) * GPIO_GOS)
+#define GPIO_BASEE (GPIO_BASE + (4) * GPIO_GOS)
+#define GPIO_BASEF (GPIO_BASE + (5) * GPIO_GOS)
+
+
+/*
+ * GPIO registers offset address definition
+ */
+#define GPIO_PXPIN_OFFSET (0x00) /* r, 32, 0x00000000 */
+#define GPIO_PXDAT_OFFSET (0x10) /* r, 32, 0x00000000 */
+#define GPIO_PXDATS_OFFSET (0x14) /* w, 32, 0x???????? */
+#define GPIO_PXDATC_OFFSET (0x18) /* w, 32, 0x???????? */
+#define GPIO_PXIM_OFFSET (0x20) /* r, 32, 0xffffffff */
+#define GPIO_PXIMS_OFFSET (0x24) /* w, 32, 0x???????? */
+#define GPIO_PXIMC_OFFSET (0x28) /* w, 32, 0x???????? */
+#define GPIO_PXPE_OFFSET (0x30) /* r, 32, 0x00000000 */
+#define GPIO_PXPES_OFFSET (0x34) /* w, 32, 0x???????? */
+#define GPIO_PXPEC_OFFSET (0x38) /* w, 32, 0x???????? */
+#define GPIO_PXFUN_OFFSET (0x40) /* r, 32, 0x00000000 */
+#define GPIO_PXFUNS_OFFSET (0x44) /* w, 32, 0x???????? */
+#define GPIO_PXFUNC_OFFSET (0x48) /* w, 32, 0x???????? */
+#define GPIO_PXSEL_OFFSET (0x50) /* r, 32, 0x00000000 */
+#define GPIO_PXSELS_OFFSET (0x54) /* w, 32, 0x???????? */
+#define GPIO_PXSELC_OFFSET (0x58) /* w, 32, 0x???????? */
+#define GPIO_PXDIR_OFFSET (0x60) /* r, 32, 0x00000000 */
+#define GPIO_PXDIRS_OFFSET (0x64) /* w, 32, 0x???????? */
+#define GPIO_PXDIRC_OFFSET (0x68) /* w, 32, 0x???????? */
+#define GPIO_PXTRG_OFFSET (0x70) /* r, 32, 0x00000000 */
+#define GPIO_PXTRGS_OFFSET (0x74) /* w, 32, 0x???????? */
+#define GPIO_PXTRGC_OFFSET (0x78) /* w, 32, 0x???????? */
+#define GPIO_PXFLG_OFFSET (0x80) /* r, 32, 0x00000000 */
+#define GPIO_PXFLGC_OFFSET (GPIO_PXDATS_OFFSET) /* w, 32, 0x???????? */
+
+
+/*
+ * GPIO registers address definition
+ */
+#define GPIO_PXPIN(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXPIN_OFFSET)
+#define GPIO_PXDAT(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDAT_OFFSET)
+#define GPIO_PXDATS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDATS_OFFSET)
+#define GPIO_PXDATC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDATC_OFFSET)
+#define GPIO_PXIM(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXIM_OFFSET)
+#define GPIO_PXIMS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXIMS_OFFSET)
+#define GPIO_PXIMC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXIMC_OFFSET)
+#define GPIO_PXPE(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXPE_OFFSET)
+#define GPIO_PXPES(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXPES_OFFSET)
+#define GPIO_PXPEC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXPEC_OFFSET)
+#define GPIO_PXFUN(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXFUN_OFFSET)
+#define GPIO_PXFUNS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXFUNS_OFFSET)
+#define GPIO_PXFUNC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXFUNC_OFFSET)
+#define GPIO_PXSEL(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXSEL_OFFSET)
+#define GPIO_PXSELS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXSELS_OFFSET)
+#define GPIO_PXSELC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXSELC_OFFSET)
+#define GPIO_PXDIR(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDIR_OFFSET)
+#define GPIO_PXDIRS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDIRS_OFFSET)
+#define GPIO_PXDIRC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXDIRC_OFFSET)
+#define GPIO_PXTRG(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXTRG_OFFSET)
+#define GPIO_PXTRGS(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXTRGS_OFFSET)
+#define GPIO_PXTRGC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXTRGC_OFFSET)
+#define GPIO_PXFLG(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXFLG_OFFSET)
+#define GPIO_PXFLGC(n) (GPIO_BASE + (n)*GPIO_GOS + GPIO_PXFLGC_OFFSET)
+
+
+
+/* */
+#define GPIO_PORT_NUM 6
+#define MAX_GPIO_NUM 192
+#define GPIO_WAKEUP (30)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+//n = 0,1,2,3,4,5 (PORTA, PORTB, PORTC, PORTD, PORTE, PORTF)
+#define REG_GPIO_PXPIN(n) REG32(GPIO_PXPIN(n))
+#define REG_GPIO_PXDAT(n) REG32(GPIO_PXDAT(n))
+#define REG_GPIO_PXDATS(n) REG32(GPIO_PXDATS(n))
+#define REG_GPIO_PXDATC(n) REG32(GPIO_PXDATC(n))
+#define REG_GPIO_PXIM(n) REG32(GPIO_PXIM(n))
+#define REG_GPIO_PXIMS(n) REG32(GPIO_PXIMS(n))
+#define REG_GPIO_PXIMC(n) REG32(GPIO_PXIMC(n))
+#define REG_GPIO_PXPE(n) REG32(GPIO_PXPE(n))
+#define REG_GPIO_PXPES(n) REG32(GPIO_PXPES(n))
+#define REG_GPIO_PXPEC(n) REG32(GPIO_PXPEC(n))
+#define REG_GPIO_PXFUN(n) REG32(GPIO_PXFUN(n))
+#define REG_GPIO_PXFUNS(n) REG32(GPIO_PXFUNS(n))
+#define REG_GPIO_PXFUNC(n) REG32(GPIO_PXFUNC(n))
+#define REG_GPIO_PXSEL(n) REG32(GPIO_PXSEL(n))
+#define REG_GPIO_PXSELS(n) REG32(GPIO_PXSELS(n))
+#define REG_GPIO_PXSELC(n) REG32(GPIO_PXSELC(n))
+#define REG_GPIO_PXDIR(n) REG32(GPIO_PXDIR(n))
+#define REG_GPIO_PXDIRS(n) REG32(GPIO_PXDIRS(n))
+#define REG_GPIO_PXDIRC(n) REG32(GPIO_PXDIRC(n))
+#define REG_GPIO_PXTRG(n) REG32(GPIO_PXTRG(n))
+#define REG_GPIO_PXTRGS(n) REG32(GPIO_PXTRGS(n))
+#define REG_GPIO_PXTRGC(n) REG32(GPIO_PXTRGC(n))
+#define REG_GPIO_PXFLG(n) REG32(GPIO_PXFLG(n))
+#define REG_GPIO_PXFLGC(n) REG32(GPIO_PXFLGC(n))
+
+/*----------------------------------------------------------------
+ * p is the port number (0,1,2,3,4,5)
+ * o is the pin offset (0-31) inside the port
+ * n is the absolute number of a pin (0-127), regardless of the port
+ */
+
+//----------------------------------------------------------------
+// Function Pins Mode
+
+#define __gpio_as_func0(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFUNS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXSELC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func1(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFUNS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func2(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFUNS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXSELC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func3(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFUNS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+} while (0)
+
+/*
+ * UART0_TxD, UART0_RxD
+ */
+#define __gpio_as_uart0() \
+do { \
+ unsigned int bits = BIT3 | BIT0; \
+ REG_GPIO_PXFUNS(5) = bits; \
+ REG_GPIO_PXTRGC(5) = bits; \
+ REG_GPIO_PXSELC(5) = bits; \
+ REG_GPIO_PXPES(5) = bits; \
+} while (0)
+
+/*
+ * UART0_TxD, UART0_RxD, UART0_CTS, UART0_RTS
+ */
+#define __gpio_as_uart0_ctsrts() \
+do { \
+ unsigned int bits = BITS_H2L(3, 0); \
+ REG_GPIO_PXFUNS(5) = bits; \
+ REG_GPIO_PXTRGC(5) = bits; \
+ REG_GPIO_PXSELC(5) = bits; \
+ REG_GPIO_PXPES(5) = bits; \
+} while (0)
+
+/*
+ * UART1_TxD, UART1_RxD
+ */
+#define __gpio_as_uart1() \
+do { \
+ unsigned int bits = BIT28 | BIT26; \
+ REG_GPIO_PXFUNS(3) = bits; \
+ REG_GPIO_PXTRGC(3) = bits; \
+ REG_GPIO_PXSELC(3) = bits; \
+ REG_GPIO_PXPES(3) = bits; \
+} while (0)
+
+/*
+ * UART1_TxD, UART1_RxD, UART1_CTS, UART1_RTS
+ */
+#define __gpio_as_uart1_ctsrts() \
+do { \
+ unsigned int bits = BITS_H2L(29, 26); \
+ REG_GPIO_PXFUNS(3) = bits; \
+ REG_GPIO_PXTRGC(3) = bits; \
+ REG_GPIO_PXSELC(3) = bits; \
+ REG_GPIO_PXPES(3) = bits; \
+} while (0)
+
+
+/*
+ * UART2_TxD, UART2_RxD
+ */
+#define __gpio_as_uart2() \
+do { \
+ unsigned int bits = BIT30 | BIT28; \
+ REG_GPIO_PXFUNS(2) = bits; \
+ REG_GPIO_PXTRGC(2) = bits; \
+ REG_GPIO_PXSELC(2) = bits; \
+ REG_GPIO_PXPES(2) = bits; \
+} while (0)
+
+/*
+ * UART2_TxD, UART2_RxD, UART2_CTS, UART2_RTS
+ */
+#define __gpio_as_uart2_ctsrts() \
+do { \
+ unsigned int bits = BITS_H2L(31, 28); \
+ REG_GPIO_PXFUNS(2) = bits; \
+ REG_GPIO_PXTRGC(2) = bits; \
+ REG_GPIO_PXSELC(2) = bits; \
+ REG_GPIO_PXPES(2) = bits; \
+} while (0)
+
+/* WARNING: the folloing macro do NOT check */
+/*
+ * UART3_TxD, UART3_RxD
+ */
+#define __gpio_as_uart3() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00000028; \
+ REG_GPIO_PXTRGC(4) = 0x00000028; \
+ REG_GPIO_PXSELS(4) = 0x00000028; \
+ REG_GPIO_PXPES(4) = 0x00000028; \
+} while (0)
+/*
+ * UART3_TxD, UART3_RxD, UART3_CTS, UART3_RTS
+ */
+#define __gpio_as_uart3_ctsrts() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00000028; \
+ REG_GPIO_PXTRGC(4) = 0x00000028; \
+ REG_GPIO_PXSELS(4) = 0x00000028; \
+ REG_GPIO_PXFUNS(4) = 0x00000300; \
+ REG_GPIO_PXTRGC(4) = 0x00000300; \
+ REG_GPIO_PXSELC(4) = 0x00000300; \
+ REG_GPIO_PXPES(4) = 0x00000328; \
+}
+
+/*
+ * SD0 ~ SD7, CS1#, CLE, ALE, FRE#, FWE#, FRB#
+ * @n: chip select number(1 ~ 6)
+ */
+#define __gpio_as_nand_8bit(n) \
+do { \
+ \
+ REG_GPIO_PXFUNS(0) = 0x000c00ff; /* SD0 ~ SD7, CS1#, FRE#, FWE# */ \
+ REG_GPIO_PXSELC(0) = 0x000c00ff; \
+ REG_GPIO_PXTRGC(0) = 0x000c00ff; \
+ REG_GPIO_PXPES(0) = 0x000c00ff; \
+ REG_GPIO_PXFUNS(1) = 0x00000003; /* CLE(SA2), ALE(SA3) */ \
+ REG_GPIO_PXSELC(1) = 0x00000003; \
+ REG_GPIO_PXTRGC(1) = 0x00000003; \
+ REG_GPIO_PXPES(1) = 0x00000003; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(0) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(0) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNC(0) = 0x00100000; /* FRB#(input) */ \
+ REG_GPIO_PXSELC(0) = 0x00100000; \
+ REG_GPIO_PXDIRC(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+#define __gpio_as_nand_16bit(n) \
+do { \
+ \
+ REG_GPIO_PXFUNS(0) = 0x000cffff; /* SD0 ~ SD15, CS1#, FRE#, FWE# */ \
+ REG_GPIO_PXSELC(0) = 0x000cffff; \
+ REG_GPIO_PXTRGC(0) = 0x000cffff; \
+ REG_GPIO_PXPES(0) = 0x000cffff; \
+ REG_GPIO_PXFUNS(1) = 0x00000003; /* CLE(SA2), ALE(SA3) */ \
+ REG_GPIO_PXSELC(1) = 0x00000003; \
+ REG_GPIO_PXTRGC(1) = 0x00000003; \
+ REG_GPIO_PXPES(1) = 0x00000003; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(0) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(0) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNC(0) = 0x00100000; /* FRB#(input) */ \
+ REG_GPIO_PXSELC(0) = 0x00100000; \
+ REG_GPIO_PXDIRC(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+/*
+ * LCD_R3~LCD_R7, LCD_G2~LCD_G7, LCD_B3~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_16bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXTRGC(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXSELC(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXPES(2) = 0x0f8ff3f8; \
+} while (0)
+
+/*
+ * LCD_R2~LCD_R7, LCD_G2~LCD_G7, LCD_B2~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_18bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fcff3fc; \
+ REG_GPIO_PXTRGC(2) = 0x0fcff3fc; \
+ REG_GPIO_PXSELC(2) = 0x0fcff3fc; \
+ REG_GPIO_PXPES(2) = 0x0fcff3fc; \
+} while (0)
+
+/*
+ * LCD_R0~LCD_R7, LCD_G0~LCD_G7, LCD_B0~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_24bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fffffff; \
+ REG_GPIO_PXTRGC(2) = 0x0fffffff; \
+ REG_GPIO_PXSELC(2) = 0x0fffffff; \
+ REG_GPIO_PXPES(2) = 0x0fffffff; \
+} while (0)
+
+/*
+ * LCD_CLS, LCD_SPL, LCD_PS, LCD_REV
+ */
+#define __gpio_as_lcd_special() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fffffff; \
+ REG_GPIO_PXTRGC(2) = 0x0fffffff; \
+ REG_GPIO_PXSELC(2) = 0x0feffbfc; \
+ REG_GPIO_PXSELS(2) = 0x00100403; \
+ REG_GPIO_PXPES(2) = 0x0fffffff; \
+} while (0)
+
+
+#define __gpio_as_epd() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0x00011e00; \
+ REG_GPIO_PXTRGS(1) = 0x00011e00; \
+ REG_GPIO_PXSELS(1) = 0x00011e00; \
+ REG_GPIO_PXPES(1) = 0x00011e00; \
+} while (0)
+
+/*
+ * CIM_D0~CIM_D7, CIM_MCLK, CIM_PCLK, CIM_VSYNC, CIM_HSYNC
+ */
+#define __gpio_as_cim() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0x0003ffc0; \
+ REG_GPIO_PXTRGC(1) = 0x0003ffc0; \
+ REG_GPIO_PXSELC(1) = 0x0003ffc0; \
+ REG_GPIO_PXPES(1) = 0x0003ffc0; \
+} while (0)
+
+/*
+ * SDATO, SDATI, BCLK, SYNC, SCLK_RSTN(gpio sepc) or
+ * SDATA_OUT, SDATA_IN, BIT_CLK, SYNC, SCLK_RESET(aic spec)
+ */
+#define __gpio_as_aic() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x16c00000; \
+ REG_GPIO_PXTRGC(4) = 0x02c00000; \
+ REG_GPIO_PXTRGS(4) = 0x14000000; \
+ REG_GPIO_PXSELC(4) = 0x14c00000; \
+ REG_GPIO_PXSELS(4) = 0x02000000; \
+ REG_GPIO_PXPES(4) = 0x16c00000; \
+} while (0)
+
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D7
+ */
+#define __gpio_as_msc0_8bit() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x3ff00000; \
+ REG_GPIO_PXTRGC(4) = 0x3ff00000; \
+ REG_GPIO_PXSELC(4) = 0x3ff00000; \
+ REG_GPIO_PXPES(4) = 0x3ff00000; \
+} while (0)
+
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D3
+ */
+#define __gpio_as_msc0_4bit() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x30f00000; \
+ REG_GPIO_PXTRGC(4) = 0x30f00000; \
+ REG_GPIO_PXSELC(4) = 0x30f00000; \
+ REG_GPIO_PXPES(4) = 0x30f00000; \
+} while (0)
+
+/*
+ * MSC1_CMD, MSC1_CLK, MSC1_D0 ~ MSC1_D3
+ */
+#define __gpio_as_msc1_4bit() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0x3f00000; \
+ REG_GPIO_PXTRGC(3) = 0x3f00000; \
+ REG_GPIO_PXSELC(3) = 0x3f00000; \
+ REG_GPIO_PXPES(3) = 0x3f00000; \
+} while (0)
+
+#if 0
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D3
+ */
+#define __gpio_as_msc0_4bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x38400300; \
+ REG_GPIO_PXTRGC(2) = 0x38400300; \
+ REG_GPIO_PXSELS(2) = 0x30400300; \
+ REG_GPIO_PXSELC(2) = 0x08000000; \
+ REG_GPIO_PXPES(2) = 0x38400300; \
+} while (0)
+
+/*
+ * MSC1_CMD, MSC1_CLK, MSC1_D0 ~ MSC1_D3
+ */
+#define __gpio_as_msc1_4bit() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xfc000000; \
+ REG_GPIO_PXTRGC(1) = 0xfc000000; \
+ REG_GPIO_PXSELC(1) = 0xfc000000; \
+ REG_GPIO_PXPES(1) = 0xfc000000; \
+} while (0)
+#endif
+
+/* Port B
+ * MSC2_CMD, MSC2_CLK, MSC2_D0 ~ MSC2_D3
+ */
+#define __gpio_as_msc2_4bit_1() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xf0300000; \
+ REG_GPIO_PXTRGC(1) = 0xf0300000; \
+ REG_GPIO_PXSELC(1) = 0xf0300000; \
+ REG_GPIO_PXPES(1) = 0xf0300000; \
+} while (0)
+
+#define __gpio_as_msc __gpio_as_msc0_4bit /* default as msc0 4bit */
+#define __gpio_as_msc0 __gpio_as_msc0_4bit /* msc0 default as 4bit */
+#define __gpio_as_msc1 __gpio_as_msc1_4bit /* msc1 only support 4bit */
+
+/*
+ * TSCLK, TSSTR, TSFRM, TSFAIL, TSDI0~7
+ */
+#define __gpio_as_tssi_1() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0x0003ffc0; \
+ REG_GPIO_PXTRGC(1) = 0x0003ffc0; \
+ REG_GPIO_PXSELS(1) = 0x0003ffc0; \
+ REG_GPIO_PXPES(1) = 0x0003ffc0; \
+} while (0)
+
+/*
+ * TSCLK, TSSTR, TSFRM, TSFAIL, TSDI0~7
+ */
+#define __gpio_as_tssi_2() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xfff00000; \
+ REG_GPIO_PXTRGC(1) = 0x0fc00000; \
+ REG_GPIO_PXTRGS(1) = 0xf0300000; \
+ REG_GPIO_PXSELC(1) = 0xfff00000; \
+ REG_GPIO_PXPES(1) = 0xfff00000; \
+} while (0)
+
+/*
+ * SSI_CE0, SSI_CE1, SSI_GPC, SSI_CLK, SSI_DT, SSI_DR
+ */
+#define __gpio_as_ssi() \
+do { \
+ REG_GPIO_PXFUNS(0) = 0x002c0000; /* SSI0_CE0, SSI0_CLK, SSI0_DT */ \
+ REG_GPIO_PXTRGS(0) = 0x002c0000; \
+ REG_GPIO_PXSELC(0) = 0x002c0000; \
+ REG_GPIO_PXPES(0) = 0x002c0000; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00100000; /* SSI0_DR */ \
+ REG_GPIO_PXTRGC(0) = 0x00100000; \
+ REG_GPIO_PXSELS(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+/*
+ * SSI_CE0, SSI_CE2, SSI_GPC, SSI_CLK, SSI_DT, SSI1_DR
+ */
+#define __gpio_as_ssi_1() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0x0000fc00; \
+ REG_GPIO_PXTRGC(5) = 0x0000fc00; \
+ REG_GPIO_PXSELC(5) = 0x0000fc00; \
+ REG_GPIO_PXPES(5) = 0x0000fc00; \
+} while (0)
+
+/* Port B
+ * SSI2_CE0, SSI2_CE2, SSI2_GPC, SSI2_CLK, SSI2_DT, SSI12_DR
+ */
+#define __gpio_as_ssi2_1() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0xf0300000; \
+ REG_GPIO_PXTRGC(5) = 0xf0300000; \
+ REG_GPIO_PXSELS(5) = 0xf0300000; \
+ REG_GPIO_PXPES(5) = 0xf0300000; \
+} while (0)
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c(n) \
+do { \
+ REG_GPIO_PXFUNS(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXTRGC(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXSELC(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXPES(3+(n)) = 0xc0000000; \
+} while (0)
+
+/*
+ * PWM0
+ */
+#define __gpio_as_pwm0() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00100000; \
+ REG_GPIO_PXSELC(4) = 0x00100000; \
+ REG_GPIO_PXPES(4) = 0x00100000; \
+} while (0)
+
+/*
+ * PWM1
+ */
+#define __gpio_as_pwm1() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x2; \
+ REG_GPIO_PXTRGC(4) = 0x2; \
+ REG_GPIO_PXSELC(4) = 0x2; \
+ REG_GPIO_PXPEC(4) = 0x2; \
+} while (0)
+
+/*
+ * PWM2
+ */
+#define __gpio_as_pwm2() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00400000; \
+ REG_GPIO_PXSELC(4) = 0x00400000; \
+ REG_GPIO_PXPES(4) = 0x00400000; \
+} while (0)
+
+/*
+ * PWM3
+ */
+#define __gpio_as_pwm3() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00800000; \
+ REG_GPIO_PXSELC(4) = 0x00800000; \
+ REG_GPIO_PXPES(4) = 0x00800000; \
+} while (0)
+
+/*
+ * PWM4
+ */
+#define __gpio_as_pwm4() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x01000000; \
+ REG_GPIO_PXSELC(4) = 0x01000000; \
+ REG_GPIO_PXPES(4) = 0x01000000; \
+} while (0)
+
+/*
+ * PWM5
+ */
+#define __gpio_as_pwm5() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x02000000; \
+ REG_GPIO_PXSELC(4) = 0x02000000; \
+ REG_GPIO_PXPES(4) = 0x02000000; \
+} while (0)
+
+/*
+ * n = 0 ~ 5
+ */
+#define __gpio_as_pwm(n) __gpio_as_pwm##n()
+
+/*
+ * OWI - PA29 function 1
+ */
+#define __gpio_as_owi() \
+do { \
+ REG_GPIO_PXFUNS(0) = 0x20000000; \
+ REG_GPIO_PXTRGC(0) = 0x20000000; \
+ REG_GPIO_PXSELS(0) = 0x20000000; \
+} while (0)
+
+/*
+ * SCC - PD08 function 0
+ * PD09 function 0
+ */
+#define __gpio_as_scc() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0xc0000300; \
+ REG_GPIO_PXTRGC(3) = 0xc0000300; \
+ REG_GPIO_PXSELC(3) = 0xc0000300; \
+} while (0)
+
+#define __gpio_as_otg_drvvbus() \
+do { \
+ REG_GPIO_PXDATC(4) = (1 << 10); \
+ REG_GPIO_PXPEC(4) = (1 << 10); \
+ REG_GPIO_PXSELC(4) = (1 << 10); \
+ REG_GPIO_PXTRGC(4) = (1 << 10); \
+ REG_GPIO_PXFUNS(4) = (1 << 10); \
+} while (0)
+
+//-------------------------------------------
+// GPIO or Interrupt Mode
+
+#define __gpio_get_port(p) (REG_GPIO_PXPIN(p))
+
+#define __gpio_port_as_output(p, o) \
+do { \
+ REG_GPIO_PXFUNC(p) = (1 << (o)); \
+ REG_GPIO_PXSELC(p) = (1 << (o)); \
+ REG_GPIO_PXDIRS(p) = (1 << (o)); \
+ REG_GPIO_PXPES(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_port_as_input(p, o) \
+do { \
+ REG_GPIO_PXFUNC(p) = (1 << (o)); \
+ REG_GPIO_PXSELC(p) = (1 << (o)); \
+ REG_GPIO_PXDIRC(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_as_output(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ __gpio_port_as_output(p, o); \
+} while (0)
+
+#define __gpio_as_input(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ __gpio_port_as_input(p, o); \
+} while (0)
+
+#define __gpio_set_pin(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDATS(p) = (1 << o); \
+} while (0)
+
+#define __gpio_clear_pin(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDATC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_get_pin(n) \
+({ \
+ unsigned int p, o, v; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ if (__gpio_get_port(p) & (1 << o)) \
+ v = 1; \
+ else \
+ v = 0; \
+ v; \
+})
+
+#define __gpio_as_irq_high_level(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRS(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_low_level(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRC(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_rise_edge(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRS(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_fall_edge(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRC(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_mask_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+} while (0)
+
+#define __gpio_unmask_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_ack_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_get_irq() \
+({ \
+ unsigned int p, i, tmp, v = 0; \
+ for (p = 3; p >= 0; p--) { \
+ tmp = REG_GPIO_PXFLG(p); \
+ for (i = 0; i < 32; i++) \
+ if (tmp & (1 << i)) \
+ v = (32*p + i); \
+ } \
+ v; \
+})
+
+#define __gpio_group_irq(n) \
+({ \
+ register int tmp, i; \
+ tmp = REG_GPIO_PXFLG(n) & (~REG_GPIO_PXIM(n)); \
+ for (i=31;i>=0;i--) \
+ if (tmp & (1 << i)) \
+ break; \
+ i; \
+})
+
+#define __gpio_enable_pull(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXPEC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_disable_pull(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXPES(p) = (1 << o); \
+} while (0)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760GPIO_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760i2c.h b/arch/mips/include/asm/mach-jz4760/jz4760i2c.h
new file mode 100644
index 00000000000..a69e37b6dd1
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760i2c.h
@@ -0,0 +1,217 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760i2c.h
+ *
+ * JZ4760 I2C register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760I2C_H__
+#define __JZ4760I2C_H__
+
+
+#define I2C0_BASE 0xB0050000
+#define I2C1_BASE 0xB0051000
+
+
+/*************************************************************************
+ * I2C
+ *************************************************************************/
+#define I2C_CTRL(n) (I2C0_BASE + (n)*0x1000 + 0x00)
+#define I2C_TAR(n) (I2C0_BASE + (n)*0x1000 + 0x04)
+#define I2C_SAR(n) (I2C0_BASE + (n)*0x1000 + 0x08)
+#define I2C_DC(n) (I2C0_BASE + (n)*0x1000 + 0x10)
+#define I2C_SHCNT(n) (I2C0_BASE + (n)*0x1000 + 0x14)
+#define I2C_SLCNT(n) (I2C0_BASE + (n)*0x1000 + 0x18)
+#define I2C_FHCNT(n) (I2C0_BASE + (n)*0x1000 + 0x1C)
+#define I2C_FLCNT(n) (I2C0_BASE + (n)*0x1000 + 0x20)
+#define I2C_INTST(n) (I2C0_BASE + (n)*0x1000 + 0x2C)
+#define I2C_INTM(n) (I2C0_BASE + (n)*0x1000 + 0x30)
+#define I2C_RXTL(n) (I2C0_BASE + (n)*0x1000 + 0x38)
+#define I2C_TXTL(n) (I2C0_BASE + (n)*0x1000 + 0x3c)
+#define I2C_CINTR(n) (I2C0_BASE + (n)*0x1000 + 0x40)
+#define I2C_CRXUF(n) (I2C0_BASE + (n)*0x1000 + 0x44)
+#define I2C_CRXOF(n) (I2C0_BASE + (n)*0x1000 + 0x48)
+#define I2C_CTXOF(n) (I2C0_BASE + (n)*0x1000 + 0x4C)
+#define I2C_CRXREQ(n) (I2C0_BASE + (n)*0x1000 + 0x50)
+#define I2C_CTXABRT(n) (I2C0_BASE + (n)*0x1000 + 0x54)
+#define I2C_CRXDONE(n) (I2C0_BASE + (n)*0x1000 + 0x58)
+#define I2C_CACT(n) (I2C0_BASE + (n)*0x1000 + 0x5C)
+#define I2C_CSTP(n) (I2C0_BASE + (n)*0x1000 + 0x60)
+#define I2C_CSTT(n) (I2C0_BASE + (n)*0x1000 + 0x64)
+#define I2C_CGC(n) (I2C0_BASE + (n)*0x1000 + 0x68)
+#define I2C_ENB(n) (I2C0_BASE + (n)*0x1000 + 0x6C)
+#define I2C_STA(n) (I2C0_BASE + (n)*0x1000 + 0x70)
+#define I2C_TXABRT(n) (I2C0_BASE + (n)*0x1000 + 0x80)
+#define I2C_SDASU(n) (I2C0_BASE + (n)*0x1000 + 0x94)
+#define I2C_ACKGC(n) (I2C0_BASE + (n)*0x1000 + 0x98)
+#define I2C_ENSTA(n) (I2C0_BASE + (n)*0x1000 + 0x9C)
+
+#define REG_I2C_CTRL(n) REG8(I2C_CTRL(n)) /* I2C Control Register (I2C_CTRL) */
+#define REG_I2C_TAR(n) REG16(I2C_TAR(n)) /* I2C target address (I2C_TAR) */
+#define REG_I2C_SAR(n) REG16(I2C_SAR(n))
+#define REG_I2C_DC(n) REG16(I2C_DC(n))
+#define REG_I2C_SHCNT(n) REG16(I2C_SHCNT(n))
+#define REG_I2C_SLCNT(n) REG16(I2C_SLCNT(n))
+#define REG_I2C_FHCNT(n) REG16(I2C_FHCNT(n))
+#define REG_I2C_FLCNT(n) REG16(I2C_FLCNT(n))
+#define REG_I2C_INTST(n) REG16(I2C_INTST(n)) /* i2c interrupt status (I2C_INTST) */
+#define REG_I2C_INTM(n) REG16(I2C_INTM(n)) /* i2c interrupt mask status (I2C_INTM) */
+#define REG_I2C_RXTL(n) REG8(I2C_RXTL(n))
+#define REG_I2C_TXTL(n) REG8(I2C_TXTL(n))
+#define REG_I2C_CINTR(n) REG8(I2C_CINTR(n))
+#define REG_I2C_CRXUF(n) REG8(I2C_CRXUF(n))
+#define REG_I2C_CRXOF(n) REG8(I2C_CRXOF(n))
+#define REG_I2C_CTXOF(n) REG8(I2C_CTXOF(n))
+#define REG_I2C_CRXREQ(n) REG8(I2C_CRXREQ(n))
+#define REG_I2C_CTXABRT(n) REG8(I2C_CTXABRT(n))
+#define REG_I2C_CRXDONE(n) REG8(I2C_CRXDONE(n))
+#define REG_I2C_CACT(n) REG8(I2C_CACT(n))
+#define REG_I2C_CSTP(n) REG8(I2C_CSTP(n))
+#define REG_I2C_CSTT(n) REG16(I2C_CSTT(n))
+#define REG_I2C_CGC(n) REG8(I2C_CGC(n))
+#define REG_I2C_ENB(n) REG8(I2C_ENB(n))
+#define REG_I2C_STA(n) REG8(I2C_STA(n))
+#define REG_I2C_TXABRT(n) REG16(I2C_TXABRT(n))
+#define REG_I2C_SDASU(n) REG8(I2C_SDASU(n))
+#define REG_I2C_ACKGC(n) REG8(I2C_ACKGC(n))
+#define REG_I2C_ENSTA(n) REG8(I2C_ENSTA(n))
+
+/* I2C Control Register (I2C_CTRL) */
+
+#define I2C_CTRL_SLVDIS (1 << 6) /* after reset slave is disabled*/
+#define I2C_CTRL_REST (1 << 5)
+#define I2C_CTRL_MATP (1 << 4) /* 1: 10bit address 0: 7bit addressing*/
+#define I2C_CTRL_SATP (1 << 3) /* standard mode 100kbps */
+#define I2C_CTRL_SPDF (2 << 1) /* fast mode 400kbps */
+#define I2C_CTRL_SPDS (1 << 1) /* standard mode 100kbps */
+#define I2C_CTRL_MD (1 << 0) /* master enabled*/
+
+/* I2C target address (I2C_TAR) */
+
+#define I2C_TAR_MATP (1 << 12)
+#define I2C_TAR_SPECIAL (1 << 11)
+#define I2C_TAR_GC_OR_START (1 << 10)
+
+/* I2C slave address */
+/* I2C data buffer and command (I2C_DC) */
+
+#define I2C_DC_CMD (1 << 8) /* 1 read 0 write*/
+
+/* i2c interrupt status (I2C_INTST) */
+
+#define I2C_INTST_IGC (1 << 11) /* */
+#define I2C_INTST_ISTT (1 << 10)
+#define I2C_INTST_ISTP (1 << 9)
+#define I2C_INTST_IACT (1 << 8)
+#define I2C_INTST_RXDN (1 << 7)
+#define I2C_INTST_TXABT (1 << 6)
+#define I2C_INTST_RDREQ (1 << 5)
+#define I2C_INTST_TXEMP (1 << 4)
+#define I2C_INTST_TXOF (1 << 3)
+#define I2C_INTST_RXFL (1 << 2)
+#define I2C_INTST_RXOF (1 << 1)
+#define I2C_INTST_RXUF (1 << 0)
+
+/* i2c interrupt mask status (I2C_INTM) */
+
+#define I2C_INTM_MIGC (1 << 11) /* */
+#define I2C_INTM_MISTT (1 << 10)
+#define I2C_INTM_MISTP (1 << 9)
+#define I2C_INTM_MIACT (1 << 8)
+#define I2C_INTM_MRXDN (1 << 7)
+#define I2C_INTM_MTXABT (1 << 6)
+#define I2C_INTM_MRDREQ (1 << 5)
+#define I2C_INTM_MTXEMP (1 << 4)
+#define I2C_INTM_MTXOF (1 << 3)
+#define I2C_INTM_MRXFL (1 << 2)
+#define I2C_INTM_MRXOF (1 << 1)
+#define I2C_INTM_MRXUF (1 << 0)
+
+/* I2C Clear Combined and Individual Interrupts (I2C_CINTR) */
+
+#define I2C_CINTR_CINT
+
+/* I2C Clear TX_OVER Interrupt */
+/* I2C Clear RDREQ Interrupt */
+/* I2C Clear TX_ABRT Interrupt */
+/* I2C Clear RX_DONE Interrupt */
+/* I2C Clear ACTIVITY Interrupt */
+/* I2C Clear STOP Interrupts */
+/* I2C Clear START Interrupts */
+/* I2C Clear GEN_CALL Interrupts */
+
+/* I2C Enable (I2C_ENB) */
+
+#define I2C_ENB_I2CENB (1 << 0) /* Enable the i2c */
+
+/* I2C Status Register (I2C_STA) */
+
+#define I2C_STA_SLVACT (1 << 6) /* Slave FSM is not in IDLE state */
+#define I2C_STA_MSTACT (1 << 5) /* Master FSM is not in IDLE state */
+#define I2C_STA_RFF (1 << 4) /* RFIFO if full */
+#define I2C_STA_RFNE (1 << 3) /* RFIFO is not empty */
+#define I2C_STA_TFE (1 << 2) /* TFIFO is empty */
+#define I2C_STA_TFNF (1 << 1) /* TFIFO is not full */
+#define I2C_STA_ACT (1 << 0) /* I2C Activity Status */
+
+/* I2C Transmit Abort Status Register (I2C_TXABRT) */
+
+#define I2C_TXABRT_SLVRD_INTX (1 << 15)
+#define I2C_TXABRT_SLV_ARBLOST (1 << 14)
+#define I2C_TXABRT_SLVFLUSH_TXFIFO (1 << 13)
+#define I2C_TXABRT_ARB_LOST (1 << 12)
+#define I2C_TXABRT_ABRT_MASTER_DIS (1 << 11)
+#define I2C_TXABRT_ABRT_10B_RD_NORSTRT (1 << 10)
+#define I2C_TXABRT_SBYTE_NORSTRT (1 << 9)
+#define I2C_TXABRT_ABRT_HS_NORSTRT (1 << 8)
+#define I2C_TXABRT_SBYTE_ACKDET (1 << 7)
+#define I2C_TXABRT_ABRT_HS_ACKD (1 << 6)
+#define I2C_TXABRT_ABRT_GCALL_READ (1 << 5)
+#define I2C_TXABRT_ABRT_GCALL_NOACK (1 << 4)
+#define I2C_TXABRT_ABRT_XDATA_NOACK (1 << 3)
+#define I2C_TXABRT_ABRT_10ADDR2_NOACK (1 << 2)
+#define I2C_TXABRT_ABRT_10ADDR1_NOACK (1 << 1)
+#define I2C_TXABRT_ABRT_7B_ADDR_NOACK (1 << 0)
+
+/* I2C Enable Status Register (I2C_ENSTA) */
+
+#define I2C_ENSTA_SLVRDLST (1 << 2)
+#define I2C_ENSTA_SLVDISB (1 << 1)
+#define I2C_ENSTA_I2CEN (1 << 0) /* when read as 1, i2c is deemed to be in an enabled state
+ when read as 0, i2c is deemed completely inactive. The cpu can
+ safely read this bit anytime .When this bit is read as 0 ,the cpu can
+ safely read SLVRDLST and SLVDISB */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * I2C
+ ***************************************************************************/
+
+#define __i2c_enable(n) ( REG_I2C_ENB(n) = 1 )
+#define __i2c_disable(n) ( REG_I2C_ENB(n) = 0 )
+
+#define __i2c_is_enable(n) ( REG_I2C_ENSTA(n) & I2C_ENB_I2CENB )
+#define __i2c_is_disable(n) ( !(REG_I2C_ENSTA(n) & I2C_ENB_I2CENB) )
+
+#define __i2c_abrt(n) ( REG_I2C_TXABRT(n) != 0 )
+#define __i2c_master_active(n) ( REG_I2C_STA(n) & I2C_STA_MSTACT )
+#define __i2c_abrt_7b_addr_nack(n) ( REG_I2C_TXABRT(n) & I2C_TXABRT_ABRT_7B_ADDR_NOACK )
+#define __i2c_txfifo_is_empty(n) ( REG_I2C_STA(n) & I2C_STA_TFE )
+#define __i2c_clear_interrupts(ret,n) ( ret = REG_I2C_CINTR(n) )
+
+/*
+#define __i2c_set_clk(dev_clk, i2c_clk) \
+ ( REG_I2C_GR = (dev_clk) / (16*(i2c_clk)) - 1 )
+*/
+
+#define __i2c_read(n) ( REG_I2C_DC(n) & 0xff )
+#define __i2c_write(val,n) ( REG_I2C_DC(n) = (val) )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760I2C_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760intc.h b/arch/mips/include/asm/mach-jz4760/jz4760intc.h
new file mode 100644
index 00000000000..44e6a5570af
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760intc.h
@@ -0,0 +1,114 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760intc.h
+ *
+ * JZ4760 INTC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760INTC_H__
+#define __JZ4760INTC_H__
+
+
+#define INTC_BASE 0xB0001000
+
+
+/*************************************************************************
+ * INTC (Interrupt Controller)
+ *************************************************************************/
+/* n = 0 ~ 1 */
+#define INTC_ISR(n) (INTC_BASE + 0x00 + (n) * 0x20)
+#define INTC_IMR(n) (INTC_BASE + 0x04 + (n) * 0x20)
+#define INTC_ICMR(n) INTC_IMR(n)
+#define INTC_IMSR(n) (INTC_BASE + 0x08 + (n) * 0x20)
+#define INTC_ICMSR(n) INTC_IMSR(n)
+#define INTC_IMCR(n) (INTC_BASE + 0x0c + (n) * 0x20)
+#define INTC_IPR(n) (INTC_BASE + 0x10 + (n) * 0x20)
+//#define INTC_ISSR (INTC_BASE + 0x18) /* Interrupt Controller Source Set Register */
+//#define INTC_ISCR (INTC_BASE + 0x1c) /* Interrupt Controller Source Clear Register */
+
+#define REG_INTC_ISR(n) REG32(INTC_ISR(n))
+#define REG_INTC_IMR(n) REG32(INTC_IMR(n))
+#define REG_INTC_IMSR(n) REG32(INTC_IMSR(n))
+#define REG_INTC_IMCR(n) REG32(INTC_IMCR(n))
+#define REG_INTC_IPR(n) REG32(INTC_IPR(n))
+//#define REG_INTC_ISSR REG32(INTC_ISSR)
+//#define REG_INTC_ISCR REG32(INTC_ISCR)
+
+// 1st-level interrupts
+#define IRQ_I2C1 0
+#define IRQ_I2C0 1
+#define IRQ_UART3 2
+#define IRQ_UART2 3
+#define IRQ_UART1 4
+#define IRQ_UART0 5
+#define IRQ_SSI2 6
+#define IRQ_SSI1 7
+#define IRQ_SSI0 8
+#define IRQ_TSSI 9
+#define IRQ_BDMA 10
+#define IRQ_KBC 11
+#define IRQ_GPIO5 12
+#define IRQ_GPIO4 13
+#define IRQ_GPIO3 14
+#define IRQ_GPIO2 15
+#define IRQ_GPIO1 16
+#define IRQ_GPIO0 17
+#define IRQ_SADC 18
+#define IRQ_ETH 19
+#define IRQ_UHC 20
+#define IRQ_OTG 21
+#define IRQ_MDMA 22
+#define IRQ_DMAC1 23
+#define IRQ_DMAC0 24
+#define IRQ_TCU2 25
+#define IRQ_TCU1 26
+#define IRQ_TCU0 27
+#define IRQ_GPS 28
+#define IRQ_IPU 29
+#define IRQ_CIM 30
+#define IRQ_LCD 31
+
+#define IRQ_RTC 32
+#define IRQ_OWI 33
+#define IRQ_AIC 34
+#define IRQ_MSC2 35
+#define IRQ_MSC1 36
+#define IRQ_MSC0 37
+#define IRQ_SCC 38
+#define IRQ_BCH 39
+#define IRQ_PCM 40
+
+
+// 2nd-level interrupts
+
+#define IRQ_DMA_0 46 /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+//#define IRQ_DMA_0 32 /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+#define IRQ_DMA_1 (IRQ_DMA_0 + HALF_DMA_NUM) /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+#define IRQ_MDMA_0 (IRQ_DMA_0 + MAX_DMA_NUM) /* 64 ~ 66 for MDMAC channel 0 ~ 2 */
+#define IRQ_BDMA_0 (IRQ_DMA_0 + MAX_DMA_NUM + MAX_MDMA_NUM) /* 61 ~ 63 for BDMA channel 0 ~ 2 */
+
+//#define IRQ_GPIO_0 96 /* 96 to 287 for GPIO pin 0 to 127 */
+#define IRQ_GPIO_0 64 /* 96 to 287 for GPIO pin 0 to 127 */
+
+#define NUM_INTC 41
+#define NUM_DMA MAX_DMA_NUM /* 12 */
+#define NUM_MDMA MAX_MDMA_NUM /* 3 */
+#define NUM_GPIO MAX_GPIO_NUM /* GPIO NUM: 192, Jz4760 real num GPIO 178 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * INTC
+ ***************************************************************************/
+#define __intc_unmask_irq(n) (REG_INTC_IMCR((n)/32) = (1 << ((n)%32)))
+#define __intc_mask_irq(n) (REG_INTC_IMSR((n)/32) = (1 << ((n)%32)))
+#define __intc_ack_irq(n) (REG_INTC_IPR((n)/32) = (1 << ((n)%32))) /* A dummy ack, as the Pending Register is Read Only. Should we remove __intc_ack_irq() */
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760INTC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760ipu.h b/arch/mips/include/asm/mach-jz4760/jz4760ipu.h
new file mode 100644
index 00000000000..5cccb1f12b6
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760ipu.h
@@ -0,0 +1,328 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760ipu.h
+ *
+ * JZ4760 IPU register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760IPU_H__
+#define __JZ4760IPU_H__
+
+
+#define IPU_BASE 0xB3080000
+
+/*************************************************************************
+ * IPU (Image Processing Unit)
+ *************************************************************************/
+#define IPU_V_BASE 0xB3080000
+#define IPU_P_BASE 0x13080000
+
+/* Register offset */
+#define REG_CTRL 0x0 /* IPU Control Register */
+#define REG_STATUS 0x4 /* IPU Status Register */
+#define REG_D_FMT 0x8 /* Data Format Register */
+#define REG_Y_ADDR 0xc /* Input Y or YUV422 Packaged Data Address Register */
+#define REG_U_ADDR 0x10 /* Input U Data Address Register */
+#define REG_V_ADDR 0x14 /* Input V Data Address Register */
+#define REG_IN_FM_GS 0x18 /* Input Geometric Size Register */
+#define REG_Y_STRIDE 0x1c /* Input Y Data Line Stride Register */
+#define REG_UV_STRIDE 0x20 /* Input UV Data Line Stride Register */
+#define REG_OUT_ADDR 0x24 /* Output Frame Start Address Register */
+#define REG_OUT_GS 0x28 /* Output Geometric Size Register */
+#define REG_OUT_STRIDE 0x2c /* Output Data Line Stride Register */
+#define REG_RSZ_COEF_INDEX 0x30 /* Resize Coefficients Table Index Register */
+#define REG_CSC_CO_COEF 0x34 /* CSC C0 Coefficient Register */
+#define REG_CSC_C1_COEF 0x38 /* CSC C1 Coefficient Register */
+#define REG_CSC_C2_COEF 0x3c /* CSC C2 Coefficient Register */
+#define REG_CSC_C3_COEF 0x40 /* CSC C3 Coefficient Register */
+#define REG_CSC_C4_COEF 0x44 /* CSC C4 Coefficient Register */
+#define HRSZ_LUT_BASE 0x48 /* Horizontal Resize Coefficients Look Up Table Register group */
+#define VRSZ_LUT_BASE 0x4c /* Virtical Resize Coefficients Look Up Table Register group */
+#define REG_CSC_OFSET_PARA 0x50 /* CSC Offset Parameter Register */
+#define REG_Y_PHY_T_ADDR 0x54 /* Input Y Physical Table Address Register */
+#define REG_U_PHY_T_ADDR 0x58 /* Input U Physical Table Address Register */
+#define REG_V_PHY_T_ADDR 0x5c /* Input V Physical Table Address Register */
+#define REG_OUT_PHY_T_ADDR 0x60 /* Output Physical Table Address Register */
+
+/* REG_CTRL: IPU Control Register */
+#define IPU_CE_SFT 0x0
+#define IPU_CE_MSK 0x1
+#define IPU_RUN_SFT 0x1
+#define IPU_RUN_MSK 0x1
+#define HRSZ_EN_SFT 0x2
+#define HRSZ_EN_MSK 0x1
+#define VRSZ_EN_SFT 0x3
+#define VRSZ_EN_MSK 0x1
+#define CSC_EN_SFT 0x4
+#define CSC_EN_MSK 0x1
+#define FM_IRQ_EN_SFT 0x5
+#define FM_IRQ_EN_MSK 0x1
+#define IPU_RST_SFT 0x6
+#define IPU_RST_MSK 0x1
+#define H_SCALE_SFT 0x8
+#define H_SCALE_MSK 0x1
+#define V_SCALE_SFT 0x9
+#define V_SCALE_MSK 0x1
+#define PKG_SEL_SFT 0xA
+#define PKG_SEL_MSK 0x1
+#define LCDC_SEL_SFT 0xB
+#define LCDC_SEL_MSK 0x1
+#define SPAGE_MAP_SFT 0xC
+#define SPAGE_MAP_MSK 0x1
+#define DPAGE_SEL_SFT 0xD
+#define DPAGE_SEL_MSK 0x1
+#define DISP_SEL_SFT 0xE
+#define DISP_SEL_MSK 0x1
+#define FIELD_CONF_EN_SFT 15
+#define FIELD_CONF_EN_MSK 1
+#define FIELD_SEL_SFT 16
+#define FIELD_SEL_MSK 1
+#define DFIX_SEL_SFT 17
+#define DFIX_SEL_MSK 1
+
+/* REG_STATUS: IPU Status Register */
+#define OUT_END_SFT 0x0
+#define OUT_END_MSK 0x1
+#define FMT_ERR_SFT 0x1
+#define FMT_ERR_MSK 0x1
+#define SIZE_ERR_SFT 0x2
+#define SIZE_ERR_MSK 0x1
+
+/* D_FMT: Data Format Register */
+#define IN_FMT_SFT 0x0
+#define IN_FMT_MSK 0x3
+#define IN_OFT_SFT 0x2
+#define IN_OFT_MSK 0x3
+#define YUV_PKG_OUT_SFT 0x10
+#define YUV_PKG_OUT_MSK 0x7
+#define OUT_FMT_SFT 0x13
+#define OUT_FMT_MSK 0x3
+#define RGB_OUT_OFT_SFT 0x15
+#define RGB_OUT_OFT_MSK 0x7
+#define RGB888_FMT_SFT 0x18
+#define RGB888_FMT_MSK 0x1
+
+/* IN_FM_GS: Input Geometric Size Register */
+#define IN_FM_H_SFT 0x0
+#define IN_FM_H_MSK 0xFFF
+#define IN_FM_W_SFT 0x10
+#define IN_FM_W_MSK 0xFFF
+
+/* Y_STRIDE: Input Y Data Line Stride Register */
+#define Y_S_SFT 0x0
+#define Y_S_MSK 0x3FFF
+
+/* UV_STRIDE: Input UV Data Line Stride Register */
+#define V_S_SFT 0x0
+#define V_S_MSK 0x1FFF
+#define U_S_SFT 0x10
+#define U_S_MSK 0x1FFF
+
+/* OUT_GS: Output Geometric Size Register */
+#define OUT_FM_H_SFT 0x0
+#define OUT_FM_H_MSK 0x1FFF
+#define OUT_FM_W_SFT 0x10
+#define OUT_FM_W_MSK 0x7FFF
+
+/* OUT_STRIDE: Output Data Line Stride Register */
+#define OUT_S_SFT 0x0
+#define OUT_S_MSK 0xFFFF
+
+/* RSZ_COEF_INDEX: Resize Coefficients Table Index Register */
+#define VE_IDX_SFT 0x0
+#define VE_IDX_MSK 0x1F
+#define HE_IDX_SFT 0x10
+#define HE_IDX_MSK 0x1F
+
+/* CSC_CX_COEF: CSC CX Coefficient Register */
+#define CX_COEF_SFT 0x0
+#define CX_COEF_MSK 0xFFF
+
+/* HRSZ_LUT_BASE, VRSZ_LUT_BASE: Resize Coefficients Look Up Table Register group */
+#define LUT_LEN 20
+
+#define OUT_N_SFT 0x0
+#define OUT_N_MSK 0x1
+#define IN_N_SFT 0x1
+#define IN_N_MSK 0x1
+#define W_COEF_SFT 0x2
+#define W_COEF_MSK 0x3FF
+
+/* CSC_OFSET_PARA: CSC Offset Parameter Register */
+#define CHROM_OF_SFT 0x10
+#define CHROM_OF_MSK 0xFF
+#define LUMA_OF_SFT 0x00
+#define LUMA_OF_MSK 0xFF
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+#if 0
+/*************************************************************************
+ * IPU (Image Processing Unit)
+ *************************************************************************/
+#define u32 volatile unsigned long
+
+#define write_reg(reg, val) \
+do { \
+ *(u32 *)(reg) = (val); \
+} while(0)
+
+#define read_reg(reg, off) (*(u32 *)((reg)+(off)))
+
+
+#define set_ipu_fmt(rgb_888_out_fmt, rgb_out_oft, out_fmt, yuv_pkg_out, in_oft, in_fmt ) \
+({ write_reg( (IPU_V_BASE + REG_D_FMT), ((in_fmt) & IN_FMT_MSK)<<IN_FMT_SFT \
+| ((in_oft) & IN_OFT_MSK)<< IN_OFT_SFT \
+| ((out_fmt) & OUT_FMT_MSK)<<OUT_FMT_SFT \
+| ((yuv_pkg_out) & YUV_PKG_OUT_MSK ) << YUV_PKG_OUT_SFT \
+| ((rgb_888_out_fmt) & RGB888_FMT_MSK ) << RGB888_FMT_SFT \
+| ((rgb_out_oft) & RGB_OUT_OFT_MSK ) << RGB_OUT_OFT_SFT); \
+})
+#define set_y_addr(y_addr) \
+({ write_reg( (IPU_V_BASE + REG_Y_ADDR), y_addr); \
+})
+#define set_u_addr(u_addr) \
+({ write_reg( (IPU_V_BASE + REG_U_ADDR), u_addr); \
+})
+
+#define set_v_addr(v_addr) \
+({ write_reg( (IPU_V_BASE + REG_V_ADDR), v_addr); \
+})
+
+#define set_y_phy_t_addr(y_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_Y_PHY_T_ADDR), y_phy_t_addr); \
+})
+
+#define set_u_phy_t_addr(u_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_U_PHY_T_ADDR), u_phy_t_addr); \
+})
+
+#define set_v_phy_t_addr(v_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_V_PHY_T_ADDR), v_phy_t_addr); \
+})
+
+#define set_out_phy_t_addr(out_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_OUT_PHY_T_ADDR), out_phy_t_addr); \
+})
+
+#define set_inframe_gsize(width, height, y_stride, u_stride, v_stride) \
+({ write_reg( (IPU_V_BASE + REG_IN_FM_GS), ((width) & IN_FM_W_MSK)<<IN_FM_W_SFT \
+| ((height) & IN_FM_H_MSK)<<IN_FM_H_SFT); \
+ write_reg( (IPU_V_BASE + REG_Y_STRIDE), ((y_stride) & Y_S_MSK)<<Y_S_SFT); \
+ write_reg( (IPU_V_BASE + REG_UV_STRIDE), ((u_stride) & U_S_MSK)<<U_S_SFT \
+| ((v_stride) & V_S_MSK)<<V_S_SFT); \
+})
+#define set_out_addr(out_addr) \
+({ write_reg( (IPU_V_BASE + REG_OUT_ADDR), out_addr); \
+})
+#define set_outframe_gsize(width, height, o_stride) \
+({ write_reg( (IPU_V_BASE + REG_OUT_GS), ((width) & OUT_FM_W_MSK)<<OUT_FM_W_SFT \
+| ((height) & OUT_FM_H_MSK)<<OUT_FM_H_SFT); \
+ write_reg( (IPU_V_BASE + REG_OUT_STRIDE), ((o_stride) & OUT_S_MSK)<<OUT_S_SFT); \
+})
+#define set_rsz_lut_end(h_end, v_end) \
+({ write_reg( (IPU_V_BASE + REG_RSZ_COEF_INDEX), ((h_end) & HE_IDX_MSK)<<HE_IDX_SFT \
+| ((v_end) & VE_IDX_MSK)<<VE_IDX_SFT); \
+})
+#define set_csc_c0(c0_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_CO_COEF), ((c0_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c1(c1_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C1_COEF), ((c1_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c2(c2_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C2_COEF), ((c2_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c3(c3_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C3_COEF), ((c3_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c4(c4_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C4_COEF), ((c4_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_hrsz_lut_coef(coef, in_n, out_n) \
+({ write_reg( (IPU_V_BASE + HRSZ_LUT_BASE ), ((coef) & W_COEF_MSK)<<W_COEF_SFT \
+| ((in_n) & IN_N_MSK)<<IN_N_SFT | ((out_n) & OUT_N_MSK)<<OUT_N_SFT); \
+})
+#define set_vrsz_lut_coef(coef, in_n, out_n) \
+({ write_reg( (IPU_V_BASE + VRSZ_LUT_BASE), ((coef) & W_COEF_MSK)<<W_COEF_SFT \
+| ((in_n) & IN_N_MSK)<<IN_N_SFT | ((out_n) & OUT_N_MSK)<<OUT_N_SFT); \
+})
+
+#define set_primary_ctrl(vrsz_en, hrsz_en,csc_en, irq_en) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((irq_en) & FM_IRQ_EN_MSK)<<FM_IRQ_EN_SFT \
+| ((vrsz_en) & VRSZ_EN_MSK)<<VRSZ_EN_SFT \
+| ((hrsz_en) & HRSZ_EN_MSK)<<HRSZ_EN_SFT \
+| ((csc_en) & CSC_EN_MSK)<<CSC_EN_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(CSC_EN_MSK<<CSC_EN_SFT | FM_IRQ_EN_MSK<<FM_IRQ_EN_SFT | VRSZ_EN_MSK<<VRSZ_EN_SFT | HRSZ_EN_MSK<<HRSZ_EN_SFT ) ); \
+})
+
+#define set_source_ctrl(pkg_sel, spage_sel) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((pkg_sel) & PKG_SEL_MSK )<< PKG_SEL_SFT \
+| ((spage_sel) & SPAGE_MAP_MSK )<< SPAGE_MAP_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(SPAGE_MAP_MSK << SPAGE_MAP_SFT | PKG_SEL_MSK << PKG_SEL_SFT ) ) ; \
+})
+
+#define set_out_ctrl(lcdc_sel, dpage_sel, disp_sel) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((lcdc_sel) & LCDC_SEL_MSK )<< LCDC_SEL_SFT \
+| ((dpage_sel) & DPAGE_SEL_MSK )<< DPAGE_SEL_SFT \
+| ((disp_sel) & DISP_SEL_MSK )<< DISP_SEL_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(LCDC_SEL_MSK<< LCDC_SEL_SFT | DPAGE_SEL_MSK << DPAGE_SEL_SFT | DISP_SEL_MSK << DISP_SEL_SFT ) ); \
+})
+
+#define set_scale_ctrl(v_scal, h_scal) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((v_scal) & V_SCALE_MSK)<<V_SCALE_SFT \
+| ((h_scal) & H_SCALE_MSK)<<H_SCALE_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) & ~(V_SCALE_MSK<<V_SCALE_SFT | H_SCALE_MSK<<H_SCALE_SFT ) ); \
+})
+
+
+#define set_csc_ofset_para(chrom_oft, luma_oft) \
+({ write_reg( (IPU_V_BASE + REG_CSC_OFSET_PARA ), ((chrom_oft) & CHROM_OF_MSK ) << CHROM_OF_SFT \
+| ((luma_oft) & LUMA_OF_MSK ) << LUMA_OF_SFT ) ; \
+})
+
+#define sw_reset_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) \
+| IPU_RST_MSK<<IPU_RST_SFT); \
+})
+#define enable_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) | 0x1); \
+})
+#define disable_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) & ~0x1); \
+})
+#define run_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) | 0x2); \
+})
+#define stop_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) & ~0x2); \
+})
+
+#define polling_end_flag() \
+({ (read_reg(IPU_V_BASE, REG_STATUS)) & 0x01; \
+})
+
+#define start_vlut_coef_write() \
+({ write_reg( (IPU_V_BASE + VRSZ_LUT_BASE), ( 0x1<<12 ) ); \
+})
+
+#define start_hlut_coef_write() \
+({ write_reg( (IPU_V_BASE + HRSZ_LUT_BASE), ( 0x01<<12 ) ); \
+})
+
+#define clear_end_flag() \
+({ write_reg( (IPU_V_BASE + REG_STATUS), 0); \
+})
+#endif /* #if 0 */
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760IPU_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760lcdc.h b/arch/mips/include/asm/mach-jz4760/jz4760lcdc.h
new file mode 100644
index 00000000000..bd7a4ce2d54
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760lcdc.h
@@ -0,0 +1,1074 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760lcdc.h
+ *
+ * JZ4760 LCDC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760LCDC_H__
+#define __JZ4760LCDC_H__
+
+
+#define LCD_BASE 0xB3050000
+#define SLCD_BASE 0xB3050000
+
+
+/*************************************************************************
+ * SLCD (Smart LCD Controller)
+ *************************************************************************/
+
+#define SLCD_CFG (SLCD_BASE + 0xA0) /* SLCD Configure Register */
+#define SLCD_CTRL (SLCD_BASE + 0xA4) /* SLCD Control Register */
+#define SLCD_STATE (SLCD_BASE + 0xA8) /* SLCD Status Register */
+#define SLCD_DATA (SLCD_BASE + 0xAC) /* SLCD Data Register */
+
+#define REG_SLCD_CFG REG32(SLCD_CFG)
+#define REG_SLCD_CTRL REG8(SLCD_CTRL)
+#define REG_SLCD_STATE REG8(SLCD_STATE)
+#define REG_SLCD_DATA REG32(SLCD_DATA)
+
+/* SLCD Configure Register */
+#define SLCD_CFG_DWIDTH_BIT 10
+#define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_18BIT (0 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_16BIT (1 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x3 (2 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x2 (3 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x1 (4 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_24BIT (5 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_9BIT_x2 (7 << SLCD_CFG_DWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_BIT (8)
+#define SLCD_CFG_CWIDTH_MASK (0x7 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_16BIT (0 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_8BIT (1 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_18BIT (2 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_24BIT (3 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CS_ACTIVE_LOW (0 << 4)
+#define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4)
+#define SLCD_CFG_RS_CMD_LOW (0 << 3)
+#define SLCD_CFG_RS_CMD_HIGH (1 << 3)
+#define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1)
+#define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1)
+#define SLCD_CFG_TYPE_PARALLEL (0 << 0)
+#define SLCD_CFG_TYPE_SERIAL (1 << 0)
+
+/* SLCD Control Register */
+#define SLCD_CTRL_DMA_MODE (1 << 2)
+#define SLCD_CTRL_DMA_START (1 << 1)
+#define SLCD_CTRL_DMA_EN (1 << 0)
+
+/* SLCD Status Register */
+#define SLCD_STATE_BUSY (1 << 0)
+
+/* SLCD Data Register */
+#define SLCD_DATA_RS_DATA (0 << 31)
+#define SLCD_DATA_RS_COMMAND (1 << 31)
+
+/*************************************************************************
+ * LCD (LCD Controller)
+ *************************************************************************/
+#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */
+#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */
+#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */
+
+#define LCD_OSDC (LCD_BASE + 0x100) /* LCD OSD Configure Register */
+#define LCD_OSDCTRL (LCD_BASE + 0x104) /* LCD OSD Control Register */
+#define LCD_OSDS (LCD_BASE + 0x108) /* LCD OSD Status Register */
+#define LCD_BGC (LCD_BASE + 0x10C) /* LCD Background Color Register */
+#define LCD_KEY0 (LCD_BASE + 0x110) /* LCD Foreground Color Key Register 0 */
+#define LCD_KEY1 (LCD_BASE + 0x114) /* LCD Foreground Color Key Register 1 */
+#define LCD_ALPHA (LCD_BASE + 0x118) /* LCD ALPHA Register */
+#define LCD_IPUR (LCD_BASE + 0x11C) /* LCD IPU Restart Register */
+
+#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */
+#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
+#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
+#define LCD_XYP0 (LCD_BASE + 0x120) /* Foreground 0 XY Position Register */
+#define LCD_XYP1 (LCD_BASE + 0x124) /* Foreground 1 XY Position Register */
+#define LCD_XYP0_PART2 (LCD_BASE + 0x1F0) /* Foreground 0 PART2 XY Position Register */
+#define LCD_SIZE0 (LCD_BASE + 0x128) /* Foreground 0 Size Register */
+#define LCD_SIZE1 (LCD_BASE + 0x12C) /* Foreground 1 Size Register */
+#define LCD_SIZE0_PART2 (LCD_BASE + 0x1F4) /*Foreground 0 PART2 Size Register */
+#define LCD_RGBC (LCD_BASE + 0x90) /* RGB Controll Register */
+
+#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */
+#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */
+#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */
+#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */
+#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */
+#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */
+#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */
+#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */
+#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */
+#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */
+#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */
+#define LCD_OFFS0 (LCD_BASE + 0x60) /* DMA Offsize Register 0 */
+#define LCD_PW0 (LCD_BASE + 0x64) /* DMA Page Width Register 0 */
+#define LCD_CNUM0 (LCD_BASE + 0x68) /* DMA Command Counter Register 0 */
+#define LCD_DESSIZE0 (LCD_BASE + 0x6C) /* Foreground Size in Descriptor 0 Register*/
+
+#define LCD_DA0_PART2 (LCD_BASE + 0x1C0) /* Descriptor Address Register PART2 */
+#define LCD_SA0_PART2 (LCD_BASE + 0x1C4) /* Source Address Register PART2 */
+#define LCD_FID0_PART2 (LCD_BASE + 0x1C8) /* Frame ID Register PART2 */
+#define LCD_CMD0_PART2 (LCD_BASE + 0x1CC) /* DMA Command Register PART2 */
+#define LCD_OFFS0_PART2 (LCD_BASE + 0x1E0) /* DMA Offsize Register PART2 */
+#define LCD_PW0_PART2 (LCD_BASE + 0x1E4) /* DMA Command Counter Register PART2 */
+#define LCD_CNUM0_PART2 (LCD_BASE + 0x1E8) /* Foreground Size in Descriptor PART2 Register */
+#define LCD_DESSIZE0_PART2 (LCD_BASE + 0x1EC) /* */
+
+#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */
+#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */
+#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */
+#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */
+#define LCD_OFFS1 (LCD_BASE + 0x70) /* DMA Offsize Register 1 */
+#define LCD_PW1 (LCD_BASE + 0x74) /* DMA Page Width Register 1 */
+#define LCD_CNUM1 (LCD_BASE + 0x78) /* DMA Command Counter Register 1 */
+#define LCD_DESSIZE1 (LCD_BASE + 0x7C) /* Foreground Size in Descriptor 1 Register*/
+
+#define REG_LCD_CFG REG32(LCD_CFG)
+#define REG_LCD_CTRL REG32(LCD_CTRL)
+#define REG_LCD_STATE REG32(LCD_STATE)
+
+#define REG_LCD_OSDC REG16(LCD_OSDC)
+#define REG_LCD_OSDCTRL REG16(LCD_OSDCTRL)
+#define REG_LCD_OSDS REG16(LCD_OSDS)
+#define REG_LCD_BGC REG32(LCD_BGC)
+#define REG_LCD_KEY0 REG32(LCD_KEY0)
+#define REG_LCD_KEY1 REG32(LCD_KEY1)
+#define REG_LCD_ALPHA REG8(LCD_ALPHA)
+#define REG_LCD_IPUR REG32(LCD_IPUR)
+
+#define REG_LCD_VAT REG32(LCD_VAT)
+#define REG_LCD_DAH REG32(LCD_DAH)
+#define REG_LCD_DAV REG32(LCD_DAV)
+
+#define REG_LCD_XYP0 REG32(LCD_XYP0)
+#define REG_LCD_XYP0_PART2 REG32(LCD_XYP0_PART2)
+#define REG_LCD_XYP1 REG32(LCD_XYP1)
+#define REG_LCD_SIZE0 REG32(LCD_SIZE0)
+#define REG_LCD_SIZE0_PART2 REG32(LCD_SIZE0_PART2)
+#define REG_LCD_SIZE1 REG32(LCD_SIZE1)
+
+#define REG_LCD_RGBC REG16(LCD_RGBC)
+
+#define REG_LCD_VSYNC REG32(LCD_VSYNC)
+#define REG_LCD_HSYNC REG32(LCD_HSYNC)
+#define REG_LCD_PS REG32(LCD_PS)
+#define REG_LCD_CLS REG32(LCD_CLS)
+#define REG_LCD_SPL REG32(LCD_SPL)
+#define REG_LCD_REV REG32(LCD_REV)
+#define REG_LCD_IID REG32(LCD_IID)
+#define REG_LCD_DA0 REG32(LCD_DA0)
+#define REG_LCD_SA0 REG32(LCD_SA0)
+#define REG_LCD_FID0 REG32(LCD_FID0)
+#define REG_LCD_CMD0 REG32(LCD_CMD0)
+
+#define REG_LCD_OFFS0 REG32(LCD_OFFS0)
+#define REG_LCD_PW0 REG32(LCD_PW0)
+#define REG_LCD_CNUM0 REG32(LCD_CNUM0)
+#define REG_LCD_DESSIZE0 REG32(LCD_DESSIZE0)
+
+#define REG_LCD_DA0_PART2 REG32(LCD_DA0_PART2)
+#define REG_LCD_SA0_PART2 REG32(LCD_SA0_PART2)
+#define REG_LCD_FID0_PART2 REG32(LCD_FID0_PART2)
+#define REG_LCD_CMD0_PART2 REG32(LCD_CMD0_PART2)
+#define REG_LCD_OFFS0_PART2 REG32(LCD_OFFS0_PART2)
+#define REG_LCD_PW0_PART2 REG32(LCD_PW0_PART2)
+#define REG_LCD_CNUM0_PART2 REG32(LCD_CNUM0_PART2)
+#define REG_LCD_DESSIZE0_PART2 REG32(LCD_DESSIZE0_PART2)
+
+#define REG_LCD_DA1 REG32(LCD_DA1)
+#define REG_LCD_SA1 REG32(LCD_SA1)
+#define REG_LCD_FID1 REG32(LCD_FID1)
+#define REG_LCD_CMD1 REG32(LCD_CMD1)
+#define REG_LCD_OFFS1 REG32(LCD_OFFS1)
+#define REG_LCD_PW1 REG32(LCD_PW1)
+#define REG_LCD_CNUM1 REG32(LCD_CNUM1)
+#define REG_LCD_DESSIZE1 REG32(LCD_DESSIZE1)
+
+/* LCD Configure Register */
+#define LCD_CFG_LCDPIN_BIT 31 /* LCD pins selection */
+#define LCD_CFG_LCDPIN_MASK (0x1 << LCD_CFG_LCDPIN_BIT)
+ #define LCD_CFG_LCDPIN_LCD (0x0 << LCD_CFG_LCDPIN_BIT)
+ #define LCD_CFG_LCDPIN_SLCD (0x1 << LCD_CFG_LCDPIN_BIT)
+#define LCD_CFG_TVEPEH (1 << 30) /* TVE PAL enable extra halfline signal */
+#define LCD_CFG_FUHOLD (1 << 29) /* hold pixel clock when outFIFO underrun */
+#define LCD_CFG_NEWDES (1 << 28) /* use new descripter. old: 4words, new:8words */
+#define LCD_CFG_PALBP (1 << 27) /* bypass data format and alpha blending */
+#define LCD_CFG_TVEN (1 << 26) /* indicate the terminal is lcd or tv */
+#define LCD_CFG_RECOVER (1 << 25) /* Auto recover when output fifo underrun */
+#define LCD_CFG_DITHER (1 << 24) /* Dither function */
+#define LCD_CFG_PSM (1 << 23) /* PS signal mode */
+#define LCD_CFG_CLSM (1 << 22) /* CLS signal mode */
+#define LCD_CFG_SPLM (1 << 21) /* SPL signal mode */
+#define LCD_CFG_REVM (1 << 20) /* REV signal mode */
+#define LCD_CFG_HSYNM (1 << 19) /* HSYNC signal mode */
+#define LCD_CFG_PCLKM (1 << 18) /* PCLK signal mode */
+#define LCD_CFG_INVDAT (1 << 17) /* Inverse output data */
+#define LCD_CFG_SYNDIR_IN (1 << 16) /* VSYNC&HSYNC direction */
+#define LCD_CFG_PSP (1 << 15) /* PS pin reset state */
+#define LCD_CFG_CLSP (1 << 14) /* CLS pin reset state */
+#define LCD_CFG_SPLP (1 << 13) /* SPL pin reset state */
+#define LCD_CFG_REVP (1 << 12) /* REV pin reset state */
+#define LCD_CFG_HSP (1 << 11) /* HSYNC polarity:0-active high,1-active low */
+#define LCD_CFG_PCP (1 << 10) /* PCLK polarity:0-rising,1-falling */
+#define LCD_CFG_DEP (1 << 9) /* DE polarity:0-active high,1-active low */
+#define LCD_CFG_VSP (1 << 8) /* VSYNC polarity:0-rising,1-falling */
+#define LCD_CFG_MODE_TFT_18BIT (1 << 7) /* 18bit TFT */
+#define LCD_CFG_MODE_TFT_16BIT (0 << 7) /* 16bit TFT */
+#define LCD_CFG_MODE_TFT_24BIT (1 << 6) /* 24bit TFT */
+#define LCD_CFG_PDW_BIT 4 /* STN pins utilization */
+#define LCD_CFG_PDW_MASK (0x3 << LCD_DEV_PDW_BIT)
+#define LCD_CFG_PDW_1 (0 << LCD_CFG_PDW_BIT) /* LCD_D[0] */
+ #define LCD_CFG_PDW_2 (1 << LCD_CFG_PDW_BIT) /* LCD_D[0:1] */
+ #define LCD_CFG_PDW_4 (2 << LCD_CFG_PDW_BIT) /* LCD_D[0:3]/LCD_D[8:11] */
+ #define LCD_CFG_PDW_8 (3 << LCD_CFG_PDW_BIT) /* LCD_D[0:7]/LCD_D[8:15] */
+#define LCD_CFG_MODE_BIT 0 /* Display Device Mode Select */
+#define LCD_CFG_MODE_MASK (0x0f << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_CFG_MODE_BIT) /* 16,18 bit TFT */
+ #define LCD_CFG_MODE_SPECIAL_TFT_1 (1 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SPECIAL_TFT_2 (2 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SPECIAL_TFT_3 (3 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_INTER_CCIR656 (6 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SERIAL_TFT (12 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_LCM (13 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SLCD LCD_CFG_MODE_LCM
+
+/* LCD Control Register */
+#define LCD_CTRL_PINMD (1 << 30) /* This register set Pin distribution in 16-bit parallel mode
+ 0: 16-bit data correspond with LCD_D[15:0]
+ 1: 16-bit data correspond with LCD_D[17:10], LCD_D[8:1] */
+#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */
+#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
+ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */
+ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */
+ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */
+ #define LCD_CTRL_BST_32 (3 << LCD_CTRL_BST_BIT) /* 32-word */
+#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode(foreground 0 in OSD mode) */
+#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode(foreground 0 in OSD mode) */
+#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */
+#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */
+#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
+ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */
+ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */
+ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */
+#define LCD_CTRL_PDD_BIT 16 /* Load Palette Delay Counter */
+#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT)
+///#define LCD_CTRL_VGA (1 << 15) /* VGA interface enable */
+//#define LCD_CTRL_DACTE (1 << 14) /* DAC loop back test */
+#define LCD_CTRL_EOFM (1 << 13) /* EOF interrupt mask */
+#define LCD_CTRL_SOFM (1 << 12) /* SOF interrupt mask */
+#define LCD_CTRL_OFUM (1 << 11) /* Output FIFO underrun interrupt mask */
+#define LCD_CTRL_IFUM0 (1 << 10) /* Input FIFO 0 underrun interrupt mask */
+#define LCD_CTRL_IFUM1 (1 << 9) /* Input FIFO 1 underrun interrupt mask */
+#define LCD_CTRL_LDDM (1 << 8) /* LCD disable done interrupt mask */
+#define LCD_CTRL_QDM (1 << 7) /* LCD quick disable done interrupt mask */
+#define LCD_CTRL_BEDN (1 << 6) /* Endian selection */
+#define LCD_CTRL_PEDN (1 << 5) /* Endian in byte:0-msb first, 1-lsb first */
+#define LCD_CTRL_DIS (1 << 4) /* Disable indicate bit */
+#define LCD_CTRL_ENA (1 << 3) /* LCD enable bit */
+#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */
+#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
+ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */
+ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */
+ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */
+ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */
+ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */
+ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */
+ #define LCD_CTRL_BPP_CMPS_24 (6 << LCD_CTRL_BPP_BIT) /* 24 compress bpp */
+ #define LCD_CTRL_BPP_30 (7 << LCD_CTRL_BPP_BIT) /* 30 bpp */
+
+/* LCD Status Register */
+
+#define EPD_STATE_FEND (1<<22)
+#define EPD_STATE_PWRUP (1<<20)
+#define EPD_STATE_PWRDN (1<<19)
+
+#define LCD_STATE_QD (1 << 7) /* Quick Disable Done */
+#define LCD_STATE_EOF (1 << 5) /* EOF Flag */
+#define LCD_STATE_SOF (1 << 4) /* SOF Flag */
+#define LCD_STATE_OFU (1 << 3) /* Output FIFO Underrun */
+#define LCD_STATE_IFU0 (1 << 2) /* Input FIFO 0 Underrun */
+#define LCD_STATE_IFU1 (1 << 1) /* Input FIFO 1 Underrun */
+#define LCD_STATE_LDD (1 << 0) /* LCD Disabled */
+
+/* OSD Configure Register */
+#define LCD_OSDC_SOFM1 (1 << 15) /* Start of frame interrupt mask for foreground 1 */
+#define LCD_OSDC_EOFM1 (1 << 14) /* End of frame interrupt mask for foreground 1 */
+#define LCD_OSDC_SOFM0 (1 << 11) /* Start of frame interrupt mask for foreground 0 */
+#define LCD_OSDC_EOFM0 (1 << 10) /* End of frame interrupt mask for foreground 0 */
+
+////////////////////////////////////////////////////////////
+#define LCD_OSDC_ENDM (1 << 9) /* End of frame interrupt mask for panel. */
+#define LCD_OSDC_F0DIVMD (1 << 8) /* Divide Foreground 0 into 2 parts.
+ * 0: Foreground 0 only has one part. */
+#define LCD_OSDC_F0P1EN (1 << 7) /* 1: Foreground 0 PART1 is enabled.
+ * 0: Foreground 0 PART1 is disabled. */
+#define LCD_OSDC_F0P2MD (1 << 6) /* 1: PART 1&2 same level and same heighth
+ * 0: PART 1&2 have no same line */
+#define LCD_OSDC_F0P2EN (1 << 5) /* 1: Foreground 0 PART2 is enabled.
+ * 0: Foreground 0 PART2 is disabled.*/
+////////////////////////////////////////////////////////////
+
+#define LCD_OSDC_F1EN (1 << 4) /* enable foreground 1 */
+#define LCD_OSDC_F0EN (1 << 3) /* enable foreground 0 */
+#define LCD_OSDC_ALPHAEN (1 << 2) /* enable alpha blending */
+#define LCD_OSDC_ALPHAMD (1 << 1) /* alpha blending mode */
+#define LCD_OSDC_OSDEN (1 << 0) /* OSD mode enable */
+
+/* OSD Controll Register */
+#define LCD_OSDCTRL_IPU (1 << 15) /* input data from IPU */
+#define LCD_OSDCTRL_RGB565 (0 << 4) /* foreground 1, 16bpp, 0-RGB565, 1-RGB555 */
+#define LCD_OSDCTRL_RGB555 (1 << 4) /* foreground 1, 16bpp, 0-RGB565, 1-RGB555 */
+#define LCD_OSDCTRL_CHANGES (1 << 3) /* Change size flag */
+#define LCD_OSDCTRL_OSDBPP_BIT 0 /* Bits Per Pixel of OSD Channel 1 */
+#define LCD_OSDCTRL_OSDBPP_MASK (0x7<<LCD_OSDCTRL_OSDBPP_BIT) /* Bits Per Pixel of OSD Channel 1's MASK */
+ #define LCD_OSDCTRL_OSDBPP_2 (1 << LCD_OSDCTRL_OSDBPP_BIT)
+ #define LCD_OSDCTRL_OSDBPP_4 (2 << LCD_OSDCTRL_OSDBPP_BIT)
+ #define LCD_OSDCTRL_OSDBPP_16 (4 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 15,16 bit*/
+ #define LCD_OSDCTRL_OSDBPP_15_16 (4 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 15,16 bit*/
+ #define LCD_OSDCTRL_OSDBPP_18_24 (5 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 18,24 bit*/
+ #define LCD_OSDCTRL_OSDBPP_CMPS_24 (6 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB compress 24 bit*/
+ #define LCD_OSDCTRL_OSDBPP_30 (7 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 30 bit*/
+
+/* OSD State Register */
+#define LCD_OSDS_SOF1 (1 << 15) /* Start of frame flag for foreground 1 */
+#define LCD_OSDS_EOF1 (1 << 14) /* End of frame flag for foreground 1 */
+#define LCD_OSDS_SOF0 (1 << 11) /* Start of frame flag for foreground 0 */
+#define LCD_OSDS_EOF0 (1 << 10) /* End of frame flag for foreground 0 */
+#define LCD_OSDS_READY (1 << 0) /* Read for accept the change */
+
+/* Background Color Register */
+#define LCD_BGC_RED_OFFSET (1 << 16) /* Red color offset */
+#define LCD_BGC_RED_MASK (0xFF<<LCD_BGC_RED_OFFSET)
+#define LCD_BGC_GREEN_OFFSET (1 << 8) /* Green color offset */
+#define LCD_BGC_GREEN_MASK (0xFF<<LCD_BGC_GREEN_OFFSET)
+#define LCD_BGC_BLUE_OFFSET (1 << 0) /* Blue color offset */
+#define LCD_BGC_BLUE_MASK (0xFF<<LCD_BGC_BLUE_OFFSET)
+
+/* Foreground Color Key Register 0,1(foreground 0, foreground 1) */
+#define LCD_KEY_KEYEN (1 << 31) /* enable color key */
+#define LCD_KEY_KEYMD (1 << 30) /* color key mode */
+#define LCD_KEY_RED_OFFSET 16 /* Red color offset */
+#define LCD_KEY_RED_MASK (0xFF<<LCD_KEY_RED_OFFSET)
+#define LCD_KEY_GREEN_OFFSET 8 /* Green color offset */
+#define LCD_KEY_GREEN_MASK (0xFF<<LCD_KEY_GREEN_OFFSET)
+#define LCD_KEY_BLUE_OFFSET 0 /* Blue color offset */
+#define LCD_KEY_BLUE_MASK (0xFF<<LCD_KEY_BLUE_OFFSET)
+#define LCD_KEY_MASK (LCD_KEY_RED_MASK|LCD_KEY_GREEN_MASK|LCD_KEY_BLUE_MASK)
+
+/* IPU Restart Register */
+#define LCD_IPUR_IPUREN (1 << 31) /* IPU restart function enable*/
+#define LCD_IPUR_IPURMASK (0xFFFFFF) /* IPU restart value mask*/
+
+/* RGB Control Register */
+#define LCD_RGBC_RGBDM (1 << 15) /* enable RGB Dummy data */
+#define LCD_RGBC_DMM (1 << 14) /* RGB Dummy mode */
+#define LCD_RGBC_YCC (1 << 8) /* RGB to YCC */
+#define LCD_RGBC_ODDRGB_BIT 4 /* odd line serial RGB data arrangement */
+#define LCD_RGBC_ODDRGB_MASK (0x7<<LCD_RGBC_ODDRGB_BIT)
+ #define LCD_RGBC_ODD_RGB 0
+ #define LCD_RGBC_ODD_RBG 1
+ #define LCD_RGBC_ODD_GRB 2
+ #define LCD_RGBC_ODD_GBR 3
+ #define LCD_RGBC_ODD_BRG 4
+ #define LCD_RGBC_ODD_BGR 5
+#define LCD_RGBC_EVENRGB_BIT 0 /* even line serial RGB data arrangement */
+#define LCD_RGBC_EVENRGB_MASK (0x7<<LCD_RGBC_EVENRGB_BIT)
+ #define LCD_RGBC_EVEN_RGB 0
+ #define LCD_RGBC_EVEN_RBG 1
+ #define LCD_RGBC_EVEN_GRB 2
+ #define LCD_RGBC_EVEN_GBR 3
+ #define LCD_RGBC_EVEN_BRG 4
+ #define LCD_RGBC_EVEN_BGR 5
+
+/* Vertical Synchronize Register */
+#define LCD_VSYNC_VPS_BIT 16 /* VSYNC pulse start in line clock, fixed to 0 */
+#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT)
+#define LCD_VSYNC_VPE_BIT 0 /* VSYNC pulse end in line clock */
+#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT)
+
+/* Horizontal Synchronize Register */
+#define LCD_HSYNC_HPS_BIT 16 /* HSYNC pulse start position in dot clock */
+#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT)
+#define LCD_HSYNC_HPE_BIT 0 /* HSYNC pulse end position in dot clock */
+#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT)
+
+/* Virtual Area Setting Register */
+#define LCD_VAT_HT_BIT 16 /* Horizontal Total size in dot clock */
+#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT)
+#define LCD_VAT_VT_BIT 0 /* Vertical Total size in dot clock */
+#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT)
+
+/* Display Area Horizontal Start/End Point Register */
+#define LCD_DAH_HDS_BIT 16 /* Horizontal display area start in dot clock */
+#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT)
+#define LCD_DAH_HDE_BIT 0 /* Horizontal display area end in dot clock */
+#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT)
+
+/* Display Area Vertical Start/End Point Register */
+#define LCD_DAV_VDS_BIT 16 /* Vertical display area start in line clock */
+#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT)
+#define LCD_DAV_VDE_BIT 0 /* Vertical display area end in line clock */
+#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT)
+
+/* Foreground XY Position Register */
+#define LCD_XYP_YPOS_BIT 16 /* Y position bit of foreground 0 or 1 */
+#define LCD_XYP_YPOS_MASK (0xffff << LCD_XYP_YPOS_BIT)
+#define LCD_XYP_XPOS_BIT 0 /* X position bit of foreground 0 or 1 */
+#define LCD_XYP_XPOS_MASK (0xffff << LCD_XYP_XPOS_BIT)
+
+/* PS Signal Setting */
+#define LCD_PS_PSS_BIT 16 /* PS signal start position in dot clock */
+#define LCD_PS_PSS_MASK (0xffff << LCD_PS_PSS_BIT)
+#define LCD_PS_PSE_BIT 0 /* PS signal end position in dot clock */
+#define LCD_PS_PSE_MASK (0xffff << LCD_PS_PSE_BIT)
+
+/* CLS Signal Setting */
+#define LCD_CLS_CLSS_BIT 16 /* CLS signal start position in dot clock */
+#define LCD_CLS_CLSS_MASK (0xffff << LCD_CLS_CLSS_BIT)
+#define LCD_CLS_CLSE_BIT 0 /* CLS signal end position in dot clock */
+#define LCD_CLS_CLSE_MASK (0xffff << LCD_CLS_CLSE_BIT)
+
+/* SPL Signal Setting */
+#define LCD_SPL_SPLS_BIT 16 /* SPL signal start position in dot clock */
+#define LCD_SPL_SPLS_MASK (0xffff << LCD_SPL_SPLS_BIT)
+#define LCD_SPL_SPLE_BIT 0 /* SPL signal end position in dot clock */
+#define LCD_SPL_SPLE_MASK (0xffff << LCD_SPL_SPLE_BIT)
+
+/* REV Signal Setting */
+#define LCD_REV_REVS_BIT 16 /* REV signal start position in dot clock */
+#define LCD_REV_REVS_MASK (0xffff << LCD_REV_REVS_BIT)
+
+/* DMA Command Register */
+#define LCD_CMD_SOFINT (1 << 31)
+#define LCD_CMD_EOFINT (1 << 30)
+#define LCD_CMD_CMD (1 << 29) /* indicate command in slcd mode */
+#define LCD_CMD_PAL (1 << 28)
+#define LCD_CMD_LEN_BIT 0
+#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT)
+
+/* DMA Offsize Register 0,1 */
+
+/* DMA Page Width Register 0,1 */
+
+/* DMA Command Counter Register 0,1 */
+
+/* Foreground 0,1 Size Register */
+#define LCD_DESSIZE_HEIGHT_BIT 16 /* height of foreground 1 */
+#define LCD_DESSIZE_HEIGHT_MASK (0xffff << LCD_DESSIZE_HEIGHT_BIT)
+#define LCD_DESSIZE_WIDTH_BIT 0 /* width of foreground 1 */
+#define LCD_DESSIZE_WIDTH_MASK (0xffff << LCD_DESSIZE_WIDTH_BIT)
+
+
+/*************************************************************************
+ * EPD
+ *************************************************************************/
+#if defined(CONFIG_JZ4760_AUO_EPD_DISPLAY)
+
+#define EPD_CTRL (LCD_BASE + 0x200)
+#define EPD_STA (LCD_BASE + 0x204)
+#define EPD_ISR (LCD_BASE + 0x208)
+#define EPD_CFG0 (LCD_BASE + 0x20C)
+#define EPD_CFG1 (LCD_BASE + 0x210)
+#define EPD_PPL0 (LCD_BASE + 0x214)
+#define EPD_PLL1 (LCD_BASE + 0x218)
+#define EPD_VAT (LCD_BASE + 0x21C)
+#define EPD_DAV (LCD_BASE + 0x220)
+#define EPD_DAH (LCD_BASE + 0x224)
+#define EPD_VSYNC (LCD_BASE + 0x228)
+#define EPD_HSYNC (LCD_BASE + 0x22C)
+#define EPD_GDCLK (LCD_BASE + 0x230)
+#define EPD_GDOE (LCD_BASE + 0x234)
+#define EPD_GDSP (LCD_BASE + 0x238)
+#define EPD_SDOE (LCD_BASE + 0x23C)
+#define EPD_SDSP (LCD_BASE + 0x240)
+#define EPD_PMGR0 (LCD_BASE + 0x244)
+#define EPD_PWGR1 (LCD_BASE + 0x248)
+#define EPD_PWGR2 (LCD_BASE + 0x24C)
+#define EPD_PWGR3 (LCD_BASE + 0x250)
+#define EPD_PWGR4 (LCD_BASE + 0x254)
+#define EPD_VCOM0 (LCD_BASE + 0x258)
+#define EPD_VCOM1 (LCD_BASE + 0x25C)
+#define EPD_VCOM2 (LCD_BASE + 0x260)
+#define EPD_VCOM3 (LCD_BASE + 0x264)
+#define EPD_VCOM4 (LCD_BASE + 0x268)
+#define EPD_VCOM5 (LCD_BASE + 0x26C)
+#define EPD_PWDR (LCD_BASE + 0x270)
+#define EPD_PPL0_POS (LCD_BASE + 0x280)
+#define EPD_PPL0_SIZE (LCD_BASE + 0x284)
+#define EPD_PPL1_POS (LCD_BASE + 0x288)
+#define EPD_PPL1_SIZE (LCD_BASE + 0x28C)
+#define EPD_PPL2_POS (LCD_BASE + 0x290)
+#define EPD_PPL2_SIZE (LCD_BASE + 0x294)
+#define EPD_PPL3_POS (LCD_BASE + 0x298)
+#define EPD_PPL3_SIZE (LCD_BASE + 0x29C)
+#define EPD_PPL4_POS (LCD_BASE + 0x2A0)
+#define EPD_PPL4_SIZE (LCD_BASE + 0x2A4)
+#define EPD_PPL5_POS (LCD_BASE + 0x2A8)
+#define EPD_PPL5_SIZE (LCD_BASE + 0x2AC)
+#define EPD_PPL6_POS (LCD_BASE + 0x2B0)
+#define EPD_PPL6_SIZE (LCD_BASE + 0x2B4)
+#define EPD_PPL7_POS (LCD_BASE + 0x2B8)
+#define EPD_PPL7_SIZE (LCD_BASE + 0x2C0)
+
+
+#define REG_EPD_CTRL REG32(EPD_CTRL)
+#define REG_EPD_STA REG32(EPD_STA)
+#define REG_EPD_ISR REG32(EPD_ISR)
+#define REG_EPD_CFG0 REG32(EPD_CFG0)
+#define REG_EPD_CFG1 REG32(EPD_CFG1)
+#define REG_EPD_PPL0 REG32(EPD_PPL0)
+#define REG_EPD_PLL1 REG32(EPD_PLL1)
+#define REG_EPD_VAT REG32(EPD_VAT)
+#define REG_EPD_DAV REG32(EPD_DAV)
+#define REG_EPD_DAH REG32(EPD_DAH)
+#define REG_EPD_VSYNC REG32(EPD_VSYNC)
+#define REG_EPD_HSYNC REG32(EPD_HSYNC)
+#define REG_EPD_GDCLK REG32(EPD_GDCLK)
+#define REG_EPD_GDOE REG32(EPD_GDOE)
+#define REG_EPD_GDSP REG32(EPD_GDSP)
+#define REG_EPD_SDOE REG32(EPD_SDOE)
+#define REG_EPD_SDSP REG32(EPD_SDSP)
+#define REG_EPD_PMGR0 REG32(EPD_PMGR0)
+#define REG_EPD_PWGR1 REG32(EPD_PWGR1)
+#define REG_EPD_PWGR2 REG32(EPD_PWGR2)
+#define REG_EPD_PWGR3 REG32(EPD_PWGR3)
+#define REG_EPD_PWGR4 REG32(EPD_PWGR4)
+#define REG_EPD_VCOM0 REG32(EPD_VCOM0)
+#define REG_EPD_VCOM1 REG32(EPD_VCOM1)
+#define REG_EPD_VCOM2 REG32(EPD_VCOM2)
+#define REG_EPD_VCOM3 REG32(EPD_VCOM3)
+#define REG_EPD_VCOM4 REG32(EPD_VCOM4)
+#define REG_EPD_VCOM5 REG32(EPD_VCOM5)
+#define REG_EPD_PWDR REG32(EPD_PWDR)
+#define REG_EPD_PPL0_POS REG32(EPD_PPL0_POS)
+#define REG_EPD_PPL0_SIZE REG32(EPD_PPL0_SIZE)
+#define REG_EPD_PPL1_POS REG32(EPD_PPL1_POS)
+#define REG_EPD_PPL1_SIZE REG32(EPD_PPL1_SIZE)
+#define REG_EPD_PPL2_POS REG32(EPD_PPL2_POS)
+#define REG_EPD_PPL2_SIZE REG32(EPD_PPL2_SIZE)
+#define REG_EPD_PPL3_POS REG32(EPD_PPL3_POS)
+#define REG_EPD_PPL3_SIZE REG32(EPD_PPL3_SIZE)
+#define REG_EPD_PPL4_POS REG32(EPD_PPL4_POS)
+#define REG_EPD_PPL4_SIZE REG32(EPD_PPL4_SIZE)
+#define REG_EPD_PPL5_POS REG32(EPD_PPL5_POS)
+#define REG_EPD_PPL5_SIZE REG32(EPD_PPL5_SIZE)
+#define REG_EPD_PPL6_POS REG32(EPD_PPL6_POS)
+#define REG_EPD_PPL6_SIZE REG32(EPD_PPL6_SIZE)
+#define REG_EPD_PPL7_POS REG32(EPD_PPL7_POS)
+#define REG_EPD_PPL7_SIZE REG32(EPD_PPL7_SIZE)
+
+#else // for E-ink
+
+
+#define EPD_CTRL1 (LCD_BASE + 0xc0)
+#define EPD_CTRL2 (LCD_BASE + 0xc4)
+#define EPD_CTRL3 (LCD_BASE + 0xc8)
+#define EPD_CTRL4 (LCD_BASE + 0xcc)
+#define EPD_CTRL5 (LCD_BASE + 0xd0)
+#define EPD_CTRL6 (LCD_BASE + 0xd4)
+#define EPD_CTRL7 (LCD_BASE + 0xd8)
+#define EPD_CTRL8 (LCD_BASE + 0xdc)
+#define EPD_CTRL9 (LCD_BASE + 0xe0)
+#define EPD_VCOM0 (LCD_BASE + 0xf0)
+#define EPD_VCOM1 (LCD_BASE + 0xf4)
+#define EPD_VCOM2 (LCD_BASE + 0xf8)
+#define EPD_VCOM3 (LCD_BASE + 0xfc)
+
+#define REG_EPD_CTRL1 REG32(EPD_CTRL1)
+#define REG_EPD_CTRL2 REG32(EPD_CTRL2)
+#define REG_EPD_CTRL3 REG32(EPD_CTRL3)
+#define REG_EPD_CTRL4 REG32(EPD_CTRL4)
+#define REG_EPD_CTRL5 REG32(EPD_CTRL5)
+#define REG_EPD_CTRL6 REG32(EPD_CTRL6)
+#define REG_EPD_CTRL7 REG32(EPD_CTRL7)
+#define REG_EPD_CTRL8 REG32(EPD_CTRL8)
+#define REG_EPD_CTRL9 REG32(EPD_CTRL9)
+
+#define REG_EPD_VCOM0 REG32(EPD_VCOM0)
+#define REG_EPD_VCOM1 REG32(EPD_VCOM1)
+#define REG_EPD_VCOM2 REG32(EPD_VCOM2)
+#define REG_EPD_VCOM3 REG32(EPD_VCOM3)
+
+
+
+#define EPD_CTRL1_GDCEN_BIT 16
+#define EPD_CTRL1_GDCEN_MASK (0xfff<<EPD_CTRL1_GDCEN_BIT)
+#define EPD_CTRL1_AUO (1<<15)
+#define EPD_CTRL1_GDOEP (1<<14)
+#define EPD_CTRL1_GDRL (1<<13)
+#define EPD_CTRL1_SDOREV (1<<12)
+#define EPD_CTRL1_SDCEREV (1<<11)
+#define EPD_CTRL1_SDSHR (1<<10)
+#define EPD_CTRL1_PPC (1<<9)
+#define EPD_CTRL1_PADDINGD_BIT 1
+#define EPD_CTRL1_PADDINGD_MASK (0xff<<EPD_CTRL1_PADDINGD_BIT)
+#define EPD_CTRL1_DDREN (1<<0)
+
+#define EPD_CTRL2_DELAY01_BIT 20
+#define EPD_CTRL2_DELAY01_MASK (0xfff<<EPD_CTRL2_DELAY01_BIT)
+#define EPD_CTRL2_PWROFF (1<<19)
+#define EPD_CTRL2_PWRON (1<<18)
+#define EPD_CTRL2_PWRCOMP (1<<17)
+#define EPD_CTRL2_SDCE1_BIT 13
+#define EPD_CTRL2_SDCE1_MASK (0xf<<EPD_CTRL2_SDCE1_BIT)
+#define EPD_CTRL2_SDOS_BIT 4
+#define EPD_CTRL2_SDOS_MASK (0x1f<<EPD_CTRL2_SDOS_BIT)
+#define EPD_CTRL2_SDCN_BIT 0
+#define EPD_CTRL2_SDCN_MASK (0xf<<EPD_CTRL2_SDCN_BIT)
+
+#define EPD_CTRL3_DELAY23
+#define EPD_CTRL3_DELAY12
+#define EPD_CTRL4_PWR7P
+#define EPD_CTRL4_PWR6P
+#define EPD_CTRL4_PWR5P
+#define EPD_CTRL4_PWR4P
+#define EPD_CTRL4_PWR3P
+#define EPD_CTRL4_PWR2P
+#define EPD_CTRL4_PWR1P
+#define EPD_CTRL4_PWR0P
+#define EPD_CTRL4_PWRDNM
+#define EPD_CTRL4_EPDDMAM
+#define EPD_CTRL4_FENDM
+#define EPD_CTRL4_FCEM
+#define EPD_CTRL4_PWRUPM
+#define EPD_CTRL4_FEINTSEL
+#define EPD_CTRL4_FCANCEL
+#define EPD_CTRL4_FEN (1<<9)
+#define EPD_CTRL4_SDCEP
+#define EPD_CTRL4_SDLEP
+#define EPD_CTRL4_SDOEP
+#define EPD_CTRL4_GDCP
+#define EPD_CTRL4_GDSPP
+
+#define EPD_CTRL5_GDCDIS
+#define EPD_CTRL5_MAX_FRM
+#define EPD_CTRL5_DMA_MODE
+#define EPD_CTRL5_OBPP
+#define EPD_CTRL5_OMODE
+#define EPD_CTRL5_EPD_EN
+
+#define EPD_CTRL6_GDSPDIS
+#define EPD_CTRL6_GDSPEN
+#define EPD_CTRL7_SDOEE
+#define EPD_CTRL7_SDOES
+
+#define EPD_CTRL8_DELAY45
+#define EPD_CTRL8_DELAY34
+
+#define EPD_CTRL9_DELAY67
+#define EPD_CTRL9_DELAY56
+
+#endif //End E-ink
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * SLCD (Smart LCD Controller)
+ *************************************************************************/
+#define __slcd_set_data_18bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_18BIT )
+#define __slcd_set_data_16bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_16BIT )
+#define __slcd_set_data_8bit_x3() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x3 )
+#define __slcd_set_data_8bit_x2() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x2 )
+#define __slcd_set_data_8bit_x1() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x1 )
+#define __slcd_set_data_24bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_24BIT )
+#define __slcd_set_data_9bit_x2() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_9BIT_x2 )
+
+#define __slcd_set_cmd_16bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_16BIT )
+#define __slcd_set_cmd_8bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_8BIT )
+#define __slcd_set_cmd_18bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_18BIT )
+#define __slcd_set_cmd_24bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_24BIT )
+
+#define __slcd_set_cs_high() ( REG_SLCD_CFG |= SLCD_CFG_CS_ACTIVE_HIGH )
+#define __slcd_set_cs_low() ( REG_SLCD_CFG &= ~SLCD_CFG_CS_ACTIVE_HIGH )
+
+#define __slcd_set_rs_high() ( REG_SLCD_CFG |= SLCD_CFG_RS_CMD_HIGH )
+#define __slcd_set_rs_low() ( REG_SLCD_CFG &= ~SLCD_CFG_RS_CMD_HIGH )
+
+#define __slcd_set_clk_falling() ( REG_SLCD_CFG &= ~SLCD_CFG_CLK_ACTIVE_RISING )
+#define __slcd_set_clk_rising() ( REG_SLCD_CFG |= SLCD_CFG_CLK_ACTIVE_RISING )
+
+#define __slcd_set_parallel_type() ( REG_SLCD_CFG &= ~SLCD_CFG_TYPE_SERIAL )
+#define __slcd_set_serial_type() ( REG_SLCD_CFG |= SLCD_CFG_TYPE_SERIAL )
+
+/* SLCD Control Register */
+#define __slcd_enable_dma() ( REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN )
+#define __slcd_disable_dma() ( REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN )
+
+/* SLCD Status Register */
+#define __slcd_is_busy() ( REG_SLCD_STATE & SLCD_STATE_BUSY )
+
+/* SLCD Data Register */
+#define __slcd_set_cmd_rs() ( REG_SLCD_DATA |= SLCD_DATA_RS_COMMAND)
+#define __slcd_set_data_rs() ( REG_SLCD_DATA &= ~SLCD_DATA_RS_COMMAND)
+
+
+/***************************************************************************
+ * LCD
+ ***************************************************************************/
+
+/***************************************************************************
+ * LCD
+ ***************************************************************************/
+#define __lcd_as_smart_lcd() ( REG_LCD_CFG |= ( LCD_CFG_LCDPIN_SLCD | LCD_CFG_MODE_SLCD))
+#define __lcd_as_general_lcd() ( REG_LCD_CFG &= ~( LCD_CFG_LCDPIN_SLCD | LCD_CFG_MODE_SLCD))
+
+#define __lcd_enable_tvepeh() ( REG_LCD_CFG |= LCD_CFG_TVEPEH )
+#define __lcd_disable_tvepeh() ( REG_LCD_CFG &= ~LCD_CFG_TVEPEH )
+
+#define __lcd_enable_fuhold() ( REG_LCD_CFG |= LCD_CFG_FUHOLD )
+#define __lcd_disable_fuhold() ( REG_LCD_CFG &= ~LCD_CFG_FUHOLD )
+
+#define __lcd_des_8word() ( REG_LCD_CFG |= LCD_CFG_NEWDES )
+#define __lcd_des_4word() ( REG_LCD_CFG &= ~LCD_CFG_NEWDES )
+
+#define __lcd_enable_bypass_pal() ( REG_LCD_CFG |= LCD_CFG_PALBP )
+#define __lcd_disable_bypass_pal() ( REG_LCD_CFG &= ~LCD_CFG_PALBP )
+
+#define __lcd_set_lcdpnl_term() ( REG_LCD_CFG |= LCD_CFG_TVEN )
+#define __lcd_set_tv_term() ( REG_LCD_CFG &= ~LCD_CFG_TVEN )
+
+#define __lcd_enable_auto_recover() ( REG_LCD_CFG |= LCD_CFG_RECOVER )
+#define __lcd_disable_auto_recover() ( REG_LCD_CFG &= ~LCD_CFG_RECOVER )
+
+#define __lcd_enable_dither() ( REG_LCD_CFG |= LCD_CFG_DITHER )
+#define __lcd_disable_dither() ( REG_LCD_CFG &= ~LCD_CFG_DITHER )
+
+#define __lcd_disable_ps_mode() ( REG_LCD_CFG |= LCD_CFG_PSM )
+#define __lcd_enable_ps_mode() ( REG_LCD_CFG &= ~LCD_CFG_PSM )
+
+#define __lcd_disable_cls_mode() ( REG_LCD_CFG |= LCD_CFG_CLSM )
+#define __lcd_enable_cls_mode() ( REG_LCD_CFG &= ~LCD_CFG_CLSM )
+
+#define __lcd_disable_spl_mode() ( REG_LCD_CFG |= LCD_CFG_SPLM )
+#define __lcd_enable_spl_mode() ( REG_LCD_CFG &= ~LCD_CFG_SPLM )
+
+#define __lcd_disable_rev_mode() ( REG_LCD_CFG |= LCD_CFG_REVM )
+#define __lcd_enable_rev_mode() ( REG_LCD_CFG &= ~LCD_CFG_REVM )
+
+#define __lcd_disable_hsync_mode() ( REG_LCD_CFG |= LCD_CFG_HSYNM )
+#define __lcd_enable_hsync_mode() ( REG_LCD_CFG &= ~LCD_CFG_HSYNM )
+
+#define __lcd_disable_pclk_mode() ( REG_LCD_CFG |= LCD_CFG_PCLKM )
+#define __lcd_enable_pclk_mode() ( REG_LCD_CFG &= ~LCD_CFG_PCLKM )
+
+#define __lcd_normal_outdata() ( REG_LCD_CFG &= ~LCD_CFG_INVDAT )
+#define __lcd_inverse_outdata() ( REG_LCD_CFG |= LCD_CFG_INVDAT )
+
+#define __lcd_sync_input() ( REG_LCD_CFG |= LCD_CFG_SYNDIR_IN )
+#define __lcd_sync_output() ( REG_LCD_CFG &= ~LCD_CFG_SYNDIR_IN )
+
+#define __lcd_hsync_active_high() ( REG_LCD_CFG &= ~LCD_CFG_HSP )
+#define __lcd_hsync_active_low() ( REG_LCD_CFG |= LCD_CFG_HSP )
+
+#define __lcd_pclk_rising() ( REG_LCD_CFG &= ~LCD_CFG_PCP )
+#define __lcd_pclk_falling() ( REG_LCD_CFG |= LCD_CFG_PCP )
+
+#define __lcd_de_active_high() ( REG_LCD_CFG &= ~LCD_CFG_DEP )
+#define __lcd_de_active_low() ( REG_LCD_CFG |= LCD_CFG_DEP )
+
+#define __lcd_vsync_rising() ( REG_LCD_CFG &= ~LCD_CFG_VSP )
+#define __lcd_vsync_falling() ( REG_LCD_CFG |= LCD_CFG_VSP )
+
+#define __lcd_set_16_tftpnl() \
+ ( REG_LCD_CFG = (REG_LCD_CFG & ~LCD_CFG_MODE_TFT_MASK) | LCD_CFG_MODE_TFT_16BIT )
+
+#define __lcd_set_18_tftpnl() \
+ ( REG_LCD_CFG = (REG_LCD_CFG & ~LCD_CFG_MODE_TFT_MASK) | LCD_CFG_MODE_TFT_18BIT )
+
+#define __lcd_set_24_tftpnl() ( REG_LCD_CFG |= LCD_CFG_MODE_TFT_24BIT )
+
+/*
+ * n=1,2,4,8 for single mono-STN
+ * n=4,8 for dual mono-STN
+ */
+#define __lcd_set_panel_datawidth(n) \
+do { \
+ REG_LCD_CFG &= ~LCD_CFG_PDW_MASK; \
+ REG_LCD_CFG |= LCD_CFG_PDW_n##; \
+} while (0)
+
+/* m = LCD_CFG_MODE_GENERUIC_TFT_xxx */
+#define __lcd_set_panel_mode(m) \
+do { \
+ REG_LCD_CFG &= ~LCD_CFG_MODE_MASK; \
+ REG_LCD_CFG |= (m); \
+} while(0)
+
+/* n=4,8,16 */
+#define __lcd_set_burst_length(n) \
+do { \
+ REG_LCD_CTRL &= ~LCD_CTRL_BST_MASK; \
+ REG_LCD_CTRL |= LCD_CTRL_BST_n##; \
+} while (0)
+
+#define __lcd_select_rgb565() ( REG_LCD_CTRL &= ~LCD_CTRL_RGB555 )
+#define __lcd_select_rgb555() ( REG_LCD_CTRL |= LCD_CTRL_RGB555 )
+
+#define __lcd_set_ofup() ( REG_LCD_CTRL |= LCD_CTRL_OFUP )
+#define __lcd_clr_ofup() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUP )
+
+/* n=2,4,16 */
+#define __lcd_set_stn_frc(n) \
+do { \
+ REG_LCD_CTRL &= ~LCD_CTRL_FRC_MASK; \
+ REG_LCD_CTRL |= LCD_CTRL_FRC_n##; \
+} while (0)
+
+#define __lcd_enable_eof_intr() ( REG_LCD_CTRL |= LCD_CTRL_EOFM )
+#define __lcd_disable_eof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_EOFM )
+
+#define __lcd_enable_sof_intr() ( REG_LCD_CTRL |= LCD_CTRL_SOFM )
+#define __lcd_disable_sof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_SOFM )
+
+#define __lcd_enable_ofu_intr() ( REG_LCD_CTRL |= LCD_CTRL_OFUM )
+#define __lcd_disable_ofu_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUM )
+
+#define __lcd_enable_ifu0_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM0 )
+#define __lcd_disable_ifu0_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM0 )
+
+#define __lcd_enable_ifu1_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM1 )
+#define __lcd_disable_ifu1_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM1 )
+
+#define __lcd_enable_ldd_intr() ( REG_LCD_CTRL |= LCD_CTRL_LDDM )
+#define __lcd_disable_ldd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_LDDM )
+
+#define __lcd_enable_qd_intr() ( REG_LCD_CTRL |= LCD_CTRL_QDM )
+#define __lcd_disable_qd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_QDM )
+
+#define __lcd_reverse_byte_endian() ( REG_LCD_CTRL |= LCD_CTRL_BEDN )
+#define __lcd_normal_byte_endian() ( REG_LCD_CTRL &= ~LCD_CTRL_BEDN )
+
+#define __lcd_pixel_endian_little() ( REG_LCD_CTRL |= LCD_CTRL_PEDN )
+#define __lcd_pixel_endian_big() ( REG_LCD_CTRL &= ~LCD_CTRL_PEDN )
+
+#define __lcd_set_dis() ( REG_LCD_CTRL |= LCD_CTRL_DIS )
+#define __lcd_clr_dis() ( REG_LCD_CTRL &= ~LCD_CTRL_DIS )
+
+#define __lcd_set_ena() ( REG_LCD_CTRL |= LCD_CTRL_ENA )
+#define __lcd_clr_ena() ( REG_LCD_CTRL &= ~LCD_CTRL_ENA )
+
+/* n=1,2,4,8,16 */
+#define __lcd_set_bpp(n) \
+ ( REG_LCD_CTRL = (REG_LCD_CTRL & ~LCD_CTRL_BPP_MASK) | LCD_CTRL_BPP_##n )
+
+/* LCD status register indication */
+
+#define __lcd_quick_disable_done() ( REG_LCD_STATE & LCD_STATE_QD )
+#define __lcd_disable_done() ( REG_LCD_STATE & LCD_STATE_LDD )
+#define __lcd_infifo0_underrun() ( REG_LCD_STATE & LCD_STATE_IFU0 )
+#define __lcd_infifo1_underrun() ( REG_LCD_STATE & LCD_STATE_IFU1 )
+#define __lcd_outfifo_underrun() ( REG_LCD_STATE & LCD_STATE_OFU )
+#define __lcd_start_of_frame() ( REG_LCD_STATE & LCD_STATE_SOF )
+#define __lcd_end_of_frame() ( REG_LCD_STATE & LCD_STATE_EOF )
+
+#define __lcd_clr_outfifounderrun() ( REG_LCD_STATE &= ~LCD_STATE_OFU )
+#define __lcd_clr_sof() ( REG_LCD_STATE &= ~LCD_STATE_SOF )
+#define __lcd_clr_eof() ( REG_LCD_STATE &= ~LCD_STATE_EOF )
+
+/* OSD functions */
+#define __lcd_enable_osd() (REG_LCD_OSDC |= LCD_OSDC_OSDEN)
+#define __lcd_enable_f0() (REG_LCD_OSDC |= LCD_OSDC_F0EN)
+#define __lcd_enable_f1() (REG_LCD_OSDC |= LCD_OSDC_F1EN)
+#define __lcd_enable_alpha() (REG_LCD_OSDC |= LCD_OSDC_ALPHAEN)
+#define __lcd_enable_alphamd() (REG_LCD_OSDC |= LCD_OSDC_ALPHAMD)
+
+#define __lcd_disable_osd() (REG_LCD_OSDC &= ~LCD_OSDC_OSDEN)
+#define __lcd_disable_f0() (REG_LCD_OSDC &= ~LCD_OSDC_F0EN)
+#define __lcd_disable_f1() (REG_LCD_OSDC &= ~LCD_OSDC_F1EN)
+#define __lcd_disable_alpha() (REG_LCD_OSDC &= ~LCD_OSDC_ALPHAEN)
+#define __lcd_disable_alphamd() (REG_LCD_OSDC &= ~LCD_OSDC_ALPHAMD)
+
+/* OSD Controll Register */
+#define __lcd_fg1_use_ipu() (REG_LCD_OSDCTRL |= LCD_OSDCTRL_IPU)
+#define __lcd_fg1_use_dma_chan1() (REG_LCD_OSDCTRL &= ~LCD_OSDCTRL_IPU)
+#define __lcd_fg1_unuse_ipu() __lcd_fg1_use_dma_chan1()
+#define __lcd_osd_rgb555_mode() ( REG_LCD_OSDCTRL |= LCD_OSDCTRL_RGB555 )
+#define __lcd_osd_rgb565_mode() ( REG_LCD_OSDCTRL &= ~LCD_OSDCTRL_RGB555 )
+#define __lcd_osd_change_size() ( REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES )
+#define __lcd_osd_bpp_15_16() \
+ ( REG_LCD_OSDCTRL = (REG_LCD_OSDCTRL & ~LCD_OSDCTRL_OSDBPP_MASK) | LCD_OSDCTRL_OSDBPP_15_16 )
+#define __lcd_osd_bpp_18_24() \
+ ( REG_LCD_OSDCTRL = (REG_LCD_OSDCTRL & ~LCD_OSDCTRL_OSDBPP_MASK) | LCD_OSDCTRL_OSDBPP_18_24 )
+
+/* OSD State Register */
+#define __lcd_start_of_fg1() ( REG_LCD_STATE & LCD_OSDS_SOF1 )
+#define __lcd_end_of_fg1() ( REG_LCD_STATE & LCD_OSDS_EOF1 )
+#define __lcd_start_of_fg0() ( REG_LCD_STATE & LCD_OSDS_SOF0 )
+#define __lcd_end_of_fg0() ( REG_LCD_STATE & LCD_OSDS_EOF0 )
+#define __lcd_change_is_rdy() ( REG_LCD_STATE & LCD_OSDS_READY )
+
+/* Foreground Color Key Register 0,1(foreground 0, foreground 1) */
+#define __lcd_enable_colorkey0() (REG_LCD_KEY0 |= LCD_KEY_KEYEN)
+#define __lcd_enable_colorkey1() (REG_LCD_KEY1 |= LCD_KEY_KEYEN)
+#define __lcd_enable_colorkey0_md() (REG_LCD_KEY0 |= LCD_KEY_KEYMD)
+#define __lcd_enable_colorkey1_md() (REG_LCD_KEY1 |= LCD_KEY_KEYMD)
+#define __lcd_set_colorkey0(key) (REG_LCD_KEY0 = (REG_LCD_KEY0&~0xFFFFFF)|(key))
+#define __lcd_set_colorkey1(key) (REG_LCD_KEY1 = (REG_LCD_KEY1&~0xFFFFFF)|(key))
+
+#define __lcd_disable_colorkey0() (REG_LCD_KEY0 &= ~LCD_KEY_KEYEN)
+#define __lcd_disable_colorkey1() (REG_LCD_KEY1 &= ~LCD_KEY_KEYEN)
+#define __lcd_disable_colorkey0_md() (REG_LCD_KEY0 &= ~LCD_KEY_KEYMD)
+#define __lcd_disable_colorkey1_md() (REG_LCD_KEY1 &= ~LCD_KEY_KEYMD)
+
+/* IPU Restart Register */
+#define __lcd_enable_ipu_restart() (REG_LCD_IPUR |= LCD_IPUR_IPUREN)
+#define __lcd_disable_ipu_restart() (REG_LCD_IPUR &= ~LCD_IPUR_IPUREN)
+#define __lcd_set_ipu_restart_triger(n) (REG_LCD_IPUR = (REG_LCD_IPUR&(~0xFFFFFF))|(n))
+
+/* RGB Control Register */
+#define __lcd_enable_rgb_dummy() (REG_LCD_RGBC |= LCD_RGBC_RGBDM)
+#define __lcd_disable_rgb_dummy() (REG_LCD_RGBC &= ~LCD_RGBC_RGBDM)
+
+#define __lcd_dummy_rgb() (REG_LCD_RGBC |= LCD_RGBC_DMM)
+#define __lcd_rgb_dummy() (REG_LCD_RGBC &= ~LCD_RGBC_DMM)
+
+#define __lcd_rgb2ycc() (REG_LCD_RGBC |= LCD_RGBC_YCC)
+#define __lcd_notrgb2ycc() (REG_LCD_RGBC &= ~LCD_RGBC_YCC)
+
+#define __lcd_odd_mode_rgb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_RGB )
+#define __lcd_odd_mode_rbg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_RBG )
+#define __lcd_odd_mode_grb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_GRB)
+
+#define __lcd_odd_mode_gbr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_GBR)
+#define __lcd_odd_mode_brg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_BRG)
+#define __lcd_odd_mode_bgr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_BGR)
+
+#define __lcd_even_mode_rgb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_RGB )
+#define __lcd_even_mode_rbg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_RBG )
+#define __lcd_even_mode_grb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_GRB)
+
+#define __lcd_even_mode_gbr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_GBR)
+#define __lcd_even_mode_brg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_BRG)
+#define __lcd_even_mode_bgr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_BGR)
+
+/* Vertical Synchronize Register */
+#define __lcd_vsync_get_vps() \
+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPS_MASK) >> LCD_VSYNC_VPS_BIT )
+
+#define __lcd_vsync_get_vpe() \
+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPE_MASK) >> LCD_VSYNC_VPE_BIT )
+#define __lcd_vsync_set_vpe(n) \
+do { \
+ REG_LCD_VSYNC &= ~LCD_VSYNC_VPE_MASK; \
+ REG_LCD_VSYNC |= (n) << LCD_VSYNC_VPE_BIT; \
+} while (0)
+
+#define __lcd_hsync_get_hps() \
+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPS_MASK) >> LCD_HSYNC_HPS_BIT )
+#define __lcd_hsync_set_hps(n) \
+do { \
+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPS_MASK; \
+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPS_BIT; \
+} while (0)
+
+#define __lcd_hsync_get_hpe() \
+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPE_MASK) >> LCD_VSYNC_HPE_BIT )
+#define __lcd_hsync_set_hpe(n) \
+do { \
+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPE_MASK; \
+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPE_BIT; \
+} while (0)
+
+#define __lcd_vat_get_ht() \
+ ( (REG_LCD_VAT & LCD_VAT_HT_MASK) >> LCD_VAT_HT_BIT )
+#define __lcd_vat_set_ht(n) \
+do { \
+ REG_LCD_VAT &= ~LCD_VAT_HT_MASK; \
+ REG_LCD_VAT |= (n) << LCD_VAT_HT_BIT; \
+} while (0)
+
+#define __lcd_vat_get_vt() \
+ ( (REG_LCD_VAT & LCD_VAT_VT_MASK) >> LCD_VAT_VT_BIT )
+#define __lcd_vat_set_vt(n) \
+do { \
+ REG_LCD_VAT &= ~LCD_VAT_VT_MASK; \
+ REG_LCD_VAT |= (n) << LCD_VAT_VT_BIT; \
+} while (0)
+
+#define __lcd_dah_get_hds() \
+ ( (REG_LCD_DAH & LCD_DAH_HDS_MASK) >> LCD_DAH_HDS_BIT )
+#define __lcd_dah_set_hds(n) \
+do { \
+ REG_LCD_DAH &= ~LCD_DAH_HDS_MASK; \
+ REG_LCD_DAH |= (n) << LCD_DAH_HDS_BIT; \
+} while (0)
+
+#define __lcd_dah_get_hde() \
+ ( (REG_LCD_DAH & LCD_DAH_HDE_MASK) >> LCD_DAH_HDE_BIT )
+#define __lcd_dah_set_hde(n) \
+do { \
+ REG_LCD_DAH &= ~LCD_DAH_HDE_MASK; \
+ REG_LCD_DAH |= (n) << LCD_DAH_HDE_BIT; \
+} while (0)
+
+#define __lcd_dav_get_vds() \
+ ( (REG_LCD_DAV & LCD_DAV_VDS_MASK) >> LCD_DAV_VDS_BIT )
+#define __lcd_dav_set_vds(n) \
+do { \
+ REG_LCD_DAV &= ~LCD_DAV_VDS_MASK; \
+ REG_LCD_DAV |= (n) << LCD_DAV_VDS_BIT; \
+} while (0)
+
+#define __lcd_dav_get_vde() \
+ ( (REG_LCD_DAV & LCD_DAV_VDE_MASK) >> LCD_DAV_VDE_BIT )
+#define __lcd_dav_set_vde(n) \
+do { \
+ REG_LCD_DAV &= ~LCD_DAV_VDE_MASK; \
+ REG_LCD_DAV |= (n) << LCD_DAV_VDE_BIT; \
+} while (0)
+
+/* DMA Command Register */
+#define __lcd_cmd0_set_sofint() ( REG_LCD_CMD0 |= LCD_CMD_SOFINT )
+#define __lcd_cmd0_clr_sofint() ( REG_LCD_CMD0 &= ~LCD_CMD_SOFINT )
+#define __lcd_cmd1_set_sofint() ( REG_LCD_CMD1 |= LCD_CMD_SOFINT )
+#define __lcd_cmd1_clr_sofint() ( REG_LCD_CMD1 &= ~LCD_CMD_SOFINT )
+
+#define __lcd_cmd0_set_eofint() ( REG_LCD_CMD0 |= LCD_CMD_EOFINT )
+#define __lcd_cmd0_clr_eofint() ( REG_LCD_CMD0 &= ~LCD_CMD_EOFINT )
+#define __lcd_cmd1_set_eofint() ( REG_LCD_CMD1 |= LCD_CMD_EOFINT )
+#define __lcd_cmd1_clr_eofint() ( REG_LCD_CMD1 &= ~LCD_CMD_EOFINT )
+
+#define __lcd_cmd0_set_pal() ( REG_LCD_CMD0 |= LCD_CMD_PAL )
+#define __lcd_cmd0_clr_pal() ( REG_LCD_CMD0 &= ~LCD_CMD_PAL )
+
+#define __lcd_cmd0_get_len() \
+ ( (REG_LCD_CMD0 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT )
+#define __lcd_cmd1_get_len() \
+ ( (REG_LCD_CMD1 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760LCDC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760mc.h b/arch/mips/include/asm/mach-jz4760/jz4760mc.h
new file mode 100644
index 00000000000..ed0c6c3bbc1
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760mc.h
@@ -0,0 +1,128 @@
+/*
+ * jz4760mc.h
+ * JZ4760 MC register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760MC_H__
+#define __JZ4760MC_H__
+
+
+/*
+ * Motion compensation module(MC) address definition
+ */
+#define MC_BASE 0xb3250000
+
+
+/*
+ * MC registers offset address definition
+ */
+#define MC_MCCR_OFFSET (0x00) /* rw, 32, 0x???????? */
+#define MC_MCSR_OFFSET (0x04) /* rw, 32, 0x???????? */
+#define MC_MCRBAR_OFFSET (0x08) /* rw, 32, 0x???????? */
+#define MC_MCT1LFCR_OFFSET (0x0c) /* rw, 32, 0x???????? */
+#define MC_MCT2LFCR_OFFSET (0x10) /* rw, 32, 0x???????? */
+#define MC_MCCBAR_OFFSET (0x14) /* rw, 32, 0x???????? */
+#define MC_MCIIR_OFFSET (0x18) /* rw, 32, 0x???????? */
+#define MC_MCSIR_OFFSET (0x1c) /* rw, 32, 0x???????? */
+#define MC_MCT1MFCR_OFFSET (0x20) /* rw, 32, 0x???????? */
+#define MC_MCT2MFCR_OFFSET (0x24) /* rw, 32, 0x???????? */
+#define MC_MCFGIR_OFFSET (0x28) /* rw, 32, 0x???????? */
+#define MC_MCFCIR_OFFSET (0x2c) /* rw, 32, 0x???????? */
+#define MC_MCRNDTR_OFFSET (0x40) /* rw, 32, 0x???????? */
+
+#define MC_MC2CR_OFFSET (0x8000) /* rw, 32, 0x???????? */
+#define MC_MC2SR_OFFSET (0x8004) /* rw, 32, 0x???????? */
+#define MC_MC2RBAR_OFFSET (0x8008) /* rw, 32, 0x???????? */
+#define MC_MC2CBAR_OFFSET (0x800c) /* rw, 32, 0x???????? */
+#define MC_MC2IIR_OFFSET (0x8010) /* rw, 32, 0x???????? */
+#define MC_MC2TFCR_OFFSET (0x8014) /* rw, 32, 0x???????? */
+#define MC_MC2SIR_OFFSET (0x8018) /* rw, 32, 0x???????? */
+#define MC_MC2FCIR_OFFSET (0x801c) /* rw, 32, 0x???????? */
+#define MC_MC2RNDTR_OFFSET (0x8040) /* rw, 32, 0x???????? */
+
+
+/*
+ * MC registers address definition
+ */
+#define MC_MCCR (MC_BASE + MC_MCCR_OFFSET)
+#define MC_MCSR (MC_BASE + MC_MCSR_OFFSET)
+#define MC_MCRBAR (MC_BASE + MC_MCRBAR_OFFSET)
+#define MC_MCT1LFCR (MC_BASE + MC_MCT1LFCR_OFFSET)
+#define MC_MCT2LFCR (MC_BASE + MC_MCT2LFCR_OFFSET)
+#define MC_MCCBAR (MC_BASE + MC_MCCBAR_OFFSET)
+#define MC_MCIIR (MC_BASE + MC_MCIIR_OFFSET)
+#define MC_MCSIR (MC_BASE + MC_MCSIR_OFFSET)
+#define MC_MCT1MFCR (MC_BASE + MC_MCT1MFCR_OFFSET)
+#define MC_MCT2MFCR (MC_BASE + MC_MCT2MFCR_OFFSET)
+#define MC_MCFGIR (MC_BASE + MC_MCFGIR_OFFSET)
+#define MC_MCFCIR (MC_BASE + MC_MCFCIR_OFFSET)
+#define MC_MCRNDTR (MC_BASE + MC_MCRNDTR_OFFSET)
+
+#define MC_MC2CR (MC_BASE + MC_MC2CR_OFFSET)
+#define MC_MC2SR (MC_BASE + MC_MC2SR_OFFSET)
+#define MC_MC2RBAR (MC_BASE + MC_MC2RBAR_OFFSET)
+#define MC_MC2CBAR (MC_BASE + MC_MC2CBAR_OFFSET)
+#define MC_MC2IIR (MC_BASE + MC_MC2IIR_OFFSET)
+#define MC_MC2TFCR (MC_BASE + MC_MC2TFCR_OFFSET)
+#define MC_MC2SIR (MC_BASE + MC_MC2SIR_OFFSET)
+#define MC_MC2FCIR (MC_BASE + MC_MC2FCIR_OFFSET)
+#define MC_MC2RNDTR (MC_BASE + MC_MC2RNDTR_OFFSET)
+
+
+/*
+ * MC registers common define
+ */
+
+/* MC Control Register(MCCR) */
+#define MCCR_RETE BIT16
+#define MCCR_DIPE BIT7
+#define MCCR_CKGEN BIT6
+#define MCCR_FDDEN BIT5
+#define MCCR_DINSE BIT3
+#define MCCR_FAE BIT2
+#define MCCR_RST BIT1
+#define MCCR_CHEN BIT0
+
+#define MCCR_FDDPGN_LSB 8
+#define MCCR_FDDPGN_MASK BITS_H2L(15, MCCR_FDDPGN_LSB)
+
+/* MC Status Register(MCSR) */
+#define MCSR_DLEND BIT1
+#define MCSR_BKLEND BIT0
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+#define REG_MC_MCCR REG32(REG_MC_MCCR)
+#define REG_MC_MCSR REG32(REG_MC_MCSR)
+#define REG_MC_MCRBAR REG32(REG_MC_MCRBAR)
+#define REG_MC_MCT1LFCR REG32(REG_MC_MCT1LFCR)
+#define REG_MC_MCT2LFCR REG32(REG_MC_MCT2LFCR)
+#define REG_MC_MCCBAR REG32(REG_MC_MCCBAR)
+#define REG_MC_MCIIR REG32(REG_MC_MCIIR)
+#define REG_MC_MCSIR REG32(REG_MC_MCSIR)
+#define REG_MC_MCT1MFCR REG32(REG_MC_MCT1MFCR)
+#define REG_MC_MCT2MFCR REG32(REG_MC_MCT2MFCR)
+#define REG_MC_MCFGIR REG32(REG_MC_MCFGIR)
+#define REG_MC_MCFCIR REG32(REG_MC_MCFCIR)
+#define REG_MC_MCRNDTR REG32(REG_MC_MCRNDTR)
+
+#define REG_MC_MC2CR REG32(REG_MC_MC2CR)
+#define REG_MC_MC2SR REG32(REG_MC_MC2SR)
+#define REG_MC_MC2RBAR REG32(REG_MC_MC2RBAR)
+#define REG_MC_MC2CBAR REG32(REG_MC_MC2CBAR)
+#define REG_MC_MC2IIR REG32(REG_MC_MC2IIR)
+#define REG_MC_MC2TFCR REG32(REG_MC_MC2TFCR)
+#define REG_MC_MC2SIR REG32(REG_MC_MC2SIR)
+#define REG_MC_MC2FCIR REG32(REG_MC_MC2FCIR)
+#define REG_MC_MC2RNDTR REG32(REG_MC_MC2RNDTR)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760MC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760mdma.h b/arch/mips/include/asm/mach-jz4760/jz4760mdma.h
new file mode 100644
index 00000000000..956142a40a6
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760mdma.h
@@ -0,0 +1,209 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760mdma.h
+ *
+ * JZ4760 MDMA register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760MDMA_H__
+#define __JZ4760MDMA_H__
+
+
+#define MDMAC_BASE 0xB3030000 /* Memory Copy DMAC */
+
+/*************************************************************************
+ * MDMAC (MEM Copy DMA Controller)
+ *************************************************************************/
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define MDMAC_DSAR(n) (MDMAC_BASE + (0x00 + (n) * 0x20)) /* DMA source address */
+#define MDMAC_DTAR(n) (MDMAC_BASE + (0x04 + (n) * 0x20)) /* DMA target address */
+#define MDMAC_DTCR(n) (MDMAC_BASE + (0x08 + (n) * 0x20)) /* DMA transfer count */
+#define MDMAC_DRSR(n) (MDMAC_BASE + (0x0c + (n) * 0x20)) /* DMA request source */
+#define MDMAC_DCCSR(n) (MDMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */
+#define MDMAC_DCMD(n) (MDMAC_BASE + (0x14 + (n) * 0x20)) /* DMA command */
+#define MDMAC_DDA(n) (MDMAC_BASE + (0x18 + (n) * 0x20)) /* DMA descriptor address */
+#define MDMAC_DSD(n) (MDMAC_BASE + (0xc0 + (n) * 0x04)) /* DMA Stride Address */
+
+#define MDMAC_DMACR (MDMAC_BASE + 0x0300) /* DMA control register */
+#define MDMAC_DMAIPR (MDMAC_BASE + 0x0304) /* DMA interrupt pending */
+#define MDMAC_DMADBR (MDMAC_BASE + 0x0308) /* DMA doorbell */
+#define MDMAC_DMADBSR (MDMAC_BASE + 0x030C) /* DMA doorbell set */
+#define MDMAC_DMACKE (MDMAC_BASE + 0x0310)
+
+#define REG_MDMAC_DSAR(n) REG32(MDMAC_DSAR((n)))
+#define REG_MDMAC_DTAR(n) REG32(MDMAC_DTAR((n)))
+#define REG_MDMAC_DTCR(n) REG32(MDMAC_DTCR((n)))
+#define REG_MDMAC_DRSR(n) REG32(MDMAC_DRSR((n)))
+#define REG_MDMAC_DCCSR(n) REG32(MDMAC_DCCSR((n)))
+#define REG_MDMAC_DCMD(n) REG32(MDMAC_DCMD((n)))
+#define REG_MDMAC_DDA(n) REG32(MDMAC_DDA((n)))
+#define REG_MDMAC_DSD(n) REG32(MDMAC_DSD(n))
+#define REG_MDMAC_DMACR REG32(MDMAC_DMACR)
+#define REG_MDMAC_DMAIPR REG32(MDMAC_DMAIPR)
+#define REG_MDMAC_DMADBR REG32(MDMAC_DMADBR)
+#define REG_MDMAC_DMADBSR REG32(MDMAC_DMADBSR)
+#define REG_MDMAC_DMACKE REG32(MDMAC_DMACKE)
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * Mem Copy DMAC
+ ***************************************************************************/
+
+/* n is the DMA channel index (0 - 11) */
+
+#define __mdmac_enable_module \
+ ( REG_MDMAC_DMACR |= DMAC_MDMACR_DMAE | DMAC_MDMACR_PR_012345 )
+#define __mdmac_disable_module \
+ ( REG_MDMAC_DMACR &= ~DMAC_MDMACR_DMAE )
+
+/* p=0,1,2,3 */
+#define __mdmac_set_priority(p) \
+do { \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_PR_MASK; \
+ REG_MDMAC_DMACR |= ((p) << DMAC_DMACR_PR_BIT); \
+} while (0)
+
+#define __mdmac_test_halt_error ( REG_MDMAC_DMACR & DMAC_MDMACR_HLT )
+#define __mdmac_test_addr_error ( REG_MDMAC_DMACR & DMAC_MDMACR_AR )
+
+#define __mdmac_channel_enable_clk \
+ REG_MDMAC_DMACKE |= 1 << (n);
+
+#define __mdmac_enable_descriptor(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES )
+#define __mdmac_disable_descriptor(n) \
+ ( REG_MDMAC_DCCSR((n)) |= DMAC_DCCSR_NDES )
+
+#define __mdmac_enable_channel(n) \
+do { \
+ REG_MDMAC_DCCSR((n)) |= DMAC_DCCSR_EN; \
+} while (0)
+#define __mdmac_disable_channel(n) \
+do { \
+ REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN; \
+} while (0)
+#define __mdmac_channel_enabled(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_EN )
+
+#define __mdmac_channel_enable_irq(n) \
+ ( REG_MDMAC_DCMD((n)) |= DMAC_DCMD_TIE )
+#define __mdmac_channel_disable_irq(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE )
+
+#define __mdmac_channel_transmit_halt_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_HLT )
+#define __mdmac_channel_transmit_end_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_TT )
+#define __mdmac_channel_address_error_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_AR )
+#define __mdmac_channel_count_terminated_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_CT )
+#define __mdmac_channel_descriptor_invalid_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_INV )
+
+#define __mdmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT; \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_HLT; \
+ } while (0)
+#define __mdmac_channel_clear_transmit_end(n) \
+ ( REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_TT )
+#define __mdmac_channel_clear_address_error(n) \
+ do { \
+ REG_MDMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_MDMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_MDMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_AR; \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_AR; \
+ } while (0)
+#define __mdmac_channel_clear_count_terminated(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT )
+#define __mdmac_channel_clear_descriptor_invalid(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV )
+
+#define __mdmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __mdmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __mdmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; \
+} while (0)
+
+/* v=0-15 */
+#define __mdmac_channel_set_rdil(n,v) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK; \
+ REG_MDMAC_DCMD((n) |= ((v) << DMAC_DCMD_RDIL_BIT); \
+} while (0)
+
+#define __mdmac_channel_dest_addr_fixed(n) \
+ (REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DAI)
+#define __mdmac_channel_dest_addr_increment(n) \
+ (REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DAI)
+
+#define __mdmac_channel_src_addr_fixed(n) \
+ (REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_SAI)
+#define __mdmac_channel_src_addr_increment(n) \
+ (REG_MDMAC_DCMD((n)) |= DMAC_DCMD_SAI)
+
+#define __mdmac_channel_set_doorbell(n) \
+ (REG_MDMAC_DMADBSR = (1 << (n)))
+
+#define __mdmac_channel_irq_detected(n) (REG_MDMAC_DMAIPR & (1 << (n)))
+#define __mdmac_channel_ack_irq(n) (REG_MDMAC_DMAIPR &= ~(1 <<(n)))
+
+static __inline__ int __mdmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_MDMA_NUM; i++)
+ if (__mdmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760MDMA_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760me.h b/arch/mips/include/asm/mach-jz4760/jz4760me.h
new file mode 100644
index 00000000000..b0e4e1b0cfb
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760me.h
@@ -0,0 +1,93 @@
+/*
+ * jz4760me.h
+ * JZ4760 ME register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760ME_H__
+#define __JZ4760ME_H__
+
+
+/*
+ * Motion estimation module(ME) address definition
+ */
+#define ME_BASE 0xb3260000
+
+
+/*
+ * ME registers offset address definition
+ */
+#define ME_MECR_OFFSET (0x00) /* rw, 32, 0x???????0 */
+#define ME_MERBAR_OFFSET (0x04) /* rw, 32, 0x???????? */
+#define ME_MECBAR_OFFSET (0x08) /* rw, 32, 0x???????? */
+#define ME_MEDAR_OFFSET (0x0c) /* rw, 32, 0x???????? */
+#define ME_MERFSR_OFFSET (0x10) /* rw, 32, 0x???????? */
+#define ME_MECFSR_OFFSET (0x14) /* rw, 32, 0x???????? */
+#define ME_MEDFSR_OFFSET (0x18) /* rw, 32, 0x???????? */
+#define ME_MESR_OFFSET (0x1c) /* rw, 32, 0x???????? */
+#define ME_MEMR_OFFSET (0x20) /* rw, 32, 0x???????? */
+#define ME_MEFR_OFFSET (0x24) /* rw, 32, 0x???????? */
+
+
+/*
+ * ME registers address definition
+ */
+#define ME_MECR (ME_BASE + ME_MECR_OFFSET)
+#define ME_MERBAR (ME_BASE + ME_MERBAR_OFFSET)
+#define ME_MECBAR (ME_BASE + ME_MECBAR_OFFSET)
+#define ME_MEDAR (ME_BASE + ME_MEDAR_OFFSET)
+#define ME_MERFSR (ME_BASE + ME_MERFSR_OFFSET)
+#define ME_MECFSR (ME_BASE + ME_MECFSR_OFFSET)
+#define ME_MEDFSR (ME_BASE + ME_MEDFSR_OFFSET)
+#define ME_MESR (ME_BASE + ME_MESR_OFFSET)
+#define ME_MEMR (ME_BASE + ME_MEMR_OFFSET)
+#define ME_MEFR (ME_BASE + ME_MEFR_OFFSET)
+
+
+/*
+ * ME registers common define
+ */
+
+/* ME control register(MECR) */
+#define MECR_FLUSH BIT2
+#define MECR_RESET BIT1
+#define MECR_ENABLE BIT0
+
+/* ME settings register(MESR) */
+#define MESR_GATE_LSB 16
+#define MESR_GATE_MASK BITS_H2L(31, MESR_GATE_LSB)
+
+#define MESR_NUM_LSB 0
+#define MESR_NUM_MASK BITS_H2L(5, MESR_NUM_LSB)
+
+/* ME MVD register(MEMR) */
+#define MEMR_MVDY_LSB 16
+#define MESR_MVDY_MASK BITS_H2L(31, MEMR_MVDY_LSB)
+
+#define MEMR_MVDX_LSB 0
+#define MESR_MVDX_MASK BITS_H2L(15, MEMR_MVDX_LSB)
+
+/* ME flag register(MEFR) */
+#define MEFR_INTRA BIT1
+#define MEFR_COMPLETED BIT0
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_ME_MECR REG32(ME_MECR)
+#define REG_ME_MERBAR REG32(ME_MERBAR)
+#define REG_ME_MECBAR REG32(ME_MECBAR)
+#define REG_ME_MEDAR REG32(ME_MEDAR)
+#define REG_ME_MERFSR REG32(ME_MERFSR)
+#define REG_ME_MECFSR REG32(ME_MECFSR)
+#define REG_ME_MEDFSR REG32(ME_MEDFSR)
+#define REG_ME_MESR REG32(ME_MESR)
+#define REG_ME_MEMR REG32(ME_MEMR)
+#define REG_ME_MEFR REG32(ME_MEFR)
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760ME_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760misc.h b/arch/mips/include/asm/mach-jz4760/jz4760misc.h
new file mode 100644
index 00000000000..e744ea0fd7c
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760misc.h
@@ -0,0 +1,91 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760misc.h
+ *
+ * JZ4760 misc definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760MISC_H__
+#define __JZ4760MISC_H__
+
+
+#if defined(__ASSEMBLY__) || defined(__LANGUAGE_ASSEMBLY)
+ #ifndef __MIPS_ASSEMBLER
+ #define __MIPS_ASSEMBLER
+ #endif
+ #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))
+
+ #define INREG8(x) ((unsigned char)(*(volatile unsigned char *)(x)))
+ #define OUTREG8(x, y) *(volatile unsigned char *)(x) = (y)
+ #define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y))
+ #define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y))
+ #define CMSREG8(x, y, m) OUTREG8(x, (INREG8(x)&~(m))|(y))
+
+ #define INREG16(x) ((unsigned short)(*(volatile unsigned short *)(x)))
+ #define OUTREG16(x, y) *(volatile unsigned short *)(x) = (y)
+ #define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y))
+ #define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y))
+ #define CMSREG16(x, y, m) OUTREG16(x, (INREG16(x)&~(m))|(y))
+
+ #define INREG32(x) ((unsigned int)(*(volatile unsigned int *)(x)))
+ #define OUTREG32(x, y) *(volatile unsigned int *)(x) = (y)
+ #define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y))
+ #define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y))
+ #define CMSREG32(x, y, m) OUTREG32(x, (INREG32(x)&~(m))|(y))
+
+#endif
+
+
+/*
+ * Define the bit field macro to avoid the bit mistake
+ */
+#define BIT0 (1 << 0)
+#define BIT1 (1 << 1)
+#define BIT2 (1 << 2)
+#define BIT3 (1 << 3)
+#define BIT4 (1 << 4)
+#define BIT5 (1 << 5)
+#define BIT6 (1 << 6)
+#define BIT7 (1 << 7)
+#define BIT8 (1 << 8)
+#define BIT9 (1 << 9)
+#define BIT10 (1 << 10)
+#define BIT11 (1 << 11)
+#define BIT12 (1 << 12)
+#define BIT13 (1 << 13)
+#define BIT14 (1 << 14)
+#define BIT15 (1 << 15)
+#define BIT16 (1 << 16)
+#define BIT17 (1 << 17)
+#define BIT18 (1 << 18)
+#define BIT19 (1 << 19)
+#define BIT20 (1 << 20)
+#define BIT21 (1 << 21)
+#define BIT22 (1 << 22)
+#define BIT23 (1 << 23)
+#define BIT24 (1 << 24)
+#define BIT25 (1 << 25)
+#define BIT26 (1 << 26)
+#define BIT27 (1 << 27)
+#define BIT28 (1 << 28)
+#define BIT29 (1 << 29)
+#define BIT30 (1 << 30)
+#define BIT31 (1 << 31)
+
+
+/* Generate the bit field mask from msb to lsb */
+#define BITS_H2L(msb, lsb) ((0xFFFFFFFF >> (32-((msb)-(lsb)+1))) << (lsb))
+
+
+/* Get the bit field value from the data which is read from the register */
+#define get_bf_value(data, lsb, mask) (((data) & (mask)) >> (lsb))
+
+
+#endif /* __JZ4760MISC_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760msc.h b/arch/mips/include/asm/mach-jz4760/jz4760msc.h
new file mode 100644
index 00000000000..176ecaf3af9
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760msc.h
@@ -0,0 +1,325 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760msc.h
+ *
+ * JZ4760 MSC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760MSC_H__
+#define __JZ4760MSC_H__
+
+
+#define MSC0_BASE 0xB0021000
+#define MSC1_BASE 0xB0022000
+#define MSC2_BASE 0xB0023000
+
+
+/*************************************************************************
+ * MSC
+ ************************************************************************/
+/* n = 0, 1 (MSC0, MSC1) */
+#define MSC_STRPCL(n) (MSC0_BASE + (n)*0x1000 + 0x000)
+#define MSC_STAT(n) (MSC0_BASE + (n)*0x1000 + 0x004)
+#define MSC_CLKRT(n) (MSC0_BASE + (n)*0x1000 + 0x008)
+#define MSC_CMDAT(n) (MSC0_BASE + (n)*0x1000 + 0x00C)
+#define MSC_RESTO(n) (MSC0_BASE + (n)*0x1000 + 0x010)
+#define MSC_RDTO(n) (MSC0_BASE + (n)*0x1000 + 0x014)
+#define MSC_BLKLEN(n) (MSC0_BASE + (n)*0x1000 + 0x018)
+#define MSC_NOB(n) (MSC0_BASE + (n)*0x1000 + 0x01C)
+#define MSC_SNOB(n) (MSC0_BASE + (n)*0x1000 + 0x020)
+#define MSC_IMASK(n) (MSC0_BASE + (n)*0x1000 + 0x024)
+#define MSC_IREG(n) (MSC0_BASE + (n)*0x1000 + 0x028)
+#define MSC_CMD(n) (MSC0_BASE + (n)*0x1000 + 0x02C)
+#define MSC_ARG(n) (MSC0_BASE + (n)*0x1000 + 0x030)
+#define MSC_RES(n) (MSC0_BASE + (n)*0x1000 + 0x034)
+#define MSC_RXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x038)
+#define MSC_TXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x03C)
+#define MSC_LPM(n) (MSC0_BASE + (n)*0x1000 + 0x040)
+
+#define REG_MSC_STRPCL(n) REG16(MSC_STRPCL(n))
+#define REG_MSC_STAT(n) REG32(MSC_STAT(n))
+#define REG_MSC_CLKRT(n) REG16(MSC_CLKRT(n))
+#define REG_MSC_CMDAT(n) REG32(MSC_CMDAT(n))
+#define REG_MSC_RESTO(n) REG16(MSC_RESTO(n))
+#define REG_MSC_RDTO(n) REG16(MSC_RDTO(n))
+#define REG_MSC_BLKLEN(n) REG16(MSC_BLKLEN(n))
+#define REG_MSC_NOB(n) REG16(MSC_NOB(n))
+#define REG_MSC_SNOB(n) REG16(MSC_SNOB(n))
+#define REG_MSC_IMASK(n) REG32(MSC_IMASK(n))
+#define REG_MSC_IREG(n) REG16(MSC_IREG(n))
+#define REG_MSC_CMD(n) REG8(MSC_CMD(n))
+#define REG_MSC_ARG(n) REG32(MSC_ARG(n))
+#define REG_MSC_RES(n) REG16(MSC_RES(n))
+#define REG_MSC_RXFIFO(n) REG32(MSC_RXFIFO(n))
+#define REG_MSC_TXFIFO(n) REG32(MSC_TXFIFO(n))
+#define REG_MSC_LPM(n) REG32(MSC_LPM(n))
+
+/* MSC Clock and Control Register (MSC_STRPCL) */
+#define MSC_STRPCL_SEND_CCSD (1 << 15) /*send command completion signal disable to ceata */
+#define MSC_STRPCL_SEND_AS_CCSD (1 << 14) /*send internally generated stop after sending ccsd */
+#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
+#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
+#define MSC_STRPCL_START_READWAIT (1 << 5)
+#define MSC_STRPCL_STOP_READWAIT (1 << 4)
+#define MSC_STRPCL_RESET (1 << 3)
+#define MSC_STRPCL_START_OP (1 << 2)
+#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
+#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
+ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
+ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
+
+/* MSC Status Register (MSC_STAT) */
+#define MSC_STAT_AUTO_CMD_DONE (1 << 31) /*12 is internally generated by controller has finished */
+#define MSC_STAT_IS_RESETTING (1 << 15)
+#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
+#define MSC_STAT_PRG_DONE (1 << 13)
+#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
+#define MSC_STAT_END_CMD_RES (1 << 11)
+#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
+#define MSC_STAT_IS_READWAIT (1 << 9)
+#define MSC_STAT_CLK_EN (1 << 8)
+#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
+#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
+#define MSC_STAT_CRC_RES_ERR (1 << 5)
+#define MSC_STAT_CRC_READ_ERROR (1 << 4)
+#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
+#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
+ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
+ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
+#define MSC_STAT_TIME_OUT_RES (1 << 1)
+#define MSC_STAT_TIME_OUT_READ (1 << 0)
+
+/* MSC Bus Clock Control Register (MSC_CLKRT) */
+#define MSC_CLKRT_CLK_RATE_BIT 0
+#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
+ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
+
+/* MSC Command Sequence Control Register (MSC_CMDAT) */
+#define MSC_CMDAT_CCS_EXPECTED (1 << 31) /* interrupts are enabled in ce-ata */
+#define MSC_CMDAT_READ_CEATA (1 << 30)
+#define MSC_CMDAT_SDIO_PRDT (1 << 17) /* exact 2 cycle */
+#define MSC_CMDAT_SEND_AS_STOP (1 << 16)
+#define MSC_CMDAT_RTRG_BIT 14
+ #define MSC_CMDAT_RTRG_EQUALT_8 (0x0 << MSC_CMDAT_RTRG_BIT)
+ #define MSC_CMDAT_RTRG_EQUALT_16 (0x1 << MSC_CMDAT_RTRG_BIT) /* reset value */
+ #define MSC_CMDAT_RTRG_EQUALT_24 (0x2 << MSC_CMDAT_RTRG_BIT)
+
+#define MSC_CMDAT_TTRG_BIT 12
+ #define MSC_CMDAT_TTRG_LESS_8 (0x0 << MSC_CMDAT_TTRG_BIT)
+ #define MSC_CMDAT_TTRG_LESS_16 (0x1 << MSC_CMDAT_TTRG_BIT) /*reset value */
+ #define MSC_CMDAT_TTRG_LESS_24 (0x2 << MSC_CMDAT_TTRG_BIT)
+#define MSC_CMDAT_STOP_ABORT (1 << 11)
+#define MSC_CMDAT_BUS_WIDTH_BIT 9
+#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
+ #define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) /* 1-bit data bus */
+ #define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) /* 4-bit data bus */
+ #define MSC_CMDAT_BUS_WIDTH_8BIT (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) /* 8-bit data bus */
+#define MSC_CMDAT_DMA_EN (1 << 8)
+#define MSC_CMDAT_INIT (1 << 7)
+#define MSC_CMDAT_BUSY (1 << 6)
+#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
+#define MSC_CMDAT_WRITE (1 << 4)
+#define MSC_CMDAT_READ (0 << 4)
+#define MSC_CMDAT_DATA_EN (1 << 3)
+#define MSC_CMDAT_RESPONSE_BIT 0
+#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
+ #define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) /* No response */
+ #define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) /* Format R1 and R1b */
+ #define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) /* Format R2 */
+ #define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) /* Format R3 */
+ #define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) /* Format R4 */
+ #define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) /* Format R5 */
+ #define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) /* Format R6 */
+
+#define CMDAT_DMA_EN (1 << 8)
+#define CMDAT_INIT (1 << 7)
+#define CMDAT_BUSY (1 << 6)
+#define CMDAT_STREAM (1 << 5)
+#define CMDAT_WRITE (1 << 4)
+#define CMDAT_DATA_EN (1 << 3)
+
+/* MSC Interrupts Mask Register (MSC_IMASK) */
+#define MSC_IMASK_AUTO_CMD_DONE (1 << 8)
+#define MSC_IMASK_SDIO (1 << 7)
+#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
+#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
+#define MSC_IMASK_END_CMD_RES (1 << 2)
+#define MSC_IMASK_PRG_DONE (1 << 1)
+#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)
+
+/* MSC Interrupts Status Register (MSC_IREG) */
+#define MSC_IREG_AUTO_CMD_DONE (1 << 8)
+#define MSC_IREG_SDIO (1 << 7)
+#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
+#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
+#define MSC_IREG_END_CMD_RES (1 << 2)
+#define MSC_IREG_PRG_DONE (1 << 1)
+#define MSC_IREG_DATA_TRAN_DONE (1 << 0)
+
+/* MSC Low Power Mode Register (MSC_LPM) */
+#define MSC_SET_LPM (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * MSC
+ ***************************************************************************/
+/* n = 0, 1 (MSC0, MSC1) */
+
+#define __msc_start_op(n) \
+ ( REG_MSC_STRPCL(n) = MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START )
+
+#define __msc_set_resto(n, to) ( REG_MSC_RESTO(n) = to )
+#define __msc_set_rdto(n, to) ( REG_MSC_RDTO(n) = to )
+#define __msc_set_cmd(n, cmd) ( REG_MSC_CMD(n) = cmd )
+#define __msc_set_arg(n, arg) ( REG_MSC_ARG(n) = arg )
+#define __msc_set_nob(n, nob) ( REG_MSC_NOB(n) = nob )
+#define __msc_get_nob(n) ( REG_MSC_NOB(n) )
+#define __msc_set_blklen(n, len) ( REG_MSC_BLKLEN(n) = len )
+#define __msc_set_cmdat(n, cmdat) ( REG_MSC_CMDAT(n) = cmdat )
+#define __msc_set_cmdat_ioabort(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_IO_ABORT )
+#define __msc_clear_cmdat_ioabort(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_IO_ABORT )
+
+#define __msc_set_cmdat_bus_width1(n) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_BUS_WIDTH_MASK; \
+ REG_MSC_CMDAT(n) |= MSC_CMDAT_BUS_WIDTH_1BIT; \
+} while(0)
+
+#define __msc_set_cmdat_bus_width4(n) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_BUS_WIDTH_MASK; \
+ REG_MSC_CMDAT(n) |= MSC_CMDAT_BUS_WIDTH_4BIT; \
+} while(0)
+
+#define __msc_set_cmdat_dma_en(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_DMA_EN )
+#define __msc_set_cmdat_init(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_INIT )
+#define __msc_set_cmdat_busy(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_BUSY )
+#define __msc_set_cmdat_stream(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_STREAM_BLOCK )
+#define __msc_set_cmdat_block(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_STREAM_BLOCK )
+#define __msc_set_cmdat_read(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_WRITE_READ )
+#define __msc_set_cmdat_write(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_WRITE_READ )
+#define __msc_set_cmdat_data_en(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_DATA_EN )
+
+/* r is MSC_CMDAT_RESPONSE_FORMAT_Rx or MSC_CMDAT_RESPONSE_FORMAT_NONE */
+#define __msc_set_cmdat_res_format(n, r) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_RESPONSE_FORMAT_MASK; \
+ REG_MSC_CMDAT(n) |= (r); \
+} while(0)
+
+#define __msc_clear_cmdat(n) \
+ REG_MSC_CMDAT(n) &= ~( MSC_CMDAT_IO_ABORT | MSC_CMDAT_DMA_EN | MSC_CMDAT_INIT| \
+ MSC_CMDAT_BUSY | MSC_CMDAT_STREAM_BLOCK | MSC_CMDAT_WRITE_READ | \
+ MSC_CMDAT_DATA_EN | MSC_CMDAT_RESPONSE_FORMAT_MASK )
+
+#define __msc_get_imask(n) ( REG_MSC_IMASK(n) )
+#define __msc_mask_all_intrs(n) ( REG_MSC_IMASK(n) = 0xff )
+#define __msc_unmask_all_intrs(n) ( REG_MSC_IMASK(n) = 0x00 )
+#define __msc_mask_rd(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_RXFIFO_RD_REQ )
+#define __msc_unmask_rd(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_RXFIFO_RD_REQ )
+#define __msc_mask_wr(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_TXFIFO_WR_REQ )
+#define __msc_unmask_wr(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_TXFIFO_WR_REQ )
+#define __msc_mask_endcmdres(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_END_CMD_RES )
+#define __msc_unmask_endcmdres(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_END_CMD_RES )
+#define __msc_mask_datatrandone(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_DATA_TRAN_DONE )
+#define __msc_unmask_datatrandone(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_DATA_TRAN_DONE )
+#define __msc_mask_prgdone(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_PRG_DONE )
+#define __msc_unmask_prgdone(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_PRG_DONE )
+
+/* m=0,1,2,3,4,5,6,7 */
+#define __msc_set_clkrt(n, m) \
+do { \
+ REG_MSC_CLKRT(n) = m; \
+} while(0)
+
+#define __msc_get_ireg(n) ( REG_MSC_IREG(n) )
+#define __msc_ireg_rd(n) ( REG_MSC_IREG(n) & MSC_IREG_RXFIFO_RD_REQ )
+#define __msc_ireg_wr(n) ( REG_MSC_IREG(n) & MSC_IREG_TXFIFO_WR_REQ )
+#define __msc_ireg_end_cmd_res(n) ( REG_MSC_IREG(n) & MSC_IREG_END_CMD_RES )
+#define __msc_ireg_data_tran_done(n) ( REG_MSC_IREG(n) & MSC_IREG_DATA_TRAN_DONE )
+#define __msc_ireg_prg_done(n) ( REG_MSC_IREG(n) & MSC_IREG_PRG_DONE )
+#define __msc_ireg_clear_end_cmd_res(n) ( REG_MSC_IREG(n) = MSC_IREG_END_CMD_RES )
+#define __msc_ireg_clear_data_tran_done(n) ( REG_MSC_IREG(n) = MSC_IREG_DATA_TRAN_DONE )
+#define __msc_ireg_clear_prg_done(n) ( REG_MSC_IREG(n) = MSC_IREG_PRG_DONE )
+
+#define __msc_get_stat(n) ( REG_MSC_STAT(n) )
+#define __msc_stat_not_end_cmd_res(n) ( (REG_MSC_STAT(n) & MSC_STAT_END_CMD_RES) == 0)
+#define __msc_stat_crc_err(n) \
+ ( REG_MSC_STAT(n) & (MSC_STAT_CRC_RES_ERR | MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR_YES) )
+#define __msc_stat_res_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_RES_ERR )
+#define __msc_stat_rd_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_READ_ERROR )
+#define __msc_stat_wr_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_WRITE_ERROR_YES )
+#define __msc_stat_resto_err(n) ( REG_MSC_STAT(n) & MSC_STAT_TIME_OUT_RES )
+#define __msc_stat_rdto_err(n) ( REG_MSC_STAT(n) & MSC_STAT_TIME_OUT_READ )
+
+#define __msc_rd_resfifo(n) ( REG_MSC_RES(n) )
+#define __msc_rd_rxfifo(n) ( REG_MSC_RXFIFO(n) )
+#define __msc_wr_txfifo(n, v) ( REG_MSC_TXFIFO(n) = v )
+
+#define __msc_reset(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_RESET; \
+ while (REG_MSC_STAT(n) & MSC_STAT_IS_RESETTING); \
+} while (0)
+
+#define __msc_start_clk(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_CLOCK_CONTROL_START; \
+} while (0)
+
+#define __msc_stop_clk(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_CLOCK_CONTROL_STOP; \
+} while (0)
+
+#define MMC_CLK 19169200
+#define SD_CLK 24576000
+
+/* msc_clk should little than pclk and little than clk retrieve from card */
+#define __msc_calc_clk_divisor(type,dev_clk,msc_clk,lv) \
+do { \
+ unsigned int rate, pclk, i; \
+ pclk = dev_clk; \
+ rate = type?SD_CLK:MMC_CLK; \
+ if (msc_clk && msc_clk < pclk) \
+ pclk = msc_clk; \
+ i = 0; \
+ while (pclk < rate) \
+ { \
+ i ++; \
+ rate >>= 1; \
+ } \
+ lv = i; \
+} while(0)
+
+/* divide rate to little than or equal to 400kHz */
+#define __msc_calc_slow_clk_divisor(type, lv) \
+do { \
+ unsigned int rate, i; \
+ rate = (type?SD_CLK:MMC_CLK)/1000/400; \
+ i = 0; \
+ while (rate > 0) \
+ { \
+ rate >>= 1; \
+ i ++; \
+ } \
+ lv = i; \
+} while(0)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760MSC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760nemc.h b/arch/mips/include/asm/mach-jz4760/jz4760nemc.h
new file mode 100644
index 00000000000..abc0374c5d8
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760nemc.h
@@ -0,0 +1,58 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760nemc.h
+ *
+ * JZ4760 NEMC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760NEMC_H__
+#define __JZ4760NEMC_H__
+
+
+#define NEMC_BASE 0xB3410000
+
+/*************************************************************************
+ * NEMC (External Memory Controller for NAND)
+ *************************************************************************/
+
+#define NEMC_NFCSR (NEMC_BASE + 0x050) /* NAND Flash Control/Status Register */
+#define NEMC_SMCR (NEMC_BASE + 0x14) /* Static Memory Control Register 1 */
+
+
+#define REG_NEMC_NFCSR REG32(NEMC_NFCSR)
+#define REG_NEMC_SMCR1 REG32(NEMC_SMCR)
+
+// PN(bit 0):0-disable, 1-enable
+// PN(bit 1):0-no reset, 1-reset
+// (bit 2):Reserved
+// BITCNT(bit 3):0-disable, 1-enable
+// BITCNT(bit 4):0-calculate, 1's number, 1-calculate 0's number
+// BITCNT(bit 5):0-no reset, 1-reset bitcnt
+#define NEMC_PNCR (NEMC_BASE+0x100)
+#define NEMC_PNDR (NEMC_BASE+0x104)
+#define NEMC_BITCNT (NEMC_BASE+0x108)
+
+#define REG_NEMC_PNCR REG32(NEMC_PNCR)
+#define REG_NEMC_PNDR REG32(NEMC_PNDR)
+#define REG_NEMC_BITCNT REG32(NEMC_BITCNT)
+
+#define REG_NEMC_SMCR REG32(NEMC_SMCR)
+
+/* NAND Flash Control/Status Register */
+#define NEMC_NFCSR_NFCE4 (1 << 7) /* NAND Flash Enable */
+#define NEMC_NFCSR_NFE4 (1 << 6) /* NAND Flash FCE# Assertion Enable */
+#define NEMC_NFCSR_NFCE3 (1 << 5)
+#define NEMC_NFCSR_NFE3 (1 << 4)
+#define NEMC_NFCSR_NFCE2 (1 << 3)
+#define NEMC_NFCSR_NFE2 (1 << 2)
+#define NEMC_NFCSR_NFCE1 (1 << 1)
+#define NEMC_NFCSR_NFE1 (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760NEMC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760ost.h b/arch/mips/include/asm/mach-jz4760/jz4760ost.h
new file mode 100644
index 00000000000..c70e2dca25c
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760ost.h
@@ -0,0 +1,64 @@
+/*
+ * jz4760ost.h
+ * JZ4760 OST register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760OST_H__
+#define __JZ4760OST_H__
+
+
+/*
+ * Operating system timer module(OST) address definition
+ */
+#define OST_BASE 0xb0002000
+
+
+/*
+ * OST registers offset address definition
+ */
+#define OST_OSTDR_OFFSET (0xe0) /* rw, 32, 0x???????? */
+#define OST_OSTCNT_OFFSET (0xe8) /* rw, 32, 0x???????? */
+#define OST_OSTCSR_OFFSET (0xec) /* rw, 16, 0x0000 */
+
+
+/*
+ * OST registers address definition
+ */
+#define OST_OSTDR (OST_BASE + OST_OSTDR_OFFSET)
+#define OST_OSTCNT (OST_BASE + OST_OSTCNT_OFFSET)
+#define OST_OSTCSR (OST_BASE + OST_OSTCSR_OFFSET)
+
+
+/*
+ * OST registers common define
+ */
+
+/* Operating system control register(OSTCSR) */
+#define OSTCSR_CNT_MD BIT15
+#define OSTCSR_SD BIT9
+#define OSTCSR_EXT_EN BIT2
+#define OSTCSR_RTC_EN BIT1
+#define OSTCSR_PCK_EN BIT0
+
+#define OSTCSR_PRESCALE_LSB 3
+#define OSTCSR_PRESCALE_MASK BITS_H2L(5, OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE1 (0x0 << OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE4 (0x1 << OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE16 (0x2 << OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE64 (0x3 << OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE256 (0x4 << OSTCSR_PRESCALE_LSB)
+#define OSTCSR_PRESCALE1024 (0x5 << OSTCSR_PRESCALE_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_OST_OSTDR REG32(OST_OSTDR)
+#define REG_OST_OSTCNT REG32(OST_OSTCNT)
+#define REG_OST_OSTCSR REG16(OST_OSTCSR)
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760OST_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760otg.h b/arch/mips/include/asm/mach-jz4760/jz4760otg.h
new file mode 100644
index 00000000000..7bb778bfc52
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760otg.h
@@ -0,0 +1,135 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760otg.h
+ *
+ * JZ4760 OTG register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760OTG_H__
+#define __JZ4760OTG_H__
+
+
+#define UDC_BASE 0xB3440000
+
+/*************************************************************************
+ * USB Device
+ *************************************************************************/
+#define USB_BASE UDC_BASE
+
+#define USB_REG_FADDR (USB_BASE + 0x00) /* Function Address 8-bit */
+#define USB_REG_POWER (USB_BASE + 0x01) /* Power Managemetn 8-bit */
+#define USB_REG_INTRIN (USB_BASE + 0x02) /* Interrupt IN 16-bit */
+#define USB_REG_INTROUT (USB_BASE + 0x04) /* Interrupt OUT 16-bit */
+#define USB_REG_INTRINE (USB_BASE + 0x06) /* Intr IN enable 16-bit */
+#define USB_REG_INTROUTE (USB_BASE + 0x08) /* Intr OUT enable 16-bit */
+#define USB_REG_INTRUSB (USB_BASE + 0x0a) /* Interrupt USB 8-bit */
+#define USB_REG_INTRUSBE (USB_BASE + 0x0b) /* Interrupt USB Enable 8-bit */
+#define USB_REG_FRAME (USB_BASE + 0x0c) /* Frame number 16-bit */
+#define USB_REG_INDEX (USB_BASE + 0x0e) /* Index register 8-bit */
+#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */
+
+#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */
+#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */
+#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */
+#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */
+#define USB_REG_OUTMAXP (USB_BASE + 0x14) /* EP1 OUT Max Pkt Size 16-bit */
+#define USB_REG_OUTCSR (USB_BASE + 0x16) /* EP1 OUT CSR LSB 8/16bit */
+#define USB_REG_OUTCSRH (USB_BASE + 0x17) /* EP1 OUT CSR MSB 8-bit */
+#define USB_REG_OUTCOUNT (USB_BASE + 0x18) /* bytes in EP0/1 OUT FIFO 16-bit */
+
+#define USB_FIFO_EP0 (USB_BASE + 0x20)
+#define USB_FIFO_EP1 (USB_BASE + 0x24)
+#define USB_FIFO_EP2 (USB_BASE + 0x28)
+
+#define USB_REG_EPINFO (USB_BASE + 0x78) /* Endpoint information */
+#define USB_REG_RAMINFO (USB_BASE + 0x79) /* RAM information */
+
+#define USB_REG_INTR (USB_BASE + 0x200) /* DMA pending interrupts */
+#define USB_REG_CNTL1 (USB_BASE + 0x204) /* DMA channel 1 control */
+#define USB_REG_ADDR1 (USB_BASE + 0x208) /* DMA channel 1 AHB memory addr */
+#define USB_REG_COUNT1 (USB_BASE + 0x20c) /* DMA channel 1 byte count */
+#define USB_REG_CNTL2 (USB_BASE + 0x214) /* DMA channel 2 control */
+#define USB_REG_ADDR2 (USB_BASE + 0x218) /* DMA channel 2 AHB memory addr */
+#define USB_REG_COUNT2 (USB_BASE + 0x21c) /* DMA channel 2 byte count */
+
+
+/* Power register bit masks */
+#define USB_POWER_SUSPENDM 0x01
+#define USB_POWER_RESUME 0x04
+#define USB_POWER_HSMODE 0x10
+#define USB_POWER_HSENAB 0x20
+#define USB_POWER_SOFTCONN 0x40
+
+/* Interrupt register bit masks */
+#define USB_INTR_SUSPEND 0x01
+#define USB_INTR_RESUME 0x02
+#define USB_INTR_RESET 0x04
+
+#define USB_INTR_EP0 0x0001
+#define USB_INTR_INEP1 0x0002
+#define USB_INTR_INEP2 0x0004
+#define USB_INTR_OUTEP1 0x0002
+
+/* CSR0 bit masks */
+#define USB_CSR0_OUTPKTRDY 0x01
+#define USB_CSR0_INPKTRDY 0x02
+#define USB_CSR0_SENTSTALL 0x04
+#define USB_CSR0_DATAEND 0x08
+#define USB_CSR0_SETUPEND 0x10
+#define USB_CSR0_SENDSTALL 0x20
+#define USB_CSR0_SVDOUTPKTRDY 0x40
+#define USB_CSR0_SVDSETUPEND 0x80
+
+/* Endpoint CSR register bits */
+#define USB_INCSRH_AUTOSET 0x80
+#define USB_INCSRH_ISO 0x40
+#define USB_INCSRH_MODE 0x20
+#define USB_INCSRH_DMAREQENAB 0x10
+#define USB_INCSRH_DMAREQMODE 0x04
+#define USB_INCSR_CDT 0x40
+#define USB_INCSR_SENTSTALL 0x20
+#define USB_INCSR_SENDSTALL 0x10
+#define USB_INCSR_FF 0x08
+#define USB_INCSR_UNDERRUN 0x04
+#define USB_INCSR_FFNOTEMPT 0x02
+#define USB_INCSR_INPKTRDY 0x01
+#define USB_OUTCSRH_AUTOCLR 0x80
+#define USB_OUTCSRH_ISO 0x40
+#define USB_OUTCSRH_DMAREQENAB 0x20
+#define USB_OUTCSRH_DNYT 0x10
+#define USB_OUTCSRH_DMAREQMODE 0x08
+#define USB_OUTCSR_CDT 0x80
+#define USB_OUTCSR_SENTSTALL 0x40
+#define USB_OUTCSR_SENDSTALL 0x20
+#define USB_OUTCSR_FF 0x10
+#define USB_OUTCSR_DATAERR 0x08
+#define USB_OUTCSR_OVERRUN 0x04
+#define USB_OUTCSR_FFFULL 0x02
+#define USB_OUTCSR_OUTPKTRDY 0x01
+
+/* Testmode register bits */
+#define USB_TEST_SE0NAK 0x01
+#define USB_TEST_J 0x02
+#define USB_TEST_K 0x04
+#define USB_TEST_PACKET 0x08
+
+/* DMA control bits */
+#define USB_CNTL_ENA 0x01
+#define USB_CNTL_DIR_IN 0x02
+#define USB_CNTL_MODE_1 0x04
+#define USB_CNTL_INTR_EN 0x08
+#define USB_CNTL_EP(n) ((n) << 4)
+#define USB_CNTL_BURST_0 (0 << 9)
+#define USB_CNTL_BURST_4 (1 << 9)
+#define USB_CNTL_BURST_8 (2 << 9)
+#define USB_CNTL_BURST_16 (3 << 9)
+
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760OTG_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760otp.h b/arch/mips/include/asm/mach-jz4760/jz4760otp.h
new file mode 100644
index 00000000000..728823eb1d1
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760otp.h
@@ -0,0 +1,97 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760otp.h
+ *
+ * JZ4760 OTP register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760OTP_H__
+#define __JZ4760OTP_H__
+
+
+/*************************************************************************
+ * OTP (One Time Programmable Module)
+ *************************************************************************/
+#define OTP_ID0 (OTP_BASE + 0x00) /* ID0 Register */
+#define OTP_ID1 (OTP_BASE + 0x04) /* ID1 Register */
+#define OTP_ID2 (OTP_BASE + 0x08) /* ID2 Register */
+#define OTP_ID3 (OTP_BASE + 0x0C) /* ID3 Register */
+#define OTP_BR0 (OTP_BASE + 0x10) /* BOOTROM0 Register */
+#define OTP_BR1 (OTP_BASE + 0x14) /* BOOTROM1 Register */
+#define OTP_HW0 (OTP_BASE + 0x18) /* Chip Hardware 0 Register */
+#define OTP_HW1 (OTP_BASE + 0x1C) /* Chip Hardware 1 Register */
+
+#define REG_OTP_ID0 REG32(OTP_ID0)
+#define REG_OTP_ID1 REG32(OTP_ID1)
+#define REG_OTP_ID2 REG32(OTP_ID2)
+#define REG_OTP_ID3 REG32(OTP_ID3)
+#define REG_OTP_BR0 REG32(OTP_BR0)
+#define REG_OTP_BR1 REG32(OTP_BR1)
+#define REG_OTP_HW0 REG32(OTP_HW0)
+#define REG_OTP_HW1 REG32(OTP_HW1)
+
+/* ID0 Register */
+#define OTP_ID0_WID_BIT 24 /* Wafer ID */
+#define OTP_ID0_WID_MASK (0xff << OTP_ID0_WID_BIT)
+#define OTP_ID0_MID_BIT 16 /* MASK ID */
+#define OTP_ID0_MID_MASK (0xff << OTP_ID0_MID_BIT)
+#define OTP_ID0_FID_BIT 8 /* Foundary ID */
+#define OTP_ID0_FID_MASK (0xff << OTP_ID0_FID_BIT)
+#define OTP_ID0_PID_BIT 0 /* Product ID */
+#define OTP_ID0_PID_MASK (0xff << OTP_ID0_PID_BIT)
+
+/* ID1 Register */
+#define OTP_ID1_LID_BIT 8 /* Lot ID */
+#define OTP_ID1_LID_MASK (0xffffff << OTP_ID1_LID_BIT)
+#define OTP_ID1_TID_BIT 0 /* Test House ID */
+#define OTP_ID1_TID_MASK (0xff << OTP_ID1_TID_BIT)
+
+/* ID2 Register */
+#define OTP_ID2_XADR_BIT 24 /* Die X-dir Address */
+#define OTP_ID2_XADR_MASK (0xff << OTP_ID2_XADR_BIT)
+#define OTP_ID2_YADR_BIT 16 /* Die Y-dir Address */
+#define OTP_ID2_YADR_MASK (0xff << OTP_ID2_YADR_BIT)
+#define OTP_ID2_TDATE_BIT 0 /* Testing Date */
+#define OTP_ID2_TDATE_MASK (0xffff << OTP_ID2_TDATE_BIT)
+
+/* ID3 Register */
+#define OTP_ID3_CID_BIT 16 /* Customer ID */
+#define OTP_ID3_CID_MASK (0xffff << OTP_ID3_CID_BIT)
+#define OTP_ID3_CP_BIT 0 /* Chip Parameters */
+#define OTP_ID3_CP_MASK (0xffff << OTP_ID3_CP_BIT)
+
+/* BOOTROM1 Register */
+#define OTP_BR1_UDCBOOT_BIT 0
+#define OTP_BR1_UDCBOOT_MASK (0xff << OTP_BR1_UDCBOOT_BIT)
+ #define OTP_BR1_UDCBOOT_AUTO (0xf0 << OTP_BR1_UDCBOOT_BIT)
+ #define OTP_BR1_UDCBOOT_24M (0x0f << OTP_BR1_UDCBOOT_BIT) /* 24MHz OSC */
+ #define OTP_BR1_UDCBOOT_13M (0x0c << OTP_BR1_UDCBOOT_BIT) /* 13MHz OSC */
+ #define OTP_BR1_UDCBOOT_26M (0x03 << OTP_BR1_UDCBOOT_BIT) /* 26MHz OSC */
+ #define OTP_BR1_UDCBOOT_27M (0x00 << OTP_BR1_UDCBOOT_BIT) /* 27MHz OSC */
+
+/* Chip Hardware 1 Register */
+#define OTP_HW1_MC_EN (0x3 << 30) /* MC is enabled */
+#define OTP_HW1_ME_EN (0x3 << 28)
+#define OTP_HW1_DE_EN (0x3 << 26)
+#define OTP_HW1_IDCT_EN (0x3 << 24)
+#define OTP_HW1_UART3_EN (0x3 << 22)
+#define OTP_HW1_UART2_EN (0x3 << 20)
+#define OTP_HW1_UART1_EN (0x3 << 18)
+#define OTP_HW1_UART0_EN (0x3 << 16)
+#define OTP_HW1_SSI1_EN (0x3 << 14)
+#define OTP_HW1_SSI0_EN (0x3 << 12)
+#define OTP_HW1_MSC1_EN (0x3 << 10)
+#define OTP_HW1_MSC0_EN (0x3 << 8)
+#define OTP_HW1_UHC_EN (0x3 << 6)
+#define OTP_HW1_TVE_EN (0x3 << 4)
+#define OTP_HW1_TSSI_EN (0x3 << 2)
+#define OTP_HW1_CIM_EN (0x3 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760OTP_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760owi.h b/arch/mips/include/asm/mach-jz4760/jz4760owi.h
new file mode 100644
index 00000000000..32aa1563b3a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760owi.h
@@ -0,0 +1,82 @@
+/*
+ * jz4760owi.h
+ * JZ4760 OWI register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760OWI_H__
+#define __JZ4760OWI_H__
+
+
+/*
+ * One wire bus interface(OWI) address definition
+ */
+#define OWI_BASE 0xb0072000
+
+
+/*
+ * OWI registers offset address definition
+ */
+#define OWI_OWICFG_OFFSET (0x00) /* rw, 8, 0x00 */
+#define OWI_OWICTL_OFFSET (0x04) /* rw, 8, 0x00 */
+#define OWI_OWISTS_OFFSET (0x08) /* rw, 8, 0x00 */
+#define OWI_OWIDAT_OFFSET (0x0c) /* rw, 8, 0x00 */
+#define OWI_OWIDIV_OFFSET (0x10) /* rw, 8, 0x00 */
+
+
+/*
+ * OWI registers address definition
+ */
+#define OWI_OWICFG (OWI_BASE + OWI_OWICFG_OFFSET)
+#define OWI_OWICTL (OWI_BASE + OWI_OWICTL_OFFSET)
+#define OWI_OWISTS (OWI_BASE + OWI_OWISTS_OFFSET)
+#define OWI_OWIDAT (OWI_BASE + OWI_OWIDAT_OFFSET)
+#define OWI_OWIDIV (OWI_BASE + OWI_OWIDIV_OFFSET)
+
+
+/*
+ * OWI registers common define
+ */
+
+/* OWI configure register(OWICFG) */
+#define OWICFG_MODE BIT7
+#define OWICFG_RDDATA BIT6
+#define OWICFG_WRDATA BIT5
+#define OWICFG_RDST BIT4
+#define OWICFG_WR1RD BIT3
+#define OWICFG_WR0 BIT2
+#define OWICFG_RST BIT1
+#define OWICFG_ENA BIT0
+
+/* OWI control register(OWICTL) */
+#define OWICTL_EBYTE BIT2
+#define OWICTL_EBIT BIT1
+#define OWICTL_ERST BIT0
+
+/* OWI status register(OWISTS) */
+#define OWISTS_PST BIT7
+#define OWISTS_BYTE_RDY BIT2
+#define OWISTS_BIT_RDY BIT1
+#define OWISTS_PST_RDY BIT0
+
+/* OWI clock divide register(OWIDIV) */
+#define OWIDIV_CLKDIV_LSB 0
+#define OWIDIV_CLKDIV_MASK BITS_H2L(5, OWIDIV_CLKDIV_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/* Basic ops */
+#define REG_OWI_OWICFG REG8(OWI_OWICFG)
+#define REG_OWI_OWICTL REG8(OWI_OWICTL)
+#define REG_OWI_OWISTS REG8(OWI_OWISTS)
+#define REG_OWI_OWIDAT REG8(OWI_OWIDAT)
+#define REG_OWI_OWIDIV REG8(OWI_OWIDIV)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760OWI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760pcm.h b/arch/mips/include/asm/mach-jz4760/jz4760pcm.h
new file mode 100644
index 00000000000..732910dac3e
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760pcm.h
@@ -0,0 +1,218 @@
+/*
+ * jz4760pcm.h
+ * JZ4760 PCM register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760PCM_H__
+#define __JZ4760PCM_H__
+
+
+/*
+ * Pulse-code modulation module(PCM) address definition
+ */
+#define PCM_BASE 0xb0071000
+
+
+/*
+ * PCM registers offset address definition
+ */
+#define PCM_PCTL_OFFSET (0x00) /* rw, 32, 0x00000000 */
+#define PCM_PCFG_OFFSET (0x04) /* rw, 32, 0x00000110 */
+#define PCM_PDP_OFFSET (0x08) /* rw, 32, 0x00000000 */
+#define PCM_PINTC_OFFSET (0x0c) /* rw, 32, 0x00000000 */
+#define PCM_PINTS_OFFSET (0x10) /* rw, 32, 0x00000100 */
+#define PCM_PDIV_OFFSET (0x14) /* rw, 32, 0x00000001 */
+
+
+/*
+ * PCM registers address definition
+ */
+#define PCM_PCTL (PCM_BASE + PCM_PCTL_OFFSET)
+#define PCM_PCFG (PCM_BASE + PCM_PCFG_OFFSET)
+#define PCM_PDP (PCM_BASE + PCM_PDP_OFFSET)
+#define PCM_PINTC (PCM_BASE + PCM_PINTC_OFFSET)
+#define PCM_PINTS (PCM_BASE + PCM_PINTS_OFFSET)
+#define PCM_PDIV (PCM_BASE + PCM_PDIV_OFFSET)
+
+
+/*
+ * CPM registers common define
+ */
+
+/* PCM controller control register (PCTL) */
+#define PCTL_ERDMA BIT9
+#define PCTL_ETDMA BIT8
+#define PCTL_LSMP BIT7
+#define PCTL_ERPL BIT6
+#define PCTL_EREC BIT5
+#define PCTL_FLUSH BIT4
+#define PCTL_RST BIT3
+#define PCTL_CLKEN BIT1
+#define PCTL_PCMEN BIT0
+
+/* PCM controller configure register (PCFG) */
+#define PCFG_ISS_16BIT BIT12
+#define PCFG_OSS_16BIT BIT11
+#define PCFG_IMSBPOS BIT10
+#define PCFG_OMSBPOS BIT9
+#define PCFG_MODE_SLAVE BIT0
+
+#define PCFG_SLOT_LSB 13
+#define PCFG_SLOT_MASK BIT_H2L(14, PCFG_SLOT_LSB)
+#define PCFG_SLOT(n) ((n) << PCFG_SLOT_LSB)
+
+#define PCFG_RFTH_LSB 5
+#define PCFG_RFTH_MASK BIT_H2L(8, PCFG_RFTH_LSB)
+
+#define PCFG_TFTH_LSB 1
+#define PCFG_TFTH_MASK BIT_H2L(4, PCFG_TFTH_LSB)
+
+/* PCM controller interrupt control register(PINTC) */
+#define PINTC_ETFS BIT3
+#define PINTC_ETUR BIT2
+#define PINTC_ERFS BIT1
+#define PINTC_EROR BIT0
+
+/* PCM controller interrupt status register(PINTS) */
+#define PINTS_RSTS BIT14
+#define PINTS_TFS BIT8
+#define PINTS_TUR BIT7
+#define PINTS_RFS BIT1
+#define PINTS_ROR BIT0
+
+#define PINTS_TFL_LSB 9
+#define PINTS_TFL_MASK BITS_H2L(13, PINTS_TFL_LSB)
+
+#define PINTS_RFL_LSB 2
+#define PINTS_RFL_MASK BITS_H2L(6, PINTS_RFL_LSB)
+
+/* PCM controller clock division register(PDIV) */
+#define PDIV_SYNL_LSB 11
+#define PDIV_SYNL_MASK BITS_H2L(16, PDIV_SYNL_LSB)
+
+#define PDIV_SYNDIV_LSB 6
+#define PDIV_SYNDIV_MASK BITS_H2L(10, PDIV_SYNDIV_LSB)
+
+#define PDIV_CLKDIV_LSB 0
+#define PDIV_CLKDIV_MASK BITS_H2L(5, PDIV_CLKDIV_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+#define REG_PCM_PCTL REG32(PCM_PCTL)
+#define REG_PCM_PCFG REG32(PCM_PCFG)
+#define REG_PCM_PDP REG32(PCM_PDP)
+#define REG_PCM_PINTC REG32(PCM_PINTC)
+#define REG_PCM_PINTS REG32(PCM_PINTS)
+#define REG_PCM_PDIV REG32(PCM_PDIV)
+
+/*
+ * PCM_DIN, PCM_DOUT, PCM_CLK, PCM_SYN
+*/
+#define __gpio_as_pcm() \
+do { \
+ unsigned int bits = BITS_H2L(3, 0); \
+ REG_GPIO_PXFUNS(3) = bits; \
+ REG_GPIO_PXSELC(3) = bits; \
+ REG_GPIO_PXTRGC(3) = bits; \
+ REG_GPIO_PXPES(3) = bits; \
+} while (0)
+
+#define __pcm_enable() (REG_PCM_PCTL |= PCTL_PCMEN)
+#define __pcm_disable() (REG_PCM_PCTL &= ~PCTL_PCMEN)
+
+#define __pcm_clk_enable() (REG_PCM_PCTL |= PCTL_CLKEN)
+#define __pcm_clk_disable() (REG_PCM_PCTL &= ~PCTL_CLKEN)
+
+#define __pcm_reset() (REG_PCM_PCTL |= PCTL_RST)
+#define __pcm_flush_fifo() (REG_PCM_PCTL |= PCTL_FLUSH)
+
+#define __pcm_enable_record() (REG_PCM_PCTL |= PCTL_EREC)
+#define __pcm_disable_record() (REG_PCM_PCTL &= ~PCTL_EREC)
+#define __pcm_enable_playback() (REG_PCM_PCTL |= PCTL_ERPL)
+#define __pcm_disable_playback() (REG_PCM_PCTL &= ~PCTL_ERPL)
+
+#define __pcm_enable_rxfifo() __pcm_enable_record()
+#define __pcm_disable_rxfifo() __pcm_disable_record()
+#define __pcm_enable_txfifo() __pcm_enable_playback()
+#define __pcm_disable_txfifo() __pcm_disable_playback()
+
+#define __pcm_last_sample() (REG_PCM_PCTL |= PCTL_LSMP)
+#define __pcm_zero_sample() (REG_PCM_PCTL &= ~PCTL_LSMP)
+
+#define __pcm_enable_transmit_dma() (REG_PCM_PCTL |= PCTL_ETDMA)
+#define __pcm_disable_transmit_dma() (REG_PCM_PCTL &= ~PCTL_ETDMA)
+#define __pcm_enable_receive_dma() (REG_PCM_PCTL |= PCTL_ERDMA)
+#define __pcm_disable_receive_dma() (REG_PCM_PCTL &= ~PCTL_ERDMA)
+
+#define __pcm_as_master() (REG_PCM_PCFG &= PCFG_MODE)
+#define __pcm_as_slave() (REG_PCM_PCFG |= ~PCFG_MODE)
+
+#define __pcm_set_transmit_trigger(n) \
+do { \
+ REG_PCM_PCFG &= ~PCFG_TFTH_MASK; \
+ REG_PCM_PCFG |= ((n) << PCFG_TFTH_BIT); \
+} while(0)
+
+#define __pcm_set_receive_trigger(n) \
+do { \
+ REG_PCM_PCFG &= ~PCFG_RFTH_MASK; \
+ REG_PCM_PCFG |= ((n) << PCFG_RFTH_BIT); \
+} while(0)
+
+#define __pcm_omsb_same_sync() (REG_PCM_PCFG &= ~PCFG_OMSBPOS)
+#define __pcm_omsb_next_sync() (REG_PCM_PCFG |= PCFG_OMSBPOS)
+
+#define __pcm_imsb_same_sync() (REG_PCM_PCFG &= ~PCFG_IMSBPOS)
+#define __pcm_imsb_next_sync() (REG_PCM_PCFG |= PCFG_IMSBPOS)
+
+#define __pcm_set_iss(n) \
+(n == 16 ? REG_PCM_PCFG |= PCFG_ISS_16BIT : REG_PCM_PCFG &= ~PCFG_ISS_16BIT)
+
+#define __pcm_set_oss(n) \
+(n == 16 ? REG_PCM_PCFG |= PCFG_OSS_16BIT : REG_PCM_PCFG &= ~PCFG_OSS_16BIT)
+
+#define __pcm_set_valid_slot(n) \
+(REG_PCM_PCFG = (REG_PCM_PCFG & ~PCFG_SLOT_MASK) | PCFG_SLOT(n))
+
+#define __pcm_write_data(v) (REG_PCM_PDP = (v))
+#define __pcm_read_data() (REG_PCM_PDP)
+
+#define __pcm_enable_tfs_intr() (REG_PCM_PINTC |= PINTC_ETFS)
+#define __pcm_disable_tfs_intr() (REG_PCM_PINTC &= ~PINTC_ETFS)
+
+#define __pcm_enable_tur_intr() (REG_PCM_PINTC |= PINTC_ETUR)
+#define __pcm_disable_tur_intr() (REG_PCM_PINTC &= ~PINTC_ETUR)
+
+#define __pcm_enable_rfs_intr() (REG_PCM_PINTC |= PINTC_ERFS)
+#define __pcm_disable_rfs_intr() (REG_PCM_PINTC &= ~PINTC_ERFS)
+
+#define __pcm_enable_ror_intr() (REG_PCM_PINTC |= PINTC_EROR)
+#define __pcm_disable_ror_intr() (REG_PCM_PINTC &= ~PINTC_EROR)
+
+#define __pcm_ints_valid_tx() (((REG_PCM_PINTS & PINTS_TFL_MASK) >> PINTS_TFL_LSB))
+#define __pcm_ints_valid_rx() (((REG_PCM_PINTS & PINTS_RFL_MASK) >> PINTS_RFL_LSB))
+
+#define __pcm_set_clk_div(n) \
+(REG_PCM_DIV = (REG_PCM_PDIV & ~PDIV_CLKDIV_MASK) | ((n) << PDIV_CLKDIV_LSB))
+
+#define __pcm_set_clk_rate(sysclk, pcmclk) \
+__pcm_set_clk_div(((sysclk) / (pcmclk) - 1))
+
+#define __pcm_set_sync_div(n) \
+(REG_PCM_PDIV = (REG_PCM_PDIV & ~PDIV_SYNDIV_MASK) | ((n) << PDIV_SYNDIV_LSB))
+
+#define __pcm_set_sync_rate(pcmclk, sync) \
+__pcm_set_sync_div(((pcmclk) / (8 * (sync)) - 1))
+
+#define __pcm_set_sync_len(n) \
+(REG_PCM_PDIV = (REG_PCM_PDIV & ~PDIV_SYNL_MASK) | (n << PDIV_SYNL_LSB))
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760PCM_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760rtc.h b/arch/mips/include/asm/mach-jz4760/jz4760rtc.h
new file mode 100644
index 00000000000..ea711a9fc18
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760rtc.h
@@ -0,0 +1,172 @@
+/*
+ * jz4760rtc.h
+ * JZ4760 RTC register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: cjwang@ingenic.cn
+ */
+
+#ifndef __JZ4760RTC_H__
+#define __JZ4760RTC_H__
+
+
+/*
+ * Real time clock module(RTC) address definition
+ */
+#define RTC_BASE 0xb0003000
+
+
+/*
+ * RTC registers offset address definition
+ */
+#define RTC_RTCCR_OFFSET (0x00) /* rw, 32, 0x00000081 */
+#define RTC_RTCSR_OFFSET (0x04) /* rw, 32, 0x???????? */
+#define RTC_RTCSAR_OFFSET (0x08) /* rw, 32, 0x???????? */
+#define RTC_RTCGR_OFFSET (0x0c) /* rw, 32, 0x0??????? */
+
+#define RTC_HCR_OFFSET (0x20) /* rw, 32, 0x00000000 */
+#define RTC_HWFCR_OFFSET (0x24) /* rw, 32, 0x0000???0 */
+#define RTC_HRCR_OFFSET (0x28) /* rw, 32, 0x00000??0 */
+#define RTC_HWCR_OFFSET (0x2c) /* rw, 32, 0x00000008 */
+#define RTC_HWRSR_OFFSET (0x30) /* rw, 32, 0x00000000 */
+#define RTC_HSPR_OFFSET (0x34) /* rw, 32, 0x???????? */
+#define RTC_WENR_OFFSET (0x3c) /* rw, 32, 0x00000000 */
+
+
+/*
+ * RTC registers address definition
+ */
+#define RTC_RTCCR (RTC_BASE + RTC_RTCCR_OFFSET)
+#define RTC_RTCSR (RTC_BASE + RTC_RTCSR_OFFSET)
+#define RTC_RTCSAR (RTC_BASE + RTC_RTCSAR_OFFSET)
+#define RTC_RTCGR (RTC_BASE + RTC_RTCGR_OFFSET)
+
+#define RTC_HCR (RTC_BASE + RTC_HCR_OFFSET)
+#define RTC_HWFCR (RTC_BASE + RTC_HWFCR_OFFSET)
+#define RTC_HRCR (RTC_BASE + RTC_HRCR_OFFSET)
+#define RTC_HWCR (RTC_BASE + RTC_HWCR_OFFSET)
+#define RTC_HWRSR (RTC_BASE + RTC_HWRSR_OFFSET)
+#define RTC_HSPR (RTC_BASE + RTC_HSPR_OFFSET)
+#define RTC_WENR (RTC_BASE + RTC_WENR_OFFSET)
+
+
+/*
+ * RTC registers common define
+ */
+
+/* RTC control register(RTCCR) */
+#define RTCCR_WRDY BIT7
+#define RTCCR_1HZ BIT6
+#define RTCCR_1HZIE BIT5
+#define RTCCR_AF BIT4
+#define RTCCR_AIE BIT3
+#define RTCCR_AE BIT2
+#define RTCCR_SELEXC BIT1
+#define RTCCR_RTCE BIT0
+
+/* RTC regulator register(RTCGR) */
+#define RTCGR_LOCK BIT31
+
+#define RTCGR_ADJC_LSB 16
+#define RTCGR_ADJC_MASK BITS_H2L(25, RTCGR_ADJC_LSB)
+
+#define RTCGR_NC1HZ_LSB 0
+#define RTCGR_NC1HZ_MASK BITS_H2L(15, RTCGR_NC1HZ_LSB)
+
+/* Hibernate control register(HCR) */
+#define HCR_PD BIT0
+
+/* Hibernate wakeup filter counter register(HWFCR) */
+#define HWFCR_LSB 5
+#define HWFCR_MASK BITS_H2L(15, HWFCR_LSB)
+#define HWFCR_WAIT_TIME(ms) (((ms) << HWFCR_LSB) > HWFCR_MASK ? HWFCR_MASK : ((ms) << HWFCR_LSB))
+
+/* Hibernate reset counter register(HRCR) */
+#define HRCR_LSB 5
+#define HRCR_MASK BITS_H2L(11, HRCR_LSB)
+#define HRCR_WAIT_TIME(ms) (((ms) << HRCR_LSB) > HRCR_MASK ? HRCR_MASK : ((ms) << HRCR_LSB))
+
+/* Hibernate wakeup control register(HWCR) */
+#define HWCR_EPDET BIT3
+#define HWCR_WKUPVL BIT2
+#define HWCR_EALM BIT0
+
+/* Hibernate wakeup status register(HWRSR) */
+#define HWRSR_APD BIT8
+#define HWRSR_HR BIT5
+#define HWRSR_PPR BIT4
+#define HWRSR_PIN BIT1
+#define HWRSR_ALM BIT0
+
+/* write enable pattern register(WENR) */
+#define WENR_WEN BIT31
+
+#define WENR_WENPAT_LSB 0
+#define WENR_WENPAT_MASK BITS_H2L(15, WENR_WENPAT_LSB)
+#define WENR_WENPAT_WRITABLE (0xa55a)
+
+/* Hibernate scratch pattern register(HSPR) */
+#define HSPR_RTCV 0x52544356 /* The value is 'RTCV', means rtc is valid */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/* Waiting for the RTC register writing finish */
+#define __wait_write_ready() \
+do { \
+ unsigned int timeout = 1; \
+ while (!(rtc_read_reg(RTC_RTCCR) & RTCCR_WRDY) && timeout++); \
+}while(0);
+
+/* Waiting for the RTC register writable */
+#define __wait_writable() \
+do { \
+ unsigned int timeout = 1; \
+ __wait_write_ready(); \
+ OUTREG32(RTC_WENR, WENR_WENPAT_WRITABLE); \
+ __wait_write_ready(); \
+ while (!(rtc_read_reg(RTC_WENR) & WENR_WEN) && timeout++); \
+}while(0);
+
+/* Basic RTC ops */
+#define rtc_read_reg(reg) \
+({ \
+ unsigned int data; \
+ do { \
+ data = INREG32(reg); \
+ } while (INREG32(reg) != data); \
+ data; \
+})
+
+#define rtc_write_reg(reg, data) \
+do { \
+ __wait_writable(); \
+ OUTREG32(reg, data); \
+ __wait_write_ready(); \
+}while(0);
+
+#define rtc_set_reg(reg, data) rtc_write_reg(reg, rtc_read_reg(reg) | (data))
+#define rtc_clr_reg(reg, data) rtc_write_reg(reg, rtc_read_reg(reg) & ~(data))
+
+typedef volatile struct
+{
+ unsigned int RTCCR;
+ unsigned int RTCSR;
+ unsigned int RTCSAR;
+ unsigned int RTCGR;
+
+ unsigned int RTCRSV[(RTC_HCR_OFFSET - RTC_RTCGR_OFFSET)/4];
+
+ unsigned int HCR;
+ unsigned int HWFCR;
+ unsigned int HRCR;
+ unsigned int HWCR;
+ unsigned int HWRSR;
+ unsigned int HSPR;
+ unsigned int WENR;
+} JZ4760_RTC, *PJZ4760_RTC;
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760RTC_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760sadc.h b/arch/mips/include/asm/mach-jz4760/jz4760sadc.h
new file mode 100644
index 00000000000..d5283ffb606
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760sadc.h
@@ -0,0 +1,182 @@
+/*
+ * jz4760sadc.h
+ * JZ4760 SADC register definition.
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author:jfli@ingenic.cn
+ */
+
+#ifndef __JZ4760SADC_H__
+#define __JZ4760SADC_H__
+
+
+/*
+ * SAR A/D Controller(SADC) address definition
+ */
+#define SADC_BASE 0xb0070000
+
+
+/*
+ * SADC registers offset definition
+ */
+#define SADC_ADENA_OFFSET (0x00) /* rw, 8, 0x00 */
+#define SADC_ADCFG_OFFSET (0x04) /* rw, 32, 0x0002000c */
+#define SADC_ADCTRL_OFFSET (0x08) /* rw, 8, 0x3f */
+#define SADC_ADSTATE_OFFSET (0x0c) /* rw, 8, 0x00 */
+#define SADC_ADSAME_OFFSET (0x10) /* rw, 16, 0x0000 */
+#define SADC_ADWAIT_OFFSET (0x14) /* rw, 16, 0x0000 */
+#define SADC_ADTCH_OFFSET (0x18) /* rw, 32, 0x00000000 */
+#define SADC_ADVDAT_OFFSET (0x1c) /* rw, 16, 0x0000 */
+#define SADC_ADADAT_OFFSET (0x20) /* rw, 16, 0x0000 */
+#define SADC_ADFLT_OFFSET (0x24) /* rw, 16, 0x0000 */
+#define SADC_ADCLK_OFFSET (0x28) /* rw, 32, 0x00000000 */
+
+
+/*
+ * SADC registers address definition
+ */
+#define SADC_ADENA (SADC_BASE + SADC_ADENA_OFFSET) /* ADC Enable Register */
+#define SADC_ADCFG (SADC_BASE + SADC_ADCFG_OFFSET) /* ADC Configure Register */
+#define SADC_ADCTRL (SADC_BASE + SADC_ADCTRL_OFFSET) /* ADC Control Register */
+#define SADC_ADSTATE (SADC_BASE + SADC_ADSTATE_OFFSET)/* ADC Status Register*/
+#define SADC_ADSAME (SADC_BASE + SADC_ADSAME_OFFSET) /* ADC Same Point Time Register */
+#define SADC_ADWAIT (SADC_BASE + SADC_ADWAIT_OFFSET) /* ADC Wait Time Register */
+#define SADC_ADTCH (SADC_BASE + SADC_ADTCH_OFFSET) /* ADC Touch Screen Data Register */
+#define SADC_ADVDAT (SADC_BASE + SADC_ADVDAT_OFFSET) /* ADC VBAT Data Register */
+#define SADC_ADADAT (SADC_BASE + SADC_ADADAT_OFFSET) /* ADC AUX Data Register */
+#define SADC_ADFLT (SADC_BASE + SADC_ADFLT_OFFSET) /* ADC Filter Register */
+#define SADC_ADCLK (SADC_BASE + SADC_ADCLK_OFFSET) /* ADC Clock Divide Register */
+
+
+/*
+ * SADC registers common define
+ */
+
+/* ADC Enable Register (ADENA) */
+#define ADENA_POWER BIT7
+#define ADENA_SLP_MD BIT6
+#define ADENA_TCHEN BIT2
+#define ADENA_VBATEN BIT1
+#define ADENA_AUXEN BIT0
+
+/* ADC Configure Register (ADCFG) */
+#define ADCFG_SPZZ BIT31
+#define ADCFG_DMA_EN BIT15
+
+#define ADCFG_XYZ_LSB 13
+#define ADCFG_XYZ_MASK BITS_H2L(14, ADCFG_XYZ_LSB)
+ #define ADCFG_XYZ_XYS (0x0 << ADCFG_XYZ_LSB)
+ #define ADCFG_XYZ_XYD (0x1 << ADCFG_XYZ_LSB)
+ #define ADCFG_XYZ_XYZ1Z2 (0x2 << ADCFG_XYZ_LSB)
+
+#define ADCFG_SNUM_LSB 10
+#define ADCFG_SNUM_MASK BITS_H2L(12, ADCFG_SNUM_LSB)
+ #define ADCFG_SNUM(n) (((n) <= 6 ? ((n)-1) : ((n)-2)) << ADCFG_SNUM_LSB)
+
+#define ADCFG_CMD_LSB 0
+#define ADCFG_CMD_MASK BITS_H2L(1, ADCFG_CMD_LSB)
+ #define ADCFG_CMD_AUX(n) ((n) << ADCFG_CMD_LSB)
+
+/* ADC Control Register (ADCCTRL) */
+#define ADCTRL_SLPENDM BIT5
+#define ADCTRL_PENDM BIT4
+#define ADCTRL_PENUM BIT3
+#define ADCTRL_DTCHM BIT2
+#define ADCTRL_VRDYM BIT1
+#define ADCTRL_ARDYM BIT0
+#define ADCTRL_MASK_ALL (ADCTRL_SLPENDM | ADCTRL_PENDM | ADCTRL_PENUM \
+ | ADCTRL_DTCHM | ADCTRL_VRDYM | ADCTRL_ARDYM)
+
+/* ADC Status Register (ADSTATE) */
+#define ADSTATE_SLP_RDY BIT7
+#define ADSTATE_SLPEND BIT5
+#define ADSTATE_PEND BIT4
+#define ADSTATE_PENU BIT3
+#define ADSTATE_DTCH BIT2
+#define ADSTATE_VRDY BIT1
+#define ADSTATE_ARDY BIT0
+
+/* ADC Same Point Time Register (ADSAME) */
+#define ADSAME_SCNT_LSB 0
+#define ADSAME_SCNT_MASK BITS_H2L(15, ADSAME_SCNT_LSB)
+
+/* ADC Wait Pen Down Time Register (ADWAIT) */
+#define ADWAIT_WCNT_LSB 0
+#define ADWAIT_WCNT_MASK BITS_H2L(15, ADWAIT_WCNT_LSB)
+
+/* ADC Touch Screen Data Register (ADTCH) */
+#define ADTCH_TYPE1 BIT31
+#define ADTCH_TYPE0 BIT15
+
+#define ADTCH_DATA1_LSB 16
+#define ADTCH_DATA1_MASK BITS_H2L(27, ADTCH_DATA1_LSB)
+
+#define ADTCH_DATA0_LSB 0
+#define ADTCH_DATA0_MASK BITS_H2L(11, ADTCH_DATA0_LSB)
+
+/* ADC VBAT Date Register (ADVDAT) */
+#define ADVDAT_VDATA_LSB 0
+#define ADVDAT_VDATA_MASK BITS_H2L(11, ADVDAT_VDATA_LSB)
+
+/* ADC AUX Data Register (ADADAT) */
+#define ADADAT_ADATA_LSB 0
+#define ADADAT_ADATA_MASK BITS_H2L(11, ADADAT_ADATA_LSB)
+
+/* ADC Clock Divide Register (ADCLK) */
+#define ADCLK_CLKDIV_MS_LSB 16
+#define ADCLK_CLKDIV_MS_MASK BITS_H2L(31, ADCLK_CLKDIV_MS_LSB)
+
+#define ADCLK_CLKDIV_US_LSB 8
+#define ADCLK_CLKDIV_US_MASK BITS_H2L(15, ADCLK_CLKDIV_US_LSB)
+
+#define ADCLK_CLKDIV_LSB 0
+#define ADCLK_CLKDIV_MASK BITS_H2L(7, ADCLK_CLKDIV_LSB)
+
+/* ADC Filter Register (ADFLT) */
+#define ADFLT_FLT_EN BIT15
+
+#define ADFLT_FLT_D_LSB 0
+#define ADFLT_FLT_D_MASK BITS_H2L(11, ADFLT_FLT_D_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_SADC_ADENA REG8(SADC_ADENA)
+#define REG_SADC_ADCFG REG32(SADC_ADCFG)
+#define REG_SADC_ADCTRL REG8(SADC_ADCTRL)
+#define REG_SADC_ADSTATE REG8(SADC_ADSTATE)
+#define REG_SADC_ADSAME REG16(SADC_ADSAME)
+#define REG_SADC_ADWAIT REG16(SADC_ADWAIT)
+#define REG_SADC_ADTCH REG32(SADC_ADTCH)
+#define REG_SADC_ADVDAT REG16(SADC_ADVDAT)
+#define REG_SADC_ADADAT REG16(SADC_ADADAT)
+#define REG_SADC_ADFLT REG16(SADC_ADFLT)
+#define REG_SADC_ADCLK REG32(SADC_ADCLK)
+
+
+typedef volatile struct
+{
+ unsigned char ADENA;
+ unsigned char ADENARSV[3];
+ unsigned int ADCFG;
+ unsigned char ADCTRL;
+ unsigned char ADCTRLRSV[3];
+ unsigned char ADSTATE;
+ unsigned char ADSTATERSV[3];
+ unsigned short ADSAME;
+ unsigned short ADSAMERSV[1];
+ unsigned short ADWAIT;
+ unsigned short ADWAITRSV[1];
+ unsigned int ADTCH;
+ unsigned short ADVDAT;
+ unsigned short ADVDATRSV[1];
+ unsigned short ADADAT;
+ unsigned short ADADATRSV[1];
+ unsigned short ADFLT;
+ unsigned short ADFLTRSV[1];
+ unsigned int ADCLK;
+} JZ4760_SADC, *PJZ4760_SADC;
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760SADC_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760scc.h b/arch/mips/include/asm/mach-jz4760/jz4760scc.h
new file mode 100644
index 00000000000..b007dc1cf0a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760scc.h
@@ -0,0 +1,191 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760scc.h
+ *
+ * JZ4760 SCC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760SCC_H__
+#define __JZ4760SCC_H__
+
+
+#define SCC_BASE 0xB0040000
+
+/*************************************************************************
+ * SCC
+ *************************************************************************/
+#define SCC_DR (SCC_BASE + 0x000)
+#define SCC_FDR (SCC_BASE + 0x004)
+#define SCC_CR (SCC_BASE + 0x008)
+#define SCC_SR (SCC_BASE + 0x00C)
+#define SCC_TFR (SCC_BASE + 0x010)
+#define SCC_EGTR (SCC_BASE + 0x014)
+#define SCC_ECR (SCC_BASE + 0x018)
+#define SCC_RTOR (SCC_BASE + 0x01C)
+
+#define REG_SCC_DR REG8(SCC_DR)
+#define REG_SCC_FDR REG8(SCC_FDR)
+#define REG_SCC_CR REG32(SCC_CR)
+#define REG_SCC_SR REG16(SCC_SR)
+#define REG_SCC_TFR REG16(SCC_TFR)
+#define REG_SCC_EGTR REG8(SCC_EGTR)
+#define REG_SCC_ECR REG32(SCC_ECR)
+#define REG_SCC_RTOR REG8(SCC_RTOR)
+
+/* SCC FIFO Data Count Register (SCC_FDR) */
+
+#define SCC_FDR_EMPTY 0x00
+#define SCC_FDR_FULL 0x10
+
+/* SCC Control Register (SCC_CR) */
+
+#define SCC_CR_SCCE (1 << 31)
+#define SCC_CR_TRS (1 << 30)
+#define SCC_CR_T2R (1 << 29)
+#define SCC_CR_FDIV_BIT 24
+#define SCC_CR_FDIV_MASK (0x3 << SCC_CR_FDIV_BIT)
+ #define SCC_CR_FDIV_1 (0 << SCC_CR_FDIV_BIT) /* SCC_CLK frequency is the same as device clock */
+ #define SCC_CR_FDIV_2 (1 << SCC_CR_FDIV_BIT) /* SCC_CLK frequency is half of device clock */
+#define SCC_CR_FLUSH (1 << 23)
+#define SCC_CR_TRIG_BIT 16
+#define SCC_CR_TRIG_MASK (0x3 << SCC_CR_TRIG_BIT)
+ #define SCC_CR_TRIG_1 (0 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 1 */
+ #define SCC_CR_TRIG_4 (1 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 4 */
+ #define SCC_CR_TRIG_8 (2 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 8 */
+ #define SCC_CR_TRIG_14 (3 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 14 */
+#define SCC_CR_TP (1 << 15)
+#define SCC_CR_CONV (1 << 14)
+#define SCC_CR_TXIE (1 << 13)
+#define SCC_CR_RXIE (1 << 12)
+#define SCC_CR_TENDIE (1 << 11)
+#define SCC_CR_RTOIE (1 << 10)
+#define SCC_CR_ECIE (1 << 9)
+#define SCC_CR_EPIE (1 << 8)
+#define SCC_CR_RETIE (1 << 7)
+#define SCC_CR_EOIE (1 << 6)
+#define SCC_CR_TSEND (1 << 3)
+#define SCC_CR_PX_BIT 1
+#define SCC_CR_PX_MASK (0x3 << SCC_CR_PX_BIT)
+ #define SCC_CR_PX_NOT_SUPPORT (0 << SCC_CR_PX_BIT) /* SCC does not support clock stop */
+ #define SCC_CR_PX_STOP_LOW (1 << SCC_CR_PX_BIT) /* SCC_CLK stops at state low */
+ #define SCC_CR_PX_STOP_HIGH (2 << SCC_CR_PX_BIT) /* SCC_CLK stops at state high */
+#define SCC_CR_CLKSTP (1 << 0)
+
+/* SCC Status Register (SCC_SR) */
+
+#define SCC_SR_TRANS (1 << 15)
+#define SCC_SR_ORER (1 << 12)
+#define SCC_SR_RTO (1 << 11)
+#define SCC_SR_PER (1 << 10)
+#define SCC_SR_TFTG (1 << 9)
+#define SCC_SR_RFTG (1 << 8)
+#define SCC_SR_TEND (1 << 7)
+#define SCC_SR_RETR_3 (1 << 4)
+#define SCC_SR_ECNTO (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * SCC
+ ***************************************************************************/
+
+#define __scc_enable() ( REG_SCC_CR |= SCC_CR_SCCE )
+#define __scc_disable() ( REG_SCC_CR &= ~SCC_CR_SCCE )
+
+#define __scc_set_tx_mode() ( REG_SCC_CR |= SCC_CR_TRS )
+#define __scc_set_rx_mode() ( REG_SCC_CR &= ~SCC_CR_TRS )
+
+#define __scc_enable_t2r() ( REG_SCC_CR |= SCC_CR_T2R )
+#define __scc_disable_t2r() ( REG_SCC_CR &= ~SCC_CR_T2R )
+
+#define __scc_clk_as_devclk() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_FDIV_MASK; \
+ REG_SCC_CR |= SCC_CR_FDIV_1; \
+} while (0)
+
+#define __scc_clk_as_half_devclk() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_FDIV_MASK; \
+ REG_SCC_CR |= SCC_CR_FDIV_2; \
+} while (0)
+
+/* n=1,4,8,14 */
+#define __scc_set_fifo_trigger(n) \
+do { \
+ REG_SCC_CR &= ~SCC_CR_TRIG_MASK; \
+ REG_SCC_CR |= SCC_CR_TRIG_##n; \
+} while (0)
+
+#define __scc_set_protocol(p) \
+do { \
+ if (p) \
+ REG_SCC_CR |= SCC_CR_TP; \
+ else \
+ REG_SCC_CR &= ~SCC_CR_TP; \
+} while (0)
+
+#define __scc_flush_fifo() ( REG_SCC_CR |= SCC_CR_FLUSH )
+
+#define __scc_set_invert_mode() ( REG_SCC_CR |= SCC_CR_CONV )
+#define __scc_set_direct_mode() ( REG_SCC_CR &= ~SCC_CR_CONV )
+
+#define SCC_ERR_INTRS \
+ ( SCC_CR_ECIE | SCC_CR_EPIE | SCC_CR_RETIE | SCC_CR_EOIE )
+#define SCC_ALL_INTRS \
+ ( SCC_CR_TXIE | SCC_CR_RXIE | SCC_CR_TENDIE | SCC_CR_RTOIE | \
+ SCC_CR_ECIE | SCC_CR_EPIE | SCC_CR_RETIE | SCC_CR_EOIE )
+
+#define __scc_enable_err_intrs() ( REG_SCC_CR |= SCC_ERR_INTRS )
+#define __scc_disable_err_intrs() ( REG_SCC_CR &= ~SCC_ERR_INTRS )
+
+#define SCC_ALL_ERRORS \
+ ( SCC_SR_ORER | SCC_SR_RTO | SCC_SR_PER | SCC_SR_RETR_3 | SCC_SR_ECNTO)
+
+#define __scc_clear_errors() ( REG_SCC_SR &= ~SCC_ALL_ERRORS )
+
+#define __scc_enable_all_intrs() ( REG_SCC_CR |= SCC_ALL_INTRS )
+#define __scc_disable_all_intrs() ( REG_SCC_CR &= ~SCC_ALL_INTRS )
+
+#define __scc_enable_tx_intr() ( REG_SCC_CR |= SCC_CR_TXIE | SCC_CR_TENDIE )
+#define __scc_disable_tx_intr() ( REG_SCC_CR &= ~(SCC_CR_TXIE | SCC_CR_TENDIE) )
+
+#define __scc_enable_rx_intr() ( REG_SCC_CR |= SCC_CR_RXIE)
+#define __scc_disable_rx_intr() ( REG_SCC_CR &= ~SCC_CR_RXIE)
+
+#define __scc_set_tsend() ( REG_SCC_CR |= SCC_CR_TSEND )
+#define __scc_clear_tsend() ( REG_SCC_CR &= ~SCC_CR_TSEND )
+
+#define __scc_set_clockstop() ( REG_SCC_CR |= SCC_CR_CLKSTP )
+#define __scc_clear_clockstop() ( REG_SCC_CR &= ~SCC_CR_CLKSTP )
+
+#define __scc_clockstop_low() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_PX_MASK; \
+ REG_SCC_CR |= SCC_CR_PX_STOP_LOW; \
+} while (0)
+
+#define __scc_clockstop_high() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_PX_MASK; \
+ REG_SCC_CR |= SCC_CR_PX_STOP_HIGH; \
+} while (0)
+
+/* SCC status checking */
+#define __scc_check_transfer_status() ( REG_SCC_SR & SCC_SR_TRANS )
+#define __scc_check_rx_overrun_error() ( REG_SCC_SR & SCC_SR_ORER )
+#define __scc_check_rx_timeout() ( REG_SCC_SR & SCC_SR_RTO )
+#define __scc_check_parity_error() ( REG_SCC_SR & SCC_SR_PER )
+#define __scc_check_txfifo_trigger() ( REG_SCC_SR & SCC_SR_TFTG )
+#define __scc_check_rxfifo_trigger() ( REG_SCC_SR & SCC_SR_RFTG )
+#define __scc_check_tx_end() ( REG_SCC_SR & SCC_SR_TEND )
+#define __scc_check_retx_3() ( REG_SCC_SR & SCC_SR_RETR_3 )
+#define __scc_check_ecnt_overflow() ( REG_SCC_SR & SCC_SR_ECNTO )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760SCC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760ssi.h b/arch/mips/include/asm/mach-jz4760/jz4760ssi.h
new file mode 100644
index 00000000000..f2b027b7b92
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760ssi.h
@@ -0,0 +1,350 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760ssi.h
+ *
+ * JZ4760 SSI register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760SSI_H__
+#define __JZ4760SSI_H__
+
+
+#define SSI0_BASE 0xB0043000
+#define SSI1_BASE 0xB0044000
+#define SSI2_BASE 0xB0045000
+
+
+
+/*************************************************************************
+ * SSI (Synchronous Serial Interface)
+ *************************************************************************/
+/* n = 0, 1 (SSI0, SSI1) */
+#define SSI_DR(n) (SSI0_BASE + 0x000 + (n)*0x2000)
+#define SSI_CR0(n) (SSI0_BASE + 0x004 + (n)*0x2000)
+#define SSI_CR1(n) (SSI0_BASE + 0x008 + (n)*0x2000)
+#define SSI_SR(n) (SSI0_BASE + 0x00C + (n)*0x2000)
+#define SSI_ITR(n) (SSI0_BASE + 0x010 + (n)*0x2000)
+#define SSI_ICR(n) (SSI0_BASE + 0x014 + (n)*0x2000)
+#define SSI_GR(n) (SSI0_BASE + 0x018 + (n)*0x2000)
+
+#define REG_SSI_DR(n) REG32(SSI_DR(n))
+#define REG_SSI_CR0(n) REG16(SSI_CR0(n))
+#define REG_SSI_CR1(n) REG32(SSI_CR1(n))
+#define REG_SSI_SR(n) REG32(SSI_SR(n))
+#define REG_SSI_ITR(n) REG16(SSI_ITR(n))
+#define REG_SSI_ICR(n) REG8(SSI_ICR(n))
+#define REG_SSI_GR(n) REG16(SSI_GR(n))
+
+/* SSI Data Register (SSI_DR) */
+
+#define SSI_DR_GPC_BIT 0
+#define SSI_DR_GPC_MASK (0x1ff << SSI_DR_GPC_BIT)
+
+#define SSI_MAX_FIFO_ENTRIES 128 /* 128 txfifo and 128 rxfifo */
+
+/* SSI Control Register 0 (SSI_CR0) */
+
+#define SSI_CR0_SSIE (1 << 15)
+#define SSI_CR0_TIE (1 << 14)
+#define SSI_CR0_RIE (1 << 13)
+#define SSI_CR0_TEIE (1 << 12)
+#define SSI_CR0_REIE (1 << 11)
+#define SSI_CR0_LOOP (1 << 10)
+#define SSI_CR0_RFINE (1 << 9)
+#define SSI_CR0_RFINC (1 << 8)
+#define SSI_CR0_EACLRUN (1 << 7) /* hardware auto clear underrun when TxFifo no empty */
+#define SSI_CR0_FSEL (1 << 6)
+#define SSI_CR0_TFLUSH (1 << 2)
+#define SSI_CR0_RFLUSH (1 << 1)
+#define SSI_CR0_DISREV (1 << 0)
+
+/* SSI Control Register 1 (SSI_CR1) */
+
+#define SSI_CR1_FRMHL_BIT 30
+#define SSI_CR1_FRMHL_MASK (0x3 << SSI_CR1_FRMHL_BIT)
+ #define SSI_CR1_FRMHL_CELOW_CE2LOW (0 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is low valid */
+ #define SSI_CR1_FRMHL_CEHIGH_CE2LOW (1 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is low valid */
+ #define SSI_CR1_FRMHL_CELOW_CE2HIGH (2 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is high valid */
+ #define SSI_CR1_FRMHL_CEHIGH_CE2HIGH (3 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is high valid */
+#define SSI_CR1_TFVCK_BIT 28
+#define SSI_CR1_TFVCK_MASK (0x3 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_0 (0 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_1 (1 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_2 (2 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_3 (3 << SSI_CR1_TFVCK_BIT)
+#define SSI_CR1_TCKFI_BIT 26
+#define SSI_CR1_TCKFI_MASK (0x3 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_0 (0 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_1 (1 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_2 (2 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_3 (3 << SSI_CR1_TCKFI_BIT)
+#define SSI_CR1_LFST (1 << 25)
+#define SSI_CR1_ITFRM (1 << 24)
+#define SSI_CR1_UNFIN (1 << 23)
+#define SSI_CR1_MULTS (1 << 22)
+#define SSI_CR1_FMAT_BIT 20
+#define SSI_CR1_FMAT_MASK (0x3 << SSI_CR1_FMAT_BIT)
+ #define SSI_CR1_FMAT_SPI (0 << SSI_CR1_FMAT_BIT) /* Motorola¡¯s SPI format */
+ #define SSI_CR1_FMAT_SSP (1 << SSI_CR1_FMAT_BIT) /* TI's SSP format */
+ #define SSI_CR1_FMAT_MW1 (2 << SSI_CR1_FMAT_BIT) /* National Microwire 1 format */
+ #define SSI_CR1_FMAT_MW2 (3 << SSI_CR1_FMAT_BIT) /* National Microwire 2 format */
+#define SSI_CR1_TTRG_BIT 16 /* SSI1 TX trigger */
+#define SSI_CR1_TTRG_MASK (0xf << SSI_CR1_TTRG_BIT)
+#define SSI_CR1_MCOM_BIT 12
+#define SSI_CR1_MCOM_MASK (0xf << SSI_CR1_MCOM_BIT)
+ #define SSI_CR1_MCOM_1BIT (0x0 << SSI_CR1_MCOM_BIT) /* 1-bit command selected */
+ #define SSI_CR1_MCOM_2BIT (0x1 << SSI_CR1_MCOM_BIT) /* 2-bit command selected */
+ #define SSI_CR1_MCOM_3BIT (0x2 << SSI_CR1_MCOM_BIT) /* 3-bit command selected */
+ #define SSI_CR1_MCOM_4BIT (0x3 << SSI_CR1_MCOM_BIT) /* 4-bit command selected */
+ #define SSI_CR1_MCOM_5BIT (0x4 << SSI_CR1_MCOM_BIT) /* 5-bit command selected */
+ #define SSI_CR1_MCOM_6BIT (0x5 << SSI_CR1_MCOM_BIT) /* 6-bit command selected */
+ #define SSI_CR1_MCOM_7BIT (0x6 << SSI_CR1_MCOM_BIT) /* 7-bit command selected */
+ #define SSI_CR1_MCOM_8BIT (0x7 << SSI_CR1_MCOM_BIT) /* 8-bit command selected */
+ #define SSI_CR1_MCOM_9BIT (0x8 << SSI_CR1_MCOM_BIT) /* 9-bit command selected */
+ #define SSI_CR1_MCOM_10BIT (0x9 << SSI_CR1_MCOM_BIT) /* 10-bit command selected */
+ #define SSI_CR1_MCOM_11BIT (0xA << SSI_CR1_MCOM_BIT) /* 11-bit command selected */
+ #define SSI_CR1_MCOM_12BIT (0xB << SSI_CR1_MCOM_BIT) /* 12-bit command selected */
+ #define SSI_CR1_MCOM_13BIT (0xC << SSI_CR1_MCOM_BIT) /* 13-bit command selected */
+ #define SSI_CR1_MCOM_14BIT (0xD << SSI_CR1_MCOM_BIT) /* 14-bit command selected */
+ #define SSI_CR1_MCOM_15BIT (0xE << SSI_CR1_MCOM_BIT) /* 15-bit command selected */
+ #define SSI_CR1_MCOM_16BIT (0xF << SSI_CR1_MCOM_BIT) /* 16-bit command selected */
+#define SSI_CR1_RTRG_BIT 8 /* SSI RX trigger */
+#define SSI_CR1_RTRG_MASK (0xf << SSI_CR1_RTRG_BIT)
+#define SSI_CR1_FLEN_BIT 4
+#define SSI_CR1_FLEN_MASK (0xf << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_2BIT (0x0 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_3BIT (0x1 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_4BIT (0x2 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_5BIT (0x3 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_6BIT (0x4 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_7BIT (0x5 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_8BIT (0x6 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_9BIT (0x7 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_10BIT (0x8 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_11BIT (0x9 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_12BIT (0xA << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_13BIT (0xB << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_14BIT (0xC << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_15BIT (0xD << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_16BIT (0xE << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_17BIT (0xF << SSI_CR1_FLEN_BIT)
+#define SSI_CR1_PHA (1 << 1)
+#define SSI_CR1_POL (1 << 0)
+
+/* SSI Status Register (SSI_SR) */
+
+#define SSI_SR_TFIFONUM_BIT 16
+#define SSI_SR_TFIFONUM_MASK (0xff << SSI_SR_TFIFONUM_BIT)
+#define SSI_SR_RFIFONUM_BIT 8
+#define SSI_SR_RFIFONUM_MASK (0xff << SSI_SR_RFIFONUM_BIT)
+#define SSI_SR_END (1 << 7)
+#define SSI_SR_BUSY (1 << 6)
+#define SSI_SR_TFF (1 << 5)
+#define SSI_SR_RFE (1 << 4)
+#define SSI_SR_TFHE (1 << 3)
+#define SSI_SR_RFHF (1 << 2)
+#define SSI_SR_UNDR (1 << 1)
+#define SSI_SR_OVER (1 << 0)
+
+/* SSI Interval Time Control Register (SSI_ITR) */
+
+#define SSI_ITR_CNTCLK (1 << 15)
+#define SSI_ITR_IVLTM_BIT 0
+#define SSI_ITR_IVLTM_MASK (0x7fff << SSI_ITR_IVLTM_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * SSI (Synchronous Serial Interface)
+ ***************************************************************************/
+/* n = 0, 1 (SSI0, SSI1) */
+#define __ssi_enable(n) ( REG_SSI_CR0(n) |= SSI_CR0_SSIE )
+#define __ssi_disable(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_SSIE )
+#define __ssi_select_ce(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_FSEL )
+
+#define __ssi_normal_mode(n) ( REG_SSI_ITR(n) &= ~SSI_ITR_IVLTM_MASK )
+
+#define __ssi_select_ce2(n) \
+do { \
+ REG_SSI_CR0(n) |= SSI_CR0_FSEL; \
+ REG_SSI_CR1(n) &= ~SSI_CR1_MULTS; \
+} while (0)
+
+#define __ssi_select_gpc(n) \
+do { \
+ REG_SSI_CR0(n) &= ~SSI_CR0_FSEL; \
+ REG_SSI_CR1(n) |= SSI_CR1_MULTS; \
+} while (0)
+
+#define __ssi_underrun_auto_clear(n) \
+do { \
+ REG_SSI_CR0(n) |= SSI_CR0_EACLRUN; \
+} while (0)
+
+#define __ssi_underrun_clear_manually(n) \
+do { \
+ REG_SSI_CR0(n) &= ~SSI_CR0_EACLRUN; \
+} while (0)
+
+#define __ssi_enable_tx_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TIE | SSI_CR0_TEIE )
+
+#define __ssi_disable_tx_intr(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_TIE | SSI_CR0_TEIE) )
+
+#define __ssi_enable_rx_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_RIE | SSI_CR0_REIE )
+
+#define __ssi_disable_rx_intr(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_RIE | SSI_CR0_REIE) )
+
+#define __ssi_enable_txfifo_half_empty_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TIE )
+#define __ssi_disable_txfifo_half_empty_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_TIE )
+#define __ssi_enable_tx_error_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TEIE )
+#define __ssi_disable_tx_error_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_TEIE )
+#define __ssi_enable_rxfifo_half_full_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_RIE )
+#define __ssi_disable_rxfifo_half_full_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_RIE )
+#define __ssi_enable_rx_error_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_REIE )
+#define __ssi_disable_rx_error_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_REIE )
+
+#define __ssi_enable_loopback(n) ( REG_SSI_CR0(n) |= SSI_CR0_LOOP )
+#define __ssi_disable_loopback(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_LOOP )
+
+#define __ssi_enable_receive(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_DISREV )
+#define __ssi_disable_receive(n) ( REG_SSI_CR0(n) |= SSI_CR0_DISREV )
+
+#define __ssi_finish_receive(n) \
+ ( REG_SSI_CR0(n) |= (SSI_CR0_RFINE | SSI_CR0_RFINC) )
+
+#define __ssi_disable_recvfinish(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_RFINE | SSI_CR0_RFINC) )
+
+#define __ssi_flush_txfifo(n) ( REG_SSI_CR0(n) |= SSI_CR0_TFLUSH )
+#define __ssi_flush_rxfifo(n) ( REG_SSI_CR0(n) |= SSI_CR0_RFLUSH )
+
+#define __ssi_flush_fifo(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TFLUSH | SSI_CR0_RFLUSH )
+
+#define __ssi_finish_transmit(n) ( REG_SSI_CR1(n) &= ~SSI_CR1_UNFIN )
+#define __ssi_wait_transmit(n) ( REG_SSI_CR1(n) |= SSI_CR1_UNFIN )
+#define __ssi_use_busy_wait_mode(n) __ssi_wait_transmit(n)
+#define __ssi_unset_busy_wait_mode(n) __ssi_finish_transmit(n)
+
+#define __ssi_spi_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_FMAT_MASK; \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_SPI; \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK); \
+ REG_SSI_CR1(n) |= (SSI_CR1_TFVCK_1 | SSI_CR1_TCKFI_1); \
+ } while (0)
+
+/* TI's SSP format, must clear SSI_CR1.UNFIN */
+#define __ssi_ssp_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_FMAT_MASK | SSI_CR1_UNFIN); \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_SSP; \
+ } while (0)
+
+/* National's Microwire format, must clear SSI_CR0.RFINE, and set max delay */
+#define __ssi_microwire_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_FMAT_MASK; \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_MW1; \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK); \
+ REG_SSI_CR1(n) |= (SSI_CR1_TFVCK_3 | SSI_CR1_TCKFI_3); \
+ REG_SSI_CR0(n) &= ~SSI_CR0_RFINE; \
+ } while (0)
+
+/* CE# level (FRMHL), CE# in interval time (ITFRM),
+ clock phase and polarity (PHA POL),
+ interval time (SSIITR), interval characters/frame (SSIICR) */
+
+/* frmhl,endian,mcom,flen,pha,pol MASK */
+#define SSICR1_MISC_MASK \
+ ( SSI_CR1_FRMHL_MASK | SSI_CR1_LFST | SSI_CR1_MCOM_MASK \
+ | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL )
+
+#define __ssi_spi_set_misc(n,frmhl,endian,flen,mcom,pha,pol) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSICR1_MISC_MASK; \
+ REG_SSI_CR1(n) |= ((frmhl) << 30) | ((endian) << 25) | \
+ (((mcom) - 1) << 12) | (((flen) - 2) << 4) | \
+ ((pha) << 1) | (pol); \
+ } while(0)
+
+/* Transfer with MSB or LSB first */
+#define __ssi_set_msb(n) ( REG_SSI_CR1(n) &= ~SSI_CR1_LFST )
+#define __ssi_set_lsb(n) ( REG_SSI_CR1(n) |= SSI_CR1_LFST )
+
+#define __ssi_set_frame_length(n, m) \
+ REG_SSI_CR1(n) = (REG_SSI_CR1(n) & ~SSI_CR1_FLEN_MASK) | (((m) - 2) << 4)
+
+/* m = 1 - 16 */
+#define __ssi_set_microwire_command_length(n,m) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_MCOM_MASK) | SSI_CR1_MCOM_##m##BIT) )
+
+/* Set the clock phase for SPI */
+#define __ssi_set_spi_clock_phase(n, m) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_PHA) | (((m)&0x1)<< 1)))
+
+/* Set the clock polarity for SPI */
+#define __ssi_set_spi_clock_polarity(n, p) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_POL) | ((p)&0x1)) )
+
+/* SSI tx trigger, m = i x 8 */
+#define __ssi_set_tx_trigger(n, m) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_TTRG_MASK; \
+ REG_SSI_CR1(n) |= ((m)/8)<<SSI_CR1_TTRG_BIT; \
+ } while (0)
+
+/* SSI rx trigger, m = i x 8 */
+#define __ssi_set_rx_trigger(n, m) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_RTRG_MASK; \
+ REG_SSI_CR1(n) |= ((m)/8)<<SSI_CR1_RTRG_BIT; \
+ } while (0)
+
+#define __ssi_get_txfifo_count(n) \
+ ( (REG_SSI_SR(n) & SSI_SR_TFIFONUM_MASK) >> SSI_SR_TFIFONUM_BIT )
+
+#define __ssi_get_rxfifo_count(n) \
+ ( (REG_SSI_SR(n) & SSI_SR_RFIFONUM_MASK) >> SSI_SR_RFIFONUM_BIT )
+
+#define __ssi_transfer_end(n) ( REG_SSI_SR(n) & SSI_SR_END )
+#define __ssi_is_busy(n) ( REG_SSI_SR(n) & SSI_SR_BUSY )
+
+#define __ssi_txfifo_full(n) ( REG_SSI_SR(n) & SSI_SR_TFF )
+#define __ssi_rxfifo_empty(n) ( REG_SSI_SR(n) & SSI_SR_RFE )
+#define __ssi_rxfifo_half_full(n) ( REG_SSI_SR(n) & SSI_SR_RFHF )
+#define __ssi_txfifo_half_empty(n) ( REG_SSI_SR(n) & SSI_SR_TFHE )
+#define __ssi_underrun(n) ( REG_SSI_SR(n) & SSI_SR_UNDR )
+#define __ssi_overrun(n) ( REG_SSI_SR(n) & SSI_SR_OVER )
+#define __ssi_clear_underrun(n) ( REG_SSI_SR(n) = ~SSI_SR_UNDR )
+#define __ssi_clear_overrun(n) ( REG_SSI_SR(n) = ~SSI_SR_OVER )
+#define __ssi_clear_errors(n) ( REG_SSI_SR(n) &= ~(SSI_SR_UNDR | SSI_SR_OVER) )
+
+#define __ssi_set_clk(n, dev_clk, ssi_clk) \
+ ( REG_SSI_GR(n) = (dev_clk) / (2*(ssi_clk)) - 1 )
+
+#define __ssi_receive_data(n) REG_SSI_DR(n)
+#define __ssi_transmit_data(n, v) (REG_SSI_DR(n) = (v))
+
+
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760SSI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760tcu.h b/arch/mips/include/asm/mach-jz4760/jz4760tcu.h
new file mode 100644
index 00000000000..9148be93926
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760tcu.h
@@ -0,0 +1,305 @@
+/*
+ * jz4760tcu.h
+ * JZ4760 TCU register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: fyliao@ingenic.cn
+ */
+
+#ifndef __JZ4760TCU_H__
+#define __JZ4760TCU_H__
+
+
+/*
+ * Timer and counter unit module(TCU) address definition
+ */
+#define TCU_BASE 0xb0002000
+
+/* TCU group offset */
+#define TCU_GOS 0x10
+
+/* TCU total channel number */
+#define TCU_CHANNEL_NUM 8
+
+
+/*
+ * TCU registers offset definition
+ */
+#define TCU_TER_OFFSET (0x10) /* r, 16, 0x0000 */
+#define TCU_TESR_OFFSET (0x14) /* w, 16, 0x???? */
+#define TCU_TECR_OFFSET (0x18) /* w, 16, 0x???? */
+#define TCU_TSR_OFFSET (0x1c) /* r, 32, 0x00000000 */
+#define TCU_TFR_OFFSET (0x20) /* r, 32, 0x003F003F */
+#define TCU_TFSR_OFFSET (0x24) /* w, 32, 0x???????? */
+#define TCU_TFCR_OFFSET (0x28) /* w, 32, 0x???????? */
+#define TCU_TSSR_OFFSET (0x2c) /* w, 32, 0x00000000 */
+#define TCU_TMR_OFFSET (0x30) /* r, 32, 0x00000000 */
+#define TCU_TMSR_OFFSET (0x34) /* w, 32, 0x???????? */
+#define TCU_TMCR_OFFSET (0x38) /* w, 32, 0x???????? */
+#define TCU_TSCR_OFFSET (0x3c) /* w, 32, 0x0000 */
+
+#define TCU_TDFR_OFFSET (0x40) /* rw,16, 0x???? */
+#define TCU_TDHR_OFFSET (0x44) /* rw,16, 0x???? */
+#define TCU_TCNT_OFFSET (0x48) /* rw,16, 0x???? */
+#define TCU_TCSR_OFFSET (0x4c) /* rw,16, 0x0000 */
+
+#define TCU_TSTR_OFFSET (0xf0) /* r, 32, 0x00000000 */
+#define TCU_TSTSR_OFFSET (0xf4) /* w, 32, 0x???????? */
+#define TCU_TSTCR_OFFSET (0xf8) /* w, 32, 0x???????? */
+
+
+/*
+ * TCU registers address definition
+ */
+#define TCU_TER (TCU_BASE + TCU_TER_OFFSET)
+#define TCU_TESR (TCU_BASE + TCU_TESR_OFFSET)
+#define TCU_TECR (TCU_BASE + TCU_TECR_OFFSET)
+#define TCU_TSR (TCU_BASE + TCU_TSR_OFFSET)
+#define TCU_TFR (TCU_BASE + TCU_TFR_OFFSET)
+#define TCU_TFSR (TCU_BASE + TCU_TFSR_OFFSET)
+#define TCU_TFCR (TCU_BASE + TCU_TFCR_OFFSET)
+#define TCU_TSSR (TCU_BASE + TCU_TSSR_OFFSET)
+#define TCU_TMR (TCU_BASE + TCU_TMR_OFFSET)
+#define TCU_TMSR (TCU_BASE + TCU_TMSR_OFFSET)
+#define TCU_TMCR (TCU_BASE + TCU_TMCR_OFFSET)
+#define TCU_TSCR (TCU_BASE + TCU_TSCR_OFFSET)
+#define TCU_TSTR (TCU_BASE + TCU_TSTR_OFFSET)
+#define TCU_TSTSR (TCU_BASE + TCU_TSTSR_OFFSET)
+#define TCU_TSTCR (TCU_BASE + TCU_TSTCR_OFFSET)
+
+/* n is the TCU channel index (0 - 7) */
+#define TCU_TDFR(n) (TCU_BASE + (n) * TCU_GOS + TCU_TDFR_OFFSET)
+#define TCU_TDHR(n) (TCU_BASE + (n) * TCU_GOS + TCU_TDHR_OFFSET)
+#define TCU_TCNT(n) (TCU_BASE + (n) * TCU_GOS + TCU_TCNT_OFFSET)
+#define TCU_TCSR(n) (TCU_BASE + (n) * TCU_GOS + TCU_TCSR_OFFSET)
+
+
+/*
+ * TCU registers bit field common define
+ */
+
+/* When n is NOT less than TCU_CHANNEL_NUM, change to TCU_CHANNEL_NUM - 1 */
+#define __TIMER(n) (1 << ((n) < TCU_CHANNEL_NUM ? (n) : (TCU_CHANNEL_NUM - 1))
+
+/* Timer counter enable register(TER) */
+#define TER_OSTEN BIT15
+#define TER_TCEN(n) __TIMER(n)
+
+/* Timer counter enable set register(TESR) */
+#define TESR_OST BIT15
+#define TESR_TIMER(n) __TIMER(n)
+
+/* Timer counter enable clear register(TECR) */
+#define TECR_OST BIT15
+#define TECR_TIMER(n) __TIMER(n)
+
+/* Timer stop register(TSR) */
+#define TSR_WDT_STOP BIT16
+#define TSR_OST_STOP BIT15
+#define TSR_TIMER_STOP(n) __TIMER(n)
+
+/* Timer stop set register(TSSR) */
+#define TSSR_WDT BIT16
+#define TSSR_OST BIT15
+#define TSSR_TIMER(n) __TIMER(n)
+
+/* Timer stop clear register(TSCR) */
+#define TSCR_WDT BIT16
+#define TSCR_OST BIT15
+#define TSSR_TIMER(n) __TIMER(n)
+
+/* Timer flag register(TFR) */
+#define TFR_HFLAG(n) (__TIMER(n) << 16)
+#define TFR_OSTFLAG BIT15
+#define TFR_FFLAG(n) __TIMER(n)
+
+/* Timer flag set register(TFSR) */
+#define TFSR_HFLAG(n) (__TIMER(n) << 16)
+#define TFSR_OSTFLAG BIT15
+#define TFSR_FFLAG(n) __TIMER(n)
+
+/* Timer flag clear register(TFCR) */
+#define TFCR_HFLAG(n) (__TIMER(n) << 16)
+#define TFCR_OSTFLAG BIT15
+#define TFCR_FFLAG(n) (__TIMER(n))
+
+/* Timer mast register(TMR) */
+#define TMR_HMASK(n) (__TIMER(n) << 16)
+#define TMR_OSTMASK BIT15
+#define TMR_FMASK(n) (__TIMER(n))
+
+/* Timer mask set register(TMSR) */
+#define TMSR_HMASK(n) (__TIMER(n) << 16)
+#define TMSR_OSTMASK BIT15
+#define TMSR_FMASK(n) (__TIMER(n))
+
+/* Timer mask clear register(TMCR) */
+#define TMCR_HMASK(n) (__TIMER(n) << 16)
+#define TMCR_OSTMASK BIT15
+#define TMCR_FMASK(n) (__TIMER(n))
+
+/* Timer control register(TCSR) */
+#define TCSR_CLRZ BIT10
+#define TCSR_SD_ABRUPT BIT9
+#define TCSR_INITL_HIGH BIT8
+#define TCSR_PWM_EN BIT7
+#define TCSR_PWM_IN_EN BIT6
+#define TCSR_EXT_EN BIT2
+#define TCSR_RTC_EN BIT1
+#define TCSR_PCK_EN BIT0
+
+#define TCSR_PRESCALE_LSB 3
+#define TCSR_PRESCALE_MASK BITS_H2L(5, TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE1 (0x0 << TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE4 (0x1 << TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE16 (0x2 << TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE64 (0x3 << TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE256 (0x4 << TCSR_PRESCALE_LSB)
+#define TCSR_PRESCALE1024 (0x5 << TCSR_PRESCALE_LSB)
+
+/* Timer data full register(TDFR) */
+#define TDFR_TDFR_LSB 0
+#define TDFR_TDFR_MASK BITS_H2L(15, TDFR_TDFR_LSB)
+
+/* Timer data half register(TDHR) */
+#define TDHR_TDHR_LSB 0
+#define TDHR_TDHR_MASK BITS_H2L(15, TDHR_TDHR_LSB)
+
+/* Timer counter register(TCNT) */
+#define TCNT_TCNT_LSB 0
+#define TCNT_TCNT_MASK BITS_H2L(15, TCNT_TCNT_LSB)
+
+/* Timer status register(TSTR) */
+#define TSTR_REAL2 BIT18
+#define TSTR_REAL1 BIT17
+#define TSTR_BUSY2 BIT2
+#define TSTR_BUSY1 BIT1
+
+/* Timer status set register(TSTSR) */
+#define TSTSR_REALS2 BIT18
+#define TSTSR_REALS1 BIT17
+#define TSTSR_BUSYS2 BIT2
+#define TSTSR_BUSYS1 BIT1
+
+/* Timer status clear register(TSTCR) */
+#define TSTCR_REALC2 BIT18
+#define TSTCR_REALC1 BIT17
+#define TSTCR_BUSYC2 BIT2
+#define TSTCR_BUSYC1 BIT1
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_TCU_TER REG16(TCU_TER)
+#define REG_TCU_TESR REG16(TCU_TESR)
+#define REG_TCU_TECR REG16(TCU_TECR)
+#define REG_TCU_TSR REG32(TCU_TSR)
+#define REG_TCU_TFR REG32(TCU_TFR)
+#define REG_TCU_TFSR REG32(TCU_TFSR)
+#define REG_TCU_TFCR REG32(TCU_TFCR)
+#define REG_TCU_TSSR REG32(TCU_TSSR)
+#define REG_TCU_TMR REG32(TCU_TMR)
+#define REG_TCU_TMSR REG32(TCU_TMSR)
+#define REG_TCU_TMCR REG32(TCU_TMCR)
+#define REG_TCU_TSCR REG32(TCU_TSCR)
+#define REG_TCU_TSTR REG32(TCU_TSTR)
+#define REG_TCU_TSTSR REG32(TCU_TSTSR)
+#define REG_TCU_TSTCR REG32(TCU_TSTCR)
+
+#define REG_TCU_TDFR(n) REG16(TCU_TDFR(n))
+#define REG_TCU_TDHR(n) REG16(TCU_TDHR(n))
+#define REG_TCU_TCNT(n) REG16(TCU_TCNT(n))
+#define REG_TCU_TCSR(n) REG16(TCU_TCSR(n))
+
+
+// where 'n' is the TCU channel
+#define __tcu_select_extalclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCSR_EXT_EN | TCSR_RTC_EN | TCSR_PCK_EN)) | TCSR_EXT_EN)
+#define __tcu_select_rtcclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCSR_EXT_EN | TCSR_RTC_EN | TCSR_PCK_EN)) | TCSR_RTC_EN)
+#define __tcu_select_pclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCSR_EXT_EN | TCSR_RTC_EN | TCSR_PCK_EN)) | TCSR_PCK_EN)
+#define __tcu_disable_pclk(n) \
+ REG_TCU_TCSR(n) = (REG_TCU_TCSR((n)) & ~TCSR_PCK_EN);
+#define __tcu_select_clk_div1(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE1)
+#define __tcu_select_clk_div4(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE4)
+#define __tcu_select_clk_div16(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE16)
+#define __tcu_select_clk_div64(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE64)
+#define __tcu_select_clk_div256(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE256)
+#define __tcu_select_clk_div1024(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCSR_PRESCALE_MASK) | TCSR_PRESCALE1024)
+
+#define __tcu_enable_pwm_output(n) (REG_TCU_TCSR((n)) |= TCSR_PWM_EN)
+#define __tcu_disable_pwm_output(n) (REG_TCU_TCSR((n)) &= ~TCSR_PWM_EN)
+
+#define __tcu_init_pwm_output_high(n) (REG_TCU_TCSR((n)) |= TCSR_INITL_HIGH)
+#define __tcu_init_pwm_output_low(n) (REG_TCU_TCSR((n)) &= ~TCSR_INITL_HIGH)
+
+#define __tcu_set_pwm_output_shutdown_graceful(n) (REG_TCU_TCSR((n)) &= ~TCSR_SD_ABRUPT)
+#define __tcu_set_pwm_output_shutdown_abrupt(n) (REG_TCU_TCSR((n)) |= TCSR_SD_ABRUPT)
+
+#define __tcu_clear_counter_to_zero(n) (REG_TCU_TCSR((n)) |= TCSR_CLRZ)
+
+#define __tcu_ost_enabled() (REG_TCU_TER & TER_OSTEN)
+#define __tcu_enable_ost() (REG_TCU_TESR = TESR_OST)
+#define __tcu_disable_ost() (REG_TCU_TECR = TECR_OST)
+
+#define __tcu_counter_enabled(n) (REG_TCU_TER & (1 << (n)))
+#define __tcu_start_counter(n) (REG_TCU_TESR |= (1 << (n)))
+#define __tcu_stop_counter(n) (REG_TCU_TECR |= (1 << (n)))
+
+#define __tcu_half_match_flag(n) (REG_TCU_TFR & (1 << ((n) + 16)))
+#define __tcu_full_match_flag(n) (REG_TCU_TFR & (1 << (n)))
+#define __tcu_set_half_match_flag(n) (REG_TCU_TFSR = (1 << ((n) + 16)))
+#define __tcu_set_full_match_flag(n) (REG_TCU_TFSR = (1 << (n)))
+#define __tcu_clear_half_match_flag(n) (REG_TCU_TFCR = (1 << ((n) + 16)))
+#define __tcu_clear_full_match_flag(n) (REG_TCU_TFCR = (1 << (n)))
+#define __tcu_mask_half_match_irq(n) (REG_TCU_TMSR = (1 << ((n) + 16)))
+#define __tcu_mask_full_match_irq(n) (REG_TCU_TMSR = (1 << (n)))
+#define __tcu_unmask_half_match_irq(n) (REG_TCU_TMCR = (1 << ((n) + 16)))
+#define __tcu_unmask_full_match_irq(n) (REG_TCU_TMCR = (1 << (n)))
+
+#define __tcu_ost_match_flag() (REG_TCU_TFR & TFR_OSTFLAG)
+#define __tcu_set_ost_match_flag() (REG_TCU_TFSR = TFSR_OSTFLAG)
+#define __tcu_clear_ost_match_flag() (REG_TCU_TFCR = TFCR_OSTFLAG)
+#define __tcu_ost_match_irq_masked() (REG_TCU_TMR & TMR_OSTMASK)
+#define __tcu_mask_ost_match_irq() (REG_TCU_TMSR = TMSR_OSTMASK)
+#define __tcu_unmask_ost_match_irq() (REG_TCU_TMCR = TMCR_OSTMASK)
+
+#define __tcu_wdt_clock_stopped() (REG_TCU_TSR & TSR_WDT_STOP)
+#define __tcu_ost_clock_stopped() (REG_TCU_TSR & TSR_OST_STOP)
+#define __tcu_timer_clock_stopped(n) (REG_TCU_TSR & (1 << (n)))
+
+#define __tcu_start_wdt_clock() (REG_TCU_TSCR = TSCR_WDT)
+#define __tcu_start_ost_clock() (REG_TCU_TSCR = TSCR_OST)
+#define __tcu_start_timer_clock(n) (REG_TCU_TSCR = (1 << (n)))
+
+#define __tcu_stop_wdt_clock() (REG_TCU_TSSR = TSSR_WDT)
+#define __tcu_stop_ost_clock() (REG_TCU_TSSR = TSSR_OST)
+#define __tcu_stop_timer_clock(n) (REG_TCU_TSSR = (1 << (n)))
+
+#define __tcu_get_count(n) (REG_TCU_TCNT((n)))
+#define __tcu_set_count(n,v) (REG_TCU_TCNT((n)) = (v))
+#define __tcu_set_full_data(n,v) (REG_TCU_TDFR((n)) = (v))
+#define __tcu_set_half_data(n,v) (REG_TCU_TDHR((n)) = (v))
+
+/* TCU2, counter 1, 2*/
+#define __tcu_read_real_value(n) (REG_TCU_TSTR & (1 << ((n) + 16)))
+#define __tcu_read_false_value(n) (REG_TCU_TSTR & (1 << ((n) + 16)))
+#define __tcu_counter_busy(n) (REG_TCU_TSTR & (1 << (n)))
+#define __tcu_counter_ready(n) (REG_TCU_TSTR & (1 << (n)))
+
+#define __tcu_set_read_real_value(n) (REG_TCU_TSTSR = (1 << ((n) + 16)))
+#define __tcu_set_read_false_value(n) (REG_TCU_TSTCR = (1 << ((n) + 16)))
+#define __tcu_set_counter_busy(n) (REG_TCU_TSTSR = (1 << (n)))
+#define __tcu_set_counter_ready(n) (REG_TCU_TSTCR = (1 << (n)))
+
+#endif /* __MIPS_ASSEMBLER */
+
+
+#endif /* __JZ4760TCU_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760tssi.h b/arch/mips/include/asm/mach-jz4760/jz4760tssi.h
new file mode 100644
index 00000000000..64209cbc3dd
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760tssi.h
@@ -0,0 +1,105 @@
+/*
+ * jz4760tssi.h
+ * JZ4760 TSSI register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760TSSI_H__
+#define __JZ4760TSSI_H__
+
+
+/*
+ * TS slave interface(TSSI) address definition
+ */
+#define TSSI_BASE 0xb0073000
+
+
+/*
+ * TS registers offset address definition
+ */
+#define TSSI_TSENA_OFFSET (0x00) /* rw, 8, 0x08 */
+#define TSSI_TSCFG_OFFSET (0x04) /* rw, 16, 0x04ff */
+#define TSSI_TSCTRL_OFFSET (0x08) /* rw, 8, 0x03 */
+#define TSSI_TSSTAT_OFFSET (0x0c) /* rw, 8, 0x00 */
+#define TSSI_TSFIFO_OFFSET (0x10) /* rw, 32, 0x???????? */
+#define TSSI_TSPEN_OFFSET (0x14) /* rw, 32, 0x00000000 */
+#define TSSI_TSNUM_OFFSET (0x18) /* rw, 8, 0x00 */
+#define TSSI_TSDTR_OFFSET (0x1c) /* rw, 8, 0x7f */
+#define TSSI_TSPID_OFFSET (0x20) /* rw, 32, 0x00000000 */
+
+
+/*
+ * TS registers address definition
+ */
+#define TSSI_TSENA (TSSI_BASE + TSSI_TSENA_OFFSET)
+#define TSSI_TSCFG (TSSI_BASE + TSSI_TSCFG_OFFSET)
+#define TSSI_TSCTRL (TSSI_BASE + TSSI_TSCTRL_OFFSET)
+#define TSSI_TSSTAT (TSSI_BASE + TSSI_TSSTAT_OFFSET)
+#define TSSI_TSFIFO (TSSI_BASE + TSSI_TSFIFO_OFFSET)
+#define TSSI_TSPEN (TSSI_BASE + TSSI_TSPEN_OFFSET)
+#define TSSI_TSNUM (TSSI_BASE + TSSI_TSNUM_OFFSET)
+#define TSSI_TSDTR (TSSI_BASE + TSSI_TSDTR_OFFSET)
+#define TSSI_TSPID(n) (TSSI_BASE + TSSI_TSPID_OFFSET + (n)*4) /* max n is 15 */
+
+
+/*
+ * TS registers common define
+ */
+
+/* TSSI enable register(TSENA) */
+#define TSENA_RESET BIT7
+#define TSENA_FAIL BIT4
+#define TSENA_PEN0 BIT3
+#define TSENA_PIDEN BIT2
+#define TSENA_DMAEN BIT1
+#define TSENA_ENA BIT0
+
+/* TSSI configure register(TSCFG) */
+#define TSCFG_EDNWD BIT9
+#define TSCFG_EDNBT BIT8
+#define TSCFG_TSDI_HIGH BIT7
+#define TSCFG_USE0 BIT6
+#define TSCFG_TSCLK BIT5
+#define TSCFG_PARAL BIT4
+#define TSCFG_CLKP BIT3
+#define TSCFG_FRM_HIGH BIT2
+#define TSCFG_STR_HIGH BIT1
+#define TSCFG_FAIL_HIGH BIT0
+
+#define TSCFG_TRIGV_LSB 14
+#define TSCFG_TRIGV_MASK BIT_H2L(15, TSCFG_TRIGV_LSB)
+#define TSCFG_TRIGV(n) (((n)/8) << TSCFG_TRIGV_LSB) /* n = 4, 8, 16 */
+
+#define TSCFG_TRANSMD_LSB 10
+#define TSCFG_TRANSMD_MASK BIT_H2L(11, TSCFG_TRANSMD_LSB)
+
+/* TSSI control register(TSCTRL) */
+#define TSCTRL_FDTRM BIT2
+#define TSCTRL_FOVERUNM BIT1
+#define TSCTRL_FTRIGM BIT0
+
+/* TSSI state register(TSSTAT) */
+#define TSSTAT_FDTR BIT2
+#define TSSTAT_FOVERUN BIT1
+#define TSSTAT_FTRIG BIT0
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_TSSI_TSENA REG8(TSSI_TSENA)
+#define REG_TSSI_TSCFG REG16(TSSI_TSCFG)
+#define REG_TSSI_TSCTRL REG8(TSSI_TSCTRL)
+#define REG_TSSI_TSSTAT REG8(TSSI_TSSTAT)
+#define REG_TSSI_TSFIFO REG32(TSSI_TSFIFO)
+#define REG_TSSI_TSPEN REG32(TSSI_TSPEN)
+#define REG_TSSI_TSNUM REG8(TSSI_TSNUM)
+#define REG_TSSI_TSDTR REG8(TSSI_TSDTR)
+#define REG_TSSI_TSPID(n) REG32(TSSI_TSPID(n))
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760TSSI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760tve.h b/arch/mips/include/asm/mach-jz4760/jz4760tve.h
new file mode 100644
index 00000000000..3e53fcdf298
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760tve.h
@@ -0,0 +1,396 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760tve.h
+ *
+ * JZ4760 TVE register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760TVE_H__
+#define __JZ4760TVE_H__
+
+
+#define TVE_BASE 0xB3050100
+
+
+
+/*************************************************************************
+ * TVE (TV Encoder Controller)
+ *************************************************************************/
+#define TVE_CTRL (TVE_BASE + 0x40) /* TV Encoder Control register */
+#define TVE_FRCFG (TVE_BASE + 0x44) /* Frame configure register */
+#define TVE_SLCFG1 (TVE_BASE + 0x50) /* TV signal level configure register 1 */
+#define TVE_SLCFG2 (TVE_BASE + 0x54) /* TV signal level configure register 2*/
+#define TVE_SLCFG3 (TVE_BASE + 0x58) /* TV signal level configure register 3*/
+#define TVE_LTCFG1 (TVE_BASE + 0x60) /* Line timing configure register 1 */
+#define TVE_LTCFG2 (TVE_BASE + 0x64) /* Line timing configure register 2 */
+#define TVE_CFREQ (TVE_BASE + 0x70) /* Chrominance sub-carrier frequency configure register */
+#define TVE_CPHASE (TVE_BASE + 0x74) /* Chrominance sub-carrier phase configure register */
+#define TVE_CBCRCFG (TVE_BASE + 0x78) /* Chrominance filter configure register */
+#define TVE_WSSCR (TVE_BASE + 0x80) /* Wide screen signal control register */
+#define TVE_WSSCFG1 (TVE_BASE + 0x84) /* Wide screen signal configure register 1 */
+#define TVE_WSSCFG2 (TVE_BASE + 0x88) /* Wide screen signal configure register 2 */
+#define TVE_WSSCFG3 (TVE_BASE + 0x8c) /* Wide screen signal configure register 3 */
+
+#define REG_TVE_CTRL REG32(TVE_CTRL)
+#define REG_TVE_FRCFG REG32(TVE_FRCFG)
+#define REG_TVE_SLCFG1 REG32(TVE_SLCFG1)
+#define REG_TVE_SLCFG2 REG32(TVE_SLCFG2)
+#define REG_TVE_SLCFG3 REG32(TVE_SLCFG3)
+#define REG_TVE_LTCFG1 REG32(TVE_LTCFG1)
+#define REG_TVE_LTCFG2 REG32(TVE_LTCFG2)
+#define REG_TVE_CFREQ REG32(TVE_CFREQ)
+#define REG_TVE_CPHASE REG32(TVE_CPHASE)
+#define REG_TVE_CBCRCFG REG32(TVE_CBCRCFG)
+#define REG_TVE_WSSCR REG32(TVE_WSSCR)
+#define REG_TVE_WSSCFG1 REG32(TVE_WSSCFG1)
+#define REG_TVE_WSSCFG2 REG32(TVE_WSSCFG2)
+#define REG_TVE_WSSCFG3 REG32(TVE_WSSCFG3)
+
+/* TV Encoder Control register */
+#define TVE_CTRL_EYCBCR (1 << 25) /* YCbCr_enable */
+#define TVE_CTRL_ECVBS (1 << 24) /* 1: cvbs_enable 0: s-video*/
+#define TVE_CTRL_DAPD3 (1 << 23) /* DAC 3 power down */
+#define TVE_CTRL_DAPD2 (1 << 22) /* DAC 2 power down */
+#define TVE_CTRL_DAPD1 (1 << 21) /* DAC 1 power down */
+#define TVE_CTRL_DAPD (1 << 20) /* power down all DACs */
+#define TVE_CTRL_YCDLY_BIT 16
+#define TVE_CTRL_YCDLY_MASK (0x7 << TVE_CTRL_YCDLY_BIT)
+#define TVE_CTRL_CGAIN_BIT 14
+#define TVE_CTRL_CGAIN_MASK (0x3 << TVE_CTRL_CGAIN_BIT)
+ #define TVE_CTRL_CGAIN_FULL (0 << TVE_CTRL_CGAIN_BIT) /* gain = 1 */
+ #define TVE_CTRL_CGAIN_QUTR (1 << TVE_CTRL_CGAIN_BIT) /* gain = 1/4 */
+ #define TVE_CTRL_CGAIN_HALF (2 << TVE_CTRL_CGAIN_BIT) /* gain = 1/2 */
+ #define TVE_CTRL_CGAIN_THREE_QURT (3 << TVE_CTRL_CGAIN_BIT) /* gain = 3/4 */
+#define TVE_CTRL_CBW_BIT 12
+#define TVE_CTRL_CBW_MASK (0x3 << TVE_CTRL_CBW_BIT)
+ #define TVE_CTRL_CBW_NARROW (0 << TVE_CTRL_CBW_BIT) /* Narrow band */
+ #define TVE_CTRL_CBW_WIDE (1 << TVE_CTRL_CBW_BIT) /* Wide band */
+ #define TVE_CTRL_CBW_EXTRA (2 << TVE_CTRL_CBW_BIT) /* Extra wide band */
+ #define TVE_CTRL_CBW_ULTRA (3 << TVE_CTRL_CBW_BIT) /* Ultra wide band */
+#define TVE_CTRL_SYNCT (1 << 9)
+#define TVE_CTRL_PAL (1 << 8) /* 1: PAL, 0: NTSC */
+#define TVE_CTRL_FINV (1 << 7) /* invert_top:1-invert top and bottom fields. */
+#define TVE_CTRL_ZBLACK (1 << 6) /* bypass_yclamp:1-Black of luminance (Y) input is 0.*/
+#define TVE_CTRL_CR1ST (1 << 5) /* uv_order:0-Cb before Cr,1-Cr before Cb */
+#define TVE_CTRL_CLBAR (1 << 4) /* Color bar mode:0-Output input video to TV,1-Output color bar to TV */
+#define TVE_CTRL_SWRST (1 << 0) /* Software reset:1-TVE is reset */
+
+/* Signal level configure register 1 */
+#define TVE_SLCFG1_BLACKL_BIT 0
+#define TVE_SLCFG1_BLACKL_MASK (0x3ff << TVE_SLCFG1_BLACKL_BIT)
+#define TVE_SLCFG1_WHITEL_BIT 16
+#define TVE_SLCFG1_WHITEL_MASK (0x3ff << TVE_SLCFG1_WHITEL_BIT)
+
+/* Signal level configure register 2 */
+#define TVE_SLCFG2_BLANKL_BIT 0
+#define TVE_SLCFG2_BLANKL_MASK (0x3ff << TVE_SLCFG2_BLANKL_BIT)
+#define TVE_SLCFG2_VBLANKL_BIT 16
+#define TVE_SLCFG2_VBLANKL_MASK (0x3ff << TVE_SLCFG2_VBLANKL_BIT)
+
+/* Signal level configure register 3 */
+#define TVE_SLCFG3_SYNCL_BIT 0
+#define TVE_SLCFG3_SYNCL_MASK (0xff << TVE_SLCFG3_SYNCL_BIT)
+
+/* Line timing configure register 1 */
+#define TVE_LTCFG1_BACKP_BIT 0
+#define TVE_LTCFG1_BACKP_MASK (0x7f << TVE_LTCFG1_BACKP_BIT)
+#define TVE_LTCFG1_HSYNCW_BIT 8
+#define TVE_LTCFG1_HSYNCW_MASK (0x7f << TVE_LTCFG1_HSYNCW_BIT)
+#define TVE_LTCFG1_FRONTP_BIT 16
+#define TVE_LTCFG1_FRONTP_MASK (0x1f << TVE_LTCFG1_FRONTP_BIT)
+
+/* Line timing configure register 2 */
+#define TVE_LTCFG2_BURSTW_BIT 0
+#define TVE_LTCFG2_BURSTW_MASK (0x3f << TVE_LTCFG2_BURSTW_BIT)
+#define TVE_LTCFG2_PREBW_BIT 8
+#define TVE_LTCFG2_PREBW_MASK (0x1f << TVE_LTCFG2_PREBW_BIT)
+#define TVE_LTCFG2_ACTLIN_BIT 16
+#define TVE_LTCFG2_ACTLIN_MASK (0x7ff << TVE_LTCFG2_ACTLIN_BIT)
+
+/* Chrominance sub-carrier phase configure register */
+#define TVE_CPHASE_CCRSTP_BIT 0
+#define TVE_CPHASE_CCRSTP_MASK (0x3 << TVE_CPHASE_CCRSTP_BIT)
+ #define TVE_CPHASE_CCRSTP_8 (0 << TVE_CPHASE_CCRSTP_BIT) /* Every 8 field */
+ #define TVE_CPHASE_CCRSTP_4 (1 << TVE_CPHASE_CCRSTP_BIT) /* Every 4 field */
+ #define TVE_CPHASE_CCRSTP_2 (2 << TVE_CPHASE_CCRSTP_BIT) /* Every 2 lines */
+ #define TVE_CPHASE_CCRSTP_0 (3 << TVE_CPHASE_CCRSTP_BIT) /* Never */
+#define TVE_CPHASE_ACTPH_BIT 16
+#define TVE_CPHASE_ACTPH_MASK (0xff << TVE_CPHASE_ACTPH_BIT)
+#define TVE_CPHASE_INITPH_BIT 24
+#define TVE_CPHASE_INITPH_MASK (0xff << TVE_CPHASE_INITPH_BIT)
+
+/* Chrominance filter configure register */
+#define TVE_CBCRCFG_CRGAIN_BIT 0
+#define TVE_CBCRCFG_CRGAIN_MASK (0xff << TVE_CBCRCFG_CRGAIN_BIT)
+#define TVE_CBCRCFG_CBGAIN_BIT 8
+#define TVE_CBCRCFG_CBGAIN_MASK (0xff << TVE_CBCRCFG_CBGAIN_BIT)
+#define TVE_CBCRCFG_CRBA_BIT 16
+#define TVE_CBCRCFG_CRBA_MASK (0xff << TVE_CBCRCFG_CRBA_BIT)
+#define TVE_CBCRCFG_CBBA_BIT 24
+#define TVE_CBCRCFG_CBBA_MASK (0xff << TVE_CBCRCFG_CBBA_BIT)
+
+/* Frame configure register */
+#define TVE_FRCFG_NLINE_BIT 0
+#define TVE_FRCFG_NLINE_MASK (0x3ff << TVE_FRCFG_NLINE_BIT)
+#define TVE_FRCFG_L1ST_BIT 16
+#define TVE_FRCFG_L1ST_MASK (0xff << TVE_FRCFG_L1ST_BIT)
+
+/* Wide screen signal control register */
+#define TVE_WSSCR_EWSS0_BIT 0
+#define TVE_WSSCR_EWSS1_BIT 1
+#define TVE_WSSCR_WSSTP_BIT 2
+#define TVE_WSSCR_WSSCKBP_BIT 3
+#define TVE_WSSCR_WSSEDGE_BIT 4
+#define TVE_WSSCR_WSSEDGE_MASK (0x7 << TVE_WSSCR_WSSEDGE_BIT)
+#define TVE_WSSCR_ENCH_BIT 8
+#define TVE_WSSCR_NCHW_BIT 9
+#define TVE_WSSCR_NCHFREQ_BIT 12
+#define TVE_WSSCR_NCHFREQ_MASK (0x7 << TVE_WSSCR_NCHFREQ_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * TVE (TV Encoder Controller) ops
+ *************************************************************************/
+/* TV Encoder Control register ops */
+#define __tve_soft_reset() (REG_TVE_CTRL |= TVE_CTRL_SWRST)
+
+#define __tve_output_colorbar() (REG_TVE_CTRL |= TVE_CTRL_CLBAR)
+#define __tve_output_video() (REG_TVE_CTRL &= ~TVE_CTRL_CLBAR)
+
+#define __tve_input_cr_first() (REG_TVE_CTRL |= TVE_CTRL_CR1ST)
+#define __tve_input_cb_first() (REG_TVE_CTRL &= ~TVE_CTRL_CR1ST)
+
+#define __tve_set_0_as_black() (REG_TVE_CTRL |= TVE_CTRL_ZBLACK)
+#define __tve_set_16_as_black() (REG_TVE_CTRL &= ~TVE_CTRL_ZBLACK)
+
+#define __tve_ena_invert_top_bottom() (REG_TVE_CTRL |= TVE_CTRL_FINV)
+#define __tve_dis_invert_top_bottom() (REG_TVE_CTRL &= ~TVE_CTRL_FINV)
+
+#define __tve_set_pal_mode() (REG_TVE_CTRL |= TVE_CTRL_PAL)
+#define __tve_set_ntsc_mode() (REG_TVE_CTRL &= ~TVE_CTRL_PAL)
+
+#define __tve_set_pal_dura() (REG_TVE_CTRL |= TVE_CTRL_SYNCT)
+#define __tve_set_ntsc_dura() (REG_TVE_CTRL &= ~TVE_CTRL_SYNCT)
+
+/* n = 0 ~ 3 */
+#define __tve_set_c_bandwidth(n) \
+do {\
+ REG_TVE_CTRL &= ~TVE_CTRL_CBW_MASK;\
+ REG_TVE_CTRL |= (n) << TVE_CTRL_CBW_BIT; \
+}while(0)
+
+/* n = 0 ~ 3 */
+#define __tve_set_c_gain(n) \
+do {\
+ REG_TVE_CTRL &= ~TVE_CTRL_CGAIN_MASK;\
+ (REG_TVE_CTRL |= (n) << TVE_CTRL_CGAIN_BIT; \
+}while(0)
+
+/* n = 0 ~ 7 */
+#define __tve_set_yc_delay(n) \
+do { \
+ REG_TVE_CTRL &= ~TVE_CTRL_YCDLY_MASK \
+ REG_TVE_CTRL |= ((n) << TVE_CTRL_YCDLY_BIT); \
+} while(0)
+
+#define __tve_disable_all_dacs() (REG_TVE_CTRL |= TVE_CTRL_DAPD)
+#define __tve_disable_dac1() (REG_TVE_CTRL |= TVE_CTRL_DAPD1)
+#define __tve_enable_dac1() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD1)
+#define __tve_disable_dac2() (REG_TVE_CTRL |= TVE_CTRL_DAPD2)
+#define __tve_enable_dac2() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD2)
+#define __tve_disable_dac3() (REG_TVE_CTRL |= TVE_CTRL_DAPD3)
+#define __tve_enable_dac3() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD3)
+
+#define __tve_enable_svideo_fmt() (REG_TVE_CTRL |= TVE_CTRL_ECVBS)
+#define __tve_enable_cvbs_fmt() (REG_TVE_CTRL &= ~TVE_CTRL_ECVBS)
+
+/* TV Encoder Frame Configure register ops */
+/* n = 0 ~ 255 */
+#define __tve_set_first_video_line(n) \
+do {\
+ REG_TVE_FRCFG &= ~TVE_FRCFG_L1ST_MASK;\
+ REG_TVE_FRCFG |= (n) << TVE_FRCFG_L1ST_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_line_num_per_frm(n) \
+do {\
+ REG_TVE_FRCFG &= ~TVE_FRCFG_NLINE_MASK;\
+ REG_TVE_CFG |= (n) << TVE_FRCFG_NLINE_BIT;\
+} while(0)
+#define __tve_get_video_line_num()\
+ (((REG_TVE_FRCFG & TVE_FRCFG_NLINE_MASK) >> TVE_FRCFG_NLINE_BIT) - 1 - 2 * ((REG_TVE_FRCFG & TVE_FRCFG_L1ST_MASK) >> TVE_FRCFG_L1ST_BIT))
+
+/* TV Encoder Signal Level Configure register ops */
+/* n = 0 ~ 1023 */
+#define __tve_set_white_level(n) \
+do {\
+ REG_TVE_SLCFG1 &= ~TVE_SLCFG1_WHITEL_MASK;\
+ REG_TVE_SLCFG1 |= (n) << TVE_SLCFG1_WHITEL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_black_level(n) \
+do {\
+ REG_TVE_SLCFG1 &= ~TVE_SLCFG1_BLACKL_MASK;\
+ REG_TVE_SLCFG1 |= (n) << TVE_SLCFG1_BLACKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_blank_level(n) \
+do {\
+ REG_TVE_SLCFG2 &= ~TVE_SLCFG2_BLANKL_MASK;\
+ REG_TVE_SLCFG2 |= (n) << TVE_SLCFG2_BLANKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_vbi_blank_level(n) \
+do {\
+ REG_TVE_SLCFG2 &= ~TVE_SLCFG2_VBLANKL_MASK;\
+ REG_TVE_SLCFG2 |= (n) << TVE_SLCFG2_VBLANKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_sync_level(n) \
+do {\
+ REG_TVE_SLCFG3 &= ~TVE_SLCFG3_SYNCL_MASK;\
+ REG_TVE_SLCFG3 |= (n) << TVE_SLCFG3_SYNCL_BIT;\
+} while(0)
+
+/* TV Encoder Signal Level Configure register ops */
+/* n = 0 ~ 31 */
+#define __tve_set_front_porch(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_FRONTP_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_FRONTP_BIT; \
+} while(0)
+/* n = 0 ~ 127 */
+#define __tve_set_hsync_width(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_HSYNCW_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_HSYNCW_BIT; \
+} while(0)
+/* n = 0 ~ 127 */
+#define __tve_set_back_porch(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_BACKP_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_BACKP_BIT; \
+} while(0)
+/* n = 0 ~ 2047 */
+#define __tve_set_active_linec(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_ACTLIN_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_ACTLIN_BIT; \
+} while(0)
+/* n = 0 ~ 31 */
+#define __tve_set_breezy_way(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_PREBW_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_PREBW_BIT; \
+} while(0)
+
+/* n = 0 ~ 127 */
+#define __tve_set_burst_width(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_BURSTW_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_BURSTW_BIT; \
+} while(0)
+
+/* TV Encoder Chrominance filter and Modulation register ops */
+/* n = 0 ~ (2^32-1) */
+#define __tve_set_c_sub_carrier_freq(n) REG_TVE_CFREQ = (n)
+/* n = 0 ~ 255 */
+#define __tve_set_c_sub_carrier_init_phase(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_INITPH_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_INITPH_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_c_sub_carrier_act_phase(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_ACTPH_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_ACTPH_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_c_phase_rst_period(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_CCRSTP_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_CCRSTP_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cb_burst_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CBBA_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CBBA_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cr_burst_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CRBA_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CRBA_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cb_gain_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CBGAIN_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CBGAIN_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cr_gain_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CRGAIN_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CRGAIN_BIT; \
+} while(0)
+
+/* TV Encoder Wide Screen Signal Control register ops */
+/* n = 0 ~ 7 */
+#define __tve_set_notch_freq(n) \
+do { \
+ REG_TVE_WSSCR &= ~TVE_WSSCR_NCHFREQ_MASK; \
+ REG_TVE_WSSCR |= (n) << TVE_WSSCR_NCHFREQ_BIT; \
+} while(0)
+/* n = 0 ~ 7 */
+#define __tve_set_notch_width() (REG_TVE_WSSCR |= TVE_WSSCR_NCHW_BIT)
+#define __tve_clear_notch_width() (REG_TVE_WSSCR &= ~TVE_WSSCR_NCHW_BIT)
+#define __tve_enable_notch() (REG_TVE_WSSCR |= TVE_WSSCR_ENCH_BIT)
+#define __tve_disable_notch() (REG_TVE_WSSCR &= ~TVE_WSSCR_ENCH_BIT)
+/* n = 0 ~ 7 */
+#define __tve_set_wss_edge(n) \
+do { \
+ REG_TVE_WSSCR &= ~TVE_WSSCR_WSSEDGE_MASK; \
+ REG_TVE_WSSCR |= (n) << TVE_WSSCR_WSSEDGE_BIT; \
+} while(0)
+#define __tve_set_wss_clkbyp() (REG_TVE_WSSCR |= TVE_WSSCR_WSSCKBP_BIT)
+#define __tve_set_wss_type() (REG_TVE_WSSCR |= TVE_WSSCR_WSSTP_BIT)
+#define __tve_enable_wssf1() (REG_TVE_WSSCR |= TVE_WSSCR_EWSS1_BIT)
+#define __tve_enable_wssf0() (REG_TVE_WSSCR |= TVE_WSSCR_EWSS0_BIT)
+
+/* TV Encoder Wide Screen Signal Configure register 1, 2 and 3 ops */
+/* n = 0 ~ 1023 */
+#define __tve_set_wss_level(n) \
+do { \
+ REG_TVE_WSSCFG1 &= ~TVE_WSSCFG1_WSSL_MASK; \
+ REG_TVE_WSSCFG1 |= (n) << TVE_WSSCFG1_WSSL_BIT; \
+} while(0)
+/* n = 0 ~ 4095 */
+#define __tve_set_wss_freq(n) \
+do { \
+ REG_TVE_WSSCFG1 &= ~TVE_WSSCFG1_WSSFREQ_MASK; \
+ REG_TVE_WSSCFG1 |= (n) << TVE_WSSCFG1_WSSFREQ_BIT; \
+} while(0)
+/* n = 0, 1; l = 0 ~ 255 */
+#define __tve_set_wss_line(n,v) \
+do { \
+ REG_TVE_WSSCFG##n &= ~TVE_WSSCFG_WSSLINE_MASK; \
+ REG_TVE_WSSCFG##n |= (v) << TVE_WSSCFG_WSSLINE_BIT; \
+} while(0)
+/* n = 0, 1; d = 0 ~ (2^20-1) */
+#define __tve_set_wss_data(n, v) \
+do { \
+ REG_TVE_WSSCFG##n &= ~TVE_WSSCFG_WSSLINE_MASK; \
+ REG_TVE_WSSCFG##n |= (v) << TVE_WSSCFG_WSSLINE_BIT; \
+} while(0)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760TVE_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760uart.h b/arch/mips/include/asm/mach-jz4760/jz4760uart.h
new file mode 100644
index 00000000000..ed3151e6835
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760uart.h
@@ -0,0 +1,280 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760uart.h
+ *
+ * JZ4760 UART register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760UART_H__
+#define __JZ4760UART_H__
+
+
+#define UART0_BASE 0xB0030000
+#define UART1_BASE 0xB0031000
+#define UART2_BASE 0xB0032000
+#define UART3_BASE 0xB0033000
+
+/*************************************************************************
+ * 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 UART1_RDR (UART1_BASE + OFF_RDR)
+#define UART1_TDR (UART1_BASE + OFF_TDR)
+#define UART1_DLLR (UART1_BASE + OFF_DLLR)
+#define UART1_DLHR (UART1_BASE + OFF_DLHR)
+#define UART1_IER (UART1_BASE + OFF_IER)
+#define UART1_ISR (UART1_BASE + OFF_ISR)
+#define UART1_FCR (UART1_BASE + OFF_FCR)
+#define UART1_LCR (UART1_BASE + OFF_LCR)
+#define UART1_MCR (UART1_BASE + OFF_MCR)
+#define UART1_LSR (UART1_BASE + OFF_LSR)
+#define UART1_MSR (UART1_BASE + OFF_MSR)
+#define UART1_SPR (UART1_BASE + OFF_SPR)
+#define UART1_SIRCR (UART1_BASE + OFF_SIRCR)
+
+#define UART2_RDR (UART2_BASE + OFF_RDR)
+#define UART2_TDR (UART2_BASE + OFF_TDR)
+#define UART2_DLLR (UART2_BASE + OFF_DLLR)
+#define UART2_DLHR (UART2_BASE + OFF_DLHR)
+#define UART2_IER (UART2_BASE + OFF_IER)
+#define UART2_ISR (UART2_BASE + OFF_ISR)
+#define UART2_FCR (UART2_BASE + OFF_FCR)
+#define UART2_LCR (UART2_BASE + OFF_LCR)
+#define UART2_MCR (UART2_BASE + OFF_MCR)
+#define UART2_LSR (UART2_BASE + OFF_LSR)
+#define UART2_MSR (UART2_BASE + OFF_MSR)
+#define UART2_SPR (UART2_BASE + OFF_SPR)
+#define UART2_SIRCR (UART2_BASE + OFF_SIRCR)
+
+#define UART3_RDR (UART3_BASE + OFF_RDR)
+#define UART3_TDR (UART3_BASE + OFF_TDR)
+#define UART3_DLLR (UART3_BASE + OFF_DLLR)
+#define UART3_DLHR (UART3_BASE + OFF_DLHR)
+#define UART3_IER (UART3_BASE + OFF_IER)
+#define UART3_ISR (UART3_BASE + OFF_ISR)
+#define UART3_FCR (UART3_BASE + OFF_FCR)
+#define UART3_LCR (UART3_BASE + OFF_LCR)
+#define UART3_MCR (UART3_BASE + OFF_MCR)
+#define UART3_LSR (UART3_BASE + OFF_LSR)
+#define UART3_MSR (UART3_BASE + OFF_MSR)
+#define UART3_SPR (UART3_BASE + OFF_SPR)
+#define UART3_SIRCR (UART3_BASE + OFF_SIRCR)
+
+
+/*
+ * 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_FCM (1 << 6) /* 0: software 1: hardware */
+#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 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * UART
+ ***************************************************************************/
+#define __jtag_as_uart3() \
+do { \
+ REG_GPIO_PXSELC(0) = 0x40000000; \
+ REG_GPIO_PXSELS(0) = 0x80000000; \
+} while(0)
+
+#define __uart_enable(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) |= UARTFCR_UUE | UARTFCR_FE )
+#define __uart_disable(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) = ~UARTFCR_UUE )
+
+#define __uart_enable_transmit_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_TIE )
+#define __uart_disable_transmit_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~UARTIER_TIE )
+
+#define __uart_enable_receive_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE )
+#define __uart_disable_receive_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~(UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE) )
+
+#define __uart_enable_loopback(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) |= UARTMCR_LOOP )
+#define __uart_disable_loopback(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) &= ~UARTMCR_LOOP )
+
+#define __uart_set_8n1(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) = UARTLCR_WLEN_8 )
+
+#define __uart_set_baud(n, devclk, baud) \
+ do { \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) |= UARTLCR_DLAB; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLLR) = (devclk / 16 / baud) & 0xff; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLHR) = ((devclk / 16 / baud) >> 8) & 0xff; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) &= ~UARTLCR_DLAB; \
+ } while (0)
+
+#define __uart_parity_error(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_PER) != 0 )
+
+#define __uart_clear_errors(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) &= ~(UARTLSR_ORER | UARTLSR_BRK | UARTLSR_FER | UARTLSR_PER | UARTLSR_RFER) )
+
+#define __uart_transmit_fifo_empty(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TDRQ) != 0 )
+
+#define __uart_transmit_end(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TEMT) != 0 )
+
+#define __uart_transmit_char(n, ch) \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_TDR) = (ch)
+
+#define __uart_receive_fifo_full(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 )
+
+#define __uart_receive_ready(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 )
+
+#define __uart_receive_char(n) \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_RDR)
+
+#define __uart_disable_irda() \
+ ( REG8(IRDA_BASE + OFF_SIRCR) &= ~(SIRCR_TSIRE | SIRCR_RSIRE) )
+#define __uart_enable_irda() \
+ /* Tx high pulse as 0, Rx low pulse as 0 */ \
+ ( REG8(IRDA_BASE + OFF_SIRCR) = SIRCR_TSIRE | SIRCR_RSIRE | SIRCR_RXPL | SIRCR_TPWS )
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760UART_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760wdt.h b/arch/mips/include/asm/mach-jz4760/jz4760wdt.h
new file mode 100644
index 00000000000..100e5c549fa
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760wdt.h
@@ -0,0 +1,70 @@
+/*
+ * jz4760wdt.h
+ * JZ4760 WDT register definition
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: whxu@ingenic.cn
+ */
+
+#ifndef __JZ4760WDT_H__
+#define __JZ4760WDT_H__
+
+
+/*
+ * Watchdog timer module(WDT) address definition
+ */
+#define WDT_BASE 0xb0002000
+
+
+/*
+ * WDT registers offset address definition
+ */
+#define WDT_WDR_OFFSET (0x00) /* rw, 16, 0x???? */
+#define WDT_WCER_OFFSET (0x04) /* rw, 8, 0x00 */
+#define WDT_WCNT_OFFSET (0x08) /* rw, 16, 0x???? */
+#define WDT_WCSR_OFFSET (0x0c) /* rw, 16, 0x0000 */
+
+
+/*
+ * WDT registers address definition
+ */
+#define WDT_WDR (WDT_BASE + WDT_WDR_OFFSET)
+#define WDT_WCER (WDT_BASE + WDT_WCER_OFFSET)
+#define WDT_WCNT (WDT_BASE + WDT_WCNT_OFFSET)
+#define WDT_WCSR (WDT_BASE + WDT_WCSR_OFFSET)
+
+
+/*
+ * WDT registers common define
+ */
+
+/* Watchdog counter enable register(WCER) */
+#define WCER_TCEN BIT0
+
+/* Watchdog control register(WCSR) */
+#define WCSR_PRESCALE_LSB 3
+#define WCSR_PRESCALE_MASK BITS_H2L(5, WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE1 (0x0 << WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE4 (0x1 << WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE16 (0x2 << WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE64 (0x3 << WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE256 (0x4 << WCSR_PRESCALE_LSB)
+#define WCSR_PRESCALE1024 (0x5 << WCSR_PRESCALE_LSB)
+
+#define WCSR_CLKIN_LSB 0
+#define WCSR_CLKIN_MASK BITS_H2L(2, WCSR_CLKIN_LSB)
+#define WCSR_CLKIN_PCK (0x1 << WCSR_CLKIN_LSB)
+#define WCSR_CLKIN_RTC (0x2 << WCSR_CLKIN_LSB)
+#define WCSR_CLKIN_EXT (0x4 << WCSR_CLKIN_LSB)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#define REG_WDT_WDR REG16(WDT_WDR)
+#define REG_WDT_WCER REG8(WDT_WCER)
+#define REG_WDT_WCNT REG16(WDT_WCNT)
+#define REG_WDT_WCSR REG16(WDT_WCSR)
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760WDT_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/jz4760xxx.h b/arch/mips/include/asm/mach-jz4760/jz4760xxx.h
new file mode 100644
index 00000000000..ad6b0370bab
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/jz4760xxx.h
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760xxx.h
+ *
+ * JZ4760 XXX register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760XXX_H__
+#define __JZ4760XXX_H__
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4760XXX_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4760/misc.h b/arch/mips/include/asm/mach-jz4760/misc.h
new file mode 100644
index 00000000000..79f362fbcc5
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/misc.h
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/misc.h
+ *
+ * Ingenic's JZ4760 common include.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4760_MISC_H__
+#define __ASM_JZ4760_MISC_H__
+
+/*==========================================================
+ * I2C
+ *===========================================================*/
+
+#define I2C_EEPROM_DEV 0xA /* b'1010 */
+#define I2C_RTC_DEV 0xD /* b'1101 */
+#define DIMM0_SPD_ADDR 0
+#define DIMM1_SPD_ADDR 1
+#define DIMM2_SPD_ADDR 2
+#define DIMM3_SPD_ADDR 3
+#define JZ_HCI_ADDR 7
+
+#define DIMM_SPD_LEN 128
+#define JZ_HCI_LEN 512 /* 4K bits E2PROM */
+#define I2C_RTC_LEN 16
+#define HCI_MAC_OFFSET 64
+
+extern void i2c_open(void);
+extern void i2c_close(void);
+extern void i2c_setclk(unsigned int i2cclk);
+
+extern int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count);
+extern int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count);
+
+#endif /* __ASM_JZ4760_MISC_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/regs.h b/arch/mips/include/asm/mach-jz4760/regs.h
new file mode 100644
index 00000000000..ee88a32bff0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/regs.h
@@ -0,0 +1,42 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/regs.h
+ *
+ * JZ4760 register definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __JZ4760_REGS_H__
+#define __JZ4760_REGS_H__
+
+
+/*
+ * Define the module base addresses
+ */
+/* AHB0 BUS Devices Base */
+#define HARB0_BASE 0xB3000000
+/* AHB1 BUS Devices Base */
+#define HARB1_BASE 0xB3200000
+#define DMAGP0_BASE 0xB3210000
+#define DMAGP1_BASE 0xB3220000
+#define DMAGP2_BASE 0xB3230000
+#define DEBLK_BASE 0xB3270000
+#define IDCT_BASE 0xB3280000
+#define CABAC_BASE 0xB3290000
+#define TCSM0_BASE 0xB32B0000
+#define TCSM1_BASE 0xB32C0000
+#define SRAM_BASE 0xB32D0000
+/* AHB2 BUS Devices Base */
+#define HARB2_BASE 0xB3400000
+#define UHC_BASE 0xB3430000
+#define GPS_BASE 0xB3480000
+#define ETHC_BASE 0xB34B0000
+/* APB BUS Devices Base */
+#define PS2_BASE 0xB0060000
+
+
+#endif /* __JZ4760_REGS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/serial.h b/arch/mips/include/asm/mach-jz4760/serial.h
new file mode 100644
index 00000000000..63f54e25f86
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/serial.h
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/serial.h
+ *
+ * Ingenic's JZ4760 common include.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_BOARD_SERIAL_H__
+#define __ASM_BOARD_SERIAL_H__
+
+#ifndef CONFIG_SERIAL_MANY_PORTS
+#undef RS_TABLE_SIZE
+#define RS_TABLE_SIZE 1
+#endif
+
+#define JZ_BASE_BAUD (12000000/16)
+
+#define JZ_SERIAL_PORT_DEFNS \
+ { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART0, \
+ .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART0_BASE, \
+ .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM },
+
+#endif /* __ASM_BORAD_SERIAL_H__ */
diff --git a/arch/mips/include/asm/mach-jz4760/war.h b/arch/mips/include/asm/mach-jz4760/war.h
new file mode 100644
index 00000000000..f3fa2aeccbc
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4760/war.h
@@ -0,0 +1,26 @@
+/*
+ * 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_JZ4760_WAR_H
+#define __ASM_MIPS_MACH_JZ4760_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_JZ4760_WAR_H */
+
diff --git a/arch/mips/include/asm/mach-jz4810/board-f4810.h b/arch/mips/include/asm/mach-jz4810/board-f4810.h
new file mode 100644
index 00000000000..88f25d3d4f9
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/board-f4810.h
@@ -0,0 +1,93 @@
+/*
+ * linux arch/mips/include/asm/mach-jz4810/board-f4810.h
+ *
+ * JZ4810-based F4810 board ver 1.x definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4810_F4810_H__
+#define __ASM_JZ4810_F4810_H__
+
+#define CONFIG_FPGA
+
+/*======================================================================
+ * Frequencies of on-board oscillators
+ */
+#define JZ_EXTAL 33000000 /* Main extal freq: 12 MHz */
+#define JZ_EXTAL2 32768 /* RTC extal freq: 32.768 KHz */
+#define CFG_DIV 2 /* cpu/extclk; only for FPGA */
+
+/*======================================================================
+ * GPIO
+ */
+#define GPIO_SD_VCC_EN_N 113 /* GPD17 */
+#define GPIO_SD_CD_N 110 /* GPD14 */
+#define GPIO_SD_WP 112 /* GPD16 */
+#define GPIO_USB_DETE 102 /* GPD6 */
+#define GPIO_DC_DETE_N 103 /* GPD7 */
+#define GPIO_CHARG_STAT_N 111 /* GPD15 */
+#define GPIO_DISP_OFF_N 121 /* GPD25, LCD_REV */
+//#define GPIO_LED_EN 124 /* GPD28 */
+
+#define GPIO_UDC_HOTPLUG GPIO_USB_DETE
+
+/*======================================================================
+ * LCD backlight
+ */
+#define GPIO_LCD_PWM (32*4+4) /* GPE4 PWM4 */
+
+#define LCD_PWM_CHN 4 /* pwm channel */
+#define LCD_PWM_FULL 101
+/* 100 level: 0,1,...,100 */
+#define __lcd_set_backlight_level(n) \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_set_pin(GPIO_LCD_PWM); \
+} while (0)
+
+#define __lcd_close_backlight() \
+do { \
+ __gpio_as_output(GPIO_LCD_PWM); \
+ __gpio_clear_pin(GPIO_LCD_PWM); \
+} while (0)
+
+/*======================================================================
+ * MMC/SD
+ */
+
+#define MSC_WP_PIN GPIO_SD_WP
+#define MSC_HOTPLUG_PIN GPIO_SD_CD_N
+#define MSC_HOTPLUG_IRQ (IRQ_GPIO_0 + GPIO_SD_CD_N)
+
+#define __msc_init_io() \
+do { \
+ __gpio_as_output(GPIO_SD_VCC_EN_N); \
+ __gpio_as_input(GPIO_SD_CD_N); \
+} while (0)
+
+#define __msc_enable_power() \
+do { \
+ __gpio_clear_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_disable_power() \
+do { \
+ __gpio_set_pin(GPIO_SD_VCC_EN_N); \
+} while (0)
+
+#define __msc_card_detected(s) \
+({ \
+ int detected = 1; \
+ if (__gpio_get_pin(GPIO_SD_CD_N)) \
+ detected = 0; \
+ detected; \
+})
+
+#endif /* __ASM_JZ4810_F4810_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/clock.h b/arch/mips/include/asm/mach-jz4810/clock.h
new file mode 100644
index 00000000000..383b0fcc700
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/clock.h
@@ -0,0 +1,267 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/clock.h
+ *
+ * JZ4810 clocks definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4810_CLOCK_H__
+#define __ASM_JZ4810_CLOCK_H__
+
+#ifndef JZ_EXTAL
+#define JZ_EXTAL 33000000 /* 3.6864 MHz */
+#endif
+#ifndef JZ_EXTAL2
+#define JZ_EXTAL2 32768 /* 32.768 KHz */
+#endif
+
+/*
+ * JZ4810 clocks structure
+ */
+typedef struct {
+ unsigned int cclk; /* CPU clock */
+ unsigned int hclk; /* System bus clock: AHB0,AHB1 */
+ unsigned int h1clk; /* For compatible, the same as h1clk */
+ unsigned int h2clk; /* System bus clock: AHB2 */
+ unsigned int pclk; /* Peripheral bus clock */
+ unsigned int mclk; /* EMC or DDR controller clock */
+ unsigned int sclk; /* NEMC controller clock */
+ unsigned int cko; /* SDRAM or DDR clock */
+ unsigned int pixclk; /* LCD pixel clock */
+ unsigned int tveclk; /* TV encoder 27M clock */
+ unsigned int cimmclk; /* Clock output from CIM module */
+ unsigned int cimpclk; /* Clock input to CIM module */
+ unsigned int gpuclk; /* GPU clock */
+ unsigned int gpsclk; /* GPS clock */
+ unsigned int i2sclk; /* I2S codec clock */
+ unsigned int bitclk; /* AC97 bit clock */
+ unsigned int pcmclk; /* PCM clock */
+ unsigned int mscclk; /* MSC clock */
+ unsigned int ssiclk; /* SSI clock */
+ unsigned int tssiclk; /* TSSI clock */
+ unsigned int otgclk; /* USB OTG clock */
+ unsigned int uhcclk; /* USB UHCI clock */
+ unsigned int extalclk; /* EXTAL clock for
+ UART,I2C,TCU,USB2.0-PHY,AUDIO CODEC */
+ 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)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL*CFG_DIV;
+#else
+ unsigned long m, n, no, pllout;
+ unsigned long cppcr = REG_CPM_CPPCR;
+ unsigned long od[4] = {1, 2, 4, 8};
+ if ((cppcr & CPM_CPPCR_PLLEN) && !(cppcr & CPM_CPPCR_PLLBP)) {
+ m = __cpm_get_pllm() << 1;
+ n = __cpm_get_plln();
+ no = od[__cpm_get_pllod()];
+ pllout = ((JZ_EXTAL) / (n * no)) * m;
+ } else
+ pllout = JZ_EXTAL;
+ return pllout;
+#endif
+}
+
+/* PLL output frequency / 2 */
+static __inline__ unsigned int __cpm_get_pllout2(void)
+{
+#if defined(CONFIG_FPGA)
+ return __cpm_get_pllout();
+#else
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS)
+ return __cpm_get_pllout();
+ else
+ return __cpm_get_pllout()/2;
+#endif
+}
+
+/* CPU core clock */
+static __inline__ unsigned int __cpm_get_cclk(void)
+{
+
+#if defined(CONFIG_FGPA)
+ return JZ_EXTAL * CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+ return __cpm_get_pllout() / div[__cpm_get_cdiv()];
+#endif
+}
+
+/* AHB0, AHB1 clock */
+static __inline__ unsigned int __cpm_get_hclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_hdiv()];
+#endif
+
+}
+
+#define __cpm_get_h0clk(void) __cpm_get_hclk()
+#define __cpm_get_h1clk(void) __cpm_get_hclk()
+
+
+/* AHB2 clock */
+static __inline__ unsigned int __cpm_get_h2clk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_h2div()];
+#endif
+
+}
+
+/* Memory bus clock */
+static __inline__ unsigned int __cpm_get_mclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL/CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_mdiv()];
+#endif
+}
+
+/* APB peripheral bus clock */
+static __inline__ unsigned int __cpm_get_pclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return JZ_EXTAL/CFG_DIV;
+#else
+ int div[] = {1, 2, 3, 4, 6, 8};
+
+ return __cpm_get_pllout() / div[__cpm_get_pdiv()];
+#endif
+}
+
+/* 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_I2SCDR & CPM_I2SCDR_I2CS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_i2sdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_i2sdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* USB OTG clock */
+static __inline__ unsigned int __cpm_get_otgclk(void)
+{
+ if (REG_CPM_USBCDR & CPM_USBCDR_UCS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_otgdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_otgdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* MSC clock */
+static __inline__ unsigned int __cpm_get_mscclk(int n)
+{
+ if (REG_CPM_MSCCDR & CPM_MSCCDR_MCS) {
+ if (REG_CPM_CPCCR & CPM_CPCCR_PCS) {
+ return __cpm_get_pllout() / (__cpm_get_mscdiv() + 1);
+ } else {
+ return __cpm_get_pllout2() / (__cpm_get_mscdiv() + 1);
+ }
+ } else {
+ return JZ_EXTAL;
+ }
+}
+
+/* EXTAL clock */
+static __inline__ unsigned int __cpm_get_extalclk0(void)
+{
+ return JZ_EXTAL;
+}
+
+/* EXTAL clock for UART,I2C,SSI,SADC,USB-PHY */
+static __inline__ unsigned int __cpm_get_extalclk(void)
+{
+#if defined(CONFIG_FPGA)
+ return __cpm_get_extalclk0() / CFG_DIV;
+#else
+ if (REG_CPM_CPCCR & CPM_CPCCR_ECS)
+ return __cpm_get_extalclk0() / 2;
+ else
+ return __cpm_get_extalclk0();
+#endif
+
+}
+
+/* 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.
+ * @n: the index of MMC/SD controller
+ */
+static inline void __cpm_select_msc_clk(int n, 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;
+ REG_CPM_CPCCR |= CPM_CPCCR_CE;
+}
+
+/*
+ * Output 48MHz for high speed card.
+ */
+static inline void __cpm_select_msc_clk_high(int n, int sd)
+{
+ unsigned int pllout2 = __cpm_get_pllout2();
+ unsigned int div = 0;
+
+ div = pllout2 / 48000000;
+
+ REG_CPM_MSCCDR = div - 1;
+ REG_CPM_CPCCR |= CPM_CPCCR_CE;
+}
+
+#endif /* __ASM_JZ4810_CLOCK_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/dma.h b/arch/mips/include/asm/mach-jz4810/dma.h
new file mode 100644
index 00000000000..042aa2c7acc
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/dma.h
@@ -0,0 +1,329 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/dma.h
+ *
+ * JZ4810 DMA definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4810_DMA_H__
+#define __ASM_JZ4810_DMA_H__
+
+#include <linux/interrupt.h>
+#include <asm/io.h> /* need byte IO */
+#include <linux/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+/*
+ * Descriptor structure for JZ4810 DMA engine
+ * Note: this structure must always be aligned to a 16-bytes boundary.
+ */
+
+/* old descriptor 4-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 ddadr; /* Points to the next descriptor + transfer count */
+} jz_dma_desc;
+
+/* new descriptor 8-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 ddadr; /* Points to the next descriptor + transfer count */
+ volatile u32 dstrd; /* DMA source and target stride address */
+ volatile u32 dreqt; /* DMA request type for current transfer */
+ volatile u32 reserved0; /* Reserved */
+ volatile u32 reserved1; /* Reserved */
+} jz_dma_desc_8word;
+
+/* new descriptor 8-word */
+typedef struct {
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+ volatile u32 dsadr; /* DSAR value for the current transfer */
+ volatile u32 dtadr; /* DTAR value for the current transfer */
+ volatile u32 dcnt; /* transfer count */
+ volatile u32 dstrd; /* DMA source and target stride address */
+ volatile u32 dreqt; /* DMA request type for current transfer */
+ volatile u32 dnt; /* NAND detect timer enable(15) and value(0~5), and Tail counter(22~16)*/
+ volatile u32 ddadr; /* Next descriptor address(31~4) */
+} jz_bdma_desc_8word;
+
+/* DMA Device ID's follow */
+enum {
+ DMA_ID_EXT = 0, /* External request with DREQn */
+ DMA_ID_NAND, /* NAND DMA request */
+ DMA_ID_BCH_ENC, /* BCH Encoding DMA request */
+ DMA_ID_BCH_DEC, /* BCH Decoding DMA request */
+ DMA_ID_AUTO, /* Auto-request */
+// DMA_ID_TSSI_RX, /* TSSI receive fifo full request */
+ DMA_ID_UART3_TX, /* UART3 transmit-fifo-empty request */
+ DMA_ID_UART3_RX, /* UART3 receve-fifo-full request */
+ DMA_ID_UART2_TX, /* UART2 transmit-fifo-empty request */
+ DMA_ID_UART2_RX, /* UART2 receve-fifo-full request */
+ DMA_ID_UART1_TX, /* UART1 transmit-fifo-empty request */
+ DMA_ID_UART1_RX, /* UART1 receve-fifo-full request */
+ DMA_ID_UART0_TX, /* UART0 transmit-fifo-empty request */
+ DMA_ID_UART0_RX, /* UART0 receve-fifo-full request */
+ DMA_ID_SSI0_TX, /* SSI0 transmit-fifo-full request */
+ DMA_ID_SSI0_RX, /* SSI0 receive-fifo-empty request */
+ DMA_ID_AIC_TX, /* AIC transmit-fifo-full request */
+ DMA_ID_AIC_RX, /* AIC receive-fifo-empty request */
+ DMA_ID_MSC0_TX, /* MSC0 transmit-fifo-full request */
+ DMA_ID_MSC0_RX, /* MSC0 receive-fifo-empty request */
+ DMA_ID_TCU_OVERFLOW, /* TCU channel n overflow interrupt */
+ DMA_ID_SADC, /* SADC transfer request */
+ DMA_ID_MSC1_TX, /* MSC1 transmit-fifo-full request */
+ DMA_ID_MSC1_RX, /* MSC1 receive-fifo-empty request */
+ DMA_ID_SSI1_TX, /* SSI1 transmit-fifo-full request */
+ DMA_ID_SSI1_RX, /* SSI1 receive-fifo-empty request */
+ DMA_ID_PCM_TX, /* PM transmit-fifo-full request */
+ DMA_ID_PCM_RX, /* PM receive-fifo-empty request */
+ DMA_ID_RAW_SET,
+ DMA_ID_MAX
+};
+
+/* DMA modes, simulated by sw */
+#define DMA_MODE_READ 0x0 /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x1 /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_AUTOINIT 0x2
+#define DMA_MODE_MASK 0x3
+
+struct jz_dma_chan {
+ int dev_id; /* DMA ID: this channel is allocated if >=0, free otherwise */
+ unsigned int io; /* DMA channel number */
+ const char *dev_str; /* string describes the DMA channel */
+ int irq; /* DMA irq number */
+ void *irq_dev; /* DMA private device structure */
+ unsigned int fifo_addr; /* physical fifo address of the requested device */
+ unsigned int cntl; /* DMA controll */
+ unsigned int mode; /* DMA configuration */
+ unsigned int source; /* DMA request source */
+};
+
+extern struct jz_dma_chan jz_dma_table[];
+
+
+#define DMA_8BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_8BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_8BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_8 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_32BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_8 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_32_32BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BYTE | DMAC_DCMD_RDIL_IGN
+#define DMA_AIC_32_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_32_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BIT_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BIT_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_RX_CMD \
+ DMAC_DCMD_DAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_TX_CMD \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_16BYTE_TX_CMD_UC \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_16BYTE | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_TX_CMD_UNPACK \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_16 | DMAC_DCMD_DWDH_16 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+#define DMA_AIC_TX_CMD_PACK \
+ DMAC_DCMD_SAI | \
+ DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | \
+ DMAC_DCMD_DS_32BIT | DMAC_DCMD_RDIL_IGN
+
+extern int jz_request_dma(int dev_id,
+ const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags,
+ void *irq_dev_id);
+extern void jz_free_dma(unsigned int dmanr);
+
+extern int jz_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data);
+extern void dump_jz_dma_channel(unsigned int dmanr);
+extern void dump_jz_bdma_channel(unsigned int dmanr);
+
+extern void enable_dma(unsigned int dmanr);
+extern void disable_dma(unsigned int dmanr);
+extern void set_dma_addr(unsigned int dmanr, unsigned int phyaddr);
+extern void set_dma_count(unsigned int dmanr, unsigned int bytecnt);
+extern void set_dma_mode(unsigned int dmanr, unsigned int mode);
+extern void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt);
+extern void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt);
+extern void jz_set_dma_src_width(int dmanr, int nbit);
+extern void jz_set_dma_dest_width(int dmanr, int nbit);
+extern void jz_set_dma_block_size(int dmanr, int nbyte);
+extern unsigned int get_dma_residue(unsigned int dmanr);
+extern spinlock_t dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ */
+#define clear_dma_ff(channel)
+
+static __inline__ struct jz_dma_chan *get_dma_chan(unsigned int dmanr)
+{
+ if (dmanr > MAX_DMA_NUM
+ || jz_dma_table[dmanr].dev_id < 0)
+ return NULL;
+ return &jz_dma_table[dmanr];
+}
+
+static __inline__ int dma_halted(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 1;
+ return __dmac_channel_transmit_halt_detected(dmanr) ? 1 : 0;
+}
+
+static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+ return chan->mode;
+}
+
+static __inline__ void clear_dma_done(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+}
+
+static __inline__ void clear_dma_halt(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT);
+ REG_DMAC_DMACR((chan->io)/HALF_DMA_NUM) &= ~(DMAC_DMACR_HLT);
+}
+
+static __inline__ void clear_dma_flag(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+ REG_DMAC_DCCSR(chan->io) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+ REG_DMAC_DMACR((chan->io)/HALF_DMA_NUM) &= ~(DMAC_DMACR_HLT | DMAC_DMACR_AR);
+}
+
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+}
+
+static __inline__ unsigned int get_dma_done_status(unsigned int dmanr)
+{
+ unsigned long dccsr;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+ dccsr = REG_DMAC_DCCSR(chan->io);
+ return dccsr & (DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+}
+
+static __inline__ int get_dma_done_irq(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return -1;
+ return chan->irq;
+}
+
+#endif /* __ASM_JZ4810_DMA_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/irq.h b/arch/mips/include/asm/mach-jz4810/irq.h
new file mode 100644
index 00000000000..e0194e3a075
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/irq.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/mips/include/asm/mach-jz4810/irq.h
+ *
+ * JZ4810 IRQ definition.
+ *
+ * Copyright (C) 2010 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_JZ4810_IRQ_H__
+#define __ASM_JZ4810_IRQ_H__
+
+/* we need 256 irq levels at least */
+#define NR_IRQS 256
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810.h b/arch/mips/include/asm/mach-jz4810/jz4810.h
new file mode 100644
index 00000000000..a7154ad02c9
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810.h
@@ -0,0 +1,77 @@
+/*
+ * linux/include/asm-mips/mach-jz4760/jz4760.h
+ *
+ * JZ4760 common definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4810_H__
+#define __ASM_JZ4810_H__
+
+#include <asm/mach-jz4810/regs.h>
+
+#include <asm/mach-jz4810/jz4810misc.h>
+#include <asm/mach-jz4810/jz4810gpio.h>
+#include <asm/mach-jz4810/jz4810dmac.h>
+#include <asm/mach-jz4810/jz4810intc.h>
+#include <asm/mach-jz4810/jz4810aic.h>
+#include <asm/mach-jz4810/jz4810bch.h>
+#include <asm/mach-jz4810/jz4810bdma.h>
+#include <asm/mach-jz4810/jz4810cim.h>
+#include <asm/mach-jz4810/jz4810cpm.h>
+#include <asm/mach-jz4810/jz4810ddrc.h>
+#include <asm/mach-jz4810/jz4810emc.h>
+#include <asm/mach-jz4810/jz4810i2c.h>
+#include <asm/mach-jz4810/jz4810ipu.h>
+#include <asm/mach-jz4810/jz4810lcdc.h>
+#include <asm/mach-jz4810/jz4810mc.h>
+#include <asm/mach-jz4810/jz4810mdma.h>
+#include <asm/mach-jz4810/jz4810me.h>
+#include <asm/mach-jz4810/jz4810msc.h>
+#include <asm/mach-jz4810/jz4810nemc.h>
+#include <asm/mach-jz4810/jz4810otg.h>
+#include <asm/mach-jz4810/jz4810otp.h>
+#include <asm/mach-jz4810/jz4810owi.h>
+#include <asm/mach-jz4810/jz4810pcm.h>
+#include <asm/mach-jz4810/jz4810rtc.h>
+#include <asm/mach-jz4810/jz4810sadc.h>
+#include <asm/mach-jz4810/jz4810scc.h>
+#include <asm/mach-jz4810/jz4810ssi.h>
+#include <asm/mach-jz4810/jz4810tcu.h>
+#include <asm/mach-jz4810/jz4810tssi.h>
+#include <asm/mach-jz4810/jz4810tve.h>
+#include <asm/mach-jz4810/jz4810uart.h>
+#include <asm/mach-jz4810/jz4810wdt.h>
+
+#include <asm/mach-jz4810/dma.h>
+#include <asm/mach-jz4810/misc.h>
+
+/*------------------------------------------------------------------
+ * Platform definitions
+ */
+
+#define JZ_SOC_NAME "JZ4810"
+
+#ifdef CONFIG_JZ4810_F4810
+#include <asm/mach-jz4810/board-f4810.h>
+#endif
+
+
+/* Add other platform definition here ... */
+
+
+/*------------------------------------------------------------------
+ * Follows are related to platform definitions
+ */
+
+#include <asm/mach-jz4810/clock.h>
+#include <asm/mach-jz4810/serial.h>
+
+#endif /* __ASM_JZ4810_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810aic.h b/arch/mips/include/asm/mach-jz4810/jz4810aic.h
new file mode 100644
index 00000000000..f5699a1a0b8
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810aic.h
@@ -0,0 +1,817 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810aic.h
+ *
+ * JZ4810 AIC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810AIC_H__
+#define __JZ4810AIC_H__
+
+
+#define AIC_BASE 0xB0020000
+#define ICDC_BASE 0xB0020000
+
+
+/*************************************************************************
+ * AIC (AC97/I2S Controller)
+ *************************************************************************/
+#define AIC_FR (AIC_BASE + 0x000)
+#define AIC_CR (AIC_BASE + 0x004)
+#define AIC_ACCR1 (AIC_BASE + 0x008)
+#define AIC_ACCR2 (AIC_BASE + 0x00C)
+#define AIC_I2SCR (AIC_BASE + 0x010)
+#define AIC_SR (AIC_BASE + 0x014)
+#define AIC_ACSR (AIC_BASE + 0x018)
+#define AIC_I2SSR (AIC_BASE + 0x01C)
+#define AIC_ACCAR (AIC_BASE + 0x020)
+#define AIC_ACCDR (AIC_BASE + 0x024)
+#define AIC_ACSAR (AIC_BASE + 0x028)
+#define AIC_ACSDR (AIC_BASE + 0x02C)
+#define AIC_I2SDIV (AIC_BASE + 0x030)
+#define AIC_DR (AIC_BASE + 0x034)
+
+#define REG_AIC_FR REG32(AIC_FR)
+#define REG_AIC_CR REG32(AIC_CR)
+#define REG_AIC_ACCR1 REG32(AIC_ACCR1)
+#define REG_AIC_ACCR2 REG32(AIC_ACCR2)
+#define REG_AIC_I2SCR REG32(AIC_I2SCR)
+#define REG_AIC_SR REG32(AIC_SR)
+#define REG_AIC_ACSR REG32(AIC_ACSR)
+#define REG_AIC_I2SSR REG32(AIC_I2SSR)
+#define REG_AIC_ACCAR REG32(AIC_ACCAR)
+#define REG_AIC_ACCDR REG32(AIC_ACCDR)
+#define REG_AIC_ACSAR REG32(AIC_ACSAR)
+#define REG_AIC_ACSDR REG32(AIC_ACSDR)
+#define REG_AIC_I2SDIV REG32(AIC_I2SDIV)
+#define REG_AIC_DR REG32(AIC_DR)
+
+/* AIC Controller Configuration Register (AIC_FR) */
+
+#define AIC_FR_RFTH_BIT 24 /* Receive FIFO Threshold */
+#define AIC_FR_RFTH_MASK (0xf << AIC_FR_RFTH_BIT)
+#define AIC_FR_TFTH_BIT 16 /* Transmit FIFO Threshold */
+#define AIC_FR_TFTH_MASK (0x1f << AIC_FR_TFTH_BIT)
+#define AIC_FR_LSMP (1 << 6) /* Play Zero sample or last sample */
+#define AIC_FR_ICDC (1 << 5) /* External(0) or Internal CODEC(1) */
+#define AIC_FR_AUSEL (1 << 4) /* AC97(0) or I2S/MSB-justified(1) */
+#define AIC_FR_RST (1 << 3) /* AIC registers reset */
+#define AIC_FR_BCKD (1 << 2) /* I2S BIT_CLK direction, 0:input,1:output */
+#define AIC_FR_SYNCD (1 << 1) /* I2S SYNC direction, 0:input,1:output */
+#define AIC_FR_ENB (1 << 0) /* AIC enable bit */
+
+/* AIC Controller Common Control Register (AIC_CR) */
+
+#define AIC_CR_EN2OLD (1 << 29) /* Enable old style */
+#define AIC_CR_PACK16 (1 << 28) /* Output Sample data 16bit packed mode select */
+#define AIC_CR_CHANNEL_BIT 24 /* Output Channel Number Select */
+#define AIC_CR_CHANNEL_MASK (0x7 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_MONO (0x0 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_STEREO (0x1 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_4CHNL (0x3 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_6CHNL (0x5 << AIC_CR_CHANNEL_BIT)
+ #define AIC_CR_CHANNEL_8CHNL (0x7 << AIC_CR_CHANNEL_BIT)
+
+#define AIC_CR_OSS_BIT 19 /* Output Sample Size from memory (AIC V2 only) */
+#define AIC_CR_OSS_MASK (0x7 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_8BIT (0x0 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_16BIT (0x1 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_18BIT (0x2 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_20BIT (0x3 << AIC_CR_OSS_BIT)
+ #define AIC_CR_OSS_24BIT (0x4 << AIC_CR_OSS_BIT)
+#define AIC_CR_ISS_BIT 16 /* Input Sample Size from memory (AIC V2 only) */
+#define AIC_CR_ISS_MASK (0x7 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_8BIT (0x0 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_16BIT (0x1 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_18BIT (0x2 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_20BIT (0x3 << AIC_CR_ISS_BIT)
+ #define AIC_CR_ISS_24BIT (0x4 << AIC_CR_ISS_BIT)
+#define AIC_CR_RDMS (1 << 15) /* Receive DMA enable */
+#define AIC_CR_TDMS (1 << 14) /* Transmit DMA enable */
+#define AIC_CR_M2S (1 << 11) /* Mono to Stereo enable */
+#define AIC_CR_ENDSW (1 << 10) /* Endian switch enable */
+#define AIC_CR_AVSTSU (1 << 9) /* Signed <-> Unsigned toggle enable */
+#define AIC_CR_TFLUSH (1 << 8) /* Flush TFIFO */
+#define AIC_CR_RFLUSH (1 << 7) /* Flush RFIFO */
+#define AIC_CR_EROR (1 << 6) /* Enable ROR interrupt */
+#define AIC_CR_ETUR (1 << 5) /* Enable TUR interrupt */
+#define AIC_CR_ERFS (1 << 4) /* Enable RFS interrupt */
+#define AIC_CR_ETFS (1 << 3) /* Enable TFS interrupt */
+#define AIC_CR_ENLBF (1 << 2) /* Enable Loopback Function */
+#define AIC_CR_ERPL (1 << 1) /* Enable Playback Function */
+#define AIC_CR_EREC (1 << 0) /* Enable Record Function */
+
+/* AIC Controller AC-link Control Register 1 (AIC_ACCR1) */
+
+#define AIC_ACCR1_RS_BIT 16 /* Receive Valid Slots */
+#define AIC_ACCR1_RS_MASK (0x3ff << AIC_ACCR1_RS_BIT)
+ #define AIC_ACCR1_RS_SLOT12 (1 << 25) /* Slot 12 valid bit */
+ #define AIC_ACCR1_RS_SLOT11 (1 << 24) /* Slot 11 valid bit */
+ #define AIC_ACCR1_RS_SLOT10 (1 << 23) /* Slot 10 valid bit */
+ #define AIC_ACCR1_RS_SLOT9 (1 << 22) /* Slot 9 valid bit, LFE */
+ #define AIC_ACCR1_RS_SLOT8 (1 << 21) /* Slot 8 valid bit, Surround Right */
+ #define AIC_ACCR1_RS_SLOT7 (1 << 20) /* Slot 7 valid bit, Surround Left */
+ #define AIC_ACCR1_RS_SLOT6 (1 << 19) /* Slot 6 valid bit, PCM Center */
+ #define AIC_ACCR1_RS_SLOT5 (1 << 18) /* Slot 5 valid bit */
+ #define AIC_ACCR1_RS_SLOT4 (1 << 17) /* Slot 4 valid bit, PCM Right */
+ #define AIC_ACCR1_RS_SLOT3 (1 << 16) /* Slot 3 valid bit, PCM Left */
+#define AIC_ACCR1_XS_BIT 0 /* Transmit Valid Slots */
+#define AIC_ACCR1_XS_MASK (0x3ff << AIC_ACCR1_XS_BIT)
+ #define AIC_ACCR1_XS_SLOT12 (1 << 9) /* Slot 12 valid bit */
+ #define AIC_ACCR1_XS_SLOT11 (1 << 8) /* Slot 11 valid bit */
+ #define AIC_ACCR1_XS_SLOT10 (1 << 7) /* Slot 10 valid bit */
+ #define AIC_ACCR1_XS_SLOT9 (1 << 6) /* Slot 9 valid bit, LFE */
+ #define AIC_ACCR1_XS_SLOT8 (1 << 5) /* Slot 8 valid bit, Surround Right */
+ #define AIC_ACCR1_XS_SLOT7 (1 << 4) /* Slot 7 valid bit, Surround Left */
+ #define AIC_ACCR1_XS_SLOT6 (1 << 3) /* Slot 6 valid bit, PCM Center */
+ #define AIC_ACCR1_XS_SLOT5 (1 << 2) /* Slot 5 valid bit */
+ #define AIC_ACCR1_XS_SLOT4 (1 << 1) /* Slot 4 valid bit, PCM Right */
+ #define AIC_ACCR1_XS_SLOT3 (1 << 0) /* Slot 3 valid bit, PCM Left */
+
+/* AIC Controller AC-link Control Register 2 (AIC_ACCR2) */
+
+#define AIC_ACCR2_ERSTO (1 << 18) /* Enable RSTO interrupt */
+#define AIC_ACCR2_ESADR (1 << 17) /* Enable SADR interrupt */
+#define AIC_ACCR2_ECADT (1 << 16) /* Enable CADT interrupt */
+#define AIC_ACCR2_OASS_BIT 8 /* Output Sample Size for AC-link */
+#define AIC_ACCR2_OASS_MASK (0x3 << AIC_ACCR2_OASS_BIT)
+ #define AIC_ACCR2_OASS_20BIT (0 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 20-bit */
+ #define AIC_ACCR2_OASS_18BIT (1 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 18-bit */
+ #define AIC_ACCR2_OASS_16BIT (2 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 16-bit */
+ #define AIC_ACCR2_OASS_8BIT (3 << AIC_ACCR2_OASS_BIT) /* Output Audio Sample Size is 8-bit */
+#define AIC_ACCR2_IASS_BIT 6 /* Output Sample Size for AC-link */
+#define AIC_ACCR2_IASS_MASK (0x3 << AIC_ACCR2_IASS_BIT)
+ #define AIC_ACCR2_IASS_20BIT (0 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 20-bit */
+ #define AIC_ACCR2_IASS_18BIT (1 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 18-bit */
+ #define AIC_ACCR2_IASS_16BIT (2 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 16-bit */
+ #define AIC_ACCR2_IASS_8BIT (3 << AIC_ACCR2_IASS_BIT) /* Input Audio Sample Size is 8-bit */
+#define AIC_ACCR2_SO (1 << 3) /* SDATA_OUT output value */
+#define AIC_ACCR2_SR (1 << 2) /* RESET# pin level */
+#define AIC_ACCR2_SS (1 << 1) /* SYNC pin level */
+#define AIC_ACCR2_SA (1 << 0) /* SYNC and SDATA_OUT alternation */
+
+/* AIC Controller I2S/MSB-justified Control Register (AIC_I2SCR) */
+
+#define AIC_I2SCR_RFIRST (1 << 17) /* Send R channel first in stereo mode */
+#define AIC_I2SCR_SWLH (1 << 16) /* Switch LR channel in 16bit-packed stereo mode */
+#define AIC_I2SCR_STPBK (1 << 12) /* Stop BIT_CLK for I2S/MSB-justified */
+#define AIC_I2SCR_WL_BIT 1 /* Input/Output Sample Size for I2S/MSB-justified */
+#define AIC_I2SCR_WL_MASK (0x7 << AIC_I2SCR_WL_BIT)
+ #define AIC_I2SCR_WL_24BIT (0 << AIC_I2SCR_WL_BIT) /* Word Length is 24 bit */
+ #define AIC_I2SCR_WL_20BIT (1 << AIC_I2SCR_WL_BIT) /* Word Length is 20 bit */
+ #define AIC_I2SCR_WL_18BIT (2 << AIC_I2SCR_WL_BIT) /* Word Length is 18 bit */
+ #define AIC_I2SCR_WL_16BIT (3 << AIC_I2SCR_WL_BIT) /* Word Length is 16 bit */
+ #define AIC_I2SCR_WL_8BIT (4 << AIC_I2SCR_WL_BIT) /* Word Length is 8 bit */
+
+#define AIC_I2SCR_ESCLK (1 << 4)
+
+#define AIC_I2SCR_AMSL (1 << 0) /* 0:I2S, 1:MSB-justified */
+
+/* AIC Controller FIFO Status Register (AIC_SR) */
+
+#define AIC_SR_RFL_BIT 24 /* Receive FIFO Level */
+#define AIC_SR_RFL_MASK (0x3f << AIC_SR_RFL_BIT)
+#define AIC_SR_TFL_BIT 8 /* Transmit FIFO level */
+#define AIC_SR_TFL_MASK (0x3f << AIC_SR_TFL_BIT)
+#define AIC_SR_ROR (1 << 6) /* Receive FIFO Overrun */
+#define AIC_SR_TUR (1 << 5) /* Transmit FIFO Underrun */
+#define AIC_SR_RFS (1 << 4) /* Receive FIFO Service Request */
+#define AIC_SR_TFS (1 << 3) /* Transmit FIFO Service Request */
+
+/* AIC Controller AC-link Status Register (AIC_ACSR) */
+
+#define AIC_ACSR_SLTERR (1 << 21) /* Slot Error Flag */
+#define AIC_ACSR_CRDY (1 << 20) /* External CODEC Ready Flag */
+#define AIC_ACSR_CLPM (1 << 19) /* External CODEC low power mode flag */
+#define AIC_ACSR_RSTO (1 << 18) /* External CODEC regs read status timeout */
+#define AIC_ACSR_SADR (1 << 17) /* External CODEC regs status addr and data received */
+#define AIC_ACSR_CADT (1 << 16) /* Command Address and Data Transmitted */
+
+/* AIC Controller I2S/MSB-justified Status Register (AIC_I2SSR) */
+
+#define AIC_I2SSR_BSY (1 << 2) /* AIC Busy in I2S/MSB-justified format */
+
+/* AIC Controller AC97 codec Command Address Register (AIC_ACCAR) */
+
+#define AIC_ACCAR_CAR_BIT 0
+#define AIC_ACCAR_CAR_MASK (0xfffff << AIC_ACCAR_CAR_BIT)
+
+/* AIC Controller AC97 codec Command Data Register (AIC_ACCDR) */
+
+#define AIC_ACCDR_CDR_BIT 0
+#define AIC_ACCDR_CDR_MASK (0xfffff << AIC_ACCDR_CDR_BIT)
+
+/* AIC Controller AC97 codec Status Address Register (AIC_ACSAR) */
+
+#define AIC_ACSAR_SAR_BIT 0
+#define AIC_ACSAR_SAR_MASK (0xfffff << AIC_ACSAR_SAR_BIT)
+
+/* AIC Controller AC97 codec Status Data Register (AIC_ACSDR) */
+
+#define AIC_ACSDR_SDR_BIT 0
+#define AIC_ACSDR_SDR_MASK (0xfffff << AIC_ACSDR_SDR_BIT)
+
+/* AIC Controller I2S/MSB-justified Clock Divider Register (AIC_I2SDIV) */
+
+#define AIC_I2SDIV_DIV_BIT 0
+#define AIC_I2SDIV_DIV_MASK (0x7f << AIC_I2SDIV_DIV_BIT)
+ #define AIC_I2SDIV_BITCLK_3072KHZ (0x0C << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 3.072MHz */
+ #define AIC_I2SDIV_BITCLK_2836KHZ (0x0D << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 2.836MHz */
+ #define AIC_I2SDIV_BITCLK_1418KHZ (0x1A << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.418MHz */
+ #define AIC_I2SDIV_BITCLK_1024KHZ (0x24 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 1.024MHz */
+ #define AIC_I2SDIV_BITCLK_7089KHZ (0x34 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 708.92KHz */
+ #define AIC_I2SDIV_BITCLK_512KHZ (0x48 << AIC_I2SDIV_DIV_BIT) /* BIT_CLK of 512.00KHz */
+
+
+
+/*************************************************************************
+ * ICDC (Internal CODEC)
+ *************************************************************************/
+
+#define ICDC_CKCFG (ICDC_BASE + 0x00a0) /* Clock Configure Register */
+#define ICDC_RGADW (ICDC_BASE + 0x00a4) /* internal register access control */
+#define ICDC_RGDATA (ICDC_BASE + 0x00a8) /* internal register data output */
+
+#define REG_ICDC_CKCFG REG32(ICDC_CKCFG)
+#define REG_ICDC_RGADW REG32(ICDC_RGADW)
+#define REG_ICDC_RGDATA REG32(ICDC_RGDATA)
+
+/* ICDC Clock Configure Register */
+#define ICDC_CKCFG_CKRDY (1 << 1)
+#define ICDC_CKCFG_SELAD (1 << 0)
+
+/* ICDC internal register access control Register */
+#define ICDC_RGADW_RGWR (1 << 16)
+#define ICDC_RGADW_RGADDR_BIT 8
+#define ICDC_RGADW_RGADDR_MASK (0x7f << ICDC_RGADW_RGADDR_BIT)
+#define ICDC_RGADW_RGDIN_BIT 0
+#define ICDC_RGADW_RGDIN_MASK (0xff << ICDC_RGADW_RGDIN_BIT)
+
+/* ICDC internal register data output Register */
+#define ICDC_RGDATA_IRQ (1 << 8)
+#define ICDC_RGDATA_RGDOUT_BIT 0
+#define ICDC_RGDATA_RGDOUT_MASK (0xff << ICDC_RGDATA_RGDOUT_BIT)
+
+/*************************************************************************
+ * SPDIF INTERFACE in AIC Controller
+ *************************************************************************/
+
+#define SPDIF_ENA (AIC_BASE + 0x080)
+#define SPDIF_CTRL (AIC_BASE + 0x084)
+#define SPDIF_STATE (AIC_BASE + 0x088)
+#define SPDIF_CFG1 (AIC_BASE + 0x08c)
+#define SPDIF_CFG2 (AIC_BASE + 0x090)
+#define SPDIF_FIFO (AIC_BASE + 0x094)
+
+#define REG_SPDIF_ENA REG32(SPDIF_ENA)
+#define REG_SPDIF_CTRL REG32(SPDIF_CTRL)
+#define REG_SPDIF_STATE REG32(SPDIF_STATE)
+#define REG_SPDIF_CFG1 REG32(SPDIF_CFG1)
+#define REG_SPDIF_CFG2 REG32(SPDIF_CFG2)
+#define REG_SPDIF_FIFO REG32(SPDIF_FIFO)
+
+/* SPDIF Enable Register (SPDIF_ENA) */
+
+#define SPDIF_ENA_SPEN (1 << 0) /* Enable or disable the SPDIF transmitter */
+
+/* SPDIF Control Register (SPDIF_CTRL) */
+
+#define SPDIF_CTRL_DMAEN (1 << 15)
+#define SPDIF_CTRL_DTYPE (1 << 14)
+#define SPDIF_CTRL_SIGN (1 << 13)
+#define SPDIF_CTRL_INVALID (1 << 12)
+#define SPDIF_CTRL_RST (1 << 11)
+#define SPDIF_CTRL_SPDIFI2S (1 << 10)
+#define SPDIF_CTRL_MTRIG (1 << 1)
+#define SPDIF_CTRL_MFFUR (1 << 0)
+
+/* SPDIF Configure 1 Register (SPDIF_CFG1) */
+
+#define SPDIF_CFG1_INITLVL (1 << 17)
+#define SPDIF_CFG1_ZROVLD (1 << 16)
+
+#define SPDIF_CFG1_TRIG_BIT 12
+#define SPDIF_CFG1_TRIG_MASK (0x3 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_4 (0x0 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_8 (0x1 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_16 (0x2 << SPDIF_CFG1_TRIG_BIT)
+ #define SPDIF_CFG1_TRIG_32 (0x3 << SPDIF_CFG1_TRIG_BIT)
+
+#define SPDIF_CFG1_SRCNUM_BIT 8
+#define SPDIF_CFG1_SRCNUM_MASK (0xf << SPDIF_CFG1_SRCNUM_BIT)
+
+#define SPDIF_CFG1_CH1NUM_BIT 4
+#define SPDIF_CFG1_CH1NUM_MASK (0xf << SPDIF_CFG1_CH1NUM_BIT)
+
+#define SPDIF_CFG1_CH2NUM_BIT 0
+#define SPDIF_CFG1_CH2NUM_MASK (0xf << SPDIF_CFG1_CH2NUM_BIT)
+
+/* SPDIF Configure 2 Register (SPDIF_CFG2) */
+
+#define SPDIF_CFG2_FS_BIT 26
+#define SPDIF_CFG2_FS_MASK (0xf << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_44K (0x0 << SPDIF_CFG2_FS_BIT) /* 44.1kHz */
+ #define SPDIF_CFG2_FS_48K (0x2 << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_32K (0x3 << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_96K (0xa << SPDIF_CFG2_FS_BIT)
+ #define SPDIF_CFG2_FS_192K (0xe << SPDIF_CFG2_FS_BIT)
+
+#define SPDIF_CFG2_ORGFRQ_BIT 22
+#define SPDIF_CFG2_ORGFRQ_MASK (0xf << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_44K (0xf << SPDIF_CFG2_ORGFRQ_BIT) /* 44.1kHz */
+ #define SPDIF_CFG2_ORGFRQ_48K (0xd << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_32K (0xc << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_96K (0x5 << SPDIF_CFG2_ORGFRQ_BIT)
+ #define SPDIF_CFG2_ORGFRQ_192K (0x1 << SPDIF_CFG2_ORGFRQ_BIT)
+
+#define SPDIF_CFG2_SAMWL_BIT 19
+#define SPDIF_CFG2_SAMWL_MASK (0x7 << SPDIF_CFG2_SAMWL_BIT)
+
+#define SPDIF_CFG2_MAXWL (1 << 18)
+
+#define SPDIF_CFG2_CLKACU_BIT 16
+#define SPDIF_CFG2_CLKACU_MASK (0x3 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL2 (0x0 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL1 (0x1 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_LVL3 (0x2 << SPDIF_CFG2_CLKACU_BIT)
+ #define SPDIF_CFG2_CLKACU_NOTMAT (0x3 << SPDIF_CFG2_CLKACU_BIT)
+
+#define SPDIF_CFG2_CATCODE_BIT 8
+#define SPDIF_CFG2_CATCODE_MASK (0xff << SPDIF_CFG2_CATCODE_BIT)
+
+#define SPDIF_CFG2_CHMD_BIT 6
+#define SPDIF_CFG2_CHMD_MASK (0x3 << SPDIF_CFG2_CHMD_BIT)
+ #define SPDIF_CFG2_CHMD_MOD0 (0x0 << SPDIF_CFG2_CHMD_BIT)
+
+#define SPDIF_CFG2_PRE (1 << 3)
+#define SPDIF_CFG2_COPYN (1 << 2)
+#define SPDIF_CFG2_AUDION (1 << 1)
+#define SPDIF_CFG2_CONPRO (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * AIC (AC'97 & I2S Controller)
+ ***************************************************************************/
+
+#define __aic_enable() ( REG_AIC_FR |= AIC_FR_ENB )
+#define __aic_disable() ( REG_AIC_FR &= ~AIC_FR_ENB )
+
+#define __aic_select_ac97() ( REG_AIC_FR &= ~AIC_FR_AUSEL )
+#define __aic_select_i2s() ( REG_AIC_FR |= AIC_FR_AUSEL )
+
+#define __aic_play_zero() ( REG_AIC_FR &= ~AIC_FR_LSMP )
+#define __aic_play_lastsample() ( REG_AIC_FR |= AIC_FR_LSMP )
+
+#define __i2s_as_master() ( REG_AIC_FR |= AIC_FR_BCKD | AIC_FR_SYNCD )
+#define __i2s_as_slave() ( REG_AIC_FR &= ~(AIC_FR_BCKD | AIC_FR_SYNCD) )
+#define __aic_reset_status() ( REG_AIC_FR & AIC_FR_RST )
+
+#define __aic_reset() \
+do { \
+ REG_AIC_FR |= AIC_FR_RST; \
+} while(0)
+
+
+#define __aic_set_transmit_trigger(n) \
+do { \
+ REG_AIC_FR &= ~AIC_FR_TFTH_MASK; \
+ REG_AIC_FR |= ((n) << AIC_FR_TFTH_BIT); \
+} while(0)
+
+#define __aic_set_receive_trigger(n) \
+do { \
+ REG_AIC_FR &= ~AIC_FR_RFTH_MASK; \
+ REG_AIC_FR |= ((n) << AIC_FR_RFTH_BIT); \
+} while(0)
+
+#define __aic_enable_oldstyle() ( REG_AIC_CR |= AIC_CR_EN2OLD )
+#define __aic_enable_newstyle() ( REG_AIC_CR &= ~AIC_CR_EN2OLD )
+#define __aic_enable_pack16() ( REG_AIC_CR |= AIC_CR_PACK16 )
+#define __aic_enable_unpack16() ( REG_AIC_CR &= ~AIC_CR_PACK16)
+
+/* n = AIC_CR_CHANNEL_MONO,AIC_CR_CHANNEL_STEREO ... */
+#define __aic_out_channel_select(n) \
+do { \
+ REG_AIC_CR &= ~AIC_CR_CHANNEL_MASK; \
+ REG_AIC_CR |= ((n) << AIC_CR_CHANNEL_BIT ); \
+} while(0)
+
+#define __aic_enable_record() ( REG_AIC_CR |= AIC_CR_EREC )
+#define __aic_disable_record() ( REG_AIC_CR &= ~AIC_CR_EREC )
+#define __aic_enable_replay() ( REG_AIC_CR |= AIC_CR_ERPL )
+#define __aic_disable_replay() ( REG_AIC_CR &= ~AIC_CR_ERPL )
+#define __aic_enable_loopback() ( REG_AIC_CR |= AIC_CR_ENLBF )
+#define __aic_disable_loopback() ( REG_AIC_CR &= ~AIC_CR_ENLBF )
+
+#define __aic_flush_tfifo() ( REG_AIC_CR |= AIC_CR_TFLUSH )
+#define __aic_unflush_tfifo() ( REG_AIC_CR &= ~AIC_CR_TFLUSH )
+#define __aic_flush_rfifo() ( REG_AIC_CR |= AIC_CR_RFLUSH )
+#define __aic_unflush_rfifo() ( REG_AIC_CR &= ~AIC_CR_RFLUSH )
+
+#define __aic_enable_transmit_intr() \
+ ( REG_AIC_CR |= (AIC_CR_ETFS | AIC_CR_ETUR) )
+#define __aic_disable_transmit_intr() \
+ ( REG_AIC_CR &= ~(AIC_CR_ETFS | AIC_CR_ETUR) )
+#define __aic_enable_receive_intr() \
+ ( REG_AIC_CR |= (AIC_CR_ERFS | AIC_CR_EROR) )
+#define __aic_disable_receive_intr() \
+ ( REG_AIC_CR &= ~(AIC_CR_ERFS | AIC_CR_EROR) )
+
+#define __aic_enable_transmit_dma() ( REG_AIC_CR |= AIC_CR_TDMS )
+#define __aic_disable_transmit_dma() ( REG_AIC_CR &= ~AIC_CR_TDMS )
+#define __aic_enable_receive_dma() ( REG_AIC_CR |= AIC_CR_RDMS )
+#define __aic_disable_receive_dma() ( REG_AIC_CR &= ~AIC_CR_RDMS )
+
+#define __aic_enable_mono2stereo() ( REG_AIC_CR |= AIC_CR_M2S )
+#define __aic_disable_mono2stereo() ( REG_AIC_CR &= ~AIC_CR_M2S )
+#define __aic_enable_byteswap() ( REG_AIC_CR |= AIC_CR_ENDSW )
+#define __aic_disable_byteswap() ( REG_AIC_CR &= ~AIC_CR_ENDSW )
+#define __aic_enable_unsignadj() ( REG_AIC_CR |= AIC_CR_AVSTSU )
+#define __aic_disable_unsignadj() ( REG_AIC_CR &= ~AIC_CR_AVSTSU )
+
+#define AC97_PCM_XS_L_FRONT AIC_ACCR1_XS_SLOT3
+#define AC97_PCM_XS_R_FRONT AIC_ACCR1_XS_SLOT4
+#define AC97_PCM_XS_CENTER AIC_ACCR1_XS_SLOT6
+#define AC97_PCM_XS_L_SURR AIC_ACCR1_XS_SLOT7
+#define AC97_PCM_XS_R_SURR AIC_ACCR1_XS_SLOT8
+#define AC97_PCM_XS_LFE AIC_ACCR1_XS_SLOT9
+
+#define AC97_PCM_RS_L_FRONT AIC_ACCR1_RS_SLOT3
+#define AC97_PCM_RS_R_FRONT AIC_ACCR1_RS_SLOT4
+#define AC97_PCM_RS_CENTER AIC_ACCR1_RS_SLOT6
+#define AC97_PCM_RS_L_SURR AIC_ACCR1_RS_SLOT7
+#define AC97_PCM_RS_R_SURR AIC_ACCR1_RS_SLOT8
+#define AC97_PCM_RS_LFE AIC_ACCR1_RS_SLOT9
+
+#define __ac97_set_xs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK )
+#define __ac97_set_xs_mono() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_XS_R_FRONT; \
+} while(0)
+#define __ac97_set_xs_stereo() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT; \
+} while(0)
+
+/* In fact, only stereo is support now. */
+#define __ac97_set_rs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK )
+#define __ac97_set_rs_mono() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_RS_R_FRONT; \
+} while(0)
+#define __ac97_set_rs_stereo() \
+do { \
+ REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \
+ REG_AIC_ACCR1 |= AC97_PCM_RS_L_FRONT | AC97_PCM_RS_R_FRONT; \
+} while(0)
+
+#define __ac97_warm_reset_codec() \
+ do { \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SA; \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SS; \
+ udelay(2); \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SS; \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SA; \
+ } while (0)
+
+#define __ac97_cold_reset_codec() \
+ do { \
+ REG_AIC_ACCR2 |= AIC_ACCR2_SR; \
+ udelay(2); \
+ REG_AIC_ACCR2 &= ~AIC_ACCR2_SR; \
+ } while (0)
+
+/* n=8,16,18,20 */
+#define __ac97_set_iass(n) \
+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_IASS_MASK) | AIC_ACCR2_IASS_##n##BIT )
+#define __ac97_set_oass(n) \
+ ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_OASS_MASK) | AIC_ACCR2_OASS_##n##BIT )
+
+/* This bit should only be set in 2 channels configuration */
+#define __i2s_send_rfirst() ( REG_AIC_I2SCR |= AIC_I2SCR_RFIRST ) /* RL */
+#define __i2s_send_lfirst() ( REG_AIC_I2SCR &= ~AIC_I2SCR_RFIRST ) /* LR */
+
+/* This bit should only be set in 2 channels configuration and 16bit-packed mode */
+#define __i2s_switch_lr() ( REG_AIC_I2SCR |= AIC_I2SCR_SWLH )
+#define __i2s_unswitch_lr() ( REG_AIC_I2SCR &= ~AIC_I2SCR_SWLH )
+
+#define __i2s_select_i2s() ( REG_AIC_I2SCR &= ~AIC_I2SCR_AMSL )
+#define __i2s_select_msbjustified() ( REG_AIC_I2SCR |= AIC_I2SCR_AMSL )
+
+/* n=8,16,18,20,24 */
+/*#define __i2s_set_sample_size(n) \
+ ( REG_AIC_I2SCR |= (REG_AIC_I2SCR & ~AIC_I2SCR_WL_MASK) | AIC_I2SCR_WL_##n##BIT )*/
+
+#define __i2s_out_channel_select(n) __aic_out_channel_select(n)
+
+#define __i2s_set_oss_sample_size(n) \
+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_OSS_MASK) | AIC_CR_OSS_##n##BIT )
+#define __i2s_set_iss_sample_size(n) \
+ ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_ISS_MASK) | AIC_CR_ISS_##n##BIT )
+
+#define __i2s_stop_bitclk() ( REG_AIC_I2SCR |= AIC_I2SCR_STPBK )
+#define __i2s_start_bitclk() ( REG_AIC_I2SCR &= ~AIC_I2SCR_STPBK )
+
+#define __aic_transmit_request() ( REG_AIC_SR & AIC_SR_TFS )
+#define __aic_receive_request() ( REG_AIC_SR & AIC_SR_RFS )
+#define __aic_transmit_underrun() ( REG_AIC_SR & AIC_SR_TUR )
+#define __aic_receive_overrun() ( REG_AIC_SR & AIC_SR_ROR )
+
+#define __aic_clear_errors() ( REG_AIC_SR &= ~(AIC_SR_TUR | AIC_SR_ROR) )
+
+#define __aic_get_transmit_resident() \
+ ( (REG_AIC_SR & AIC_SR_TFL_MASK) >> AIC_SR_TFL_BIT )
+#define __aic_get_receive_count() \
+ ( (REG_AIC_SR & AIC_SR_RFL_MASK) >> AIC_SR_RFL_BIT )
+
+#define __ac97_command_transmitted() ( REG_AIC_ACSR & AIC_ACSR_CADT )
+#define __ac97_status_received() ( REG_AIC_ACSR & AIC_ACSR_SADR )
+#define __ac97_status_receive_timeout() ( REG_AIC_ACSR & AIC_ACSR_RSTO )
+#define __ac97_codec_is_low_power_mode() ( REG_AIC_ACSR & AIC_ACSR_CLPM )
+#define __ac97_codec_is_ready() ( REG_AIC_ACSR & AIC_ACSR_CRDY )
+#define __ac97_slot_error_detected() ( REG_AIC_ACSR & AIC_ACSR_SLTERR )
+#define __ac97_clear_slot_error() ( REG_AIC_ACSR &= ~AIC_ACSR_SLTERR )
+
+#define __i2s_is_busy() ( REG_AIC_I2SSR & AIC_I2SSR_BSY )
+
+#define CODEC_READ_CMD (1 << 19)
+#define CODEC_WRITE_CMD (0 << 19)
+#define CODEC_REG_INDEX_BIT 12
+#define CODEC_REG_INDEX_MASK (0x7f << CODEC_REG_INDEX_BIT) /* 18:12 */
+#define CODEC_REG_DATA_BIT 4
+#define CODEC_REG_DATA_MASK (0x0ffff << 4) /* 19:4 */
+
+#define __ac97_out_rcmd_addr(reg) \
+do { \
+ REG_AIC_ACCAR = CODEC_READ_CMD | ((reg) << CODEC_REG_INDEX_BIT); \
+} while (0)
+
+#define __ac97_out_wcmd_addr(reg) \
+do { \
+ REG_AIC_ACCAR = CODEC_WRITE_CMD | ((reg) << CODEC_REG_INDEX_BIT); \
+} while (0)
+
+#define __ac97_out_data(value) \
+do { \
+ REG_AIC_ACCDR = ((value) << CODEC_REG_DATA_BIT); \
+} while (0)
+
+#define __ac97_in_data() \
+ ( (REG_AIC_ACSDR & CODEC_REG_DATA_MASK) >> CODEC_REG_DATA_BIT )
+
+#define __ac97_in_status_addr() \
+ ( (REG_AIC_ACSAR & CODEC_REG_INDEX_MASK) >> CODEC_REG_INDEX_BIT )
+
+#define __i2s_set_sample_rate(i2sclk, sync) \
+ ( REG_AIC_I2SDIV = ((i2sclk) / (4*64)) / (sync) )
+
+#define __aic_write_tfifo(v) ( REG_AIC_DR = (v) )
+#define __aic_read_rfifo() ( REG_AIC_DR )
+
+#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC )
+#define __aic_external_codec() ( REG_AIC_FR &= ~AIC_FR_ICDC )
+
+//
+// Define next ops for AC97 compatible
+//
+
+#define AC97_ACSR AIC_ACSR
+
+#define __ac97_enable() __aic_enable(); __aic_select_ac97()
+#define __ac97_disable() __aic_disable()
+#define __ac97_reset() __aic_reset()
+
+#define __ac97_set_transmit_trigger(n) __aic_set_transmit_trigger(n)
+#define __ac97_set_receive_trigger(n) __aic_set_receive_trigger(n)
+
+#define __ac97_enable_record() __aic_enable_record()
+#define __ac97_disable_record() __aic_disable_record()
+#define __ac97_enable_replay() __aic_enable_replay()
+#define __ac97_disable_replay() __aic_disable_replay()
+#define __ac97_enable_loopback() __aic_enable_loopback()
+#define __ac97_disable_loopback() __aic_disable_loopback()
+
+#define __ac97_enable_transmit_dma() __aic_enable_transmit_dma()
+#define __ac97_disable_transmit_dma() __aic_disable_transmit_dma()
+#define __ac97_enable_receive_dma() __aic_enable_receive_dma()
+#define __ac97_disable_receive_dma() __aic_disable_receive_dma()
+
+#define __ac97_transmit_request() __aic_transmit_request()
+#define __ac97_receive_request() __aic_receive_request()
+#define __ac97_transmit_underrun() __aic_transmit_underrun()
+#define __ac97_receive_overrun() __aic_receive_overrun()
+
+#define __ac97_clear_errors() __aic_clear_errors()
+
+#define __ac97_get_transmit_resident() __aic_get_transmit_resident()
+#define __ac97_get_receive_count() __aic_get_receive_count()
+
+#define __ac97_enable_transmit_intr() __aic_enable_transmit_intr()
+#define __ac97_disable_transmit_intr() __aic_disable_transmit_intr()
+#define __ac97_enable_receive_intr() __aic_enable_receive_intr()
+#define __ac97_disable_receive_intr() __aic_disable_receive_intr()
+
+#define __ac97_write_tfifo(v) __aic_write_tfifo(v)
+#define __ac97_read_rfifo() __aic_read_rfifo()
+
+//
+// Define next ops for I2S compatible
+//
+
+#define I2S_ACSR AIC_I2SSR
+
+#define __i2s_enable() __aic_enable(); __aic_select_i2s()
+#define __i2s_disable() __aic_disable()
+#define __i2s_reset() __aic_reset()
+
+#define __i2s_set_transmit_trigger(n) __aic_set_transmit_trigger(n)
+#define __i2s_set_receive_trigger(n) __aic_set_receive_trigger(n)
+
+#define __i2s_enable_record() __aic_enable_record()
+#define __i2s_disable_record() __aic_disable_record()
+#define __i2s_enable_replay() __aic_enable_replay()
+#define __i2s_disable_replay() __aic_disable_replay()
+#define __i2s_enable_loopback() __aic_enable_loopback()
+#define __i2s_disable_loopback() __aic_disable_loopback()
+
+#define __i2s_enable_transmit_dma() __aic_enable_transmit_dma()
+#define __i2s_disable_transmit_dma() __aic_disable_transmit_dma()
+#define __i2s_enable_receive_dma() __aic_enable_receive_dma()
+#define __i2s_disable_receive_dma() __aic_disable_receive_dma()
+
+#define __i2s_transmit_request() __aic_transmit_request()
+#define __i2s_receive_request() __aic_receive_request()
+#define __i2s_transmit_underrun() __aic_transmit_underrun()
+#define __i2s_receive_overrun() __aic_receive_overrun()
+
+#define __i2s_clear_errors() __aic_clear_errors()
+
+#define __i2s_get_transmit_resident() __aic_get_transmit_resident()
+#define __i2s_get_receive_count() __aic_get_receive_count()
+
+#define __i2s_enable_transmit_intr() __aic_enable_transmit_intr()
+#define __i2s_disable_transmit_intr() __aic_disable_transmit_intr()
+#define __i2s_enable_receive_intr() __aic_enable_receive_intr()
+#define __i2s_disable_receive_intr() __aic_disable_receive_intr()
+
+#define __i2s_write_tfifo(v) __aic_write_tfifo(v)
+#define __i2s_read_rfifo() __aic_read_rfifo()
+
+#define __i2s_reset_codec() \
+ do { \
+ } while (0)
+
+
+/*************************************************************************
+ * SPDIF INTERFACE in AIC Controller
+ *************************************************************************/
+
+#define __spdif_enable() ( REG_SPDIF_ENA |= SPDIF_ENA_SPEN )
+#define __spdif_disable() ( REG_SPDIF_ENA &= ~SPDIF_ENA_SPEN )
+
+#define __spdif_enable_transmit_dma() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DMAEN )
+#define __spdif_disable_transmit_dma() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DMAEN )
+#define __spdif_enable_dtype() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DTYPE )
+#define __spdif_disable_dtype() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DTYPE )
+#define __spdif_enable_sign() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SIGN )
+#define __spdif_disable_sign() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SIGN )
+#define __spdif_enable_invalid() ( REG_SPDIF_CTRL |= SPDIF_CTRL_INVALID )
+#define __spdif_disable_invalid() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_INVALID )
+#define __spdif_enable_reset() ( REG_SPDIF_CTRL |= SPDIF_CTRL_RST )
+#define __spdif_select_spdif() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SPDIFI2S )
+#define __spdif_select_i2s() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SPDIFI2S )
+#define __spdif_enable_MTRIGmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MTRIG )
+#define __spdif_disable_MTRIGmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MTRIG )
+#define __spdif_enable_MFFURmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MFFUR )
+#define __spdif_disable_MFFURmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MFFUR )
+
+#define __spdif_enable_initlvl_high() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_INITLVL )
+#define __spdif_enable_initlvl_low() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_INITLVL )
+#define __spdif_enable_zrovld_invald() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_ZROVLD )
+#define __spdif_enable_zrovld_vald() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_ZROVLD )
+
+/* 0, 1, 2, 3 */
+#define __spdif_set_transmit_trigger(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_TRIG_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_TRIG_BIT ); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_srcnum(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_SRCNUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_SRCNUM_BIT); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_ch1num(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH1NUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH1NUM_BIT); \
+} while(0)
+
+/* 1 ~ 15 */
+#define __spdif_set_ch2num(n) \
+do { \
+ REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH2NUM_MASK; \
+ REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH2NUM_BIT); \
+} while(0)
+
+/* 0x0, 0x2, 0x3, 0xa, 0xe */
+#define __spdif_set_fs(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_FS_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_FS_BIT); \
+} while(0)
+
+/* 0xd, 0xc, 0x5, 0x1 */
+#define __spdif_set_orgfrq(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_ORGFRQ_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_ORGFRQ_BIT); \
+} while(0)
+
+/* 0x1, 0x6, 0x2, 0x4, 0x5 */
+#define __spdif_set_samwl(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_SAMWL_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_SAMWL_BIT); \
+} while(0)
+
+#define __spdif_enable_samwl_24() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_MAXWL )
+#define __spdif_enable_samwl_20() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG2_MAXWL )
+
+/* 0x1, 0x1, 0x2, 0x3 */
+#define __spdif_set_clkacu(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CLKACU_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CLKACU_BIT); \
+} while(0)
+
+/* see IEC60958-3 */
+#define __spdif_set_catcode(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CATCODE_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CATCODE_BIT); \
+} while(0)
+
+/* n = 0x0, */
+#define __spdif_set_chmode(n) \
+do { \
+ REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CHMD_MASK; \
+ REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CHMD_BIT); \
+} while(0)
+
+#define __spdif_enable_pre() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_PRE )
+#define __spdif_disable_pre() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_PRE )
+#define __spdif_enable_copyn() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_COPYN )
+#define __spdif_disable_copyn() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_COPYN )
+/* audio sample word represents linear PCM samples */
+#define __spdif_enable_audion() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_AUDION )
+/* udio sample word used for other purpose */
+#define __spdif_disable_audion() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_AUDION )
+#define __spdif_enable_conpro() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CONPRO )
+#define __spdif_disable_conpro() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_CONPRO )
+
+/***************************************************************************
+ * ICDC
+ ***************************************************************************/
+#define __i2s_internal_codec() __aic_internal_codec()
+#define __i2s_external_codec() __aic_external_codec()
+
+#define __icdc_clk_ready() ( REG_ICDC_CKCFG & ICDC_CKCFG_CKRDY )
+#define __icdc_sel_adc() ( REG_ICDC_CKCFG |= ICDC_CKCFG_SELAD )
+#define __icdc_sel_dac() ( REG_ICDC_CKCFG &= ~ICDC_CKCFG_SELAD )
+
+#define __icdc_set_rgwr() ( REG_ICDC_RGADW |= ICDC_RGADW_RGWR )
+#define __icdc_clear_rgwr() ( REG_ICDC_RGADW &= ~ICDC_RGADW_RGWR )
+#define __icdc_rgwr_ready() ( REG_ICDC_RGADW & ICDC_RGADW_RGWR )
+
+#define __icdc_set_addr(n) \
+do { \
+ REG_ICDC_RGADW &= ~ICDC_RGADW_RGADDR_MASK; \
+ REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGADDR_BIT; \
+} while(0)
+
+#define __icdc_set_cmd(n) \
+do { \
+ REG_ICDC_RGADW &= ~ICDC_RGADW_RGDIN_MASK; \
+ REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGDIN_BIT; \
+} while(0)
+
+#define __icdc_irq_pending() ( REG_ICDC_RGDATA & ICDC_RGDATA_IRQ )
+#define __icdc_get_value() ( REG_ICDC_RGDATA & ICDC_RGDATA_RGDOUT_MASK )
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810AIC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810bch.h b/arch/mips/include/asm/mach-jz4810/jz4810bch.h
new file mode 100644
index 00000000000..426c41ac23f
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810bch.h
@@ -0,0 +1,207 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810bch.h
+ *
+ * JZ4810 bch register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810BCH_H__
+#define __JZ4810BCH_H__
+
+
+#define BCH_BASE 0xB34D0000
+
+/*************************************************************************
+ * BCH
+ *************************************************************************/
+#define BCH_CR (BCH_BASE + 0x00) /* BCH Control register */
+#define BCH_CRS (BCH_BASE + 0x04) /* BCH Control Set register */
+#define BCH_CRC (BCH_BASE + 0x08) /* BCH Control Clear register */
+#define BCH_CNT (BCH_BASE + 0x0C) /* BCH ENC/DEC Count register */
+#define BCH_DR (BCH_BASE + 0x10) /* BCH data register */
+#define BCH_PAR0 (BCH_BASE + 0x14) /* BCH Parity 0 register */
+#define BCH_PAR1 (BCH_BASE + 0x18) /* BCH Parity 1 register */
+#define BCH_PAR2 (BCH_BASE + 0x1C) /* BCH Parity 2 register */
+#define BCH_PAR3 (BCH_BASE + 0x20) /* BCH Parity 3 register */
+#define BCH_PAR4 (BCH_BASE + 0x24) /* BCH Parity 4 register */
+#define BCH_PAR5 (BCH_BASE + 0x28) /* BCH Parity 5 register */
+#define BCH_PAR6 (BCH_BASE + 0x2C) /* BCH Parity 6 register */
+#define BCH_PAR7 (BCH_BASE + 0x30) /* BCH Parity 7 register */
+#define BCH_PAR8 (BCH_BASE + 0x34) /* BCH Parity 8 register */
+#define BCH_PAR9 (BCH_BASE + 0x38) /* BCH Parity 9 register */
+#define BCH_ERR0 (BCH_BASE + 0x3C) /* BCH Error Report 0 register */
+#define BCH_ERR1 (BCH_BASE + 0x40) /* BCH Error Report 1 register */
+#define BCH_ERR2 (BCH_BASE + 0x44) /* BCH Error Report 2 register */
+#define BCH_ERR3 (BCH_BASE + 0x48) /* BCH Error Report 3 register */
+#define BCH_ERR4 (BCH_BASE + 0x4C) /* BCH Error Report 4 register */
+#define BCH_ERR5 (BCH_BASE + 0x50) /* BCH Error Report 5 register */
+#define BCH_ERR6 (BCH_BASE + 0x54) /* BCH Error Report 6 register */
+#define BCH_ERR7 (BCH_BASE + 0x58) /* BCH Error Report 7 register */
+#define BCH_ERR8 (BCH_BASE + 0x5C) /* BCH Error Report 8 register */
+#define BCH_ERR9 (BCH_BASE + 0x60) /* BCH Error Report 9 register */
+#define BCH_ERR10 (BCH_BASE + 0x64) /* BCH Error Report 10 register */
+#define BCH_ERR11 (BCH_BASE + 0x68) /* BCH Error Report 11 register */
+#define BCH_INTS (BCH_BASE + 0x6C) /* BCH Interrupt Status register */
+#define BCH_INTES (BCH_BASE + 0x70) /* BCH Interrupt Enable register */
+#define BCH_INTEC (BCH_BASE + 0x74) /* BCH Interrupt Set register */
+#define BCH_INTE (BCH_BASE + 0x78) /* BCH Interrupt Clear register */
+
+#define REG_BCH_CR REG32(BCH_CR)
+#define REG_BCH_CRS REG32(BCH_CRS)
+#define REG_BCH_CRC REG32(BCH_CRC)
+#define REG_BCH_CNT REG32(BCH_CNT)
+#define REG_BCH_DR REG8(BCH_DR)
+#define REG_BCH_PAR0 REG32(BCH_PAR0)
+#define REG_BCH_PAR1 REG32(BCH_PAR1)
+#define REG_BCH_PAR2 REG32(BCH_PAR2)
+#define REG_BCH_PAR3 REG32(BCH_PAR3)
+#define REG_BCH_PAR4 REG32(BCH_PAR4)
+#define REG_BCH_PAR5 REG32(BCH_PAR5)
+#define REG_BCH_PAR6 REG32(BCH_PAR6)
+#define REG_BCH_PAR7 REG32(BCH_PAR7)
+#define REG_BCH_PAR8 REG32(BCH_PAR8)
+#define REG_BCH_PAR9 REG32(BCH_PAR9)
+#define REG_BCH_ERR0 REG32(BCH_ERR0)
+#define REG_BCH_ERR1 REG32(BCH_ERR1)
+#define REG_BCH_ERR2 REG32(BCH_ERR2)
+#define REG_BCH_ERR3 REG32(BCH_ERR3)
+#define REG_BCH_ERR4 REG32(BCH_ERR4)
+#define REG_BCH_ERR5 REG32(BCH_ERR5)
+#define REG_BCH_ERR6 REG32(BCH_ERR6)
+#define REG_BCH_ERR7 REG32(BCH_ERR7)
+#define REG_BCH_ERR8 REG32(BCH_ERR8)
+#define REG_BCH_ERR9 REG32(BCH_ERR9)
+#define REG_BCH_ERR10 REG32(BCH_ERR10)
+#define REG_BCH_ERR11 REG32(BCH_ERR11)
+#define REG_BCH_INTS REG32(BCH_INTS)
+#define REG_BCH_INTE REG32(BCH_INTE)
+#define REG_BCH_INTEC REG32(BCH_INTEC)
+#define REG_BCH_INTES REG32(BCH_INTES)
+
+/* BCH Control Register*/
+#define BCH_CR_DMAE (1 << 7) /* BCH DMA Enable */
+#define BCH_CR_BSEL_BIT 3
+#define BCH_CR_BSEL_MASK (0x3 << BCH_CR_BSEL_BIT)
+ #define BCH_CR_BSEL_4 (0x0 << BCH_CR_BSEL_BIT) /* 4 Bit BCH Select */
+ #define BCH_CR_BSEL_8 (0x1 << BCH_CR_BSEL_BIT) /* 8 Bit BCH Select */
+ #define BCH_CR_BSEL_12 (0x2 << BCH_CR_BSEL_BIT) /* 12 Bit BCH Select */
+ #define BCH_CR_BSEL_16 (0x3 << BCH_CR_BSEL_BIT) /* 16 Bit BCH Select */
+ #define BCH_CR_BSEL_20 (0x4 << BCH_CR_BSEL_BIT) /* 20 Bit BCH Select */
+ #define BCH_CR_BSEL_24 (0x5 << BCH_CR_BSEL_BIT) /* 24 Bit BCH Select */
+#define BCH_CR_ENCE (1 << 2) /* BCH Encoding Select */
+#define BCH_CR_DECE (0 << 2) /* BCH Decoding Select */
+#define BCH_CR_BRST (1 << 1) /* BCH Reset */
+#define BCH_CR_BCHE (1 << 0) /* BCH Enable */
+
+/* BCH Interrupt Status Register */
+#define BCH_INTS_ERRC_BIT 27
+#define BCH_INTS_ERRC_MASK (0x1f << BCH_INTS_ERRC_BIT)
+#define BCH_INTS_ALL0 (1 << 5)
+#define BCH_INTS_ALLf (1 << 4)
+#define BCH_INTS_DECF (1 << 3)
+#define BCH_INTS_ENCF (1 << 2)
+#define BCH_INTS_UNCOR (1 << 1)
+#define BCH_INTS_ERR (1 << 0)
+
+/* BCH ENC/DEC Count Register */
+#define BCH_CNT_DEC_BIT 16
+#define BCH_CNT_DEC_MASK (0x7ff << BCH_CNT_DEC_BIT)
+#define BCH_CNT_ENC_BIT 0
+#define BCH_CNT_ENC_MASK (0x7ff << BCH_CNT_ENC_BIT)
+
+/* BCH Error Report Register */
+#define BCH_ERR_INDEX_ODD_BIT 0
+#define BCH_ERR_INDEX_ODD_MASK (0x1fff << BCH_ERR_INDEX_ODD_BIT)
+#define BCH_ERR_INDEX_EVEN_BIT 16
+#define BCH_ERR_INDEX_EVEN_MASK (0x1fff << BCH_ERR_INDEX_EVEN_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * BCH
+ *************************************************************************/
+#define __ecc_encoding_4bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_4 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_4 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_4bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_4 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_4 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_8bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_8 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_8 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_8bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_8 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_8 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_12bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_12 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_12 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_12bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_12 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_12 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_16bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_16 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_16 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_16bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_16 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_16 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_20bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_20 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_20 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_20bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_20 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_20 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_encoding_24bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_24 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_24 | BCH_CR_ENCE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_decoding_24bit() \
+do { \
+ REG_BCH_CRS = BCH_CR_BSEL_24 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE; \
+ REG_BCH_CRC = ~(BCH_CR_BSEL_24 | BCH_CR_DECE | BCH_CR_BRST | BCH_CR_BCHE); \
+} while(0)
+#define __ecc_dma_enable() ( REG_BCH_CRS = BCH_CR_DMAE )
+#define __ecc_dma_disable() ( REG_BCH_CRC = BCH_CR_DMAE )
+#define __ecc_disable() ( REG_BCH_CRC = BCH_CR_BCHE )
+#define __ecc_encode_sync() while (!(REG_BCH_INTS & BCH_INTS_ENCF))
+#define __ecc_decode_sync() while (!(REG_BCH_INTS & BCH_INTS_DECF))
+
+#define __ecc_cnt_dec(n) \
+do { \
+ REG_BCH_CNT &= ~BCH_CNT_DEC_MASK; \
+ REG_BCH_CNT |= (n) << BCH_CNT_DEC_BIT; \
+} while(0)
+#define __ecc_cnt_enc(n) \
+do { \
+ REG_BCH_CNT &= ~BCH_CNT_ENC_MASK; \
+ REG_BCH_CNT |= (n) << BCH_CNT_ENC_BIT; \
+} while(0)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810BCH_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810bdma.h b/arch/mips/include/asm/mach-jz4810/jz4810bdma.h
new file mode 100644
index 00000000000..fa9e558b2a3
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810bdma.h
@@ -0,0 +1,297 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810bdma.h
+ *
+ * JZ4810 BDMA register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810BDMA_H__
+#define __JZ4810BDMA_H__
+
+
+#define BDMAC_BASE 0xB3450000
+
+
+/*************************************************************************
+ * BDMAC (BCH & NAND DMA Controller)
+ *************************************************************************/
+
+/* n is the DMA channel index (0 - 2) */
+#define BDMAC_DSAR(n) (BDMAC_BASE + (0x00 + (n) * 0x20)) /* DMA source address */
+#define BDMAC_DTAR(n) (BDMAC_BASE + (0x04 + (n) * 0x20)) /* DMA target address */
+#define BDMAC_DTCR(n) (BDMAC_BASE + (0x08 + (n) * 0x20)) /* DMA transfer count */
+#define BDMAC_DRSR(n) (BDMAC_BASE + (0x0c + (n) * 0x20)) /* DMA request source */
+#define BDMAC_DCCSR(n) (BDMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */
+#define BDMAC_DCMD(n) (BDMAC_BASE + (0x14 + (n) * 0x20)) /* DMA command */
+#define BDMAC_DDA(n) (BDMAC_BASE + (0x18 + (n) * 0x20)) /* DMA descriptor address */
+#define BDMAC_DSD(n) (BDMAC_BASE + (0x1c + (n) * 0x20)) /* DMA Stride Address */
+#define BDMAC_DNT(n) (BDMAC_BASE + (0xc0 + (n) * 0x04)) /* NAND Detect Timer */
+
+#define BDMAC_DMACR (BDMAC_BASE + 0x0300) /* DMA control register */
+#define BDMAC_DMAIPR (BDMAC_BASE + 0x0304) /* DMA interrupt pending */
+#define BDMAC_DMADBR (BDMAC_BASE + 0x0308) /* DMA doorbell */
+#define BDMAC_DMADBSR (BDMAC_BASE + 0x030C) /* DMA doorbell set */
+#define BDMAC_DMACKE (BDMAC_BASE + 0x0310)
+
+#define REG_BDMAC_DSAR(n) REG32(BDMAC_DSAR((n)))
+#define REG_BDMAC_DTAR(n) REG32(BDMAC_DTAR((n)))
+#define REG_BDMAC_DTCR(n) REG32(BDMAC_DTCR((n)))
+#define REG_BDMAC_DRSR(n) REG32(BDMAC_DRSR((n)))
+#define REG_BDMAC_DCCSR(n) REG32(BDMAC_DCCSR((n)))
+#define REG_BDMAC_DCMD(n) REG32(BDMAC_DCMD((n)))
+#define REG_BDMAC_DDA(n) REG32(BDMAC_DDA((n)))
+#define REG_BDMAC_DSD(n) REG32(BDMAC_DSD(n))
+#define REG_BDMAC_DNT(n) REG32(BDMAC_DNT(n))
+
+#define REG_BDMAC_DMACR REG32(BDMAC_DMACR)
+#define REG_BDMAC_DMAIPR REG32(BDMAC_DMAIPR)
+#define REG_BDMAC_DMADBR REG32(BDMAC_DMADBR)
+#define REG_BDMAC_DMADBSR REG32(BDMAC_DMADBSR)
+#define REG_BDMAC_DMACKE REG32(BDMAC_DMACKE)
+
+// BDMA request source register
+#define BDMAC_DRSR_RS_BIT 0
+ #define BDMAC_DRSR_RS_MASK (0x3f << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_NAND (1 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_BCH_ENC (2 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_BCH_DEC (3 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT)
+ #define BDMAC_DRSR_RS_EXT (12 << DMAC_DRSR_RS_BIT)
+
+// BDMA channel control/status register
+#define BDMAC_DCCSR_NDES (1 << 31) /* descriptor (0) or not (1) ? */
+#define BDMAC_DCCSR_DES8 (1 << 30) /* Descriptor 8 Word */
+#define BDMAC_DCCSR_DES4 (0 << 30) /* Descriptor 4 Word */
+#define BDMAC_DCCSR_CDOA_BIT 16 /* copy of DMA offset address */
+ #define BDMAC_DCCSR_CDOA_MASK (0xff << BDMACC_DCCSR_CDOA_BIT)
+#define BDMAC_DCCSR_BERR (1 << 7) /* BCH error within this transfer, Only for channel 0 */
+#define BDMAC_DCCSR_AR (1 << 4) /* address error */
+#define BDMAC_DCCSR_TT (1 << 3) /* transfer terminated */
+#define BDMAC_DCCSR_HLT (1 << 2) /* DMA halted */
+#define BDMAC_DCCSR_EN (1 << 0) /* channel enable bit */
+
+// BDMA channel command register
+#define BDMAC_DCMD_EACKS_LOW (1 << 31) /* External DACK Output Level Select, active low */
+#define BDMAC_DCMD_EACKS_HIGH (0 << 31) /* External DACK Output Level Select, active high */
+#define BDMAC_DCMD_EACKM_WRITE (1 << 30) /* External DACK Output Mode Select, output in write cycle */
+#define BDMAC_DCMD_EACKM_READ (0 << 30) /* External DACK Output Mode Select, output in read cycle */
+#define BDMAC_DCMD_ERDM_BIT 28 /* External DREQ Detection Mode Select */
+ #define BDMAC_DCMD_ERDM_MASK (0x03 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_LOW (0 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_FALL (1 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_HIGH (2 << BDMAC_DCMD_ERDM_BIT)
+ #define BDMAC_DCMD_ERDM_RISE (3 << BDMAC_DCMD_ERDM_BIT)
+#define BDMAC_DCMD_BLAST (1 << 25) /* BCH last */
+#define BDMAC_DCMD_SAI (1 << 23) /* source address increment */
+#define BDMAC_DCMD_DAI (1 << 22) /* dest address increment */
+#define BDMAC_DCMD_SWDH_BIT 14 /* source port width */
+ #define BDMAC_DCMD_SWDH_MASK (0x03 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_32 (0 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_8 (1 << BDMAC_DCMD_SWDH_BIT)
+ #define BDMAC_DCMD_SWDH_16 (2 << BDMAC_DCMD_SWDH_BIT)
+#define BDMAC_DCMD_DWDH_BIT 12 /* dest port width */
+ #define BDMAC_DCMD_DWDH_MASK (0x03 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_32 (0 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_8 (1 << BDMAC_DCMD_DWDH_BIT)
+ #define BDMAC_DCMD_DWDH_16 (2 << BDMAC_DCMD_DWDH_BIT)
+#define BDMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */
+ #define BDMAC_DCMD_DS_MASK (0x07 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_32BIT (0 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_8BIT (1 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_16BIT (2 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_16BYTE (3 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_32BYTE (4 << BDMAC_DCMD_DS_BIT)
+ #define BDMAC_DCMD_DS_64BYTE (5 << BDMAC_DCMD_DS_BIT)
+#define BDMAC_DCMD_NRD (1 << 7) /* NAND direct read */
+#define BDMAC_DCMD_NWR (1 << 6) /* NAND direct write */
+#define BDMAC_DCMD_NAC (1 << 5) /* NAND AL/CL enable */
+#define BDMAC_DCMD_STDE (1 << 2) /* Stride Disable/Enable */
+#define BDMAC_DCMD_TIE (1 << 1) /* DMA transfer interrupt enable */
+#define BDMAC_DCMD_LINK (1 << 0) /* descriptor link enable */
+
+// BDMA descriptor address register
+#define BDMAC_DDA_BASE_BIT 12 /* descriptor base address */
+ #define BDMAC_DDA_BASE_MASK (0x0fffff << BDMAC_DDA_BASE_BIT)
+#define BDMAC_DDA_OFFSET_BIT 4 /* descriptor offset address */
+ #define BDMAC_DDA_OFFSET_MASK (0x0ff << BDMAC_DDA_OFFSET_BIT)
+
+// BDMA stride address register
+#define BDMAC_DSD_TSD_BIT 16 /* target stride address */
+ #define BDMAC_DSD_TSD_MASK (0xffff << BDMAC_DSD_TSD_BIT)
+#define BDMAC_DSD_SSD_BIT 0 /* source stride address */
+ #define BDMAC_DSD_SSD_MASK (0xffff << BDMAC_DSD_SSD_BIT)
+
+// BDMA NAND Detect timer register
+#define BDMAC_NDTCTIMER_EN (1 << 15) /* enable detect timer */
+#define BDMAC_TAILCNT_BIT 16
+
+// BDMA control register
+#define BDMAC_DMACR_PR_BIT 8 /* channel priority mode */
+ #define BDMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_01_2 (0 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_12_0 (1 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_20_1 (2 << BDMAC_DMACR_PR_BIT)
+ #define BDMAC_DMACR_PR_012 (3 << BDMAC_DMACR_PR_BIT)
+#define BDMAC_DMACR_HLT (1 << 3) /* DMA halt flag */
+#define BDMAC_DMACR_AR (1 << 2) /* address error flag */
+#define BDMAC_DMACR_DMAE (1 << 0) /* DMA enable bit */
+
+// BDMA interrupt pending register
+#define BDMAC_DMAIPR_CIRQ2 (1 << 2) /* irq pending status for channel 2 */
+#define BDMAC_DMAIPR_CIRQ1 (1 << 1) /* irq pending status for channel 1 */
+#define BDMAC_DMAIPR_CIRQ0 (1 << 0) /* irq pending status for channel 0 */
+
+// BDMA doorbell register
+#define BDMAC_DMADBR_DB2 (1 << 2) /* doorbell for channel 2 */
+#define BDMAC_DMADBR_DB1 (1 << 1) /* doorbell for channel 1 */
+#define BDMAC_DMADBR_DB0 (1 << 0) /* doorbell for channel 0 */
+
+// BDMA doorbell set register
+#define BDMAC_DMADBSR_DBS2 (1 << 2) /* enable doorbell for channel 2 */
+#define BDMAC_DMADBSR_DBS1 (1 << 1) /* enable doorbell for channel 1 */
+#define BDMAC_DMADBSR_DBS0 (1 << 0) /* enable doorbell for channel 0 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * BCH & NAND DMAC
+ ***************************************************************************/
+
+/* n is the DMA channel index (0 - 2) */
+
+#define __bdmac_test_halt_error ( REG_BDMAC_DMACR & BDMAC_DMACR_HLT )
+#define __bdmac_test_addr_error ( REG_BDMAC_DMACR & BDMAC_DMACR_AR )
+
+#define __bdmac_channel_enable_clk(n) \
+ REG_BDMAC_DMACKE |= 1 << (n);
+
+#define __bdmac_enable_descriptor(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_NDES )
+#define __bdmac_disable_descriptor(n) \
+ ( REG_BDMAC_DCCSR((n)) |= BDMAC_DCCSR_NDES )
+
+#define __bdmac_enable_channel(n) \
+do { \
+ REG_BDMAC_DCCSR((n)) |= BDMAC_DCCSR_EN; \
+} while (0)
+#define __bdmac_disable_channel(n) \
+do { \
+ REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_EN; \
+} while (0)
+
+#define __bdmac_channel_enable_irq(n) \
+ ( REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_TIE )
+#define __bdmac_channel_disable_irq(n) \
+ ( REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_TIE )
+
+#define __bdmac_channel_transmit_halt_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_HLT )
+#define __bdmac_channel_transmit_end_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_TT )
+#define __bdmac_channel_address_error_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_AR )
+#define __bdmac_channel_count_terminated_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_CT )
+#define __bdmac_channel_descriptor_invalid_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_INV )
+#define __bdmac_BCH_error_detected(n) \
+ ( REG_BDMAC_DCCSR((n)) & BDMAC_DCCSR_BERR )
+
+#define __bdmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_HLT; \
+ REG_BDMAC_DMACR &= ~BDMAC_DMACR_HLT; \
+ } while (0)
+#define __bdmac_channel_clear_transmit_end(n) \
+ ( REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_TT )
+#define __bdmac_channel_clear_address_error(n) \
+ do { \
+ REG_BDMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_BDMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_BDMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_BDMAC_DCCSR(n) &= ~BDMAC_DCCSR_AR; \
+ REG_BDMAC_DMACR &= ~BDMAC_DMACR_AR; \
+ } while (0)
+#define __bdmac_channel_clear_count_terminated(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_CT )
+#define __bdmac_channel_clear_descriptor_invalid(n) \
+ ( REG_BDMAC_DCCSR((n)) &= ~BDMAC_DCCSR_INV )
+
+#define __bdmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __bdmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DS_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __bdmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DWDH_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __bdmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_SWDH_MASK; \
+ REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_SWDH_##w; \
+} while (0)
+
+#define __bdmac_channel_dest_addr_fixed(n) \
+ (REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_DAI)
+#define __bdmac_channel_dest_addr_increment(n) \
+ (REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_DAI)
+
+#define __bdmac_channel_src_addr_fixed(n) \
+ (REG_BDMAC_DCMD((n)) &= ~BDMAC_DCMD_SAI)
+#define __bdmac_channel_src_addr_increment(n) \
+ (REG_BDMAC_DCMD((n)) |= BDMAC_DCMD_SAI)
+
+#define __bdmac_channel_set_doorbell(n) \
+ (REG_BDMAC_DMADBSR = (1 << (n)))
+
+#define __bdmac_channel_irq_detected(n) (REG_BDMAC_DMAIPR & (1 << (n)))
+#define __bdmac_channel_ack_irq(n) (REG_BDMAC_DMAIPR &= ~(1 <<(n)))
+
+static __inline__ int __bdmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_BDMA_NUM; i++)
+ if (__bdmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810BDMA_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810cim.h b/arch/mips/include/asm/mach-jz4810/jz4810cim.h
new file mode 100644
index 00000000000..47279adfd87
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810cim.h
@@ -0,0 +1,351 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810cim.h
+ *
+ * JZ4810 CIM register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810CIM_H__
+#define __JZ4810CIM_H__
+
+
+#define CIM_BASE 0xB3060000
+
+/*************************************************************************
+ * CIM
+ *************************************************************************/
+#define CIM_CFG (CIM_BASE + 0x0000)
+#define CIM_CTRL (CIM_BASE + 0x0004)
+#define CIM_STATE (CIM_BASE + 0x0008)
+#define CIM_IID (CIM_BASE + 0x000C)
+#define CIM_RXFIFO (CIM_BASE + 0x0010)
+#define CIM_DA (CIM_BASE + 0x0020)
+#define CIM_FA (CIM_BASE + 0x0024)
+#define CIM_FID (CIM_BASE + 0x0028)
+#define CIM_CMD (CIM_BASE + 0x002C)
+#define CIM_SIZE (CIM_BASE + 0x0030)
+#define CIM_OFFSET (CIM_BASE + 0x0034)
+#define CIM_RAM_ADDR (CIM_BASE + 0x1000)
+
+#define REG_CIM_CFG REG32(CIM_CFG)
+#define REG_CIM_CTRL REG32(CIM_CTRL)
+#define REG_CIM_STATE REG32(CIM_STATE)
+#define REG_CIM_IID REG32(CIM_IID)
+#define REG_CIM_RXFIFO REG32(CIM_RXFIFO)
+#define REG_CIM_DA REG32(CIM_DA)
+#define REG_CIM_FA REG32(CIM_FA)
+#define REG_CIM_FID REG32(CIM_FID)
+#define REG_CIM_CMD REG32(CIM_CMD)
+#define REG_CIM_SIZE REG32(CIM_SIZE)
+#define REG_CIM_OFFSET REG32(CIM_OFFSET)
+
+#define CIM_CFG_ORDER_BIT 18
+#define CIM_CFG_ORDER_MASK (0x3 << CIM_CFG_ORDER_BIT)
+ #define CIM_CFG_ORDER_0 (0x0 << CIM_CFG_ORDER_BIT) /* Y0CbY1Cr; YCbCr */
+ #define CIM_CFG_ORDER_1 (0x1 << CIM_CFG_ORDER_BIT) /* Y0CrY1Cb; YCrCb */
+ #define CIM_CFG_ORDER_2 (0x2 << CIM_CFG_ORDER_BIT) /* CbY0CrY1; CbCrY */
+ #define CIM_CFG_ORDER_3 (0x3 << CIM_CFG_ORDER_BIT) /* CrY0CbY1; CrCbY */
+#define CIM_CFG_DF_BIT 16
+#define CIM_CFG_DF_MASK (0x3 << CIM_CFG_DF_BIT)
+ #define CIM_CFG_DF_YUV444 (0x1 << CIM_CFG_DF_BIT) /* YCbCr444 */
+ #define CIM_CFG_DF_YUV422 (0x2 << CIM_CFG_DF_BIT) /* YCbCr422 */
+ #define CIM_CFG_DF_ITU656 (0x3 << CIM_CFG_DF_BIT) /* ITU656 YCbCr422 */
+#define CIM_CFG_INV_DAT (1 << 15)
+#define CIM_CFG_VSP (1 << 14) /* VSYNC Polarity:0-rising edge active,1-falling edge active */
+#define CIM_CFG_HSP (1 << 13) /* HSYNC Polarity:0-rising edge active,1-falling edge active */
+#define CIM_CFG_PCP (1 << 12) /* PCLK working edge: 0-rising, 1-falling */
+#define CIM_CFG_DMA_BURST_TYPE_BIT 10
+#define CIM_CFG_DMA_BURST_TYPE_MASK (0x3 << CIM_CFG_DMA_BURST_TYPE_BIT)
+ #define CIM_CFG_DMA_BURST_INCR4 (0 << CIM_CFG_DMA_BURST_TYPE_BIT)
+ #define CIM_CFG_DMA_BURST_INCR8 (1 << CIM_CFG_DMA_BURST_TYPE_BIT) /* Suggested */
+ #define CIM_CFG_DMA_BURST_INCR16 (2 << CIM_CFG_DMA_BURST_TYPE_BIT) /* Suggested High speed AHB*/
+#define CIM_CFG_DUMMY_ZERO (1 << 9)
+#define CIM_CFG_EXT_VSYNC (1 << 8) /* Only for ITU656 Progressive mode */
+#define CIM_CFG_PACK_BIT 4
+#define CIM_CFG_PACK_MASK (0x7 << CIM_CFG_PACK_BIT)
+ #define CIM_CFG_PACK_0 (0 << CIM_CFG_PACK_BIT) /* 11 22 33 44 0xY0CbY1Cr */
+ #define CIM_CFG_PACK_1 (1 << CIM_CFG_PACK_BIT) /* 22 33 44 11 0xCbY1CrY0 */
+ #define CIM_CFG_PACK_2 (2 << CIM_CFG_PACK_BIT) /* 33 44 11 22 0xY1CrY0Cb */
+ #define CIM_CFG_PACK_3 (3 << CIM_CFG_PACK_BIT) /* 44 11 22 33 0xCrY0CbY1 */
+ #define CIM_CFG_PACK_4 (4 << CIM_CFG_PACK_BIT) /* 44 33 22 11 0xCrY1CbY0 */
+ #define CIM_CFG_PACK_5 (5 << CIM_CFG_PACK_BIT) /* 33 22 11 44 0xY1CbY0Cr */
+ #define CIM_CFG_PACK_6 (6 << CIM_CFG_PACK_BIT) /* 22 11 44 33 0xCbY0CrY1 */
+ #define CIM_CFG_PACK_7 (7 << CIM_CFG_PACK_BIT) /* 11 44 33 22 0xY0CrY1Cb */
+#define CIM_CFG_BYPASS_BIT 2
+#define CIM_CFG_BYPASS_MASK (1 << CIM_CFG_BYPASS_BIT)
+ #define CIM_CFG_BYPASS (1 << CIM_CFG_BYPASS_BIT)
+#define CIM_CFG_DSM_BIT 0
+#define CIM_CFG_DSM_MASK (0x3 << CIM_CFG_DSM_BIT)
+ #define CIM_CFG_DSM_CPM (0 << CIM_CFG_DSM_BIT) /* CCIR656 Progressive Mode */
+ #define CIM_CFG_DSM_CIM (1 << CIM_CFG_DSM_BIT) /* CCIR656 Interlace Mode */
+ #define CIM_CFG_DSM_GCM (2 << CIM_CFG_DSM_BIT) /* Gated Clock Mode */
+
+/* CIM Control Register (CIM_CTRL) */
+#define CIM_CTRL_EEOF_LINE_BIT 20
+#define CIM_CTRL_EEOF_LINE_MASK (0xfff << CIM_CTRL_EEOF_LINE_BIT)
+#define CIM_CTRL_FRC_BIT 16
+#define CIM_CTRL_FRC_MASK (0xf << CIM_CTRL_FRC_BIT)
+ #define CIM_CTRL_FRC_1 (0x0 << CIM_CTRL_FRC_BIT) /* Sample every frame */
+ #define CIM_CTRL_FRC_2 (0x1 << CIM_CTRL_FRC_BIT) /* Sample 1/2 frame */
+ #define CIM_CTRL_FRC_3 (0x2 << CIM_CTRL_FRC_BIT) /* Sample 1/3 frame */
+ #define CIM_CTRL_FRC_4 (0x3 << CIM_CTRL_FRC_BIT) /* Sample 1/4 frame */
+ #define CIM_CTRL_FRC_5 (0x4 << CIM_CTRL_FRC_BIT) /* Sample 1/5 frame */
+ #define CIM_CTRL_FRC_6 (0x5 << CIM_CTRL_FRC_BIT) /* Sample 1/6 frame */
+ #define CIM_CTRL_FRC_7 (0x6 << CIM_CTRL_FRC_BIT) /* Sample 1/7 frame */
+ #define CIM_CTRL_FRC_8 (0x7 << CIM_CTRL_FRC_BIT) /* Sample 1/8 frame */
+ #define CIM_CTRL_FRC_9 (0x8 << CIM_CTRL_FRC_BIT) /* Sample 1/9 frame */
+ #define CIM_CTRL_FRC_10 (0x9 << CIM_CTRL_FRC_BIT) /* Sample 1/10 frame */
+ #define CIM_CTRL_FRC_11 (0xA << CIM_CTRL_FRC_BIT) /* Sample 1/11 frame */
+ #define CIM_CTRL_FRC_12 (0xB << CIM_CTRL_FRC_BIT) /* Sample 1/12 frame */
+ #define CIM_CTRL_FRC_13 (0xC << CIM_CTRL_FRC_BIT) /* Sample 1/13 frame */
+ #define CIM_CTRL_FRC_14 (0xD << CIM_CTRL_FRC_BIT) /* Sample 1/14 frame */
+ #define CIM_CTRL_FRC_15 (0xE << CIM_CTRL_FRC_BIT) /* Sample 1/15 frame */
+ #define CIM_CTRL_FRC_16 (0xF << CIM_CTRL_FRC_BIT) /* Sample 1/16 frame */
+
+#define CIM_CTRL_DMA_EEOF (1 << 15) /* Enable EEOF interrupt */
+#define CIM_CTRL_WIN_EN (1 << 14)
+#define CIM_CTRL_VDDM (1 << 13) /* VDD interrupt enable */
+#define CIM_CTRL_DMA_SOFM (1 << 12)
+#define CIM_CTRL_DMA_EOFM (1 << 11)
+#define CIM_CTRL_DMA_STOPM (1 << 10)
+#define CIM_CTRL_RXF_TRIGM (1 << 9)
+#define CIM_CTRL_RXF_OFM (1 << 8)
+#define CIM_CTRL_DMA_SYNC (1 << 7) /*when change DA, do frame sync */
+#define CIM_CTRL_RXF_TRIG_BIT 3
+#define CIM_CTRL_RXF_TRIG_MASK (0xf << CIM_CTRL_RXF_TRIG_BIT) /* trigger value = (n+1)*burst_type */
+
+#define CIM_CTRL_DMA_EN (1 << 2) /* Enable DMA */
+#define CIM_CTRL_RXF_RST (1 << 1) /* RxFIFO reset */
+#define CIM_CTRL_ENA (1 << 0) /* Enable CIM */
+
+/* CIM State Register (CIM_STATE) */
+#define CIM_STATE_DMA_EEOF (1 << 7) /* DMA Line EEOf irq */
+#define CIM_STATE_DMA_SOF (1 << 6) /* DMA start irq */
+#define CIM_STATE_DMA_EOF (1 << 5) /* DMA end irq */
+#define CIM_STATE_DMA_STOP (1 << 4) /* DMA stop irq */
+#define CIM_STATE_RXF_OF (1 << 3) /* RXFIFO over flow irq */
+#define CIM_STATE_RXF_TRIG (1 << 2) /* RXFIFO triger meet irq */
+#define CIM_STATE_RXF_EMPTY (1 << 1) /* RXFIFO empty irq */
+#define CIM_STATE_VDD (1 << 0) /* CIM disabled irq */
+
+/* CIM DMA Command Register (CIM_CMD) */
+
+#define CIM_CMD_SOFINT (1 << 31) /* enable DMA start irq */
+#define CIM_CMD_EOFINT (1 << 30) /* enable DMA end irq */
+#define CIM_CMD_EEOFINT (1 << 29) /* enable DMA EEOF irq */
+#define CIM_CMD_STOP (1 << 28) /* enable DMA stop irq */
+#define CIM_CMD_OFRCV (1 << 27) /* enable recovery when TXFiFo overflow */
+#define CIM_CMD_LEN_BIT 0
+#define CIM_CMD_LEN_MASK (0xffffff << CIM_CMD_LEN_BIT)
+
+/* CIM Window-Image Size Register (CIM_SIZE) */
+#define CIM_SIZE_LPF_BIT 16 /* Lines per freame for csc output image */
+#define CIM_SIZE_LPF_MASK (0x1fff << CIM_SIZE_LPF_BIT)
+#define CIM_SIZE_PPL_BIT 0 /* Pixels per line for csc output image, should be an even number */
+#define CIM_SIZE_PPL_MASK (0x1fff << CIM_SIZE_PPL_BIT)
+
+/* CIM Image Offset Register (CIM_OFFSET) */
+#define CIM_OFFSET_V_BIT 16 /* Vertical offset */
+#define CIM_OFFSET_V_MASK (0xfff << CIM_OFFSET_V_BIT)
+#define CIM_OFFSET_H_BIT 0 /* Horizontal offset, should be an enen number */
+#define CIM_OFFSET_H_MASK (0xfff << CIM_OFFSET_H_BIT) /*OFFSET_H should be even number*/
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * CIM
+ ***************************************************************************/
+
+#define __cim_enable() ( REG_CIM_CTRL |= CIM_CTRL_ENA )
+#define __cim_disable() ( REG_CIM_CTRL &= ~CIM_CTRL_ENA )
+
+/* n = 0, 1, 2, 3 */
+#define __cim_set_input_data_stream_order(n) \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_ORDER_MASK; \
+ REG_CIM_CFG |= ((n)<<CIM_CFG_ORDER_BIT)&CIM_CFG_ORDER_MASK; \
+ } while (0)
+
+#define __cim_input_data_format_select_RGB() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_RGB; \
+ } while (0)
+
+#define __cim_input_data_format_select_YUV444() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_YUV444; \
+ } while (0)
+
+#define __cim_input_data_format_select_YUV422() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_YUV422; \
+ } while (0)
+
+#define __cim_input_data_format_select_ITU656() \
+ do { \
+ REG_CIM_CFG &= ~CIM_CFG_DF_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DF_ITU656; \
+ } while (0)
+
+#define __cim_input_data_inverse() ( REG_CIM_CFG |= CIM_CFG_INV_DAT )
+#define __cim_input_data_normal() ( REG_CIM_CFG &= ~CIM_CFG_INV_DAT )
+
+#define __cim_vsync_active_low() ( REG_CIM_CFG |= CIM_CFG_VSP )
+#define __cim_vsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_VSP )
+
+#define __cim_hsync_active_low() ( REG_CIM_CFG |= CIM_CFG_HSP )
+#define __cim_hsync_active_high() ( REG_CIM_CFG &= ~CIM_CFG_HSP )
+
+#define __cim_sample_data_at_pclk_falling_edge() \
+ ( REG_CIM_CFG |= CIM_CFG_PCP )
+#define __cim_sample_data_at_pclk_rising_edge() \
+ ( REG_CIM_CFG &= ~CIM_CFG_PCP )
+
+#define __cim_enable_dummy_zero() ( REG_CIM_CFG |= CIM_CFG_DUMMY_ZERO )
+#define __cim_disable_dummy_zero() ( REG_CIM_CFG &= ~CIM_CFG_DUMMY_ZERO )
+
+#define __cim_select_external_vsync() ( REG_CIM_CFG |= CIM_CFG_EXT_VSYNC )
+#define __cim_select_internal_vsync() ( REG_CIM_CFG &= ~CIM_CFG_EXT_VSYNC )
+
+/* n=0-7 */
+#define __cim_set_data_packing_mode(n) \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_PACK_MASK; \
+ REG_CIM_CFG |= (CIM_CFG_PACK_##n); \
+} while (0)
+
+#define __cim_enable_bypass_func() (REG_CIM_CFG |= CIM_CFG_BYPASS)
+#define __cim_disable_bypass_func() (REG_CIM_CFG &= ~CIM_CFG_BYPASS_MASK)
+
+#define __cim_enable_ccir656_progressive_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_CPM; \
+} while (0)
+
+#define __cim_enable_ccir656_interlace_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_CIM; \
+} while (0)
+
+#define __cim_enable_gated_clock_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_GCM; \
+} while (0)
+
+#define __cim_enable_nongated_clock_mode() \
+do { \
+ REG_CIM_CFG &= ~CIM_CFG_DSM_MASK; \
+ REG_CIM_CFG |= CIM_CFG_DSM_NGCM; \
+} while (0)
+
+/* sclk:system bus clock
+ * mclk: CIM master clock
+ */
+#define __cim_set_master_clk(sclk, mclk) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_MCLKDIV_MASK; \
+ REG_CIM_CTRL |= (((sclk)/(mclk) - 1) << CIM_CTRL_MCLKDIV_BIT); \
+} while (0)
+/* n=1-16 */
+#define __cim_set_frame_rate(n) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_FRC_MASK; \
+ REG_CIM_CTRL |= CIM_CTRL_FRC_##n; \
+} while (0)
+
+#define __cim_enable_size_func() \
+ ( REG_CIM_CTRL |= CIM_CTRL_SIZEEN )
+#define __cim_disable_size_func() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_SIZEEN_MASK )
+
+#define __cim_enable_vdd_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_VDDM )
+#define __cim_disable_vdd_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_VDDM )
+
+#define __cim_enable_sof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_SOFM )
+#define __cim_disable_sof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_SOFM )
+
+#define __cim_enable_eof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_EOFM )
+#define __cim_disable_eof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EOFM )
+
+#define __cim_enable_eeof_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_EEOFM )
+#define __cim_disable_eeof_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EEOFM )
+
+#define __cim_enable_stop_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_DMA_STOPM )
+#define __cim_disable_stop_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_STOPM )
+
+#define __cim_enable_trig_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_TRIGM )
+#define __cim_disable_trig_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIGM )
+
+#define __cim_enable_rxfifo_overflow_intr() \
+ ( REG_CIM_CTRL |= CIM_CTRL_RXF_OFM )
+#define __cim_disable_rxfifo_overflow_intr() \
+ ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_OFM )
+
+/* n=4,8,12,16,20,24,28,32 */
+#define __cim_set_rxfifo_trigger(n) \
+do { \
+ REG_CIM_CTRL &= ~CIM_CTRL_RXF_TRIG_MASK; \
+ REG_CIM_CTRL |= CIM_CTRL_RXF_TRIG_##n; \
+} while (0)
+#define __cim_enable_fast_mode() ( REG_CIM_CTRL |= CIM_CTRL_FAST_MODE )
+#define __cim_disable_fast_mode() ( REG_CIM_CTRL &= ~CIM_CTRL_FAST_MODE )
+#define __cim_use_normal_mode() __cim_disable_fast_mode()
+#define __cim_enable_dma() ( REG_CIM_CTRL |= CIM_CTRL_DMA_EN )
+#define __cim_disable_dma() ( REG_CIM_CTRL &= ~CIM_CTRL_DMA_EN )
+#define __cim_reset_rxfifo() ( REG_CIM_CTRL |= CIM_CTRL_RXF_RST )
+#define __cim_unreset_rxfifo() ( REG_CIM_CTRL &= ~CIM_CTRL_RXF_RST )
+
+#define __cim_clear_state() ( REG_CIM_STATE = 0 )
+
+#define __cim_disable_done() ( REG_CIM_STATE & CIM_STATE_VDD )
+#define __cim_rxfifo_empty() ( REG_CIM_STATE & CIM_STATE_RXF_EMPTY )
+#define __cim_rxfifo_reach_trigger() ( REG_CIM_STATE & CIM_STATE_RXF_TRIG )
+#define __cim_rxfifo_overflow() ( REG_CIM_STATE & CIM_STATE_RXF_OF )
+#define __cim_clear_rxfifo_overflow() ( REG_CIM_STATE &= ~CIM_STATE_RXF_OF )
+#define __cim_dma_stop() ( REG_CIM_STATE & CIM_STATE_DMA_STOP )
+#define __cim_dma_eof() ( REG_CIM_STATE & CIM_STATE_DMA_EOF )
+#define __cim_dma_sof() ( REG_CIM_STATE & CIM_STATE_DMA_SOF )
+
+#define __cim_get_iid() ( REG_CIM_IID )
+#define __cim_get_fid() ( REG_CIM_FID )
+#define __cim_get_image_data() ( REG_CIM_RXFIFO )
+#define __cim_get_dma_cmd() ( REG_CIM_CMD )
+
+#define __cim_set_da(a) ( REG_CIM_DA = (a) )
+
+#define __cim_set_line(a) ( REG_CIM_SIZE = (REG_CIM_SIZE&(~CIM_SIZE_LPF_MASK))|((a)<<CIM_SIZE_LPF_BIT) )
+#define __cim_set_pixel(a) ( REG_CIM_SIZE = (REG_CIM_SIZE&(~CIM_SIZE_PPL_MASK))|((a)<<CIM_SIZE_PPL_BIT) )
+#define __cim_get_line() ((REG_CIM_SIZE&CIM_SIZE_LPF_MASK)>>CIM_SIZE_LPF_BIT)
+#define __cim_get_pixel() ((REG_CIM_SIZE&CIM_SIZE_PPL_MASK)>>CIM_SIZE_PPL_BIT)
+
+#define __cim_set_v_offset(a) ( REG_CIM_OFFSET = (REG_CIM_OFFSET&(~CIM_OFFSET_V_MASK)) | ((a)<<CIM_OFFSET_V_BIT) )
+#define __cim_set_h_offset(a) ( REG_CIM_OFFSET = (REG_CIM_OFFSET&(~CIM_OFFSET_H_MASK)) | ((a)<<CIM_OFFSET_H_BIT) )
+#define __cim_get_v_offset() ((REG_CIM_OFFSET&CIM_OFFSET_V_MASK)>>CIM_OFFSET_V_BIT)
+#define __cim_get_h_offset() ((REG_CIM_OFFSET&CIM_OFFSET_H_MASK)>>CIM_OFFSET_H_BIT)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810CIM_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810cpm.h b/arch/mips/include/asm/mach-jz4810/jz4810cpm.h
new file mode 100644
index 00000000000..0dd45aba6d0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810cpm.h
@@ -0,0 +1,559 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810cpm.h
+ *
+ * JZ4810 CPM register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810CPM_H__
+#define __JZ4810CPM_H__
+
+
+#define CPM_BASE 0xB0000000
+
+
+/*************************************************************************
+ * CPM (Clock reset and Power control Management)
+ *************************************************************************/
+#define CPM_CPCCR (CPM_BASE + 0x00) /* Clock control register */
+#define CPM_RSR (CPM_BASE + 0x08)
+#define CPM_CPPCR (CPM_BASE + 0x10) /* PLL control register 0 */
+#define CPM_CPPSR (CPM_BASE + 0x14) /* PLL switch and status Register */
+#define CPM_CPPCR1 (CPM_BASE + 0x30) /* PLL control register 1 */
+#define CPM_CPSPR (CPM_BASE + 0x34) /* CPM scratch pad register */
+#define CPM_CPSPPR (CPM_BASE + 0x38) /* CPM scratch protected register */
+#define CPM_USBPCR (CPM_BASE + 0x3c) /* USB parameter control register */
+#define CPM_USBRDT (CPM_BASE + 0x40) /* USB reset detect timer register */
+#define CPM_USBVBFIL (CPM_BASE + 0x44) /* USB jitter filter register */
+#define CPM_USBCDR (CPM_BASE + 0x50) /* USB OTG PHY clock divider register */
+#define CPM_I2SCDR (CPM_BASE + 0x60) /* I2S device clock divider register */
+#define CPM_LPCDR (CPM_BASE + 0x64) /* LCD pix clock divider register */
+#define CPM_MSCCDR (CPM_BASE + 0x68) /* MSC clock divider register */
+#define CPM_UHCCDR (CPM_BASE + 0x6C) /* UHC 48M clock divider register */
+#define CPM_SSICDR (CPM_BASE + 0x74) /* SSI clock divider register */
+#define CPM_CIMCDR (CPM_BASE + 0x7c) /* CIM MCLK clock divider register */
+#define CPM_GPSCDR (CPM_BASE + 0x80) /* GPS clock divider register */
+#define CPM_PCMCDR (CPM_BASE + 0x84) /* PCM device clock divider register */
+#define CPM_GPUCDR (CPM_BASE + 0x88) /* GPU clock divider register */
+
+#define CPM_PSWC0ST (CPM_BASE + 0x90)
+#define CPM_PSWC1ST (CPM_BASE + 0x94)
+#define CPM_PSWC2ST (CPM_BASE + 0x98)
+#define CPM_PSWC3ST (CPM_BASE + 0x9c)
+
+#define CPM_LCR (CPM_BASE + 0x04)
+#define CPM_CLKGR0 (CPM_BASE + 0x20)
+#define CPM_OPCR (CPM_BASE + 0x24)
+#define CPM_CLKGR1 (CPM_BASE + 0x28)
+
+#define REG_CPM_CPCCR REG32(CPM_CPCCR)
+#define REG_CPM_RSR REG32(CPM_RSR)
+#define REG_CPM_CPPCR REG32(CPM_CPPCR)
+#define REG_CPM_CPPSR REG32(CPM_CPPSR)
+#define REG_CPM_CPPCR1 REG32(CPM_CPPCR1)
+#define REG_CPM_CPSPR REG32(CPM_CPSPR)
+#define REG_CPM_CPSPPR REG32(CPM_CPSPPR)
+#define REG_CPM_USBPCR REG32(CPM_USBPCR)
+#define REG_CPM_USBRDT REG32(CPM_USBRDT)
+#define REG_CPM_USBVBFIL REG32(CPM_USBVBFIL)
+#define REG_CPM_USBCDR REG32(CPM_USBCDR)
+#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_CIMCDR REG32(CPM_CIMCDR)
+#define REG_CPM_GPSCDR REG32(CPM_GPSCDR)
+#define REG_CPM_PCMCDR REG32(CPM_PCMCDR)
+#define REG_CPM_GPUCDR REG32(CPM_GPUCDR)
+
+#define REG_CPM_PSWC0ST REG32(CPM_PSWC0ST)
+#define REG_CPM_PSWC1ST REG32(CPM_PSWC1ST)
+#define REG_CPM_PSWC2ST REG32(CPM_PSWC2ST)
+#define REG_CPM_PSWC3ST REG32(CPM_PSWC3ST)
+
+#define REG_CPM_LCR REG32(CPM_LCR)
+#define REG_CPM_CLKGR0 REG32(CPM_CLKGR0)
+#define REG_CPM_OPCR REG32(CPM_OPCR)
+#define REG_CPM_CLKGR1 REG32(CPM_CLKGR1)
+#define REG_CPM_CLKGR REG32(CPM_CLKGR0)
+
+/* Clock control register */
+#define CPM_CPCCR_ECS (1 << 31)
+#define CPM_CPCCR_MEM (1 << 30)
+#define CPM_CPCCR_SDIV_BIT 24
+#define CPM_CPCCR_SDIV_MASK (0x0f << CPM_CPCCR_SDIV_BIT)
+#define CPM_CPCCR_CE (1 << 22)
+#define CPM_CPCCR_PCS (1 << 21)
+#define CPM_CPCCR_H2DIV_BIT 16
+#define CPM_CPCCR_H2DIV_MASK (0x0f << CPM_CPCCR_H2DIV_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)
+
+/*Reset status register*/
+#define CPM_RSR_P0R (1 << 2)
+#define CPM_RSR_WR (1 << 1)
+#define CPM_RSR_PR (1 << 0)
+
+/* PLL control register 0 */
+#define CPM_CPPCR_PLLM_BIT 24
+#define CPM_CPPCR_PLLM_MASK (0x7f << CPM_CPPCR_PLLM_BIT)
+#define CPM_CPPCR_PLLN_BIT 18
+#define CPM_CPPCR_PLLN_MASK (0x0f << CPM_CPPCR_PLLN_BIT)
+#define CPM_CPPCR_PLLOD_BIT 16
+#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT)
+#define CPM_CPPCR_LOCK0 (1 << 15)
+#define CPM_CPPCR_ENLOCK (1 << 14)
+#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)
+
+/* PLL control register 1 */
+#define CPM_CPPCR1_PLL1M_BIT 24
+#define CPM_CPCCR1_PLL1M_MASK (0x7f << CPM_CPPCR1_PLL1M_BIT)
+#define CPM_CPCCR1_PLL1N_BIT 18
+#define CPM_CPCCR1_PLL1N_MASK (0x0f << CPM_CPCCR1_PLL1N_BIT)
+#define CPM_CPCCR1_PLL1OD_BIT 16
+#define CPM_CPCCR1_PLL1OD_MASK (0x03 << CPM_CPCCR1_PLL1OD_BIT)
+#define CPM_CPCCR1_P1SCS (1 << 15)
+#define CPM_CPCCR1_P1SDIV_BIT 9
+#define CPM_CPCCR1_P1SDIV_MASK (0x3f << CPM_CPCCR1_P1SDIV_BIT)
+#define CPM_CPCCR1_PLL1EN (1 << 7)
+#define CPM_CPCCR1_PLL1S (1 << 6)
+#define CPM_CPCCR1_LOCK1 (1 << 2)
+#define CPM_CPCCR1_PLL1OFF (1 << 1)
+#define CPM_CPCCR1_PLL1ON (1 << 0)
+
+/* PLL switch and status Register */
+#define CPM_CPPSR_PLLOFF (1 << 31)
+#define CPM_CPPSR_PLLBP (1 << 30)
+#define CPM_CPPSR_PLLON (1 << 29)
+#define CPM_CPPSR_PS (1 << 28)
+#define CPM_CPPSR_FS (1 << 27)
+#define CPM_CPPSR_CS (1 << 26)
+#define CPM_CPPSR_SM (1 << 02)
+#define CPM_CPPSR_PM (1 << 01)
+#define CPM_CPPSR_FM (1 << 00)
+
+/* CPM scratch protected register */
+#define CPM_CPSPPR_BIT 0
+#define CPM_CPSPPR_MASK (0xffff << CPM_CPSPPR_BIT)
+
+/* USB parameter control register */
+#define CPM_USBPCR_USB_MODE (1 << 31)
+#define CPM_USBPCR_AVLD_REG (1 << 30)
+#define CPM_USBPCR_IDPULLUP_MASK_BIT 28
+#define CPM_USBPCR_IDPULLUP_MASK_MASK (0x02 << IDPULLUP_MASK_BIT)
+#define CPM_USBPCR_INCR_MASK (1 << 27)
+#define CPM_USBPCR_CLK12_EN (1 << 26)
+#define CPM_USBPCR_COMMONONN (1 << 25)
+#define CPM_USBPCR_VBUSVLDEXT (1 << 24)
+#define CPM_USBPCR_VBUSVLDEXTSEL (1 << 23)
+#define CPM_USBPCR_POR (1 << 22)
+#define CPM_USBPCR_SIDDQ (1 << 21)
+#define CPM_USBPCR_OTG_DISABLE (1 << 20)
+#define CPM_USBPCR_COMPDISTUNE_BIT 17
+#define CPM_USBPCR_COMPDISTUNE_MASK (0x07 << COMPDISTUNE_BIT)
+#define CPM_USBPCR_OTGTUNE_BIT 14
+#define CPM_USBPCR_OTGTUNE_MASK (0x07 << OTGTUNE_BIT)
+#define CPM_USBPCR_SQRXTUNE_BIT 11
+#define CPM_USBPCR_SQRXTUNE_MASK (0x7x << SQRXTUNE_BIT)
+#define CPM_USBPCR_TXFSLSTUNE_BIT 7
+#define CPM_USBPCR_TXFSLSTUNE_MASK (0x0f << TXFSLSTUNE_BIT)
+#define CPM_USBPCR_TXPREEMPHTUNE (1 << 6)
+#define CPM_USBPCR_TXRISETUNE_BIT 4
+#define CPM_USBPCR_TXRISETUNE_MASK (0x03 << TXRISETUNE_BIT)
+#define CPM_USBPCR_TXVREFTUNE_BIT 0
+#define CPM_USBPCR_TXVREFTUNE_MASK (0x0f << TXVREFTUNE_BIT)
+
+/* USB reset detect timer register */
+#define CPM_USBRDT_VBFIL_LD_EN (1 << 25)
+#define CPM_USBRDT_IDDIG_EN (1 << 24)
+#define CPM_USBRDT_IDDIG_REG (1 << 23)
+#define CPM_USBRDT_USBRDT_BIT 0
+#define CPM_USBRDT_USBRDT_MASK (0x7fffff << CPM_USBRDT_USBRDT_BIT)
+
+/* USB OTG PHY clock divider register */
+#define CPM_USBCDR_UCS (1 << 31)
+#define CPM_USBCDR_UPCS (1 << 30)
+#define CPM_USBCDR_OTGDIV_BIT 0
+#define CPM_USBCDR_OTGDIV_MASK (0x3f << CPM_USBCDR_OTGDIV_BIT)
+
+/* I2S device clock divider register */
+#define CPM_I2SCDR_I2CS (1 << 31)
+#define CPM_I2SCDR_I2PCS (1 << 30)
+#define CPM_I2SCDR_I2SDIV_BIT 0
+#define CPM_I2SCDR_I2SDIV_MASK (0x1f << CPM_I2SCDR_I2SDIV_BIT)
+
+/* LCD pix clock divider register */
+#define CPM_LPCDR_LSCS (1 << 31)
+#define CPM_LPCDR_LTCS (1 << 30)
+#define CPM_LPCDR_LPCS (1 << 29)
+#define CPM_LPCDR_PIXDIV_BIT 0
+#define CPM_LPCDR_PIXDIV_MASK (0x7ff << CPM_LPCDR_PIXDIV_BIT)
+
+/* MSC clock divider register */
+#define CPM_MSCCDR_MCS (1 << 31)
+#define CPM_MSCCDR_MSCDIV_BIT 0
+#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT)
+
+/* UHC 48M clock divider register */
+#define CPM_UHCCDR_UHPCS (1 << 31)
+#define CPM_UHCCDR_UHCDIV_BIT 0
+#define CPM_UHCCDR_UHCDIV_MASK (0x0f << CPM_UHCCDR_UHCDIV_BIT)
+
+/* SSI clock divider register */
+#define CPM_SSICDR_SCS (1 << 31)
+#define CPM_SSICDR_SSIDIV_BIT 0
+#define CPM_SSICDR_SSIDIV_MASK (0x0f << CPM_SSICDR_SSIDIV_BIT)
+
+/* CIM MCLK clock divider register */
+#define CPM_CIMCDR_CIMDIV_BIT 0
+#define CPM_CIMCDR_CIMDIV_MASK (0xff << CPM_CIMCDR_CIMDIV_BIT)
+
+/* GPS clock divider register */
+#define CPM_GPSCDR_GPCS (1 << 31)
+#define CPM_GPSCDR_GPSDIV_BIT 0
+#define CPM_GSPCDR_GPSDIV_MASK (0x0f << CPM_GPSCDR_GPSDIV_BIT)
+
+/* PCM device clock divider register */
+#define CPM_PCMCDR_PCMS (1 << 31)
+#define CPM_PCMCDR_PCMPCS (1 << 30)
+#define CPM_PCMCDR_PCMDIV_BIT 0
+#define CPM_PCMCDR_PCMDIV_MASK (0x1ff << CPM_PCMCDR_PCMDIV_BIT)
+
+/* GPU clock divider register */
+#define CPM_GPUCDR_GPCS (1 << 31)
+#define CPM_GPUCDR_GPUDIV_BIT 0
+#define CPM_GPUCDR_GPUDIV_MASK (0x07 << CPM_GPUCDR_GPUDIV_BIT)
+
+/* Low power control register*/
+#define CPM_LCR_PDAHB1 (1 << 30)
+#define CPM_LCR_VBATIR (1 << 29)
+#define CPM_LCR_PDGPS (1 << 28)
+#define CPM_LCR_PDAHB1S (1 << 26)
+#define CPM_LCR_PDGPSS (1 << 24)
+#define CPM_LCR_PTS_BIT 8
+#define CPM_LCR_PTS_MASK (0xfff << CPM_LCR_PTS_BIT)
+#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 0 */
+#define CPM_CLKGR0_EMC (1 << 31)
+#define CPM_CLKGR0_DDR (1 << 30)
+#define CPM_CLKGR0_IPU (1 << 29)
+#define CPM_CLKGR0_LCD (1 << 28)
+#define CPM_CLKGR0_TVE (1 << 27)
+#define CPM_CLKGR0_CIM (1 << 26)
+#define CPM_CLKGR0_MDMA (1 << 25)
+#define CPM_CLKGR0_UHC (1 << 24)
+#define CPM_CLKGR0_MAC (1 << 23)
+#define CPM_CLKGR0_GPS (1 << 22)
+#define CPM_CLKGR0_DMAC (1 << 21)
+#define CPM_CLKGR0_SSI2 (1 << 20)
+#define CPM_CLKGR0_SSI1 (1 << 19)
+#define CPM_CLKGR0_UART3 (1 << 18)
+#define CPM_CLKGR0_UART2 (1 << 17)
+#define CPM_CLKGR0_UART1 (1 << 16)
+#define CPM_CLKGR0_UART0 (1 << 15)
+#define CPM_CLKGR0_SADC (1 << 14)
+#define CPM_CLKGR0_KBC (1 << 13)
+#define CPM_CLKGR0_MSC2 (1 << 12)
+#define CPM_CLKGR0_MSC1 (1 << 11)
+#define CPM_CLKGR0_OWI (1 << 10)
+#define CPM_CLKGR0_TSSI (1 << 9)
+#define CPM_CLKGR0_AIC (1 << 8)
+#define CPM_CLKGR0_SCC (1 << 7)
+#define CPM_CLKGR0_I2C1 (1 << 6)
+#define CPM_CLKGR0_I2C0 (1 << 5)
+#define CPM_CLKGR0_SSI0 (1 << 4)
+#define CPM_CLKGR0_MSC0 (1 << 3)
+#define CPM_CLKGR0_OTG (1 << 2)
+#define CPM_CLKGR0_BCH (1 << 1)
+#define CPM_CLKGR0_NEMC (1 << 0)
+
+/* Oscillator and Power Control Register */
+#define CPM_OPCR_O1ST_BIT 8
+#define CPM_OPCR_O1ST_MASK (0xff << CPM_OPCR_O1ST_BIT)
+#define CPM_OPCR_UDCPHY_ENABLE (1 << 7)
+#define CPM_OPCR_GPSEN (1 << 6)
+#define CPM_OPCR_UHCPHY_DISABLE (1 << 5)
+#define CPM_OPCR_OSC_ENABLE (1 << 4)
+#define CPM_OPCR_PD (1 << 3)
+#define CPM_OPCR_ERCS (1 << 2) /* EXCLK/512 clock and RTCLK clock selection */
+
+/* Clock gate register 1 */
+#define CPM_CLKGR1_GPU (1 << 9)
+#define CPM_CLKGR1_PCM (1 << 8)
+#define CPM_CLKGR1_AHB1 (1 << 7)
+#define CPM_CLKGR1_CABAC (1 << 6)
+#define CPM_CLKGR1_SRAM (1 << 5)
+#define CPM_CLKGR1_DCT (1 << 4)
+#define CPM_CLKGR1_ME (1 << 3)
+#define CPM_CLKGR1_DBLK (1 << 2)
+#define CPM_CLKGR1_MC (1 << 1)
+#define CPM_CLKGR1_BDMA (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#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_pll1m() \
+ ((REG_CPM_CPPCR1 & CPM_CPPCR1_PLL1M_MASK) >> CPM_CPPCR1_PLL1M_BIT)
+#define __cpm_get_pll1n() \
+ ((REG_CPM_CPPCR1 & CPM_CPPCR1_PLL1N_MASK) >> CPM_CPPCR1_PLL1N_BIT)
+#define __cpm_get_pll1od() \
+ ((REG_CPM_CPPCR1 & CPM_CPPCR1_PLL1OD_MASK) >> CPM_CPPCR1_PLL1OD_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_h2div() \
+ ((REG_CPM_CPCCR & CPM_CPCCR_H2DIV_MASK) >> CPM_CPCCR_H2DIV_BIT)
+#define __cpm_get_otgdiv() \
+ ((REG_CPM_USBCDR & CPM_USBCDR_OTGDIV_MASK) >> CPM_USBCDR_OTGDIV_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_sdiv() \
+ ((REG_CPM_CPCCR & CPM_CPCCR_SDIV_MASK) >> CPM_CPCCR_SDIV_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_mscdiv(n) \
+ ((REG_CPM_MSCCDR(n) & CPM_MSCCDR_MSCDIV_MASK) >> CPM_MSCCDR_MSCDIV_BIT)
+*/
+#define __cpm_get_ssidiv() \
+ ((REG_CPM_SSICCDR & CPM_SSICDR_SSICDIV_MASK) >> CPM_SSICDR_SSIDIV_BIT)
+#define __cpm_get_pcmdiv() \
+ ((REG_CPM_PCMCDR & CPM_PCMCDR_PCMCD_MASK) >> CPM_PCMCDR_PCMCD_BIT)
+#define __cpm_get_pll1div() \
+ ((REG_CPM_CPPCR1 & CPM_CPCCR1_P1SDIV_MASK) >> CPM_CPCCR1_P1SDIV_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_h1div(v) \
+ (REG_CPM_CPCCR = (REG_CPM_CPCCR & ~CPM_CPCCR_H1DIV_MASK) | ((v) << (CPM_CPCCR_H1DIV_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_ssidiv(v) \
+ (REG_CPM_SSICDR = (REG_CPM_SSICDR & ~CPM_SSICDR_SSIDIV_MASK) | ((v) << (CPM_SSICDR_SSIDIV_BIT)))
+#define __cpm_set_pcmdiv(v) \
+ (REG_CPM_PCMCDR = (REG_CPM_PCMCDR & ~CPM_PCMCDR_PCMDIV_MASK) | ((v) << (CPM_PCMCDR_PCMDIV_BIT)))
+#define __cpm_set_pll1div(v) \
+ (REG_CPM_CPPCR1 = (REG_CPM_CPPCR1 & ~CPM_CPCCR1_P1SDIV_MASK) | ((v) << (CPM_CPCCR1_P1SDIV_BIT)))
+
+#define __cpm_select_i2sclk_pll1() (REG_CPM_I2SCDR |= CPM_I2SCDR_I2PCS)
+#define __cpm_select_i2sclk_pll0() (REG_CPM_I2SCDR &= ~CPM_I2SCDR_I2PCS)
+#define __cpm_select_otgclk_pll1() (REG_CPM_USBCDR |= CPM_USBCDR_UPCS)
+#define __cpm_select_otgclk_pll0() (REG_CPM_USBCDR &= ~CPM_USBCDR_UPCS)
+#define __cpm_select_lcdpclk_pll1() (REG_CPM_LPCDR |= CPM_LPCDR_LPCS)
+#define __cpm_select_lcdpclk_pll0() (REG_CPM_LPCDR &= ~CPM_LPCDR_LPCS)
+#define __cpm_select_uhcclk_pll1() (REG_CPM_UHCCDR |= CPM_UHCCDR_UHPCS)
+#define __cpm_select_uhcclk_pll0() (REG_CPM_UHCCDR &= ~CPM_UHCCDR_UHPCS)
+#define __cpm_select_gpsclk_pll1() (REG_CPM_GPSCDR |= CPM_GPSCDR_GPCS)
+#define __cpm_select_gpsclk_pll0() (REG_CPM_GPSCDR &= ~CPM_GPSCDR_GPCS)
+#define __cpm_select_pcmclk_pll1() (REG_CPM_PCMCDR |= CPM_PCMCDR_PCMPCS)
+#define __cpm_select_pcmclk_pll0() (REG_CPM_PCMCDR &= ~CPM_PCMCDR_PCMPCS)
+#define __cpm_select_gpuclk_pll1() (REG_CPM_GPUCDR |= CPM_GPUCDR_GPCS)
+#define __cpm_select_gpuclk_pll0() (REG_CPM_GPUCDR &= ~CPM_GPUCDR_GPCS)
+#define __cpm_select_clk_pll1() (REG_CPM_CDR |= CPM_CDR_PCS)
+#define __cpm_select_clk_pll0() (REG_CPM_CDR &= ~CPM_CDR_PCS)
+
+
+#define __cpm_select_pcmclk_pll() (REG_CPM_PCMCDR |= CPM_PCMCDR_PCMS)
+#define __cpm_select_pcmclk_exclk() (REG_CPM_PCMCDR &= ~CPM_PCMCDR_PCMS)
+#define __cpm_select_pixclk_ext() (REG_CPM_LPCDR |= CPM_LPCDR_LPCS)
+#define __cpm_select_pixclk_pll() (REG_CPM_LPCDR &= ~CPM_LPCDR_LPCS)
+#define __cpm_select_tveclk_exclk() (REG_CPM_LPCDR |= CPM_CPCCR_LSCS)
+#define __cpm_select_tveclk_pll() (REG_CPM_LPCDR &= ~CPM_LPCDR_LSCS)
+#define __cpm_select_pixclk_lcd() (REG_CPM_LPCDR &= ~CPM_LPCDR_LTCS)
+#define __cpm_select_pixclk_tve() (REG_CPM_LPCDR |= CPM_LPCDR_LTCS)
+#define __cpm_select_i2sclk_exclk() (REG_CPM_I2SCDR &= ~CPM_I2SCDR_I2CS)
+#define __cpm_select_i2sclk_pll() (REG_CPM_I2SCDR |= CPM_I2SCDR_I2CS)
+//#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_cko()
+#define __cpm_exclk_direct() (REG_CPM_CPCCR &= ~CPM_CPCCR_ECS)
+#define __cpm_exclk_div2() (REG_CPM_CPCCR |= CPM_CPCCR_ECS)
+#define __cpm_enable_pll_change() (REG_CPM_CPCCR |= CPM_CPCCR_CE)
+
+#define __cpm_pllout_div2() (REG_CPM_CPCCR &= ~CPM_CPCCR_PCS)
+#define __cpm_pll_enable() (REG_CPM_CPPCR |= CPM_CPPCR_PLLEN)
+
+#define __cpm_pll1_enable() (REG_CPM_CPPCR1 |= CPM_CPPCR1_PLL1EN)
+
+#define __cpm_pll_is_off() (REG_CPM_CPPSR & CPM_CPPSR_PLLOFF)
+#define __cpm_pll_is_on() (REG_CPM_CPPSR & CPM_CPPSR_PLLON)
+#define __cpm_pll_bypass() (REG_CPM_CPPSR |= CPM_CPPSR_PLLBP)
+
+#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() \
+ do {\
+ (REG_CPM_CLKGR0 = 0xffffffff);\
+ (REG_CPM_CLKGR1 = 0x3ff);\
+ }while(0)
+#define __cpm_stop_emc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_EMC)
+#define __cpm_stop_ddr() (REG_CPM_CLKGR0 |= CPM_CLKGR0_DDR)
+#define __cpm_stop_ipu() (REG_CPM_CLKGR0 |= CPM_CLKGR0_IPU)
+#define __cpm_stop_lcd() (REG_CPM_CLKGR0 |= CPM_CLKGR0_LCD)
+#define __cpm_stop_tve() (REG_CPM_CLKGR0 |= CPM_CLKGR0_TVE)
+#define __cpm_stop_Cim() (REG_CPM_CLKGR0 |= CPM_CLKGR0_CIM)
+#define __cpm_stop_mdma() (REG_CPM_CLKGR0 |= CPM_CLKGR0_MDMA)
+#define __cpm_stop_uhc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_UHC)
+#define __cpm_stop_mac() (REG_CPM_CLKGR0 |= CPM_CLKGR0_MAC)
+#define __cpm_stop_gps() (REG_CPM_CLKGR0 |= CPM_CLKGR0_GPS)
+#define __cpm_stop_dmac() (REG_CPM_CLKGR0 |= CPM_CLKGR0_DMAC)
+#define __cpm_stop_ssi2() (REG_CPM_CLKGR0 |= CPM_CLKGR0_SSI2)
+#define __cpm_stop_ssi1() (REG_CPM_CLKGR0 |= CPM_CLKGR0_SSI1)
+#define __cpm_stop_uart3() (REG_CPM_CLKGR0 |= CPM_CLKGR0_UART3)
+#define __cpm_stop_uart2() (REG_CPM_CLKGR0 |= CPM_CLKGR0_UART2)
+#define __cpm_stop_uart1() (REG_CPM_CLKGR0 |= CPM_CLKGR0_UART1)
+#define __cpm_stop_uart0() (REG_CPM_CLKGR0 |= CPM_CLKGR0_UART0)
+#define __cpm_stop_sadc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_SADC)
+#define __cpm_stop_kbc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_KBC)
+#define __cpm_stop_msc2() (REG_CPM_CLKGR0 |= CPM_CLKGR0_MSC2)
+#define __cpm_stop_msc1() (REG_CPM_CLKGR0 |= CPM_CLKGR0_MSC1)
+#define __cpm_stop_owi() (REG_CPM_CLKGR0 |= CPM_CLKGR0_OWI)
+#define __cpm_stop_tssi() (REG_CPM_CLKGR0 |= CPM_CLKGR0_TSSI)
+#define __cpm_stop_aic() (REG_CPM_CLKGR0 |= CPM_CLKGR0_AIC)
+#define __cpm_stop_scc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_SCC)
+#define __cpm_stop_i2c0() (REG_CPM_CLKGR0 |= CPM_CLKGR0_I2C1)
+#define __cpm_stop_i2c1() (REG_CPM_CLKGR0 |= CPM_CLKGR0_I2C0)
+#define __cpm_stop_ssi0() (REG_CPM_CLKGR0 |= CPM_CLKGR0_SSI0)
+#define __cpm_stop_msc0() (REG_CPM_CLKGR0 |= CPM_CLKGR0_MSC0)
+#define __cpm_stop_otg() (REG_CPM_CLKGR0 |= CPM_CLKGR0_OTG)
+#define __cpm_stop_bch() (REG_CPM_CLKGR0 |= CPM_CLKGR0_BCH)
+#define __cpm_stop_nemc() (REG_CPM_CLKGR0 |= CPM_CLKGR0_NEMC)
+#define __cpm_stop_gpu() (REG_CPM_CLKGR1 |= CPM_CLKGR0_GPU)
+#define __cpm_stop_pcm() (REG_CPM_CLKGR1 |= CPM_CLKGR0_PCM)
+#define __cpm_stop_ahb1() (REG_CPM_CLKGR1 |= CPM_CLKGR0_AHB1)
+#define __cpm_stop_cabac() (REG_CPM_CLKGR1 |= CPM_CLKGR0_CABAC)
+#define __cpm_stop_sram() (REG_CPM_CLKGR1 |= CPM_CLKGR0_SRAM)
+#define __cpm_stop_dct() (REG_CPM_CLKGR1 |= CPM_CLKGR0_DCT)
+#define __cpm_stop_me() (REG_CPM_CLKGR1 |= CPM_CLKGR0_ME)
+#define __cpm_stop_dblk() (REG_CPM_CLKGR1 |= CPM_CLKGR0_DBLK)
+#define __cpm_stop_mc() (REG_CPM_CLKGR1 |= CPM_CLKGR0_MC)
+#define __cpm_stop_bdma() (REG_CPM_CLKGR1 |= CPM_CLKGR0_BDMA)
+
+#define __cpm_start_all() \
+ do {\
+ REG_CPM_CLKGR0 = 0x0;\
+ REG_CPM_CLKGR1 = 0x0;\
+ } while(0)
+#define __cpm_start_emc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_EMC)
+#define __cpm_start_ddr() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_DDR)
+#define __cpm_start_ipu() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_IPU)
+#define __cpm_start_lcd() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_LCD)
+#define __cpm_start_tve() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_TVE)
+#define __cpm_start_Cim() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_CIM)
+#define __cpm_start_mdma() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_MDMA)
+#define __cpm_start_uhc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_UHC)
+#define __cpm_start_mac() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_MAC)
+#define __cpm_start_gps() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_GPS)
+#define __cpm_start_dmac() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_DMAC)
+#define __cpm_start_ssi2() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_SSI2)
+#define __cpm_start_ssi1() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_SSI1)
+#define __cpm_start_uart3() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_UART3)
+#define __cpm_start_uart2() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_UART2)
+#define __cpm_start_uart1() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_UART1)
+#define __cpm_start_uart0() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_UART0)
+#define __cpm_start_sadc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_SADC)
+#define __cpm_start_kbc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_KBC)
+#define __cpm_start_msc2() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_MSC2)
+#define __cpm_start_msc1() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_MSC1)
+#define __cpm_start_owi() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_OWI)
+#define __cpm_start_tssi() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_TSSI)
+#define __cpm_start_aic() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_AIC)
+#define __cpm_start_scc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_SCC)
+#define __cpm_start_i2c0() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_I2C1)
+#define __cpm_start_i2c1() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_I2C0)
+#define __cpm_start_ssi0() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_SSI0)
+#define __cpm_start_msc0() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_MSC0)
+#define __cpm_start_otg() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_OTG)
+#define __cpm_start_bch() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_BCH)
+#define __cpm_start_nemc() (REG_CPM_CLKGR0 &= ~CPM_CLKGR0_NEMC)
+#define __cpm_start_gpu() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_GPU)
+#define __cpm_start_pcm() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_PCM)
+#define __cpm_start_ahb1() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_AHB1)
+#define __cpm_start_cabac() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_CABAC)
+#define __cpm_start_sram() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_SRAM)
+#define __cpm_start_dct() (REG_CPM_CLKGR1 &= ~CPM_CLKGR1_DCT)
+#define __cpm_start_me() (REG_CPM_CLKGR1 &= ~CPM_CLKGR0_ME)
+#define __cpm_start_dblk() (REG_CPM_CLKGR1 &= ~CPM_CLKGR0_DBLK)
+#define __cpm_start_mc() (REG_CPM_CLKGR1 &= ~CPM_CLKGR0_MC)
+#define __cpm_start_bdma() (REG_CPM_CLKGR1 &= ~CPM_CLKGR0_BDMA)
+
+#define __cpm_get_o1st() \
+ ((REG_CPM_OPCR & CPM_OPCR_O1ST_MASK) >> CPM_OPCR_O1ST_BIT)
+#define __cpm_set_o1st(v) \
+ (REG_CPM_OPCR = (REG_CPM_OPCR & ~CPM_OPCR_O1ST_MASK) | ((v) << (CPM_OPCR_O1ST_BIT)))
+
+#define __cpm_suspend_otg_phy() (REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE)
+#define __cpm_enable_otg_phy() (REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE)
+
+#define __cpm_suspend_uhc_phy() (REG_CPM_OPCR |= CPM_OPCR_UHCPHY_DISABLE)
+#define __cpm_enable_uhc_phy() (REG_CPM_OPCR &= ~CPM_OPCR_UHCPHY_DISABLE)
+
+#define __cpm_suspend_uhcphy() (REG_CPM_OPCR |= CPM_OPCR_UHCPHY_DISABLE)
+#define __cpm_suspend_gps() (REG_CPM_OPCR &= ~CPM_OPCR_GPSEN)
+#define __cpm_suspend_udcphy() (REG_CPM_OPCR &= ~CPM_OPCR_UDCPHY_ENABLE)
+#define __cpm_disable_osc_in_sleep() (REG_CPM_OPCR &= ~CPM_OPCR_OSC_ENABLE)
+#define __cpm_enable_osc_in_sleep() (REG_CPM_OPCR |= CPM_OPCR_OSC_ENABLE)
+#define __cpm_select_rtcclk_rtc() (REG_CPM_OPCR |= CPM_OPCR_ERCS)
+#define __cpm_select_rtcclk_exclk() (REG_CPM_OPCR &= ~CPM_OPCR_ERCS)
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810CPM_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810dbg.c b/arch/mips/include/asm/mach-jz4810/jz4810dbg.c
new file mode 100644
index 00000000000..72d27752802
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810dbg.c
@@ -0,0 +1,30 @@
+#include <asm/mach-jz4810/regs.h>
+#include <asm/mach-jz4810/jz4810misc.h>
+#include <asm/mach-jz4810/jz4810gpio.h>
+#include <asm/mach-jz4810/jz4810uart.h>
+
+static void dserial_putc (const char c)
+{
+ volatile u8 *uart_lsr = (volatile u8 *)(UART2_BASE + OFF_LSR);
+ volatile u8 *uart_tdr = (volatile u8 *)(UART2_BASE + OFF_TDR);
+
+ if (c == '\n') dserial_putc ('\r');
+
+ /* Wait for fifo to shift out some bytes */
+ while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) );
+
+ *uart_tdr = (u8)c;
+}
+
+static void dserial_puts (const char *s)
+{
+ while (*s) {
+ dserial_putc (*s++);
+ }
+}
+
+main()
+{
+ dserial_puts("\n");
+ return 0;
+}
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810ddrc.h b/arch/mips/include/asm/mach-jz4810/jz4810ddrc.h
new file mode 100644
index 00000000000..59797b75c7b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810ddrc.h
@@ -0,0 +1,345 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810ddrc.h
+ *
+ * JZ4810 DDRC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810DDRC_H__
+#define __JZ4810DDRC_H__
+
+
+#define DDRC_BASE 0xB3020000
+
+/*************************************************************************
+ * DDRC (DDR Controller)
+ *************************************************************************/
+#define DDRC_ST (DDRC_BASE + 0x0) /* DDR Status Register */
+#define DDRC_CFG (DDRC_BASE + 0x4) /* DDR Configure Register */
+#define DDRC_CTRL (DDRC_BASE + 0x8) /* DDR Control Register */
+#define DDRC_LMR (DDRC_BASE + 0xc) /* DDR Load-Mode-Register */
+#define DDRC_TIMING1 (DDRC_BASE + 0x10) /* DDR Timing Config Register 1 */
+#define DDRC_TIMING2 (DDRC_BASE + 0x14) /* DDR Timing Config Register 2 */
+#define DDRC_REFCNT (DDRC_BASE + 0x18) /* DDR Auto-Refresh Counter */
+#define DDRC_DQS (DDRC_BASE + 0x1c) /* DDR DQS Delay Control Register */
+#define DDRC_DQS_ADJ (DDRC_BASE + 0x20) /* DDR DQS Delay Adjust Register */
+#define DDRC_MMAP0 (DDRC_BASE + 0x24) /* DDR Memory Map Config Register */
+#define DDRC_MMAP1 (DDRC_BASE + 0x28) /* DDR Memory Map Config Register */
+
+/* DDRC Register */
+#define REG_DDRC_ST REG32(DDRC_ST)
+#define REG_DDRC_CFG REG32(DDRC_CFG)
+#define REG_DDRC_CTRL REG32(DDRC_CTRL)
+#define REG_DDRC_LMR REG32(DDRC_LMR)
+#define REG_DDRC_TIMING1 REG32(DDRC_TIMING1)
+#define REG_DDRC_TIMING2 REG32(DDRC_TIMING2)
+#define REG_DDRC_REFCNT REG32(DDRC_REFCNT)
+#define REG_DDRC_DQS REG32(DDRC_DQS)
+#define REG_DDRC_DQS_ADJ REG32(DDRC_DQS_ADJ)
+#define REG_DDRC_MMAP0 REG32(DDRC_MMAP0)
+#define REG_DDRC_MMAP1 REG32(DDRC_MMAP1)
+
+/* DDRC Status Register */
+#define DDRC_ST_ENDIAN (1 << 7) /* 0 Little data endian
+ 1 Big data endian */
+#define DDRC_ST_DPDN (1 << 5) /* 0 DDR memory is NOT in deep-power-down state
+ 1 DDR memory is in deep-power-down state */
+#define DDRC_ST_PDN (1 << 4) /* 0 DDR memory is NOT in power-down state
+ 1 DDR memory is in power-down state */
+#define DDRC_ST_AREF (1 << 3) /* 0 DDR memory is NOT in auto-refresh state
+ 1 DDR memory is in auto-refresh state */
+#define DDRC_ST_SREF (1 << 2) /* 0 DDR memory is NOT in self-refresh state
+ 1 DDR memory is in self-refresh state */
+#define DDRC_ST_CKE1 (1 << 1) /* 0 CKE1 Pin is low
+ 1 CKE1 Pin is high */
+#define DDRC_ST_CKE0 (1 << 0) /* 0 CKE0 Pin is low
+ 1 CKE0 Pin is high */
+
+/* DDRC Configure Register */
+#define DDRC_CFG_MSEL_BIT 16 /* Mask delay select */
+#define DDRC_CFG_MSEL_MASK (0x3 << DDRC_CFG_MSEL_BIT)
+ #define DDRC_CFG_MSEL_0 (0 << DDRC_CFG_MSEL_BIT) /* 00 No delay */
+ #define DDRC_CFG_MSEL_1 (1 << DDRC_CFG_MSEL_BIT) /* 01 delay 1 tCK */
+ #define DDRC_CFG_MSEL_2 (2 << DDRC_CFG_MSEL_BIT) /* 10 delay 2 tCK */
+ #define DDRC_CFG_MSEL_3 (3 << DDRC_CFG_MSEL_BIT) /* 11 delay 3 tCK */
+
+#define DDRC_CFG_HL (1 << 15) /* 0: no extra delay 1: one extra half tCK delay */
+
+#define DDRC_CFG_ROW1_BIT 27 /* Row Address width. */
+#define DDRC_CFG_COL1_BIT 25 /* Row Address width. */
+#define DDRC_CFG_BA1_BIT (1 << 24)
+#define DDRC_CFG_IMBA_BIT (1 << 23)
+#define DDRC_CFG_BTRUN (1 << 21)
+
+#define DDRC_CFG_TYPE_BIT 12
+#define DDRC_CFG_TYPE_MASK (0x7 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR1 (2 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_MDDR (3 << DDRC_CFG_TYPE_BIT)
+#define DDRC_CFG_TYPE_DDR2 (4 << DDRC_CFG_TYPE_BIT)
+
+#define DDRC_CFG_ROW_BIT 10 /* Row Address width. */
+#define DDRC_CFG_ROW_MASK (0x3 << DDRC_CFG_ROW_BIT)
+ #define DDRC_CFG_ROW_13 (0 << DDRC_CFG_ROW_BIT) /* 13-bit row address is used */
+ #define DDRC_CFG_ROW_14 (1 << DDRC_CFG_ROW_BIT) /* 14-bit row address is used */
+
+#define DDRC_CFG_COL_BIT 8 /* Column Address width.
+ Specify the Column address width of external DDR. */
+#define DDRC_CFG_COL_MASK (0x3 << DDRC_CFG_COL_BIT)
+ #define DDRC_CFG_COL_9 (0 << DDRC_CFG_COL_BIT) /* 9-bit Column address is used */
+ #define DDRC_CFG_COL_10 (1 << DDRC_CFG_COL_BIT) /* 10-bit Column address is used */
+
+#define DDRC_CFG_CS1EN (1 << 7) /* 0 DDR Pin CS1 un-used
+ 1 There're DDR memory connected to CS1 */
+#define DDRC_CFG_CS0EN (1 << 6) /* 0 DDR Pin CS0 un-used
+ 1 There're DDR memory connected to CS0 */
+
+#define DDRC_CFG_TSEL_BIT 18 /* Read delay select */
+#define DDRC_CFG_TSEL_MASK (0x3 << DDRC_CFG_TSEL_BIT)
+#define DDRC_CFG_TSEL_0 (0 << DDRC_CFG_TSEL_BIT) /* No delay */
+#define DDRC_CFG_TSEL_1 (1 << DDRC_CFG_TSEL_BIT) /* delay 1 tCK */
+#define DDRC_CFG_TSEL_2 (2 << DDRC_CFG_TSEL_BIT) /* delay 2 tCK */
+#define DDRC_CFG_TSEL_3 (3 << DDRC_CFG_TSEL_BIT) /* delay 3 tCK */
+
+#define DDRC_CFG_CL_BIT 2 /* CAS Latency */
+#define DDRC_CFG_CL_MASK (0xf << DDRC_CFG_CL_BIT)
+#define DDRC_CFG_CL_3 (0 << DDRC_CFG_CL_BIT) /* CL = 3 tCK */
+#define DDRC_CFG_CL_4 (1 << DDRC_CFG_CL_BIT) /* CL = 4 tCK */
+#define DDRC_CFG_CL_5 (2 << DDRC_CFG_CL_BIT) /* CL = 5 tCK */
+#define DDRC_CFG_CL_6 (3 << DDRC_CFG_CL_BIT) /* CL = 6 tCK */
+
+#define DDRC_CFG_BA (1 << 1) /* 0 4 bank device, Pin ba[1:0] valid, ba[2] un-used
+ 1 8 bank device, Pin ba[2:0] valid*/
+#define DDRC_CFG_DW (1 << 0) /*0 External memory data width is 16-bit
+ 1 External memory data width is 32-bit */
+
+/* DDRC Control Register */
+#define DDRC_CTRL_ACTPD (1 << 15) /* 0 Precharge all banks before entering power-down
+ 1 Do not precharge banks before entering power-down */
+#define DDRC_CTRL_PDT_BIT 12 /* Power-Down Timer */
+#define DDRC_CTRL_PDT_MASK (0x7 << DDRC_CTRL_PDT_BIT)
+ #define DDRC_CTRL_PDT_DIS (0 << DDRC_CTRL_PDT_BIT) /* power-down disabled */
+ #define DDRC_CTRL_PDT_8 (1 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 8 tCK idle */
+ #define DDRC_CTRL_PDT_16 (2 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 16 tCK idle */
+ #define DDRC_CTRL_PDT_32 (3 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 32 tCK idle */
+ #define DDRC_CTRL_PDT_64 (4 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 64 tCK idle */
+ #define DDRC_CTRL_PDT_128 (5 << DDRC_CTRL_PDT_BIT) /* Enter power-down after 128 tCK idle */
+
+#define DDRC_CTRL_PRET_BIT 8 /* Precharge Timer */
+#define DDRC_CTRL_PRET_MASK (0x7 << DDRC_CTRL_PRET_BIT) /* */
+ #define DDRC_CTRL_PRET_DIS (0 << DDRC_CTRL_PRET_BIT) /* PRET function Disabled */
+ #define DDRC_CTRL_PRET_8 (1 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 8 tCK idle */
+ #define DDRC_CTRL_PRET_16 (2 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 16 tCK idle */
+ #define DDRC_CTRL_PRET_32 (3 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 32 tCK idle */
+ #define DDRC_CTRL_PRET_64 (4 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 64 tCK idle */
+ #define DDRC_CTRL_PRET_128 (5 << DDRC_CTRL_PRET_BIT) /* Precharge active bank after 128 tCK idle */
+
+#define DDRC_CTRL_SR (1 << 5) /* 1 Drive external DDR device entering self-refresh mode
+ 0 Drive external DDR device exiting self-refresh mode */
+#define DDRC_CTRL_UNALIGN (1 << 4) /* 0 Disable unaligned transfer on AXI BUS
+ 1 Enable unaligned transfer on AXI BUS */
+#define DDRC_CTRL_ALH (1 << 3) /* Advanced Latency Hiding:
+ 0 Disable ALH
+ 1 Enable ALH */
+#define DDRC_CTRL_RDC (1 << 2) /* 0 dclk clock frequency is lower than 60MHz
+ 1 dclk clock frequency is higher than 60MHz */
+#define DDRC_CTRL_CKE (1 << 1) /* 0 Not set CKE Pin High
+ 1 Set CKE Pin HIGH */
+#define DDRC_CTRL_RESET (1 << 0) /* 0 End resetting ddrc_controller
+ 1 Resetting ddrc_controller */
+
+/* DDRC Load-Mode-Register */
+#define DDRC_LMR_DDR_ADDR_BIT 16 /* When performing a DDR command, DDRC_ADDR[13:0]
+ corresponding to external DDR address Pin A[13:0] */
+#define DDRC_LMR_DDR_ADDR_MASK (0xff << DDRC_LMR_DDR_ADDR_BIT)
+
+#define DDRC_LMR_BA_BIT 8 /* When performing a DDR command, BA[2:0]
+ corresponding to external DDR address Pin BA[2:0]. */
+#define DDRC_LMR_BA_MASK (0x7 << DDRC_LMR_BA_BIT)
+ /* For DDR2 */
+ #define DDRC_LMR_BA_MRS (0 << DDRC_LMR_BA_BIT) /* Mode Register set */
+ #define DDRC_LMR_BA_EMRS1 (1 << DDRC_LMR_BA_BIT) /* Extended Mode Register1 set */
+ #define DDRC_LMR_BA_EMRS2 (2 << DDRC_LMR_BA_BIT) /* Extended Mode Register2 set */
+ #define DDRC_LMR_BA_EMRS3 (3 << DDRC_LMR_BA_BIT) /* Extended Mode Register3 set */
+ /* For mobile DDR */
+ #define DDRC_LMR_BA_M_MRS (0 << DDRC_LMR_BA_BIT) /* Mode Register set */
+ #define DDRC_LMR_BA_M_EMRS (2 << DDRC_LMR_BA_BIT) /* Extended Mode Register set */
+ #define DDRC_LMR_BA_M_SR (1 << DDRC_LMR_BA_BIT) /* Status Register set */
+
+#define DDRC_LMR_CMD_BIT 4
+#define DDRC_LMR_CMD_MASK (0x3 << DDRC_LMR_CMD_BIT)
+ #define DDRC_LMR_CMD_PREC (0 << DDRC_LMR_CMD_BIT)/* Precharge one bank/All banks */
+ #define DDRC_LMR_CMD_AUREF (1 << DDRC_LMR_CMD_BIT)/* Auto-Refresh */
+ #define DDRC_LMR_CMD_LMR (2 << DDRC_LMR_CMD_BIT)/* Load Mode Register */
+
+#define DDRC_LMR_START (1 << 0) /* 0 No command is performed
+ 1 On the posedge of START, perform a command
+ defined by CMD field */
+
+/* DDRC Mode Register Set */
+#define DDR_MRS_PD_BIT (1 << 10) /* Active power down exit time */
+#define DDR_MRS_PD_MASK (1 << DDR_MRS_PD_BIT)
+ #define DDR_MRS_PD_FAST_EXIT (0 << 10)
+ #define DDR_MRS_PD_SLOW_EXIT (1 << 10)
+#define DDR_MRS_WR_BIT (1 << 9) /* Write Recovery for autoprecharge */
+#define DDR_MRS_WR_MASK (7 << DDR_MRS_WR_BIT)
+#define DDR_MRS_DLL_RST (1 << 8) /* DLL Reset */
+#define DDR_MRS_TM_BIT 7 /* Operating Mode */
+#define DDR_MRS_TM_MASK (1 << DDR_MRS_OM_BIT)
+ #define DDR_MRS_TM_NORMAL (0 << DDR_MRS_OM_BIT)
+ #define DDR_MRS_TM_TEST (1 << DDR_MRS_OM_BIT)
+#define DDR_MRS_CAS_BIT 4 /* CAS Latency */
+#define DDR_MRS_CAS_MASK (7 << DDR_MRS_CAS_BIT)
+#define DDR_MRS_BT_BIT 3 /* Burst Type */
+#define DDR_MRS_BT_MASK (1 << DDR_MRS_BT_BIT)
+ #define DDR_MRS_BT_SEQ (0 << DDR_MRS_BT_BIT) /* Sequential */
+ #define DDR_MRS_BT_INT (1 << DDR_MRS_BT_BIT) /* Interleave */
+#define DDR_MRS_BL_BIT 0 /* Burst Length */
+#define DDR_MRS_BL_MASK (7 << DDR_MRS_BL_BIT)
+ #define DDR_MRS_BL_4 (2 << DDR_MRS_BL_BIT)
+ #define DDR_MRS_BL_8 (3 << DDR_MRS_BL_BIT)
+
+/* DDRC Extended Mode Register1 Set */
+#define DDR_EMRS1_QOFF (1<<12) /* 0 Output buffer enabled
+ 1 Output buffer disabled */
+#define DDR_EMRS1_RDQS_EN (1<<11) /* 0 Disable
+ 1 Enable */
+#define DDR_EMRS1_DQS_DIS (1<<10) /* 0 Enable
+ 1 Disable */
+#define DDR_EMRS1_OCD_BIT 7 /* Additive Latency 0 -> 6 */
+#define DDR_EMRS1_OCD_MASK (0x7 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_EXIT (0 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_D0 (1 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_D1 (2 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_ADJ (4 << DDR_EMRS1_OCD_BIT)
+ #define DDR_EMRS1_OCD_DFLT (7 << DDR_EMRS1_OCD_BIT)
+#define DDR_EMRS1_AL_BIT 3 /* Additive Latency 0 -> 6 */
+#define DDR_EMRS1_AL_MASK (7 << DDR_EMRS1_AL_BIT)
+#define DDR_EMRS1_RTT_BIT 2 /* */
+#define DDR_EMRS1_RTT_MASK (0x11 << DDR_EMRS1_DIC_BIT) /* Bit 6, Bit 2 */
+#define DDR_EMRS1_DIC_BIT 1 /* Output Driver Impedence Control */
+#define DDR_EMRS1_DIC_MASK (1 << DDR_EMRS1_DIC_BIT) /* 100% */
+ #define DDR_EMRS1_DIC_NORMAL (0 << DDR_EMRS1_DIC_BIT) /* 60% */
+ #define DDR_EMRS1_DIC_HALF (1 << DDR_EMRS1_DIC_BIT)
+#define DDR_EMRS1_DLL_BIT 0 /* DLL Enable */
+#define DDR_EMRS1_DLL_MASK (1 << DDR_EMRS1_DLL_BIT)
+ #define DDR_EMRS1_DLL_EN (0 << DDR_EMRS1_DLL_BIT)
+ #define DDR_EMRS1_DLL_DIS (1 << DDR_EMRS1_DLL_BIT)
+
+/* Mobile SDRAM Extended Mode Register */
+#define DDR_EMRS_DS_BIT 5 /* Driver strength */
+#define DDR_EMRS_DS_MASK (7 << DDR_EMRS_DS_BIT)
+ #define DDR_EMRS_DS_FULL (0 << DDR_EMRS_DS_BIT) /*Full*/
+ #define DDR_EMRS_DS_HALF (1 << DDR_EMRS_DS_BIT) /*1/2 Strength*/
+ #define DDR_EMRS_DS_QUTR (2 << DDR_EMRS_DS_BIT) /*1/4 Strength*/
+ #define DDR_EMRS_DS_OCTANT (3 << DDR_EMRS_DS_BIT) /*1/8 Strength*/
+ #define DDR_EMRS_DS_QUTR3 (4 << DDR_EMRS_DS_BIT) /*3/4 Strength*/
+
+#define DDR_EMRS_PRSR_BIT 0 /* Partial Array Self Refresh */
+#define DDR_EMRS_PRSR_MASK (7 << DDR_EMRS_PRSR_BIT)
+ #define DDR_EMRS_PRSR_ALL (0 << DDR_EMRS_PRSR_BIT) /*All Banks*/
+ #define DDR_EMRS_PRSR_HALF_TL (1 << DDR_EMRS_PRSR_BIT) /*Half of Total Bank*/
+ #define DDR_EMRS_PRSR_QUTR_TL (2 << DDR_EMRS_PRSR_BIT) /*Quarter of Total Bank*/
+ #define DDR_EMRS_PRSR_HALF_B0 (5 << DDR_EMRS_PRSR_BIT) /*Half of Bank0*/
+ #define DDR_EMRS_PRSR_QUTR_B0 (6 << DDR_EMRS_PRSR_BIT) /*Quarter of Bank0*/
+
+
+/* DDRC Timing Config Register 1 */
+#define DDRC_TIMING1_TRAS_BIT 28 /* ACTIVE to PRECHARGE command period (2 * tRAS + 1) */
+#define DDRC_TIMING1_TRAS_MASK (0xf << DDRC_TIMING1_TRAS_BIT)
+
+
+#define DDRC_TIMING1_TRTP_BIT 24 /* READ to PRECHARGE command period. */
+#define DDRC_TIMING1_TRTP_MASK (0x3 << DDRC_TIMING1_TRTP_BIT)
+
+#define DDRC_TIMING1_TRP_BIT 20 /* PRECHARGE command period. */
+#define DDRC_TIMING1_TRP_MASK (0x7 << DDRC_TIMING1_TRP_BIT)
+
+#define DDRC_TIMING1_TRCD_BIT 16 /* ACTIVE to READ or WRITE command period. */
+#define DDRC_TIMING1_TRCD_MASK (0x7 << DDRC_TIMING1_TRCD_BIT)
+
+#define DDRC_TIMING1_TRC_BIT 12 /* ACTIVE to ACTIVE command period. */
+#define DDRC_TIMING1_TRC_MASK (0xf << DDRC_TIMING1_TRC_BIT)
+
+#define DDRC_TIMING1_TRRD_BIT 8 /* ACTIVE bank A to ACTIVE bank B command period. */
+#define DDRC_TIMING1_TRRD_MASK (0x3 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_DISABLE (0 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_2 (1 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_3 (2 << DDRC_TIMING1_TRRD_BIT)
+#define DDRC_TIMING1_TRRD_4 (3 << DDRC_TIMING1_TRRD_BIT)
+
+#define DDRC_TIMING1_TWR_BIT 4 /* WRITE Recovery Time defined by register MR of DDR2 memory */
+#define DDRC_TIMING1_TWR_MASK (0x7 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_1 (0 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_2 (1 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_3 (2 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_4 (3 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_5 (4 << DDRC_TIMING1_TWR_BIT)
+ #define DDRC_TIMING1_TWR_6 (5 << DDRC_TIMING1_TWR_BIT)
+
+#define DDRC_TIMING1_TWTR_BIT 0 /* WRITE to READ command delay. */
+#define DDRC_TIMING1_TWTR_MASK (0x3 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_1 (0 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_2 (1 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_3 (2 << DDRC_TIMING1_TWTR_BIT)
+ #define DDRC_TIMING1_TWTR_4 (3 << DDRC_TIMING1_TWTR_BIT)
+
+/* DDRC Timing Config Register 2 */
+#define DDRC_TIMING2_TRFC_BIT 12 /* AUTO-REFRESH command period. */
+#define DDRC_TIMING2_TRFC_MASK (0xf << DDRC_TIMING2_TRFC_BIT)
+#define DDRC_TIMING2_TMINSR_BIT 8 /* Minimum Self-Refresh / Deep-Power-Down time */
+#define DDRC_TIMING2_TMINSR_MASK (0xf << DDRC_TIMING2_TMINSR_BIT)
+#define DDRC_TIMING2_TXP_BIT 4 /* EXIT-POWER-DOWN to next valid command period. */
+#define DDRC_TIMING2_TXP_MASK (0x7 << DDRC_TIMING2_TXP_BIT)
+#define DDRC_TIMING2_TMRD_BIT 0 /* Load-Mode-Register to next valid command period. */
+#define DDRC_TIMING2_TMRD_MASK (0x3 << DDRC_TIMING2_TMRD_BIT)
+
+/* DDRC Auto-Refresh Counter */
+#define DDRC_REFCNT_CON_BIT 16 /* Constant value used to compare with CNT value. */
+#define DDRC_REFCNT_CON_MASK (0xff << DDRC_REFCNT_CON_BIT)
+#define DDRC_REFCNT_CNT_BIT 8 /* 8-bit counter */
+#define DDRC_REFCNT_CNT_MASK (0xff << DDRC_REFCNT_CNT_BIT)
+#define DDRC_REFCNT_CLKDIV_BIT 1 /* Clock Divider for auto-refresh counter. */
+#define DDRC_REFCNT_CLKDIV_MASK (0x7 << DDRC_REFCNT_CLKDIV_BIT)
+#define DDRC_REFCNT_REF_EN (1 << 0) /* Enable Refresh Counter */
+
+/* DDRC DQS Delay Control Register */
+#define DDRC_DQS_ERROR (1 << 29) /* ahb_clk Delay Detect ERROR, read-only. */
+#define DDRC_DQS_READY (1 << 28) /* ahb_clk Delay Detect READY, read-only. */
+#define DDRC_DQS_AUTO (1 << 23) /* Hardware auto-detect & set delay line */
+#define DDRC_DQS_DET (1 << 24) /* Start delay detecting. */
+#define DDRC_DQS_CLKD_BIT 16 /* CLKD is reference value for setting WDQS and RDQS.*/
+#define DDRC_DQS_CLKD_MASK (0x7f << DDRC_DQS_CLKD_BIT)
+#define DDRC_DQS_WDQS_BIT 8 /* Set delay element number to write DQS delay-line. */
+#define DDRC_DQS_WDQS_MASK (0x3f << DDRC_DQS_WDQS_BIT)
+#define DDRC_DQS_RDQS_BIT 0 /* Set delay element number to read DQS delay-line. */
+#define DDRC_DQS_RDQS_MASK (0x3f << DDRC_DQS_RDQS_BIT)
+
+/* DDRC DQS Delay Adjust Register */
+#define DDRC_DQS_ADJWDQS_BIT 8 /* The adjust value for WRITE DQS delay */
+#define DDRC_DQS_ADJWDQS_MASK (0x1f << DDRC_DQS_ADJWDQS_BIT)
+#define DDRC_DQS_ADJRDQS_BIT 0 /* The adjust value for READ DQS delay */
+#define DDRC_DQS_ADJRDQS_MASK (0x1f << DDRC_DQS_ADJRDQS_BIT)
+
+/* DDRC Memory Map Config Register */
+#define DDRC_MMAP_BASE_BIT 8 /* base address */
+#define DDRC_MMAP_BASE_MASK (0xff << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP_MASK_BIT 0 /* address mask */
+#define DDRC_MMAP_MASK_MASK (0xff << DDRC_MMAP_MASK_BIT)
+
+#define DDRC_MMAP0_BASE (0x20 << DDRC_MMAP_BASE_BIT)
+#define DDRC_MMAP1_BASE_64M (0x24 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+#define DDRC_MMAP1_BASE_128M (0x28 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+#define DDRC_MMAP1_BASE_256M (0x30 << DDRC_MMAP_BASE_BIT) /*when bank0 is 128M*/
+
+#define DDRC_MMAP_MASK_64_64 (0xfc << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+#define DDRC_MMAP_MASK_128_128 (0xf8 << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+#define DDRC_MMAP_MASK_256_256 (0xf0 << DDRC_MMAP_MASK_BIT) /*mask for two 128M SDRAM*/
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810DDRC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810dmac.h b/arch/mips/include/asm/mach-jz4810/jz4810dmac.h
new file mode 100644
index 00000000000..ebde999c268
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810dmac.h
@@ -0,0 +1,373 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810dmac.h
+ *
+ * JZ4810 DMAC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810DMAC_H__
+#define __JZ4810DMAC_H__
+
+
+#define DMAC_BASE 0xB3420000
+
+
+/*************************************************************************
+ * DMAC (DMA Controller)
+ *************************************************************************/
+
+#define MAX_DMA_NUM 12 /* max 12 channels */
+#define MAX_MDMA_NUM 3 /* max 3 channels */
+#define MAX_BDMA_NUM 3 /* max 3 channels */
+#define HALF_DMA_NUM 6 /* the number of one dma controller's channels */
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define DMAC_DSAR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x00 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA source address */
+#define DMAC_DTAR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x04 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA target address */
+#define DMAC_DTCR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x08 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA transfer count */
+#define DMAC_DRSR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x0c + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA request source */
+#define DMAC_DCCSR(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x10 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA control/status */
+#define DMAC_DCMD(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x14 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA command */
+#define DMAC_DDA(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0x18 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x20)) /* DMA descriptor address */
+#define DMAC_DSD(n) (DMAC_BASE + ((n)/HALF_DMA_NUM*0x100 + 0xc0 + ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM) * 0x04)) /* DMA Stride Address */
+
+#define DMAC_DMACR(m) (DMAC_BASE + 0x0300 + 0x100 * (m)) /* DMA control register */
+#define DMAC_DMAIPR(m) (DMAC_BASE + 0x0304 + 0x100 * (m)) /* DMA interrupt pending */
+#define DMAC_DMADBR(m) (DMAC_BASE + 0x0308 + 0x100 * (m)) /* DMA doorbell */
+#define DMAC_DMADBSR(m) (DMAC_BASE + 0x030C + 0x100 * (m)) /* DMA doorbell set */
+#define DMAC_DMACKE(m) (DMAC_BASE + 0x0310 + 0x100 * (m))
+
+#define REG_DMAC_DSAR(n) REG32(DMAC_DSAR((n)))
+#define REG_DMAC_DTAR(n) REG32(DMAC_DTAR((n)))
+#define REG_DMAC_DTCR(n) REG32(DMAC_DTCR((n)))
+#define REG_DMAC_DRSR(n) REG32(DMAC_DRSR((n)))
+#define REG_DMAC_DCCSR(n) REG32(DMAC_DCCSR((n)))
+#define REG_DMAC_DCMD(n) REG32(DMAC_DCMD((n)))
+#define REG_DMAC_DDA(n) REG32(DMAC_DDA((n)))
+#define REG_DMAC_DSD(n) REG32(DMAC_DSD(n))
+#define REG_DMAC_DMACR(m) REG32(DMAC_DMACR(m))
+#define REG_DMAC_DMAIPR(m) REG32(DMAC_DMAIPR(m))
+#define REG_DMAC_DMADBR(m) REG32(DMAC_DMADBR(m))
+#define REG_DMAC_DMADBSR(m) REG32(DMAC_DMADBSR(m))
+#define REG_DMAC_DMACKE(m) REG32(DMAC_DMACKE(m))
+
+// DMA request source register
+#define DMAC_DRSR_RS_BIT 0
+#define DMAC_DRSR_RS_MASK (0x3f << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_EXT (0 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_NAND (1 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_BCH_ENC (2 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_BCH_DEC (3 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AUTO (8 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_TSSIIN (9 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART3OUT (14 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART3IN (15 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART2OUT (16 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART2IN (17 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART1OUT (18 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART1IN (19 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART0OUT (20 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_UART0IN (21 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI0OUT (22 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI0IN (23 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AICOUT (24 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_AICIN (25 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC0OUT (26 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC0IN (27 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_TCU (28 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SADC (29 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC1OUT (30 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_MSC1IN (31 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI1OUT (32 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_SSI1IN (33 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_PMOUT (34 << DMAC_DRSR_RS_BIT)
+ #define DMAC_DRSR_RS_PMIN (35 << DMAC_DRSR_RS_BIT)
+
+// DMA channel control/status register
+#define DMAC_DCCSR_NDES (1 << 31) /* descriptor (0) or not (1) ? */
+#define DMAC_DCCSR_DES8 (1 << 30) /* Descriptor 8 Word */
+#define DMAC_DCCSR_DES4 (0 << 30) /* Descriptor 4 Word */
+#define DMAC_DCCSR_CDOA_BIT 16 /* copy of DMA offset address */
+#define DMAC_DCCSR_CDOA_MASK (0xff << DMAC_DCCSR_CDOA_BIT)
+#define DMAC_DCCSR_BERR (1 << 7) /* BCH error within this transfer, Only for channel 0 */
+#define DMAC_DCCSR_INV (1 << 6) /* descriptor invalid */
+#define DMAC_DCCSR_AR (1 << 4) /* address error */
+#define DMAC_DCCSR_TT (1 << 3) /* transfer terminated */
+#define DMAC_DCCSR_HLT (1 << 2) /* DMA halted */
+#define DMAC_DCCSR_CT (1 << 1) /* count terminated */
+#define DMAC_DCCSR_EN (1 << 0) /* channel enable bit */
+
+// DMA channel command register
+#define DMAC_DCMD_EACKS_LOW (1 << 31) /* External DACK Output Level Select, active low */
+#define DMAC_DCMD_EACKS_HIGH (0 << 31) /* External DACK Output Level Select, active high */
+#define DMAC_DCMD_EACKM_WRITE (1 << 30) /* External DACK Output Mode Select, output in write cycle */
+#define DMAC_DCMD_EACKM_READ (0 << 30) /* External DACK Output Mode Select, output in read cycle */
+#define DMAC_DCMD_ERDM_BIT 28 /* External DREQ Detection Mode Select */
+#define DMAC_DCMD_ERDM_MASK (0x03 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_LOW (0 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_FALL (1 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_HIGH (2 << DMAC_DCMD_ERDM_BIT)
+ #define DMAC_DCMD_ERDM_RISE (3 << DMAC_DCMD_ERDM_BIT)
+#define DMAC_DCMD_BLAST (1 << 25) /* BCH last */
+#define DMAC_DCMD_SAI (1 << 23) /* source address increment */
+#define DMAC_DCMD_DAI (1 << 22) /* dest address increment */
+#define DMAC_DCMD_RDIL_BIT 16 /* request detection interval length */
+#define DMAC_DCMD_RDIL_MASK (0x0f << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_IGN (0 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_2 (1 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_4 (2 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_8 (3 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_12 (4 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_16 (5 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_20 (6 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_24 (7 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_28 (8 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_32 (9 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_48 (10 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_60 (11 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_64 (12 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_124 (13 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_128 (14 << DMAC_DCMD_RDIL_BIT)
+ #define DMAC_DCMD_RDIL_200 (15 << DMAC_DCMD_RDIL_BIT)
+#define DMAC_DCMD_SWDH_BIT 14 /* source port width */
+#define DMAC_DCMD_SWDH_MASK (0x03 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_32 (0 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_8 (1 << DMAC_DCMD_SWDH_BIT)
+ #define DMAC_DCMD_SWDH_16 (2 << DMAC_DCMD_SWDH_BIT)
+#define DMAC_DCMD_DWDH_BIT 12 /* dest port width */
+#define DMAC_DCMD_DWDH_MASK (0x03 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_32 (0 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_8 (1 << DMAC_DCMD_DWDH_BIT)
+ #define DMAC_DCMD_DWDH_16 (2 << DMAC_DCMD_DWDH_BIT)
+#define DMAC_DCMD_DS_BIT 8 /* transfer data size of a data unit */
+#define DMAC_DCMD_DS_MASK (0x07 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_32BIT (0 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_8BIT (1 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_16BIT (2 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_16BYTE (3 << DMAC_DCMD_DS_BIT)
+ #define DMAC_DCMD_DS_32BYTE (4 << DMAC_DCMD_DS_BIT)
+#define DMAC_DCMD_STDE (1 << 5) /* Stride Disable/Enable */
+#define DMAC_DCMD_DES_V (1 << 4) /* descriptor valid flag */
+#define DMAC_DCMD_DES_VM (1 << 3) /* descriptor valid mask: 1:support V-bit */
+#define DMAC_DCMD_DES_VIE (1 << 2) /* DMA valid error interrupt enable */
+#define DMAC_DCMD_TIE (1 << 1) /* DMA transfer interrupt enable */
+#define DMAC_DCMD_LINK (1 << 0) /* descriptor link enable */
+
+// DMA descriptor address register
+#define DMAC_DDA_BASE_BIT 12 /* descriptor base address */
+#define DMAC_DDA_BASE_MASK (0x0fffff << DMAC_DDA_BASE_BIT)
+#define DMAC_DDA_OFFSET_BIT 4 /* descriptor offset address */
+#define DMAC_DDA_OFFSET_MASK (0x0ff << DMAC_DDA_OFFSET_BIT)
+
+// DMA stride address register
+#define DMAC_DSD_TSD_BIT 16 /* target stride address */
+#define DMAC_DSD_TSD_MASK (0xffff << DMAC_DSD_TSD_BIT)
+#define DMAC_DSD_SSD_BIT 0 /* source stride address */
+#define DMAC_DSD_SSD_MASK (0xffff << DMAC_DSD_SSD_BIT)
+
+// DMA control register
+#define DMAC_DMACR_FMSC (1 << 31) /* MSC Fast DMA mode */
+#define DMAC_DMACR_FSSI (1 << 30) /* SSI Fast DMA mode */
+#define DMAC_DMACR_FTSSI (1 << 29) /* TSSI Fast DMA mode */
+#define DMAC_DMACR_FUART (1 << 28) /* UART Fast DMA mode */
+#define DMAC_DMACR_FAIC (1 << 27) /* AIC Fast DMA mode */
+#define DMAC_DMACR_PR_BIT 8 /* channel priority mode */
+#define DMAC_DMACR_PR_MASK (0x03 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_012345 (0 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_120345 (1 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_230145 (2 << DMAC_DMACR_PR_BIT)
+ #define DMAC_DMACR_PR_340125 (3 << DMAC_DMACR_PR_BIT)
+#define DMAC_DMACR_HLT (1 << 3) /* DMA halt flag */
+#define DMAC_DMACR_AR (1 << 2) /* address error flag */
+#define DMAC_DMACR_DMAE (1 << 0) /* DMA enable bit */
+
+// DMA doorbell register
+#define DMAC_DMADBR_DB5 (1 << 5) /* doorbell for channel 5 */
+#define DMAC_DMADBR_DB4 (1 << 4) /* doorbell for channel 4 */
+#define DMAC_DMADBR_DB3 (1 << 3) /* doorbell for channel 3 */
+#define DMAC_DMADBR_DB2 (1 << 2) /* doorbell for channel 2 */
+#define DMAC_DMADBR_DB1 (1 << 1) /* doorbell for channel 1 */
+#define DMAC_DMADBR_DB0 (1 << 0) /* doorbell for channel 0 */
+
+// DMA doorbell set register
+#define DMAC_DMADBSR_DBS5 (1 << 5) /* enable doorbell for channel 5 */
+#define DMAC_DMADBSR_DBS4 (1 << 4) /* enable doorbell for channel 4 */
+#define DMAC_DMADBSR_DBS3 (1 << 3) /* enable doorbell for channel 3 */
+#define DMAC_DMADBSR_DBS2 (1 << 2) /* enable doorbell for channel 2 */
+#define DMAC_DMADBSR_DBS1 (1 << 1) /* enable doorbell for channel 1 */
+#define DMAC_DMADBSR_DBS0 (1 << 0) /* enable doorbell for channel 0 */
+
+// DMA interrupt pending register
+#define DMAC_DMAIPR_CIRQ5 (1 << 5) /* irq pending status for channel 5 */
+#define DMAC_DMAIPR_CIRQ4 (1 << 4) /* irq pending status for channel 4 */
+#define DMAC_DMAIPR_CIRQ3 (1 << 3) /* irq pending status for channel 3 */
+#define DMAC_DMAIPR_CIRQ2 (1 << 2) /* irq pending status for channel 2 */
+#define DMAC_DMAIPR_CIRQ1 (1 << 1) /* irq pending status for channel 1 */
+#define DMAC_DMAIPR_CIRQ0 (1 << 0) /* irq pending status for channel 0 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * DMAC
+ ***************************************************************************/
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define __dmac_enable_module(m) \
+ ( REG_DMAC_DMACR(m) |= DMAC_DMACR_DMAE | DMAC_DMACR_PR_012345 )
+#define __dmac_disable_module(m) \
+ ( REG_DMAC_DMACR(m) &= ~DMAC_DMACR_DMAE )
+
+/* p=0,1,2,3 */
+#define __dmac_set_priority(m,p) \
+do { \
+ REG_DMAC_DMACR(m) &= ~DMAC_DMACR_PR_MASK; \
+ REG_DMAC_DMACR(m) |= ((p) << DMAC_DMACR_PR_BIT); \
+} while (0)
+
+#define __dmac_test_halt_error(m) ( REG_DMAC_DMACR(m) & DMAC_DMACR_HLT )
+#define __dmac_test_addr_error(m) ( REG_DMAC_DMACR(m) & DMAC_DMACR_AR )
+
+#define __dmac_channel_enable_clk(n) \
+ REG_DMAC_DMACKE((n)/HALF_DMA_NUM) |= 1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM);
+
+#define __dmac_enable_descriptor(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES )
+#define __dmac_disable_descriptor(n) \
+ ( REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_NDES )
+
+#define __dmac_enable_channel(n) \
+do { \
+ REG_DMAC_DCCSR((n)) |= DMAC_DCCSR_EN; \
+} while (0)
+#define __dmac_disable_channel(n) \
+do { \
+ REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN; \
+} while (0)
+#define __dmac_channel_enabled(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_EN )
+
+#define __dmac_channel_enable_irq(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_TIE )
+#define __dmac_channel_disable_irq(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE )
+
+#define __dmac_channel_transmit_halt_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_HLT )
+#define __dmac_channel_transmit_end_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_TT )
+#define __dmac_channel_address_error_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_AR )
+#define __dmac_channel_count_terminated_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_CT )
+#define __dmac_channel_descriptor_invalid_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_INV )
+
+#define __dmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT; \
+ REG_DMAC_DMACR(n/HALF_DMA_NUM) &= ~DMAC_DMACR_HLT; \
+ } while (0)
+#define __dmac_channel_clear_transmit_end(n) \
+ ( REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_TT )
+#define __dmac_channel_clear_address_error(n) \
+ do { \
+ REG_DMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_DMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_DMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_DMAC_DCCSR(n) &= ~DMAC_DCCSR_AR; \
+ REG_DMAC_DMACR(n/HALF_DMA_NUM) &= ~DMAC_DMACR_AR; \
+ } while (0)
+#define __dmac_channel_clear_count_terminated(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT )
+#define __dmac_channel_clear_descriptor_invalid(n) \
+ ( REG_DMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV )
+
+#define __dmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __dmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __dmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __dmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; \
+ REG_DMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; \
+} while (0)
+
+/* v=0-15 */
+#define __dmac_channel_set_rdil(n,v) \
+do { \
+ REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK; \
+ REG_DMAC_DCMD((n) |= ((v) << DMAC_DCMD_RDIL_BIT); \
+} while (0)
+
+#define __dmac_channel_dest_addr_fixed(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_DAI )
+#define __dmac_channel_dest_addr_increment(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_DAI )
+
+#define __dmac_channel_src_addr_fixed(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_SAI )
+#define __dmac_channel_src_addr_increment(n) \
+ ( REG_DMAC_DCMD((n)) |= DMAC_DCMD_SAI )
+
+#define __dmac_channel_set_doorbell(n) \
+ ( REG_DMAC_DMADBSR((n)/HALF_DMA_NUM) = (1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+
+#define __dmac_channel_irq_detected(n) ( REG_DMAC_DMAIPR((n)/HALF_DMA_NUM) & (1 << ((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+#define __dmac_channel_ack_irq(n) ( REG_DMAC_DMAIPR((n)/HALF_DMA_NUM) &= ~(1 <<((n)-(n)/HALF_DMA_NUM*HALF_DMA_NUM)) )
+
+static __inline__ int __dmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_DMA_NUM; i++)
+ if (__dmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810DMAC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810emc.h b/arch/mips/include/asm/mach-jz4810/jz4810emc.h
new file mode 100644
index 00000000000..857e4ff946d
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810emc.h
@@ -0,0 +1,213 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810emc.h
+ *
+ * JZ4810 EMC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810EMC_H__
+#define __JZ4810EMC_H__
+
+
+#define EMC_BASE 0xB3010000
+
+
+/*************************************************************************
+ * EMC (External Memory Controller)
+ *************************************************************************/
+#define EMC_BCR (EMC_BASE + 0x00) /* Bus Control Register */
+#define EMC_PMEMBS1 (EMC_BASE + 0x6004)
+#define EMC_PMEMBS0 (EMC_BASE + 0x6008)
+#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_SMCR5 (EMC_BASE + 0x24) /* Static Memory Control Register 5 */
+#define EMC_SMCR6 (EMC_BASE + 0x28) /* Static Memory Control Register 6 */
+#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_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_DMAR1 (EMC_BASE + 0x94) /* SDRAM Bank 1 Addr Config Register */
+#define EMC_SDMR0 (EMC_BASE + 0xa000) /* Mode Register of SDRAM bank 0 */
+
+#define REG_EMC_BCR REG32(EMC_BCR)
+#define REG_EMC_PMEMBS1 REG32(EMC_PMEMBS1)
+#define REG_EMC_PMEMBS0 REG32(EMC_PMEMBS0)
+#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_SMCR5 REG32(EMC_SMCR5)
+#define REG_EMC_SMCR6 REG32(EMC_SMCR6)
+#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_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)
+#define REG_EMC_DMAR1 REG32(EMC_DMAR1)
+
+/* Bus Control Register */
+#define EMC_BCR_BT_SEL_BIT 30
+#define EMC_BCR_BT_SEL_MASK (0x3 << EMC_BCR_BT_SEL_BIT)
+#define EMC_BCR_PK_SEL (1 << 24)
+#define EMC_BCR_BSR_MASK (1 << 2) /* Nand and SDRAM Bus Share Select: 0, share; 1, unshare */
+ #define EMC_BCR_BSR_SHARE (0 << 2)
+ #define EMC_BCR_BSR_UNSHARE (1 << 2)
+#define EMC_BCR_BRE (1 << 1)
+#define EMC_BCR_ENDIAN (1 << 0)
+
+/* 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)
+
+/* 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_MBSEL (1 << 16)
+#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_SFR (1 << 8) /* self refresh flag */
+#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)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810EMC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810gpio.h b/arch/mips/include/asm/mach-jz4810/jz4810gpio.h
new file mode 100644
index 00000000000..062e1783e00
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810gpio.h
@@ -0,0 +1,1134 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810gpio.h
+ *
+ * JZ4810 GPIO register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810GPIO_H__
+#define __JZ4810GPIO_H__
+
+/***************************************************************************
+ * GPIO
+ ***************************************************************************/
+
+//------------------------------------------------------
+// GPIO Pins Description
+//
+// PORT 0:
+//
+// PIN/BIT N FUNC0 FUNC1 FUNC2 NOTE
+// 0 SD0 - -
+// 1 SD1 - -
+// 2 SD2 - -
+// 3 SD3 - -
+// 4 SD4 - -
+// 5 SD5 - -
+// 6 SD6 - -
+// 7 SD7 - -
+// 8 SD8 - -
+// 9 SD9 - -
+// 10 SD10 - -
+// 11 SD11 - -
+// 12 SD12 - -
+// 13 SD13 - -
+// 14 SD14 - -
+// 15 SD15 - -
+// 16 RD_ - -
+// 17 WE_ - -
+// 18 FRE_ MSC0_CLK SSI0_CLK
+// 19 FWE_ MSC0_CMD SSI0_CE0_
+// 20 MSC0_D0 SSI0_DR - 1
+// 21 CS1_ MSC0_D1 SSI0_DT
+// 22 CS2_ MSC0_D2 -
+// 23 CS3_ - -
+// 24 CS4_ - -
+// 25 CS5_ - -
+// 26 CS6_ - -
+// 27 WAIT_ - -
+// 28 DREQ0 - -
+// 29 DACK0 OWI -
+// 30 - - - 6
+// 31 - - - 7
+
+//Note1. PA20: GPIO group A bit 20. If NAND flash is used, this pin must be used as NAND FRB. (NAND flash ready/busy)
+//Note6. PA30: GPIO group A bit 30 can only be used as input and interrupt, no pull-up and pull-down.
+//Note7. PA31: GPIO group A bit 31. No corresponding pin exists for this GPIO. It is only used to select the function between UART and JTAG, which share the same set of pins, by using register PASEL [31]
+// When PASEL [31]=0, select JTAG function.
+// When PASEL [31]=1, select UART function
+
+//------------------------------------------------------
+// PORT 1:
+//
+// PIN/BIT N FUNC0 FUNC1 FUNC2 NOTE
+// 0 SA0 - -
+// 1 SA1 - -
+// 2 SA2 - - CL
+// 3 SA3 - - AL
+// 4 SA4 - -
+// 5 SA5 - -
+// 6 CIM_PCLK TSCLK -
+// 7 CIM_HSYN TSFRM -
+// 8 CIM_VSYN TSSTR -
+// 9 CIM_MCLK TSFAIL -
+// 10 CIM_D0 TSDI0 -
+// 11 CIM_D1 TSDI1 -
+// 12 CIM_D2 TSDI2 -
+// 13 CIM_D3 TSDI3 -
+// 14 CIM_D4 TSDI4 -
+// 15 CIM_D5 TSDI5 -
+// 16 CIM_D6 TSDI6 -
+// 17 CIM_D7 TSDI7 -
+// 18 - - -
+// 19 - - -
+// 20 MSC2_D0 SSI2_DR TSDI0
+// 21 MSC2_D1 SSI2_DT TSDI1
+// 22 TSDI2 - -
+// 23 TSDI3 - -
+// 24 TSDI4 - -
+// 25 TSDI5 - -
+// 26 TSDI6 - -
+// 27 TSDI7 - -
+// 28 MSC2_CLK SSI2_CLK TSCLK
+// 29 MSC2_CMD SSI2_CE0_ TSSTR
+// 30 MSC2_D2 SSI2_GPC TSFAIL
+// 31 MSC2_D3 SSI2_CE1_ TSFRM
+
+//------------------------------------------------------
+// PORT 2:
+// PIN/BIT N FUNC0 FUNC1 FUNC2 FUNC3 NOTE
+// 0 LCD_B0 (O) LCD_REV (O) - -
+// 1 LCD_B1 (O) LCD_PS (O) - -
+// 2 LCD_B2 (O) - - -
+// 3 LCD_B3 (O) - - -
+// 4 LCD_B4 (O) - - -
+// 5 LCD_B5 (O) - - -
+// 6 LCD_B6 (O) - - -
+// 7 LCD_B7 (O) - - -
+// 8 LCD_PCLK (O) - - -
+// 9 LCD_DE (O) - - -
+// 10 LCD_G0 (O) LCD_SPL (O) - -
+// 11 LCD_G1 (O) - - -
+// 12 LCD_G2 (O) - - -
+// 13 LCD_G3 (O) - - -
+// 14 LCD_G4 (O) - - -
+// 15 LCD_G5 (O) - - -
+// 16 LCD_G6 (O) - - -
+// 17 LCD_G7 (O) - - -
+// 18 LCD_HSYN (IO) - - -
+// 19 LCD_VSYN (IO) - - -
+// 20 LCD_R0 (O) LCD_CLS (O) - -
+// 21 LCD_R1 (O) - - -
+// 22 LCD_R2 (O) - - -
+// 23 LCD_R3 (O) - - -
+// 24 LCD_R4 (O) - - -
+// 25 LCD_R5 (O) - - -
+// 26 LCD_R6 (O) - - -
+// 27 LCD_R7 (O) - - -
+// 28 UART2_RxD (I) - - -
+// 29 UART2_CTS_ (I) - - -
+// 30 UART2_TxD (O) - - -
+// 31 UART2_RTS_ (O) - - -
+
+//------------------------------------------------------
+// PORT 3:
+//
+// PIN/BIT N FUNC0 FUNC1 FUNC2 FUNC3 NOTE
+// 0 MII_TXD0 - - -
+// 1 MII_TXD1 - - -
+// 2 MII_TXD2 - - -
+// 3 MII_TXD3 - - -
+// 4 MII_TXEN - - -
+// 5 MII_TXCLK(RMII_CLK) - - -
+// 6 MII_COL - - -
+// 7 MII_RXER - - -
+// 8 MII_RXDV - - -
+// 9 MII_RXCLK - - -
+// 10 MII_RXD0 - - -
+// 11 MII_RXD1 - - -
+// 12 MII_RXD2 - - -
+// 13 MII_RXD3 - - -
+// 14 MII_CRS - - -
+// 15 MII_MDC - - -
+// 16 MII_MDIO - - -
+// 17 BOOT_SEL0 - - - Note2,5
+// 18 BOOT_SEL1 - - - Note3,5
+// 19 BOOT_SEL2 - - - Note4,5
+// 20 MSC1_D0 SSI1_DR - -
+// 21 MSC1_D1 SSI1_DT - -
+// 22 MSC1_D2 SSI1_GPC - -
+// 23 MSC1_D3 SSI1_CE1_ - -
+// 24 MSC1_CLK SSI1_CLK - -
+// 25 MSC1_CMD SSI1_CE0_ - -
+// 26 UART1_RxD - - -
+// 27 UART1_CTS_ - - -
+// 28 UART1_TxD - - -
+// 29 UART1_RTS_ - - -
+// 30 I2C0_SDA - - -
+// 31 I2C0_SCK - - -
+//
+// Note2. PD17: GPIO group D bit 17 is used as BOOT_SEL0 input during boot.
+// Note3. PD18: GPIO group D bit 18 is used as BOOT_SEL1 input during boot.
+// Note4. PD19: GPIO group D bit 19 is used as BOOT_SEL2 input during boot.
+// Note5. BOOT_SEL2, BOOT_SEL1, BOOT_SEL0 are used to select boot source and function during the processor boot.
+//
+//------------------------------------------------------
+// PORT 4:
+//
+// PIN/BIT N FUNC0 FUNC1 FUNC2 FUNC3 NOTE
+// 0 PWM0 - - -
+// 1 PWM1 - - -
+// 2 PWM2 SYNC - -
+// 3 PWM3 UART3_RxD BCLK -
+// 4 PWM4 - - -
+// 5 PWM5 UART3_TxD SCLK_RSTN -
+// 6 SDATI - - -
+// 7 SDATO - - -
+// 8 UART3_CTS_ - - -
+// 9 UART3_RTS_ - - -
+// 10 - - - -
+// 11 SDATO1 - - -
+// 12 SDATO2 - - -
+// 13 SDATO3 - - -
+// 14 SSI0_DR SSI1_DR SSI2_DR -
+// 15 SSI0_CLK SI1_CLK SSI2_CLK -
+// 16 SSI0_CE0_ SI1_CE0_ SSI2_CE0_ -
+// 17 SSI0_DT SSI1_DT SSI2_DT -
+// 18 SSI0_CE1_ SSI1_CE1_ SSI2_CE1_ -
+// 19 SSI0_GPC SSI1_GPC SSI2_GPC -
+// 20 MSC0_D0 MSC1_D0 MSC2_D0 -
+// 21 MSC0_D1 MSC1_D1 MSC2_D1 -
+// 22 MSC0_D2 MSC1_D2 MSC2_D2 -
+// 23 MSC0_D3 MSC1_D3 MSC2_D3 -
+// 24 MSC0_CLK MSC1_CLK MSC2_CLK -
+// 25 MSC0_CMD MSC1_CMD MSC2_CMD -
+// 26 MSC0_D4 MSC0_D4 MSC0_D4 PS2_MCLK
+// 27 MSC0_D5 MSC0_D5 MSC0_D5 PS2_MDATA
+// 28 MSC0_D6 MSC0_D6 MSC0_D6 PS2_KCLK
+// 29 MSC0_D7 MSC0_D7 MSC0_D7 PS2_KDATA
+// 30 I2C1_SDA SCC_DATA - -
+// 31 I2C1_SCK SCC_CLK - -
+//
+//------------------------------------------------------
+// PORT 5:
+//
+// PIN/BIT N FUNC0 FUNC1 FUNC2 FUNC3 NOTE
+// 0 UART0_RxD GPS_CLK - -
+// 1 UART0_CTS_ GPS_MAG - -
+// 2 UART0_TxD GPS_SIG - -
+// 3 UART0_RTS_ - - -
+//
+//////////////////////////////////////////////////////////
+
+
+
+#define GPIO_BASE 0xB0010000
+
+
+/*************************************************************************
+ * GPIO (General-Purpose I/O Ports)
+ *************************************************************************/
+#define GPIO_BASEA GPIO_BASE +(0)*0x100
+#define GPIO_BASEB GPIO_BASE +(1)*0x100
+#define GPIO_BASEC GPIO_BASE +(2)*0x100
+#define GPIO_BASED GPIO_BASE +(3)*0x100
+#define GPIO_BASEE GPIO_BASE +(4)*0x100
+#define GPIO_BASEF GPIO_BASE +(5)*0x100
+
+#define MAX_GPIO_NUM 192
+#define GPIO_WAKEUP (30)
+
+//n = 0,1,2,3,4,5 (PORTA, PORTB, PORTC, PORTD, PORTE, PORTF)
+#define GPIO_PXPIN(n) (GPIO_BASE + (0x00 + (n)*0x100)) /* PIN Level Register */
+#define GPIO_PXINT(n) (GPIO_BASE + (0x10 + (n)*0x100)) /* Port Interrupt Register */
+#define GPIO_PXINTS(n) (GPIO_BASE + (0x14 + (n)*0x100)) /* Port Interrupt Set Register */
+#define GPIO_PXINTC(n) (GPIO_BASE + (0x18 + (n)*0x100)) /* Port Interrupt Clear Register */
+
+#define GPIO_PXIM(n) (GPIO_BASE + (0x20 + (n)*0x100)) /* Interrupt Mask Register */
+#define GPIO_PXIMS(n) (GPIO_BASE + (0x24 + (n)*0x100)) /* Interrupt Mask Set Reg */
+#define GPIO_PXIMC(n) (GPIO_BASE + (0x28 + (n)*0x100)) /* Interrupt Mask Clear Reg */
+//#define GPIO_PXMASK(n) (GPIO_BASE + (0x20 + (n)*0x100)) /* Port Interrupt Mask Register */
+//#define GPIO_PXMASKS(n) (GPIO_BASE + (0x24 + (n)*0x100)) /* Port Interrupt Mask Set Reg */
+//#define GPIO_PXMASKC(n) (GPIO_BASE + (0x28 + (n)*0x100)) /* Port Interrupt Mask Clear Reg */
+
+#define GPIO_PXPAT1(n) (GPIO_BASE + (0x30 + (n)*0x100)) /* Port Pattern 1 Register */
+#define GPIO_PXPAT1S(n) (GPIO_BASE + (0x34 + (n)*0x100)) /* Port Pattern 1 Set Reg. */
+#define GPIO_PXPAT1C(n) (GPIO_BASE + (0x38 + (n)*0x100)) /* Port Pattern 1 Clear Reg. */
+#define GPIO_PXPAT0(n) (GPIO_BASE + (0x40 + (n)*0x100)) /* Port Pattern 0 Register */
+#define GPIO_PXPAT0S(n) (GPIO_BASE + (0x44 + (n)*0x100)) /* Port Pattern 0 Set Register */
+#define GPIO_PXPAT0C(n) (GPIO_BASE + (0x48 + (n)*0x100)) /* Port Pattern 0 Clear Register */
+#define GPIO_PXFLG(n) (GPIO_BASE + (0x50 + (n)*0x100)) /* Port Flag Register */
+#define GPIO_PXFLGC(n) (GPIO_BASE + (0x54 + (n)*0x100)) /* Port Flag clear Register */
+#define GPIO_PXOEN(n) (GPIO_BASE + (0x60 + (n)*0x100)) /* Port Output Disable Register */
+#define GPIO_PXOENS(n) (GPIO_BASE + (0x64 + (n)*0x100)) /* Port Output Disable Set Register */
+#define GPIO_PXOENC(n) (GPIO_BASE + (0x68 + (n)*0x100)) /* Port Output Disable Clear Register */
+#define GPIO_PXPEN(n) (GPIO_BASE + (0x70 + (n)*0x100)) /* Port Pull Disable Register */
+#define GPIO_PXPENS(n) (GPIO_BASE + (0x74 + (n)*0x100)) /* Port Pull Disable Set Register */
+#define GPIO_PXPENC(n) (GPIO_BASE + (0x78 + (n)*0x100)) /* Port Pull Disable Clear Register */
+#define GPIO_PXDS(n) (GPIO_BASE + (0x80 + (n)*0x100)) /* Port Drive Strength Register */
+#define GPIO_PXDSS(n) (GPIO_BASE + (0x84 + (n)*0x100)) /* Port Drive Strength set Register */
+#define GPIO_PXDSC(n) (GPIO_BASE + (0x88 + (n)*0x100)) /* Port Drive Strength clear Register */
+
+#define REG_GPIO_PXPIN(n) REG32(GPIO_PXPIN((n))) /* PIN level */
+#define REG_GPIO_PXINT(n) REG32(GPIO_PXINT((n))) /* 1: interrupt pending */
+#define REG_GPIO_PXINTS(n) REG32(GPIO_PXINTS((n)))
+#define REG_GPIO_PXINTC(n) REG32(GPIO_PXINTC((n)))
+
+#define REG_GPIO_PXIM(n) REG32(GPIO_PXIM((n))) /* 1: mask pin interrupt */
+#define REG_GPIO_PXIMS(n) REG32(GPIO_PXIMS((n)))
+#define REG_GPIO_PXIMC(n) REG32(GPIO_PXIMC((n)))
+//#define REG_GPIO_PXMASK(n) REG32(GPIO_PXMASK((n))) /* 1: mask pin interrupt */
+//#define REG_GPIO_PXMASKS(n) REG32(GPIO_PXMASKS((n)))
+//#define REG_GPIO_PXMASKC(n) REG32(GPIO_PXMASKC((n)))
+#define REG_GPIO_PXPAT1(n) REG32(GPIO_PXPAT1((n))) /* 1: disable pull up/down */
+#define REG_GPIO_PXPAT1S(n) REG32(GPIO_PXPAT1S((n)))
+#define REG_GPIO_PXPAT1C(n) REG32(GPIO_PXPAT1C((n)))
+#define REG_GPIO_PXPAT0(n) REG32(GPIO_PXPAT0((n))) /* 0:GPIO/INTR, 1:FUNC */
+#define REG_GPIO_PXPAT0S(n) REG32(GPIO_PXPAT0S((n)))
+#define REG_GPIO_PXPAT0C(n) REG32(GPIO_PXPAT0C((n)))
+#define REG_GPIO_PXFLG(n) REG32(GPIO_PXFLG((n))) /* 0:GPIO/Fun0,1:intr/fun1*/
+#define REG_GPIO_PXFLGC(n) REG32(GPIO_PXFLGC((n)))
+#define REG_GPIO_PXOEN(n) REG32(GPIO_PXOEN((n)))
+#define REG_GPIO_PXOENS(n) REG32(GPIO_PXOENS((n))) /* 0:input/low-level-trig/falling-edge-trig, 1:output/high-level-trig/rising-edge-trig */
+#define REG_GPIO_PXOENC(n) REG32(GPIO_PXOENC((n)))
+#define REG_GPIO_PXPEN(n) REG32(GPIO_PXPEN((n)))
+#define REG_GPIO_PXPENS(n) REG32(GPIO_PXPENS((n))) /* 0:Level-trigger/Fun0, 1:Edge-trigger/Fun1 */
+#define REG_GPIO_PXPENC(n) REG32(GPIO_PXPENC((n)))
+#define REG_GPIO_PXDS(n) REG32(GPIO_PXDS((n)))
+#define REG_GPIO_PXDSS(n) REG32(GPIO_PXDSS((n))) /* interrupt flag */
+#define REG_GPIO_PXDSC(n) REG32(GPIO_PXDSC((n))) /* interrupt flag */
+
+#ifndef __MIPS_ASSEMBLER
+
+/*----------------------------------------------------------------
+ * p is the port number (0,1,2,3,4,5)
+ * o is the pin offset (0-31) inside the port
+ * n is the absolute number of a pin (0-127), regardless of the port
+ */
+
+//----------------------------------------------------------------
+// Function Pins Mode
+#define __gpio_as_func0(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXINTC(p) = (1 << o); \
+ REG_GPIO_PXMASKC(p) = (1 << o); \
+ REG_GPIO_PXPAT1C(p) = (1 << o); \
+ REG_GPIO_PXPAT0C(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func1(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXINTC(p) = (1 << o); \
+ REG_GPIO_PXMASKC(p) = (1 << o); \
+ REG_GPIO_PXPAT1C(p) = (1 << o); \
+ REG_GPIO_PXPAT0S(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func2(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXINTC(p) = (1 << o); \
+ REG_GPIO_PXMASKC(p) = (1 << o); \
+ REG_GPIO_PXPAT1S(p) = (1 << o); \
+ REG_GPIO_PXPAT0C(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_func3(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXINTC(p) = (1 << o); \
+ REG_GPIO_PXMASKC(p) = (1 << o); \
+ REG_GPIO_PXPAT1S(p) = (1 << o); \
+ REG_GPIO_PXPAT0S(p) = (1 << o); \
+} while (0)
+
+#if 0
+/*
+ * MII_TXD0- D3 MII_TXEN MII_TXCLK MII_COL
+ * MII_RXER MII_RXDV MII_RXCLK MII_RXD0 - D3
+ * MII_CRS MII_MDC MII_MDIO
+ */
+#define __gpio_as_eth() \
+do { \
+ REG_GPIO_PXINTC(1) = 0x00000010; \
+ REG_GPIO_PXMASKC(1) = 0x00000010; \
+ REG_GPIO_PXPAT1S(1) = 0x00000010; \
+ REG_GPIO_PXPAT0C(1) = 0x00000010; \
+ REG_GPIO_PXINTC(3) = 0x3c000000; \
+ REG_GPIO_PXMASKC(3) = 0x3c000000; \
+ REG_GPIO_PXPAT1C(3) = 0x3c000000; \
+ REG_GPIO_PXPAT0S(3) = 0x3c000000; \
+ REG_GPIO_PXINTC(5) = 0x0000fff0; \
+ REG_GPIO_PXMASKC(5) = 0x0000fff0; \
+ REG_GPIO_PXPAT1C(5) = 0x0000fff0; \
+ REG_GPIO_PXPAT0C(5) = 0x0000fff0; \
+} while (0)
+#endif
+
+#define __gpio_as_eth() \
+do { \
+ REG_GPIO_PXINTC(1) = 0x00000010; \
+ REG_GPIO_PXIMC(1) = 0x00000010; \
+ REG_GPIO_PXPAT1S(1) = 0x00000010; \
+ REG_GPIO_PXPAT0C(1) = 0x00000010; \
+ REG_GPIO_PXINTC(3) = 0x3c000000; \
+ REG_GPIO_PXIMC(3) = 0x3c000000; \
+ REG_GPIO_PXPAT1C(3) = 0x3c000000; \
+ REG_GPIO_PXPAT0S(3) = 0x3c000000; \
+ REG_GPIO_PXINTC(5) = 0x0000fff0; \
+ REG_GPIO_PXIMC(5) = 0x0000fff0; \
+ REG_GPIO_PXPAT1C(5) = 0x0000fff0; \
+ REG_GPIO_PXPAT0C(5) = 0x0000fff0; \
+} while (0)
+
+
+/*
+ * UART0_TxD, UART0_RxD
+ */
+#define __gpio_as_uart0() \
+do { \
+ REG_GPIO_PXINTC(5) = 0x00000005; \
+ REG_GPIO_PXMASKC(5) = 0x00000005; \
+ REG_GPIO_PXPAT1C(5) = 0x00000005; \
+ REG_GPIO_PXPAT0C(5) = 0x00000005; \
+} while (0)
+
+
+/*
+ * UART0_TxD, UART0_RxD, UART0_CTS, UART0_RTS
+ */
+#define __gpio_as_uart0_ctsrts() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0x0000000f; \
+ REG_GPIO_PXTRGC(5) = 0x0000000f; \
+ REG_GPIO_PXSELC(5) = 0x0000000f; \
+ REG_GPIO_PXPES(5) = 0x0000000f; \
+} while (0)
+/*
+ * GPS_CLK GPS_MAG GPS_SIG
+ */
+#define __gpio_as_gps() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0x00000007; \
+ REG_GPIO_PXTRGC(5) = 0x00000007; \
+ REG_GPIO_PXSELS(5) = 0x00000007; \
+ REG_GPIO_PXPES(5) = 0x00000007; \
+} while (0)
+
+/*
+ * UART1_TxD, UART1_RxD
+ */
+#define __gpio_as_uart1() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0x14000000; \
+ REG_GPIO_PXTRGC(3) = 0x14000000; \
+ REG_GPIO_PXSELC(3) = 0x14000000; \
+ REG_GPIO_PXPES(3) = 0x14000000; \
+} while (0)
+
+/*
+ * UART1_TxD, UART1_RxD, UART1_CTS, UART1_RTS
+ */
+#define __gpio_as_uart1_ctsrts() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0x3c000000; \
+ REG_GPIO_PXTRGC(3) = 0x3c000000; \
+ REG_GPIO_PXSELC(3) = 0x3c000000; \
+ REG_GPIO_PXPES(3) = 0x3c000000; \
+} while (0)
+
+/*
+ * UART2_TxD, UART2_RxD
+ */
+#define __gpio_as_uart2() \
+do { \
+ REG_GPIO_PXINTC(2) = 0x50000000; \
+ REG_GPIO_PXMASKC(2) = 0x50000000; \
+ REG_GPIO_PXPAT1C(2) = 0x50000000; \
+ REG_GPIO_PXPAT0C(2) = 0x50000000; \
+} while (0)
+
+/*
+ * UART2_TxD, UART2_RxD, UART2_CTS, UART2_RTS
+ */
+#define __gpio_as_uart2_ctsrts() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0xf0000000; \
+ REG_GPIO_PXTRGC(2) = 0xf0000000; \
+ REG_GPIO_PXSELC(2) = 0xf0000000; \
+ REG_GPIO_PXPES(2) = 0xf0000000; \
+} while (0)
+
+/*
+ * UART3_TxD, UART3_RxD
+ */
+#define __gpio_as_uart3() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00000028; \
+ REG_GPIO_PXTRGC(4) = 0x00000028; \
+ REG_GPIO_PXSELS(4) = 0x00000028; \
+ REG_GPIO_PXPES(4) = 0x00000028; \
+} while (0)
+
+/*
+ * UART3_TxD, UART3_RxD, UART3_CTS, UART3_RTS
+ */
+#define __gpio_as_uart3_ctsrts() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00000028; \
+ REG_GPIO_PXTRGC(4) = 0x00000028; \
+ REG_GPIO_PXSELS(4) = 0x00000028; \
+ REG_GPIO_PXFUNS(4) = 0x00000300; \
+ REG_GPIO_PXTRGC(4) = 0x00000300; \
+ REG_GPIO_PXSELC(4) = 0x00000300; \
+ REG_GPIO_PXPES(4) = 0x00000328; \
+}
+
+/*
+ * SD0 ~ SD7, CS1#, CLE, ALE, FRE#, FWE#, FRB#
+ * @n: chip select number(1 ~ 6)
+ */
+#define __gpio_as_nand_8bit(n) \
+do { \
+ \
+ REG_GPIO_PXFUNS(0) = 0x000c00ff; /* SD0 ~ SD7, CS1#, FRE#, FWE# */ \
+ REG_GPIO_PXSELC(0) = 0x000c00ff; \
+ REG_GPIO_PXTRGC(0) = 0x000c00ff; \
+ REG_GPIO_PXPES(0) = 0x000c00ff; \
+ REG_GPIO_PXFUNS(1) = 0x00000003; /* CLE(SA2), ALE(SA3) */ \
+ REG_GPIO_PXSELC(1) = 0x00000003; \
+ REG_GPIO_PXTRGC(1) = 0x00000003; \
+ REG_GPIO_PXPES(1) = 0x00000003; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(0) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(0) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNC(0) = 0x00100000; /* FRB#(input) */ \
+ REG_GPIO_PXSELC(0) = 0x00100000; \
+ REG_GPIO_PXDIRC(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+#define __gpio_as_nand_16bit(n) \
+do { \
+ \
+ REG_GPIO_PXFUNS(0) = 0x000cffff; /* SD0 ~ SD15, CS1#, FRE#, FWE# */ \
+ REG_GPIO_PXSELC(0) = 0x000cffff; \
+ REG_GPIO_PXTRGC(0) = 0x000cffff; \
+ REG_GPIO_PXPES(0) = 0x000cffff; \
+ REG_GPIO_PXFUNS(1) = 0x00000003; /* CLE(SA2), ALE(SA3) */ \
+ REG_GPIO_PXSELC(1) = 0x00000003; \
+ REG_GPIO_PXTRGC(1) = 0x00000003; \
+ REG_GPIO_PXPES(1) = 0x00000003; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(0) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(0) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNC(0) = 0x00100000; /* FRB#(input) */ \
+ REG_GPIO_PXSELC(0) = 0x00100000; \
+ REG_GPIO_PXDIRC(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+/*
+ * CS4#, RD#, WR#, WAIT#, A0 ~ A22, D0 ~ D7
+ * @n: chip select number(1 ~ 4)
+ */
+#define __gpio_as_nor_8bit(n) \
+do { \
+ /* 32/16-bit data bus */ \
+ REG_GPIO_PXFUNS(0) = 0x000000ff; \
+ REG_GPIO_PXSELC(0) = 0x000000ff; \
+ REG_GPIO_PXPES(0) = 0x000000ff; \
+ \
+ REG_GPIO_PXFUNS(2) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(2) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(2) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNS(1) = 0x0000ffff; /* A0~A15 */ \
+ REG_GPIO_PXSELC(1) = 0x0000ffff; \
+ REG_GPIO_PXPES(1) = 0x0000ffff; \
+ REG_GPIO_PXFUNS(2) = 0x06110007; /* RD#, WR#, WAIT#, A20~A22 */ \
+ REG_GPIO_PXSELC(2) = 0x06110007; \
+ REG_GPIO_PXPES(2) = 0x06110007; \
+ REG_GPIO_PXFUNS(2) = 0x000e0000; /* A17~A19 */ \
+ REG_GPIO_PXSELS(2) = 0x000e0000; \
+ REG_GPIO_PXPES(2) = 0x000e0000; \
+} while (0)
+
+/*
+ * CS4#, RD#, WR#, WAIT#, A0 ~ A22, D0 ~ D15
+ * @n: chip select number(1 ~ 4)
+ */
+#define __gpio_as_nor_16bit(n) \
+do { \
+ /* 32/16-bit data normal order */ \
+ REG_GPIO_PXFUNS(0) = 0x0000ffff; \
+ REG_GPIO_PXSELC(0) = 0x0000ffff; \
+ REG_GPIO_PXPES(0) = 0x0000ffff; \
+ \
+ REG_GPIO_PXFUNS(2) = 0x00200000 << ((n)-1); /* CSn */ \
+ REG_GPIO_PXSELC(2) = 0x00200000 << ((n)-1); \
+ REG_GPIO_PXPES(2) = 0x00200000 << ((n)-1); \
+ \
+ REG_GPIO_PXFUNS(1) = 0x0000ffff; /* A0~A15 */ \
+ REG_GPIO_PXSELC(1) = 0x0000ffff; \
+ REG_GPIO_PXPES(1) = 0x0000ffff; \
+ REG_GPIO_PXFUNS(2) = 0x06110007; /* RD#, WR#, WAIT#, A20~A22 */ \
+ REG_GPIO_PXSELC(2) = 0x06110007; \
+ REG_GPIO_PXPES(2) = 0x06110007; \
+ REG_GPIO_PXFUNS(2) = 0x000e0000; /* A17~A19 */ \
+ REG_GPIO_PXSELS(2) = 0x000e0000; \
+ REG_GPIO_PXPES(2) = 0x000e0000; \
+} while (0)
+
+/*
+ * LCD_D0~LCD_D7, LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_8bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x000c03ff; \
+ REG_GPIO_PXTRGC(2) = 0x000c03ff; \
+ REG_GPIO_PXSELC(2) = 0x000c03ff; \
+ REG_GPIO_PXPES(2) = 0x000c03ff; \
+} while (0)
+
+/*
+ * LCD_R3~LCD_R7, LCD_G2~LCD_G7, LCD_B3~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_16bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXTRGC(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXSELC(2) = 0x0f8ff3f8; \
+ REG_GPIO_PXPES(2) = 0x0f8ff3f8; \
+} while (0)
+
+/*
+ * LCD_R2~LCD_R7, LCD_G2~LCD_G7, LCD_B2~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_18bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fcff3fc; \
+ REG_GPIO_PXTRGC(2) = 0x0fcff3fc; \
+ REG_GPIO_PXSELC(2) = 0x0fcff3fc; \
+ REG_GPIO_PXPES(2) = 0x0fcff3fc; \
+} while (0)
+
+/*
+ * LCD_R0~LCD_R7, LCD_G0~LCD_G7, LCD_B0~LCD_B7,
+ * LCD_PCLK, LCD_HSYNC, LCD_VSYNC, LCD_DE
+ */
+#define __gpio_as_lcd_24bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fffffff; \
+ REG_GPIO_PXTRGC(2) = 0x0fffffff; \
+ REG_GPIO_PXSELC(2) = 0x0fffffff; \
+ REG_GPIO_PXPES(2) = 0x0fffffff; \
+} while (0)
+
+/*
+ * LCD_CLS, LCD_SPL, LCD_PS, LCD_REV
+ */
+#define __gpio_as_lcd_special() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x0fffffff; \
+ REG_GPIO_PXTRGC(2) = 0x0fffffff; \
+ REG_GPIO_PXSELC(2) = 0x0feffbfc; \
+ REG_GPIO_PXSELS(2) = 0x00100403; \
+ REG_GPIO_PXPES(2) = 0x0fffffff; \
+} while (0)
+
+/*
+ * CIM_D0~CIM_D7, CIM_MCLK, CIM_PCLK, CIM_VSYNC, CIM_HSYNC
+ */
+#define __gpio_as_cim() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0x0003ffc0; \
+ REG_GPIO_PXTRGC(1) = 0x0003ffc0; \
+ REG_GPIO_PXSELC(1) = 0x0003ffc0; \
+ REG_GPIO_PXPES(1) = 0x0003ffc0; \
+} while (0)
+
+/*
+ * SDATO, SDATI, BCLK, SYNC, SCLK_RSTN(gpio sepc) or
+ * SDATA_OUT, SDATA_IN, BIT_CLK, SYNC, SCLK_RESET(aic spec)
+ */
+#define __gpio_as_aic() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x16c00000; \
+ REG_GPIO_PXTRGC(4) = 0x02c00000; \
+ REG_GPIO_PXTRGS(4) = 0x14000000; \
+ REG_GPIO_PXSELC(4) = 0x14c00000; \
+ REG_GPIO_PXSELS(4) = 0x02000000; \
+ REG_GPIO_PXPES(4) = 0x16c00000; \
+} while (0)
+
+/*
+ * PCM_DIN, PCM_DOUT, PCM_CLK, PCM_SYN
+*/
+#define __gpio_as_pcm() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0x0000000f; \
+ REG_GPIO_PXSELC(3) = 0x0000000f; \
+ REG_GPIO_PXTRGC(3) = 0x0000000f; \
+} while (0)
+
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D7
+ */
+#define __gpio_as_msc0_8bit() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x3ff00000; \
+ REG_GPIO_PXTRGC(4) = 0x3ff00000; \
+ REG_GPIO_PXSELC(4) = 0x3ff00000; \
+ REG_GPIO_PXPES(4) = 0x3ff00000; \
+} while (0)
+
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D3
+ */
+#define __gpio_as_msc0_4bit() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x30f00000; \
+ REG_GPIO_PXTRGC(4) = 0x30f00000; \
+ REG_GPIO_PXSELC(4) = 0x30f00000; \
+ REG_GPIO_PXPES(4) = 0x30f00000; \
+} while (0)
+
+/*
+ * MSC1_CMD, MSC1_CLK, MSC1_D0 ~ MSC1_D3
+ */
+#define __gpio_as_msc1_4bit() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0x3f00000; \
+ REG_GPIO_PXTRGC(3) = 0x3f00000; \
+ REG_GPIO_PXSELC(3) = 0x3f00000; \
+ REG_GPIO_PXPES(3) = 0x3f00000; \
+} while (0)
+
+#if 0
+/*
+ * MSC0_CMD, MSC0_CLK, MSC0_D0 ~ MSC0_D3
+ */
+#define __gpio_as_msc0_4bit() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x38400300; \
+ REG_GPIO_PXTRGC(2) = 0x38400300; \
+ REG_GPIO_PXSELS(2) = 0x30400300; \
+ REG_GPIO_PXSELC(2) = 0x08000000; \
+ REG_GPIO_PXPES(2) = 0x38400300; \
+} while (0)
+
+/*
+ * MSC1_CMD, MSC1_CLK, MSC1_D0 ~ MSC1_D3
+ */
+#define __gpio_as_msc1_4bit() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xfc000000; \
+ REG_GPIO_PXTRGC(1) = 0xfc000000; \
+ REG_GPIO_PXSELC(1) = 0xfc000000; \
+ REG_GPIO_PXPES(1) = 0xfc000000; \
+} while (0)
+#endif
+
+/* Port B
+ * MSC2_CMD, MSC2_CLK, MSC2_D0 ~ MSC2_D3
+ */
+#define __gpio_as_msc2_4bit_1() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xf0300000; \
+ REG_GPIO_PXTRGC(1) = 0xf0300000; \
+ REG_GPIO_PXSELC(1) = 0xf0300000; \
+ REG_GPIO_PXPES(1) = 0xf0300000; \
+} while (0)
+
+#define __gpio_as_msc __gpio_as_msc0_4bit /* default as msc0 4bit */
+#define __gpio_as_msc0 __gpio_as_msc0_4bit /* msc0 default as 4bit */
+#define __gpio_as_msc1 __gpio_as_msc1_4bit /* msc1 only support 4bit */
+
+/*
+ * TSCLK, TSSTR, TSFRM, TSFAIL, TSDI0~7
+ */
+#define __gpio_as_tssi_1() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0x0003ffc0; \
+ REG_GPIO_PXTRGC(1) = 0x0003ffc0; \
+ REG_GPIO_PXSELS(1) = 0x0003ffc0; \
+ REG_GPIO_PXPES(1) = 0x0003ffc0; \
+} while (0)
+
+/*
+ * TSCLK, TSSTR, TSFRM, TSFAIL, TSDI0~7
+ */
+#define __gpio_as_tssi_2() \
+do { \
+ REG_GPIO_PXFUNS(1) = 0xfff00000; \
+ REG_GPIO_PXTRGC(1) = 0x0fc00000; \
+ REG_GPIO_PXTRGS(1) = 0xf0300000; \
+ REG_GPIO_PXSELC(1) = 0xfff00000; \
+ REG_GPIO_PXPES(1) = 0xfff00000; \
+} while (0)
+
+/*
+ * SSI_CE0, SSI_CE1, SSI_GPC, SSI_CLK, SSI_DT, SSI_DR
+ */
+#define __gpio_as_ssi() \
+do { \
+ REG_GPIO_PXFUNS(0) = 0x002c0000; /* SSI0_CE0, SSI0_CLK, SSI0_DT */ \
+ REG_GPIO_PXTRGS(0) = 0x002c0000; \
+ REG_GPIO_PXSELC(0) = 0x002c0000; \
+ REG_GPIO_PXPES(0) = 0x002c0000; \
+ \
+ REG_GPIO_PXFUNS(0) = 0x00100000; /* SSI0_DR */ \
+ REG_GPIO_PXTRGC(0) = 0x00100000; \
+ REG_GPIO_PXSELS(0) = 0x00100000; \
+ REG_GPIO_PXPES(0) = 0x00100000; \
+} while (0)
+
+/*
+ * SSI_CE0, SSI_CE2, SSI_GPC, SSI_CLK, SSI_DT, SSI1_DR
+ */
+#define __gpio_as_ssi_1() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0x0000fc00; \
+ REG_GPIO_PXTRGC(5) = 0x0000fc00; \
+ REG_GPIO_PXSELC(5) = 0x0000fc00; \
+ REG_GPIO_PXPES(5) = 0x0000fc00; \
+} while (0)
+
+/* Port B
+ * SSI2_CE0, SSI2_CE2, SSI2_GPC, SSI2_CLK, SSI2_DT, SSI12_DR
+ */
+#define __gpio_as_ssi2_1() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0xf0300000; \
+ REG_GPIO_PXTRGC(5) = 0xf0300000; \
+ REG_GPIO_PXSELS(5) = 0xf0300000; \
+ REG_GPIO_PXPES(5) = 0xf0300000; \
+} while (0)
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c(n) \
+do { \
+ REG_GPIO_PXFUNS(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXTRGC(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXSELC(3+(n)) = 0xc0000000; \
+ REG_GPIO_PXPES(3+(n)) = 0xc0000000; \
+} while (0)
+
+/*
+ * PWM0
+ */
+#define __gpio_as_pwm0() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00100000; \
+ REG_GPIO_PXSELC(4) = 0x00100000; \
+ REG_GPIO_PXPES(4) = 0x00100000; \
+} while (0)
+
+/*
+ * PWM1
+ */
+#define __gpio_as_pwm1() \
+do { \
+ REG_GPIO_PXFUNS(5) = 0x00000800; \
+ REG_GPIO_PXSELC(5) = 0x00000800; \
+ REG_GPIO_PXPES(5) = 0x00000800; \
+} while (0)
+
+/*
+ * PWM2
+ */
+#define __gpio_as_pwm2() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00400000; \
+ REG_GPIO_PXSELC(4) = 0x00400000; \
+ REG_GPIO_PXPES(4) = 0x00400000; \
+} while (0)
+
+/*
+ * PWM3
+ */
+#define __gpio_as_pwm3() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x00800000; \
+ REG_GPIO_PXSELC(4) = 0x00800000; \
+ REG_GPIO_PXPES(4) = 0x00800000; \
+} while (0)
+
+/*
+ * PWM4
+ */
+#define __gpio_as_pwm4() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x01000000; \
+ REG_GPIO_PXSELC(4) = 0x01000000; \
+ REG_GPIO_PXPES(4) = 0x01000000; \
+} while (0)
+
+/*
+ * PWM5
+ */
+#define __gpio_as_pwm5() \
+do { \
+ REG_GPIO_PXFUNS(4) = 0x02000000; \
+ REG_GPIO_PXSELC(4) = 0x02000000; \
+ REG_GPIO_PXPES(4) = 0x02000000; \
+} while (0)
+
+/*
+ * n = 0 ~ 5
+ */
+#define __gpio_as_pwm(n) __gpio_as_pwm##n()
+
+/*
+ * OWI - PA29 function 1
+ */
+#define __gpio_as_owi() \
+do { \
+ REG_GPIO_PXFUNS(0) = 0x20000000; \
+ REG_GPIO_PXTRGC(0) = 0x20000000; \
+ REG_GPIO_PXSELS(0) = 0x20000000; \
+} while (0)
+
+/*
+ * SCC - PD08 function 0
+ * PD09 function 0
+ */
+#define __gpio_as_scc() \
+do { \
+ REG_GPIO_PXFUNS(3) = 0xc0000300; \
+ REG_GPIO_PXTRGC(3) = 0xc0000300; \
+ REG_GPIO_PXSELC(3) = 0xc0000300; \
+} while (0)
+
+#define __gpio_as_otg_drvvbus() \
+do { \
+ REG_GPIO_PXDATC(4) = (1 << 10); \
+ REG_GPIO_PXPEC(4) = (1 << 10); \
+ REG_GPIO_PXSELC(4) = (1 << 10); \
+ REG_GPIO_PXTRGC(4) = (1 << 10); \
+ REG_GPIO_PXFUNS(4) = (1 << 10); \
+} while (0)
+
+//-------------------------------------------
+// GPIO or Interrupt Mode
+
+#define __gpio_get_port(p) (REG_GPIO_PXPIN(p))
+#define __gpio_port_as_output0(p, o) \
+do { \
+ REG_GPIO_PXINTC(p) = (1 << (o)); \
+ REG_GPIO_PXIMS(p) = (1 << (o)); \
+ REG_GPIO_PXPAT1C(p) = (1 << (o)); \
+ REG_GPIO_PXPAT0C(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_port_as_output1(p, o) \
+do { \
+ REG_GPIO_PXINTC(p) = (1 << (o)); \
+ REG_GPIO_PXINTS(p) = (1 << (o)); \
+ REG_GPIO_PXPAT1C(p) = (1 << (o)); \
+ REG_GPIO_PXPAT0S(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_port_as_input(p, o) \
+do { \
+ REG_GPIO_PXINTC(p) = (1 << (o)); \
+ REG_GPIO_PXMASKS(p) = (1 << (o)); \
+ REG_GPIO_PXPAT1S(p) = (1 << (o)); \
+ REG_GPIO_PXPAT0C(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_as_output0(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ __gpio_port_as_output0(p, o); \
+} while (0)
+
+#define __gpio_as_output1(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ __gpio_port_as_output1(p, o); \
+} while (0)
+
+#define __gpio_as_input(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ __gpio_port_as_input(p, o); \
+} while (0)
+
+#define __gpio_set_pin(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDATS(p) = (1 << o); \
+} while (0)
+
+#define __gpio_clear_pin(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDATC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_get_pin(n) \
+({ \
+ unsigned int p, o, v; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ if (__gpio_get_port(p) & (1 << o)) \
+ v = 1; \
+ else \
+ v = 0; \
+ v; \
+})
+
+#define __gpio_as_irq_high_level(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRS(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_low_level(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGC(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRC(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_rise_edge(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRS(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_as_irq_fall_edge(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+ REG_GPIO_PXTRGS(p) = (1 << o); \
+ REG_GPIO_PXFUNC(p) = (1 << o); \
+ REG_GPIO_PXSELS(p) = (1 << o); \
+ REG_GPIO_PXDIRC(p) = (1 << o); \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_mask_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMS(p) = (1 << o); \
+} while (0)
+
+#define __gpio_unmask_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXIMC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_ack_irq(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXFLGC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_get_irq() \
+({ \
+ unsigned int p, i, tmp, v = 0; \
+ for (p = 3; p >= 0; p--) { \
+ tmp = REG_GPIO_PXFLG(p); \
+ for (i = 0; i < 32; i++) \
+ if (tmp & (1 << i)) \
+ v = (32*p + i); \
+ } \
+ v; \
+})
+
+#define __gpio_group_irq(n) \
+({ \
+ register int tmp, i; \
+ tmp = REG_GPIO_PXFLG((n)); \
+ for (i=31;i>=0;i--) \
+ if (tmp & (1 << i)) \
+ break; \
+ i; \
+})
+
+#define __gpio_enable_pull(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXPEC(p) = (1 << o); \
+} while (0)
+
+#define __gpio_disable_pull(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXPES(p) = (1 << o); \
+} while (0)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810GPIO_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810i2c.h b/arch/mips/include/asm/mach-jz4810/jz4810i2c.h
new file mode 100644
index 00000000000..90f86b175d1
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810i2c.h
@@ -0,0 +1,217 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810i2c.h
+ *
+ * JZ4810 I2C register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810I2C_H__
+#define __JZ4810I2C_H__
+
+
+#define I2C0_BASE 0xB0050000
+#define I2C1_BASE 0xB0051000
+
+
+/*************************************************************************
+ * I2C
+ *************************************************************************/
+#define I2C_CTRL(n) (I2C0_BASE + (n)*0x1000 + 0x00)
+#define I2C_TAR(n) (I2C0_BASE + (n)*0x1000 + 0x04)
+#define I2C_SAR(n) (I2C0_BASE + (n)*0x1000 + 0x08)
+#define I2C_DC(n) (I2C0_BASE + (n)*0x1000 + 0x10)
+#define I2C_SHCNT(n) (I2C0_BASE + (n)*0x1000 + 0x14)
+#define I2C_SLCNT(n) (I2C0_BASE + (n)*0x1000 + 0x18)
+#define I2C_FHCNT(n) (I2C0_BASE + (n)*0x1000 + 0x1C)
+#define I2C_FLCNT(n) (I2C0_BASE + (n)*0x1000 + 0x20)
+#define I2C_INTST(n) (I2C0_BASE + (n)*0x1000 + 0x2C)
+#define I2C_INTM(n) (I2C0_BASE + (n)*0x1000 + 0x30)
+#define I2C_RXTL(n) (I2C0_BASE + (n)*0x1000 + 0x38)
+#define I2C_TXTL(n) (I2C0_BASE + (n)*0x1000 + 0x3c)
+#define I2C_CINTR(n) (I2C0_BASE + (n)*0x1000 + 0x40)
+#define I2C_CRXUF(n) (I2C0_BASE + (n)*0x1000 + 0x44)
+#define I2C_CRXOF(n) (I2C0_BASE + (n)*0x1000 + 0x48)
+#define I2C_CTXOF(n) (I2C0_BASE + (n)*0x1000 + 0x4C)
+#define I2C_CRXREQ(n) (I2C0_BASE + (n)*0x1000 + 0x50)
+#define I2C_CTXABRT(n) (I2C0_BASE + (n)*0x1000 + 0x54)
+#define I2C_CRXDONE(n) (I2C0_BASE + (n)*0x1000 + 0x58)
+#define I2C_CACT(n) (I2C0_BASE + (n)*0x1000 + 0x5C)
+#define I2C_CSTP(n) (I2C0_BASE + (n)*0x1000 + 0x60)
+#define I2C_CSTT(n) (I2C0_BASE + (n)*0x1000 + 0x64)
+#define I2C_CGC(n) (I2C0_BASE + (n)*0x1000 + 0x68)
+#define I2C_ENB(n) (I2C0_BASE + (n)*0x1000 + 0x6C)
+#define I2C_STA(n) (I2C0_BASE + (n)*0x1000 + 0x70)
+#define I2C_TXABRT(n) (I2C0_BASE + (n)*0x1000 + 0x80)
+#define I2C_SDASU(n) (I2C0_BASE + (n)*0x1000 + 0x94)
+#define I2C_ACKGC(n) (I2C0_BASE + (n)*0x1000 + 0x98)
+#define I2C_ENSTA(n) (I2C0_BASE + (n)*0x1000 + 0x9C)
+
+#define REG_I2C_CTRL(n) REG8(I2C_CTRL(n)) /* I2C Control Register (I2C_CTRL) */
+#define REG_I2C_TAR(n) REG16(I2C_TAR(n)) /* I2C target address (I2C_TAR) */
+#define REG_I2C_SAR(n) REG16(I2C_SAR(n))
+#define REG_I2C_DC(n) REG16(I2C_DC(n))
+#define REG_I2C_SHCNT(n) REG16(I2C_SHCNT(n))
+#define REG_I2C_SLCNT(n) REG16(I2C_SLCNT(n))
+#define REG_I2C_FHCNT(n) REG16(I2C_FHCNT(n))
+#define REG_I2C_FLCNT(n) REG16(I2C_FLCNT(n))
+#define REG_I2C_INTST(n) REG16(I2C_INTST(n)) /* i2c interrupt status (I2C_INTST) */
+#define REG_I2C_INTM(n) REG16(I2C_INTM(n)) /* i2c interrupt mask status (I2C_INTM) */
+#define REG_I2C_RXTL(n) REG8(I2C_RXTL(n))
+#define REG_I2C_TXTL(n) REG8(I2C_TXTL(n))
+#define REG_I2C_CINTR(n) REG8(I2C_CINTR(n))
+#define REG_I2C_CRXUF(n) REG8(I2C_CRXUF(n))
+#define REG_I2C_CRXOF(n) REG8(I2C_CRXOF(n))
+#define REG_I2C_CTXOF(n) REG8(I2C_CTXOF(n))
+#define REG_I2C_CRXREQ(n) REG8(I2C_CRXREQ(n))
+#define REG_I2C_CTXABRT(n) REG8(I2C_CTXABRT(n))
+#define REG_I2C_CRXDONE(n) REG8(I2C_CRXDONE(n))
+#define REG_I2C_CACT(n) REG8(I2C_CACT(n))
+#define REG_I2C_CSTP(n) REG8(I2C_CSTP(n))
+#define REG_I2C_CSTT(n) REG16(I2C_CSTT(n))
+#define REG_I2C_CGC(n) REG8(I2C_CGC(n))
+#define REG_I2C_ENB(n) REG8(I2C_ENB(n))
+#define REG_I2C_STA(n) REG8(I2C_STA(n))
+#define REG_I2C_TXABRT(n) REG16(I2C_TXABRT(n))
+#define REG_I2C_SDASU(n) REG8(I2C_SDASU(n))
+#define REG_I2C_ACKGC(n) REG8(I2C_ACKGC(n))
+#define REG_I2C_ENSTA(n) REG8(I2C_ENSTA(n))
+
+/* I2C Control Register (I2C_CTRL) */
+
+#define I2C_CTRL_SLVDIS (1 << 6) /* after reset slave is disabled*/
+#define I2C_CTRL_REST (1 << 5)
+#define I2C_CTRL_MATP (1 << 4) /* 1: 10bit address 0: 7bit addressing*/
+#define I2C_CTRL_SATP (1 << 3) /* standard mode 100kbps */
+#define I2C_CTRL_SPDF (2 << 1) /* fast mode 400kbps */
+#define I2C_CTRL_SPDS (1 << 1) /* standard mode 100kbps */
+#define I2C_CTRL_MD (1 << 0) /* master enabled*/
+
+/* I2C target address (I2C_TAR) */
+
+#define I2C_TAR_MATP (1 << 12)
+#define I2C_TAR_SPECIAL (1 << 11)
+#define I2C_TAR_GC_OR_START (1 << 10)
+
+/* I2C slave address */
+/* I2C data buffer and command (I2C_DC) */
+
+#define I2C_DC_CMD (1 << 8) /* 1 read 0 write*/
+
+/* i2c interrupt status (I2C_INTST) */
+
+#define I2C_INTST_IGC (1 << 11) /* */
+#define I2C_INTST_ISTT (1 << 10)
+#define I2C_INTST_ISTP (1 << 9)
+#define I2C_INTST_IACT (1 << 8)
+#define I2C_INTST_RXDN (1 << 7)
+#define I2C_INTST_TXABT (1 << 6)
+#define I2C_INTST_RDREQ (1 << 5)
+#define I2C_INTST_TXEMP (1 << 4)
+#define I2C_INTST_TXOF (1 << 3)
+#define I2C_INTST_RXFL (1 << 2)
+#define I2C_INTST_RXOF (1 << 1)
+#define I2C_INTST_RXUF (1 << 0)
+
+/* i2c interrupt mask status (I2C_INTM) */
+
+#define I2C_INTM_MIGC (1 << 11) /* */
+#define I2C_INTM_MISTT (1 << 10)
+#define I2C_INTM_MISTP (1 << 9)
+#define I2C_INTM_MIACT (1 << 8)
+#define I2C_INTM_MRXDN (1 << 7)
+#define I2C_INTM_MTXABT (1 << 6)
+#define I2C_INTM_MRDREQ (1 << 5)
+#define I2C_INTM_MTXEMP (1 << 4)
+#define I2C_INTM_MTXOF (1 << 3)
+#define I2C_INTM_MRXFL (1 << 2)
+#define I2C_INTM_MRXOF (1 << 1)
+#define I2C_INTM_MRXUF (1 << 0)
+
+/* I2C Clear Combined and Individual Interrupts (I2C_CINTR) */
+
+#define I2C_CINTR_CINT
+
+/* I2C Clear TX_OVER Interrupt */
+/* I2C Clear RDREQ Interrupt */
+/* I2C Clear TX_ABRT Interrupt */
+/* I2C Clear RX_DONE Interrupt */
+/* I2C Clear ACTIVITY Interrupt */
+/* I2C Clear STOP Interrupts */
+/* I2C Clear START Interrupts */
+/* I2C Clear GEN_CALL Interrupts */
+
+/* I2C Enable (I2C_ENB) */
+
+#define I2C_ENB_I2CENB (1 << 0) /* Enable the i2c */
+
+/* I2C Status Register (I2C_STA) */
+
+#define I2C_STA_SLVACT (1 << 6) /* Slave FSM is not in IDLE state */
+#define I2C_STA_MSTACT (1 << 5) /* Master FSM is not in IDLE state */
+#define I2C_STA_RFF (1 << 4) /* RFIFO if full */
+#define I2C_STA_RFNE (1 << 3) /* RFIFO is not empty */
+#define I2C_STA_TFE (1 << 2) /* TFIFO is empty */
+#define I2C_STA_TFNF (1 << 1) /* TFIFO is not full */
+#define I2C_STA_ACT (1 << 0) /* I2C Activity Status */
+
+/* I2C Transmit Abort Status Register (I2C_TXABRT) */
+
+#define I2C_TXABRT_SLVRD_INTX (1 << 15)
+#define I2C_TXABRT_SLV_ARBLOST (1 << 14)
+#define I2C_TXABRT_SLVFLUSH_TXFIFO (1 << 13)
+#define I2C_TXABRT_ARB_LOST (1 << 12)
+#define I2C_TXABRT_ABRT_MASTER_DIS (1 << 11)
+#define I2C_TXABRT_ABRT_10B_RD_NORSTRT (1 << 10)
+#define I2C_TXABRT_SBYTE_NORSTRT (1 << 9)
+#define I2C_TXABRT_ABRT_HS_NORSTRT (1 << 8)
+#define I2C_TXABRT_SBYTE_ACKDET (1 << 7)
+#define I2C_TXABRT_ABRT_HS_ACKD (1 << 6)
+#define I2C_TXABRT_ABRT_GCALL_READ (1 << 5)
+#define I2C_TXABRT_ABRT_GCALL_NOACK (1 << 4)
+#define I2C_TXABRT_ABRT_XDATA_NOACK (1 << 3)
+#define I2C_TXABRT_ABRT_10ADDR2_NOACK (1 << 2)
+#define I2C_TXABRT_ABRT_10ADDR1_NOACK (1 << 1)
+#define I2C_TXABRT_ABRT_7B_ADDR_NOACK (1 << 0)
+
+/* I2C Enable Status Register (I2C_ENSTA) */
+
+#define I2C_ENSTA_SLVRDLST (1 << 2)
+#define I2C_ENSTA_SLVDISB (1 << 1)
+#define I2C_ENSTA_I2CEN (1 << 0) /* when read as 1, i2c is deemed to be in an enabled state
+ when read as 0, i2c is deemed completely inactive. The cpu can
+ safely read this bit anytime .When this bit is read as 0 ,the cpu can
+ safely read SLVRDLST and SLVDISB */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * I2C
+ ***************************************************************************/
+
+#define __i2c_enable(n) ( REG_I2C_ENB(n) = 1 )
+#define __i2c_disable(n) ( REG_I2C_ENB(n) = 0 )
+
+#define __i2c_is_enable(n) ( REG_I2C_ENSTA(n) & I2C_ENB_I2CENB )
+#define __i2c_is_disable(n) ( ~(REG_I2C_ENSTA(n) & I2C_ENB_I2CENB) )
+
+#define __i2c_abrt(n) ( REG_I2C_TXABRT(n) != 0 )
+#define __i2c_master_active(n) ( REG_I2C_STA(n) & I2C_STA_MSTACT )
+#define __i2c_abrt_7b_addr_nack(n) ( REG_I2C_TXABRT(n) & I2C_TXABRT_ABRT_7B_ADDR_NOACK )
+#define __i2c_txfifo_is_empty(n) ( REG_I2C_STA(n) & I2C_STA_TFE )
+#define __i2c_clear_interrupts(ret,n) ( ret = REG_I2C_CINTR(n) )
+
+/*
+#define __i2c_set_clk(dev_clk, i2c_clk) \
+ ( REG_I2C_GR = (dev_clk) / (16*(i2c_clk)) - 1 )
+*/
+
+#define __i2c_read(n) ( REG_I2C_DC(n) & 0xff )
+#define __i2c_write(val,n) ( REG_I2C_DC(n) = (val) )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810I2C_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810intc.h b/arch/mips/include/asm/mach-jz4810/jz4810intc.h
new file mode 100644
index 00000000000..c45950d3810
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810intc.h
@@ -0,0 +1,112 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810intc.h
+ *
+ * JZ4810 INTC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810INTC_H__
+#define __JZ4810INTC_H__
+
+
+#define INTC_BASE 0xB0001000
+
+
+/*************************************************************************
+ * INTC (Interrupt Controller)
+ *************************************************************************/
+/* n = 0 ~ 1 */
+#define INTC_ISR(n) (INTC_BASE + 0x00 + (n) * 0x20)
+#define INTC_IMR(n) (INTC_BASE + 0x04 + (n) * 0x20)
+#define INTC_IMSR(n) (INTC_BASE + 0x08 + (n) * 0x20)
+#define INTC_IMCR(n) (INTC_BASE + 0x0c + (n) * 0x20)
+#define INTC_IPR(n) (INTC_BASE + 0x10 + (n) * 0x20)
+//#define INTC_ISSR (INTC_BASE + 0x18) /* Interrupt Controller Source Set Register */
+//#define INTC_ISCR (INTC_BASE + 0x1c) /* Interrupt Controller Source Clear Register */
+
+#define REG_INTC_ISR(n) REG32(INTC_ISR(n))
+#define REG_INTC_IMR(n) REG32(INTC_IMR(n))
+#define REG_INTC_IMSR(n) REG32(INTC_IMSR(n))
+#define REG_INTC_IMCR(n) REG32(INTC_IMCR(n))
+#define REG_INTC_IPR(n) REG32(INTC_IPR(n))
+//#define REG_INTC_ISSR REG32(INTC_ISSR)
+//#define REG_INTC_ISCR REG32(INTC_ISCR)
+
+// 1st-level interrupts
+#define IRQ_I2C1 0
+#define IRQ_I2C0 1
+#define IRQ_UART3 2
+#define IRQ_UART2 3
+#define IRQ_UART1 4
+#define IRQ_UART0 5
+#define IRQ_SSI2 6
+#define IRQ_SSI1 7
+#define IRQ_SSI0 8
+#define IRQ_TSSI 9
+#define IRQ_BDMA 10
+#define IRQ_KBC 11
+#define IRQ_GPIO5 12
+#define IRQ_GPIO4 13
+#define IRQ_GPIO3 14
+#define IRQ_GPIO2 15
+#define IRQ_GPIO1 16
+#define IRQ_GPIO0 17
+#define IRQ_SADC 18
+#define IRQ_ETH 19
+#define IRQ_UHC 20
+#define IRQ_OTG 21
+#define IRQ_MDMA 22
+#define IRQ_DMAC1 23
+#define IRQ_DMAC0 24
+#define IRQ_TCU2 25
+#define IRQ_TCU1 26
+#define IRQ_TCU0 27
+#define IRQ_GPS 28
+#define IRQ_IPU 29
+#define IRQ_CIM 30
+#define IRQ_LCD 31
+
+#define IRQ_RTC 32
+#define IRQ_OWI 33
+#define IRQ_AIC 34
+#define IRQ_MSC2 35
+#define IRQ_MSC1 36
+#define IRQ_MSC0 37
+#define IRQ_SCC 38
+#define IRQ_BCH 39
+#define IRQ_PCM 40
+
+
+// 2nd-level interrupts
+
+#define IRQ_DMA_0 46 /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+//#define IRQ_DMA_0 32 /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+#define IRQ_DMA_1 (IRQ_DMA_0 + HALF_DMA_NUM) /* 64 ~ 75 for DMAC0 channel 0 ~ 5 & DMAC1 channel 0 ~ 5 */
+#define IRQ_MDMA_0 (IRQ_DMA_0 + MAX_DMA_NUM) /* 64 ~ 66 for MDMAC channel 0 ~ 2 */
+#define IRQ_BDMA_0 (IRQ_DMA_0 + MAX_DMA_NUM + MAX_MDMA_NUM) /* 61 ~ 63 for BDMA channel 0 ~ 2 */
+
+//#define IRQ_GPIO_0 96 /* 96 to 287 for GPIO pin 0 to 127 */
+#define IRQ_GPIO_0 64 /* 96 to 287 for GPIO pin 0 to 127 */
+
+#define NUM_INTC 41
+#define NUM_DMA MAX_DMA_NUM /* 12 */
+#define NUM_MDMA MAX_MDMA_NUM /* 3 */
+#define NUM_GPIO MAX_GPIO_NUM /* GPIO NUM: 192, Jz4810 real num GPIO 178 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * INTC
+ ***************************************************************************/
+#define __intc_unmask_irq(n) (REG_INTC_IMCR((n)/32) = (1 << ((n)%32)))
+#define __intc_mask_irq(n) (REG_INTC_IMSR((n)/32) = (1 << ((n)%32)))
+#define __intc_ack_irq(n) (REG_INTC_IPR((n)/32) = (1 << ((n)%32))) /* A dummy ack, as the Pending Register is Read Only. Should we remove __intc_ack_irq() */
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810INTC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810ipu.h b/arch/mips/include/asm/mach-jz4810/jz4810ipu.h
new file mode 100644
index 00000000000..f8d3931bab2
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810ipu.h
@@ -0,0 +1,328 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810ipu.h
+ *
+ * JZ4810 IPU register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810IPU_H__
+#define __JZ4810IPU_H__
+
+
+#define IPU_BASE 0xB3080000
+
+/*************************************************************************
+ * IPU (Image Processing Unit)
+ *************************************************************************/
+#define IPU_V_BASE 0xB3080000
+#define IPU_P_BASE 0x13080000
+
+/* Register offset */
+#define REG_CTRL 0x0 /* IPU Control Register */
+#define REG_STATUS 0x4 /* IPU Status Register */
+#define REG_D_FMT 0x8 /* Data Format Register */
+#define REG_Y_ADDR 0xc /* Input Y or YUV422 Packaged Data Address Register */
+#define REG_U_ADDR 0x10 /* Input U Data Address Register */
+#define REG_V_ADDR 0x14 /* Input V Data Address Register */
+#define REG_IN_FM_GS 0x18 /* Input Geometric Size Register */
+#define REG_Y_STRIDE 0x1c /* Input Y Data Line Stride Register */
+#define REG_UV_STRIDE 0x20 /* Input UV Data Line Stride Register */
+#define REG_OUT_ADDR 0x24 /* Output Frame Start Address Register */
+#define REG_OUT_GS 0x28 /* Output Geometric Size Register */
+#define REG_OUT_STRIDE 0x2c /* Output Data Line Stride Register */
+#define REG_RSZ_COEF_INDEX 0x30 /* Resize Coefficients Table Index Register */
+#define REG_CSC_CO_COEF 0x34 /* CSC C0 Coefficient Register */
+#define REG_CSC_C1_COEF 0x38 /* CSC C1 Coefficient Register */
+#define REG_CSC_C2_COEF 0x3c /* CSC C2 Coefficient Register */
+#define REG_CSC_C3_COEF 0x40 /* CSC C3 Coefficient Register */
+#define REG_CSC_C4_COEF 0x44 /* CSC C4 Coefficient Register */
+#define HRSZ_LUT_BASE 0x48 /* Horizontal Resize Coefficients Look Up Table Register group */
+#define VRSZ_LUT_BASE 0x4c /* Virtical Resize Coefficients Look Up Table Register group */
+#define REG_CSC_OFSET_PARA 0x50 /* CSC Offset Parameter Register */
+#define REG_Y_PHY_T_ADDR 0x54 /* Input Y Physical Table Address Register */
+#define REG_U_PHY_T_ADDR 0x58 /* Input U Physical Table Address Register */
+#define REG_V_PHY_T_ADDR 0x5c /* Input V Physical Table Address Register */
+#define REG_OUT_PHY_T_ADDR 0x60 /* Output Physical Table Address Register */
+
+/* REG_CTRL: IPU Control Register */
+#define IPU_CE_SFT 0x0
+#define IPU_CE_MSK 0x1
+#define IPU_RUN_SFT 0x1
+#define IPU_RUN_MSK 0x1
+#define HRSZ_EN_SFT 0x2
+#define HRSZ_EN_MSK 0x1
+#define VRSZ_EN_SFT 0x3
+#define VRSZ_EN_MSK 0x1
+#define CSC_EN_SFT 0x4
+#define CSC_EN_MSK 0x1
+#define FM_IRQ_EN_SFT 0x5
+#define FM_IRQ_EN_MSK 0x1
+#define IPU_RST_SFT 0x6
+#define IPU_RST_MSK 0x1
+#define H_SCALE_SFT 0x8
+#define H_SCALE_MSK 0x1
+#define V_SCALE_SFT 0x9
+#define V_SCALE_MSK 0x1
+#define PKG_SEL_SFT 0xA
+#define PKG_SEL_MSK 0x1
+#define LCDC_SEL_SFT 0xB
+#define LCDC_SEL_MSK 0x1
+#define SPAGE_MAP_SFT 0xC
+#define SPAGE_MAP_MSK 0x1
+#define DPAGE_SEL_SFT 0xD
+#define DPAGE_SEL_MSK 0x1
+#define DISP_SEL_SFT 0xE
+#define DISP_SEL_MSK 0x1
+#define FIELD_CONF_EN_SFT 15
+#define FIELD_CONF_EN_MSK 1
+#define FIELD_SEL_SFT 16
+#define FIELD_SEL_MSK 1
+#define DFIX_SEL_SFT 17
+#define DFIX_SEL_MSK 1
+
+/* REG_STATUS: IPU Status Register */
+#define OUT_END_SFT 0x0
+#define OUT_END_MSK 0x1
+#define FMT_ERR_SFT 0x1
+#define FMT_ERR_MSK 0x1
+#define SIZE_ERR_SFT 0x2
+#define SIZE_ERR_MSK 0x1
+
+/* D_FMT: Data Format Register */
+#define IN_FMT_SFT 0x0
+#define IN_FMT_MSK 0x3
+#define IN_OFT_SFT 0x2
+#define IN_OFT_MSK 0x3
+#define YUV_PKG_OUT_SFT 0x10
+#define YUV_PKG_OUT_MSK 0x7
+#define OUT_FMT_SFT 0x13
+#define OUT_FMT_MSK 0x3
+#define RGB_OUT_OFT_SFT 0x15
+#define RGB_OUT_OFT_MSK 0x7
+#define RGB888_FMT_SFT 0x18
+#define RGB888_FMT_MSK 0x1
+
+/* IN_FM_GS: Input Geometric Size Register */
+#define IN_FM_H_SFT 0x0
+#define IN_FM_H_MSK 0xFFF
+#define IN_FM_W_SFT 0x10
+#define IN_FM_W_MSK 0xFFF
+
+/* Y_STRIDE: Input Y Data Line Stride Register */
+#define Y_S_SFT 0x0
+#define Y_S_MSK 0x3FFF
+
+/* UV_STRIDE: Input UV Data Line Stride Register */
+#define V_S_SFT 0x0
+#define V_S_MSK 0x1FFF
+#define U_S_SFT 0x10
+#define U_S_MSK 0x1FFF
+
+/* OUT_GS: Output Geometric Size Register */
+#define OUT_FM_H_SFT 0x0
+#define OUT_FM_H_MSK 0x1FFF
+#define OUT_FM_W_SFT 0x10
+#define OUT_FM_W_MSK 0x7FFF
+
+/* OUT_STRIDE: Output Data Line Stride Register */
+#define OUT_S_SFT 0x0
+#define OUT_S_MSK 0xFFFF
+
+/* RSZ_COEF_INDEX: Resize Coefficients Table Index Register */
+#define VE_IDX_SFT 0x0
+#define VE_IDX_MSK 0x1F
+#define HE_IDX_SFT 0x10
+#define HE_IDX_MSK 0x1F
+
+/* CSC_CX_COEF: CSC CX Coefficient Register */
+#define CX_COEF_SFT 0x0
+#define CX_COEF_MSK 0xFFF
+
+/* HRSZ_LUT_BASE, VRSZ_LUT_BASE: Resize Coefficients Look Up Table Register group */
+#define LUT_LEN 20
+
+#define OUT_N_SFT 0x0
+#define OUT_N_MSK 0x1
+#define IN_N_SFT 0x1
+#define IN_N_MSK 0x1
+#define W_COEF_SFT 0x2
+#define W_COEF_MSK 0x3FF
+
+/* CSC_OFSET_PARA: CSC Offset Parameter Register */
+#define CHROM_OF_SFT 0x10
+#define CHROM_OF_MSK 0xFF
+#define LUMA_OF_SFT 0x00
+#define LUMA_OF_MSK 0xFF
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+#if 0
+/*************************************************************************
+ * IPU (Image Processing Unit)
+ *************************************************************************/
+#define u32 volatile unsigned long
+
+#define write_reg(reg, val) \
+do { \
+ *(u32 *)(reg) = (val); \
+} while(0)
+
+#define read_reg(reg, off) (*(u32 *)((reg)+(off)))
+
+
+#define set_ipu_fmt(rgb_888_out_fmt, rgb_out_oft, out_fmt, yuv_pkg_out, in_oft, in_fmt ) \
+({ write_reg( (IPU_V_BASE + REG_D_FMT), ((in_fmt) & IN_FMT_MSK)<<IN_FMT_SFT \
+| ((in_oft) & IN_OFT_MSK)<< IN_OFT_SFT \
+| ((out_fmt) & OUT_FMT_MSK)<<OUT_FMT_SFT \
+| ((yuv_pkg_out) & YUV_PKG_OUT_MSK ) << YUV_PKG_OUT_SFT \
+| ((rgb_888_out_fmt) & RGB888_FMT_MSK ) << RGB888_FMT_SFT \
+| ((rgb_out_oft) & RGB_OUT_OFT_MSK ) << RGB_OUT_OFT_SFT); \
+})
+#define set_y_addr(y_addr) \
+({ write_reg( (IPU_V_BASE + REG_Y_ADDR), y_addr); \
+})
+#define set_u_addr(u_addr) \
+({ write_reg( (IPU_V_BASE + REG_U_ADDR), u_addr); \
+})
+
+#define set_v_addr(v_addr) \
+({ write_reg( (IPU_V_BASE + REG_V_ADDR), v_addr); \
+})
+
+#define set_y_phy_t_addr(y_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_Y_PHY_T_ADDR), y_phy_t_addr); \
+})
+
+#define set_u_phy_t_addr(u_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_U_PHY_T_ADDR), u_phy_t_addr); \
+})
+
+#define set_v_phy_t_addr(v_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_V_PHY_T_ADDR), v_phy_t_addr); \
+})
+
+#define set_out_phy_t_addr(out_phy_t_addr) \
+({ write_reg( (IPU_V_BASE + REG_OUT_PHY_T_ADDR), out_phy_t_addr); \
+})
+
+#define set_inframe_gsize(width, height, y_stride, u_stride, v_stride) \
+({ write_reg( (IPU_V_BASE + REG_IN_FM_GS), ((width) & IN_FM_W_MSK)<<IN_FM_W_SFT \
+| ((height) & IN_FM_H_MSK)<<IN_FM_H_SFT); \
+ write_reg( (IPU_V_BASE + REG_Y_STRIDE), ((y_stride) & Y_S_MSK)<<Y_S_SFT); \
+ write_reg( (IPU_V_BASE + REG_UV_STRIDE), ((u_stride) & U_S_MSK)<<U_S_SFT \
+| ((v_stride) & V_S_MSK)<<V_S_SFT); \
+})
+#define set_out_addr(out_addr) \
+({ write_reg( (IPU_V_BASE + REG_OUT_ADDR), out_addr); \
+})
+#define set_outframe_gsize(width, height, o_stride) \
+({ write_reg( (IPU_V_BASE + REG_OUT_GS), ((width) & OUT_FM_W_MSK)<<OUT_FM_W_SFT \
+| ((height) & OUT_FM_H_MSK)<<OUT_FM_H_SFT); \
+ write_reg( (IPU_V_BASE + REG_OUT_STRIDE), ((o_stride) & OUT_S_MSK)<<OUT_S_SFT); \
+})
+#define set_rsz_lut_end(h_end, v_end) \
+({ write_reg( (IPU_V_BASE + REG_RSZ_COEF_INDEX), ((h_end) & HE_IDX_MSK)<<HE_IDX_SFT \
+| ((v_end) & VE_IDX_MSK)<<VE_IDX_SFT); \
+})
+#define set_csc_c0(c0_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_CO_COEF), ((c0_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c1(c1_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C1_COEF), ((c1_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c2(c2_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C2_COEF), ((c2_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c3(c3_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C3_COEF), ((c3_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_csc_c4(c4_coeff) \
+({ write_reg( (IPU_V_BASE + REG_CSC_C4_COEF), ((c4_coeff) & CX_COEF_MSK)<<CX_COEF_SFT); \
+})
+#define set_hrsz_lut_coef(coef, in_n, out_n) \
+({ write_reg( (IPU_V_BASE + HRSZ_LUT_BASE ), ((coef) & W_COEF_MSK)<<W_COEF_SFT \
+| ((in_n) & IN_N_MSK)<<IN_N_SFT | ((out_n) & OUT_N_MSK)<<OUT_N_SFT); \
+})
+#define set_vrsz_lut_coef(coef, in_n, out_n) \
+({ write_reg( (IPU_V_BASE + VRSZ_LUT_BASE), ((coef) & W_COEF_MSK)<<W_COEF_SFT \
+| ((in_n) & IN_N_MSK)<<IN_N_SFT | ((out_n) & OUT_N_MSK)<<OUT_N_SFT); \
+})
+
+#define set_primary_ctrl(vrsz_en, hrsz_en,csc_en, irq_en) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((irq_en) & FM_IRQ_EN_MSK)<<FM_IRQ_EN_SFT \
+| ((vrsz_en) & VRSZ_EN_MSK)<<VRSZ_EN_SFT \
+| ((hrsz_en) & HRSZ_EN_MSK)<<HRSZ_EN_SFT \
+| ((csc_en) & CSC_EN_MSK)<<CSC_EN_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(CSC_EN_MSK<<CSC_EN_SFT | FM_IRQ_EN_MSK<<FM_IRQ_EN_SFT | VRSZ_EN_MSK<<VRSZ_EN_SFT | HRSZ_EN_MSK<<HRSZ_EN_SFT ) ); \
+})
+
+#define set_source_ctrl(pkg_sel, spage_sel) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((pkg_sel) & PKG_SEL_MSK )<< PKG_SEL_SFT \
+| ((spage_sel) & SPAGE_MAP_MSK )<< SPAGE_MAP_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(SPAGE_MAP_MSK << SPAGE_MAP_SFT | PKG_SEL_MSK << PKG_SEL_SFT ) ) ; \
+})
+
+#define set_out_ctrl(lcdc_sel, dpage_sel, disp_sel) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((lcdc_sel) & LCDC_SEL_MSK )<< LCDC_SEL_SFT \
+| ((dpage_sel) & DPAGE_SEL_MSK )<< DPAGE_SEL_SFT \
+| ((disp_sel) & DISP_SEL_MSK )<< DISP_SEL_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) \
+& ~(LCDC_SEL_MSK<< LCDC_SEL_SFT | DPAGE_SEL_MSK << DPAGE_SEL_SFT | DISP_SEL_MSK << DISP_SEL_SFT ) ); \
+})
+
+#define set_scale_ctrl(v_scal, h_scal) \
+({ write_reg( (IPU_V_BASE + REG_CTRL), ((v_scal) & V_SCALE_MSK)<<V_SCALE_SFT \
+| ((h_scal) & H_SCALE_MSK)<<H_SCALE_SFT \
+| (read_reg(IPU_V_BASE, REG_CTRL)) & ~(V_SCALE_MSK<<V_SCALE_SFT | H_SCALE_MSK<<H_SCALE_SFT ) ); \
+})
+
+
+#define set_csc_ofset_para(chrom_oft, luma_oft) \
+({ write_reg( (IPU_V_BASE + REG_CSC_OFSET_PARA ), ((chrom_oft) & CHROM_OF_MSK ) << CHROM_OF_SFT \
+| ((luma_oft) & LUMA_OF_MSK ) << LUMA_OF_SFT ) ; \
+})
+
+#define sw_reset_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) \
+| IPU_RST_MSK<<IPU_RST_SFT); \
+})
+#define enable_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) | 0x1); \
+})
+#define disable_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) & ~0x1); \
+})
+#define run_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) | 0x2); \
+})
+#define stop_ipu() \
+({ write_reg( (IPU_V_BASE + REG_CTRL), (read_reg(IPU_V_BASE, REG_CTRL)) & ~0x2); \
+})
+
+#define polling_end_flag() \
+({ (read_reg(IPU_V_BASE, REG_STATUS)) & 0x01; \
+})
+
+#define start_vlut_coef_write() \
+({ write_reg( (IPU_V_BASE + VRSZ_LUT_BASE), ( 0x1<<12 ) ); \
+})
+
+#define start_hlut_coef_write() \
+({ write_reg( (IPU_V_BASE + HRSZ_LUT_BASE), ( 0x01<<12 ) ); \
+})
+
+#define clear_end_flag() \
+({ write_reg( (IPU_V_BASE + REG_STATUS), 0); \
+})
+#endif /* #if 0 */
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810IPU_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810lcdc.h b/arch/mips/include/asm/mach-jz4810/jz4810lcdc.h
new file mode 100644
index 00000000000..147d5b49441
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810lcdc.h
@@ -0,0 +1,866 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810lcdc.h
+ *
+ * JZ4810 LCDC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810LCDC_H__
+#define __JZ4810LCDC_H__
+
+
+#define LCD_BASE 0xB3050000
+#define SLCD_BASE 0xB3050000
+
+
+/*************************************************************************
+ * SLCD (Smart LCD Controller)
+ *************************************************************************/
+
+#define SLCD_CFG (SLCD_BASE + 0xA0) /* SLCD Configure Register */
+#define SLCD_CTRL (SLCD_BASE + 0xA4) /* SLCD Control Register */
+#define SLCD_STATE (SLCD_BASE + 0xA8) /* SLCD Status Register */
+#define SLCD_DATA (SLCD_BASE + 0xAC) /* SLCD Data Register */
+
+#define REG_SLCD_CFG REG32(SLCD_CFG)
+#define REG_SLCD_CTRL REG8(SLCD_CTRL)
+#define REG_SLCD_STATE REG8(SLCD_STATE)
+#define REG_SLCD_DATA REG32(SLCD_DATA)
+
+/* SLCD Configure Register */
+#define SLCD_CFG_DWIDTH_BIT 10
+#define SLCD_CFG_DWIDTH_MASK (0x7 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_18BIT (0 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_16BIT (1 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x3 (2 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x2 (3 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_8BIT_x1 (4 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_24BIT (5 << SLCD_CFG_DWIDTH_BIT)
+ #define SLCD_CFG_DWIDTH_9BIT_x2 (7 << SLCD_CFG_DWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_BIT (8)
+#define SLCD_CFG_CWIDTH_MASK (0x7 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_16BIT (0 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_8BIT (1 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_18BIT (2 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CWIDTH_24BIT (3 << SLCD_CFG_CWIDTH_BIT)
+#define SLCD_CFG_CS_ACTIVE_LOW (0 << 4)
+#define SLCD_CFG_CS_ACTIVE_HIGH (1 << 4)
+#define SLCD_CFG_RS_CMD_LOW (0 << 3)
+#define SLCD_CFG_RS_CMD_HIGH (1 << 3)
+#define SLCD_CFG_CLK_ACTIVE_FALLING (0 << 1)
+#define SLCD_CFG_CLK_ACTIVE_RISING (1 << 1)
+#define SLCD_CFG_TYPE_PARALLEL (0 << 0)
+#define SLCD_CFG_TYPE_SERIAL (1 << 0)
+
+/* SLCD Control Register */
+#define SLCD_CTRL_DMA_MODE (1 << 2)
+#define SLCD_CTRL_DMA_START (1 << 1)
+#define SLCD_CTRL_DMA_EN (1 << 0)
+
+/* SLCD Status Register */
+#define SLCD_STATE_BUSY (1 << 0)
+
+/* SLCD Data Register */
+#define SLCD_DATA_RS_DATA (0 << 31)
+#define SLCD_DATA_RS_COMMAND (1 << 31)
+
+/*************************************************************************
+ * LCD (LCD Controller)
+ *************************************************************************/
+#define LCD_CFG (LCD_BASE + 0x00) /* LCD Configure Register */
+#define LCD_CTRL (LCD_BASE + 0x30) /* LCD Control Register */
+#define LCD_STATE (LCD_BASE + 0x34) /* LCD Status Register */
+
+#define LCD_OSDC (LCD_BASE + 0x100) /* LCD OSD Configure Register */
+#define LCD_OSDCTRL (LCD_BASE + 0x104) /* LCD OSD Control Register */
+#define LCD_OSDS (LCD_BASE + 0x108) /* LCD OSD Status Register */
+#define LCD_BGC (LCD_BASE + 0x10C) /* LCD Background Color Register */
+#define LCD_KEY0 (LCD_BASE + 0x110) /* LCD Foreground Color Key Register 0 */
+#define LCD_KEY1 (LCD_BASE + 0x114) /* LCD Foreground Color Key Register 1 */
+#define LCD_ALPHA (LCD_BASE + 0x118) /* LCD ALPHA Register */
+#define LCD_IPUR (LCD_BASE + 0x11C) /* LCD IPU Restart Register */
+
+#define LCD_VAT (LCD_BASE + 0x0c) /* Virtual Area Setting Register */
+#define LCD_DAH (LCD_BASE + 0x10) /* Display Area Horizontal Start/End Point */
+#define LCD_DAV (LCD_BASE + 0x14) /* Display Area Vertical Start/End Point */
+#define LCD_XYP0 (LCD_BASE + 0x120) /* Foreground 0 XY Position Register */
+#define LCD_XYP1 (LCD_BASE + 0x124) /* Foreground 1 XY Position Register */
+#define LCD_XYP0_PART2 (LCD_BASE + 0x1F0) /* Foreground 0 PART2 XY Position Register */
+#define LCD_SIZE0 (LCD_BASE + 0x128) /* Foreground 0 Size Register */
+#define LCD_SIZE1 (LCD_BASE + 0x12C) /* Foreground 1 Size Register */
+#define LCD_SIZE0_PART2 (LCD_BASE + 0x1F4) /*Foreground 0 PART2 Size Register */
+#define LCD_RGBC (LCD_BASE + 0x90) /* RGB Controll Register */
+
+#define LCD_VSYNC (LCD_BASE + 0x04) /* Vertical Synchronize Register */
+#define LCD_HSYNC (LCD_BASE + 0x08) /* Horizontal Synchronize Register */
+#define LCD_PS (LCD_BASE + 0x18) /* PS Signal Setting */
+#define LCD_CLS (LCD_BASE + 0x1c) /* CLS Signal Setting */
+#define LCD_SPL (LCD_BASE + 0x20) /* SPL Signal Setting */
+#define LCD_REV (LCD_BASE + 0x24) /* REV Signal Setting */
+#define LCD_IID (LCD_BASE + 0x38) /* Interrupt ID Register */
+#define LCD_DA0 (LCD_BASE + 0x40) /* Descriptor Address Register 0 */
+#define LCD_SA0 (LCD_BASE + 0x44) /* Source Address Register 0 */
+#define LCD_FID0 (LCD_BASE + 0x48) /* Frame ID Register 0 */
+#define LCD_CMD0 (LCD_BASE + 0x4c) /* DMA Command Register 0 */
+#define LCD_OFFS0 (LCD_BASE + 0x60) /* DMA Offsize Register 0 */
+#define LCD_PW0 (LCD_BASE + 0x64) /* DMA Page Width Register 0 */
+#define LCD_CNUM0 (LCD_BASE + 0x68) /* DMA Command Counter Register 0 */
+#define LCD_DESSIZE0 (LCD_BASE + 0x6C) /* Foreground Size in Descriptor 0 Register*/
+
+#define LCD_DA0_PART2 (LCD_BASE + 0x1C0) /* Descriptor Address Register PART2 */
+#define LCD_SA0_PART2 (LCD_BASE + 0x1C4) /* Source Address Register PART2 */
+#define LCD_FID0_PART2 (LCD_BASE + 0x1C8) /* Frame ID Register PART2 */
+#define LCD_CMD0_PART2 (LCD_BASE + 0x1CC) /* DMA Command Register PART2 */
+#define LCD_OFFS0_PART2 (LCD_BASE + 0x1E0) /* DMA Offsize Register PART2 */
+#define LCD_PW0_PART2 (LCD_BASE + 0x1E4) /* DMA Command Counter Register PART2 */
+#define LCD_CNUM0_PART2 (LCD_BASE + 0x1E8) /* Foreground Size in Descriptor PART2 Register */
+#define LCD_DESSIZE0_PART2 (LCD_BASE + 0x1EC) /* */
+
+#define LCD_DA1 (LCD_BASE + 0x50) /* Descriptor Address Register 1 */
+#define LCD_SA1 (LCD_BASE + 0x54) /* Source Address Register 1 */
+#define LCD_FID1 (LCD_BASE + 0x58) /* Frame ID Register 1 */
+#define LCD_CMD1 (LCD_BASE + 0x5c) /* DMA Command Register 1 */
+#define LCD_OFFS1 (LCD_BASE + 0x70) /* DMA Offsize Register 1 */
+#define LCD_PW1 (LCD_BASE + 0x74) /* DMA Page Width Register 1 */
+#define LCD_CNUM1 (LCD_BASE + 0x78) /* DMA Command Counter Register 1 */
+#define LCD_DESSIZE1 (LCD_BASE + 0x7C) /* Foreground Size in Descriptor 1 Register*/
+
+#define REG_LCD_CFG REG32(LCD_CFG)
+#define REG_LCD_CTRL REG32(LCD_CTRL)
+#define REG_LCD_STATE REG32(LCD_STATE)
+
+#define REG_LCD_OSDC REG16(LCD_OSDC)
+#define REG_LCD_OSDCTRL REG16(LCD_OSDCTRL)
+#define REG_LCD_OSDS REG16(LCD_OSDS)
+#define REG_LCD_BGC REG32(LCD_BGC)
+#define REG_LCD_KEY0 REG32(LCD_KEY0)
+#define REG_LCD_KEY1 REG32(LCD_KEY1)
+#define REG_LCD_ALPHA REG8(LCD_ALPHA)
+#define REG_LCD_IPUR REG32(LCD_IPUR)
+
+#define REG_LCD_VAT REG32(LCD_VAT)
+#define REG_LCD_DAH REG32(LCD_DAH)
+#define REG_LCD_DAV REG32(LCD_DAV)
+
+#define REG_LCD_XYP0 REG32(LCD_XYP0)
+#define REG_LCD_XYP0_PART2 REG32(LCD_XYP0_PART2)
+#define REG_LCD_XYP1 REG32(LCD_XYP1)
+#define REG_LCD_SIZE0 REG32(LCD_SIZE0)
+#define REG_LCD_SIZE0_PART2 REG32(LCD_SIZE0_PART2)
+#define REG_LCD_SIZE1 REG32(LCD_SIZE1)
+
+#define REG_LCD_RGBC REG16(LCD_RGBC)
+
+#define REG_LCD_VSYNC REG32(LCD_VSYNC)
+#define REG_LCD_HSYNC REG32(LCD_HSYNC)
+#define REG_LCD_PS REG32(LCD_PS)
+#define REG_LCD_CLS REG32(LCD_CLS)
+#define REG_LCD_SPL REG32(LCD_SPL)
+#define REG_LCD_REV REG32(LCD_REV)
+#define REG_LCD_IID REG32(LCD_IID)
+#define REG_LCD_DA0 REG32(LCD_DA0)
+#define REG_LCD_SA0 REG32(LCD_SA0)
+#define REG_LCD_FID0 REG32(LCD_FID0)
+#define REG_LCD_CMD0 REG32(LCD_CMD0)
+
+#define REG_LCD_OFFS0 REG32(LCD_OFFS0)
+#define REG_LCD_PW0 REG32(LCD_PW0)
+#define REG_LCD_CNUM0 REG32(LCD_CNUM0)
+#define REG_LCD_DESSIZE0 REG32(LCD_DESSIZE0)
+
+#define REG_LCD_DA0_PART2 REG32(LCD_DA0_PART2)
+#define REG_LCD_SA0_PART2 REG32(LCD_SA0_PART2)
+#define REG_LCD_FID0_PART2 REG32(LCD_FID0_PART2)
+#define REG_LCD_CMD0_PART2 REG32(LCD_CMD0_PART2)
+#define REG_LCD_OFFS0_PART2 REG32(LCD_OFFS0_PART2)
+#define REG_LCD_PW0_PART2 REG32(LCD_PW0_PART2)
+#define REG_LCD_CNUM0_PART2 REG32(LCD_CNUM0_PART2)
+#define REG_LCD_DESSIZE0_PART2 REG32(LCD_DESSIZE0_PART2)
+
+#define REG_LCD_DA1 REG32(LCD_DA1)
+#define REG_LCD_SA1 REG32(LCD_SA1)
+#define REG_LCD_FID1 REG32(LCD_FID1)
+#define REG_LCD_CMD1 REG32(LCD_CMD1)
+#define REG_LCD_OFFS1 REG32(LCD_OFFS1)
+#define REG_LCD_PW1 REG32(LCD_PW1)
+#define REG_LCD_CNUM1 REG32(LCD_CNUM1)
+#define REG_LCD_DESSIZE1 REG32(LCD_DESSIZE1)
+
+/* LCD Configure Register */
+#define LCD_CFG_LCDPIN_BIT 31 /* LCD pins selection */
+#define LCD_CFG_LCDPIN_MASK (0x1 << LCD_CFG_LCDPIN_BIT)
+ #define LCD_CFG_LCDPIN_LCD (0x0 << LCD_CFG_LCDPIN_BIT)
+ #define LCD_CFG_LCDPIN_SLCD (0x1 << LCD_CFG_LCDPIN_BIT)
+#define LCD_CFG_TVEPEH (1 << 30) /* TVE PAL enable extra halfline signal */
+#define LCD_CFG_FUHOLD (1 << 29) /* hold pixel clock when outFIFO underrun */
+#define LCD_CFG_NEWDES (1 << 28) /* use new descripter. old: 4words, new:8words */
+#define LCD_CFG_PALBP (1 << 27) /* bypass data format and alpha blending */
+#define LCD_CFG_TVEN (1 << 26) /* indicate the terminal is lcd or tv */
+#define LCD_CFG_RECOVER (1 << 25) /* Auto recover when output fifo underrun */
+#define LCD_CFG_DITHER (1 << 24) /* Dither function */
+#define LCD_CFG_PSM (1 << 23) /* PS signal mode */
+#define LCD_CFG_CLSM (1 << 22) /* CLS signal mode */
+#define LCD_CFG_SPLM (1 << 21) /* SPL signal mode */
+#define LCD_CFG_REVM (1 << 20) /* REV signal mode */
+#define LCD_CFG_HSYNM (1 << 19) /* HSYNC signal mode */
+#define LCD_CFG_PCLKM (1 << 18) /* PCLK signal mode */
+#define LCD_CFG_INVDAT (1 << 17) /* Inverse output data */
+#define LCD_CFG_SYNDIR_IN (1 << 16) /* VSYNC&HSYNC direction */
+#define LCD_CFG_PSP (1 << 15) /* PS pin reset state */
+#define LCD_CFG_CLSP (1 << 14) /* CLS pin reset state */
+#define LCD_CFG_SPLP (1 << 13) /* SPL pin reset state */
+#define LCD_CFG_REVP (1 << 12) /* REV pin reset state */
+#define LCD_CFG_HSP (1 << 11) /* HSYNC polarity:0-active high,1-active low */
+#define LCD_CFG_PCP (1 << 10) /* PCLK polarity:0-rising,1-falling */
+#define LCD_CFG_DEP (1 << 9) /* DE polarity:0-active high,1-active low */
+#define LCD_CFG_VSP (1 << 8) /* VSYNC polarity:0-rising,1-falling */
+#define LCD_CFG_MODE_TFT_18BIT (1 << 7) /* 18bit TFT */
+#define LCD_CFG_MODE_TFT_16BIT (0 << 7) /* 16bit TFT */
+#define LCD_CFG_MODE_TFT_24BIT (1 << 6) /* 24bit TFT */
+#define LCD_CFG_PDW_BIT 4 /* STN pins utilization */
+#define LCD_CFG_PDW_MASK (0x3 << LCD_DEV_PDW_BIT)
+#define LCD_CFG_PDW_1 (0 << LCD_CFG_PDW_BIT) /* LCD_D[0] */
+ #define LCD_CFG_PDW_2 (1 << LCD_CFG_PDW_BIT) /* LCD_D[0:1] */
+ #define LCD_CFG_PDW_4 (2 << LCD_CFG_PDW_BIT) /* LCD_D[0:3]/LCD_D[8:11] */
+ #define LCD_CFG_PDW_8 (3 << LCD_CFG_PDW_BIT) /* LCD_D[0:7]/LCD_D[8:15] */
+#define LCD_CFG_MODE_BIT 0 /* Display Device Mode Select */
+#define LCD_CFG_MODE_MASK (0x0f << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_CFG_MODE_BIT) /* 16,18 bit TFT */
+ #define LCD_CFG_MODE_SPECIAL_TFT_1 (1 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SPECIAL_TFT_2 (2 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SPECIAL_TFT_3 (3 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_INTER_CCIR656 (6 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SERIAL_TFT (12 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_LCM (13 << LCD_CFG_MODE_BIT)
+ #define LCD_CFG_MODE_SLCD LCD_CFG_MODE_LCM
+
+/* LCD Control Register */
+#define LCD_CTRL_PINMD (1 << 30) /* This register set Pin distribution in 16-bit parallel mode
+ 0: 16-bit data correspond with LCD_D[15:0]
+ 1: 16-bit data correspond with LCD_D[17:10], LCD_D[8:1] */
+#define LCD_CTRL_BST_BIT 28 /* Burst Length Selection */
+#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
+ #define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT) /* 4-word */
+ #define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT) /* 8-word */
+ #define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT) /* 16-word */
+ #define LCD_CTRL_BST_32 (3 << LCD_CTRL_BST_BIT) /* 32-word */
+#define LCD_CTRL_RGB565 (0 << 27) /* RGB565 mode(foreground 0 in OSD mode) */
+#define LCD_CTRL_RGB555 (1 << 27) /* RGB555 mode(foreground 0 in OSD mode) */
+#define LCD_CTRL_OFUP (1 << 26) /* Output FIFO underrun protection enable */
+#define LCD_CTRL_FRC_BIT 24 /* STN FRC Algorithm Selection */
+#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
+ #define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT) /* 16 grayscale */
+ #define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT) /* 4 grayscale */
+ #define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT) /* 2 grayscale */
+#define LCD_CTRL_PDD_BIT 16 /* Load Palette Delay Counter */
+#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT)
+///#define LCD_CTRL_VGA (1 << 15) /* VGA interface enable */
+//#define LCD_CTRL_DACTE (1 << 14) /* DAC loop back test */
+#define LCD_CTRL_EOFM (1 << 13) /* EOF interrupt mask */
+#define LCD_CTRL_SOFM (1 << 12) /* SOF interrupt mask */
+#define LCD_CTRL_OFUM (1 << 11) /* Output FIFO underrun interrupt mask */
+#define LCD_CTRL_IFUM0 (1 << 10) /* Input FIFO 0 underrun interrupt mask */
+#define LCD_CTRL_IFUM1 (1 << 9) /* Input FIFO 1 underrun interrupt mask */
+#define LCD_CTRL_LDDM (1 << 8) /* LCD disable done interrupt mask */
+#define LCD_CTRL_QDM (1 << 7) /* LCD quick disable done interrupt mask */
+#define LCD_CTRL_BEDN (1 << 6) /* Endian selection */
+#define LCD_CTRL_PEDN (1 << 5) /* Endian in byte:0-msb first, 1-lsb first */
+#define LCD_CTRL_DIS (1 << 4) /* Disable indicate bit */
+#define LCD_CTRL_ENA (1 << 3) /* LCD enable bit */
+#define LCD_CTRL_BPP_BIT 0 /* Bits Per Pixel */
+#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
+ #define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT) /* 1 bpp */
+ #define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT) /* 2 bpp */
+ #define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT) /* 4 bpp */
+ #define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT) /* 8 bpp */
+ #define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT) /* 15/16 bpp */
+ #define LCD_CTRL_BPP_18_24 (5 << LCD_CTRL_BPP_BIT) /* 18/24/32 bpp */
+ #define LCD_CTRL_BPP_CMPS_24 (6 << LCD_CTRL_BPP_BIT) /* 24 compress bpp */
+ #define LCD_CTRL_BPP_30 (7 << LCD_CTRL_BPP_BIT) /* 30 bpp */
+
+/* LCD Status Register */
+#define LCD_STATE_QD (1 << 7) /* Quick Disable Done */
+#define LCD_STATE_EOF (1 << 5) /* EOF Flag */
+#define LCD_STATE_SOF (1 << 4) /* SOF Flag */
+#define LCD_STATE_OFU (1 << 3) /* Output FIFO Underrun */
+#define LCD_STATE_IFU0 (1 << 2) /* Input FIFO 0 Underrun */
+#define LCD_STATE_IFU1 (1 << 1) /* Input FIFO 1 Underrun */
+#define LCD_STATE_LDD (1 << 0) /* LCD Disabled */
+
+/* OSD Configure Register */
+#define LCD_OSDC_SOFM1 (1 << 15) /* Start of frame interrupt mask for foreground 1 */
+#define LCD_OSDC_EOFM1 (1 << 14) /* End of frame interrupt mask for foreground 1 */
+#define LCD_OSDC_SOFM0 (1 << 11) /* Start of frame interrupt mask for foreground 0 */
+#define LCD_OSDC_EOFM0 (1 << 10) /* End of frame interrupt mask for foreground 0 */
+
+////////////////////////////////////////////////////////////
+#define LCD_OSDC_ENDM (1 << 9) /* End of frame interrupt mask for panel. */
+#define LCD_OSDC_F0DIVMD (1 << 8) /* Divide Foreground 0 into 2 parts.
+ * 0: Foreground 0 only has one part. */
+#define LCD_OSDC_F0P1EN (1 << 7) /* 1: Foreground 0 PART1 is enabled.
+ * 0: Foreground 0 PART1 is disabled. */
+#define LCD_OSDC_F0P2MD (1 << 6) /* 1: PART 1&2 same level and same heighth
+ * 0: PART 1&2 have no same line */
+#define LCD_OSDC_F0P2EN (1 << 5) /* 1: Foreground 0 PART2 is enabled.
+ * 0: Foreground 0 PART2 is disabled.*/
+////////////////////////////////////////////////////////////
+
+#define LCD_OSDC_F1EN (1 << 4) /* enable foreground 1 */
+#define LCD_OSDC_F0EN (1 << 3) /* enable foreground 0 */
+#define LCD_OSDC_ALPHAEN (1 << 2) /* enable alpha blending */
+#define LCD_OSDC_ALPHAMD (1 << 1) /* alpha blending mode */
+#define LCD_OSDC_OSDEN (1 << 0) /* OSD mode enable */
+
+/* OSD Controll Register */
+#define LCD_OSDCTRL_IPU (1 << 15) /* input data from IPU */
+#define LCD_OSDCTRL_RGB565 (0 << 4) /* foreground 1, 16bpp, 0-RGB565, 1-RGB555 */
+#define LCD_OSDCTRL_RGB555 (1 << 4) /* foreground 1, 16bpp, 0-RGB565, 1-RGB555 */
+#define LCD_OSDCTRL_CHANGES (1 << 3) /* Change size flag */
+#define LCD_OSDCTRL_OSDBPP_BIT 0 /* Bits Per Pixel of OSD Channel 1 */
+#define LCD_OSDCTRL_OSDBPP_MASK (0x7<<LCD_OSDCTRL_OSDBPP_BIT) /* Bits Per Pixel of OSD Channel 1's MASK */
+ #define LCD_OSDCTRL_OSDBPP_16 (4 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 15,16 bit*/
+ #define LCD_OSDCTRL_OSDBPP_15_16 (4 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 15,16 bit*/
+ #define LCD_OSDCTRL_OSDBPP_18_24 (5 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 18,24 bit*/
+ #define LCD_OSDCTRL_OSDBPP_CMPS_24 (6 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB compress 24 bit*/
+ #define LCD_OSDCTRL_OSDBPP_30 (7 << LCD_OSDCTRL_OSDBPP_BIT) /* RGB 30 bit*/
+
+/* OSD State Register */
+#define LCD_OSDS_SOF1 (1 << 15) /* Start of frame flag for foreground 1 */
+#define LCD_OSDS_EOF1 (1 << 14) /* End of frame flag for foreground 1 */
+#define LCD_OSDS_SOF0 (1 << 11) /* Start of frame flag for foreground 0 */
+#define LCD_OSDS_EOF0 (1 << 10) /* End of frame flag for foreground 0 */
+#define LCD_OSDS_READY (1 << 0) /* Read for accept the change */
+
+/* Background Color Register */
+#define LCD_BGC_RED_OFFSET (1 << 16) /* Red color offset */
+#define LCD_BGC_RED_MASK (0xFF<<LCD_BGC_RED_OFFSET)
+#define LCD_BGC_GREEN_OFFSET (1 << 8) /* Green color offset */
+#define LCD_BGC_GREEN_MASK (0xFF<<LCD_BGC_GREEN_OFFSET)
+#define LCD_BGC_BLUE_OFFSET (1 << 0) /* Blue color offset */
+#define LCD_BGC_BLUE_MASK (0xFF<<LCD_BGC_BLUE_OFFSET)
+
+/* Foreground Color Key Register 0,1(foreground 0, foreground 1) */
+#define LCD_KEY_KEYEN (1 << 31) /* enable color key */
+#define LCD_KEY_KEYMD (1 << 30) /* color key mode */
+#define LCD_KEY_RED_OFFSET 16 /* Red color offset */
+#define LCD_KEY_RED_MASK (0xFF<<LCD_KEY_RED_OFFSET)
+#define LCD_KEY_GREEN_OFFSET 8 /* Green color offset */
+#define LCD_KEY_GREEN_MASK (0xFF<<LCD_KEY_GREEN_OFFSET)
+#define LCD_KEY_BLUE_OFFSET 0 /* Blue color offset */
+#define LCD_KEY_BLUE_MASK (0xFF<<LCD_KEY_BLUE_OFFSET)
+#define LCD_KEY_MASK (LCD_KEY_RED_MASK|LCD_KEY_GREEN_MASK|LCD_KEY_BLUE_MASK)
+
+/* IPU Restart Register */
+#define LCD_IPUR_IPUREN (1 << 31) /* IPU restart function enable*/
+#define LCD_IPUR_IPURMASK (0xFFFFFF) /* IPU restart value mask*/
+
+/* RGB Control Register */
+#define LCD_RGBC_RGBDM (1 << 15) /* enable RGB Dummy data */
+#define LCD_RGBC_DMM (1 << 14) /* RGB Dummy mode */
+#define LCD_RGBC_YCC (1 << 8) /* RGB to YCC */
+#define LCD_RGBC_ODDRGB_BIT 4 /* odd line serial RGB data arrangement */
+#define LCD_RGBC_ODDRGB_MASK (0x7<<LCD_RGBC_ODDRGB_BIT)
+ #define LCD_RGBC_ODD_RGB 0
+ #define LCD_RGBC_ODD_RBG 1
+ #define LCD_RGBC_ODD_GRB 2
+ #define LCD_RGBC_ODD_GBR 3
+ #define LCD_RGBC_ODD_BRG 4
+ #define LCD_RGBC_ODD_BGR 5
+#define LCD_RGBC_EVENRGB_BIT 0 /* even line serial RGB data arrangement */
+#define LCD_RGBC_EVENRGB_MASK (0x7<<LCD_RGBC_EVENRGB_BIT)
+ #define LCD_RGBC_EVEN_RGB 0
+ #define LCD_RGBC_EVEN_RBG 1
+ #define LCD_RGBC_EVEN_GRB 2
+ #define LCD_RGBC_EVEN_GBR 3
+ #define LCD_RGBC_EVEN_BRG 4
+ #define LCD_RGBC_EVEN_BGR 5
+
+/* Vertical Synchronize Register */
+#define LCD_VSYNC_VPS_BIT 16 /* VSYNC pulse start in line clock, fixed to 0 */
+#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT)
+#define LCD_VSYNC_VPE_BIT 0 /* VSYNC pulse end in line clock */
+#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT)
+
+/* Horizontal Synchronize Register */
+#define LCD_HSYNC_HPS_BIT 16 /* HSYNC pulse start position in dot clock */
+#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT)
+#define LCD_HSYNC_HPE_BIT 0 /* HSYNC pulse end position in dot clock */
+#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT)
+
+/* Virtual Area Setting Register */
+#define LCD_VAT_HT_BIT 16 /* Horizontal Total size in dot clock */
+#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT)
+#define LCD_VAT_VT_BIT 0 /* Vertical Total size in dot clock */
+#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT)
+
+/* Display Area Horizontal Start/End Point Register */
+#define LCD_DAH_HDS_BIT 16 /* Horizontal display area start in dot clock */
+#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT)
+#define LCD_DAH_HDE_BIT 0 /* Horizontal display area end in dot clock */
+#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT)
+
+/* Display Area Vertical Start/End Point Register */
+#define LCD_DAV_VDS_BIT 16 /* Vertical display area start in line clock */
+#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT)
+#define LCD_DAV_VDE_BIT 0 /* Vertical display area end in line clock */
+#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT)
+
+/* Foreground XY Position Register */
+#define LCD_XYP_YPOS_BIT 16 /* Y position bit of foreground 0 or 1 */
+#define LCD_XYP_YPOS_MASK (0xffff << LCD_XYP_YPOS_BIT)
+#define LCD_XYP_XPOS_BIT 0 /* X position bit of foreground 0 or 1 */
+#define LCD_XYP_XPOS_MASK (0xffff << LCD_XYP_XPOS_BIT)
+
+/* PS Signal Setting */
+#define LCD_PS_PSS_BIT 16 /* PS signal start position in dot clock */
+#define LCD_PS_PSS_MASK (0xffff << LCD_PS_PSS_BIT)
+#define LCD_PS_PSE_BIT 0 /* PS signal end position in dot clock */
+#define LCD_PS_PSE_MASK (0xffff << LCD_PS_PSE_BIT)
+
+/* CLS Signal Setting */
+#define LCD_CLS_CLSS_BIT 16 /* CLS signal start position in dot clock */
+#define LCD_CLS_CLSS_MASK (0xffff << LCD_CLS_CLSS_BIT)
+#define LCD_CLS_CLSE_BIT 0 /* CLS signal end position in dot clock */
+#define LCD_CLS_CLSE_MASK (0xffff << LCD_CLS_CLSE_BIT)
+
+/* SPL Signal Setting */
+#define LCD_SPL_SPLS_BIT 16 /* SPL signal start position in dot clock */
+#define LCD_SPL_SPLS_MASK (0xffff << LCD_SPL_SPLS_BIT)
+#define LCD_SPL_SPLE_BIT 0 /* SPL signal end position in dot clock */
+#define LCD_SPL_SPLE_MASK (0xffff << LCD_SPL_SPLE_BIT)
+
+/* REV Signal Setting */
+#define LCD_REV_REVS_BIT 16 /* REV signal start position in dot clock */
+#define LCD_REV_REVS_MASK (0xffff << LCD_REV_REVS_BIT)
+
+/* DMA Command Register */
+#define LCD_CMD_SOFINT (1 << 31)
+#define LCD_CMD_EOFINT (1 << 30)
+#define LCD_CMD_CMD (1 << 29) /* indicate command in slcd mode */
+#define LCD_CMD_PAL (1 << 28)
+#define LCD_CMD_LEN_BIT 0
+#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT)
+
+/* DMA Offsize Register 0,1 */
+
+/* DMA Page Width Register 0,1 */
+
+/* DMA Command Counter Register 0,1 */
+
+/* Foreground 0,1 Size Register */
+#define LCD_DESSIZE_HEIGHT_BIT 16 /* height of foreground 1 */
+#define LCD_DESSIZE_HEIGHT_MASK (0xffff << LCD_DESSIZE_HEIGHT_BIT)
+#define LCD_DESSIZE_WIDTH_BIT 0 /* width of foreground 1 */
+#define LCD_DESSIZE_WIDTH_MASK (0xffff << LCD_DESSIZE_WIDTH_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * SLCD (Smart LCD Controller)
+ *************************************************************************/
+#define __slcd_set_data_18bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_18BIT )
+#define __slcd_set_data_16bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_16BIT )
+#define __slcd_set_data_8bit_x3() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x3 )
+#define __slcd_set_data_8bit_x2() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x2 )
+#define __slcd_set_data_8bit_x1() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_8BIT_x1 )
+#define __slcd_set_data_24bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_24BIT )
+#define __slcd_set_data_9bit_x2() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_DWIDTH_MASK) | SLCD_CFG_DWIDTH_9BIT_x2 )
+
+#define __slcd_set_cmd_16bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_16BIT )
+#define __slcd_set_cmd_8bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_8BIT )
+#define __slcd_set_cmd_18bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_18BIT )
+#define __slcd_set_cmd_24bit() \
+ ( REG_SLCD_CFG = (REG_SLCD_CFG & ~SLCD_CFG_CWIDTH_MASK) | SLCD_CFG_CWIDTH_24BIT )
+
+#define __slcd_set_cs_high() ( REG_SLCD_CFG |= SLCD_CFG_CS_ACTIVE_HIGH )
+#define __slcd_set_cs_low() ( REG_SLCD_CFG &= ~SLCD_CFG_CS_ACTIVE_HIGH )
+
+#define __slcd_set_rs_high() ( REG_SLCD_CFG |= SLCD_CFG_RS_CMD_HIGH )
+#define __slcd_set_rs_low() ( REG_SLCD_CFG &= ~SLCD_CFG_RS_CMD_HIGH )
+
+#define __slcd_set_clk_falling() ( REG_SLCD_CFG &= ~SLCD_CFG_CLK_ACTIVE_RISING )
+#define __slcd_set_clk_rising() ( REG_SLCD_CFG |= SLCD_CFG_CLK_ACTIVE_RISING )
+
+#define __slcd_set_parallel_type() ( REG_SLCD_CFG &= ~SLCD_CFG_TYPE_SERIAL )
+#define __slcd_set_serial_type() ( REG_SLCD_CFG |= SLCD_CFG_TYPE_SERIAL )
+
+/* SLCD Control Register */
+#define __slcd_enable_dma() ( REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN )
+#define __slcd_disable_dma() ( REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN )
+
+/* SLCD Status Register */
+#define __slcd_is_busy() ( REG_SLCD_STATE & SLCD_STATE_BUSY )
+
+/* SLCD Data Register */
+#define __slcd_set_cmd_rs() ( REG_SLCD_DATA |= SLCD_DATA_RS_COMMAND)
+#define __slcd_set_data_rs() ( REG_SLCD_DATA &= ~SLCD_DATA_RS_COMMAND)
+
+
+/***************************************************************************
+ * LCD
+ ***************************************************************************/
+
+/***************************************************************************
+ * LCD
+ ***************************************************************************/
+#define __lcd_as_smart_lcd() ( REG_LCD_CFG |= ( LCD_CFG_LCDPIN_SLCD | LCD_CFG_MODE_SLCD))
+#define __lcd_as_general_lcd() ( REG_LCD_CFG &= ~( LCD_CFG_LCDPIN_SLCD | LCD_CFG_MODE_SLCD))
+
+#define __lcd_enable_tvepeh() ( REG_LCD_CFG |= LCD_CFG_TVEPEH )
+#define __lcd_disable_tvepeh() ( REG_LCD_CFG &= ~LCD_CFG_TVEPEH )
+
+#define __lcd_enable_fuhold() ( REG_LCD_CFG |= LCD_CFG_FUHOLD )
+#define __lcd_disable_fuhold() ( REG_LCD_CFG &= ~LCD_CFG_FUHOLD )
+
+#define __lcd_des_8word() ( REG_LCD_CFG |= LCD_CFG_NEWDES )
+#define __lcd_des_4word() ( REG_LCD_CFG &= ~LCD_CFG_NEWDES )
+
+#define __lcd_enable_bypass_pal() ( REG_LCD_CFG |= LCD_CFG_PALBP )
+#define __lcd_disable_bypass_pal() ( REG_LCD_CFG &= ~LCD_CFG_PALBP )
+
+#define __lcd_set_lcdpnl_term() ( REG_LCD_CFG |= LCD_CFG_TVEN )
+#define __lcd_set_tv_term() ( REG_LCD_CFG &= ~LCD_CFG_TVEN )
+
+#define __lcd_enable_auto_recover() ( REG_LCD_CFG |= LCD_CFG_RECOVER )
+#define __lcd_disable_auto_recover() ( REG_LCD_CFG &= ~LCD_CFG_RECOVER )
+
+#define __lcd_enable_dither() ( REG_LCD_CFG |= LCD_CFG_DITHER )
+#define __lcd_disable_dither() ( REG_LCD_CFG &= ~LCD_CFG_DITHER )
+
+#define __lcd_disable_ps_mode() ( REG_LCD_CFG |= LCD_CFG_PSM )
+#define __lcd_enable_ps_mode() ( REG_LCD_CFG &= ~LCD_CFG_PSM )
+
+#define __lcd_disable_cls_mode() ( REG_LCD_CFG |= LCD_CFG_CLSM )
+#define __lcd_enable_cls_mode() ( REG_LCD_CFG &= ~LCD_CFG_CLSM )
+
+#define __lcd_disable_spl_mode() ( REG_LCD_CFG |= LCD_CFG_SPLM )
+#define __lcd_enable_spl_mode() ( REG_LCD_CFG &= ~LCD_CFG_SPLM )
+
+#define __lcd_disable_rev_mode() ( REG_LCD_CFG |= LCD_CFG_REVM )
+#define __lcd_enable_rev_mode() ( REG_LCD_CFG &= ~LCD_CFG_REVM )
+
+#define __lcd_disable_hsync_mode() ( REG_LCD_CFG |= LCD_CFG_HSYNM )
+#define __lcd_enable_hsync_mode() ( REG_LCD_CFG &= ~LCD_CFG_HSYNM )
+
+#define __lcd_disable_pclk_mode() ( REG_LCD_CFG |= LCD_CFG_PCLKM )
+#define __lcd_enable_pclk_mode() ( REG_LCD_CFG &= ~LCD_CFG_PCLKM )
+
+#define __lcd_normal_outdata() ( REG_LCD_CFG &= ~LCD_CFG_INVDAT )
+#define __lcd_inverse_outdata() ( REG_LCD_CFG |= LCD_CFG_INVDAT )
+
+#define __lcd_sync_input() ( REG_LCD_CFG |= LCD_CFG_SYNDIR_IN )
+#define __lcd_sync_output() ( REG_LCD_CFG &= ~LCD_CFG_SYNDIR_IN )
+
+#define __lcd_hsync_active_high() ( REG_LCD_CFG &= ~LCD_CFG_HSP )
+#define __lcd_hsync_active_low() ( REG_LCD_CFG |= LCD_CFG_HSP )
+
+#define __lcd_pclk_rising() ( REG_LCD_CFG &= ~LCD_CFG_PCP )
+#define __lcd_pclk_falling() ( REG_LCD_CFG |= LCD_CFG_PCP )
+
+#define __lcd_de_active_high() ( REG_LCD_CFG &= ~LCD_CFG_DEP )
+#define __lcd_de_active_low() ( REG_LCD_CFG |= LCD_CFG_DEP )
+
+#define __lcd_vsync_rising() ( REG_LCD_CFG &= ~LCD_CFG_VSP )
+#define __lcd_vsync_falling() ( REG_LCD_CFG |= LCD_CFG_VSP )
+
+#define __lcd_set_16_tftpnl() \
+ ( REG_LCD_CFG = (REG_LCD_CFG & ~LCD_CFG_MODE_TFT_MASK) | LCD_CFG_MODE_TFT_16BIT )
+
+#define __lcd_set_18_tftpnl() \
+ ( REG_LCD_CFG = (REG_LCD_CFG & ~LCD_CFG_MODE_TFT_MASK) | LCD_CFG_MODE_TFT_18BIT )
+
+#define __lcd_set_24_tftpnl() ( REG_LCD_CFG |= LCD_CFG_MODE_TFT_24BIT )
+
+/*
+ * n=1,2,4,8 for single mono-STN
+ * n=4,8 for dual mono-STN
+ */
+#define __lcd_set_panel_datawidth(n) \
+do { \
+ REG_LCD_CFG &= ~LCD_CFG_PDW_MASK; \
+ REG_LCD_CFG |= LCD_CFG_PDW_n##; \
+} while (0)
+
+/* m = LCD_CFG_MODE_GENERUIC_TFT_xxx */
+#define __lcd_set_panel_mode(m) \
+do { \
+ REG_LCD_CFG &= ~LCD_CFG_MODE_MASK; \
+ REG_LCD_CFG |= (m); \
+} while(0)
+
+/* n=4,8,16 */
+#define __lcd_set_burst_length(n) \
+do { \
+ REG_LCD_CTRL &= ~LCD_CTRL_BST_MASK; \
+ REG_LCD_CTRL |= LCD_CTRL_BST_n##; \
+} while (0)
+
+#define __lcd_select_rgb565() ( REG_LCD_CTRL &= ~LCD_CTRL_RGB555 )
+#define __lcd_select_rgb555() ( REG_LCD_CTRL |= LCD_CTRL_RGB555 )
+
+#define __lcd_set_ofup() ( REG_LCD_CTRL |= LCD_CTRL_OFUP )
+#define __lcd_clr_ofup() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUP )
+
+/* n=2,4,16 */
+#define __lcd_set_stn_frc(n) \
+do { \
+ REG_LCD_CTRL &= ~LCD_CTRL_FRC_MASK; \
+ REG_LCD_CTRL |= LCD_CTRL_FRC_n##; \
+} while (0)
+
+#define __lcd_enable_eof_intr() ( REG_LCD_CTRL |= LCD_CTRL_EOFM )
+#define __lcd_disable_eof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_EOFM )
+
+#define __lcd_enable_sof_intr() ( REG_LCD_CTRL |= LCD_CTRL_SOFM )
+#define __lcd_disable_sof_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_SOFM )
+
+#define __lcd_enable_ofu_intr() ( REG_LCD_CTRL |= LCD_CTRL_OFUM )
+#define __lcd_disable_ofu_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_OFUM )
+
+#define __lcd_enable_ifu0_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM0 )
+#define __lcd_disable_ifu0_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM0 )
+
+#define __lcd_enable_ifu1_intr() ( REG_LCD_CTRL |= LCD_CTRL_IFUM1 )
+#define __lcd_disable_ifu1_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_IFUM1 )
+
+#define __lcd_enable_ldd_intr() ( REG_LCD_CTRL |= LCD_CTRL_LDDM )
+#define __lcd_disable_ldd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_LDDM )
+
+#define __lcd_enable_qd_intr() ( REG_LCD_CTRL |= LCD_CTRL_QDM )
+#define __lcd_disable_qd_intr() ( REG_LCD_CTRL &= ~LCD_CTRL_QDM )
+
+#define __lcd_reverse_byte_endian() ( REG_LCD_CTRL |= LCD_CTRL_BEDN )
+#define __lcd_normal_byte_endian() ( REG_LCD_CTRL &= ~LCD_CTRL_BEDN )
+
+#define __lcd_pixel_endian_little() ( REG_LCD_CTRL |= LCD_CTRL_PEDN )
+#define __lcd_pixel_endian_big() ( REG_LCD_CTRL &= ~LCD_CTRL_PEDN )
+
+#define __lcd_set_dis() ( REG_LCD_CTRL |= LCD_CTRL_DIS )
+#define __lcd_clr_dis() ( REG_LCD_CTRL &= ~LCD_CTRL_DIS )
+
+#define __lcd_set_ena() ( REG_LCD_CTRL |= LCD_CTRL_ENA )
+#define __lcd_clr_ena() ( REG_LCD_CTRL &= ~LCD_CTRL_ENA )
+
+/* n=1,2,4,8,16 */
+#define __lcd_set_bpp(n) \
+ ( REG_LCD_CTRL = (REG_LCD_CTRL & ~LCD_CTRL_BPP_MASK) | LCD_CTRL_BPP_##n )
+
+/* LCD status register indication */
+
+#define __lcd_quick_disable_done() ( REG_LCD_STATE & LCD_STATE_QD )
+#define __lcd_disable_done() ( REG_LCD_STATE & LCD_STATE_LDD )
+#define __lcd_infifo0_underrun() ( REG_LCD_STATE & LCD_STATE_IFU0 )
+#define __lcd_infifo1_underrun() ( REG_LCD_STATE & LCD_STATE_IFU1 )
+#define __lcd_outfifo_underrun() ( REG_LCD_STATE & LCD_STATE_OFU )
+#define __lcd_start_of_frame() ( REG_LCD_STATE & LCD_STATE_SOF )
+#define __lcd_end_of_frame() ( REG_LCD_STATE & LCD_STATE_EOF )
+
+#define __lcd_clr_outfifounderrun() ( REG_LCD_STATE &= ~LCD_STATE_OFU )
+#define __lcd_clr_sof() ( REG_LCD_STATE &= ~LCD_STATE_SOF )
+#define __lcd_clr_eof() ( REG_LCD_STATE &= ~LCD_STATE_EOF )
+
+/* OSD functions */
+#define __lcd_enable_osd() (REG_LCD_OSDC |= LCD_OSDC_OSDEN)
+#define __lcd_enable_f0() (REG_LCD_OSDC |= LCD_OSDC_F0EN)
+#define __lcd_enable_f1() (REG_LCD_OSDC |= LCD_OSDC_F1EN)
+#define __lcd_enable_alpha() (REG_LCD_OSDC |= LCD_OSDC_ALPHAEN)
+#define __lcd_enable_alphamd() (REG_LCD_OSDC |= LCD_OSDC_ALPHAMD)
+
+#define __lcd_disable_osd() (REG_LCD_OSDC &= ~LCD_OSDC_OSDEN)
+#define __lcd_disable_f0() (REG_LCD_OSDC &= ~LCD_OSDC_F0EN)
+#define __lcd_disable_f1() (REG_LCD_OSDC &= ~LCD_OSDC_F1EN)
+#define __lcd_disable_alpha() (REG_LCD_OSDC &= ~LCD_OSDC_ALPHAEN)
+#define __lcd_disable_alphamd() (REG_LCD_OSDC &= ~LCD_OSDC_ALPHAMD)
+
+/* OSD Controll Register */
+#define __lcd_fg1_use_ipu() (REG_LCD_OSDCTRL |= LCD_OSDCTRL_IPU)
+#define __lcd_fg1_use_dma_chan1() (REG_LCD_OSDCTRL &= ~LCD_OSDCTRL_IPU)
+#define __lcd_fg1_unuse_ipu() __lcd_fg1_use_dma_chan1()
+#define __lcd_osd_rgb555_mode() ( REG_LCD_OSDCTRL |= LCD_OSDCTRL_RGB555 )
+#define __lcd_osd_rgb565_mode() ( REG_LCD_OSDCTRL &= ~LCD_OSDCTRL_RGB555 )
+#define __lcd_osd_change_size() ( REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES )
+#define __lcd_osd_bpp_15_16() \
+ ( REG_LCD_OSDCTRL = (REG_LCD_OSDCTRL & ~LCD_OSDCTRL_OSDBPP_MASK) | LCD_OSDCTRL_OSDBPP_15_16 )
+#define __lcd_osd_bpp_18_24() \
+ ( REG_LCD_OSDCTRL = (REG_LCD_OSDCTRL & ~LCD_OSDCTRL_OSDBPP_MASK) | LCD_OSDCTRL_OSDBPP_18_24 )
+
+/* OSD State Register */
+#define __lcd_start_of_fg1() ( REG_LCD_STATE & LCD_OSDS_SOF1 )
+#define __lcd_end_of_fg1() ( REG_LCD_STATE & LCD_OSDS_EOF1 )
+#define __lcd_start_of_fg0() ( REG_LCD_STATE & LCD_OSDS_SOF0 )
+#define __lcd_end_of_fg0() ( REG_LCD_STATE & LCD_OSDS_EOF0 )
+#define __lcd_change_is_rdy() ( REG_LCD_STATE & LCD_OSDS_READY )
+
+/* Foreground Color Key Register 0,1(foreground 0, foreground 1) */
+#define __lcd_enable_colorkey0() (REG_LCD_KEY0 |= LCD_KEY_KEYEN)
+#define __lcd_enable_colorkey1() (REG_LCD_KEY1 |= LCD_KEY_KEYEN)
+#define __lcd_enable_colorkey0_md() (REG_LCD_KEY0 |= LCD_KEY_KEYMD)
+#define __lcd_enable_colorkey1_md() (REG_LCD_KEY1 |= LCD_KEY_KEYMD)
+#define __lcd_set_colorkey0(key) (REG_LCD_KEY0 = (REG_LCD_KEY0&~0xFFFFFF)|(key))
+#define __lcd_set_colorkey1(key) (REG_LCD_KEY1 = (REG_LCD_KEY1&~0xFFFFFF)|(key))
+
+#define __lcd_disable_colorkey0() (REG_LCD_KEY0 &= ~LCD_KEY_KEYEN)
+#define __lcd_disable_colorkey1() (REG_LCD_KEY1 &= ~LCD_KEY_KEYEN)
+#define __lcd_disable_colorkey0_md() (REG_LCD_KEY0 &= ~LCD_KEY_KEYMD)
+#define __lcd_disable_colorkey1_md() (REG_LCD_KEY1 &= ~LCD_KEY_KEYMD)
+
+/* IPU Restart Register */
+#define __lcd_enable_ipu_restart() (REG_LCD_IPUR |= LCD_IPUR_IPUREN)
+#define __lcd_disable_ipu_restart() (REG_LCD_IPUR &= ~LCD_IPUR_IPUREN)
+#define __lcd_set_ipu_restart_triger(n) (REG_LCD_IPUR = (REG_LCD_IPUR&(~0xFFFFFF))|(n))
+
+/* RGB Control Register */
+#define __lcd_enable_rgb_dummy() (REG_LCD_RGBC |= LCD_RGBC_RGBDM)
+#define __lcd_disable_rgb_dummy() (REG_LCD_RGBC &= ~LCD_RGBC_RGBDM)
+
+#define __lcd_dummy_rgb() (REG_LCD_RGBC |= LCD_RGBC_DMM)
+#define __lcd_rgb_dummy() (REG_LCD_RGBC &= ~LCD_RGBC_DMM)
+
+#define __lcd_rgb2ycc() (REG_LCD_RGBC |= LCD_RGBC_YCC)
+#define __lcd_notrgb2ycc() (REG_LCD_RGBC &= ~LCD_RGBC_YCC)
+
+#define __lcd_odd_mode_rgb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_RGB )
+#define __lcd_odd_mode_rbg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_RBG )
+#define __lcd_odd_mode_grb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_GRB)
+
+#define __lcd_odd_mode_gbr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_GBR)
+#define __lcd_odd_mode_brg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_BRG)
+#define __lcd_odd_mode_bgr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_ODDRGB_MASK) | LCD_RGBC_ODD_BGR)
+
+#define __lcd_even_mode_rgb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_RGB )
+#define __lcd_even_mode_rbg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_RBG )
+#define __lcd_even_mode_grb() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_GRB)
+
+#define __lcd_even_mode_gbr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_GBR)
+#define __lcd_even_mode_brg() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_BRG)
+#define __lcd_even_mode_bgr() \
+ ( REG_LCD_RGBC = (REG_LCD_RGBC & ~LCD_RGBC_EVENRGB_MASK) | LCD_RGBC_EVEN_BGR)
+
+/* Vertical Synchronize Register */
+#define __lcd_vsync_get_vps() \
+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPS_MASK) >> LCD_VSYNC_VPS_BIT )
+
+#define __lcd_vsync_get_vpe() \
+ ( (REG_LCD_VSYNC & LCD_VSYNC_VPE_MASK) >> LCD_VSYNC_VPE_BIT )
+#define __lcd_vsync_set_vpe(n) \
+do { \
+ REG_LCD_VSYNC &= ~LCD_VSYNC_VPE_MASK; \
+ REG_LCD_VSYNC |= (n) << LCD_VSYNC_VPE_BIT; \
+} while (0)
+
+#define __lcd_hsync_get_hps() \
+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPS_MASK) >> LCD_HSYNC_HPS_BIT )
+#define __lcd_hsync_set_hps(n) \
+do { \
+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPS_MASK; \
+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPS_BIT; \
+} while (0)
+
+#define __lcd_hsync_get_hpe() \
+ ( (REG_LCD_HSYNC & LCD_HSYNC_HPE_MASK) >> LCD_VSYNC_HPE_BIT )
+#define __lcd_hsync_set_hpe(n) \
+do { \
+ REG_LCD_HSYNC &= ~LCD_HSYNC_HPE_MASK; \
+ REG_LCD_HSYNC |= (n) << LCD_HSYNC_HPE_BIT; \
+} while (0)
+
+#define __lcd_vat_get_ht() \
+ ( (REG_LCD_VAT & LCD_VAT_HT_MASK) >> LCD_VAT_HT_BIT )
+#define __lcd_vat_set_ht(n) \
+do { \
+ REG_LCD_VAT &= ~LCD_VAT_HT_MASK; \
+ REG_LCD_VAT |= (n) << LCD_VAT_HT_BIT; \
+} while (0)
+
+#define __lcd_vat_get_vt() \
+ ( (REG_LCD_VAT & LCD_VAT_VT_MASK) >> LCD_VAT_VT_BIT )
+#define __lcd_vat_set_vt(n) \
+do { \
+ REG_LCD_VAT &= ~LCD_VAT_VT_MASK; \
+ REG_LCD_VAT |= (n) << LCD_VAT_VT_BIT; \
+} while (0)
+
+#define __lcd_dah_get_hds() \
+ ( (REG_LCD_DAH & LCD_DAH_HDS_MASK) >> LCD_DAH_HDS_BIT )
+#define __lcd_dah_set_hds(n) \
+do { \
+ REG_LCD_DAH &= ~LCD_DAH_HDS_MASK; \
+ REG_LCD_DAH |= (n) << LCD_DAH_HDS_BIT; \
+} while (0)
+
+#define __lcd_dah_get_hde() \
+ ( (REG_LCD_DAH & LCD_DAH_HDE_MASK) >> LCD_DAH_HDE_BIT )
+#define __lcd_dah_set_hde(n) \
+do { \
+ REG_LCD_DAH &= ~LCD_DAH_HDE_MASK; \
+ REG_LCD_DAH |= (n) << LCD_DAH_HDE_BIT; \
+} while (0)
+
+#define __lcd_dav_get_vds() \
+ ( (REG_LCD_DAV & LCD_DAV_VDS_MASK) >> LCD_DAV_VDS_BIT )
+#define __lcd_dav_set_vds(n) \
+do { \
+ REG_LCD_DAV &= ~LCD_DAV_VDS_MASK; \
+ REG_LCD_DAV |= (n) << LCD_DAV_VDS_BIT; \
+} while (0)
+
+#define __lcd_dav_get_vde() \
+ ( (REG_LCD_DAV & LCD_DAV_VDE_MASK) >> LCD_DAV_VDE_BIT )
+#define __lcd_dav_set_vde(n) \
+do { \
+ REG_LCD_DAV &= ~LCD_DAV_VDE_MASK; \
+ REG_LCD_DAV |= (n) << LCD_DAV_VDE_BIT; \
+} while (0)
+
+/* DMA Command Register */
+#define __lcd_cmd0_set_sofint() ( REG_LCD_CMD0 |= LCD_CMD_SOFINT )
+#define __lcd_cmd0_clr_sofint() ( REG_LCD_CMD0 &= ~LCD_CMD_SOFINT )
+#define __lcd_cmd1_set_sofint() ( REG_LCD_CMD1 |= LCD_CMD_SOFINT )
+#define __lcd_cmd1_clr_sofint() ( REG_LCD_CMD1 &= ~LCD_CMD_SOFINT )
+
+#define __lcd_cmd0_set_eofint() ( REG_LCD_CMD0 |= LCD_CMD_EOFINT )
+#define __lcd_cmd0_clr_eofint() ( REG_LCD_CMD0 &= ~LCD_CMD_EOFINT )
+#define __lcd_cmd1_set_eofint() ( REG_LCD_CMD1 |= LCD_CMD_EOFINT )
+#define __lcd_cmd1_clr_eofint() ( REG_LCD_CMD1 &= ~LCD_CMD_EOFINT )
+
+#define __lcd_cmd0_set_pal() ( REG_LCD_CMD0 |= LCD_CMD_PAL )
+#define __lcd_cmd0_clr_pal() ( REG_LCD_CMD0 &= ~LCD_CMD_PAL )
+
+#define __lcd_cmd0_get_len() \
+ ( (REG_LCD_CMD0 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT )
+#define __lcd_cmd1_get_len() \
+ ( (REG_LCD_CMD1 & LCD_CMD_LEN_MASK) >> LCD_CMD_LEN_BIT )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810LCDC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810mc.h b/arch/mips/include/asm/mach-jz4810/jz4810mc.h
new file mode 100644
index 00000000000..1356bfd3882
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810mc.h
@@ -0,0 +1,135 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810mc.h
+ *
+ * JZ4810 MC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810MC_H__
+#define __JZ4810MC_H__
+
+
+#define MC_BASE 0xB3250000
+
+/*************************************************************************
+ * MC (Motion Compensation)
+ *************************************************************************/
+#define MC_CTRL (MC_BASE + 0x00) /* MC Control Register */
+#define MC_STAT (MC_BASE + 0x04) /* MC Status Register */
+#define MC_REF_ADDR (MC_BASE + 0x08) /* MC Reference Block Address Register */
+#define MC_REF2_ADDR (MC_BASE + 0x0C) /* MC 2nd Reference Block Address Register */
+#define MC_CURR_ADDR (MC_BASE + 0x10) /* MC Current Block Address Register */
+#define MC_REF_STRD (MC_BASE + 0x14) /* MC Reference Frame Stride Register */
+#define MC_CURR_STRD (MC_BASE + 0x18) /* MC Current Frame Stride Register */
+#define MC_ITP_INFO (MC_BASE + 0x1C) /* MC Block Interpolation Information Register */
+#define MC_TAP_COEF1 (MC_BASE + 0x20) /* MC TAP Filter Coefficient 1 Register */
+#define MC_TAP_COEF2 (MC_BASE + 0x24) /* MC TAP Filter Coefficient 2 Register */
+
+#define REG_MC_CTRL REG32(MC_CTRL)
+#define REG_MC_STAT REG32(MC_STAT)
+#define REG_MC_REF_ADDR REG32(MC_REF_ADDR)
+#define REG_MC_REF2_ADDR REG32(MC_REF2_ADDR)
+#define REG_MC_CURR_ADDR REG32(MC_CURR_ADDR)
+#define REG_MC_REF_STRD REG32(MC_REF_STRD)
+#define REG_MC_CURR_STRD REG32(MC_CURR_STRD)
+#define REG_MC_ITP_INFO REG32(MC_ITP_INFO)
+#define REG_MC_TAP_COEF1 REG32(MC_TAP_COEF1)
+#define REG_MC_TAP_COEF2 REG32(MC_TAP_COEF2)
+
+/* MC Control Register */
+#define MC_CTRL_CACHECLR (1 << 2) /* MC Cache clear */
+#define MC_CTRL_RESET (1 << 1) /* MC Reset */
+#define MC_CTRL_ENABLE (1 << 0) /* MC enable */
+
+/* MC Status Register */
+#define MC_STAT_OUT_END (1 << 0) /* Output DMA termination flag */
+
+/* MC Reference Frame Stride Register, unit: byte */
+#define MC_REF_STRD_BIT 16
+#define MC_REF_STRD_MASK (0xfff << MC_REF_STRD_BIT)
+#define MC_REF_STRD2_BIT 0
+#define MC_REF_STRD2_MASK (0xfff << MC_REF_STRD2_BIT)
+
+/* MC Current Frame Stride Register, unit: byte */
+#define MC_CURR_STRD_BIT 0
+#define MC_CURR_STRD_MASK (0xfff << MC_CURR_STRD_BIT)
+
+/* MC Block Interpolation Information Register */
+#define MC_ITP_INFO_RND1_BIT 24 /* Rounding data during interpolation */
+#define MC_ITP_INFO_RND1_MASK (0xff << MC_ITP_INFO_RND1_BIT)
+#define MC_ITP_INFO_RND0_BIT 16 /* Rounding data during interpolation */
+#define MC_ITP_INFO_RND0_MASK (0xff << MC_ITP_INFO_RND0_BIT)
+#define MC_ITP_INFO_AVG (1 << 12) /* 0: output interpolated data directly; 1: doing average operation with 2nd source data after interpolating and output */
+#define MC_ITP_INFO_FMT_BIT 8 /* Indicate current interpolation's type */
+#define MC_ITP_INFO_RMT_MASK (0xf << MC_ITP_INFO_RMT_BIT)
+ #define MC_ITP_INFO_FMT_MPEG_HPEL (0x0 << MC_ITP_INFO_RMT_BIT) /* MPEG Half-pixel interpolation */
+ #define MC_ITP_INFO_FMT_MPEG_QPEL (0x1 << MC_ITP_INFO_RMT_BIT) /* MPEG 8-tap Quarter-pixel interpolation */
+ #define MC_ITP_INFO_FMT_H264_QPEL (0x2 << MC_ITP_INFO_RMT_BIT) /* H264 6-tap Quarter-pixel interpolation */
+ #define MC_ITP_INFO_FMT_H264_EPEL (0x3 << MC_ITP_INFO_RMT_BIT) /* H264 2-tap Eight-pixel interpolation */
+ #define MC_ITP_INFO_FMT_H264_WPDT (0x4 << MC_ITP_INFO_RMT_BIT) /* H264 Weighted-prediction */
+ #define MC_ITP_INFO_FMT_WMV2_QPEL (0x5 << MC_ITP_INFO_RMT_BIT) /* WMV2 4-tap Quarter-pixel interpolation */
+ #define MC_ITP_INFO_FMT_VC1_QPEL (0x6 << MC_ITP_INFO_RMT_BIT) /* VC1 4-tap Quarter-pixel interpolation */
+ #define MC_ITP_INFO_FMT_RV8_TPEL (0x7 << MC_ITP_INFO_RMT_BIT) /* RV8 4-tap Third-pixel interpolation */
+ #define MC_ITP_INFO_FMT_RV8_CHROM (0x8 << MC_ITP_INFO_RMT_BIT) /* RV8 2-tap Third-pixel interpolation */
+ #define MC_ITP_INFO_FMT_RV9_QPEL (0x9 << MC_ITP_INFO_RMT_BIT) /* RV9 6-tap Quarter-pixel interpolation */
+ #define MC_ITP_INFO_FMT_RV9_CHROM (0xa << MC_ITP_INFO_RMT_BIT) /* RV9 2-tap Quarter-pixel interpolation */
+#define MC_ITP_INFO_BLK_W_BIT 6 /* Indicate reference block's width, unit: pixel */
+#define MC_ITP_INFO_BLK_W_MASK (0x3 << MC_ITP_INFO_BLK_W_BIT)
+ #define MC_ITP_INFO_BLK_W_2 (0x0 << MC_ITP_INFO_BLK_W_BIT)
+ #define MC_ITP_INFO_BLK_W_4 (0x1 << MC_ITP_INFO_BLK_W_BIT)
+ #define MC_ITP_INFO_BLK_W_8 (0x2 << MC_ITP_INFO_BLK_W_BIT)
+ #define MC_ITP_INFO_BLK_W_16 (0x3 << MC_ITP_INFO_BLK_W_BIT)
+#define MC_ITP_INFO_BLK_H_BIT 4 /* Indicate reference block's height, unit: pixel */
+#define MC_ITP_INFO_BLK_H_MASK (0x3 << MC_ITP_INFO_BLK_H_BIT)
+ #define MC_ITP_INFO_BLK_H_2 (0x0 << MC_ITP_INFO_BLK_H_BIT)
+ #define MC_ITP_INFO_BLK_H_4 (0x1 << MC_ITP_INFO_BLK_H_BIT)
+ #define MC_ITP_INFO_BLK_H_8 (0x2 << MC_ITP_INFO_BLK_H_BIT)
+ #define MC_ITP_INFO_BLK_H_16 (0x3 << MC_ITP_INFO_BLK_H_BIT)
+#define MC_ITP_INFO_ITP_CASE_BIT 0 /* Indicate interpolation final destination pixel position */
+#define MC_ITP_INFO_ITP_CASE_MASK (0xf << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H0V0 (0x0 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H1V0 (0x1 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H2V0 (0x2 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H3V0 (0x3 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H0V1 (0x4 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H1V1 (0x5 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H2V1 (0x6 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H3V1 (0x7 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H0V2 (0x8 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H1V2 (0x9 << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H2V2 (0xa << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H3V2 (0xb << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H0V3 (0xc << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H1V3 (0xd << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H2V3 (0xe << MC_ITP_INFO_ITP_CASE_BIT)
+ #define MC_ITP_INFO_ITP_CASE_H3V3 (0xf << MC_ITP_INFO_ITP_CASE_BIT)
+
+/* MC TAP Filter Coefficient 1 Register */
+#define MC_TAP_COEF1_TAP_COEF4_BIT 24
+#define MC_TAP_COEF1_TAP_COEF4_MASK (0xff << MC_TAP_COEF1_TAP_COEF4_BIT)
+#define MC_TAP_COEF1_TAP_COEF3_BIT 16
+#define MC_TAP_COEF1_TAP_COEF3_MASK (0xff << MC_TAP_COEF1_TAP_COEF3_BIT)
+#define MC_TAP_COEF1_TAP_COEF2_BIT 8
+#define MC_TAP_COEF1_TAP_COEF2_MASK (0xff << MC_TAP_COEF1_TAP_COEF2_BIT)
+#define MC_TAP_COEF1_TAP_COEF1_BIT 0
+#define MC_TAP_COEF1_TAP_COEF1_MASK (0xff << MC_TAP_COEF1_TAP_COEF1_BIT)
+
+/* MC TAP Filter Coefficient 2 Register */
+#define MC_TAP_COEF2_TAP_COEF8_BIT 24
+#define MC_TAP_COEF2_TAP_COEF8_MASK (0xff << MC_TAP_COEF2_TAP_COEF8_BIT)
+#define MC_TAP_COEF2_TAP_COEF7_BIT 16
+#define MC_TAP_COEF2_TAP_COEF7_MASK (0xff << MC_TAP_COEF2_TAP_COEF7_BIT)
+#define MC_TAP_COEF2_TAP_COEF6_BIT 8
+#define MC_TAP_COEF2_TAP_COEF6_MASK (0xff << MC_TAP_COEF2_TAP_COEF6_BIT)
+#define MC_TAP_COEF2_TAP_COEF5_BIT 0
+#define MC_TAP_COEF2_TAP_COEF5_MASK (0xff << MC_TAP_COEF2_TAP_COEF5_BIT)
+
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810MC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810mdma.h b/arch/mips/include/asm/mach-jz4810/jz4810mdma.h
new file mode 100644
index 00000000000..b61ffdb4d50
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810mdma.h
@@ -0,0 +1,209 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810mdma.h
+ *
+ * JZ4810 MDMA register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810MDMA_H__
+#define __JZ4810MDMA_H__
+
+
+#define MDMAC_BASE 0xB3030000 /* Memory Copy DMAC */
+
+/*************************************************************************
+ * MDMAC (MEM Copy DMA Controller)
+ *************************************************************************/
+
+/* m is the DMA controller index (0, 1), n is the DMA channel index (0 - 11) */
+
+#define MDMAC_DSAR(n) (MDMAC_BASE + (0x00 + (n) * 0x20)) /* DMA source address */
+#define MDMAC_DTAR(n) (MDMAC_BASE + (0x04 + (n) * 0x20)) /* DMA target address */
+#define MDMAC_DTCR(n) (MDMAC_BASE + (0x08 + (n) * 0x20)) /* DMA transfer count */
+#define MDMAC_DRSR(n) (MDMAC_BASE + (0x0c + (n) * 0x20)) /* DMA request source */
+#define MDMAC_DCCSR(n) (MDMAC_BASE + (0x10 + (n) * 0x20)) /* DMA control/status */
+#define MDMAC_DCMD(n) (MDMAC_BASE + (0x14 + (n) * 0x20)) /* DMA command */
+#define MDMAC_DDA(n) (MDMAC_BASE + (0x18 + (n) * 0x20)) /* DMA descriptor address */
+#define MDMAC_DSD(n) (MDMAC_BASE + (0xc0 + (n) * 0x04)) /* DMA Stride Address */
+
+#define MDMAC_DMACR (MDMAC_BASE + 0x0300) /* DMA control register */
+#define MDMAC_DMAIPR (MDMAC_BASE + 0x0304) /* DMA interrupt pending */
+#define MDMAC_DMADBR (MDMAC_BASE + 0x0308) /* DMA doorbell */
+#define MDMAC_DMADBSR (MDMAC_BASE + 0x030C) /* DMA doorbell set */
+#define MDMAC_DMACKE (MDMAC_BASE + 0x0310)
+
+#define REG_MDMAC_DSAR(n) REG32(MDMAC_DSAR((n)))
+#define REG_MDMAC_DTAR(n) REG32(MDMAC_DTAR((n)))
+#define REG_MDMAC_DTCR(n) REG32(MDMAC_DTCR((n)))
+#define REG_MDMAC_DRSR(n) REG32(MDMAC_DRSR((n)))
+#define REG_MDMAC_DCCSR(n) REG32(MDMAC_DCCSR((n)))
+#define REG_MDMAC_DCMD(n) REG32(MDMAC_DCMD((n)))
+#define REG_MDMAC_DDA(n) REG32(MDMAC_DDA((n)))
+#define REG_MDMAC_DSD(n) REG32(MDMAC_DSD(n))
+#define REG_MDMAC_DMACR REG32(MDMAC_DMACR)
+#define REG_MDMAC_DMAIPR REG32(MDMAC_DMAIPR)
+#define REG_MDMAC_DMADBR REG32(MDMAC_DMADBR)
+#define REG_MDMAC_DMADBSR REG32(MDMAC_DMADBSR)
+#define REG_MDMAC_DMACKE REG32(MDMAC_DMACKE)
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * Mem Copy DMAC
+ ***************************************************************************/
+
+/* n is the DMA channel index (0 - 11) */
+
+#define __mdmac_enable_module \
+ ( REG_MDMAC_DMACR |= DMAC_MDMACR_DMAE | DMAC_MDMACR_PR_012345 )
+#define __mdmac_disable_module \
+ ( REG_MDMAC_DMACR &= ~DMAC_MDMACR_DMAE )
+
+/* p=0,1,2,3 */
+#define __mdmac_set_priority(p) \
+do { \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_PR_MASK; \
+ REG_MDMAC_DMACR |= ((p) << DMAC_DMACR_PR_BIT); \
+} while (0)
+
+#define __mdmac_test_halt_error ( REG_MDMAC_DMACR & DMAC_MDMACR_HLT )
+#define __mdmac_test_addr_error ( REG_MDMAC_DMACR & DMAC_MDMACR_AR )
+
+#define __mdmac_channel_enable_clk \
+ REG_MDMAC_DMACKE |= 1 << (n);
+
+#define __mdmac_enable_descriptor(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_NDES )
+#define __mdmac_disable_descriptor(n) \
+ ( REG_MDMAC_DCCSR((n)) |= DMAC_DCCSR_NDES )
+
+#define __mdmac_enable_channel(n) \
+do { \
+ REG_MDMAC_DCCSR((n)) |= DMAC_DCCSR_EN; \
+} while (0)
+#define __mdmac_disable_channel(n) \
+do { \
+ REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_EN; \
+} while (0)
+#define __mdmac_channel_enabled(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_EN )
+
+#define __mdmac_channel_enable_irq(n) \
+ ( REG_MDMAC_DCMD((n)) |= DMAC_DCMD_TIE )
+#define __mdmac_channel_disable_irq(n) \
+ ( REG_DMAC_DCMD((n)) &= ~DMAC_DCMD_TIE )
+
+#define __mdmac_channel_transmit_halt_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_HLT )
+#define __mdmac_channel_transmit_end_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_TT )
+#define __mdmac_channel_address_error_detected(n) \
+ ( REG_DMAC_DCCSR((n)) & DMAC_DCCSR_AR )
+#define __mdmac_channel_count_terminated_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_CT )
+#define __mdmac_channel_descriptor_invalid_detected(n) \
+ ( REG_MDMAC_DCCSR((n)) & DMAC_DCCSR_INV )
+
+#define __mdmac_channel_clear_transmit_halt(n) \
+ do { \
+ /* clear both channel halt error and globle halt error */ \
+ REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_HLT; \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_HLT; \
+ } while (0)
+#define __mdmac_channel_clear_transmit_end(n) \
+ ( REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_TT )
+#define __mdmac_channel_clear_address_error(n) \
+ do { \
+ REG_MDMAC_DDA(n) = 0; /* clear descriptor address register */ \
+ REG_MDMAC_DSAR(n) = 0; /* clear source address register */ \
+ REG_MDMAC_DTAR(n) = 0; /* clear target address register */ \
+ /* clear both channel addr error and globle address error */ \
+ REG_MDMAC_DCCSR(n) &= ~DMAC_DCCSR_AR; \
+ REG_MDMAC_DMACR &= ~DMAC_DMACR_AR; \
+ } while (0)
+#define __mdmac_channel_clear_count_terminated(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_CT )
+#define __mdmac_channel_clear_descriptor_invalid(n) \
+ ( REG_MDMAC_DCCSR((n)) &= ~DMAC_DCCSR_INV )
+
+#define __mdmac_channel_set_transfer_unit_32bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_32BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_16bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_16BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_8bit(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_8BIT; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_16byte(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_16BYTE; \
+} while (0)
+
+#define __mdmac_channel_set_transfer_unit_32byte(n) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DS_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DS_32BYTE; \
+} while (0)
+
+/* w=8,16,32 */
+#define __mdmac_channel_set_dest_port_width(n,w) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DWDH_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DWDH_##w; \
+} while (0)
+
+/* w=8,16,32 */
+#define __mdmac_channel_set_src_port_width(n,w) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_SWDH_MASK; \
+ REG_MDMAC_DCMD((n)) |= DMAC_DCMD_SWDH_##w; \
+} while (0)
+
+/* v=0-15 */
+#define __mdmac_channel_set_rdil(n,v) \
+do { \
+ REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_RDIL_MASK; \
+ REG_MDMAC_DCMD((n) |= ((v) << DMAC_DCMD_RDIL_BIT); \
+} while (0)
+
+#define __mdmac_channel_dest_addr_fixed(n) \
+ (REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_DAI)
+#define __mdmac_channel_dest_addr_increment(n) \
+ (REG_MDMAC_DCMD((n)) |= DMAC_DCMD_DAI)
+
+#define __mdmac_channel_src_addr_fixed(n) \
+ (REG_MDMAC_DCMD((n)) &= ~DMAC_DCMD_SAI)
+#define __mdmac_channel_src_addr_increment(n) \
+ (REG_MDMAC_DCMD((n)) |= DMAC_DCMD_SAI)
+
+#define __mdmac_channel_set_doorbell(n) \
+ (REG_MDMAC_DMADBSR = (1 << (n)))
+
+#define __mdmac_channel_irq_detected(n) (REG_MDMAC_DMAIPR & (1 << (n)))
+#define __mdmac_channel_ack_irq(n) (REG_MDMAC_DMAIPR &= ~(1 <<(n)))
+
+static __inline__ int __mdmac_get_irq(void)
+{
+ int i;
+ for (i = 0; i < MAX_MDMA_NUM; i++)
+ if (__mdmac_channel_irq_detected(i))
+ return i;
+ return -1;
+}
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810MDMA_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810me.h b/arch/mips/include/asm/mach-jz4810/jz4810me.h
new file mode 100644
index 00000000000..5fb3f237435
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810me.h
@@ -0,0 +1,69 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810ME.h
+ *
+ * JZ4810 ME register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810ME_H__
+#define __JZ4810ME_H__
+
+
+#define ME_BASE 0xB3260000
+
+/*************************************************************************
+ * ME (Motion Estimation)
+ *************************************************************************/
+#define ME_CTRL (ME_BASE + 0x00) /* ME Control Register */
+#define ME_REF_ADDR (ME_BASE + 0x04) /* ME Reference Block Address Register */
+#define ME_CURR_ADDR (ME_BASE + 0x08) /* ME Current Block Address Register */
+#define ME_DIFF_ADDR (ME_BASE + 0x0C) /* ME Difference Address Register */
+#define ME_REF_STRD (ME_BASE + 0x10) /* ME Reference Frame Stride Register */
+#define ME_CURR_STRD (ME_BASE + 0x14) /* ME Current Frame Stride Register */
+#define ME_DIFF_STRD (ME_BASE + 0x18) /* ME Difference Frame Stride Register */
+#define ME_SETTINGS (ME_BASE + 0x1C) /* ME Settings Register */
+#define ME_MVD (ME_BASE + 0x20) /* ME Motion Vector Difference Register */
+#define ME_FLAG (ME_BASE + 0x24) /* ME Flag Register */
+
+#define REG_ME_CTRL REG32(ME_CTRL)
+#define REG_ME_REF_ADDR REG32(ME_REF_ADDR)
+#define REG_ME_CURR_ADDR REG32(ME_CURR_ADDR)
+#define REG_ME_DIFF_ADDR REG32(ME_DIFF_ADDR)
+#define REG_ME_REF_STRD REG32(ME_REF_STRD)
+#define REG_ME_CURR_STRD REG32(ME_CURR_STRD)
+#define REG_ME_DIFF_STRD REG32(ME_DIFF_STRD)
+#define REG_ME_SETTINGS REG32(ME_SETTINGS)
+#define REG_ME_MVD REG32(ME_MVD)
+#define REG_ME_FLAG REG32(ME_FLAG)
+
+
+/* ME Control Register */
+#define ME_CTRL_FLUSH (1 << 2) /* ME cache clear */
+#define ME_CTRL_RESET (1 << 1) /* ME reset */
+#define ME_CTRL_ENABLE (1 << 0) /* ME enable */
+
+/* ME Settings Register */
+#define ME_SETTINGS_SAD_GATE_BIT 16 /* The max SAD value which can be accepted */
+#define ME_SETTINGS_SAD_GATE_MASK (0xffff << ME_SETTINGS_SAD_GATE_BIT)
+#define ME_SETTINGS_STEP_NUM_BIT 0 /* The max step number the search process can not exceed */
+#define ME_SETTINGS_STEP_NUM_MASK (0x3f << ME_SETTINGS_STEP_NUM_BIT)
+
+/* ME Motion Vector Difference Register */
+#define ME_MVD_MVDY_BIT 16 /* The MVD value of coordinate-Y */
+#define ME_MVD_MVDY_MASK (0xffff << ME_MVD_MVDY_BIT)
+#define ME_MVD_MVDX_BIT 0 /* The MVD value of coordinate-X */
+#define ME_MVD_MVDX_MASK (0xffff << ME_MVD_MVDX_BIT)
+
+/* ME Flag Register */
+#define ME_FLAG_INTRA (1 << 1) /* Indicate the current MB will be predicted in intra mode */
+#define ME_FLAG_COMPLETED (1 << 0) /* The ME of the current part of the MB is completed */
+
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810ME_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810misc.h b/arch/mips/include/asm/mach-jz4810/jz4810misc.h
new file mode 100644
index 00000000000..e6176f01ff3
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810misc.h
@@ -0,0 +1,28 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810misc.h
+ *
+ * JZ4810 misc definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810MISC_H__
+#define __JZ4810MISC_H__
+
+
+#if defined(__ASSEMBLY__) || defined(__LANGUAGE_ASSEMBLY)
+ #ifndef __MIPS_ASSEMBLER
+ #define __MIPS_ASSEMBLER
+ #endif
+ #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
+
+
+#endif /* __JZ4810MISC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810msc.h b/arch/mips/include/asm/mach-jz4810/jz4810msc.h
new file mode 100644
index 00000000000..564a8efd644
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810msc.h
@@ -0,0 +1,325 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810msc.h
+ *
+ * JZ4810 MSC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810MSC_H__
+#define __JZ4810MSC_H__
+
+
+#define MSC0_BASE 0xB0021000
+#define MSC1_BASE 0xB0022000
+#define MSC2_BASE 0xB0023000
+
+
+/*************************************************************************
+ * MSC
+ ************************************************************************/
+/* n = 0, 1 (MSC0, MSC1) */
+#define MSC_STRPCL(n) (MSC0_BASE + (n)*0x1000 + 0x000)
+#define MSC_STAT(n) (MSC0_BASE + (n)*0x1000 + 0x004)
+#define MSC_CLKRT(n) (MSC0_BASE + (n)*0x1000 + 0x008)
+#define MSC_CMDAT(n) (MSC0_BASE + (n)*0x1000 + 0x00C)
+#define MSC_RESTO(n) (MSC0_BASE + (n)*0x1000 + 0x010)
+#define MSC_RDTO(n) (MSC0_BASE + (n)*0x1000 + 0x014)
+#define MSC_BLKLEN(n) (MSC0_BASE + (n)*0x1000 + 0x018)
+#define MSC_NOB(n) (MSC0_BASE + (n)*0x1000 + 0x01C)
+#define MSC_SNOB(n) (MSC0_BASE + (n)*0x1000 + 0x020)
+#define MSC_IMASK(n) (MSC0_BASE + (n)*0x1000 + 0x024)
+#define MSC_IREG(n) (MSC0_BASE + (n)*0x1000 + 0x028)
+#define MSC_CMD(n) (MSC0_BASE + (n)*0x1000 + 0x02C)
+#define MSC_ARG(n) (MSC0_BASE + (n)*0x1000 + 0x030)
+#define MSC_RES(n) (MSC0_BASE + (n)*0x1000 + 0x034)
+#define MSC_RXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x038)
+#define MSC_TXFIFO(n) (MSC0_BASE + (n)*0x1000 + 0x03C)
+#define MSC_LPM(n) (MSC0_BASE + (n)*0x1000 + 0x040)
+
+#define REG_MSC_STRPCL(n) REG16(MSC_STRPCL(n))
+#define REG_MSC_STAT(n) REG32(MSC_STAT(n))
+#define REG_MSC_CLKRT(n) REG16(MSC_CLKRT(n))
+#define REG_MSC_CMDAT(n) REG32(MSC_CMDAT(n))
+#define REG_MSC_RESTO(n) REG16(MSC_RESTO(n))
+#define REG_MSC_RDTO(n) REG16(MSC_RDTO(n))
+#define REG_MSC_BLKLEN(n) REG16(MSC_BLKLEN(n))
+#define REG_MSC_NOB(n) REG16(MSC_NOB(n))
+#define REG_MSC_SNOB(n) REG16(MSC_SNOB(n))
+#define REG_MSC_IMASK(n) REG32(MSC_IMASK(n))
+#define REG_MSC_IREG(n) REG16(MSC_IREG(n))
+#define REG_MSC_CMD(n) REG8(MSC_CMD(n))
+#define REG_MSC_ARG(n) REG32(MSC_ARG(n))
+#define REG_MSC_RES(n) REG16(MSC_RES(n))
+#define REG_MSC_RXFIFO(n) REG32(MSC_RXFIFO(n))
+#define REG_MSC_TXFIFO(n) REG32(MSC_TXFIFO(n))
+#define REG_MSC_LPM(n) REG32(MSC_LPM(n))
+
+/* MSC Clock and Control Register (MSC_STRPCL) */
+#define MSC_STRPCL_SEND_CCSD (1 << 15) /*send command completion signal disable to ceata */
+#define MSC_STRPCL_SEND_AS_CCSD (1 << 14) /*send internally generated stop after sending ccsd */
+#define MSC_STRPCL_EXIT_MULTIPLE (1 << 7)
+#define MSC_STRPCL_EXIT_TRANSFER (1 << 6)
+#define MSC_STRPCL_START_READWAIT (1 << 5)
+#define MSC_STRPCL_STOP_READWAIT (1 << 4)
+#define MSC_STRPCL_RESET (1 << 3)
+#define MSC_STRPCL_START_OP (1 << 2)
+#define MSC_STRPCL_CLOCK_CONTROL_BIT 0
+#define MSC_STRPCL_CLOCK_CONTROL_MASK (0x3 << MSC_STRPCL_CLOCK_CONTROL_BIT)
+ #define MSC_STRPCL_CLOCK_CONTROL_STOP (0x1 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Stop MMC/SD clock */
+ #define MSC_STRPCL_CLOCK_CONTROL_START (0x2 << MSC_STRPCL_CLOCK_CONTROL_BIT) /* Start MMC/SD clock */
+
+/* MSC Status Register (MSC_STAT) */
+#define MSC_STAT_AUTO_CMD_DONE (1 << 31) /*12 is internally generated by controller has finished */
+#define MSC_STAT_IS_RESETTING (1 << 15)
+#define MSC_STAT_SDIO_INT_ACTIVE (1 << 14)
+#define MSC_STAT_PRG_DONE (1 << 13)
+#define MSC_STAT_DATA_TRAN_DONE (1 << 12)
+#define MSC_STAT_END_CMD_RES (1 << 11)
+#define MSC_STAT_DATA_FIFO_AFULL (1 << 10)
+#define MSC_STAT_IS_READWAIT (1 << 9)
+#define MSC_STAT_CLK_EN (1 << 8)
+#define MSC_STAT_DATA_FIFO_FULL (1 << 7)
+#define MSC_STAT_DATA_FIFO_EMPTY (1 << 6)
+#define MSC_STAT_CRC_RES_ERR (1 << 5)
+#define MSC_STAT_CRC_READ_ERROR (1 << 4)
+#define MSC_STAT_CRC_WRITE_ERROR_BIT 2
+#define MSC_STAT_CRC_WRITE_ERROR_MASK (0x3 << MSC_STAT_CRC_WRITE_ERROR_BIT)
+ #define MSC_STAT_CRC_WRITE_ERROR_NO (0 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No error on transmission of data */
+ #define MSC_STAT_CRC_WRITE_ERROR (1 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* Card observed erroneous transmission of data */
+ #define MSC_STAT_CRC_WRITE_ERROR_NOSTS (2 << MSC_STAT_CRC_WRITE_ERROR_BIT) /* No CRC status is sent back */
+#define MSC_STAT_TIME_OUT_RES (1 << 1)
+#define MSC_STAT_TIME_OUT_READ (1 << 0)
+
+/* MSC Bus Clock Control Register (MSC_CLKRT) */
+#define MSC_CLKRT_CLK_RATE_BIT 0
+#define MSC_CLKRT_CLK_RATE_MASK (0x7 << MSC_CLKRT_CLK_RATE_BIT)
+ #define MSC_CLKRT_CLK_RATE_DIV_1 (0x0 << MSC_CLKRT_CLK_RATE_BIT) /* CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_2 (0x1 << MSC_CLKRT_CLK_RATE_BIT) /* 1/2 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_4 (0x2 << MSC_CLKRT_CLK_RATE_BIT) /* 1/4 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_8 (0x3 << MSC_CLKRT_CLK_RATE_BIT) /* 1/8 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_16 (0x4 << MSC_CLKRT_CLK_RATE_BIT) /* 1/16 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_32 (0x5 << MSC_CLKRT_CLK_RATE_BIT) /* 1/32 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_64 (0x6 << MSC_CLKRT_CLK_RATE_BIT) /* 1/64 of CLK_SRC */
+ #define MSC_CLKRT_CLK_RATE_DIV_128 (0x7 << MSC_CLKRT_CLK_RATE_BIT) /* 1/128 of CLK_SRC */
+
+/* MSC Command Sequence Control Register (MSC_CMDAT) */
+#define MSC_CMDAT_CCS_EXPECTED (1 << 31) /* interrupts are enabled in ce-ata */
+#define MSC_CMDAT_READ_CEATA (1 << 30)
+#define MSC_CMDAT_SDIO_PRDT (1 << 17) /* exact 2 cycle */
+#define MSC_CMDAT_SEND_AS_STOP (1 << 16)
+#define MSC_CMDAT_RTRG_BIT 14
+ #define MSC_CMDAT_RTRG_EQUALT_8 (0x0 << MSC_CMDAT_RTRG_BIT)
+ #define MSC_CMDAT_RTRG_EQUALT_16 (0x1 << MSC_CMDAT_RTRG_BIT) /* reset value */
+ #define MSC_CMDAT_RTRG_EQUALT_24 (0x2 << MSC_CMDAT_RTRG_BIT)
+
+#define MSC_CMDAT_TTRG_BIT 12
+ #define MSC_CMDAT_TTRG_LESS_8 (0x0 << MSC_CMDAT_TTRG_BIT)
+ #define MSC_CMDAT_TTRG_LESS_16 (0x1 << MSC_CMDAT_TTRG_BIT) /*reset value */
+ #define MSC_CMDAT_TTRG_LESS_24 (0x2 << MSC_CMDAT_TTRG_BIT)
+#define MSC_CMDAT_STOP_ABORT (1 << 11)
+#define MSC_CMDAT_BUS_WIDTH_BIT 9
+#define MSC_CMDAT_BUS_WIDTH_MASK (0x3 << MSC_CMDAT_BUS_WIDTH_BIT)
+ #define MSC_CMDAT_BUS_WIDTH_1BIT (0x0 << MSC_CMDAT_BUS_WIDTH_BIT) /* 1-bit data bus */
+ #define MSC_CMDAT_BUS_WIDTH_4BIT (0x2 << MSC_CMDAT_BUS_WIDTH_BIT) /* 4-bit data bus */
+ #define MSC_CMDAT_BUS_WIDTH_8BIT (0x3 << MSC_CMDAT_BUS_WIDTH_BIT) /* 8-bit data bus */
+#define MSC_CMDAT_DMA_EN (1 << 8)
+#define MSC_CMDAT_INIT (1 << 7)
+#define MSC_CMDAT_BUSY (1 << 6)
+#define MSC_CMDAT_STREAM_BLOCK (1 << 5)
+#define MSC_CMDAT_WRITE (1 << 4)
+#define MSC_CMDAT_READ (0 << 4)
+#define MSC_CMDAT_DATA_EN (1 << 3)
+#define MSC_CMDAT_RESPONSE_BIT 0
+#define MSC_CMDAT_RESPONSE_MASK (0x7 << MSC_CMDAT_RESPONSE_BIT)
+ #define MSC_CMDAT_RESPONSE_NONE (0x0 << MSC_CMDAT_RESPONSE_BIT) /* No response */
+ #define MSC_CMDAT_RESPONSE_R1 (0x1 << MSC_CMDAT_RESPONSE_BIT) /* Format R1 and R1b */
+ #define MSC_CMDAT_RESPONSE_R2 (0x2 << MSC_CMDAT_RESPONSE_BIT) /* Format R2 */
+ #define MSC_CMDAT_RESPONSE_R3 (0x3 << MSC_CMDAT_RESPONSE_BIT) /* Format R3 */
+ #define MSC_CMDAT_RESPONSE_R4 (0x4 << MSC_CMDAT_RESPONSE_BIT) /* Format R4 */
+ #define MSC_CMDAT_RESPONSE_R5 (0x5 << MSC_CMDAT_RESPONSE_BIT) /* Format R5 */
+ #define MSC_CMDAT_RESPONSE_R6 (0x6 << MSC_CMDAT_RESPONSE_BIT) /* Format R6 */
+
+#define CMDAT_DMA_EN (1 << 8)
+#define CMDAT_INIT (1 << 7)
+#define CMDAT_BUSY (1 << 6)
+#define CMDAT_STREAM (1 << 5)
+#define CMDAT_WRITE (1 << 4)
+#define CMDAT_DATA_EN (1 << 3)
+
+/* MSC Interrupts Mask Register (MSC_IMASK) */
+#define MSC_IMASK_AUTO_CMD_DONE (1 << 8)
+#define MSC_IMASK_SDIO (1 << 7)
+#define MSC_IMASK_TXFIFO_WR_REQ (1 << 6)
+#define MSC_IMASK_RXFIFO_RD_REQ (1 << 5)
+#define MSC_IMASK_END_CMD_RES (1 << 2)
+#define MSC_IMASK_PRG_DONE (1 << 1)
+#define MSC_IMASK_DATA_TRAN_DONE (1 << 0)
+
+/* MSC Interrupts Status Register (MSC_IREG) */
+#define MSC_IREG_AUTO_CMD_DONE (1 << 8)
+#define MSC_IREG_SDIO (1 << 7)
+#define MSC_IREG_TXFIFO_WR_REQ (1 << 6)
+#define MSC_IREG_RXFIFO_RD_REQ (1 << 5)
+#define MSC_IREG_END_CMD_RES (1 << 2)
+#define MSC_IREG_PRG_DONE (1 << 1)
+#define MSC_IREG_DATA_TRAN_DONE (1 << 0)
+
+/* MSC Low Power Mode Register (MSC_LPM) */
+#define MSC_SET_LPM (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * MSC
+ ***************************************************************************/
+/* n = 0, 1 (MSC0, MSC1) */
+
+#define __msc_start_op(n) \
+ ( REG_MSC_STRPCL(n) = MSC_STRPCL_START_OP | MSC_STRPCL_CLOCK_CONTROL_START )
+
+#define __msc_set_resto(n, to) ( REG_MSC_RESTO(n) = to )
+#define __msc_set_rdto(n, to) ( REG_MSC_RDTO(n) = to )
+#define __msc_set_cmd(n, cmd) ( REG_MSC_CMD(n) = cmd )
+#define __msc_set_arg(n, arg) ( REG_MSC_ARG(n) = arg )
+#define __msc_set_nob(n, nob) ( REG_MSC_NOB(n) = nob )
+#define __msc_get_nob(n) ( REG_MSC_NOB(n) )
+#define __msc_set_blklen(n, len) ( REG_MSC_BLKLEN(n) = len )
+#define __msc_set_cmdat(n, cmdat) ( REG_MSC_CMDAT(n) = cmdat )
+#define __msc_set_cmdat_ioabort(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_IO_ABORT )
+#define __msc_clear_cmdat_ioabort(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_IO_ABORT )
+
+#define __msc_set_cmdat_bus_width1(n) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_BUS_WIDTH_MASK; \
+ REG_MSC_CMDAT(n) |= MSC_CMDAT_BUS_WIDTH_1BIT; \
+} while(0)
+
+#define __msc_set_cmdat_bus_width4(n) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_BUS_WIDTH_MASK; \
+ REG_MSC_CMDAT(n) |= MSC_CMDAT_BUS_WIDTH_4BIT; \
+} while(0)
+
+#define __msc_set_cmdat_dma_en(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_DMA_EN )
+#define __msc_set_cmdat_init(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_INIT )
+#define __msc_set_cmdat_busy(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_BUSY )
+#define __msc_set_cmdat_stream(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_STREAM_BLOCK )
+#define __msc_set_cmdat_block(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_STREAM_BLOCK )
+#define __msc_set_cmdat_read(n) ( REG_MSC_CMDAT(n) &= ~MSC_CMDAT_WRITE_READ )
+#define __msc_set_cmdat_write(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_WRITE_READ )
+#define __msc_set_cmdat_data_en(n) ( REG_MSC_CMDAT(n) |= MSC_CMDAT_DATA_EN )
+
+/* r is MSC_CMDAT_RESPONSE_FORMAT_Rx or MSC_CMDAT_RESPONSE_FORMAT_NONE */
+#define __msc_set_cmdat_res_format(n, r) \
+do { \
+ REG_MSC_CMDAT(n) &= ~MSC_CMDAT_RESPONSE_FORMAT_MASK; \
+ REG_MSC_CMDAT(n) |= (r); \
+} while(0)
+
+#define __msc_clear_cmdat(n) \
+ REG_MSC_CMDAT(n) &= ~( MSC_CMDAT_IO_ABORT | MSC_CMDAT_DMA_EN | MSC_CMDAT_INIT| \
+ MSC_CMDAT_BUSY | MSC_CMDAT_STREAM_BLOCK | MSC_CMDAT_WRITE_READ | \
+ MSC_CMDAT_DATA_EN | MSC_CMDAT_RESPONSE_FORMAT_MASK )
+
+#define __msc_get_imask(n) ( REG_MSC_IMASK(n) )
+#define __msc_mask_all_intrs(n) ( REG_MSC_IMASK(n) = 0xff )
+#define __msc_unmask_all_intrs(n) ( REG_MSC_IMASK(n) = 0x00 )
+#define __msc_mask_rd(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_RXFIFO_RD_REQ )
+#define __msc_unmask_rd(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_RXFIFO_RD_REQ )
+#define __msc_mask_wr(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_TXFIFO_WR_REQ )
+#define __msc_unmask_wr(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_TXFIFO_WR_REQ )
+#define __msc_mask_endcmdres(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_END_CMD_RES )
+#define __msc_unmask_endcmdres(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_END_CMD_RES )
+#define __msc_mask_datatrandone(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_DATA_TRAN_DONE )
+#define __msc_unmask_datatrandone(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_DATA_TRAN_DONE )
+#define __msc_mask_prgdone(n) ( REG_MSC_IMASK(n) |= MSC_IMASK_PRG_DONE )
+#define __msc_unmask_prgdone(n) ( REG_MSC_IMASK(n) &= ~MSC_IMASK_PRG_DONE )
+
+/* m=0,1,2,3,4,5,6,7 */
+#define __msc_set_clkrt(n, m) \
+do { \
+ REG_MSC_CLKRT(n) = m; \
+} while(0)
+
+#define __msc_get_ireg(n) ( REG_MSC_IREG(n) )
+#define __msc_ireg_rd(n) ( REG_MSC_IREG(n) & MSC_IREG_RXFIFO_RD_REQ )
+#define __msc_ireg_wr(n) ( REG_MSC_IREG(n) & MSC_IREG_TXFIFO_WR_REQ )
+#define __msc_ireg_end_cmd_res(n) ( REG_MSC_IREG(n) & MSC_IREG_END_CMD_RES )
+#define __msc_ireg_data_tran_done(n) ( REG_MSC_IREG(n) & MSC_IREG_DATA_TRAN_DONE )
+#define __msc_ireg_prg_done(n) ( REG_MSC_IREG(n) & MSC_IREG_PRG_DONE )
+#define __msc_ireg_clear_end_cmd_res(n) ( REG_MSC_IREG(n) = MSC_IREG_END_CMD_RES )
+#define __msc_ireg_clear_data_tran_done(n) ( REG_MSC_IREG(n) = MSC_IREG_DATA_TRAN_DONE )
+#define __msc_ireg_clear_prg_done(n) ( REG_MSC_IREG(n) = MSC_IREG_PRG_DONE )
+
+#define __msc_get_stat(n) ( REG_MSC_STAT(n) )
+#define __msc_stat_not_end_cmd_res(n) ( (REG_MSC_STAT(n) & MSC_STAT_END_CMD_RES) == 0)
+#define __msc_stat_crc_err(n) \
+ ( REG_MSC_STAT(n) & (MSC_STAT_CRC_RES_ERR | MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR_YES) )
+#define __msc_stat_res_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_RES_ERR )
+#define __msc_stat_rd_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_READ_ERROR )
+#define __msc_stat_wr_crc_err(n) ( REG_MSC_STAT(n) & MSC_STAT_CRC_WRITE_ERROR_YES )
+#define __msc_stat_resto_err(n) ( REG_MSC_STAT(n) & MSC_STAT_TIME_OUT_RES )
+#define __msc_stat_rdto_err(n) ( REG_MSC_STAT(n) & MSC_STAT_TIME_OUT_READ )
+
+#define __msc_rd_resfifo(n) ( REG_MSC_RES(n) )
+#define __msc_rd_rxfifo(n) ( REG_MSC_RXFIFO(n) )
+#define __msc_wr_txfifo(n, v) ( REG_MSC_TXFIFO(n) = v )
+
+#define __msc_reset(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_RESET; \
+ while (REG_MSC_STAT(n) & MSC_STAT_IS_RESETTING); \
+} while (0)
+
+#define __msc_start_clk(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_CLOCK_CONTROL_START; \
+} while (0)
+
+#define __msc_stop_clk(n) \
+do { \
+ REG_MSC_STRPCL(n) = MSC_STRPCL_CLOCK_CONTROL_STOP; \
+} while (0)
+
+#define MMC_CLK 19169200
+#define SD_CLK 24576000
+
+/* msc_clk should little than pclk and little than clk retrieve from card */
+#define __msc_calc_clk_divisor(type,dev_clk,msc_clk,lv) \
+do { \
+ unsigned int rate, pclk, i; \
+ pclk = dev_clk; \
+ rate = type?SD_CLK:MMC_CLK; \
+ if (msc_clk && msc_clk < pclk) \
+ pclk = msc_clk; \
+ i = 0; \
+ while (pclk < rate) \
+ { \
+ i ++; \
+ rate >>= 1; \
+ } \
+ lv = i; \
+} while(0)
+
+/* divide rate to little than or equal to 400kHz */
+#define __msc_calc_slow_clk_divisor(type, lv) \
+do { \
+ unsigned int rate, i; \
+ rate = (type?SD_CLK:MMC_CLK)/1000/400; \
+ i = 0; \
+ while (rate > 0) \
+ { \
+ rate >>= 1; \
+ i ++; \
+ } \
+ lv = i; \
+} while(0)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810MSC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810nemc.h b/arch/mips/include/asm/mach-jz4810/jz4810nemc.h
new file mode 100644
index 00000000000..e33f8b989c7
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810nemc.h
@@ -0,0 +1,58 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810nemc.h
+ *
+ * JZ4810 NEMC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810NEMC_H__
+#define __JZ4810NEMC_H__
+
+
+#define NEMC_BASE 0xB3410000
+
+/*************************************************************************
+ * NEMC (External Memory Controller for NAND)
+ *************************************************************************/
+
+#define NEMC_NFCSR (NEMC_BASE + 0x050) /* NAND Flash Control/Status Register */
+#define NEMC_SMCR (NEMC_BASE + 0x14) /* Static Memory Control Register 1 */
+
+
+#define REG_NEMC_NFCSR REG32(NEMC_NFCSR)
+#define REG_NEMC_SMCR1 REG32(NEMC_SMCR)
+
+// PN(bit 0):0-disable, 1-enable
+// PN(bit 1):0-no reset, 1-reset
+// (bit 2):Reserved
+// BITCNT(bit 3):0-disable, 1-enable
+// BITCNT(bit 4):0-calculate, 1's number, 1-calculate 0's number
+// BITCNT(bit 5):0-no reset, 1-reset bitcnt
+#define NEMC_PNCR (NEMC_BASE+0x100)
+#define NEMC_PNDR (NEMC_BASE+0x104)
+#define NEMC_BITCNT (NEMC_BASE+0x108)
+
+#define REG_NEMC_PNCR REG32(NEMC_PNCR)
+#define REG_NEMC_PNDR REG32(NEMC_PNDR)
+#define REG_NEMC_BITCNT REG32(NEMC_BITCNT)
+
+#define REG_NEMC_SMCR REG32(NEMC_SMCR)
+
+/* NAND Flash Control/Status Register */
+#define NEMC_NFCSR_NFCE4 (1 << 7) /* NAND Flash Enable */
+#define NEMC_NFCSR_NFE4 (1 << 6) /* NAND Flash FCE# Assertion Enable */
+#define NEMC_NFCSR_NFCE3 (1 << 5)
+#define NEMC_NFCSR_NFE3 (1 << 4)
+#define NEMC_NFCSR_NFCE2 (1 << 3)
+#define NEMC_NFCSR_NFE2 (1 << 2)
+#define NEMC_NFCSR_NFCE1 (1 << 1)
+#define NEMC_NFCSR_NFE1 (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810NEMC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810otg.h b/arch/mips/include/asm/mach-jz4810/jz4810otg.h
new file mode 100644
index 00000000000..db923947419
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810otg.h
@@ -0,0 +1,135 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810otg.h
+ *
+ * JZ4810 OTG register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810OTG_H__
+#define __JZ4810OTG_H__
+
+
+#define UDC_BASE 0xB3440000
+
+/*************************************************************************
+ * USB Device
+ *************************************************************************/
+#define USB_BASE UDC_BASE
+
+#define USB_REG_FADDR (USB_BASE + 0x00) /* Function Address 8-bit */
+#define USB_REG_POWER (USB_BASE + 0x01) /* Power Managemetn 8-bit */
+#define USB_REG_INTRIN (USB_BASE + 0x02) /* Interrupt IN 16-bit */
+#define USB_REG_INTROUT (USB_BASE + 0x04) /* Interrupt OUT 16-bit */
+#define USB_REG_INTRINE (USB_BASE + 0x06) /* Intr IN enable 16-bit */
+#define USB_REG_INTROUTE (USB_BASE + 0x08) /* Intr OUT enable 16-bit */
+#define USB_REG_INTRUSB (USB_BASE + 0x0a) /* Interrupt USB 8-bit */
+#define USB_REG_INTRUSBE (USB_BASE + 0x0b) /* Interrupt USB Enable 8-bit */
+#define USB_REG_FRAME (USB_BASE + 0x0c) /* Frame number 16-bit */
+#define USB_REG_INDEX (USB_BASE + 0x0e) /* Index register 8-bit */
+#define USB_REG_TESTMODE (USB_BASE + 0x0f) /* USB test mode 8-bit */
+
+#define USB_REG_CSR0 (USB_BASE + 0x12) /* EP0 CSR 8-bit */
+#define USB_REG_INMAXP (USB_BASE + 0x10) /* EP1-2 IN Max Pkt Size 16-bit */
+#define USB_REG_INCSR (USB_BASE + 0x12) /* EP1-2 IN CSR LSB 8/16bit */
+#define USB_REG_INCSRH (USB_BASE + 0x13) /* EP1-2 IN CSR MSB 8-bit */
+#define USB_REG_OUTMAXP (USB_BASE + 0x14) /* EP1 OUT Max Pkt Size 16-bit */
+#define USB_REG_OUTCSR (USB_BASE + 0x16) /* EP1 OUT CSR LSB 8/16bit */
+#define USB_REG_OUTCSRH (USB_BASE + 0x17) /* EP1 OUT CSR MSB 8-bit */
+#define USB_REG_OUTCOUNT (USB_BASE + 0x18) /* bytes in EP0/1 OUT FIFO 16-bit */
+
+#define USB_FIFO_EP0 (USB_BASE + 0x20)
+#define USB_FIFO_EP1 (USB_BASE + 0x24)
+#define USB_FIFO_EP2 (USB_BASE + 0x28)
+
+#define USB_REG_EPINFO (USB_BASE + 0x78) /* Endpoint information */
+#define USB_REG_RAMINFO (USB_BASE + 0x79) /* RAM information */
+
+#define USB_REG_INTR (USB_BASE + 0x200) /* DMA pending interrupts */
+#define USB_REG_CNTL1 (USB_BASE + 0x204) /* DMA channel 1 control */
+#define USB_REG_ADDR1 (USB_BASE + 0x208) /* DMA channel 1 AHB memory addr */
+#define USB_REG_COUNT1 (USB_BASE + 0x20c) /* DMA channel 1 byte count */
+#define USB_REG_CNTL2 (USB_BASE + 0x214) /* DMA channel 2 control */
+#define USB_REG_ADDR2 (USB_BASE + 0x218) /* DMA channel 2 AHB memory addr */
+#define USB_REG_COUNT2 (USB_BASE + 0x21c) /* DMA channel 2 byte count */
+
+
+/* Power register bit masks */
+#define USB_POWER_SUSPENDM 0x01
+#define USB_POWER_RESUME 0x04
+#define USB_POWER_HSMODE 0x10
+#define USB_POWER_HSENAB 0x20
+#define USB_POWER_SOFTCONN 0x40
+
+/* Interrupt register bit masks */
+#define USB_INTR_SUSPEND 0x01
+#define USB_INTR_RESUME 0x02
+#define USB_INTR_RESET 0x04
+
+#define USB_INTR_EP0 0x0001
+#define USB_INTR_INEP1 0x0002
+#define USB_INTR_INEP2 0x0004
+#define USB_INTR_OUTEP1 0x0002
+
+/* CSR0 bit masks */
+#define USB_CSR0_OUTPKTRDY 0x01
+#define USB_CSR0_INPKTRDY 0x02
+#define USB_CSR0_SENTSTALL 0x04
+#define USB_CSR0_DATAEND 0x08
+#define USB_CSR0_SETUPEND 0x10
+#define USB_CSR0_SENDSTALL 0x20
+#define USB_CSR0_SVDOUTPKTRDY 0x40
+#define USB_CSR0_SVDSETUPEND 0x80
+
+/* Endpoint CSR register bits */
+#define USB_INCSRH_AUTOSET 0x80
+#define USB_INCSRH_ISO 0x40
+#define USB_INCSRH_MODE 0x20
+#define USB_INCSRH_DMAREQENAB 0x10
+#define USB_INCSRH_DMAREQMODE 0x04
+#define USB_INCSR_CDT 0x40
+#define USB_INCSR_SENTSTALL 0x20
+#define USB_INCSR_SENDSTALL 0x10
+#define USB_INCSR_FF 0x08
+#define USB_INCSR_UNDERRUN 0x04
+#define USB_INCSR_FFNOTEMPT 0x02
+#define USB_INCSR_INPKTRDY 0x01
+#define USB_OUTCSRH_AUTOCLR 0x80
+#define USB_OUTCSRH_ISO 0x40
+#define USB_OUTCSRH_DMAREQENAB 0x20
+#define USB_OUTCSRH_DNYT 0x10
+#define USB_OUTCSRH_DMAREQMODE 0x08
+#define USB_OUTCSR_CDT 0x80
+#define USB_OUTCSR_SENTSTALL 0x40
+#define USB_OUTCSR_SENDSTALL 0x20
+#define USB_OUTCSR_FF 0x10
+#define USB_OUTCSR_DATAERR 0x08
+#define USB_OUTCSR_OVERRUN 0x04
+#define USB_OUTCSR_FFFULL 0x02
+#define USB_OUTCSR_OUTPKTRDY 0x01
+
+/* Testmode register bits */
+#define USB_TEST_SE0NAK 0x01
+#define USB_TEST_J 0x02
+#define USB_TEST_K 0x04
+#define USB_TEST_PACKET 0x08
+
+/* DMA control bits */
+#define USB_CNTL_ENA 0x01
+#define USB_CNTL_DIR_IN 0x02
+#define USB_CNTL_MODE_1 0x04
+#define USB_CNTL_INTR_EN 0x08
+#define USB_CNTL_EP(n) ((n) << 4)
+#define USB_CNTL_BURST_0 (0 << 9)
+#define USB_CNTL_BURST_4 (1 << 9)
+#define USB_CNTL_BURST_8 (2 << 9)
+#define USB_CNTL_BURST_16 (3 << 9)
+
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810OTG_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810otp.h b/arch/mips/include/asm/mach-jz4810/jz4810otp.h
new file mode 100644
index 00000000000..4192847361b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810otp.h
@@ -0,0 +1,97 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810otp.h
+ *
+ * JZ4810 OTP register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810OTP_H__
+#define __JZ4810OTP_H__
+
+
+/*************************************************************************
+ * OTP (One Time Programmable Module)
+ *************************************************************************/
+#define OTP_ID0 (OTP_BASE + 0x00) /* ID0 Register */
+#define OTP_ID1 (OTP_BASE + 0x04) /* ID1 Register */
+#define OTP_ID2 (OTP_BASE + 0x08) /* ID2 Register */
+#define OTP_ID3 (OTP_BASE + 0x0C) /* ID3 Register */
+#define OTP_BR0 (OTP_BASE + 0x10) /* BOOTROM0 Register */
+#define OTP_BR1 (OTP_BASE + 0x14) /* BOOTROM1 Register */
+#define OTP_HW0 (OTP_BASE + 0x18) /* Chip Hardware 0 Register */
+#define OTP_HW1 (OTP_BASE + 0x1C) /* Chip Hardware 1 Register */
+
+#define REG_OTP_ID0 REG32(OTP_ID0)
+#define REG_OTP_ID1 REG32(OTP_ID1)
+#define REG_OTP_ID2 REG32(OTP_ID2)
+#define REG_OTP_ID3 REG32(OTP_ID3)
+#define REG_OTP_BR0 REG32(OTP_BR0)
+#define REG_OTP_BR1 REG32(OTP_BR1)
+#define REG_OTP_HW0 REG32(OTP_HW0)
+#define REG_OTP_HW1 REG32(OTP_HW1)
+
+/* ID0 Register */
+#define OTP_ID0_WID_BIT 24 /* Wafer ID */
+#define OTP_ID0_WID_MASK (0xff << OTP_ID0_WID_BIT)
+#define OTP_ID0_MID_BIT 16 /* MASK ID */
+#define OTP_ID0_MID_MASK (0xff << OTP_ID0_MID_BIT)
+#define OTP_ID0_FID_BIT 8 /* Foundary ID */
+#define OTP_ID0_FID_MASK (0xff << OTP_ID0_FID_BIT)
+#define OTP_ID0_PID_BIT 0 /* Product ID */
+#define OTP_ID0_PID_MASK (0xff << OTP_ID0_PID_BIT)
+
+/* ID1 Register */
+#define OTP_ID1_LID_BIT 8 /* Lot ID */
+#define OTP_ID1_LID_MASK (0xffffff << OTP_ID1_LID_BIT)
+#define OTP_ID1_TID_BIT 0 /* Test House ID */
+#define OTP_ID1_TID_MASK (0xff << OTP_ID1_TID_BIT)
+
+/* ID2 Register */
+#define OTP_ID2_XADR_BIT 24 /* Die X-dir Address */
+#define OTP_ID2_XADR_MASK (0xff << OTP_ID2_XADR_BIT)
+#define OTP_ID2_YADR_BIT 16 /* Die Y-dir Address */
+#define OTP_ID2_YADR_MASK (0xff << OTP_ID2_YADR_BIT)
+#define OTP_ID2_TDATE_BIT 0 /* Testing Date */
+#define OTP_ID2_TDATE_MASK (0xffff << OTP_ID2_TDATE_BIT)
+
+/* ID3 Register */
+#define OTP_ID3_CID_BIT 16 /* Customer ID */
+#define OTP_ID3_CID_MASK (0xffff << OTP_ID3_CID_BIT)
+#define OTP_ID3_CP_BIT 0 /* Chip Parameters */
+#define OTP_ID3_CP_MASK (0xffff << OTP_ID3_CP_BIT)
+
+/* BOOTROM1 Register */
+#define OTP_BR1_UDCBOOT_BIT 0
+#define OTP_BR1_UDCBOOT_MASK (0xff << OTP_BR1_UDCBOOT_BIT)
+ #define OTP_BR1_UDCBOOT_AUTO (0xf0 << OTP_BR1_UDCBOOT_BIT)
+ #define OTP_BR1_UDCBOOT_24M (0x0f << OTP_BR1_UDCBOOT_BIT) /* 24MHz OSC */
+ #define OTP_BR1_UDCBOOT_13M (0x0c << OTP_BR1_UDCBOOT_BIT) /* 13MHz OSC */
+ #define OTP_BR1_UDCBOOT_26M (0x03 << OTP_BR1_UDCBOOT_BIT) /* 26MHz OSC */
+ #define OTP_BR1_UDCBOOT_27M (0x00 << OTP_BR1_UDCBOOT_BIT) /* 27MHz OSC */
+
+/* Chip Hardware 1 Register */
+#define OTP_HW1_MC_EN (0x3 << 30) /* MC is enabled */
+#define OTP_HW1_ME_EN (0x3 << 28)
+#define OTP_HW1_DE_EN (0x3 << 26)
+#define OTP_HW1_IDCT_EN (0x3 << 24)
+#define OTP_HW1_UART3_EN (0x3 << 22)
+#define OTP_HW1_UART2_EN (0x3 << 20)
+#define OTP_HW1_UART1_EN (0x3 << 18)
+#define OTP_HW1_UART0_EN (0x3 << 16)
+#define OTP_HW1_SSI1_EN (0x3 << 14)
+#define OTP_HW1_SSI0_EN (0x3 << 12)
+#define OTP_HW1_MSC1_EN (0x3 << 10)
+#define OTP_HW1_MSC0_EN (0x3 << 8)
+#define OTP_HW1_UHC_EN (0x3 << 6)
+#define OTP_HW1_TVE_EN (0x3 << 4)
+#define OTP_HW1_TSSI_EN (0x3 << 2)
+#define OTP_HW1_CIM_EN (0x3 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810OTP_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810owi.h b/arch/mips/include/asm/mach-jz4810/jz4810owi.h
new file mode 100644
index 00000000000..86ca2e91aa0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810owi.h
@@ -0,0 +1,120 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810owi.h
+ *
+ * JZ4810 OWI register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810OWI_H__
+#define __JZ4810OWI_H__
+
+
+#define OWI_BASE 0xB0072000
+
+/*************************************************************************
+ * OWI (One-wire Bus Controller )
+ *************************************************************************/
+#define OWI_CFG (OWI_BASE + 0x00) /* OWI Configure Register */
+#define OWI_CTL (OWI_BASE + 0x04) /* OWI Control Register */
+#define OWI_STS (OWI_BASE + 0x08) /* OWI Status Register */
+#define OWI_DAT (OWI_BASE + 0x0c) /* OWI Data Register */
+#define OWI_DIV (OWI_BASE + 0x10) /* OWI Clock Divide Register */
+
+#define REG_OWI_CFG REG8(OWI_CFG)
+#define REG_OWI_CTL REG8(OWI_CTL)
+#define REG_OWI_STS REG8(OWI_STS)
+#define REG_OWI_DAT REG8(OWI_DAT)
+#define REG_OWI_DIV REG8(OWI_DIV)
+
+/* OWI Configure Register */
+#define OWI_CFG_MODE (1 << 7) /* 0: Regular speed mode 1: Overdrive speed mode */
+#define OWI_CFG_RDDATA (1 << 6) /* 1: receive data from one-wire bus and stored in OWDAT*/
+#define OWI_CFG_WRDATA (1 << 5) /* 1: transmit the data in OWDAT */
+#define OWI_CFG_RDST (1 << 4) /* 1: was sampled during a read */
+#define OWI_CFG_WR1RD (1 << 3) /* 1: generate write 1 sequence on line */
+#define OWI_CFG_WR0 (1 << 2) /* 1: generate write 0 sequence on line */
+#define OWI_CFG_RST (1 << 1) /* 1: generate reset pulse and sample slaves presence pulse*/
+#define OWI_CFG_ENA (1 << 0) /* 1: enable the OWI operation */
+
+/* OWI Control Register */
+#define OWI_CTL_EBYTE (1 << 2) /* enable byte write/read interrupt */
+#define OWI_CTL_EBIT (1 << 1) /* enable bit write/read interrupt */
+#define OWI_CTL_ERST (1 << 0) /* enable reset sequence finished interrupt */
+
+/* OWI Status Register */
+#define OWI_STS_PST (1 << 7) /* 1: one-wire bus has device on it */
+#define OWI_STS_BYTE_RDY (1 << 2) /* 1: have received or transmitted a data */
+#define OWI_STS_BIT_RDY (1 << 1) /* 1: have received or transmitted a bit */
+#define OWI_STS_PST_RDY (1 << 0) /* 1: have finished a reset pulse */
+
+/* OWI Clock Divide Register */
+#define OWI_DIV_CLKDIV_BIT 5
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * OWI (one-wire bus) ops
+ ***************************************************************************/
+
+/* OW control register ops */
+#define __owi_enable_all_interrupts() ( REG_OWI_CTL = (OWI_CTL_EBYTE | OWI_CTL_EBIT | OWI_CTL_ERST) )
+#define __owi_disable_all_interrupts() ( REG_OWI_CTL = 0 )
+
+#define __owi_enable_byte_interrupt() ( REG_OWI_CTL |= OWI_CTL_EBYTE )
+#define __owi_disable_byte_interrupt() ( REG_OWI_CTL &= ~OWI_CTL_EBYTE )
+#define __owi_enable_bit_interrupt() ( REG_OWI_CTL |= OWI_CTL_EBIT )
+#define __owi_disable_bit_interrupt() ( REG_OWI_CTL &= ~OWI_CTL_EBIT )
+#define __owi_enable_rst_interrupt() ( REG_OWI_CTL |= OWI_CTL_ERST )
+#define __owi_disable_rst_interrupt() ( REG_OWI_CTL &=~OWI_CTL_ERST )
+
+/* OW configure register ops */
+#define __owi_select_regular_mode() ( REG_OWI_CFG &= ~OWI_CFG_MODE )
+#define __owi_select_overdrive_mode() ( REG_OWI_CFG |= OWI_CFG_MODE )
+
+#define __owi_set_rddata() ( REG_OWI_CFG |= OWI_CFG_RDDATA )
+#define __owi_clr_rddata() ( REG_OWI_CFG &= ~OWI_CFG_RDDATA )
+#define __owi_get_rddata() ( REG_OWI_CFG & OWI_CFG_RDDATA )
+
+#define __owi_set_wrdata() ( REG_OWI_CFG |= OWI_CFG_WRDATA )
+#define __owi_clr_wrdata() ( REG_OWI_CFG &= ~OWI_CFG_WRDATA )
+#define __owi_get_wrdata() ( REG_OWI_CFG & OWI_CFG_WRDATA )
+
+#define __owi_get_rdst() ( REG_OWI_CFG & OWI_CFG_RDST )
+
+#define __owi_set_wr1rd() ( REG_OWI_CFG |= OWI_CFG_WR1RD )
+#define __owi_clr_wr1rd() ( REG_OWI_CFG &= ~OWI_CFG_WR1RD )
+#define __owi_get_wr1rd() ( REG_OWI_CFG & OWI_CFG_WR1RD )
+
+#define __owi_set_wr0() ( REG_OWI_CFG |= OWI_CFG_WR0 )
+#define __owi_clr_wr0() ( REG_OWI_CFG &= ~OWI_CFG_WR0 )
+#define __owi_get_wr0() ( REG_OWI_CFG & OWI_CFG_WR0 )
+
+#define __owi_set_rst() ( REG_OWI_CFG |= OWI_CFG_RST )
+#define __owi_clr_rst() ( REG_OWI_CFG &= ~OWI_CFG_RST )
+#define __owi_get_rst() ( REG_OWI_CFG & OWI_CFG_RST )
+
+#define __owi_enable_ow_ops() ( REG_OWI_CFG |= OWI_CFG_ENA )
+#define __owi_disable_ow_ops() ( REG_OWI_CFG &= ~OWI_CFG_ENA )
+#define __owi_get_enable() ( REG_OWI_CFG & OWI_CFG_ENA )
+
+#define __owi_wait_ops_rdy() \
+ do { \
+ while(__owi_get_enable()); \
+ udelay(1); \
+ } while(0);
+
+/* OW status register ops */
+#define __owi_clr_sts() ( REG_OWI_STS = 0 )
+#define __owi_get_sts_pst() ( REG_OWI_STS & OWI_STS_PST )
+#define __owi_get_sts_byte_rdy() ( REG_OWI_STS & OWI_STS_BYTE_RDY )
+#define __owi_get_sts_bit_rdy() ( REG_OWI_STS & OWI_STS_BIT_RDY )
+#define __owi_get_sts_pst_rdy() ( REG_OWI_STS & OWI_STS_PST_RDY )
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810OWI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810pcm.h b/arch/mips/include/asm/mach-jz4810/jz4810pcm.h
new file mode 100644
index 00000000000..f399bc410d9
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810pcm.h
@@ -0,0 +1,202 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810pcm.h
+ *
+ * JZ4810 PCM register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810PCM_H__
+#define __JZ4810PCM_H__
+
+
+#define PCM_BASE 0xB0071000
+
+/*************************************************************************
+ * PCM Controller
+ *************************************************************************/
+
+#define PCM_CTL (PCM_BASE + 0x000)
+#define PCM_CFG (PCM_BASE + 0x004)
+#define PCM_DP (PCM_BASE + 0x008)
+#define PCM_INTC (PCM_BASE + 0x00c)
+#define PCM_INTS (PCM_BASE + 0x010)
+#define PCM_DIV (PCM_BASE + 0x014)
+
+#define REG_PCM_CTL REG32(PCM_CTL)
+#define REG_PCM_CFG REG32(PCM_CFG)
+#define REG_PCM_DP REG32(PCM_DP)
+#define REG_PCM_INTC REG32(PCM_INTC)
+#define REG_PCM_INTS REG32(PCM_INTS)
+#define REG_PCM_DIV REG32(PCM_DIV)
+
+/* PCM Controller control Register (PCM_CTL) */
+
+#define PCM_CTL_ERDMA (1 << 9) /* Enable Receive DMA */
+#define PCM_CTL_ETDMA (1 << 8) /* Enable Transmit DMA */
+#define PCM_CTL_LSMP (1 << 7) /* Play Zero sample or last sample */
+#define PCM_CTL_ERPL (1 << 6) /* Enable Playing Back Function */
+#define PCM_CTL_EREC (1 << 5) /* Enable Recording Function */
+#define PCM_CTL_FLUSH (1 << 4) /* FIFO flush */
+#define PCM_CTL_RST (1 << 3) /* Reset PCM */
+#define PCM_CTL_CLKEN (1 << 1) /* Enable the clock division logic */
+#define PCM_CTL_PCMEN (1 << 0) /* Enable PCM module */
+
+/* PCM Controller configure Register (PCM_CFG) */
+
+#define PCM_CFG_SLOT_BIT 13
+#define PCM_CFG_SLOT_MASK (0x3 << PCM_CFG_SLOT_BIT)
+ #define PCM_CFG_SLOT_0 (0 << PCM_CFG_SLOT_BIT) /* Slot is 0 */
+ #define PCM_CFG_SLOT_1 (1 << PCM_CFG_SLOT_BIT) /* Slot is 1 */
+ #define PCM_CFG_SLOT_2 (2 << PCM_CFG_SLOT_BIT) /* Slot is 2 */
+ #define PCM_CFG_SLOT_3 (3 << PCM_CFG_SLOT_BIT) /* Slot is 3 */
+#define PCM_CFG_ISS_BIT 12
+#define PCM_CFG_ISS_MASK (0x1 << PCM_CFG_ISS_BIT)
+ #define PCM_CFG_ISS_8 (0 << PCM_CFG_ISS_BIT)
+ #define PCM_CFG_ISS_16 (1 << PCM_CFG_ISS_BIT)
+#define PCM_CFG_OSS_BIT 11
+#define PCM_CFG_OSS_MASK (0x1 << PCM_CFG_OSS_BIT)
+ #define PCM_CFG_OSS_8 (0 << PCM_CFG_OSS_BIT)
+ #define PCM_CFG_OSS_16 (1 << PCM_CFG_OSS_BIT)
+#define PCM_CFG_IMSBPOS (1 << 10)
+#define PCM_CFG_OMSBPOS (1 << 9)
+#define PCM_CFG_RFTH_BIT 5 /* Receive FIFO Threshold */
+#define PCM_CFG_RFTH_MASK (0xf << PCM_CFG_RFTH_BIT)
+#define PCM_CFG_TFTH_BIT 1 /* Transmit FIFO Threshold */
+#define PCM_CFG_TFTH_MASK (0xf << PCM_CFG_TFTH_BIT)
+#define PCM_CFG_MODE (0x0 << 0)
+
+/* PCM Controller interrupt control Register (PCM_INTC) */
+
+#define PCM_INTC_ETFS (1 << 3)
+#define PCM_INTC_ETUR (1 << 2)
+#define PCM_INTC_ERFS (1 << 1)
+#define PCM_INTC_EROR (1 << 0)
+
+/* PCM Controller interrupt status Register (PCM_INTS) */
+
+#define PCM_INTS_RSTS (1 << 14) /* Reset or flush has not complete */
+#define PCM_INTS_TFL_BIT 9
+#define PCM_INTS_TFL_MASK (0x1f << PCM_INTS_TFL_BIT)
+#define PCM_INTS_TFS (1 << 8) /* Tranmit FIFO Service Request */
+#define PCM_INTS_TUR (1 << 7) /* Transmit FIFO Under Run */
+#define PCM_INTS_RFL_BIT 2
+#define PCM_INTS_RFL_MASK (0x1f << PCM_INTS_RFL_BIT)
+#define PCM_INTS_RFS (1 << 1) /* Receive FIFO Service Request */
+#define PCM_INTS_ROR (1 << 0) /* Receive FIFO Over Run */
+
+/* PCM Controller clock division Register (PCM_DIV) */
+#define PCM_DIV_SYNL_BIT 11
+#define PCM_DIV_SYNL_MASK (0x3f << PCM_DIV_SYNL_BIT)
+#define PCM_DIV_SYNDIV_BIT 6
+#define PCM_DIV_SYNDIV_MASK (0x1f << PCM_DIV_SYNDIV_BIT)
+#define PCM_DIV_CLKDIV_BIT 0
+#define PCM_DIV_CLKDIV_MASK (0x3f << PCM_DIV_CLKDIV_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * PCM Controller operation
+ *************************************************************************/
+
+#define __pcm_enable() ( REG_PCM_CTL |= PCM_CTL_PCMEN )
+#define __pcm_disable() ( REG_PCM_CTL &= ~PCM_CTL_PCMEN )
+
+#define __pcm_clk_enable() ( REG_PCM_CTL |= PCM_CTL_CLKEN )
+#define __pcm_clk_disable() ( REG_PCM_CTL &= ~PCM_CTL_CLKEN )
+
+#define __pcm_reset() ( REG_PCM_CTL |= PCM_CTL_RST )
+#define __pcm_flush_fifo() ( REG_PCM_CTL |= PCM_CTL_FLUSH )
+
+#define __pcm_enable_record() ( REG_PCM_CTL |= PCM_CTL_EREC )
+#define __pcm_disable_record() ( REG_PCM_CTL &= ~PCM_CTL_EREC )
+#define __pcm_enable_playback() ( REG_PCM_CTL |= PCM_CTL_ERPL )
+#define __pcm_disable_playback() ( REG_PCM_CTL &= ~PCM_CTL_ERPL )
+
+#define __pcm_enable_rxfifo() __pcm_enable_record()
+#define __pcm_disable_rxfifo() __pcm_disable_record()
+#define __pcm_enable_txfifo() __pcm_enable_playback()
+#define __pcm_disable_txfifo() __pcm_disable_playback()
+
+#define __pcm_last_sample() ( REG_PCM_CTL |= PCM_CTL_LSMP )
+#define __pcm_zero_sample() ( REG_PCM_CTL &= ~PCM_CTL_LSMP )
+
+#define __pcm_enable_transmit_dma() ( REG_PCM_CTL |= PCM_CTL_ETDMA )
+#define __pcm_disable_transmit_dma() ( REG_PCM_CTL &= ~PCM_CTL_ETDMA )
+#define __pcm_enable_receive_dma() ( REG_PCM_CTL |= PCM_CTL_ERDMA )
+#define __pcm_disable_receive_dma() ( REG_PCM_CTL &= ~PCM_CTL_ERDMA )
+
+#define __pcm_as_master() ( REG_PCM_CFG &= PCM_CFG_MODE )
+#define __pcm_as_slave() ( REG_PCM_CFG |= ~PCM_CFG_MODE )
+
+#define __pcm_set_transmit_trigger(n) \
+do { \
+ REG_PCM_CFG &= ~PCM_CFG_TFTH_MASK; \
+ REG_PCM_CFG |= ((n) << PCM_CFG_TFTH_BIT); \
+} while(0)
+
+#define __pcm_set_receive_trigger(n) \
+do { \
+ REG_PCM_CFG &= ~PCM_CFG_RFTH_MASK; \
+ REG_PCM_CFG |= ((n) << PCM_CFG_RFTH_BIT); \
+} while(0)
+
+#define __pcm_omsb_same_sync() ( REG_PCM_CFG &= ~PCM_CFG_OMSBPOS )
+#define __pcm_omsb_next_sync() ( REG_PCM_CFG |= PCM_CFG_OMSBPOS )
+
+#define __pcm_imsb_same_sync() ( REG_PCM_CFG &= ~PCM_CFG_IMSBPOS )
+#define __pcm_imsb_next_sync() ( REG_PCM_CFG |= PCM_CFG_IMSBPOS )
+
+/* set input sample size 8 or 16*/
+#define __pcm_set_iss(n) \
+( REG_PCM_CFG = (REG_PCM_CFG & ~PCM_CFG_ISS_MASK) | PCM_CFG_ISS_##n )
+/* set output sample size 8 or 16*/
+#define __pcm_set_oss(n) \
+( REG_PCM_CFG = (REG_PCM_CFG & ~PCM_CFG_OSS_MASK) | PCM_CFG_OSS_##n )
+
+#define __pcm_set_valid_slot(n) \
+( REG_PCM_CFG = (REG_PCM_CFG & ~PCM_CFG_SLOT_MASK) | PCM_CFG_SLOT_##n )
+
+#define __pcm_write_data(v) ( REG_PCM_DP = (v) )
+#define __pcm_read_data() ( REG_PCM_DP )
+
+#define __pcm_enable_tfs_intr() ( REG_PCM_INTC |= PCM_INTC_ETFS )
+#define __pcm_disable_tfs_intr() ( REG_PCM_INTC &= ~PCM_INTC_ETFS )
+
+#define __pcm_enable_tur_intr() ( REG_PCM_INTC |= PCM_INTC_ETUR )
+#define __pcm_disable_tur_intr() ( REG_PCM_INTC &= ~PCM_INTC_ETUR )
+
+#define __pcm_enable_rfs_intr() ( REG_PCM_INTC |= PCM_INTC_ERFS )
+#define __pcm_disable_rfs_intr() ( REG_PCM_INTC &= ~PCM_INTC_ERFS )
+
+#define __pcm_enable_ror_intr() ( REG_PCM_INTC |= PCM_INTC_EROR )
+#define __pcm_disable_ror_intr() ( REG_PCM_INTC &= ~PCM_INTC_EROR )
+
+#define __pcm_ints_valid_tx() \
+( ((REG_PCM_INTS & PCM_INTS_TFL_MASK) >> PCM_INTS_TFL_BIT) )
+#define __pcm_ints_valid_rx() \
+( ((REG_PCM_INTS & PCM_INTS_RFL_MASK) >> PCM_INTS_RFL_BIT) )
+
+#define __pcm_set_clk_div(n) \
+( REG_PCM_DIV = (REG_PCM_DIV & ~PCM_DIV_CLKDIV_MASK) | ((n) << PCM_DIV_CLKDIV_BIT) )
+
+/* sysclk(cpm_pcm_sysclk) Hz is created by cpm logic, and pcmclk Hz is the pcm in/out clock wanted */
+#define __pcm_set_clk_rate(sysclk, pcmclk) \
+__pcm_set_clk_div(((sysclk) / (pcmclk) - 1))
+
+#define __pcm_set_sync_div(n) \
+( REG_PCM_DIV = (REG_PCM_DIV & ~PCM_DIV_SYNDIV_MASK) | ((n) << PCM_DIV_SYNDIV_BIT) )
+
+/* pcmclk is source clock Hz, and sync is the frame sync clock Hz wanted */
+#define __pcm_set_sync_rate(pcmclk, sync) \
+__pcm_set_sync_div(((pcmclk) / (8 * (sync)) - 1))
+
+ /* set sync length in pcmclk n = 0 ... 63 */
+#define __pcm_set_sync_len(n) \
+( REG_PCM_DIV = (REG_PCM_DIV & ~PCM_DIV_SYNL_MASK) | (n << PCM_DIV_SYNL_BIT) )
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810PCM_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810rtc.h b/arch/mips/include/asm/mach-jz4810/jz4810rtc.h
new file mode 100644
index 00000000000..8b24265782b
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810rtc.h
@@ -0,0 +1,141 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810rtc.h
+ *
+ * JZ4810 RTC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810RTC_H__
+#define __JZ4810RTC_H__
+
+
+#define RTC_BASE 0xB0003000
+
+/*************************************************************************
+ * 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 */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * RTC ops
+ ***************************************************************************/
+
+#define __rtc_write_ready() ( (REG_RTC_RCR & RTC_RCR_WRDY) >> RTC_RCR_WRDY_BIT )
+#define __rtc_enabled() ( REG_RTC_RCR |= RTC_RCR_RTCE )
+#define __rtc_disabled() ( REG_RTC_RCR &= ~RTC_RCR_RTCE )
+#define __rtc_enable_alarm() ( REG_RTC_RCR |= RTC_RCR_AE )
+#define __rtc_disable_alarm() ( REG_RTC_RCR &= ~RTC_RCR_AE )
+#define __rtc_enable_alarm_irq() ( REG_RTC_RCR |= RTC_RCR_AIE )
+#define __rtc_disable_alarm_irq() ( REG_RTC_RCR &= ~RTC_RCR_AIE )
+#define __rtc_enable_1Hz_irq() ( REG_RTC_RCR |= RTC_RCR_1HZIE )
+#define __rtc_disable_1Hz_irq() ( REG_RTC_RCR &= ~RTC_RCR_1HZIE )
+
+#define __rtc_get_1Hz_flag() ( (REG_RTC_RCR >> RTC_RCR_1HZ_BIT) & 0x1 )
+#define __rtc_clear_1Hz_flag() ( REG_RTC_RCR &= ~RTC_RCR_1HZ )
+#define __rtc_get_alarm_flag() ( (REG_RTC_RCR >> RTC_RCR_AF_BIT) & 0x1 )
+#define __rtc_clear_alarm_flag() ( REG_RTC_RCR &= ~RTC_RCR_AF )
+
+#define __rtc_get_second() ( REG_RTC_RSR )
+#define __rtc_set_second(v) ( REG_RTC_RSR = v )
+
+#define __rtc_get_alarm_second() ( REG_RTC_RSAR )
+#define __rtc_set_alarm_second(v) ( REG_RTC_RSAR = v )
+
+#define __rtc_RGR_is_locked() ( (REG_RTC_RGR >> RTC_RGR_LOCK) )
+#define __rtc_lock_RGR() ( REG_RTC_RGR |= RTC_RGR_LOCK )
+#define __rtc_unlock_RGR() ( REG_RTC_RGR &= ~RTC_RGR_LOCK )
+#define __rtc_get_adjc_val() ( (REG_RTC_RGR & RTC_RGR_ADJC_MASK) >> RTC_RGR_ADJC_BIT )
+#define __rtc_set_adjc_val(v) \
+ ( REG_RTC_RGR = ( (REG_RTC_RGR & ~RTC_RGR_ADJC_MASK) | (v << RTC_RGR_ADJC_BIT) ))
+#define __rtc_get_nc1Hz_val() ( (REG_RTC_RGR & RTC_RGR_NC1HZ_MASK) >> RTC_RGR_NC1HZ_BIT )
+#define __rtc_set_nc1Hz_val(v) \
+ ( REG_RTC_RGR = ( (REG_RTC_RGR & ~RTC_RGR_NC1HZ_MASK) | (v << RTC_RGR_NC1HZ_BIT) ))
+
+#define __rtc_power_down() ( REG_RTC_HCR |= RTC_HCR_PD )
+
+#define __rtc_get_hwfcr_val() ( REG_RTC_HWFCR & RTC_HWFCR_MASK )
+#define __rtc_set_hwfcr_val(v) ( REG_RTC_HWFCR = (v) & RTC_HWFCR_MASK )
+#define __rtc_get_hrcr_val() ( REG_RTC_HRCR & RTC_HRCR_MASK )
+#define __rtc_set_hrcr_val(v) ( REG_RTC_HRCR = (v) & RTC_HRCR_MASK )
+
+#define __rtc_enable_alarm_wakeup() ( REG_RTC_HWCR |= RTC_HWCR_EALM )
+#define __rtc_disable_alarm_wakeup() ( REG_RTC_HWCR &= ~RTC_HWCR_EALM )
+
+#define __rtc_status_hib_reset_occur() ( (REG_RTC_HWRSR >> RTC_HWRSR_HR) & 0x1 )
+#define __rtc_status_ppr_reset_occur() ( (REG_RTC_HWRSR >> RTC_HWRSR_PPR) & 0x1 )
+#define __rtc_status_wakeup_pin_waken_up() ( (REG_RTC_HWRSR >> RTC_HWRSR_PIN) & 0x1 )
+#define __rtc_status_alarm_waken_up() ( (REG_RTC_HWRSR >> RTC_HWRSR_ALM) & 0x1 )
+#define __rtc_clear_hib_stat_all() ( REG_RTC_HWRSR = 0 )
+
+#define __rtc_get_scratch_pattern() (REG_RTC_HSPR)
+#define __rtc_set_scratch_pattern(n) (REG_RTC_HSPR = n )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810RTC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810sadc.h b/arch/mips/include/asm/mach-jz4810/jz4810sadc.h
new file mode 100644
index 00000000000..f4697e12be4
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810sadc.h
@@ -0,0 +1,116 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810sadc.h
+ *
+ * JZ4810 SADC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810SADC_H__
+#define __JZ4810SADC_H__
+
+
+#define SADC_BASE 0xB0070000
+
+/*************************************************************************
+ * SADC (Smart A/D Controller)
+ *************************************************************************/
+
+#define SADC_ENA (SADC_BASE + 0x00) /* ADC Enable Register */
+#define SADC_CFG (SADC_BASE + 0x04) /* ADC Configure Register */
+#define SADC_CTRL (SADC_BASE + 0x08) /* ADC Control Register */
+#define SADC_STATE (SADC_BASE + 0x0C) /* ADC Status Register*/
+#define SADC_SAMETIME (SADC_BASE + 0x10) /* ADC Same Point Time Register */
+#define SADC_WAITTIME (SADC_BASE + 0x14) /* ADC Wait Time Register */
+#define SADC_TSDAT (SADC_BASE + 0x18) /* ADC Touch Screen Data Register */
+#define SADC_BATDAT (SADC_BASE + 0x1C) /* ADC VBAT Data Register */
+#define SADC_SADDAT (SADC_BASE + 0x20) /* ADC AUX Data Register */
+#define SADC_ADCLK (SADC_BASE + 0x28) /* ADC Clock Divide Register */
+#define SADC_FLT (SADC_BASE + 0x24) /* ADC Filter Register */
+
+#define REG_SADC_ENA REG8(SADC_ENA)
+#define REG_SADC_CFG REG32(SADC_CFG)
+#define REG_SADC_CTRL REG8(SADC_CTRL)
+#define REG_SADC_STATE REG8(SADC_STATE)
+#define REG_SADC_SAMETIME REG16(SADC_SAMETIME)
+#define REG_SADC_WAITTIME REG16(SADC_WAITTIME)
+#define REG_SADC_TSDAT REG32(SADC_TSDAT)
+#define REG_SADC_BATDAT REG16(SADC_BATDAT)
+#define REG_SADC_SADDAT REG16(SADC_SADDAT)
+#define REG_SADC_ADCLK REG32(SADC_ADCLK)
+#define REG_SADC_FLT REG16(SADC_FLT)
+ #define SADC_FLT_ENA (1 << 15)
+
+/* ADENA: ADC Enable Register */
+#define SADC_ENA_POWER (1 << 7) /* SADC Power control bit */
+#define SADC_ENA_SLP_MD (1 << 6) /* SLEEP mode control */
+#define SADC_ENA_TSEN (1 << 2) /* Touch Screen Enable */
+#define SADC_ENA_PBATEN (1 << 1) /* PBAT Enable */
+#define SADC_ENA_SADCINEN (1 << 0) /* AUX n Enable */
+
+/* ADC Configure Register */
+#define SADC_CFG_SPZZ (1 << 30)
+#define SADC_CFG_TS_DMA (1 << 15) /* Touch Screen DMA Enable */
+#define SADC_CFG_XYZ_BIT 13 /* XYZ selection */
+#define SADC_CFG_XYZ_MASK (0x3 << SADC_CFG_XYZ_BIT)
+ #define SADC_CFG_XY (0 << SADC_CFG_XYZ_BIT)
+ #define SADC_CFG_XYZ (1 << SADC_CFG_XYZ_BIT)
+ #define SADC_CFG_XYZ1Z2 (2 << SADC_CFG_XYZ_BIT)
+#define SADC_CFG_SNUM_BIT 10 /* Sample Number */
+#define SADC_CFG_SNUM(x) (((x) - 1) << SADC_CFG_SNUM_BIT)
+#define SADC_CFG_SNUM_MASK (0x7 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_1 (0x0 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_2 (0x1 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_3 (0x2 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_4 (0x3 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_5 (0x4 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_6 (0x5 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_8 (0x6 << SADC_CFG_SNUM_BIT)
+ #define SADC_CFG_SNUM_9 (0x7 << SADC_CFG_SNUM_BIT)
+#define SADC_CFG_CMD_BIT 0 /* ADC Command */
+#define SADC_CFG_CMD_MASK (0x3 << SADC_CFG_CMD_BIT)
+ #define SADC_CFG_CMD_AUX0 (0x0 << SADC_CFG_CMD_BIT) /* AUX voltage */
+ #define SADC_CFG_CMD_AUX1 (0x1 << SADC_CFG_CMD_BIT) /* AUX1 voltage */
+ #define SADC_CFG_CMD_AUX2 (0x2 << SADC_CFG_CMD_BIT) /* AUX2 voltage */
+ #define SADC_CFG_CMD_RESERVED (0x3 << SADC_CFG_CMD_BIT) /* Reserved */
+
+/* ADCCTRL: ADC Control Register */
+#define SADC_CTRL_SLPENDM (1 << 5) /* Sleep Interrupt Mask */
+#define SADC_CTRL_PENDM (1 << 4) /* Pen Down Interrupt Mask */
+#define SADC_CTRL_PENUM (1 << 3) /* Pen Up Interrupt Mask */
+#define SADC_CTRL_TSRDYM (1 << 2) /* Touch Screen Data Ready Interrupt Mask */
+#define SADC_CTRL_PBATRDYM (1 << 1) /* VBAT Data Ready Interrupt Mask */
+#define SADC_CTRL_SRDYM (1 << 0) /* AUX Data Ready Interrupt Mask */
+
+/* ADSTATE: ADC Status Register */
+#define SADC_STATE_SLP_RDY (1 << 7) /* Sleep state bit */
+#define SADC_STATE_SLEEPND (1 << 5) /* Pen Down Interrupt Flag */
+#define SADC_STATE_PEND (1 << 4) /* Pen Down Interrupt Flag */
+#define SADC_STATE_PENU (1 << 3) /* Pen Up Interrupt Flag */
+#define SADC_STATE_TSRDY (1 << 2) /* Touch Screen Data Ready Interrupt Flag */
+#define SADC_STATE_PBATRDY (1 << 1) /* VBAT Data Ready Interrupt Flag */
+#define SADC_STATE_SRDY (1 << 0) /* AUX Data Ready Interrupt Flag */
+
+/* ADTCH: ADC Touch Screen Data Register */
+#define SADC_TSDAT_TYPE1 (1 << 31)
+#define SADC_TSDAT_DATA1_BIT 16
+#define SADC_TSDAT_DATA1_MASK (0xfff << SADC_TSDAT_DATA1_BIT)
+#define SADC_TSDAT_TYPE0 (1 << 15)
+#define SADC_TSDAT_DATA0_BIT 0
+#define SADC_TSDAT_DATA0_MASK (0xfff << SADC_TSDAT_DATA0_BIT)
+
+/* ADCLK: ADC Clock Divide Register */
+#define SADC_ADCLK_CLKDIV_MS 16
+#define SADC_ADCLK_CLKDIV_MS_MASK (0xffff << SADC_ADCLK_CLKDIV_MS)
+#define SADC_ADCLK_CLKDIV_US 8
+#define SADC_ADCLK_CLKDIV_US_MASK (0xff << SADC_ADCLK_CLKDIV_US)
+#define SADC_ADCLK_CLKDIV_BIT 0
+#define SADC_ADCLK_CLKDIV_MASK (0xff << SADC_ADCLK_CLKDIV_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810SADC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810scc.h b/arch/mips/include/asm/mach-jz4810/jz4810scc.h
new file mode 100644
index 00000000000..6240b5e9625
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810scc.h
@@ -0,0 +1,191 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810scc.h
+ *
+ * JZ4810 SCC register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810SCC_H__
+#define __JZ4810SCC_H__
+
+
+#define SCC_BASE 0xB0040000
+
+/*************************************************************************
+ * SCC
+ *************************************************************************/
+#define SCC_DR (SCC_BASE + 0x000)
+#define SCC_FDR (SCC_BASE + 0x004)
+#define SCC_CR (SCC_BASE + 0x008)
+#define SCC_SR (SCC_BASE + 0x00C)
+#define SCC_TFR (SCC_BASE + 0x010)
+#define SCC_EGTR (SCC_BASE + 0x014)
+#define SCC_ECR (SCC_BASE + 0x018)
+#define SCC_RTOR (SCC_BASE + 0x01C)
+
+#define REG_SCC_DR REG8(SCC_DR)
+#define REG_SCC_FDR REG8(SCC_FDR)
+#define REG_SCC_CR REG32(SCC_CR)
+#define REG_SCC_SR REG16(SCC_SR)
+#define REG_SCC_TFR REG16(SCC_TFR)
+#define REG_SCC_EGTR REG8(SCC_EGTR)
+#define REG_SCC_ECR REG32(SCC_ECR)
+#define REG_SCC_RTOR REG8(SCC_RTOR)
+
+/* SCC FIFO Data Count Register (SCC_FDR) */
+
+#define SCC_FDR_EMPTY 0x00
+#define SCC_FDR_FULL 0x10
+
+/* SCC Control Register (SCC_CR) */
+
+#define SCC_CR_SCCE (1 << 31)
+#define SCC_CR_TRS (1 << 30)
+#define SCC_CR_T2R (1 << 29)
+#define SCC_CR_FDIV_BIT 24
+#define SCC_CR_FDIV_MASK (0x3 << SCC_CR_FDIV_BIT)
+ #define SCC_CR_FDIV_1 (0 << SCC_CR_FDIV_BIT) /* SCC_CLK frequency is the same as device clock */
+ #define SCC_CR_FDIV_2 (1 << SCC_CR_FDIV_BIT) /* SCC_CLK frequency is half of device clock */
+#define SCC_CR_FLUSH (1 << 23)
+#define SCC_CR_TRIG_BIT 16
+#define SCC_CR_TRIG_MASK (0x3 << SCC_CR_TRIG_BIT)
+ #define SCC_CR_TRIG_1 (0 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 1 */
+ #define SCC_CR_TRIG_4 (1 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 4 */
+ #define SCC_CR_TRIG_8 (2 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 8 */
+ #define SCC_CR_TRIG_14 (3 << SCC_CR_TRIG_BIT) /* Receive/Transmit-FIFO Trigger is 14 */
+#define SCC_CR_TP (1 << 15)
+#define SCC_CR_CONV (1 << 14)
+#define SCC_CR_TXIE (1 << 13)
+#define SCC_CR_RXIE (1 << 12)
+#define SCC_CR_TENDIE (1 << 11)
+#define SCC_CR_RTOIE (1 << 10)
+#define SCC_CR_ECIE (1 << 9)
+#define SCC_CR_EPIE (1 << 8)
+#define SCC_CR_RETIE (1 << 7)
+#define SCC_CR_EOIE (1 << 6)
+#define SCC_CR_TSEND (1 << 3)
+#define SCC_CR_PX_BIT 1
+#define SCC_CR_PX_MASK (0x3 << SCC_CR_PX_BIT)
+ #define SCC_CR_PX_NOT_SUPPORT (0 << SCC_CR_PX_BIT) /* SCC does not support clock stop */
+ #define SCC_CR_PX_STOP_LOW (1 << SCC_CR_PX_BIT) /* SCC_CLK stops at state low */
+ #define SCC_CR_PX_STOP_HIGH (2 << SCC_CR_PX_BIT) /* SCC_CLK stops at state high */
+#define SCC_CR_CLKSTP (1 << 0)
+
+/* SCC Status Register (SCC_SR) */
+
+#define SCC_SR_TRANS (1 << 15)
+#define SCC_SR_ORER (1 << 12)
+#define SCC_SR_RTO (1 << 11)
+#define SCC_SR_PER (1 << 10)
+#define SCC_SR_TFTG (1 << 9)
+#define SCC_SR_RFTG (1 << 8)
+#define SCC_SR_TEND (1 << 7)
+#define SCC_SR_RETR_3 (1 << 4)
+#define SCC_SR_ECNTO (1 << 0)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * SCC
+ ***************************************************************************/
+
+#define __scc_enable() ( REG_SCC_CR |= SCC_CR_SCCE )
+#define __scc_disable() ( REG_SCC_CR &= ~SCC_CR_SCCE )
+
+#define __scc_set_tx_mode() ( REG_SCC_CR |= SCC_CR_TRS )
+#define __scc_set_rx_mode() ( REG_SCC_CR &= ~SCC_CR_TRS )
+
+#define __scc_enable_t2r() ( REG_SCC_CR |= SCC_CR_T2R )
+#define __scc_disable_t2r() ( REG_SCC_CR &= ~SCC_CR_T2R )
+
+#define __scc_clk_as_devclk() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_FDIV_MASK; \
+ REG_SCC_CR |= SCC_CR_FDIV_1; \
+} while (0)
+
+#define __scc_clk_as_half_devclk() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_FDIV_MASK; \
+ REG_SCC_CR |= SCC_CR_FDIV_2; \
+} while (0)
+
+/* n=1,4,8,14 */
+#define __scc_set_fifo_trigger(n) \
+do { \
+ REG_SCC_CR &= ~SCC_CR_TRIG_MASK; \
+ REG_SCC_CR |= SCC_CR_TRIG_##n; \
+} while (0)
+
+#define __scc_set_protocol(p) \
+do { \
+ if (p) \
+ REG_SCC_CR |= SCC_CR_TP; \
+ else \
+ REG_SCC_CR &= ~SCC_CR_TP; \
+} while (0)
+
+#define __scc_flush_fifo() ( REG_SCC_CR |= SCC_CR_FLUSH )
+
+#define __scc_set_invert_mode() ( REG_SCC_CR |= SCC_CR_CONV )
+#define __scc_set_direct_mode() ( REG_SCC_CR &= ~SCC_CR_CONV )
+
+#define SCC_ERR_INTRS \
+ ( SCC_CR_ECIE | SCC_CR_EPIE | SCC_CR_RETIE | SCC_CR_EOIE )
+#define SCC_ALL_INTRS \
+ ( SCC_CR_TXIE | SCC_CR_RXIE | SCC_CR_TENDIE | SCC_CR_RTOIE | \
+ SCC_CR_ECIE | SCC_CR_EPIE | SCC_CR_RETIE | SCC_CR_EOIE )
+
+#define __scc_enable_err_intrs() ( REG_SCC_CR |= SCC_ERR_INTRS )
+#define __scc_disable_err_intrs() ( REG_SCC_CR &= ~SCC_ERR_INTRS )
+
+#define SCC_ALL_ERRORS \
+ ( SCC_SR_ORER | SCC_SR_RTO | SCC_SR_PER | SCC_SR_RETR_3 | SCC_SR_ECNTO)
+
+#define __scc_clear_errors() ( REG_SCC_SR &= ~SCC_ALL_ERRORS )
+
+#define __scc_enable_all_intrs() ( REG_SCC_CR |= SCC_ALL_INTRS )
+#define __scc_disable_all_intrs() ( REG_SCC_CR &= ~SCC_ALL_INTRS )
+
+#define __scc_enable_tx_intr() ( REG_SCC_CR |= SCC_CR_TXIE | SCC_CR_TENDIE )
+#define __scc_disable_tx_intr() ( REG_SCC_CR &= ~(SCC_CR_TXIE | SCC_CR_TENDIE) )
+
+#define __scc_enable_rx_intr() ( REG_SCC_CR |= SCC_CR_RXIE)
+#define __scc_disable_rx_intr() ( REG_SCC_CR &= ~SCC_CR_RXIE)
+
+#define __scc_set_tsend() ( REG_SCC_CR |= SCC_CR_TSEND )
+#define __scc_clear_tsend() ( REG_SCC_CR &= ~SCC_CR_TSEND )
+
+#define __scc_set_clockstop() ( REG_SCC_CR |= SCC_CR_CLKSTP )
+#define __scc_clear_clockstop() ( REG_SCC_CR &= ~SCC_CR_CLKSTP )
+
+#define __scc_clockstop_low() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_PX_MASK; \
+ REG_SCC_CR |= SCC_CR_PX_STOP_LOW; \
+} while (0)
+
+#define __scc_clockstop_high() \
+do { \
+ REG_SCC_CR &= ~SCC_CR_PX_MASK; \
+ REG_SCC_CR |= SCC_CR_PX_STOP_HIGH; \
+} while (0)
+
+/* SCC status checking */
+#define __scc_check_transfer_status() ( REG_SCC_SR & SCC_SR_TRANS )
+#define __scc_check_rx_overrun_error() ( REG_SCC_SR & SCC_SR_ORER )
+#define __scc_check_rx_timeout() ( REG_SCC_SR & SCC_SR_RTO )
+#define __scc_check_parity_error() ( REG_SCC_SR & SCC_SR_PER )
+#define __scc_check_txfifo_trigger() ( REG_SCC_SR & SCC_SR_TFTG )
+#define __scc_check_rxfifo_trigger() ( REG_SCC_SR & SCC_SR_RFTG )
+#define __scc_check_tx_end() ( REG_SCC_SR & SCC_SR_TEND )
+#define __scc_check_retx_3() ( REG_SCC_SR & SCC_SR_RETR_3 )
+#define __scc_check_ecnt_overflow() ( REG_SCC_SR & SCC_SR_ECNTO )
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810SCC_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810ssi.h b/arch/mips/include/asm/mach-jz4810/jz4810ssi.h
new file mode 100644
index 00000000000..e355695c447
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810ssi.h
@@ -0,0 +1,350 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810ssi.h
+ *
+ * JZ4810 SSI register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810SSI_H__
+#define __JZ4810SSI_H__
+
+
+#define SSI0_BASE 0xB0043000
+#define SSI1_BASE 0xB0044000
+#define SSI2_BASE 0xB0045000
+
+
+
+/*************************************************************************
+ * SSI (Synchronous Serial Interface)
+ *************************************************************************/
+/* n = 0, 1 (SSI0, SSI1) */
+#define SSI_DR(n) (SSI0_BASE + 0x000 + (n)*0x2000)
+#define SSI_CR0(n) (SSI0_BASE + 0x004 + (n)*0x2000)
+#define SSI_CR1(n) (SSI0_BASE + 0x008 + (n)*0x2000)
+#define SSI_SR(n) (SSI0_BASE + 0x00C + (n)*0x2000)
+#define SSI_ITR(n) (SSI0_BASE + 0x010 + (n)*0x2000)
+#define SSI_ICR(n) (SSI0_BASE + 0x014 + (n)*0x2000)
+#define SSI_GR(n) (SSI0_BASE + 0x018 + (n)*0x2000)
+
+#define REG_SSI_DR(n) REG32(SSI_DR(n))
+#define REG_SSI_CR0(n) REG16(SSI_CR0(n))
+#define REG_SSI_CR1(n) REG32(SSI_CR1(n))
+#define REG_SSI_SR(n) REG32(SSI_SR(n))
+#define REG_SSI_ITR(n) REG16(SSI_ITR(n))
+#define REG_SSI_ICR(n) REG8(SSI_ICR(n))
+#define REG_SSI_GR(n) REG16(SSI_GR(n))
+
+/* SSI Data Register (SSI_DR) */
+
+#define SSI_DR_GPC_BIT 0
+#define SSI_DR_GPC_MASK (0x1ff << SSI_DR_GPC_BIT)
+
+#define SSI_MAX_FIFO_ENTRIES 128 /* 128 txfifo and 128 rxfifo */
+
+/* SSI Control Register 0 (SSI_CR0) */
+
+#define SSI_CR0_SSIE (1 << 15)
+#define SSI_CR0_TIE (1 << 14)
+#define SSI_CR0_RIE (1 << 13)
+#define SSI_CR0_TEIE (1 << 12)
+#define SSI_CR0_REIE (1 << 11)
+#define SSI_CR0_LOOP (1 << 10)
+#define SSI_CR0_RFINE (1 << 9)
+#define SSI_CR0_RFINC (1 << 8)
+#define SSI_CR0_EACLRUN (1 << 7) /* hardware auto clear underrun when TxFifo no empty */
+#define SSI_CR0_FSEL (1 << 6)
+#define SSI_CR0_TFLUSH (1 << 2)
+#define SSI_CR0_RFLUSH (1 << 1)
+#define SSI_CR0_DISREV (1 << 0)
+
+/* SSI Control Register 1 (SSI_CR1) */
+
+#define SSI_CR1_FRMHL_BIT 30
+#define SSI_CR1_FRMHL_MASK (0x3 << SSI_CR1_FRMHL_BIT)
+ #define SSI_CR1_FRMHL_CELOW_CE2LOW (0 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is low valid */
+ #define SSI_CR1_FRMHL_CEHIGH_CE2LOW (1 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is low valid */
+ #define SSI_CR1_FRMHL_CELOW_CE2HIGH (2 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is low valid and SSI_CE2_ is high valid */
+ #define SSI_CR1_FRMHL_CEHIGH_CE2HIGH (3 << SSI_CR1_FRMHL_BIT) /* SSI_CE_ is high valid and SSI_CE2_ is high valid */
+#define SSI_CR1_TFVCK_BIT 28
+#define SSI_CR1_TFVCK_MASK (0x3 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_0 (0 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_1 (1 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_2 (2 << SSI_CR1_TFVCK_BIT)
+ #define SSI_CR1_TFVCK_3 (3 << SSI_CR1_TFVCK_BIT)
+#define SSI_CR1_TCKFI_BIT 26
+#define SSI_CR1_TCKFI_MASK (0x3 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_0 (0 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_1 (1 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_2 (2 << SSI_CR1_TCKFI_BIT)
+ #define SSI_CR1_TCKFI_3 (3 << SSI_CR1_TCKFI_BIT)
+#define SSI_CR1_LFST (1 << 25)
+#define SSI_CR1_ITFRM (1 << 24)
+#define SSI_CR1_UNFIN (1 << 23)
+#define SSI_CR1_MULTS (1 << 22)
+#define SSI_CR1_FMAT_BIT 20
+#define SSI_CR1_FMAT_MASK (0x3 << SSI_CR1_FMAT_BIT)
+ #define SSI_CR1_FMAT_SPI (0 << SSI_CR1_FMAT_BIT) /* Motorola¡¯s SPI format */
+ #define SSI_CR1_FMAT_SSP (1 << SSI_CR1_FMAT_BIT) /* TI's SSP format */
+ #define SSI_CR1_FMAT_MW1 (2 << SSI_CR1_FMAT_BIT) /* National Microwire 1 format */
+ #define SSI_CR1_FMAT_MW2 (3 << SSI_CR1_FMAT_BIT) /* National Microwire 2 format */
+#define SSI_CR1_TTRG_BIT 16 /* SSI1 TX trigger */
+#define SSI_CR1_TTRG_MASK (0xf << SSI_CR1_TTRG_BIT)
+#define SSI_CR1_MCOM_BIT 12
+#define SSI_CR1_MCOM_MASK (0xf << SSI_CR1_MCOM_BIT)
+ #define SSI_CR1_MCOM_1BIT (0x0 << SSI_CR1_MCOM_BIT) /* 1-bit command selected */
+ #define SSI_CR1_MCOM_2BIT (0x1 << SSI_CR1_MCOM_BIT) /* 2-bit command selected */
+ #define SSI_CR1_MCOM_3BIT (0x2 << SSI_CR1_MCOM_BIT) /* 3-bit command selected */
+ #define SSI_CR1_MCOM_4BIT (0x3 << SSI_CR1_MCOM_BIT) /* 4-bit command selected */
+ #define SSI_CR1_MCOM_5BIT (0x4 << SSI_CR1_MCOM_BIT) /* 5-bit command selected */
+ #define SSI_CR1_MCOM_6BIT (0x5 << SSI_CR1_MCOM_BIT) /* 6-bit command selected */
+ #define SSI_CR1_MCOM_7BIT (0x6 << SSI_CR1_MCOM_BIT) /* 7-bit command selected */
+ #define SSI_CR1_MCOM_8BIT (0x7 << SSI_CR1_MCOM_BIT) /* 8-bit command selected */
+ #define SSI_CR1_MCOM_9BIT (0x8 << SSI_CR1_MCOM_BIT) /* 9-bit command selected */
+ #define SSI_CR1_MCOM_10BIT (0x9 << SSI_CR1_MCOM_BIT) /* 10-bit command selected */
+ #define SSI_CR1_MCOM_11BIT (0xA << SSI_CR1_MCOM_BIT) /* 11-bit command selected */
+ #define SSI_CR1_MCOM_12BIT (0xB << SSI_CR1_MCOM_BIT) /* 12-bit command selected */
+ #define SSI_CR1_MCOM_13BIT (0xC << SSI_CR1_MCOM_BIT) /* 13-bit command selected */
+ #define SSI_CR1_MCOM_14BIT (0xD << SSI_CR1_MCOM_BIT) /* 14-bit command selected */
+ #define SSI_CR1_MCOM_15BIT (0xE << SSI_CR1_MCOM_BIT) /* 15-bit command selected */
+ #define SSI_CR1_MCOM_16BIT (0xF << SSI_CR1_MCOM_BIT) /* 16-bit command selected */
+#define SSI_CR1_RTRG_BIT 8 /* SSI RX trigger */
+#define SSI_CR1_RTRG_MASK (0xf << SSI_CR1_RTRG_BIT)
+#define SSI_CR1_FLEN_BIT 4
+#define SSI_CR1_FLEN_MASK (0xf << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_2BIT (0x0 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_3BIT (0x1 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_4BIT (0x2 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_5BIT (0x3 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_6BIT (0x4 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_7BIT (0x5 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_8BIT (0x6 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_9BIT (0x7 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_10BIT (0x8 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_11BIT (0x9 << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_12BIT (0xA << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_13BIT (0xB << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_14BIT (0xC << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_15BIT (0xD << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_16BIT (0xE << SSI_CR1_FLEN_BIT)
+ #define SSI_CR1_FLEN_17BIT (0xF << SSI_CR1_FLEN_BIT)
+#define SSI_CR1_PHA (1 << 1)
+#define SSI_CR1_POL (1 << 0)
+
+/* SSI Status Register (SSI_SR) */
+
+#define SSI_SR_TFIFONUM_BIT 16
+#define SSI_SR_TFIFONUM_MASK (0xff << SSI_SR_TFIFONUM_BIT)
+#define SSI_SR_RFIFONUM_BIT 8
+#define SSI_SR_RFIFONUM_MASK (0xff << SSI_SR_RFIFONUM_BIT)
+#define SSI_SR_END (1 << 7)
+#define SSI_SR_BUSY (1 << 6)
+#define SSI_SR_TFF (1 << 5)
+#define SSI_SR_RFE (1 << 4)
+#define SSI_SR_TFHE (1 << 3)
+#define SSI_SR_RFHF (1 << 2)
+#define SSI_SR_UNDR (1 << 1)
+#define SSI_SR_OVER (1 << 0)
+
+/* SSI Interval Time Control Register (SSI_ITR) */
+
+#define SSI_ITR_CNTCLK (1 << 15)
+#define SSI_ITR_IVLTM_BIT 0
+#define SSI_ITR_IVLTM_MASK (0x7fff << SSI_ITR_IVLTM_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * SSI (Synchronous Serial Interface)
+ ***************************************************************************/
+/* n = 0, 1 (SSI0, SSI1) */
+#define __ssi_enable(n) ( REG_SSI_CR0(n) |= SSI_CR0_SSIE )
+#define __ssi_disable(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_SSIE )
+#define __ssi_select_ce(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_FSEL )
+
+#define __ssi_normal_mode(n) ( REG_SSI_ITR(n) &= ~SSI_ITR_IVLTM_MASK )
+
+#define __ssi_select_ce2(n) \
+do { \
+ REG_SSI_CR0(n) |= SSI_CR0_FSEL; \
+ REG_SSI_CR1(n) &= ~SSI_CR1_MULTS; \
+} while (0)
+
+#define __ssi_select_gpc(n) \
+do { \
+ REG_SSI_CR0(n) &= ~SSI_CR0_FSEL; \
+ REG_SSI_CR1(n) |= SSI_CR1_MULTS; \
+} while (0)
+
+#define __ssi_underrun_auto_clear(n) \
+do { \
+ REG_SSI_CR0(n) |= SSI_CR0_EACLRUN; \
+} while (0)
+
+#define __ssi_underrun_clear_manually(n) \
+do { \
+ REG_SSI_CR0(n) &= ~SSI_CR0_EACLRUN; \
+} while (0)
+
+#define __ssi_enable_tx_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TIE | SSI_CR0_TEIE )
+
+#define __ssi_disable_tx_intr(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_TIE | SSI_CR0_TEIE) )
+
+#define __ssi_enable_rx_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_RIE | SSI_CR0_REIE )
+
+#define __ssi_disable_rx_intr(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_RIE | SSI_CR0_REIE) )
+
+#define __ssi_enable_txfifo_half_empty_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TIE )
+#define __ssi_disable_txfifo_half_empty_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_TIE )
+#define __ssi_enable_tx_error_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TEIE )
+#define __ssi_disable_tx_error_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_TEIE )
+#define __ssi_enable_rxfifo_half_full_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_RIE )
+#define __ssi_disable_rxfifo_half_full_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_RIE )
+#define __ssi_enable_rx_error_intr(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_REIE )
+#define __ssi_disable_rx_error_intr(n) \
+ ( REG_SSI_CR0(n) &= ~SSI_CR0_REIE )
+
+#define __ssi_enable_loopback(n) ( REG_SSI_CR0(n) |= SSI_CR0_LOOP )
+#define __ssi_disable_loopback(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_LOOP )
+
+#define __ssi_enable_receive(n) ( REG_SSI_CR0(n) &= ~SSI_CR0_DISREV )
+#define __ssi_disable_receive(n) ( REG_SSI_CR0(n) |= SSI_CR0_DISREV )
+
+#define __ssi_finish_receive(n) \
+ ( REG_SSI_CR0(n) |= (SSI_CR0_RFINE | SSI_CR0_RFINC) )
+
+#define __ssi_disable_recvfinish(n) \
+ ( REG_SSI_CR0(n) &= ~(SSI_CR0_RFINE | SSI_CR0_RFINC) )
+
+#define __ssi_flush_txfifo(n) ( REG_SSI_CR0(n) |= SSI_CR0_TFLUSH )
+#define __ssi_flush_rxfifo(n) ( REG_SSI_CR0(n) |= SSI_CR0_RFLUSH )
+
+#define __ssi_flush_fifo(n) \
+ ( REG_SSI_CR0(n) |= SSI_CR0_TFLUSH | SSI_CR0_RFLUSH )
+
+#define __ssi_finish_transmit(n) ( REG_SSI_CR1(n) &= ~SSI_CR1_UNFIN )
+#define __ssi_wait_transmit(n) ( REG_SSI_CR1(n) |= SSI_CR1_UNFIN )
+#define __ssi_use_busy_wait_mode(n) __ssi_wait_transmit(n)
+#define __ssi_unset_busy_wait_mode(n) __ssi_finish_transmit(n)
+
+#define __ssi_spi_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_FMAT_MASK; \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_SPI; \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK); \
+ REG_SSI_CR1(n) |= (SSI_CR1_TFVCK_1 | SSI_CR1_TCKFI_1); \
+ } while (0)
+
+/* TI's SSP format, must clear SSI_CR1.UNFIN */
+#define __ssi_ssp_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_FMAT_MASK | SSI_CR1_UNFIN); \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_SSP; \
+ } while (0)
+
+/* National's Microwire format, must clear SSI_CR0.RFINE, and set max delay */
+#define __ssi_microwire_format(n) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_FMAT_MASK; \
+ REG_SSI_CR1(n) |= SSI_CR1_FMAT_MW1; \
+ REG_SSI_CR1(n) &= ~(SSI_CR1_TFVCK_MASK|SSI_CR1_TCKFI_MASK); \
+ REG_SSI_CR1(n) |= (SSI_CR1_TFVCK_3 | SSI_CR1_TCKFI_3); \
+ REG_SSI_CR0(n) &= ~SSI_CR0_RFINE; \
+ } while (0)
+
+/* CE# level (FRMHL), CE# in interval time (ITFRM),
+ clock phase and polarity (PHA POL),
+ interval time (SSIITR), interval characters/frame (SSIICR) */
+
+/* frmhl,endian,mcom,flen,pha,pol MASK */
+#define SSICR1_MISC_MASK \
+ ( SSI_CR1_FRMHL_MASK | SSI_CR1_LFST | SSI_CR1_MCOM_MASK \
+ | SSI_CR1_FLEN_MASK | SSI_CR1_PHA | SSI_CR1_POL )
+
+#define __ssi_spi_set_misc(n,frmhl,endian,flen,mcom,pha,pol) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSICR1_MISC_MASK; \
+ REG_SSI_CR1(n) |= ((frmhl) << 30) | ((endian) << 25) | \
+ (((mcom) - 1) << 12) | (((flen) - 2) << 4) | \
+ ((pha) << 1) | (pol); \
+ } while(0)
+
+/* Transfer with MSB or LSB first */
+#define __ssi_set_msb(n) ( REG_SSI_CR1(n) &= ~SSI_CR1_LFST )
+#define __ssi_set_lsb(n) ( REG_SSI_CR1(n) |= SSI_CR1_LFST )
+
+#define __ssi_set_frame_length(n, m) \
+ REG_SSI_CR1(n) = (REG_SSI_CR1(n) & ~SSI_CR1_FLEN_MASK) | (((m) - 2) << 4)
+
+/* m = 1 - 16 */
+#define __ssi_set_microwire_command_length(n,m) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_MCOM_MASK) | SSI_CR1_MCOM_##m##BIT) )
+
+/* Set the clock phase for SPI */
+#define __ssi_set_spi_clock_phase(n, m) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_PHA) | (((m)&0x1)<< 1)))
+
+/* Set the clock polarity for SPI */
+#define __ssi_set_spi_clock_polarity(n, p) \
+ ( REG_SSI_CR1(n) = ((REG_SSI_CR1(n) & ~SSI_CR1_POL) | ((p)&0x1)) )
+
+/* SSI tx trigger, m = i x 8 */
+#define __ssi_set_tx_trigger(n, m) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_TTRG_MASK; \
+ REG_SSI_CR1(n) |= ((m)/8)<<SSI_CR1_TTRG_BIT; \
+ } while (0)
+
+/* SSI rx trigger, m = i x 8 */
+#define __ssi_set_rx_trigger(n, m) \
+ do { \
+ REG_SSI_CR1(n) &= ~SSI_CR1_RTRG_MASK; \
+ REG_SSI_CR1(n) |= ((m)/8)<<SSI_CR1_RTRG_BIT; \
+ } while (0)
+
+#define __ssi_get_txfifo_count(n) \
+ ( (REG_SSI_SR(n) & SSI_SR_TFIFONUM_MASK) >> SSI_SR_TFIFONUM_BIT )
+
+#define __ssi_get_rxfifo_count(n) \
+ ( (REG_SSI_SR(n) & SSI_SR_RFIFONUM_MASK) >> SSI_SR_RFIFONUM_BIT )
+
+#define __ssi_transfer_end(n) ( REG_SSI_SR(n) & SSI_SR_END )
+#define __ssi_is_busy(n) ( REG_SSI_SR(n) & SSI_SR_BUSY )
+
+#define __ssi_txfifo_full(n) ( REG_SSI_SR(n) & SSI_SR_TFF )
+#define __ssi_rxfifo_empty(n) ( REG_SSI_SR(n) & SSI_SR_RFE )
+#define __ssi_rxfifo_half_full(n) ( REG_SSI_SR(n) & SSI_SR_RFHF )
+#define __ssi_txfifo_half_empty(n) ( REG_SSI_SR(n) & SSI_SR_TFHE )
+#define __ssi_underrun(n) ( REG_SSI_SR(n) & SSI_SR_UNDR )
+#define __ssi_overrun(n) ( REG_SSI_SR(n) & SSI_SR_OVER )
+#define __ssi_clear_underrun(n) ( REG_SSI_SR(n) = ~SSI_SR_UNDR )
+#define __ssi_clear_overrun(n) ( REG_SSI_SR(n) = ~SSI_SR_OVER )
+#define __ssi_clear_errors(n) ( REG_SSI_SR(n) &= ~(SSI_SR_UNDR | SSI_SR_OVER) )
+
+#define __ssi_set_clk(n, dev_clk, ssi_clk) \
+ ( REG_SSI_GR(n) = (dev_clk) / (2*(ssi_clk)) - 1 )
+
+#define __ssi_receive_data(n) REG_SSI_DR(n)
+#define __ssi_transmit_data(n, v) (REG_SSI_DR(n) = (v))
+
+
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810SSI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810tcu.h b/arch/mips/include/asm/mach-jz4810/jz4810tcu.h
new file mode 100644
index 00000000000..92ca9eb1dcf
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810tcu.h
@@ -0,0 +1,427 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810tcu.h
+ *
+ * JZ4810 tcu register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810TCU_H__
+#define __JZ4810TCU_H__
+
+
+#define TCU_BASE 0xB0002000
+
+
+/*************************************************************************
+ * TCU (Timer Counter Unit)
+ *************************************************************************/
+#define TCU_TSTR (TCU_BASE + 0xF0) /* Timer Status Register,Only Used In Tcu2 Mode */
+#define TCU_TSTSR (TCU_BASE + 0xF4) /* Timer Status Set Register */
+#define TCU_TSTCR (TCU_BASE + 0xF8) /* Timer Status Clear Register */
+#define TCU_TSR (TCU_BASE + 0x1C) /* Timer Stop Register */
+#define TCU_TSSR (TCU_BASE + 0x2C) /* Timer Stop Set Register */
+#define TCU_TSCR (TCU_BASE + 0x3C) /* Timer Stop Clear Register */
+#define TCU_TER (TCU_BASE + 0x10) /* Timer Counter Enable Register */
+#define TCU_TESR (TCU_BASE + 0x14) /* Timer Counter Enable Set Register */
+#define TCU_TECR (TCU_BASE + 0x18) /* Timer Counter Enable Clear Register */
+#define TCU_TFR (TCU_BASE + 0x20) /* Timer Flag Register */
+#define TCU_TFSR (TCU_BASE + 0x24) /* Timer Flag Set Register */
+#define TCU_TFCR (TCU_BASE + 0x28) /* Timer Flag Clear Register */
+#define TCU_TMR (TCU_BASE + 0x30) /* Timer Mask Register */
+#define TCU_TMSR (TCU_BASE + 0x34) /* Timer Mask Set Register */
+#define TCU_TMCR (TCU_BASE + 0x38) /* Timer Mask Clear Register */
+
+#define TCU_TDFR0 (TCU_BASE + 0x40) /* Timer Data Full Register */
+#define TCU_TDHR0 (TCU_BASE + 0x44) /* Timer Data Half Register */
+#define TCU_TCNT0 (TCU_BASE + 0x48) /* Timer Counter Register */
+#define TCU_TCSR0 (TCU_BASE + 0x4C) /* Timer Control Register */
+#define TCU_TDFR1 (TCU_BASE + 0x50)
+#define TCU_TDHR1 (TCU_BASE + 0x54)
+#define TCU_TCNT1 (TCU_BASE + 0x58)
+#define TCU_TCSR1 (TCU_BASE + 0x5C)
+#define TCU_TDFR2 (TCU_BASE + 0x60)
+#define TCU_TDHR2 (TCU_BASE + 0x64)
+#define TCU_TCNT2 (TCU_BASE + 0x68)
+#define TCU_TCSR2 (TCU_BASE + 0x6C)
+#define TCU_TDFR3 (TCU_BASE + 0x70)
+#define TCU_TDHR3 (TCU_BASE + 0x74)
+#define TCU_TCNT3 (TCU_BASE + 0x78)
+#define TCU_TCSR3 (TCU_BASE + 0x7C)
+#define TCU_TDFR4 (TCU_BASE + 0x80)
+#define TCU_TDHR4 (TCU_BASE + 0x84)
+#define TCU_TCNT4 (TCU_BASE + 0x88)
+#define TCU_TCSR4 (TCU_BASE + 0x8C)
+#define TCU_TDFR5 (TCU_BASE + 0x90)
+#define TCU_TDHR5 (TCU_BASE + 0x94)
+#define TCU_TCNT5 (TCU_BASE + 0x98)
+#define TCU_TCSR5 (TCU_BASE + 0x9C)
+
+#define REG_TCU_TSTR REG32(TCU_TSTR)
+#define REG_TCU_TSTSR REG32(TCU_TSTSR)
+#define REG_TCU_TSTCR REG32(TCU_TSTCR)
+#define REG_TCU_TSR REG32(TCU_TSR)
+#define REG_TCU_TSSR REG32(TCU_TSSR)
+#define REG_TCU_TSCR REG32(TCU_TSCR)
+#define REG_TCU_TER REG16(TCU_TER)
+#define REG_TCU_TESR REG32(TCU_TESR)
+#define REG_TCU_TECR REG32(TCU_TECR)
+#define REG_TCU_TFR REG32(TCU_TFR)
+#define REG_TCU_TFSR REG32(TCU_TFSR)
+#define REG_TCU_TFCR REG32(TCU_TFCR)
+#define REG_TCU_TMR REG32(TCU_TMR)
+#define REG_TCU_TMSR REG32(TCU_TMSR)
+#define REG_TCU_TMCR REG32(TCU_TMCR)
+#define REG_TCU_TDFR0 REG16(TCU_TDFR0)
+#define REG_TCU_TDHR0 REG16(TCU_TDHR0)
+#define REG_TCU_TCNT0 REG16(TCU_TCNT0)
+#define REG_TCU_TCSR0 REG16(TCU_TCSR0)
+#define REG_TCU_TDFR1 REG16(TCU_TDFR1)
+#define REG_TCU_TDHR1 REG16(TCU_TDHR1)
+#define REG_TCU_TCNT1 REG16(TCU_TCNT1)
+#define REG_TCU_TCSR1 REG16(TCU_TCSR1)
+#define REG_TCU_TDFR2 REG16(TCU_TDFR2)
+#define REG_TCU_TDHR2 REG16(TCU_TDHR2)
+#define REG_TCU_TCNT2 REG16(TCU_TCNT2)
+#define REG_TCU_TCSR2 REG16(TCU_TCSR2)
+#define REG_TCU_TDFR3 REG16(TCU_TDFR3)
+#define REG_TCU_TDHR3 REG16(TCU_TDHR3)
+#define REG_TCU_TCNT3 REG16(TCU_TCNT3)
+#define REG_TCU_TCSR3 REG16(TCU_TCSR3)
+#define REG_TCU_TDFR4 REG16(TCU_TDFR4)
+#define REG_TCU_TDHR4 REG16(TCU_TDHR4)
+#define REG_TCU_TCNT4 REG16(TCU_TCNT4)
+#define REG_TCU_TCSR4 REG16(TCU_TCSR4)
+
+// n = 0,1,2,3,4,5
+#define TCU_TDFR(n) (TCU_BASE + (0x40 + (n)*0x10)) /* Timer Data Full Reg */
+#define TCU_TDHR(n) (TCU_BASE + (0x44 + (n)*0x10)) /* Timer Data Half Reg */
+#define TCU_TCNT(n) (TCU_BASE + (0x48 + (n)*0x10)) /* Timer Counter Reg */
+#define TCU_TCSR(n) (TCU_BASE + (0x4C + (n)*0x10)) /* Timer Control Reg */
+#define TCU_OSTDR (TCU_BASE + 0xe0) /* Operating System Timer Data Reg */
+#define TCU_OSTCNT (TCU_BASE + 0xe8) /* Operating System Timer Counter Reg */
+#define TCU_OSTCSR (TCU_BASE + 0xeC) /* Operating System Timer Control Reg */
+
+#define REG_TCU_TDFR(n) REG16(TCU_TDFR((n)))
+#define REG_TCU_TDHR(n) REG16(TCU_TDHR((n)))
+#define REG_TCU_TCNT(n) REG16(TCU_TCNT((n)))
+#define REG_TCU_TCSR(n) REG16(TCU_TCSR((n)))
+#define REG_TCU_OSTDR REG32(TCU_OSTDR)
+#define REG_TCU_OSTCNT REG32(TCU_OSTCNT)
+#define REG_TCU_OSTCSR REG32(TCU_OSTCSR)
+
+// Register definitions
+#define TCU_TSTR_REAL2 (1 << 18) /* only used in TCU2 mode */
+#define TCU_TSTR_REAL1 (1 << 17) /* only used in TCU2 mode */
+#define TCU_TSTR_BUSY2 (1 << 2) /* only used in TCU2 mode */
+#define TCU_TSTR_BUSY1 (1 << 1) /* only used in TCU2 mode */
+
+#define TCU_TSTSR_REAL2 (1 << 18)
+#define TCU_TSTSR_REAL1 (1 << 17)
+#define TCU_TSTSR_BUSY2 (1 << 2)
+#define TCU_TSTSR_BUSY1 (1 << 1)
+
+#define TCU_TSTCR_REAL2 (1 << 18)
+#define TCU_TSTCR_REAL1 (1 << 17)
+#define TCU_TSTCR_BUSY2 (1 << 2)
+#define TCU_TSTCR_BUSY1 (1 << 1)
+
+#define TCU_TSR_WDTS (1 << 16) /*the clock supplies to wdt is stopped */
+#define TCU_TSR_OSTS (1 << 15) /*the clock supplies to osts is stopped */
+#define TCU_TSR_STOP5 (1 << 5) /*the clock supplies to timer5 is stopped */
+#define TCU_TSR_STOP4 (1 << 4) /*the clock supplies to timer4 is stopped */
+#define TCU_TSR_STOP3 (1 << 3) /*the clock supplies to timer3 is stopped */
+#define TCU_TSR_STOP2 (1 << 2) /*the clock supplies to timer2 is stopped */
+#define TCU_TSR_STOP1 (1 << 1) /*the clock supplies to timer1 is stopped */
+#define TCU_TSR_STOP0 (1 << 0) /*the clock supplies to timer0 is stopped */
+
+#define TCU_TSSR_WDTSS (1 << 16)
+#define TCU_TSSR_OSTSS (1 << 15)
+#define TCU_TSSR_STPS5 (1 << 5)
+#define TCU_TSSR_STPS4 (1 << 4)
+#define TCU_TSSR_STPS3 (1 << 3)
+#define TCU_TSSR_STPS2 (1 << 2)
+#define TCU_TSSR_STPS1 (1 << 1)
+#define TCU_TSSR_STPS0 (1 << 0)
+
+#define TCU_TSCR_WDTSC (1 << 16)
+#define TCU_TSCR_OSTSC (1 << 15)
+#define TCU_TSCR_STPC5 (1 << 5)
+#define TCU_TSCR_STPC4 (1 << 4)
+#define TCU_TSCR_STPC3 (1 << 3)
+#define TCU_TSCR_STPC2 (1 << 2)
+#define TCU_TSCR_STPC1 (1 << 1)
+#define TCU_TSCR_STPC0 (1 << 0)
+
+#define TCU_TER_OSTEN (1 << 15) /* enable the counter in ost */
+#define TCU_TER_TCEN5 (1 << 5) /* enable the counter in timer5 */
+#define TCU_TER_TCEN4 (1 << 4)
+#define TCU_TER_TCEN3 (1 << 3)
+#define TCU_TER_TCEN2 (1 << 2)
+#define TCU_TER_TCEN1 (1 << 1)
+#define TCU_TER_TCEN0 (1 << 0)
+
+#define TCU_TESR_OSTST (1 << 15)
+#define TCU_TESR_TCST5 (1 << 5)
+#define TCU_TESR_TCST4 (1 << 4)
+#define TCU_TESR_TCST3 (1 << 3)
+#define TCU_TESR_TCST2 (1 << 2)
+#define TCU_TESR_TCST1 (1 << 1)
+#define TCU_TESR_TCST0 (1 << 0)
+
+#define TCU_TECR_OSTCL (1 << 15)
+#define TCU_TECR_TCCL5 (1 << 5)
+#define TCU_TECR_TCCL4 (1 << 4)
+#define TCU_TECR_TCCL3 (1 << 3)
+#define TCU_TECR_TCCL2 (1 << 2)
+#define TCU_TECR_TCCL1 (1 << 1)
+#define TCU_TECR_TCCL0 (1 << 0)
+
+#define TCU_TFR_HFLAG5 (1 << 21) /* half comparison match flag */
+#define TCU_TFR_HFLAG4 (1 << 20)
+#define TCU_TFR_HFLAG3 (1 << 19)
+#define TCU_TFR_HFLAG2 (1 << 18)
+#define TCU_TFR_HFLAG1 (1 << 17)
+#define TCU_TFR_HFLAG0 (1 << 16)
+#define TCU_TFR_OSTFLAG (1 << 15) /* ost comparison match flag */
+#define TCU_TFR_FFLAG5 (1 << 5) /* full comparison match flag */
+#define TCU_TFR_FFLAG4 (1 << 4)
+#define TCU_TFR_FFLAG3 (1 << 3)
+#define TCU_TFR_FFLAG2 (1 << 2)
+#define TCU_TFR_FFLAG1 (1 << 1)
+#define TCU_TFR_FFLAG0 (1 << 0)
+
+#define TCU_TFSR_HFST5 (1 << 21)
+#define TCU_TFSR_HFST4 (1 << 20)
+#define TCU_TFSR_HFST3 (1 << 19)
+#define TCU_TFSR_HFST2 (1 << 18)
+#define TCU_TFSR_HFST1 (1 << 17)
+#define TCU_TFSR_HFST0 (1 << 16)
+#define TCU_TFSR_OSTFST (1 << 15)
+#define TCU_TFSR_FFST5 (1 << 5)
+#define TCU_TFSR_FFST4 (1 << 4)
+#define TCU_TFSR_FFST3 (1 << 3)
+#define TCU_TFSR_FFST2 (1 << 2)
+#define TCU_TFSR_FFST1 (1 << 1)
+#define TCU_TFSR_FFST0 (1 << 0)
+
+#define TCU_TFCR_HFCL5 (1 << 21)
+#define TCU_TFCR_HFCL4 (1 << 20)
+#define TCU_TFCR_HFCL3 (1 << 19)
+#define TCU_TFCR_HFCL2 (1 << 18)
+#define TCU_TFCR_HFCL1 (1 << 17)
+#define TCU_TFCR_HFCL0 (1 << 16)
+#define TCU_TFCR_OSTFCL (1 << 15)
+#define TCU_TFCR_FFCL5 (1 << 5)
+#define TCU_TFCR_FFCL4 (1 << 4)
+#define TCU_TFCR_FFCL3 (1 << 3)
+#define TCU_TFCR_FFCL2 (1 << 2)
+#define TCU_TFCR_FFCL1 (1 << 1)
+#define TCU_TFCR_FFCL0 (1 << 0)
+
+#define TCU_TMR_HMASK5 (1 << 21) /* half comparison match interrupt mask */
+#define TCU_TMR_HMASK4 (1 << 20)
+#define TCU_TMR_HMASK3 (1 << 19)
+#define TCU_TMR_HMASK2 (1 << 18)
+#define TCU_TMR_HMASK1 (1 << 17)
+#define TCU_TMR_HMASK0 (1 << 16)
+#define TCU_TMR_OSTMASK (1 << 15) /* ost comparison match interrupt mask */
+#define TCU_TMR_FMASK5 (1 << 5) /* full comparison match interrupt mask */
+#define TCU_TMR_FMASK4 (1 << 4)
+#define TCU_TMR_FMASK3 (1 << 3)
+#define TCU_TMR_FMASK2 (1 << 2)
+#define TCU_TMR_FMASK1 (1 << 1)
+#define TCU_TMR_FMASK0 (1 << 0)
+
+#define TCU_TMSR_HMST5 (1 << 21)
+#define TCU_TMSR_HMST4 (1 << 20)
+#define TCU_TMSR_HMST3 (1 << 19)
+#define TCU_TMSR_HMST2 (1 << 18)
+#define TCU_TMSR_HMST1 (1 << 17)
+#define TCU_TMSR_HMST0 (1 << 16)
+#define TCU_TMSR_OSTMST (1 << 15)
+#define TCU_TMSR_FMST5 (1 << 5)
+#define TCU_TMSR_FMST4 (1 << 4)
+#define TCU_TMSR_FMST3 (1 << 3)
+#define TCU_TMSR_FMST2 (1 << 2)
+#define TCU_TMSR_FMST1 (1 << 1)
+#define TCU_TMSR_FMST0 (1 << 0)
+
+#define TCU_TMCR_HMCL5 (1 << 21)
+#define TCU_TMCR_HMCL4 (1 << 20)
+#define TCU_TMCR_HMCL3 (1 << 19)
+#define TCU_TMCR_HMCL2 (1 << 18)
+#define TCU_TMCR_HMCL1 (1 << 17)
+#define TCU_TMCR_HMCL0 (1 << 16)
+#define TCU_TMCR_OSTMCL (1 << 15)
+#define TCU_TMCR_FMCL5 (1 << 5)
+#define TCU_TMCR_FMCL4 (1 << 4)
+#define TCU_TMCR_FMCL3 (1 << 3)
+#define TCU_TMCR_FMCL2 (1 << 2)
+#define TCU_TMCR_FMCL1 (1 << 1)
+#define TCU_TMCR_FMCL0 (1 << 0)
+
+#define TCU_TCSR_CNT_CLRZ (1 << 10) /* clear counter to 0, only used in TCU2 mode */
+#define TCU_TCSR_PWM_SD (1 << 9) /* shut down the pwm output only used in TCU1 mode */
+#define TCU_TCSR_PWM_INITL_HIGH (1 << 8) /* selects an initial output level for pwm output */
+#define TCU_TCSR_PWM_EN (1 << 7) /* pwm pin output enable */
+#define TCU_TCSR_PRESCALE_BIT 3 /* select the tcnt count clock frequency*/
+#define TCU_TCSR_PRESCALE_MASK (0x7 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE1 (0x0 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE4 (0x1 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE16 (0x2 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE64 (0x3 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE256 (0x4 << TCU_TCSR_PRESCALE_BIT)
+ #define TCU_TCSR_PRESCALE1024 (0x5 << TCU_TCSR_PRESCALE_BIT)
+#define TCU_TCSR_EXT_EN (1 << 2) /* select extal as the timer clock input */
+#define TCU_TCSR_RTC_EN (1 << 1) /* select rtcclk as the timer clock input */
+#define TCU_TCSR_PCK_EN (1 << 0) /* select pclk as the timer clock input */
+
+#define TCU_TSTR_REAL2 (1 << 18) /* the value read from counter 2 is a real value */
+#define TCU_TSTR_REAL1 (1 << 17)
+#define TCU_TSTR_BUSY2 (1 << 2) /* the counter 2 is busy now */
+#define TCU_TSTR_BUSY1 (1 << 1)
+
+#define TCU_TSTSR_REALS2 (1 << 18)
+#define TCU_TSTSR_REALS1 (1 << 17)
+#define TCU_TSTSR_BUSYS2 (1 << 2)
+#define TCU_TSTSR_BUSYS1 (1 << 1)
+
+#define TCU_TSTCR_REALC2 (1 << 18)
+#define TCU_TSTCR_REALC1 (1 << 17)
+#define TCU_TSTCR_BUSYC2 (1 << 2)
+#define TCU_TSTCR_BUSYC1 (1 << 1)
+
+#define TCU_OSTCR_CNT_MD (1 << 15) /* when the value counter is equal to compare value,the counter is go on increasing till overflow,and then icrease from 0 */
+#define TCU_OSTCR_PWM_SD (1 << 9) /* shut down the pwm output, only used in TCU1 mode */
+#define TCU_OSTCSR_PRESCALE_BIT 3
+#define TCU_OSTCSR_PRESCALE_MASK (0x7 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE1 (0x0 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE4 (0x1 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE16 (0x2 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE64 (0x3 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE256 (0x4 << TCU_OSTCSR_PRESCALE_BIT)
+ #define TCU_OSTCSR_PRESCALE1024 (0x5 << TCU_OSTCSR_PRESCALE_BIT)
+#define TCU_OSTCSR_EXT_EN (1 << 2) /* select extal as the timer clock input */
+#define TCU_OSTCSR_RTC_EN (1 << 1) /* select rtcclk as the timer clock input */
+#define TCU_OSTCSR_PCK_EN (1 << 0) /* select pclk as the timer clock input */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * TCU
+ ***************************************************************************/
+// where 'n' is the TCU channel
+#define __tcu_select_extalclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_EXT_EN)
+#define __tcu_select_rtcclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_RTC_EN)
+#define __tcu_select_pclk(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~(TCU_TCSR_EXT_EN | TCU_TCSR_RTC_EN | TCU_TCSR_PCK_EN)) | TCU_TCSR_PCK_EN)
+#define __tcu_disable_pclk(n) \
+ REG_TCU_TCSR(n) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PCK_EN);
+#define __tcu_select_clk_div1(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1)
+#define __tcu_select_clk_div4(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE4)
+#define __tcu_select_clk_div16(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE16)
+#define __tcu_select_clk_div64(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE64)
+#define __tcu_select_clk_div256(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE256)
+#define __tcu_select_clk_div1024(n) \
+ (REG_TCU_TCSR((n)) = (REG_TCU_TCSR((n)) & ~TCU_TCSR_PRESCALE_MASK) | TCU_TCSR_PRESCALE1024)
+
+#define __tcu_enable_pwm_output(n) (REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_EN)
+#define __tcu_disable_pwm_output(n) (REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_EN)
+
+#define __tcu_init_pwm_output_high(n) (REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_INITL_HIGH)
+#define __tcu_init_pwm_output_low(n) (REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_INITL_HIGH)
+
+#define __tcu_set_pwm_output_shutdown_graceful(n) (REG_TCU_TCSR((n)) &= ~TCU_TCSR_PWM_SD)
+#define __tcu_set_pwm_output_shutdown_abrupt(n) (REG_TCU_TCSR((n)) |= TCU_TCSR_PWM_SD)
+
+#define __tcu_clear_counter_to_zero(n) (REG_TCU_TCSR((n)) |= TCU_TCSR_CNT_CLRZ)
+
+#define __tcu_ost_enabled() (REG_TCU_TER & TCU_TER_OSTEN)
+#define __tcu_enable_ost() (REG_TCU_TESR = TCU_TESR_OSTST)
+#define __tcu_disable_ost() (REG_TCU_TECR = TCU_TECR_OSTCL)
+
+#define __tcu_counter_enabled(n) (REG_TCU_TER & (1 << (n)))
+#define __tcu_start_counter(n) (REG_TCU_TESR |= (1 << (n)))
+#define __tcu_stop_counter(n) (REG_TCU_TECR |= (1 << (n)))
+
+#define __tcu_half_match_flag(n) (REG_TCU_TFR & (1 << ((n) + 16)))
+#define __tcu_full_match_flag(n) (REG_TCU_TFR & (1 << (n)))
+#define __tcu_set_half_match_flag(n) (REG_TCU_TFSR = (1 << ((n) + 16)))
+#define __tcu_set_full_match_flag(n) (REG_TCU_TFSR = (1 << (n)))
+#define __tcu_clear_half_match_flag(n) (REG_TCU_TFCR = (1 << ((n) + 16)))
+#define __tcu_clear_full_match_flag(n) (REG_TCU_TFCR = (1 << (n)))
+#define __tcu_mask_half_match_irq(n) (REG_TCU_TMSR = (1 << ((n) + 16)))
+#define __tcu_mask_full_match_irq(n) (REG_TCU_TMSR = (1 << (n)))
+#define __tcu_unmask_half_match_irq(n) (REG_TCU_TMCR = (1 << ((n) + 16)))
+#define __tcu_unmask_full_match_irq(n) (REG_TCU_TMCR = (1 << (n)))
+
+#define __tcu_ost_match_flag() (REG_TCU_TFR & TCU_TFR_OSTFLAG)
+#define __tcu_set_ost_match_flag() (REG_TCU_TFSR = TCU_TFSR_OSTFST)
+#define __tcu_clear_ost_match_flag() (REG_TCU_TFCR = TCU_TFCR_OSTFCL)
+#define __tcu_ost_match_irq_masked() (REG_TCU_TMR & TCU_TMR_OSTMASK)
+#define __tcu_mask_ost_match_irq() (REG_TCU_TMSR = TCU_TMSR_OSTMST)
+#define __tcu_unmask_ost_match_irq() (REG_TCU_TMCR = TCU_TMCR_OSTMCL)
+
+#define __tcu_wdt_clock_stopped() (REG_TCU_TSR & TCU_TSSR_WDTSC)
+#define __tcu_ost_clock_stopped() (REG_TCU_TSR & TCU_TSR_OST)
+#define __tcu_timer_clock_stopped(n) (REG_TCU_TSR & (1 << (n)))
+
+#define __tcu_start_wdt_clock() (REG_TCU_TSCR = TCU_TSSR_WDTSC)
+#define __tcu_start_ost_clock() (REG_TCU_TSCR = TCU_TSCR_OSTSC)
+#define __tcu_start_timer_clock(n) (REG_TCU_TSCR = (1 << (n)))
+
+#define __tcu_stop_wdt_clock() (REG_TCU_TSSR = TCU_TSSR_WDTSC)
+#define __tcu_stop_ost_clock() (REG_TCU_TSSR = TCU_TSSR_OSTSS)
+#define __tcu_stop_timer_clock(n) (REG_TCU_TSSR = (1 << (n)))
+
+#define __tcu_get_count(n) (REG_TCU_TCNT((n)))
+#define __tcu_set_count(n,v) (REG_TCU_TCNT((n)) = (v))
+#define __tcu_set_full_data(n,v) (REG_TCU_TDFR((n)) = (v))
+#define __tcu_set_half_data(n,v) (REG_TCU_TDHR((n)) = (v))
+
+/* TCU2, counter 1, 2*/
+#define __tcu_read_real_value(n) (REG_TCU_TSTR & (1 << ((n) + 16)))
+#define __tcu_read_false_value(n) (REG_TCU_TSTR & (1 << ((n) + 16)))
+#define __tcu_counter_busy(n) (REG_TCU_TSTR & (1 << (n)))
+#define __tcu_counter_ready(n) (REG_TCU_TSTR & (1 << (n)))
+
+#define __tcu_set_read_real_value(n) (REG_TCU_TSTSR = (1 << ((n) + 16)))
+#define __tcu_set_read_false_value(n) (REG_TCU_TSTCR = (1 << ((n) + 16)))
+#define __tcu_set_counter_busy(n) (REG_TCU_TSTSR = (1 << (n)))
+#define __tcu_set_counter_ready(n) (REG_TCU_TSTCR = (1 << (n)))
+
+/* ost counter */
+#define __ostcu_set_pwm_output_shutdown_graceful() (REG_TCU_OSTCSR &= ~TCU_TCSR_PWM_SD)
+#define __ostcu_set_ost_output_shutdown_abrupt() (REG_TCU_OSTCSR |= TCU_TCSR_PWM_SD)
+#define __ostcu_select_clk_div1() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE1)
+#define __ostcu_select_clk_div4() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE4)
+#define __ostcu_select_clk_div16() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE16)
+#define __ostcu_select_clk_div64() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE64)
+#define __ostcu_select_clk_div256() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE256)
+#define __ostcu_select_clk_div1024() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~TCU_OSTCSR_PRESCALE_MASK) | TCU_OSTCSR_PRESCALE1024)
+#define __ostcu_select_rtcclk() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~(TCU_OSTCSR_EXT_EN | TCU_OSTCSR_RTC_EN | TCU_OSTCSR_PCK_EN)) | TCU_OSTCSR_RTC_EN)
+#define __ostcu_select_extalclk() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~(TCU_OSTCSR_EXT_EN | TCU_OSTCSR_RTC_EN | TCU_OSTCSR_PCK_EN)) | TCU_OSTCSR_EXT_EN)
+#define __ostcu_select_pclk() \
+ (REG_TCU_OSTCSR = (REG_TCU_OSTCSR & ~(TCU_OSTCSR_EXT_EN | TCU_OSTCSR_RTC_EN | TCU_OSTCSR_PCK_EN)) | TCU_OSTCSR_PCK_EN)
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810TCU_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810tssi.h b/arch/mips/include/asm/mach-jz4810/jz4810tssi.h
new file mode 100644
index 00000000000..997fcf923ce
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810tssi.h
@@ -0,0 +1,225 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810tssi.h
+ *
+ * JZ4810 TSSI register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810TSSI_H__
+#define __JZ4810TSSI_H__
+
+
+#define TSSI0_BASE 0xB0073000
+
+/*************************************************************************
+ * TSSI MPEG 2-TS slave interface
+ *************************************************************************/
+#define TSSI_ENA ( TSSI0_BASE + 0x00 ) /* TSSI enable register */
+#define TSSI_CFG ( TSSI0_BASE + 0x04 ) /* TSSI configure register */
+#define TSSI_CTRL ( TSSI0_BASE + 0x08 ) /* TSSI control register */
+#define TSSI_STAT ( TSSI0_BASE + 0x0c ) /* TSSI state register */
+#define TSSI_FIFO ( TSSI0_BASE + 0x10 ) /* TSSI FIFO register */
+#define TSSI_PEN ( TSSI0_BASE + 0x14 ) /* TSSI PID enable register */
+#define TSSI_PID(n) ( TSSI0_BASE + 0x20 + 4*(n) ) /* TSSI PID filter register */
+#define TSSI_PID0 ( TSSI0_BASE + 0x20 )
+#define TSSI_PID1 ( TSSI0_BASE + 0x24 )
+#define TSSI_PID2 ( TSSI0_BASE + 0x28 )
+#define TSSI_PID3 ( TSSI0_BASE + 0x2c )
+#define TSSI_PID4 ( TSSI0_BASE + 0x30 )
+#define TSSI_PID5 ( TSSI0_BASE + 0x34 )
+#define TSSI_PID6 ( TSSI0_BASE + 0x38 )
+#define TSSI_PID7 ( TSSI0_BASE + 0x3c )
+#define TSSI_PID_MAX 8 /* max PID: 7 */
+
+#define REG_TSSI_ENA REG8( TSSI_ENA )
+#define REG_TSSI_CFG REG16( TSSI_CFG )
+#define REG_TSSI_CTRL REG8( TSSI_CTRL )
+#define REG_TSSI_STAT REG8( TSSI_STAT )
+#define REG_TSSI_FIFO REG32( TSSI_FIFO )
+#define REG_TSSI_PEN REG32( TSSI_PEN )
+#define REG_TSSI_PID(n) REG32( TSSI_PID(n) )
+#define REG_TSSI_PID0 REG32( TSSI_PID0 )
+#define REG_TSSI_PID1 REG32( TSSI_PID1 )
+#define REG_TSSI_PID2 REG32( TSSI_PID2 )
+#define REG_TSSI_PID3 REG32( TSSI_PID3 )
+#define REG_TSSI_PID4 REG32( TSSI_PID4 )
+#define REG_TSSI_PID5 REG32( TSSI_PID5 )
+#define REG_TSSI_PID6 REG32( TSSI_PID6 )
+#define REG_TSSI_PID7 REG32( TSSI_PID7 )
+
+/* TSSI enable register */
+#define TSSI_ENA_SFT_RST ( 1 << 7 ) /* soft reset bit */
+#define TSSI_ENA_PID_EN ( 1 << 2 ) /* soft filtering function enable bit */
+#define TSSI_ENA_DMA_EN ( 1 << 1 ) /* DMA enable bit */
+#define TSSI_ENA_ENA ( 1 << 0 ) /* TSSI enable bit */
+
+/* TSSI configure register */
+#define TSSI_CFG_TRIG_BIT 14 /* fifo trig number */
+#define TSSI_CFG_TRIG_MASK ( 0x3 << TSSI_CFG_TRIG_BIT)
+#define TSSI_CFG_TRIG_4 ( 0 << TSSI_CFG_TRIG_BIT)
+#define TSSI_CFG_TRIG_8 ( 1 << TSSI_CFG_TRIG_BIT)
+#define TSSI_CFG_TRIG_16 ( 2 << TSSI_CFG_TRIG_BIT)
+#define TSSI_CFG_END_WD ( 1 << 9 ) /* order of data in word */
+#define TSSI_CFG_END_BT ( 1 << 8 ) /* order of data in byte */
+#define TSSI_CFG_TSDI_H ( 1 << 7 ) /* data pin polarity */
+#define TSSI_CFG_USE_0 ( 1 << 6 ) /* serial mode data pin select */
+#define TSSI_CFG_USE_TSDI0 ( 0 << 6 ) /* TSDI0 as serial mode data pin */
+#define TSSI_CFG_USE_TSDI7 ( 1 << 6 ) /* TSDI7 as serial mode data pin */
+#define TSSI_CFG_TSCLK_CH ( 1 << 5 ) /* clk channel select */
+#define TSSI_CFG_PARAL ( 1 << 4 ) /* mode select */
+#define TSSI_CFG_PARAL_MODE ( 1 << 4 ) /* parallel select */
+#define TSSI_CFG_SERIAL_MODE ( 0 << 4 ) /* serial select */
+#define TSSI_CFG_TSCLK_P ( 1 << 3 ) /* clk edge select */
+#define TSSI_CFG_TSFRM_H ( 1 << 2 ) /* TSFRM polarity select */
+#define TSSI_CFG_TSSTR_H ( 1 << 1 ) /* TSSTR polarity select */
+#define TSSI_CFG_TSFAIL_H ( 1 << 0 ) /* TSFAIL polarity select */
+
+/* TSSI control register */
+#define TSSI_CTRL_OVRNM ( 1 << 1 ) /* FIFO overrun interrupt mask bit */
+#define TSSI_CTRL_TRIGM ( 1 << 0 ) /* FIFO trigger interrupt mask bit */
+
+/* TSSI state register */
+#define TSSI_STAT_OVRN ( 1 << 1 ) /* FIFO overrun interrupt flag bit */
+#define TSSI_STAT_TRIG ( 1 << 0 ) /* FIFO trigger interrupt flag bit */
+
+/* TSSI PID enable register */
+#define TSSI_PEN_EN00 ( 1 << 0 ) /* enable PID n */
+#define TSSI_PEN_EN10 ( 1 << 1 )
+#define TSSI_PEN_EN20 ( 1 << 2 )
+#define TSSI_PEN_EN30 ( 1 << 3 )
+#define TSSI_PEN_EN40 ( 1 << 4 )
+#define TSSI_PEN_EN50 ( 1 << 5 )
+#define TSSI_PEN_EN60 ( 1 << 6 )
+#define TSSI_PEN_EN70 ( 1 << 7 )
+#define TSSI_PEN_EN01 ( 1 << 16 )
+#define TSSI_PEN_EN11 ( 1 << 17 )
+#define TSSI_PEN_EN21 ( 1 << 18 )
+#define TSSI_PEN_EN31 ( 1 << 19 )
+#define TSSI_PEN_EN41 ( 1 << 20 )
+#define TSSI_PEN_EN51 ( 1 << 21 )
+#define TSSI_PEN_EN61 ( 1 << 22 )
+#define TSSI_PEN_EN71 ( 1 << 23 )
+#define TSSI_PEN_PID0 ( 1 << 31 ) /* PID filter enable PID0 */
+
+/* TSSI PID Filter Registers */
+#define TSSI_PID_PID1_BIT 16
+#define TSSI_PID_PID1_MASK (0x1FFF<<TSSI_PID_PID1_BIT)
+#define TSSI_PID_PID0_BIT 0
+#define TSSI_PID_PID0_MASK (0x1FFF<<TSSI_PID_PID0_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * TSSI MPEG 2-TS slave interface operation
+ *************************************************************************/
+#define __tssi_enable() ( REG_TSSI_ENA |= TSSI_ENA_ENA )
+#define __tssi_disable() ( REG_TSSI_ENA &= ~TSSI_ENA_ENA )
+#define __tssi_soft_reset() ( REG_TSSI_ENA |= TSSI_ENA_SFT_RST )
+#define __tssi_dma_enable() ( REG_TSSI_ENA |= TSSI_ENA_DMA_EN )
+#define __tssi_dma_disable() ( REG_TSSI_ENA &= ~TSSI_ENA_DMA_EN )
+#define __tssi_filter_enable() ( REG_TSSI_ENA |= TSSI_ENA_PID_EN )
+#define __tssi_filter_disable() ( REG_TSSI_ENA &= ~TSSI_ENA_PID_EN )
+
+/* n = 4, 8, 16 */
+#define __tssi_set_tigger_num(n) \
+ do { \
+ REG_TSSI_CFG &= ~TSSI_CFG_TRIG_MASK; \
+ REG_TSSI_CFG |= TSSI_CFG_TRIG_##n; \
+ } while (0)
+
+#define __tssi_set_wd_1() ( REG_TSSI_CFG |= TSSI_CFG_END_WD )
+#define __tssi_set_wd_0() ( REG_TSSI_CFG &= ~TSSI_CFG_END_WD )
+
+#define __tssi_set_bt_1() ( REG_TSSI_CFG |= TSSI_CFG_END_BD )
+#define __tssi_set_bt_0() ( REG_TSSI_CFG &= ~TSSI_CFG_END_BD )
+
+#define __tssi_set_data_pola_high() ( REG_TSSI_CFG |= TSSI_CFG_TSDI_H )
+#define __tssi_set_data_pola_low() ( REG_TSSI_CFG &= ~TSSI_CFG_TSDI_H )
+
+#define __tssi_set_data_use_data0() ( REG_TSSI_CFG |= TSSI_CFG_USE_0 )
+#define __tssi_set_data_use_data7() ( REG_TSSI_CFG &= ~TSSI_CFG_USE_0 )
+
+#define __tssi_select_clk_fast() ( REG_TSSI_CFG &= ~TSSI_CFG_TSCLK_CH )
+#define __tssi_select_clk_slow() ( REG_TSSI_CFG |= TSSI_CFG_TSCLK_CH )
+
+#define __tssi_select_serail_mode() ( REG_TSSI_CFG &= ~TSSI_CFG_PARAL )
+#define __tssi_select_paral_mode() ( REG_TSSI_CFG |= TSSI_CFG_PARAL )
+
+#define __tssi_select_clk_nega_edge() ( REG_TSSI_CFG &= ~TSSI_CFG_TSCLK_P )
+#define __tssi_select_clk_posi_edge() ( REG_TSSI_CFG |= TSSI_CFG_TSCLK_P )
+
+#define __tssi_select_frm_act_high() ( REG_TSSI_CFG |= TSSI_CFG_TSFRM_H )
+#define __tssi_select_frm_act_low() ( REG_TSSI_CFG &= ~TSSI_CFG_TSFRM_H )
+
+#define __tssi_select_str_act_high() ( REG_TSSI_CFG |= TSSI_CFG_TSSTR_H )
+#define __tssi_select_str_act_low() ( REG_TSSI_CFG &= ~TSSI_CFG_TSSTR_H )
+
+#define __tssi_select_fail_act_high() ( REG_TSSI_CFG |= TSSI_CFG_TSFAIL_H )
+#define __tssi_select_fail_act_low() ( REG_TSSI_CFG &= ~TSSI_CFG_TSFAIL_H )
+
+#define __tssi_enable_ovrn_irq() ( REG_TSSI_CTRL &= ~TSSI_CTRL_OVRNM )
+#define __tssi_disable_ovrn_irq() ( REG_TSSI_CTRL |= TSSI_CTRL_OVRNM )
+
+#define __tssi_enable_trig_irq() ( REG_TSSI_CTRL &= ~TSSI_CTRL_TRIGM )
+#define __tssi_disable_trig_irq() ( REG_TSSI_CTRL |= TSSI_CTRL_TRIGM )
+
+#define __tssi_state_is_overrun() ( REG_TSSI_STAT & TSSI_STAT_OVRN )
+#define __tssi_state_trigger_meet() ( REG_TSSI_STAT & TSSI_STAT_TRIG )
+#define __tssi_clear_state() ( REG_TSSI_STAT = 0 ) /* write 0??? */
+#define __tssi_state_clear_overrun() ( REG_TSSI_STAT = TSSI_STAT_OVRN )
+
+#define __tssi_enable_filte_pid0() ( REG_TSSI_PEN |= TSSI_PEN_PID0 )
+#define __tssi_disable_filte_pid0() ( REG_TSSI_PEN &= ~TSSI_PEN_PID0 )
+
+/* m = 0, ..., 15 */
+#define __tssi_enable_pid_filter(m) \
+ do { \
+ int n = (m); \
+ if ( n>=0 && n <(TSSI_PID_MAX*2) ) { \
+ if ( n >= TSSI_PID_MAX ) n += 8; \
+ REG_TSSI_PEN |= ( 1 << n ); \
+ } \
+ } while (0)
+
+/* m = 0, ..., 15 */
+#define __tssi_disable_pid_filter(m) \
+ do { \
+ int n = (m); \
+ if ( n>=0 && n <(TSSI_PID_MAX*2) ) { \
+ if ( n >= TSSI_PID_MAX ) n += 8; \
+ REG_TSSI_PEN &= ~( 1 << n ); \
+ } \
+ } while (0)
+
+/* n = 0, ..., 7 */
+#define __tssi_set_pid0(n, pid0) \
+ do { \
+ REG_TSSI_PID(n) &= ~TSSI_PID_PID0_MASK; \
+ REG_TSSI_PID(n) |= ((pid0)<<TSSI_PID_PID0_BIT)&TSSI_PID_PID0_MASK; \
+ }while (0)
+/* n = 0, ..., 7 */
+#define __tssi_set_pid1(n, pid1) \
+ do { \
+ REG_TSSI_PID(n) &= ~TSSI_PID_PID1_MASK; \
+ REG_TSSI_PID(n) |= ((pid1)<<TSSI_PID_PID1_BIT)&TSSI_PID_PID1_MASK; \
+ }while (0)
+
+/* n = 0, ..., 15 */
+#define __tssi_set_pid(n, pid) \
+ do { \
+ if ( n>=0 && n < TSSI_PID_MAX*2) { \
+ if ( n < TSSI_PID_MAX ) \
+ __tssi_set_pid0(n, pid); \
+ else \
+ __tssi_set_pid1(n-TSSI_PID_MAX, pid); \
+ } \
+ }while (0)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810TSSI_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810tve.h b/arch/mips/include/asm/mach-jz4810/jz4810tve.h
new file mode 100644
index 00000000000..8f8fe3211a0
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810tve.h
@@ -0,0 +1,396 @@
+ /*
+ * linux/include/asm-mips/mach-jz4810/jz4810tve.h
+ *
+ * JZ4810 TVE register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810TVE_H__
+#define __JZ4810TVE_H__
+
+
+#define TVE_BASE 0xB3050100
+
+
+
+/*************************************************************************
+ * TVE (TV Encoder Controller)
+ *************************************************************************/
+#define TVE_CTRL (TVE_BASE + 0x40) /* TV Encoder Control register */
+#define TVE_FRCFG (TVE_BASE + 0x44) /* Frame configure register */
+#define TVE_SLCFG1 (TVE_BASE + 0x50) /* TV signal level configure register 1 */
+#define TVE_SLCFG2 (TVE_BASE + 0x54) /* TV signal level configure register 2*/
+#define TVE_SLCFG3 (TVE_BASE + 0x58) /* TV signal level configure register 3*/
+#define TVE_LTCFG1 (TVE_BASE + 0x60) /* Line timing configure register 1 */
+#define TVE_LTCFG2 (TVE_BASE + 0x64) /* Line timing configure register 2 */
+#define TVE_CFREQ (TVE_BASE + 0x70) /* Chrominance sub-carrier frequency configure register */
+#define TVE_CPHASE (TVE_BASE + 0x74) /* Chrominance sub-carrier phase configure register */
+#define TVE_CBCRCFG (TVE_BASE + 0x78) /* Chrominance filter configure register */
+#define TVE_WSSCR (TVE_BASE + 0x80) /* Wide screen signal control register */
+#define TVE_WSSCFG1 (TVE_BASE + 0x84) /* Wide screen signal configure register 1 */
+#define TVE_WSSCFG2 (TVE_BASE + 0x88) /* Wide screen signal configure register 2 */
+#define TVE_WSSCFG3 (TVE_BASE + 0x8c) /* Wide screen signal configure register 3 */
+
+#define REG_TVE_CTRL REG32(TVE_CTRL)
+#define REG_TVE_FRCFG REG32(TVE_FRCFG)
+#define REG_TVE_SLCFG1 REG32(TVE_SLCFG1)
+#define REG_TVE_SLCFG2 REG32(TVE_SLCFG2)
+#define REG_TVE_SLCFG3 REG32(TVE_SLCFG3)
+#define REG_TVE_LTCFG1 REG32(TVE_LTCFG1)
+#define REG_TVE_LTCFG2 REG32(TVE_LTCFG2)
+#define REG_TVE_CFREQ REG32(TVE_CFREQ)
+#define REG_TVE_CPHASE REG32(TVE_CPHASE)
+#define REG_TVE_CBCRCFG REG32(TVE_CBCRCFG)
+#define REG_TVE_WSSCR REG32(TVE_WSSCR)
+#define REG_TVE_WSSCFG1 REG32(TVE_WSSCFG1)
+#define REG_TVE_WSSCFG2 REG32(TVE_WSSCFG2)
+#define REG_TVE_WSSCFG3 REG32(TVE_WSSCFG3)
+
+/* TV Encoder Control register */
+#define TVE_CTRL_EYCBCR (1 << 25) /* YCbCr_enable */
+#define TVE_CTRL_ECVBS (1 << 24) /* 1: cvbs_enable 0: s-video*/
+#define TVE_CTRL_DAPD3 (1 << 23) /* DAC 3 power down */
+#define TVE_CTRL_DAPD2 (1 << 22) /* DAC 2 power down */
+#define TVE_CTRL_DAPD1 (1 << 21) /* DAC 1 power down */
+#define TVE_CTRL_DAPD (1 << 20) /* power down all DACs */
+#define TVE_CTRL_YCDLY_BIT 16
+#define TVE_CTRL_YCDLY_MASK (0x7 << TVE_CTRL_YCDLY_BIT)
+#define TVE_CTRL_CGAIN_BIT 14
+#define TVE_CTRL_CGAIN_MASK (0x3 << TVE_CTRL_CGAIN_BIT)
+ #define TVE_CTRL_CGAIN_FULL (0 << TVE_CTRL_CGAIN_BIT) /* gain = 1 */
+ #define TVE_CTRL_CGAIN_QUTR (1 << TVE_CTRL_CGAIN_BIT) /* gain = 1/4 */
+ #define TVE_CTRL_CGAIN_HALF (2 << TVE_CTRL_CGAIN_BIT) /* gain = 1/2 */
+ #define TVE_CTRL_CGAIN_THREE_QURT (3 << TVE_CTRL_CGAIN_BIT) /* gain = 3/4 */
+#define TVE_CTRL_CBW_BIT 12
+#define TVE_CTRL_CBW_MASK (0x3 << TVE_CTRL_CBW_BIT)
+ #define TVE_CTRL_CBW_NARROW (0 << TVE_CTRL_CBW_BIT) /* Narrow band */
+ #define TVE_CTRL_CBW_WIDE (1 << TVE_CTRL_CBW_BIT) /* Wide band */
+ #define TVE_CTRL_CBW_EXTRA (2 << TVE_CTRL_CBW_BIT) /* Extra wide band */
+ #define TVE_CTRL_CBW_ULTRA (3 << TVE_CTRL_CBW_BIT) /* Ultra wide band */
+#define TVE_CTRL_SYNCT (1 << 9)
+#define TVE_CTRL_PAL (1 << 8) /* 1: PAL, 0: NTSC */
+#define TVE_CTRL_FINV (1 << 7) /* invert_top:1-invert top and bottom fields. */
+#define TVE_CTRL_ZBLACK (1 << 6) /* bypass_yclamp:1-Black of luminance (Y) input is 0.*/
+#define TVE_CTRL_CR1ST (1 << 5) /* uv_order:0-Cb before Cr,1-Cr before Cb */
+#define TVE_CTRL_CLBAR (1 << 4) /* Color bar mode:0-Output input video to TV,1-Output color bar to TV */
+#define TVE_CTRL_SWRST (1 << 0) /* Software reset:1-TVE is reset */
+
+/* Signal level configure register 1 */
+#define TVE_SLCFG1_BLACKL_BIT 0
+#define TVE_SLCFG1_BLACKL_MASK (0x3ff << TVE_SLCFG1_BLACKL_BIT)
+#define TVE_SLCFG1_WHITEL_BIT 16
+#define TVE_SLCFG1_WHITEL_MASK (0x3ff << TVE_SLCFG1_WHITEL_BIT)
+
+/* Signal level configure register 2 */
+#define TVE_SLCFG2_BLANKL_BIT 0
+#define TVE_SLCFG2_BLANKL_MASK (0x3ff << TVE_SLCFG2_BLANKL_BIT)
+#define TVE_SLCFG2_VBLANKL_BIT 16
+#define TVE_SLCFG2_VBLANKL_MASK (0x3ff << TVE_SLCFG2_VBLANKL_BIT)
+
+/* Signal level configure register 3 */
+#define TVE_SLCFG3_SYNCL_BIT 0
+#define TVE_SLCFG3_SYNCL_MASK (0xff << TVE_SLCFG3_SYNCL_BIT)
+
+/* Line timing configure register 1 */
+#define TVE_LTCFG1_BACKP_BIT 0
+#define TVE_LTCFG1_BACKP_MASK (0x7f << TVE_LTCFG1_BACKP_BIT)
+#define TVE_LTCFG1_HSYNCW_BIT 8
+#define TVE_LTCFG1_HSYNCW_MASK (0x7f << TVE_LTCFG1_HSYNCW_BIT)
+#define TVE_LTCFG1_FRONTP_BIT 16
+#define TVE_LTCFG1_FRONTP_MASK (0x1f << TVE_LTCFG1_FRONTP_BIT)
+
+/* Line timing configure register 2 */
+#define TVE_LTCFG2_BURSTW_BIT 0
+#define TVE_LTCFG2_BURSTW_MASK (0x3f << TVE_LTCFG2_BURSTW_BIT)
+#define TVE_LTCFG2_PREBW_BIT 8
+#define TVE_LTCFG2_PREBW_MASK (0x1f << TVE_LTCFG2_PREBW_BIT)
+#define TVE_LTCFG2_ACTLIN_BIT 16
+#define TVE_LTCFG2_ACTLIN_MASK (0x7ff << TVE_LTCFG2_ACTLIN_BIT)
+
+/* Chrominance sub-carrier phase configure register */
+#define TVE_CPHASE_CCRSTP_BIT 0
+#define TVE_CPHASE_CCRSTP_MASK (0x3 << TVE_CPHASE_CCRSTP_BIT)
+ #define TVE_CPHASE_CCRSTP_8 (0 << TVE_CPHASE_CCRSTP_BIT) /* Every 8 field */
+ #define TVE_CPHASE_CCRSTP_4 (1 << TVE_CPHASE_CCRSTP_BIT) /* Every 4 field */
+ #define TVE_CPHASE_CCRSTP_2 (2 << TVE_CPHASE_CCRSTP_BIT) /* Every 2 lines */
+ #define TVE_CPHASE_CCRSTP_0 (3 << TVE_CPHASE_CCRSTP_BIT) /* Never */
+#define TVE_CPHASE_ACTPH_BIT 16
+#define TVE_CPHASE_ACTPH_MASK (0xff << TVE_CPHASE_ACTPH_BIT)
+#define TVE_CPHASE_INITPH_BIT 24
+#define TVE_CPHASE_INITPH_MASK (0xff << TVE_CPHASE_INITPH_BIT)
+
+/* Chrominance filter configure register */
+#define TVE_CBCRCFG_CRGAIN_BIT 0
+#define TVE_CBCRCFG_CRGAIN_MASK (0xff << TVE_CBCRCFG_CRGAIN_BIT)
+#define TVE_CBCRCFG_CBGAIN_BIT 8
+#define TVE_CBCRCFG_CBGAIN_MASK (0xff << TVE_CBCRCFG_CBGAIN_BIT)
+#define TVE_CBCRCFG_CRBA_BIT 16
+#define TVE_CBCRCFG_CRBA_MASK (0xff << TVE_CBCRCFG_CRBA_BIT)
+#define TVE_CBCRCFG_CBBA_BIT 24
+#define TVE_CBCRCFG_CBBA_MASK (0xff << TVE_CBCRCFG_CBBA_BIT)
+
+/* Frame configure register */
+#define TVE_FRCFG_NLINE_BIT 0
+#define TVE_FRCFG_NLINE_MASK (0x3ff << TVE_FRCFG_NLINE_BIT)
+#define TVE_FRCFG_L1ST_BIT 16
+#define TVE_FRCFG_L1ST_MASK (0xff << TVE_FRCFG_L1ST_BIT)
+
+/* Wide screen signal control register */
+#define TVE_WSSCR_EWSS0_BIT 0
+#define TVE_WSSCR_EWSS1_BIT 1
+#define TVE_WSSCR_WSSTP_BIT 2
+#define TVE_WSSCR_WSSCKBP_BIT 3
+#define TVE_WSSCR_WSSEDGE_BIT 4
+#define TVE_WSSCR_WSSEDGE_MASK (0x7 << TVE_WSSCR_WSSEDGE_BIT)
+#define TVE_WSSCR_ENCH_BIT 8
+#define TVE_WSSCR_NCHW_BIT 9
+#define TVE_WSSCR_NCHFREQ_BIT 12
+#define TVE_WSSCR_NCHFREQ_MASK (0x7 << TVE_WSSCR_NCHFREQ_BIT)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/*************************************************************************
+ * TVE (TV Encoder Controller) ops
+ *************************************************************************/
+/* TV Encoder Control register ops */
+#define __tve_soft_reset() (REG_TVE_CTRL |= TVE_CTRL_SWRST)
+
+#define __tve_output_colorbar() (REG_TVE_CTRL |= TVE_CTRL_CLBAR)
+#define __tve_output_video() (REG_TVE_CTRL &= ~TVE_CTRL_CLBAR)
+
+#define __tve_input_cr_first() (REG_TVE_CTRL |= TVE_CTRL_CR1ST)
+#define __tve_input_cb_first() (REG_TVE_CTRL &= ~TVE_CTRL_CR1ST)
+
+#define __tve_set_0_as_black() (REG_TVE_CTRL |= TVE_CTRL_ZBLACK)
+#define __tve_set_16_as_black() (REG_TVE_CTRL &= ~TVE_CTRL_ZBLACK)
+
+#define __tve_ena_invert_top_bottom() (REG_TVE_CTRL |= TVE_CTRL_FINV)
+#define __tve_dis_invert_top_bottom() (REG_TVE_CTRL &= ~TVE_CTRL_FINV)
+
+#define __tve_set_pal_mode() (REG_TVE_CTRL |= TVE_CTRL_PAL)
+#define __tve_set_ntsc_mode() (REG_TVE_CTRL &= ~TVE_CTRL_PAL)
+
+#define __tve_set_pal_dura() (REG_TVE_CTRL |= TVE_CTRL_SYNCT)
+#define __tve_set_ntsc_dura() (REG_TVE_CTRL &= ~TVE_CTRL_SYNCT)
+
+/* n = 0 ~ 3 */
+#define __tve_set_c_bandwidth(n) \
+do {\
+ REG_TVE_CTRL &= ~TVE_CTRL_CBW_MASK;\
+ REG_TVE_CTRL |= (n) << TVE_CTRL_CBW_BIT; \
+}while(0)
+
+/* n = 0 ~ 3 */
+#define __tve_set_c_gain(n) \
+do {\
+ REG_TVE_CTRL &= ~TVE_CTRL_CGAIN_MASK;\
+ (REG_TVE_CTRL |= (n) << TVE_CTRL_CGAIN_BIT; \
+}while(0)
+
+/* n = 0 ~ 7 */
+#define __tve_set_yc_delay(n) \
+do { \
+ REG_TVE_CTRL &= ~TVE_CTRL_YCDLY_MASK \
+ REG_TVE_CTRL |= ((n) << TVE_CTRL_YCDLY_BIT); \
+} while(0)
+
+#define __tve_disable_all_dacs() (REG_TVE_CTRL |= TVE_CTRL_DAPD)
+#define __tve_disable_dac1() (REG_TVE_CTRL |= TVE_CTRL_DAPD1)
+#define __tve_enable_dac1() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD1)
+#define __tve_disable_dac2() (REG_TVE_CTRL |= TVE_CTRL_DAPD2)
+#define __tve_enable_dac2() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD2)
+#define __tve_disable_dac3() (REG_TVE_CTRL |= TVE_CTRL_DAPD3)
+#define __tve_enable_dac3() (REG_TVE_CTRL &= ~TVE_CTRL_DAPD3)
+
+#define __tve_enable_svideo_fmt() (REG_TVE_CTRL |= TVE_CTRL_ECVBS)
+#define __tve_enable_cvbs_fmt() (REG_TVE_CTRL &= ~TVE_CTRL_ECVBS)
+
+/* TV Encoder Frame Configure register ops */
+/* n = 0 ~ 255 */
+#define __tve_set_first_video_line(n) \
+do {\
+ REG_TVE_FRCFG &= ~TVE_FRCFG_L1ST_MASK;\
+ REG_TVE_FRCFG |= (n) << TVE_FRCFG_L1ST_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_line_num_per_frm(n) \
+do {\
+ REG_TVE_FRCFG &= ~TVE_FRCFG_NLINE_MASK;\
+ REG_TVE_CFG |= (n) << TVE_FRCFG_NLINE_BIT;\
+} while(0)
+#define __tve_get_video_line_num()\
+ (((REG_TVE_FRCFG & TVE_FRCFG_NLINE_MASK) >> TVE_FRCFG_NLINE_BIT) - 1 - 2 * ((REG_TVE_FRCFG & TVE_FRCFG_L1ST_MASK) >> TVE_FRCFG_L1ST_BIT))
+
+/* TV Encoder Signal Level Configure register ops */
+/* n = 0 ~ 1023 */
+#define __tve_set_white_level(n) \
+do {\
+ REG_TVE_SLCFG1 &= ~TVE_SLCFG1_WHITEL_MASK;\
+ REG_TVE_SLCFG1 |= (n) << TVE_SLCFG1_WHITEL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_black_level(n) \
+do {\
+ REG_TVE_SLCFG1 &= ~TVE_SLCFG1_BLACKL_MASK;\
+ REG_TVE_SLCFG1 |= (n) << TVE_SLCFG1_BLACKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_blank_level(n) \
+do {\
+ REG_TVE_SLCFG2 &= ~TVE_SLCFG2_BLANKL_MASK;\
+ REG_TVE_SLCFG2 |= (n) << TVE_SLCFG2_BLANKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_vbi_blank_level(n) \
+do {\
+ REG_TVE_SLCFG2 &= ~TVE_SLCFG2_VBLANKL_MASK;\
+ REG_TVE_SLCFG2 |= (n) << TVE_SLCFG2_VBLANKL_BIT;\
+} while(0)
+/* n = 0 ~ 1023 */
+#define __tve_set_sync_level(n) \
+do {\
+ REG_TVE_SLCFG3 &= ~TVE_SLCFG3_SYNCL_MASK;\
+ REG_TVE_SLCFG3 |= (n) << TVE_SLCFG3_SYNCL_BIT;\
+} while(0)
+
+/* TV Encoder Signal Level Configure register ops */
+/* n = 0 ~ 31 */
+#define __tve_set_front_porch(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_FRONTP_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_FRONTP_BIT; \
+} while(0)
+/* n = 0 ~ 127 */
+#define __tve_set_hsync_width(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_HSYNCW_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_HSYNCW_BIT; \
+} while(0)
+/* n = 0 ~ 127 */
+#define __tve_set_back_porch(n) \
+do {\
+ REG_TVE_LTCFG1 &= ~TVE_LTCFG1_BACKP_MASK;\
+ REG_TVE_LTCFG1 |= (n) << TVE_LTCFG1_BACKP_BIT; \
+} while(0)
+/* n = 0 ~ 2047 */
+#define __tve_set_active_linec(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_ACTLIN_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_ACTLIN_BIT; \
+} while(0)
+/* n = 0 ~ 31 */
+#define __tve_set_breezy_way(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_PREBW_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_PREBW_BIT; \
+} while(0)
+
+/* n = 0 ~ 127 */
+#define __tve_set_burst_width(n) \
+do {\
+ REG_TVE_LTCFG2 &= ~TVE_LTCFG2_BURSTW_MASK;\
+ REG_TVE_LTCFG2 |= (n) << TVE_LTCFG2_BURSTW_BIT; \
+} while(0)
+
+/* TV Encoder Chrominance filter and Modulation register ops */
+/* n = 0 ~ (2^32-1) */
+#define __tve_set_c_sub_carrier_freq(n) REG_TVE_CFREQ = (n)
+/* n = 0 ~ 255 */
+#define __tve_set_c_sub_carrier_init_phase(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_INITPH_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_INITPH_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_c_sub_carrier_act_phase(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_ACTPH_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_ACTPH_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_c_phase_rst_period(n) \
+do { \
+ REG_TVE_CPHASE &= ~TVE_CPHASE_CCRSTP_MASK; \
+ REG_TVE_CPHASE |= (n) << TVE_CPHASE_CCRSTP_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cb_burst_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CBBA_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CBBA_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cr_burst_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CRBA_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CRBA_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cb_gain_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CBGAIN_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CBGAIN_BIT; \
+} while(0)
+/* n = 0 ~ 255 */
+#define __tve_set_cr_gain_amp(n) \
+do { \
+ REG_TVE_CBCRCFG &= ~TVE_CBCRCFG_CRGAIN_MASK; \
+ REG_TVE_CBCRCFG |= (n) << TVE_CBCRCFG_CRGAIN_BIT; \
+} while(0)
+
+/* TV Encoder Wide Screen Signal Control register ops */
+/* n = 0 ~ 7 */
+#define __tve_set_notch_freq(n) \
+do { \
+ REG_TVE_WSSCR &= ~TVE_WSSCR_NCHFREQ_MASK; \
+ REG_TVE_WSSCR |= (n) << TVE_WSSCR_NCHFREQ_BIT; \
+} while(0)
+/* n = 0 ~ 7 */
+#define __tve_set_notch_width() (REG_TVE_WSSCR |= TVE_WSSCR_NCHW_BIT)
+#define __tve_clear_notch_width() (REG_TVE_WSSCR &= ~TVE_WSSCR_NCHW_BIT)
+#define __tve_enable_notch() (REG_TVE_WSSCR |= TVE_WSSCR_ENCH_BIT)
+#define __tve_disable_notch() (REG_TVE_WSSCR &= ~TVE_WSSCR_ENCH_BIT)
+/* n = 0 ~ 7 */
+#define __tve_set_wss_edge(n) \
+do { \
+ REG_TVE_WSSCR &= ~TVE_WSSCR_WSSEDGE_MASK; \
+ REG_TVE_WSSCR |= (n) << TVE_WSSCR_WSSEDGE_BIT; \
+} while(0)
+#define __tve_set_wss_clkbyp() (REG_TVE_WSSCR |= TVE_WSSCR_WSSCKBP_BIT)
+#define __tve_set_wss_type() (REG_TVE_WSSCR |= TVE_WSSCR_WSSTP_BIT)
+#define __tve_enable_wssf1() (REG_TVE_WSSCR |= TVE_WSSCR_EWSS1_BIT)
+#define __tve_enable_wssf0() (REG_TVE_WSSCR |= TVE_WSSCR_EWSS0_BIT)
+
+/* TV Encoder Wide Screen Signal Configure register 1, 2 and 3 ops */
+/* n = 0 ~ 1023 */
+#define __tve_set_wss_level(n) \
+do { \
+ REG_TVE_WSSCFG1 &= ~TVE_WSSCFG1_WSSL_MASK; \
+ REG_TVE_WSSCFG1 |= (n) << TVE_WSSCFG1_WSSL_BIT; \
+} while(0)
+/* n = 0 ~ 4095 */
+#define __tve_set_wss_freq(n) \
+do { \
+ REG_TVE_WSSCFG1 &= ~TVE_WSSCFG1_WSSFREQ_MASK; \
+ REG_TVE_WSSCFG1 |= (n) << TVE_WSSCFG1_WSSFREQ_BIT; \
+} while(0)
+/* n = 0, 1; l = 0 ~ 255 */
+#define __tve_set_wss_line(n,v) \
+do { \
+ REG_TVE_WSSCFG##n &= ~TVE_WSSCFG_WSSLINE_MASK; \
+ REG_TVE_WSSCFG##n |= (v) << TVE_WSSCFG_WSSLINE_BIT; \
+} while(0)
+/* n = 0, 1; d = 0 ~ (2^20-1) */
+#define __tve_set_wss_data(n, v) \
+do { \
+ REG_TVE_WSSCFG##n &= ~TVE_WSSCFG_WSSLINE_MASK; \
+ REG_TVE_WSSCFG##n |= (v) << TVE_WSSCFG_WSSLINE_BIT; \
+} while(0)
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810TVE_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810uart.h b/arch/mips/include/asm/mach-jz4810/jz4810uart.h
new file mode 100644
index 00000000000..c54c63dd5ff
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810uart.h
@@ -0,0 +1,293 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810uart.h
+ *
+ * JZ4810 UART register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810UART_H__
+#define __JZ4810UART_H__
+
+
+#define UART0_BASE 0xB0030000
+#define UART1_BASE 0xB0031000
+#define UART2_BASE 0xB0032000
+#define UART3_BASE 0xB0033000
+
+/*************************************************************************
+ * 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 UART1_RDR (UART1_BASE + OFF_RDR)
+#define UART1_TDR (UART1_BASE + OFF_TDR)
+#define UART1_DLLR (UART1_BASE + OFF_DLLR)
+#define UART1_DLHR (UART1_BASE + OFF_DLHR)
+#define UART1_IER (UART1_BASE + OFF_IER)
+#define UART1_ISR (UART1_BASE + OFF_ISR)
+#define UART1_FCR (UART1_BASE + OFF_FCR)
+#define UART1_LCR (UART1_BASE + OFF_LCR)
+#define UART1_MCR (UART1_BASE + OFF_MCR)
+#define UART1_LSR (UART1_BASE + OFF_LSR)
+#define UART1_MSR (UART1_BASE + OFF_MSR)
+#define UART1_SPR (UART1_BASE + OFF_SPR)
+#define UART1_SIRCR (UART1_BASE + OFF_SIRCR)
+
+#define UART2_RDR (UART2_BASE + OFF_RDR)
+#define UART2_TDR (UART2_BASE + OFF_TDR)
+#define UART2_DLLR (UART2_BASE + OFF_DLLR)
+#define UART2_DLHR (UART2_BASE + OFF_DLHR)
+#define UART2_IER (UART2_BASE + OFF_IER)
+#define UART2_ISR (UART2_BASE + OFF_ISR)
+#define UART2_FCR (UART2_BASE + OFF_FCR)
+#define UART2_LCR (UART2_BASE + OFF_LCR)
+#define UART2_MCR (UART2_BASE + OFF_MCR)
+#define UART2_LSR (UART2_BASE + OFF_LSR)
+#define UART2_MSR (UART2_BASE + OFF_MSR)
+#define UART2_SPR (UART2_BASE + OFF_SPR)
+#define UART2_SIRCR (UART2_BASE + OFF_SIRCR)
+
+#define UART3_RDR (UART3_BASE + OFF_RDR)
+#define UART3_TDR (UART3_BASE + OFF_TDR)
+#define UART3_DLLR (UART3_BASE + OFF_DLLR)
+#define UART3_DLHR (UART3_BASE + OFF_DLHR)
+#define UART3_IER (UART3_BASE + OFF_IER)
+#define UART3_ISR (UART3_BASE + OFF_ISR)
+#define UART3_FCR (UART3_BASE + OFF_FCR)
+#define UART3_LCR (UART3_BASE + OFF_LCR)
+#define UART3_MCR (UART3_BASE + OFF_MCR)
+#define UART3_LSR (UART3_BASE + OFF_LSR)
+#define UART3_MSR (UART3_BASE + OFF_MSR)
+#define UART3_SPR (UART3_BASE + OFF_SPR)
+#define UART3_SIRCR (UART3_BASE + OFF_SIRCR)
+
+
+/*
+ * 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_FCM (1 << 6) /* 0: software 1: hardware */
+#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 */
+
+/*
+ * Define macros for UART_LSR
+ * UART Line Status Register
+ */
+#define UART_LSR_DR (1 << 0) /* 0: receive FIFO is empty 1: receive data is ready */
+#define UART_LSR_ORER (1 << 1) /* 0: no overrun error */
+#define UART_LSR_PER (1 << 2) /* 0: no parity error */
+#define UART_LSR_FER (1 << 3) /* 0; no framing error */
+#define UART_LSR_BRK (1 << 4) /* 0: no break detected 1: receive a break signal */
+#define UART_LSR_TDRQ (1 << 5) /* 1: transmit FIFO half "empty" */
+#define UART_LSR_TEMT (1 << 6) /* 1: transmit FIFO and shift registers empty */
+#define UART_LSR_RFER (1 << 7) /* 0: no receive error 1: receive error in FIFO mode */
+
+
+#ifndef __MIPS_ASSEMBLER
+
+/***************************************************************************
+ * UART
+ ***************************************************************************/
+#define __jtag_as_uart3() \
+do { \
+ REG_GPIO_PXSELC(0) = 0x40000000; \
+ REG_GPIO_PXSELS(0) = 0x80000000; \
+} while(0)
+
+#define __uart_enable(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) |= UARTFCR_UUE | UARTFCR_FE )
+#define __uart_disable(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_FCR) = ~UARTFCR_UUE )
+
+#define __uart_enable_transmit_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_TIE )
+#define __uart_disable_transmit_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~UARTIER_TIE )
+
+#define __uart_enable_receive_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) |= UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE )
+#define __uart_disable_receive_irq(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_IER) &= ~(UARTIER_RIE | UARTIER_RLIE | UARTIER_RTIE) )
+
+#define __uart_enable_loopback(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) |= UARTMCR_LOOP )
+#define __uart_disable_loopback(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_MCR) &= ~UARTMCR_LOOP )
+
+#define __uart_set_8n1(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) = UARTLCR_WLEN_8 )
+
+#define __uart_set_baud(n, devclk, baud) \
+ do { \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) |= UARTLCR_DLAB; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLLR) = (devclk / 16 / baud) & 0xff; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_DLHR) = ((devclk / 16 / baud) >> 8) & 0xff; \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_LCR) &= ~UARTLCR_DLAB; \
+ } while (0)
+
+#define __uart_parity_error(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_PER) != 0 )
+
+#define __uart_clear_errors(n) \
+ ( REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) &= ~(UARTLSR_ORER | UARTLSR_BRK | UARTLSR_FER | UARTLSR_PER | UARTLSR_RFER) )
+
+#define __uart_transmit_fifo_empty(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TDRQ) != 0 )
+
+#define __uart_transmit_end(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_TEMT) != 0 )
+
+#define __uart_transmit_char(n, ch) \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_TDR) = (ch)
+
+#define __uart_receive_fifo_full(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 )
+
+#define __uart_receive_ready(n) \
+ ( (REG8(UART_BASE + UART_OFF*(n) + OFF_LSR) & UARTLSR_DR) != 0 )
+
+#define __uart_receive_char(n) \
+ REG8(UART_BASE + UART_OFF*(n) + OFF_RDR)
+
+#define __uart_disable_irda() \
+ ( REG8(IRDA_BASE + OFF_SIRCR) &= ~(SIRCR_TSIRE | SIRCR_RSIRE) )
+#define __uart_enable_irda() \
+ /* Tx high pulse as 0, Rx low pulse as 0 */ \
+ ( REG8(IRDA_BASE + OFF_SIRCR) = SIRCR_TSIRE | SIRCR_RSIRE | SIRCR_RXPL | SIRCR_TPWS )
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810UART_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810wdt.h b/arch/mips/include/asm/mach-jz4810/jz4810wdt.h
new file mode 100644
index 00000000000..82f025511e7
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810wdt.h
@@ -0,0 +1,80 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810wdt.h
+ *
+ * JZ4810 WDT register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810WDT_H__
+#define __JZ4810WDT_H__
+
+
+#define WDT_BASE 0xB0002000
+/*************************************************************************
+ * 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)
+
+
+#ifndef __MIPS_ASSEMBLER
+
+
+/***************************************************************************
+ * WDT
+ ***************************************************************************/
+#define __wdt_start() ( REG_WDT_TCER |= WDT_TCER_TCEN )
+#define __wdt_stop() ( REG_WDT_TCER &= ~WDT_TCER_TCEN )
+#define __wdt_set_count(v) ( REG_WDT_TCNT = (v) )
+#define __wdt_set_data(v) ( REG_WDT_TDR = (v) )
+
+#define __wdt_select_extalclk() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_EXT_EN)
+#define __wdt_select_rtcclk() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_RTC_EN)
+#define __wdt_select_pclk() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~(WDT_TCSR_EXT_EN | WDT_TCSR_RTC_EN | WDT_TCSR_PCK_EN)) | WDT_TCSR_PCK_EN)
+
+#define __wdt_select_clk_div1() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1)
+#define __wdt_select_clk_div4() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE4)
+#define __wdt_select_clk_div16() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE16)
+#define __wdt_select_clk_div64() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE64)
+#define __wdt_select_clk_div256() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE256)
+#define __wdt_select_clk_div1024() \
+ (REG_WDT_TCSR = (REG_WDT_TCSR & ~WDT_TCSR_PRESCALE_MASK) | WDT_TCSR_PRESCALE1024)
+
+
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810WDT_H__ */
+
+
diff --git a/arch/mips/include/asm/mach-jz4810/jz4810xxx.h b/arch/mips/include/asm/mach-jz4810/jz4810xxx.h
new file mode 100644
index 00000000000..4e569f85609
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/jz4810xxx.h
@@ -0,0 +1,18 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/jz4810xxx.h
+ *
+ * JZ4810 XXX register definition.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4810XXX_H__
+#define __JZ4810XXX_H__
+
+
+#ifndef __MIPS_ASSEMBLER
+
+#endif /* __MIPS_ASSEMBLER */
+
+#endif /* __JZ4810XXX_H__ */
+
diff --git a/arch/mips/include/asm/mach-jz4810/misc.h b/arch/mips/include/asm/mach-jz4810/misc.h
new file mode 100644
index 00000000000..523ff193b53
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/misc.h
@@ -0,0 +1,44 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/misc.h
+ *
+ * Ingenic's JZ4810 common include.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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_JZ4810_MISC_H__
+#define __ASM_JZ4810_MISC_H__
+
+/*==========================================================
+ * I2C
+ *===========================================================*/
+
+#define I2C_EEPROM_DEV 0xA /* b'1010 */
+#define I2C_RTC_DEV 0xD /* b'1101 */
+#define DIMM0_SPD_ADDR 0
+#define DIMM1_SPD_ADDR 1
+#define DIMM2_SPD_ADDR 2
+#define DIMM3_SPD_ADDR 3
+#define JZ_HCI_ADDR 7
+
+#define DIMM_SPD_LEN 128
+#define JZ_HCI_LEN 512 /* 4K bits E2PROM */
+#define I2C_RTC_LEN 16
+#define HCI_MAC_OFFSET 64
+
+extern void i2c_open(void);
+extern void i2c_close(void);
+extern void i2c_setclk(unsigned int i2cclk);
+
+extern int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count);
+extern int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count);
+
+#endif /* __ASM_JZ4810_MISC_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/regs.h b/arch/mips/include/asm/mach-jz4810/regs.h
new file mode 100644
index 00000000000..263eb763d09
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/regs.h
@@ -0,0 +1,43 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/regs.h
+ *
+ * JZ4810 register definition.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __JZ4810_REGS_H__
+#define __JZ4810_REGS_H__
+
+
+/*
+ * Define the module base addresses
+ */
+/* AHB0 BUS Devices Base */
+#define HARB0_BASE 0xB3000000
+/* AHB1 BUS Devices Base */
+#define HARB1_BASE 0xB3200000
+#define DMAGP0_BASE 0xB3210000
+#define DMAGP1_BASE 0xB3220000
+#define DMAGP2_BASE 0xB3230000
+#define DEBLK_BASE 0xB3270000
+#define IDCT_BASE 0xB3280000
+#define CABAC_BASE 0xB3290000
+#define TCSM0_BASE 0xB32B0000
+#define TCSM1_BASE 0xB32C0000
+#define SRAM_BASE 0xB32D0000
+/* AHB2 BUS Devices Base */
+#define HARB2_BASE 0xB3400000
+#define UHC_BASE 0xB3430000
+#define GPS_BASE 0xB3480000
+#define ETHC_BASE 0xB34B0000
+/* APB BUS Devices Base */
+#define OST_BASE 0xB0002000
+#define PS2_BASE 0xB0060000
+
+
+#endif /* __JZ4810_REGS_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/serial.h b/arch/mips/include/asm/mach-jz4810/serial.h
new file mode 100644
index 00000000000..ced1867f3b2
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/serial.h
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-mips/mach-jz4810/serial.h
+ *
+ * Ingenic's JZ4810 common include.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ *
+ * Author: <cwjia@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 (33000000/16)
+
+#define JZ_SERIAL_PORT_DEFNS \
+ { .baud_base = JZ_BASE_BAUD, .irq = IRQ_UART2, \
+ .flags = STD_COM_FLAGS, .iomem_base = (u8 *)UART2_BASE, \
+ .iomem_reg_shift = 2, .io_type = SERIAL_IO_MEM },
+
+#endif /* __ASM_BORAD_SERIAL_H__ */
diff --git a/arch/mips/include/asm/mach-jz4810/war.h b/arch/mips/include/asm/mach-jz4810/war.h
new file mode 100644
index 00000000000..bded284ed7f
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4810/war.h
@@ -0,0 +1,26 @@
+/*
+ * 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_JZ4810_WAR_H
+#define __ASM_MIPS_MACH_JZ4810_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_JZ4810_WAR_H */
+
diff --git a/arch/mips/jz4750/board-apus.c b/arch/mips/jz4750/board-apus.c
index 7347dfaa56e..632802ff05c 100644
--- a/arch/mips/jz4750/board-apus.c
+++ b/arch/mips/jz4750/board-apus.c
@@ -25,6 +25,12 @@
#include <asm/jzsoc.h>
+#include <asm/jzmmc/jz_mmc_platform_data.h>
+
+void __init board_msc_init(void);
+
+extern int jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat);
+
extern void (*jz_timer_callback)(void);
static void dancing(void)
@@ -41,6 +47,159 @@ static void apus_timer_callback(void)
}
}
+static void apus_sd_gpio_init(struct device *dev)
+{
+ __gpio_as_msc0_8bit();
+ __gpio_as_output(GPIO_SD0_VCC_EN_N);
+ __gpio_as_input(GPIO_SD0_CD_N);
+}
+
+static void apus_sd_power_on(struct device *dev)
+{
+ __gpio_clear_pin(GPIO_SD0_VCC_EN_N);
+}
+
+static void apus_sd_power_off(struct device *dev)
+{
+ __gpio_set_pin(GPIO_SD0_VCC_EN_N);
+}
+
+static void apus_sd_cpm_start(struct device *dev)
+{
+ __cpm_start_msc(0);
+}
+
+static unsigned int apus_sd_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD0_CD_N);
+ return (!status);
+}
+
+#if 0
+static void apus_sd_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_high_level(MSC0_HOTPLUG_PIN); /* wait remove */
+ else
+ __gpio_as_irq_low_level(MSC0_HOTPLUG_PIN); /* wait insert */
+}
+#else
+static void apus_sd_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_rise_edge(MSC0_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_fall_edge(MSC0_HOTPLUG_PIN);
+}
+#endif
+
+static unsigned int apus_sd_get_wp(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD0_WP);
+ return (status);
+}
+
+struct jz_mmc_platform_data apus_sd_data = {
+#ifndef CONFIG_JZ_MSC0_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC0_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD0_CD_N,
+ .init = apus_sd_gpio_init,
+ .power_on = apus_sd_power_on,
+ .power_off = apus_sd_power_off,
+ .cpm_start = apus_sd_cpm_start,
+ .status = apus_sd_status,
+ .plug_change = apus_sd_plug_change,
+ .write_protect = apus_sd_get_wp,
+ .max_bus_width = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC0_BUS_1
+ .bus_width = 1,
+#elif defined CONFIG_JZ_MSC0_BUS_4
+ .bus_width = 4,
+#else
+ .bus_width = 8,
+#endif
+};
+
+static void apus_tf_gpio_init(struct device *dev)
+{
+ __gpio_as_msc1_4bit();
+ __gpio_as_output(GPIO_SD1_VCC_EN_N);
+ __gpio_as_input(GPIO_SD1_CD_N);
+}
+
+static void apus_tf_power_on(struct device *dev)
+{
+ __msc1_enable_power();
+}
+
+static void apus_tf_power_off(struct device *dev)
+{
+ __msc1_disable_power();
+}
+
+static void apus_tf_cpm_start(struct device *dev)
+{
+ __cpm_start_msc(1);
+}
+
+static unsigned int apus_tf_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD1_CD_N);
+ return (status);
+}
+
+#if 0
+static void apus_tf_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_low_level(MSC1_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_high_level(MSC1_HOTPLUG_PIN);
+}
+#else
+static void apus_tf_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_fall_edge(MSC1_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_rise_edge(MSC1_HOTPLUG_PIN);
+}
+#endif
+
+struct jz_mmc_platform_data apus_tf_data = {
+#ifndef CONFIG_JZ_MSC1_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC1_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD1_CD_N,
+ .init = apus_tf_gpio_init,
+ .power_on = apus_tf_power_on,
+ .power_off = apus_tf_power_off,
+ .cpm_start = apus_tf_cpm_start,
+ .status = apus_tf_status,
+ .plug_change = apus_tf_plug_change,
+ .max_bus_width = MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC1_BUS_1
+ .bus_width = 1,
+#else
+ .bus_width = 4,
+#endif
+};
+
static void __init board_cpm_setup(void)
{
/* Stop unused module clocks here.
@@ -53,6 +212,17 @@ static void __init board_gpio_setup(void)
__gpio_as_pcm();
}
+void __init board_msc_init(void)
+{
+#ifdef CONFIG_JZ_MSC0
+ jz_add_msc_devices(0, &apus_sd_data);
+#endif
+
+#ifdef CONFIG_JZ_MSC1
+ jz_add_msc_devices(1, &apus_tf_data);
+#endif
+}
+
void __init jz_board_setup(void)
{
printk("JZ4750 APUS board setup\n");
diff --git a/arch/mips/jz4750/i2c.c b/arch/mips/jz4750/i2c.c
index 13eb839d580..fd1e68518ea 100644
--- a/arch/mips/jz4750/i2c.c
+++ b/arch/mips/jz4750/i2c.c
@@ -28,11 +28,28 @@
#define PFX "I_I2C"
-#define D(fmt, args...) \
-// printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args)
-
-#define E(fmt, args...) \
- printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args)
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+//#define DEBUG_I2C
+
+#ifdef DEBUG_I2C
+#define D(fmt, args...) \
+ ({ \
+ printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args); \
+ printk(KERN_ERR PFX": CR = %#0x SR = %#0x\n", REG_I2C_CR, REG_I2C_SR); \
+ })
+
+#define E(fmt, args...) \
+ ({ \
+ printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args); \
+ printk(KERN_ERR PFX": CR = %#0x SR = %#0x\n", REG_I2C_CR, REG_I2C_SR); \
+ })
+#else
+#define D(fmt, args...) do { } while(0)
+#define E(fmt, args...) do { } while(0)
+#endif
/* Controller. */
struct i2c_ctrl {
@@ -48,12 +65,12 @@ static inline void i2c_ctrl_enable(void)
D("Called.");
__i2c_enable();
-
+
udelay(I2C_CTRL_WAIT_ENABLE);
-
+
return;
}
-
+
static inline void i2c_ctrl_disable(void)
{
D("Called.");
@@ -61,14 +78,14 @@ static inline void i2c_ctrl_disable(void)
__i2c_disable();
udelay(I2C_CTRL_WAIT_DISABLE);
-
+
return;
}
static inline void i2c_ctrl_set_clk(unsigned long clk)
{
struct i2c_ctrl *ctrl = &g_i2c_ctrl;
-
+
D("Called.");
if (ctrl->clk != clk) {
@@ -83,265 +100,284 @@ static inline void i2c_ctrl_set_clk(unsigned long clk)
return;
}
-/*
- * I2C bus protocol basic routines
- */
-static inline int __i2c_put_data(unsigned char data, unsigned long timeout)
+static void delay_i2c_clock(int count)
+{
+ volatile int i, j;
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < 2000; j++) {
+ ;
+ }
+ }
+}
+
+static int i2c_put_data(unsigned char data)
{
- unsigned long t;
-
+
+ if (__i2c_check_drf()){
+ printk("WARNING: need clear DRF first\n");
+ __i2c_clear_drf();
+ delay_i2c_clock(1);
+ }
__i2c_write(data);
__i2c_set_drf();
-
- t = timeout;
- while (__i2c_check_drf() != 0 && t)
- t--;
- if (!t) {
- E("__i2c_check_drf() timeout, Data: 0x%x. timeout: %lu.", data, timeout);
- return -ETIMEDOUT;
- }
+ do {
+ delay_i2c_clock(1);
+ } while (__i2c_check_drf() != 0);
+
+#if 0
+ while (!__i2c_transmit_ended())
+ delay_i2c_clock(1);
+#endif
- while (!__i2c_transmit_ended() && t)
- t--;
+ /* wait for the i2c controller set the ack BIT*/
+ delay_i2c_clock(1);
- if (!t) {
- E("__i2c_transmit_ended() timeout, Data: 0x%x, timeout: %lu.", data, timeout);
+ if (__i2c_received_ack())
+ return 0;
+ else {
+ printk("%s ERROR, get an NACK\n", __FUNCTION__);
return -ETIMEDOUT;
}
+}
- t = timeout;
- while (!__i2c_received_ack() && t)
- t--;
- if (!t) {
- E("__i2c_received_ack() timeout, Data: 0x%x, timeout: %lu.", data, timeout);
- return -ETIMEDOUT;
+static int i2c_get_data(unsigned char *data, int ack)
+{
+ while (__i2c_check_drf() == 0)
+ delay_i2c_clock(1);
+
+ *data = __i2c_read();
+
+ /* wait for the i2c controller from TRANSFERRING to IDLE*/
+ delay_i2c_clock(1);
+
+ __i2c_clear_drf();
+
+ if (!ack) {
+ __i2c_send_nack();
+ __i2c_send_stop();
}
return 0;
}
-static inline int __i2c_get_data(unsigned char *data, int ack, unsigned long timeout)
+static int xfer_read(unsigned char device, unsigned char *buf, int length)
{
- unsigned long t;
+ int cnt = 0;
- ack ? __i2c_send_ack() : __i2c_send_nack();
-
- t = timeout;
- while (__i2c_check_drf() == 0 && t)
- t--;
+ if (length == 1)
+ __i2c_send_nack();
+ else
+ __i2c_send_ack();
- if (!t) {
- E("__i2c_check_drf() timeout. timeout: %lu", timeout);
- return -ETIMEDOUT;
+#if defined(CONFIG_TOUCHSCREEN_JZ_MT4D)
+ if ((device == 0x40) && __gpio_get_pin(GPIO_ATTN)) {
+ return -EBUSY;
}
+#endif
- *data = __i2c_read();
+ __i2c_send_start();
+ __i2c_write((device << 1) | I2C_READ);
+ __i2c_set_drf();
- __i2c_clear_drf();
+ /* wait for i2c controller from IDLE to TRANSFERRING*/
+ delay_i2c_clock(1);
- return 0;
-}
+ while (!__i2c_transmit_ended())
+ delay_i2c_clock(1);
+ if (!__i2c_received_ack())
+ goto xfer_read_err;
-static inline int put_data(struct i_i2c_dev *dev, unsigned char data)
-{
- return __i2c_put_data(data, dev->timing->timeout);
-}
+ do {
+ i2c_get_data(buf, (length - cnt) != 2);
-static inline int get_data(struct i_i2c_dev *dev, unsigned char *data, int ack)
-{
- return __i2c_get_data(data, ack, dev->timing->timeout);
-}
+ cnt++;
+ buf++;
+ } while (cnt < length);
-static inline void i2c_start(void)
-{
- __i2c_send_start();
-
- udelay(I2C_BUS_TIMING_START_HOLD);
+ if (length == 1)
+ __i2c_send_stop();
- return;
-}
+ do {
+ __i2c_clear_drf();
+ /* wait for i2c controller from TRANSFERRING to IDLE*/
+ delay_i2c_clock(8);
+ } while (__i2c_check_drf());
-static inline void i2c_stop(void)
-{
+ //__i2c_send_stop();
+
+ return 0;
+
+xfer_read_err:
__i2c_send_stop();
-
- udelay(I2C_BUS_TIMING_STOP_HOLD);
+ printk("Read I2C device 0x%2x failed.\n", device);
- return;
+ return -ENODEV;
}
-static inline int i2c_start_and_send_address(struct i_i2c_dev *dev, off_t off, int dir)
+static int xfer_write(unsigned char device, unsigned char *buf, int length, int stop_before_restart)
{
- unsigned int ra = ((dev->address << 1) & 0xff) | 0x1;
- unsigned int wa = ((dev->address << 1) & 0xff);
-
- int rv;
-
- i2c_start();
+ int cnt = 0, ret = 0;
- if (put_data(dev, wa) < 0) {
- E("Failed to send write address.");
- rv = -ENODEV;
- goto err;
+ __i2c_send_start();
+ if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) {
+ ret = -ENODEV;
+ goto xfer_write_err;
}
- if (dev->cap & I_I2C_CAP_16BIT_OFFSET_MSB) {
- if (put_data(dev, (off >> 8) & 0xFF) < 0) {
- E("Failed to send off >> 8 MSB.");
- rv = -EINVAL;
- goto err;
- }
- }
+ while (cnt < length) {
+ ret = i2c_put_data(*buf);
+ if (ret < 0)
+ goto xfer_write_err;
- if (put_data(dev, (off & 0xFF)) < 0) {
- E("Failed to send off.");
- rv = -EINVAL;
- goto err;
+ cnt++;
+ buf++;
}
- if (dev->cap & I_I2C_CAP_16BIT_OFFSET_LSB) {
- if (put_data(dev, (off >> 8) & 0xFF) < 0) {
- E("Failed to send off >> 8 LSB.");
- rv = -EINVAL;
- goto err;
- }
- }
+xfer_write_err:
+ if ( (ret < 0) || stop_before_restart)
+ __i2c_send_stop();
+ while (!__i2c_transmit_ended()) ;
+ delay_i2c_clock(1);
- if (dir == I_I2C_IO_DIR_READ) {
- if (dev->flags & I_I2C_FLAG_STOP_BEFORE_RESTART)
- i2c_stop();
+ if (ret == -ENODEV)
+ printk("Write I2C device 0x%2x failed\n", device);
- i2c_start();
+ return ret;
+}
- if (put_data(dev, ra) < 0) {
- E("Failed to send read address.");
- rv = -ENODEV;
- goto err;
- }
+static __inline__ int __write_mem_location(struct i_i2c_dev *dev, off_t off, unsigned char offset[2])
+{
+ int idx = 0;
+
+ if (dev->cap & I_I2C_CAP_16BIT_OFFSET_MSB) {
+ offset[idx++] = (off >> 8) & 0xFF;
}
- return 0;
+ offset[idx++] = off & 0xFF;
+
+ if (dev->cap & I_I2C_CAP_16BIT_OFFSET_LSB) {
+ offset[idx++] = (off >> 8) & 0xFF;
+ }
-err:
- i2c_stop();
- return rv;
+ return idx;
}
-static inline int i2c_read_data(struct i_i2c_dev *dev, char *buf, size_t count)
+static int write_mem_location(struct i_i2c_dev *dev, off_t off)
{
- int i, rv;
- int ack = 1;
-
-// D("buf: 0x%p, count: %d.", buf, count);
+ int nb_off = 0;
+ int ret;
+ unsigned char offset[2] = { 0 };
- for (i = 0; i < count; i++) {
- if (i == count - 1) {
-// D("Nack.");
- ack = 0;
- }
+ nb_off = __write_mem_location(dev, off, offset);
+ /* write the offset */
+ ret = xfer_write(dev->address, offset, nb_off, 0);
+ if (ret != 0)
+ printk("write dev(%#0x) offset(%d) error, ret = %d\n", dev->address, (int)off, ret);
- rv = get_data(dev, buf + i, ack);
- if (rv) {
- E("get_data() failed: rv: %d i: %d.", rv, i);
- return rv;
- }
- }
-
- return 0;
+ return ret;
}
-static inline int i2c_write_data(struct i_i2c_dev *dev, char *buf, size_t count)
+/*
+ * I2C interface
+ */
+int i_i2c_read_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
{
+ int ret = 0;
+ int rd_bytes = 0;
+ //struct i2c_ctrl *ctrl = &g_i2c_ctrl;
+ struct i_i2c_timing *timing = dev->timing;
+
+ //unsigned long flags;
+ unsigned long io_size, size;
+
unsigned long i;
- int rv;
-
-// D("buf: 0x%p, count: %d.", buf, count);
+ unsigned char *data = (unsigned char *)buf;
- for (i = 0; i < count; i++) {
- rv = put_data(dev, buf[i]);
- if (rv) {
- E("put_data() failed: %d.\n", rv);
- return rv;
- }
+ //spin_lock_irqsave(&ctrl->lock, flags);
+
+ i2c_ctrl_set_clk(timing->clk);
+ i2c_ctrl_enable();
+
+ io_size = dev->read_size;
+ size = count < io_size ? count : io_size;
+
+ for (i = 0; i < count; i += io_size) {
+ ret = write_mem_location(dev, off + i);
+ if (ret != 0)
+ goto err;
+ /* read data */
+ rd_bytes = ( (count - i) > size) ? size : (count - i);
+ ret = xfer_read(dev->address, data + i, rd_bytes);
+ if (ret != 0)
+ goto err;
}
-
- return 0;
+
+ ret = count;
+ err:
+ i2c_ctrl_disable();
+ //spin_unlock_irqrestore(&ctrl->lock, flags);
+ return ret;
}
+EXPORT_SYMBOL(i_i2c_read_dev);
-static int do_i2c(struct i_i2c_dev *dev, off_t off, char *buf, size_t count, int dir)
+int i_i2c_write_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
{
- struct i2c_ctrl *ctrl = &g_i2c_ctrl;
+ int ret = 0;
+ int n_bytes = 0;
+ //struct i2c_ctrl *ctrl = &g_i2c_ctrl;
struct i_i2c_timing *timing = dev->timing;
- unsigned long flags;
+ //unsigned long flags;
unsigned long io_size, size;
unsigned long i;
- int rv = 0;
+ unsigned char *buffer = (unsigned char *)buf;
+ unsigned char *data = NULL;
+
+ int nb_off = 0;
+ unsigned char offset[2] = { 0 };
+
+ //spin_lock_irqsave(&ctrl->lock, flags);
- spin_lock_irqsave(&ctrl->lock, flags);
-
- i2c_ctrl_enable();
i2c_ctrl_set_clk(timing->clk);
+ i2c_ctrl_enable();
- io_size = dir ? dev->write_size : dev->read_size;
+ io_size = dev->write_size;
size = count < io_size ? count : io_size;
- for (i = 0; i < count; i += io_size) {
- rv = i2c_start_and_send_address(dev, off + i, dir);
- if (rv) {
- E("i2c_start_and_send_address() failed: %d, i: %lu.", rv, i);
- i2c_stop();
- goto err;
- }
-
-// D("Pass send address.");
+ data = kzalloc(size + 2, GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto err;
+ }
- if (!dir)
- rv = i2c_read_data(dev, buf + i, size);
- else
- rv = i2c_write_data(dev, buf + i, size);
+ for (i = 0; i < count; i += size) {
+ // printk("===>write offset = %d\n", (int)(off + i));
+ memset(data, 0, size + 2);
+ nb_off = __write_mem_location(dev, off + i, offset);
+ memcpy(data, offset, nb_off);
-// D("Pass rw data.");
+ n_bytes = ( (count - i) > size) ? size : (count - i);
+ memcpy(data + nb_off, buffer + i, n_bytes);
- if (rv) {
- E("i2c_read/write_data() failed: %d, i: %lu.", rv, i);
- i2c_stop();
+ ret = xfer_write(dev->address, data, n_bytes + nb_off, 1);
+ if (ret != 0)
goto err;
- }
-
- i2c_stop();
-
- if (dir)
- mdelay(timing->t_wr);
- }
-
-err:
- i2c_ctrl_disable();
- spin_unlock_irqrestore(&ctrl->lock, flags);
+ if (dev->timing->t_wr)
+ mdelay(dev->timing->t_wr);
+ }
- return rv;
-}
-/*
- * I2C interface
- */
-int i_i2c_read_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
-{
- D("off: %d, buf: 0x%p, count: %d.", off, buf, count);
-
- return do_i2c(dev, off, buf, count, 0);
-}
-EXPORT_SYMBOL(i_i2c_read_dev);
-int i_i2c_write_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
-{
- D("off: %d, buf: 0x%p, count: %d.", off, buf, count);
+ ret = count;
- return do_i2c(dev, off, buf, count, 1);
+ err:
+ i2c_ctrl_disable();
+ //spin_unlock_irqrestore(&ctrl->lock, flags);
+ return ret;
}
EXPORT_SYMBOL(i_i2c_write_dev);
@@ -352,30 +388,143 @@ int i_i2c_init_dev(struct i_i2c_dev *dev)
if (!timing) {
printk(KERN_ERR PFX": %s(): Please setup the timing of I2C device: 0x%p.\n", __func__, dev);
return -EINVAL;
- }
-
+ }
+
if (!timing->timeout)
timing->timeout = (100 * 1000);
-
+
if (!timing->clk)
timing->clk = (100 * 1000); /* default 100 KHz */
-
- if (!(dev->cap & I_I2C_CAP_SEQ_READ))
+
+ if (!(dev->cap & I_I2C_CAP_SEQ_READ))
dev->read_size = 1;
-
+
if (!(dev->cap & I_I2C_CAP_SEQ_WRITE))
dev->write_size = 1;
- return 0;
+ return 0;
}
EXPORT_SYMBOL(i_i2c_init_dev);
+
+static struct i_i2c_timing i2c_tm_default = {
+ .timeout = 100 * 1000,
+ .clk = 100 * 1000, /* default 100KHZ */
+ .t_wr = 5, /* eeprom write cycle time: 5ms */
+};
+
+static struct i_i2c_dev i2c_dev_default = {
+ .name = "default_i2c_adapter",
+ .cap = I_I2C_CAP_SEQ_READ | I_I2C_CAP_SEQ_WRITE,
+ .flags = 0,
+ .read_size = 16, /* 8K, the max size of data we can read in a transaction(S--->P) */
+ .write_size = 16, /* 8K the max size of data we can write in a transaction(S--->P) */
+ .lock = SPIN_LOCK_UNLOCKED,
+ .timing = &i2c_tm_default,
+};
+
+void i2c_open(void)
+{
+ i2c_ctrl_set_clk(i2c_dev_default.timing->clk);
+ i2c_ctrl_enable();
+}
+EXPORT_SYMBOL(i2c_open);
+
+void i2c_close(void)
+{
+ i2c_ctrl_disable();
+}
+EXPORT_SYMBOL(i2c_close);
+
+void i2c_setclk(unsigned int i2cclk)
+{
+ i2c_ctrl_set_clk(i2cclk);
+}
+EXPORT_SYMBOL(i2c_setclk);
+
+int i2c_lseek(unsigned char device, unsigned char offset)
+{
+#if 0
+ int ret = 0;
+ spin_lock(&i2c_dev_default.lock); /* maybe semaphore is more suitable!!!!! */
+
+ __i2c_send_nack(); /* Master does not send ACK, slave sends it */
+ __i2c_send_start();
+ if (i2c_put_data(device << 1) < 0)
+ goto device_err;
+ if (i2c_put_data(offset) < 0)
+ goto address_err;
+
+ spin_unlock(&i2c_dev_default.lock);
+ return 0;
+
+ device_err:
+ printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device);
+ __i2c_send_stop();
+ spin_unlock(&i2c_dev_default.lock);
+ return -ENODEV;
+ address_err:
+ printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device);
+ __i2c_send_stop();
+ spin_unlock(&i2c_dev_default.lock);
+ return -EREMOTEIO;
+#else
+ return 0;
+#endif
+}
+EXPORT_SYMBOL(i2c_lseek);
+
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int ret = 0;
+
+#ifdef DEBUG_I2C
+ printk("device = %#0x, address = %#0x\n",
+ device, address);
+#endif
+
+ spin_lock(&i2c_dev_default.lock); /* maybe semaphore is more suitable!!!!! */
+ /* device ----> address
+ * address ---> offset
+ */
+
+ i2c_dev_default.address = device;
+ ret = i_i2c_read_dev(&i2c_dev_default, address, buf, count);
+
+ spin_unlock(&i2c_dev_default.lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(i2c_read);
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int ret = 0;
+
+#ifdef DEBUG_I2C
+ printk("device = %#0x, address = %#0x\n",
+ device, address);
+#endif
+
+ spin_lock(&i2c_dev_default.lock); /* maybe semaphore is more suitable!!!!! */
+
+ i2c_dev_default.address = device;
+ ret = i_i2c_write_dev(&i2c_dev_default, address, buf, count);
+
+ spin_unlock(&i2c_dev_default.lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(i2c_write);
+
static int __init i_i2c_init(void)
{
struct i2c_ctrl *ctrl = &g_i2c_ctrl;
spin_lock_init(&ctrl->lock);
-
+
__gpio_as_i2c();
i2c_ctrl_set_clk(100 * 1000);
diff --git a/arch/mips/jz4750/platform.c b/arch/mips/jz4750/platform.c
index fa3c49a7729..0d5ac617b1e 100644
--- a/arch/mips/jz4750/platform.c
+++ b/arch/mips/jz4750/platform.c
@@ -16,6 +16,13 @@
#include <asm/jzsoc.h>
+
+#include <asm/jzmmc/jz_mmc_platform_data.h>
+
+extern void __init board_msc_init(void);
+
+int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat);
+
/* OHCI (USB full speed host controller) */
static struct resource jz_usb_ohci_resources[] = {
[0] = {
@@ -99,6 +106,7 @@ static struct platform_device jz_usb_gdt_device = {
};
/** MMC/SD controller **/
+#if 0
static struct resource jz_mmc_resources[] = {
[0] = {
.start = CPHYSADDR(MSC_BASE),
@@ -124,6 +132,91 @@ static struct platform_device jz_mmc_device = {
.num_resources = ARRAY_SIZE(jz_mmc_resources),
.resource = jz_mmc_resources,
};
+#else
+/** MMC/SD controller MSC0**/
+static struct resource jz_msc0_resources[] = {
+ {
+ .start = CPHYSADDR(MSC_BASE),
+ .end = CPHYSADDR(MSC_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC0,
+ .end = IRQ_MSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC0_RX,
+ .end = DMA_ID_MSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 jz_msc0_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc0_device = {
+ .name = "jz-msc0",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_msc0_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc0_resources),
+ .resource = jz_msc0_resources,
+};
+
+/** MMC/SD controller MSC1**/
+static struct resource jz_msc1_resources[] = {
+ {
+ .start = CPHYSADDR(MSC_BASE) + 0x1000,
+ .end = CPHYSADDR(MSC_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC1,
+ .end = IRQ_MSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC1_RX,
+ .end = DMA_ID_MSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+
+};
+
+static u64 jz_msc1_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc1_device = {
+ .name = "jz-msc1",
+ .id = 1,
+ .dev = {
+ .dma_mask = &jz_msc1_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc1_resources),
+ .resource = jz_msc1_resources,
+};
+
+static struct platform_device *jz_msc_devices[] __initdata = {
+ &jz_msc0_device,
+ &jz_msc1_device,
+};
+
+int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat)
+{
+ struct platform_device *pdev;
+
+ if (controller < 0 || controller > 1)
+ return -EINVAL;
+
+ pdev = jz_msc_devices[controller];
+
+ pdev->dev.platform_data = plat;
+
+ return platform_device_register(pdev);
+}
+#endif
/** I2C controller **/
@@ -161,12 +254,13 @@ static struct platform_device *jz_platform_devices[] __initdata = {
&jz_usb_ohci_device,
&jz_lcd_device,
&jz_usb_gdt_device,
- &jz_mmc_device,
+ // &jz_mmc_device,
&jz_i2c_device,
};
static int __init jz_platform_init(void)
{
+ board_msc_init();
return platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices));
}
diff --git a/arch/mips/jz4750/pm.c b/arch/mips/jz4750/pm.c
index 10476e276e1..eea9864e3e6 100644
--- a/arch/mips/jz4750/pm.c
+++ b/arch/mips/jz4750/pm.c
@@ -244,10 +244,14 @@ static int jz_pm_do_sleep(void)
unsigned long sadc = REG_SADC_ENA;
unsigned long sleep_gpio_save[7*(GPIO_PORT_NUM-1)];
+ unsigned long flags;
+
printk(JZ_SOC_NAME": Put CPU into sleep mode.\n");
/* Preserve current time */
delta = xtime.tv_sec - REG_RTC_RSR;
+
+ local_irq_save(flags);
/* Disable nand flash */
REG_EMC_NFCSR = ~0xff;
@@ -323,6 +327,8 @@ static int jz_pm_do_sleep(void)
/* Restore Oscillator and Power Control Register */
REG_CPM_OPCR = opcr;
+
+ local_irq_restore(flags);
/* Restore current time */
xtime.tv_sec = REG_RTC_RSR + delta;
@@ -336,33 +342,12 @@ int jz_pm_hibernate(void)
return jz_pm_do_hibernate();
}
-#ifndef CONFIG_JZ_POWEROFF
-static irqreturn_t pm_irq_handler (int irq, void *dev_id)
-{
- return IRQ_HANDLED;
-}
-#endif
-
/* Put CPU to SLEEP mode */
int jz_pm_sleep(void)
{
- int retval;
-
-#ifndef CONFIG_JZ_POWEROFF
- if ((retval = request_irq (IRQ_GPIO_0 + GPIO_WAKEUP, pm_irq_handler, IRQF_DISABLED,
- "PM", NULL))) {
- printk ("PM could not get IRQ for GPIO_WAKEUP\n");
- return retval;
- }
-#endif
-
jz_pm_do_sleep();
-#ifndef CONFIG_JZ_POWEROFF
- free_irq (IRQ_GPIO_0 + GPIO_WAKEUP, NULL);
-#endif
-
- return retval;
+ return 0;
}
/*
diff --git a/arch/mips/jz4750/time.c b/arch/mips/jz4750/time.c
index b5167d7ab19..0d997d1c10f 100644
--- a/arch/mips/jz4750/time.c
+++ b/arch/mips/jz4750/time.c
@@ -62,27 +62,27 @@ union clycle_type
cycle_t cycle64;
unsigned int cycle32[2];
};
-static union clycle_type old_cycle = {0};
cycle_t jz_get_cycles(struct clocksource *cs)
{
- /* convert jiffes to jz timer cycles */
- unsigned int ostcount;
- unsigned long cpuflags;
- unsigned int current_cycle;
-
- local_irq_save(cpuflags);
- current_cycle = current_cycle_high;
- ostcount = REG_TCU_OSTCNT;
- local_irq_restore(cpuflags);
- if((ostcount < old_cycle.cycle32[0]) && (current_cycle == old_cycle.cycle32[1])){
- old_cycle.cycle32[0] = ostcount;
- old_cycle.cycle32[1]++;
- }else{
- old_cycle.cycle32[0] = ostcount;
- old_cycle.cycle32[1] = current_cycle;
- }
- return (old_cycle.cycle64);
+ /* convert jiffes to jz timer cycles */
+ unsigned int ostcount;
+ unsigned long cpuflags;
+ unsigned int current_cycle;
+ unsigned int flag;
+ union clycle_type old_cycle;
+ local_irq_save(cpuflags);
+ current_cycle = current_cycle_high;
+ ostcount = REG_TCU_OSTCNT;
+ flag = (REG_TCU_TFR & TCU_TFCR_OSTFCL) ? 1: 0;
+ if(flag)
+ ostcount = REG_TCU_OSTCNT;
+ local_irq_restore(cpuflags);
+
+ old_cycle.cycle32[0] = ostcount;
+ old_cycle.cycle32[1] = current_cycle + flag;
+
+ return (old_cycle.cycle64);
}
diff --git a/arch/mips/jz4750d/i2c.c b/arch/mips/jz4750d/i2c.c
index c12142f02c9..7632b87b594 100644
--- a/arch/mips/jz4750d/i2c.c
+++ b/arch/mips/jz4750d/i2c.c
@@ -1,273 +1,388 @@
-/*
- * linux/arch/mips/jz4750d/i2c.c
- *
- * Jz4750D I2C routines.
- *
- * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
- * Author: <lhhuang@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/module.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-
-#include <asm/jzsoc.h>
-
-/* I2C protocol */
-#define I2C_READ 1
-#define I2C_WRITE 0
-
-#define TIMEOUT 1000
-
-/*
- * I2C bus protocol basic routines
- */
-static int i2c_put_data(unsigned char data)
-{
- unsigned int timeout = TIMEOUT*10;
-
- __i2c_write(data);
- __i2c_set_drf();
- while (__i2c_check_drf() != 0);
- while (!__i2c_transmit_ended());
- while (!__i2c_received_ack() && timeout)
- timeout--;
-
- if (timeout)
- return 0;
- else
- return -ETIMEDOUT;
-}
-
-#ifdef CONFIG_JZ_TPANEL_ATA2508
-static int i2c_put_data_nack(unsigned char data)
-{
- unsigned int timeout = TIMEOUT*10;
-
- __i2c_write(data);
- __i2c_set_drf();
- while (__i2c_check_drf() != 0);
- while (!__i2c_transmit_ended());
- while (timeout--);
- return 0;
-}
-#endif
-
-static int i2c_get_data(unsigned char *data, int ack)
-{
- int timeout = TIMEOUT*10;
-
- if (!ack)
- __i2c_send_nack();
- else
- __i2c_send_ack();
-
- while (__i2c_check_drf() == 0 && timeout)
- timeout--;
-
- if (timeout) {
- if (!ack)
- __i2c_send_stop();
- *data = __i2c_read();
- __i2c_clear_drf();
- return 0;
- } else
- return -ETIMEDOUT;
-}
-
-/*
- * I2C interface
- */
-void i2c_open(void)
-{
- __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */
- __i2c_enable();
-}
-
-void i2c_close(void)
-{
- udelay(300); /* wait for STOP goes over. */
- __i2c_disable();
-}
-
-void i2c_setclk(unsigned int i2cclk)
-{
- __i2c_set_clk(jz_clocks.extalclk, i2cclk);
-}
-
-int i2c_lseek(unsigned char device, unsigned char offset)
-{
- __i2c_send_nack(); /* Master does not send ACK, slave sends it */
- __i2c_send_start();
- if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
- goto device_err;
- if (i2c_put_data(offset) < 0)
- goto address_err;
- return 0;
- device_err:
- printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device);
- __i2c_send_stop();
- return -ENODEV;
- address_err:
- printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device);
- __i2c_send_stop();
- return -EREMOTEIO;
-}
-
-int i2c_read(unsigned char device, unsigned char *buf,
- unsigned char address, int count)
-{
- int cnt = count;
- int timeout = 5;
-
-L_try_again:
-
- if (timeout < 0)
- goto L_timeout;
-
- __i2c_send_nack(); /* Master does not send ACK, slave sends it */
- __i2c_send_start();
- if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
- goto device_werr;
- if (i2c_put_data(address) < 0)
- goto address_err;
-
- __i2c_send_start();
- if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
- goto device_rerr;
- __i2c_send_ack(); /* Master sends ACK for continue reading */
- while (cnt) {
- if (cnt == 1) {
- if (i2c_get_data(buf, 0) < 0)
- break;
- } else {
- if (i2c_get_data(buf, 1) < 0)
- break;
- }
- cnt--;
- buf++;
- }
-
- __i2c_send_stop();
- return count - cnt;
- device_rerr:
- device_werr:
- address_err:
- timeout --;
- __i2c_send_stop();
- goto L_try_again;
-
-L_timeout:
- __i2c_send_stop();
- printk("Read I2C device 0x%2x failed.\n", device);
- return -ENODEV;
-}
-
-int i2c_write(unsigned char device, unsigned char *buf,
- unsigned char address, int count)
-{
- int cnt = count;
- int cnt_in_pg;
- int timeout = 5;
- unsigned char *tmpbuf;
- unsigned char tmpaddr;
-
- __i2c_send_nack(); /* Master does not send ACK, slave sends it */
-
- W_try_again:
- if (timeout < 0)
- goto W_timeout;
-
- cnt = count;
- tmpbuf = (unsigned char *)buf;
- tmpaddr = address;
-
- start_write_page:
- cnt_in_pg = 0;
- __i2c_send_start();
- if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
- goto device_err;
-#ifdef CONFIG_JZ_TPANEL_ATA2508
- if (address == 0xff) {
- if (i2c_put_data_nack(tmpaddr) < 0)
- goto address_err;
- while (cnt) {
- if (++cnt_in_pg > 8) {
- __i2c_send_stop();
- mdelay(1);
- tmpaddr += 8;
- goto start_write_page;
- }
- if (i2c_put_data_nack(*tmpbuf) < 0)
- break;
- cnt--;
- tmpbuf++;
- }
- }
- else {
-
- if (i2c_put_data(tmpaddr) < 0)
- goto address_err;
- while (cnt) {
- if (++cnt_in_pg > 8) {
- __i2c_send_stop();
- mdelay(1);
- tmpaddr += 8;
- goto start_write_page;
- }
- if (i2c_put_data(*tmpbuf) < 0)
- break;
- cnt--;
- tmpbuf++;
- }
- }
-#else
- if (i2c_put_data(tmpaddr) < 0)
- goto address_err;
- while (cnt) {
- if (++cnt_in_pg > 8) {
- __i2c_send_stop();
- mdelay(1);
- tmpaddr += 8;
- goto start_write_page;
- }
- if (i2c_put_data(*tmpbuf) < 0)
- break;
- cnt--;
- tmpbuf++;
- }
-#endif
- __i2c_send_stop();
- return count - cnt;
- device_err:
- address_err:
- timeout--;
- __i2c_send_stop();
- goto W_try_again;
-
- W_timeout:
- printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device);
- __i2c_send_stop();
- return -ENODEV;
-}
-
-EXPORT_SYMBOL(i2c_open);
-EXPORT_SYMBOL(i2c_close);
-EXPORT_SYMBOL(i2c_setclk);
-EXPORT_SYMBOL(i2c_read);
-EXPORT_SYMBOL(i2c_write);
+/*
+ * linux/arch/mips/jz4750/i2c.c
+ *
+ * JZ4750 Simple I2C Driver.
+ *
+ * Copyright (c) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River <zwang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/jzsoc.h>
+
+#define I2C_BUS_TIMING_START_HOLD 1 /* us */
+#define I2C_BUS_TIMING_STOP_HOLD 10 /* us */
+
+#define I2C_CTRL_WAIT_ENABLE 1 /* us */
+#define I2C_CTRL_WAIT_DISABLE 1 /* us */
+
+#define PFX "I_I2C"
+
+#define D(fmt, args...) \
+// printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args)
+
+#define E(fmt, args...) \
+ printk(KERN_ERR PFX": %s(): LINE: %d - "fmt"\n", __func__, __LINE__, ##args)
+
+/* Controller. */
+struct i2c_ctrl {
+ spinlock_t lock;
+
+ unsigned long clk;
+};
+
+static struct i2c_ctrl g_i2c_ctrl;
+
+static inline void i2c_ctrl_enable(void)
+{
+ D("Called.");
+
+ __i2c_enable();
+
+ udelay(I2C_CTRL_WAIT_ENABLE);
+
+ return;
+}
+
+static inline void i2c_ctrl_disable(void)
+{
+ D("Called.");
+
+ __i2c_disable();
+
+ udelay(I2C_CTRL_WAIT_DISABLE);
+
+ return;
+}
+
+static inline void i2c_ctrl_set_clk(unsigned long clk)
+{
+ struct i2c_ctrl *ctrl = &g_i2c_ctrl;
+
+ D("Called.");
+
+ if (ctrl->clk != clk) {
+ D("Set clock.");
+
+ __i2c_set_clk(jz_clocks.extalclk, clk);
+ ctrl->clk = clk;
+
+ mdelay(1);
+ }
+
+ return;
+}
+
+/*
+ * I2C bus protocol basic routines
+ */
+static inline int __i2c_put_data(unsigned char data, unsigned long timeout)
+{
+ unsigned long t;
+
+ __i2c_write(data);
+ __i2c_set_drf();
+
+ t = timeout;
+ while (__i2c_check_drf() != 0 && t)
+ t--;
+
+ if (!t) {
+ E("__i2c_check_drf() timeout, Data: 0x%x. timeout: %lu.", data, timeout);
+ return -ETIMEDOUT;
+ }
+
+ while (!__i2c_transmit_ended() && t)
+ t--;
+
+ if (!t) {
+ E("__i2c_transmit_ended() timeout, Data: 0x%x, timeout: %lu.", data, timeout);
+ return -ETIMEDOUT;
+ }
+
+ t = timeout;
+ while (!__i2c_received_ack() && t)
+ t--;
+
+ if (!t) {
+ E("__i2c_received_ack() timeout, Data: 0x%x, timeout: %lu.", data, timeout);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static inline int __i2c_get_data(unsigned char *data, int ack, unsigned long timeout)
+{
+ unsigned long t;
+
+ ack ? __i2c_send_ack() : __i2c_send_nack();
+
+ t = timeout;
+ while (__i2c_check_drf() == 0 && t)
+ t--;
+
+ if (!t) {
+ E("__i2c_check_drf() timeout. timeout: %lu", timeout);
+ return -ETIMEDOUT;
+ }
+
+ *data = __i2c_read();
+
+ __i2c_clear_drf();
+
+ return 0;
+}
+
+static inline int put_data(struct i_i2c_dev *dev, unsigned char data)
+{
+ return __i2c_put_data(data, dev->timing->timeout);
+}
+
+static inline int get_data(struct i_i2c_dev *dev, unsigned char *data, int ack)
+{
+ return __i2c_get_data(data, ack, dev->timing->timeout);
+}
+
+static inline void i2c_start(void)
+{
+ __i2c_send_start();
+
+ udelay(I2C_BUS_TIMING_START_HOLD);
+
+ return;
+}
+
+static inline void i2c_stop(void)
+{
+ __i2c_send_stop();
+
+ udelay(I2C_BUS_TIMING_STOP_HOLD);
+
+ return;
+}
+
+static inline int i2c_start_and_send_address(struct i_i2c_dev *dev, off_t off, int dir)
+{
+ unsigned int ra = ((dev->address << 1) & 0xff) | 0x1;
+ unsigned int wa = ((dev->address << 1) & 0xff);
+
+ int rv;
+
+ i2c_start();
+
+ if (put_data(dev, wa) < 0) {
+ E("Failed to send write address.");
+ rv = -ENODEV;
+ goto err;
+ }
+
+ if (dev->cap & I_I2C_CAP_16BIT_OFFSET_MSB) {
+ if (put_data(dev, (off >> 8) & 0xFF) < 0) {
+ E("Failed to send off >> 8 MSB.");
+ rv = -EINVAL;
+ goto err;
+ }
+ }
+
+ if (put_data(dev, (off & 0xFF)) < 0) {
+ E("Failed to send off.");
+ rv = -EINVAL;
+ goto err;
+ }
+
+ if (dev->cap & I_I2C_CAP_16BIT_OFFSET_LSB) {
+ if (put_data(dev, (off >> 8) & 0xFF) < 0) {
+ E("Failed to send off >> 8 LSB.");
+ rv = -EINVAL;
+ goto err;
+ }
+ }
+
+ if (dir == I_I2C_IO_DIR_READ) {
+ if (dev->flags & I_I2C_FLAG_STOP_BEFORE_RESTART)
+ i2c_stop();
+
+ i2c_start();
+
+ if (put_data(dev, ra) < 0) {
+ E("Failed to send read address.");
+ rv = -ENODEV;
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ i2c_stop();
+ return rv;
+}
+
+static inline int i2c_read_data(struct i_i2c_dev *dev, char *buf, size_t count)
+{
+ int i, rv;
+ int ack = 1;
+
+// D("buf: 0x%p, count: %d.", buf, count);
+
+ for (i = 0; i < count; i++) {
+ if (i == count - 1) {
+// D("Nack.");
+ ack = 0;
+ }
+
+ rv = get_data(dev, buf + i, ack);
+ if (rv) {
+ E("get_data() failed: rv: %d i: %d.", rv, i);
+ return rv;
+ }
+ }
+
+ return 0;
+}
+
+static inline int i2c_write_data(struct i_i2c_dev *dev, char *buf, size_t count)
+{
+ unsigned long i;
+ int rv;
+
+// D("buf: 0x%p, count: %d.", buf, count);
+
+ for (i = 0; i < count; i++) {
+ rv = put_data(dev, buf[i]);
+ if (rv) {
+ E("put_data() failed: %d.\n", rv);
+ return rv;
+ }
+ }
+
+ return 0;
+}
+
+static int do_i2c(struct i_i2c_dev *dev, off_t off, char *buf, size_t count, int dir)
+{
+ struct i2c_ctrl *ctrl = &g_i2c_ctrl;
+ struct i_i2c_timing *timing = dev->timing;
+
+ unsigned long flags;
+ unsigned long io_size, size;
+
+ unsigned long i;
+ int rv = 0;
+
+ spin_lock_irqsave(&ctrl->lock, flags);
+
+ i2c_ctrl_enable();
+ i2c_ctrl_set_clk(timing->clk);
+
+ io_size = dir ? dev->write_size : dev->read_size;
+ size = count < io_size ? count : io_size;
+
+ for (i = 0; i < count; i += io_size) {
+ rv = i2c_start_and_send_address(dev, off + i, dir);
+ if (rv) {
+ E("i2c_start_and_send_address() failed: %d, i: %lu.", rv, i);
+ i2c_stop();
+ goto err;
+ }
+
+// D("Pass send address.");
+
+ if (!dir)
+ rv = i2c_read_data(dev, buf + i, size);
+ else
+ rv = i2c_write_data(dev, buf + i, size);
+
+// D("Pass rw data.");
+
+ if (rv) {
+ E("i2c_read/write_data() failed: %d, i: %lu.", rv, i);
+ i2c_stop();
+ goto err;
+ }
+
+ i2c_stop();
+
+ if (dir && timing->t_wr)
+ mdelay(timing->t_wr);
+ }
+
+err:
+ i2c_ctrl_disable();
+
+ spin_unlock_irqrestore(&ctrl->lock, flags);
+
+ return rv;
+}
+
+/*
+ * I2C interface
+ */
+int i_i2c_read_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
+{
+ D("off: %d, buf: 0x%p, count: %d.", off, buf, count);
+
+ return do_i2c(dev, off, buf, count, 0);
+}
+EXPORT_SYMBOL(i_i2c_read_dev);
+
+int i_i2c_write_dev(struct i_i2c_dev *dev, off_t off, void *buf, size_t count)
+{
+ D("off: %d, buf: 0x%p, count: %d.", off, buf, count);
+
+ return do_i2c(dev, off, buf, count, 1);
+}
+EXPORT_SYMBOL(i_i2c_write_dev);
+
+int i_i2c_init_dev(struct i_i2c_dev *dev)
+{
+ struct i_i2c_timing *timing = dev->timing;
+
+ if (!timing) {
+ printk(KERN_ERR PFX": %s(): Please setup the timing of I2C device: 0x%p.\n", __func__, dev);
+ return -EINVAL;
+ }
+
+ if (!timing->timeout)
+ timing->timeout = (100 * 1000);
+
+ if (!timing->clk)
+ timing->clk = (100 * 1000); /* default 100 KHz */
+
+ if (!(dev->cap & I_I2C_CAP_SEQ_READ))
+ dev->read_size = 1;
+
+ if (!(dev->cap & I_I2C_CAP_SEQ_WRITE))
+ dev->write_size = 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(i_i2c_init_dev);
+
+static int __init i_i2c_init(void)
+{
+ struct i2c_ctrl *ctrl = &g_i2c_ctrl;
+
+ spin_lock_init(&ctrl->lock);
+
+ __gpio_as_i2c();
+
+ i2c_ctrl_set_clk(100 * 1000);
+
+ printk(KERN_INFO JZ_SOC_NAME": Simple I2C Driver Registered.\n");
+
+ return 0;
+}
+
+module_init(i_i2c_init);
diff --git a/arch/mips/jz4750d/pm.c b/arch/mips/jz4750d/pm.c
index 611fcadfebf..8fc39a31b77 100644
--- a/arch/mips/jz4750d/pm.c
+++ b/arch/mips/jz4750d/pm.c
@@ -242,11 +242,15 @@ static int jz_pm_do_sleep(void)
unsigned long imr = REG_INTC_IMR;
unsigned long sadc = REG_SADC_ENA;
unsigned long sleep_gpio_save[7*(GPIO_PORT_NUM-1)];
-
+
+ unsigned long flags;
+
printk("Put CPU into sleep mode.\n");
/* Preserve current time */
delta = xtime.tv_sec - REG_RTC_RSR;
+
+ local_irq_save(flags);
/* Disable nand flash */
REG_EMC_NFCSR = ~0xff;
@@ -272,6 +276,7 @@ static int jz_pm_do_sleep(void)
/* enable RTC alarm */
__intc_unmask_irq(IRQ_RTC);
+
#if 0
/* make system wake up after n seconds by RTC alarm */
unsigned int v, n;
@@ -322,7 +327,9 @@ static int jz_pm_do_sleep(void)
/* Restore Oscillator and Power Control Register */
REG_CPM_OPCR = opcr;
-
+
+ local_irq_restore(flags);
+
/* Restore current time */
xtime.tv_sec = REG_RTC_RSR + delta;
@@ -335,33 +342,10 @@ int jz_pm_hibernate(void)
return jz_pm_do_hibernate();
}
-#ifndef CONFIG_JZ_POWEROFF
-static irqreturn_t pm_irq_handler (int irq, void *dev_id)
-{
- return IRQ_HANDLED;
-}
-#endif
-
/* Put CPU to SLEEP mode */
int jz_pm_sleep(void)
{
- int retval;
-
-#ifndef CONFIG_JZ_POWEROFF
- if ((retval = request_irq (IRQ_GPIO_0 + GPIO_WAKEUP, pm_irq_handler, IRQF_DISABLED,
- "PM", NULL))) {
- printk ("PM could not get IRQ for GPIO_WAKEUP\n");
- return retval;
- }
-#endif
-
- retval = jz_pm_do_sleep();
-
-#ifndef CONFIG_JZ_POWEROFF
- free_irq (IRQ_GPIO_0 + GPIO_WAKEUP, NULL);
-#endif
-
- return retval;
+ return jz_pm_do_sleep();
}
/*
diff --git a/arch/mips/jz4750d/time.c b/arch/mips/jz4750d/time.c
index 406e63df937..0d997d1c10f 100644
--- a/arch/mips/jz4750d/time.c
+++ b/arch/mips/jz4750d/time.c
@@ -1,7 +1,7 @@
/*
- * linux/arch/mips/jz4750d/time.c
+ * linux/arch/mips/jz4750/time.c
*
- * Setting up the clock on the JZ4750D boards.
+ * Setting up the clock on the JZ4750 boards.
*
* Copyright (C) 2008 Ingenic Semiconductor Inc.
* Author: <jlwei@ingenic.cn>
@@ -24,14 +24,13 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/clockchips.h>
-
#include <asm/time.h>
#include <asm/jzsoc.h>
/* This is for machines which generate the exact clock. */
-#define JZ_TIMER_IRQ IRQ_TCU0
-
+#define JZ_TIMER_TCU_CH 5
+#define JZ_TIMER_IRQ IRQ_TCU1
#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */
static struct clocksource clocksource_jz; /* Jz clock source */
@@ -42,9 +41,7 @@ void (*jz_timer_callback)(void);
static irqreturn_t jz_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = dev_id;
-
- REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */
-
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
if (jz_timer_callback)
jz_timer_callback();
@@ -59,13 +56,37 @@ static struct irqaction jz_irqaction = {
.name = "jz-timerirq",
};
+static unsigned int current_cycle_high = 0;
+union clycle_type
+{
+ cycle_t cycle64;
+ unsigned int cycle32[2];
+};
cycle_t jz_get_cycles(struct clocksource *cs)
{
/* convert jiffes to jz timer cycles */
- return (cycle_t)( jiffies*((JZ_TIMER_CLOCK)/HZ) + REG_TCU_OSTCNT);
+ unsigned int ostcount;
+ unsigned long cpuflags;
+ unsigned int current_cycle;
+ unsigned int flag;
+ union clycle_type old_cycle;
+ local_irq_save(cpuflags);
+ current_cycle = current_cycle_high;
+ ostcount = REG_TCU_OSTCNT;
+ flag = (REG_TCU_TFR & TCU_TFCR_OSTFCL) ? 1: 0;
+ if(flag)
+ ostcount = REG_TCU_OSTCNT;
+ local_irq_restore(cpuflags);
+
+ old_cycle.cycle32[0] = ostcount;
+ old_cycle.cycle32[1] = current_cycle + flag;
+
+ return (old_cycle.cycle64);
}
+
+
static struct clocksource clocksource_jz = {
.name = "jz_clocksource",
.rating = 300,
@@ -75,10 +96,44 @@ static struct clocksource clocksource_jz = {
.flags = CLOCK_SOURCE_WATCHDOG,
};
+
+
+static irqreturn_t jzclock_handler(int irq, void *dev_id)
+{
+ REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */
+ current_cycle_high++;
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz_clockaction = {
+ .handler = jzclock_handler,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "jz-clockcycle",
+};
static int __init jz_clocksource_init(void)
{
+ unsigned int latch;
+
+ /* Init timer */
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift);
clocksource_register(&clocksource_jz);
+ //---------------------init sys clock -----------------
+
+ REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN;
+
+ REG_TCU_OSTCNT = 0;
+ REG_TCU_OSTDR = 0xffffffff;
+
+ jz_clockaction.dev_id = &clocksource_jz;
+
+ setup_irq(IRQ_TCU0, &jz_clockaction);
+ REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */
+ REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */
+ REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */
+
+ //---------------------endif init sys clock -----------------
return 0;
}
@@ -109,6 +164,7 @@ static struct clock_event_device jz_clockevent_device = {
// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */
/* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+ .mult = 1,
.rating = 300,
.irq = JZ_TIMER_IRQ,
.set_mode = jz_set_mode,
@@ -119,38 +175,40 @@ static void __init jz_clockevent_init(void)
{
struct clock_event_device *cd = &jz_clockevent_device;
unsigned int cpu = smp_processor_id();
-
cd->cpumask = cpumask_of(cpu);
clockevents_register_device(cd);
}
static void __init jz_timer_setup(void)
{
+ unsigned int latch;
+
jz_clocksource_init(); /* init jz clock source */
jz_clockevent_init(); /* init jz clock event */
+ //---------------------init sys tick -----------------
+ /* Init timer */
+ __tcu_stop_counter(JZ_TIMER_TCU_CH);
+ __cpm_start_tcu();
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
+ REG_TCU_TMSR = ((1 << JZ_TIMER_TCU_CH) | (1 << (JZ_TIMER_TCU_CH + 16)));
+ REG_TCU_TCSR(JZ_TIMER_TCU_CH) = TCU_TCSR_PRESCALE16 | TCU_TCSR_EXT_EN;
+ REG_TCU_TDFR(JZ_TIMER_TCU_CH) = latch - 1;
+ REG_TCU_TDHR(JZ_TIMER_TCU_CH) = latch + 1;
+ REG_TCU_TCNT(JZ_TIMER_TCU_CH) = 0;
/*
* Make irqs happen for the system timer
*/
jz_irqaction.dev_id = &jz_clockevent_device;
setup_irq(JZ_TIMER_IRQ, &jz_irqaction);
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
+ __tcu_unmask_full_match_irq(JZ_TIMER_TCU_CH);
+ __tcu_start_counter(JZ_TIMER_TCU_CH);
}
void __init plat_time_init(void)
{
- unsigned int latch;
-
- /* Init timer */
- latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
-
- REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN;
- REG_TCU_OSTCNT = 0;
- REG_TCU_OSTDR = latch;
-
- REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */
- REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */
- REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */
-
jz_timer_setup();
}
diff --git a/arch/mips/jz4760/Makefile b/arch/mips/jz4760/Makefile
new file mode 100644
index 00000000000..a03e184c0dd
--- /dev/null
+++ b/arch/mips/jz4760/Makefile
@@ -0,0 +1,29 @@
+#
+# Makefile for the Ingenic JZ4760.
+#
+
+# Object file lists.
+
+obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
+ platform.o cpm.o #i2c.o
+
+obj-$(CONFIG_PROC_FS) += proc.o
+
+# board specific support
+obj-$(CONFIG_JZ4760_ALTAIR) += board-altair.o
+obj-$(CONFIG_JZ4760_CYGNUS) += board-cygnus.o
+obj-$(CONFIG_JZ4760_LEPUS) += board-lepus.o
+
+obj-$(CONFIG_JZ4760_F4760) += board-f4760.o
+obj-$(CONFIG_SOC_JZ4760) += fpu.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o sleep.o
+
+# CPU Frequency scaling support
+
+obj-$(CONFIG_CPU_FREQ_JZ) += cpufreq.o
+
+#obj-$(CONFIG_JZ4760_ALTAIR) += gpiolib.o
+
diff --git a/arch/mips/jz4760/board-altair.c b/arch/mips/jz4760/board-altair.c
new file mode 100644
index 00000000000..0dc75377b53
--- /dev/null
+++ b/arch/mips/jz4760/board-altair.c
@@ -0,0 +1,557 @@
+/*
+ * linux/arch/mips/jz4760/board-altair.c
+ *
+ * JZ4760 Altair board setup routines.
+ *
+ * Copyright (c) 2006-2010 Ingenic Semiconductor Inc.
+ *
+ * Author: Jason<xwang@ingenic>
+ * Based on board-cygnus.c
+ *
+ * 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/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+/*
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/watchdog.h>
+#include <linux/mfd/wm831x/status.h>
+*/
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+//#include <linux/timed_gpio.h>
+
+#include <asm/jzsoc.h>
+//#include <asm/jzmmc/jz_mmc_platform_data.h>
+
+#define WM831X_LDO_MAX_NAME 6
+
+void __init board_msc_init(void);
+
+//extern int jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat);
+extern void (*jz_timer_callback)(void);
+
+#if 0
+static void dancing(void)
+{
+ static unsigned char slash[] = "\\|/-";
+// static volatile unsigned char *p = (unsigned char *)0xb6000058;
+ static volatile unsigned char *p = (unsigned char *)0xb6000016;
+ static unsigned int count = 0;
+ *p = slash[count++];
+ count &= 3;
+}
+#endif
+
+/* MSC SETUP */
+/*
+static void altair_sdio_gpio_init(struct device *dev)
+{
+ __gpio_as_msc0_4bit();
+
+ // BT/WLAN reset
+ __gpio_as_output(17); //GPA17
+ __gpio_clear_pin(17);
+ mdelay(10);
+ __gpio_as_input(17);
+}
+
+static void altair_sdio_power_on(struct device *dev)
+{
+ __msc0_enable_power();
+}
+
+static void altair_sdio_power_off(struct device *dev)
+{
+ __msc0_disable_power();
+}
+
+static unsigned int altair_sdio_status(struct device *dev)
+{
+ unsigned int status;
+
+ // WIFI virtual 'card detect' status
+ status = 1;
+ return (status);
+}
+
+static struct jz_mmc_platform_data altair_sdio_data = {
+ .support_sdio = 1,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .init = altair_sdio_gpio_init,
+ .power_on = altair_sdio_power_on,
+ .power_off = altair_sdio_power_off,
+ .status = altair_sdio_status,
+ .max_bus_width = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_8_BIT_DATA,
+#ifdef CONFIG_JZ_MSC0_BUS_1
+ .bus_width = 1,
+#elif defined CONFIG_JZ_MSC0_BUS_4
+ .bus_width = 4,
+#else
+ .bus_width = 8,
+#endif
+};
+
+static void altair_tf_gpio_init(struct device *dev)
+{
+ __gpio_as_msc1_4bit();
+ __gpio_as_output(GPIO_SD1_VCC_EN_N);
+}
+
+static void altair_tf_power_on(struct device *dev)
+{
+ __msc1_enable_power();
+}
+
+static void altair_tf_power_off(struct device *dev)
+{
+ __msc1_disable_power();
+}
+
+static unsigned int altair_tf_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD1_CD_N);
+ return (status);
+}
+
+static void altair_tf_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_low_level(MSC1_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_high_level(MSC1_HOTPLUG_PIN);
+}
+
+static struct jz_mmc_platform_data altair_tf_data = {
+#ifndef CONFIG_JZ_MSC1_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC1_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD1_CD_N,
+ .init = altair_tf_gpio_init,
+ .power_on = altair_tf_power_on,
+ .power_off = altair_tf_power_off,
+ .status = altair_tf_status,
+ .plug_change = altair_tf_plug_change,
+ .max_bus_width = MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC1_BUS_1
+ .bus_width = 1,
+#else
+ .bus_width = 4,
+#endif
+};
+
+void __init board_msc_init(void)
+{
+#ifdef CONFIG_JZ_MSC0
+ jz_add_msc_devices(0, &altair_sdio_data);
+#endif
+
+#ifdef CONFIG_JZ_MSC1
+ jz_add_msc_devices(1, &altair_tf_data);
+#endif
+}
+
+*/
+
+static void f4760_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+// dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4760/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ __jtag_as_uart3(); /* for GSM modem IW368 */
+}
+
+void __init jz_board_setup(void)
+{
+ printk("JZ4760 Altair board setup\n");
+// jz_restart(NULL);
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = f4760_timer_callback;
+}
+
+/**
+ * Called by arch/mips/kernel/proc.c when 'cat /proc/cpuinfo'.
+ * Android requires the 'Hardware:' field in cpuinfo to setup the init.%hardware%.rc.
+ */
+const char *get_board_type(void)
+{
+ return "Altair";
+}
+
+/*****
+ * Wm831x init
+ *****/
+
+/*
+struct wm831x_ldo {
+ char name[WM831X_LDO_MAX_NAME];
+ struct regulator_desc desc;
+ int base;
+ struct wm831x *wm831x;
+ struct regulator_dev *regulator;
+};
+
+static int wm8310_pre_init(struct wm831x *wm831x){
+ //close all wm831x regulator .
+ int ret;
+
+ ret = wm831x_set_bits(wm831x,WM831X_LDO_ENABLE,0x7ff,0);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to close all ldo: %d\n",ret);
+
+ return 0;
+}
+
+static int wm8310_post_init(struct wm831x *wm831x){
+
+ int ret;
+
+ ret = wm831x_reg_unlock(wm831x);
+ if (ret != 0) {
+ dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret);
+ return -1;
+ }
+
+ // close wm831x watchdog
+ ret = wm831x_set_bits(wm831x,WM831X_WATCHDOG,WM831X_WDOG_ENA,0);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to close watchdog: %d\n",ret);
+
+ // set ON pin timeout period and set secondary action as irq
+
+ ret = wm831x_set_bits(wm831x,WM831X_ON_PIN_CONTROL,
+ WM831X_ON_PIN_SECACT_MASK |
+ WM831X_ON_PIN_PRIMACT_MASK |
+ WM831X_ON_PIN_TO_MASK,
+ WM831X_ON_PIN_AS_IRQ );
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to set ON pin timeout period: %d\n",ret);
+
+ wm831x_reg_lock(wm831x);
+ //set wm831x LED1 as a flag of charge status
+ ret = wm831x_set_bits(wm831x,WM831X_STATUS_LED_1,WM831X_LED1_MASK,
+ WM831X_LED1_CHARGE_STATE);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to set status of charge on led1: %d\n",ret);
+
+ return 0;
+}
+
+struct wm831x_backlight_pdata wm8310_backlight = {
+
+ .isink = 1,
+ .max_uA = 3000,
+};
+static struct wm831x_battery_pdata wm8310_battery_data={
+
+ .enable = 1,
+ .fast_enable = 1,
+ .off_mask = 0,
+ .trickle_ilim = 50,
+ .vsel = 4200,
+ .eoc_iterm = 50,
+ .fast_ilim = 400,
+ .timeout = 300,
+};
+
+struct wm831x_status_pdata wm8310_led_status[] = {
+ {
+ .default_src = WM831X_STATUS_CHARGER,
+ .name = "wm831x-status",
+ },
+};
+
+static struct regulator_init_data wm8310_dcdc[]={
+ {
+ .constraints = {
+ .name = "wm831x-dcdc1",
+// .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc2",
+// .boot_on = 1,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc3",
+// .boot_on = 1,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc4",
+// .boot_on = 1,
+ },
+ },
+};
+
+static int wm8310_ldo1_init( void *driver_data )
+{
+ return 0;
+}
+struct wm831x_ldo ldo1_driver_data = {
+ .base = WM831X_LDO1_CONTROL,
+};
+
+static struct regulator_init_data wm8310_ldo[]={
+ {
+ .constraints = {
+ .name = "wm831x-ldo1",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+ .regulator_init = &wm8310_ldo1_init,
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo2",
+ .apply_uV = 1,
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo3",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 1,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo4",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo5",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo6",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo7",
+ .apply_uV = 1,
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo8",
+ .apply_uV = 1,
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo9",
+ .apply_uV = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo10",
+ .apply_uV = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo11",
+ .boot_on = 0,
+ },
+
+ },
+
+};
+
+static struct wm831x_pdata wm831x_platform_data = {
+ .pre_init = &wm8310_pre_init,
+ .post_init = &wm8310_post_init,
+ .backlight = &wm8310_backlight,
+ .battery = &wm8310_battery_data,
+ .dcdc = { wm8310_dcdc, wm8310_dcdc+1, wm8310_dcdc+2, wm8310_dcdc+3 },
+ .ldo = {
+ wm8310_ldo, wm8310_ldo+1,wm8310_ldo+2,wm8310_ldo+3,
+ wm8310_ldo+4,wm8310_ldo+5,wm8310_ldo+6,wm8310_ldo+7,
+ wm8310_ldo+8,wm8310_ldo+9,wm8310_ldo+10
+ },
+};
+
+static struct i2c_board_info wm831x_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8310", 0x34),
+ .irq = GPIO_WM831x_DETECT + IRQ_GPIO_0,
+ .platform_data = &wm831x_platform_data,
+ },
+};
+*/
+
+static struct i2c_board_info altair_i2c0_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("ov3640", 0x3c),
+ },
+ {
+ },
+};
+
+static struct i2c_board_info altair_i2c1_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("jz_mt4d_ts", 0x40),
+ .irq = LCD_INT_IRQ,
+ },
+ {
+ },
+};
+
+static struct i2c_board_info altair_gpio_i2c_devs[] __initdata = {
+#if 0
+ {
+ I2C_BOARD_INFO("jz_mt4d_ts", 0x40),
+ .irq = LCD_INT_IRQ,
+ },
+#endif
+ {
+ },
+};
+
+static struct i2c_gpio_platform_data altair_i2c_gpio_data = {
+ .sda_pin = CIM_I2C_SDA,
+ .scl_pin = CIM_I2C_SCK,
+};
+
+static struct platform_device altair_i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &altair_i2c_gpio_data,
+ },
+};
+
+/*
+struct timed_gpio vibrator_timed_gpio = {
+ .name = "vibrator",
+// .gpio = GPIO_VIBRATOR_EN_N,
+ .active_low = 1,
+ .max_timeout = 15000,
+};
+
+static struct timed_gpio_platform_data vibrator_platform_data = {
+ .num_gpios = 1,
+ .gpios = &vibrator_timed_gpio,
+};
+
+static struct platform_device altair_timed_gpio_device = {
+ .name = TIMED_GPIO_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &vibrator_platform_data,
+ },
+
+};
+
+static struct platform_device *altair_platform_devices[] __initdata = {
+ &altair_timed_gpio_device,
+ &altair_i2c_gpio_device,
+};
+*/
+
+static int __init altair_board_init( void )
+{
+// i2c_register_board_info(1, wm831x_i2c_devs, ARRAY_SIZE(wm831x_i2c_devs));
+ i2c_register_board_info(0, altair_i2c0_devs, ARRAY_SIZE(altair_i2c0_devs));
+ i2c_register_board_info(1, altair_i2c1_devs, ARRAY_SIZE(altair_i2c1_devs));
+ i2c_register_board_info(2, altair_gpio_i2c_devs, ARRAY_SIZE(altair_gpio_i2c_devs));
+// platform_add_devices(altair_platform_devices, ARRAY_SIZE(altair_platform_devices));
+
+ /*
+ * for gpio-based bitbanging i2c bus
+ */
+ __gpio_as_output(IOSWITCH_EN);
+ __gpio_clear_pin(IOSWITCH_EN);
+
+ return 0;
+}
+
+arch_initcall(altair_board_init);
diff --git a/arch/mips/jz4760/board-cygnus.c b/arch/mips/jz4760/board-cygnus.c
new file mode 100644
index 00000000000..9624b211c25
--- /dev/null
+++ b/arch/mips/jz4760/board-cygnus.c
@@ -0,0 +1,451 @@
+/*
+ * linux/arch/mips/jz4760/board-cygnus.c
+ *
+ * JZ4760 Cygnus board setup routines.
+ *
+ * Copyright (c) 2006-2010 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+//#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/jzsoc.h>
+
+extern void (*jz_timer_callback)(void);
+//extern int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat);
+
+void __init board_msc_init(void);
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+/*
+ * __gpio_as_sleep set all pins to pull-disable, and set all pins as input
+ * except sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+#define __gpio_as_sleep() \
+do { \
+ REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXSELC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXPES(1) = 0xffffffff; \
+ REG_GPIO_PXFUNC(2) = ~0x01e00000; \
+ REG_GPIO_PXSELC(2) = ~0x01e00000; \
+ REG_GPIO_PXDIRC(2) = ~0x01e00000; \
+ REG_GPIO_PXPES(2) = 0xffffffff; \
+ REG_GPIO_PXFUNC(3) = 0xffffffff; \
+ REG_GPIO_PXSELC(3) = 0xffffffff; \
+ REG_GPIO_PXDIRC(3) = 0xffffffff; \
+ REG_GPIO_PXPES(3) = 0xffffffff; \
+ REG_GPIO_PXFUNC(4) = 0xffffffff; \
+ REG_GPIO_PXSELC(4) = 0xffffffff; \
+ REG_GPIO_PXDIRC(4) = 0xffffffff; \
+ REG_GPIO_PXPES(4) = 0xffffffff; \
+ REG_GPIO_PXFUNC(5) = 0xffffffff; \
+ REG_GPIO_PXSELC(5) = 0xffffffff; \
+ REG_GPIO_PXDIRC(5) = 0xffffffff; \
+ REG_GPIO_PXPES(5) = 0xffffffff; \
+} while (0)
+
+struct wakeup_key_s {
+ int gpio; /* gpio pin number */
+ int active_low; /* the key interrupt pin is low voltage
+ or fall edge acitve */
+};
+
+/* add wakeup keys here */
+static struct wakeup_key_s wakeup_key[] = {
+ {
+ .gpio = KEY_C0,
+ .active_low = 1,
+ },
+ {
+ .gpio = KEY_C1,
+ .active_low = 1,
+ },
+ {
+ .gpio = KEY_C2,
+ .active_low = 1,
+ },
+ {
+ .gpio = KEY_C3,
+ .active_low = 1,
+ },
+ {
+ .gpio = KEY_C4,
+ .active_low = 1,
+ },
+#if defined(CONFIG_GSM_IW368)
+ {
+ .gpio = GPIO_GSM_RI,
+ .active_low = 1,
+ },
+#endif
+};
+
+static void wakeup_key_setup(void)
+{
+ int i;
+ int num = sizeof(wakeup_key) / sizeof(wakeup_key[0]);
+
+ for(i = 0; i < num; i++) {
+#if 1
+ if(wakeup_key[i].active_low)
+ __gpio_as_irq_fall_edge(wakeup_key[i].gpio);
+ else
+ __gpio_as_irq_rise_edge(wakeup_key[i].gpio);
+#endif
+ __gpio_ack_irq(wakeup_key[i].gpio);
+ __gpio_unmask_irq(wakeup_key[i].gpio);
+ __intc_unmask_irq(IRQ_GPIO0 - (wakeup_key[i].gpio/32)); /* unmask IRQ_GPIOn */
+ }
+}
+
+
+/* NOTES:
+ * 1: Pins that are floated (NC) should be set as input and pull-enable.
+ * 2: Pins that are pull-up or pull-down by outside should be set as input
+ * and pull-disable.
+ * 3: Pins that are connected to a chip except sdram and nand flash
+ * should be set as input and pull-disable, too.
+ */
+void jz_board_do_sleep(unsigned long *ptr)
+{
+ unsigned char i;
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("run dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+
+ /* Save GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ *ptr++ = REG_GPIO_PXFUN(i);
+ *ptr++ = REG_GPIO_PXSEL(i);
+ *ptr++ = REG_GPIO_PXDIR(i);
+ *ptr++ = REG_GPIO_PXPE(i);
+ *ptr++ = REG_GPIO_PXIM(i);
+ *ptr++ = REG_GPIO_PXDAT(i);
+ *ptr++ = REG_GPIO_PXTRG(i);
+ }
+
+ /*
+ * Set all pins to pull-disable, and set all pins as input except
+ * sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+ // __gpio_as_sleep();
+
+ /*
+ * Set proper status for GPC21 to GPC24 which can be used as CS1_N to CS4_N.
+ * Keep the pins' function used for chip select(CS) here according to your
+ * system to avoid chip select crashing with sdram when resuming from sleep mode.
+ */
+
+#if defined(CONFIG_JZ4760_APUS)
+ /* GPB25/CS1_N is used as chip select for nand flash, shouldn't be change. */
+
+ /* GPB26/CS2_N is connected to nand flash, needn't be changed. */
+
+ /* GPB28/CS3_N is used as cs8900's chip select, shouldn't be changed. */
+
+ /* GPB27/CS4_N is used as NOR's chip select, shouldn't be changed. */
+#endif
+
+ /*
+ * Enable pull for NC pins here according to your system
+ */
+
+#if defined(CONFIG_JZ4760_APUS)
+#endif
+
+ /*
+ * If you must set some GPIOs as output to high level or low level,
+ * you can set them here, using:
+ * __gpio_as_output(n);
+ * __gpio_set_pin(n); or __gpio_clear_pin(n);
+ */
+
+#if defined(CONFIG_JZ4760_APUS)
+ /* GPC7 which is used as AMPEN_N should be set to high to disable audio amplifier */
+ __gpio_as_output(32*2+7);
+ __gpio_set_pin(32*2+7);
+#endif
+
+#ifdef DEBUG
+ /* Keep uart function for printing debug message */
+ __gpio_as_uart0();
+ __gpio_as_uart1();
+ __gpio_as_uart2();
+ __gpio_as_uart3();
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("sleep dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+#endif
+ wakeup_key_setup();
+}
+
+void jz_board_do_resume(unsigned long *ptr)
+{
+ unsigned char i;
+
+ /* Restore GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ REG_GPIO_PXFUNS(i) = *ptr;
+ REG_GPIO_PXFUNC(i) = ~(*ptr++);
+
+ REG_GPIO_PXSELS(i) = *ptr;
+ REG_GPIO_PXSELC(i) = ~(*ptr++);
+
+ REG_GPIO_PXDIRS(i) = *ptr;
+ REG_GPIO_PXDIRC(i) = ~(*ptr++);
+
+ REG_GPIO_PXPES(i) = *ptr;
+ REG_GPIO_PXPEC(i) = ~(*ptr++);
+
+ REG_GPIO_PXIMS(i)=*ptr;
+ REG_GPIO_PXIMC(i)=~(*ptr++);
+
+ REG_GPIO_PXDATS(i)=*ptr;
+ REG_GPIO_PXDATC(i)=~(*ptr++);
+
+ REG_GPIO_PXTRGS(i)=*ptr;
+ REG_GPIO_PXTRGC(i)=~(*ptr++);
+ }
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("resume dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+}
+
+#if 0
+static void dancing(void)
+{
+ static unsigned char slash[] = "\\|/-";
+// static volatile unsigned char *p = (unsigned char *)0xb6000058;
+ static volatile unsigned char *p = (unsigned char *)0xb6000016;
+ static unsigned int count = 0;
+ *p = slash[count++];
+ count &= 3;
+}
+#endif
+
+/* MSC SETUP */
+static void cygnus_sd_8bit_gpio_init(struct device *dev)
+{
+ __gpio_as_msc0_8bit();
+ __gpio_as_output(GPIO_SD0_VCC_EN_N);
+ __gpio_as_input(GPIO_SD0_CD_N);
+}
+
+static void cygnus_sd_8bit_power_on(struct device *dev)
+{
+ __gpio_clear_pin(GPIO_SD0_VCC_EN_N);
+}
+
+static void cygnus_sd_8bit_power_off(struct device *dev)
+{
+ __gpio_set_pin(GPIO_SD0_VCC_EN_N);
+}
+
+/*
+static unsigned int cygnus_sd_8bit_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD0_CD_N);
+ return (!status);
+}
+*/
+
+/*
+static void cygnus_sd_8bit_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_high_level(MSC0_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_low_level(MSC0_HOTPLUG_PIN);
+}
+*/
+
+static unsigned int cygnus_sd_8bit_get_wp(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD0_WP_N);
+ return (status);
+}
+
+/*
+struct jz_mmc_platform_data cygnus_sd_8bit_data = {
+#ifndef CONFIG_JZ_MSC0_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC0_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD0_CD_N,
+ .init = cygnus_sd_8bit_gpio_init,
+ .power_on = cygnus_sd_8bit_power_on,
+ .power_off = cygnus_sd_8bit_power_off,
+ .status = cygnus_sd_8bit_status,
+ .plug_change = cygnus_sd_8bit_plug_change,
+ .write_protect = cygnus_sd_8bit_get_wp,
+ .max_bus_width = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_8_BIT_DATA,
+#ifdef CONFIG_JZ_MSC0_BUS_1
+ .bus_width = 1,
+#elif defined CONFIG_JZ_MSC0_BUS_4
+ .bus_width = 4,
+#else
+ .bus_width = 8,
+#endif
+};
+*/
+
+/*
+static void cygnus_sd_4bit_gpio_init(struct device *dev)
+{
+ __gpio_as_msc1_4bit();
+ __gpio_as_output(GPIO_SD1_VCC_EN_N);
+ __gpio_as_input(GPIO_SD1_CD_N);
+}
+
+static void cygnus_sd_4bit_power_on(struct device *dev)
+{
+ __msc1_enable_power();
+}
+
+static void cygnus_sd_4bit_power_off(struct device *dev)
+{
+ __msc1_disable_power();
+}
+
+static unsigned int cygnus_sd_4bit_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD1_CD_N);
+ return (status);
+}
+
+static void cygnus_sd_4bit_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_low_level(MSC1_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_high_level(MSC1_HOTPLUG_PIN);
+}
+
+static unsigned int cygnus_sd_4bit_get_wp(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD1_WP_N);
+ return (status);
+}
+
+struct jz_mmc_platform_data cygnus_sd_4bit_data = {
+#ifndef CONFIG_JZ_MSC1_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC1_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD1_CD_N,
+ .init = cygnus_sd_4bit_gpio_init,
+ .power_on = cygnus_sd_4bit_power_on,
+ .power_off = cygnus_sd_4bit_power_off,
+ .status = cygnus_sd_4bit_status,
+ .plug_change = cygnus_sd_4bit_plug_change,
+ .write_protect = cygnus_sd_4bit_get_wp,
+ .max_bus_width = MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC1_BUS_1
+ .bus_width = 1,
+#else
+ .bus_width = 4,
+#endif
+};
+
+void __init board_msc_init(void)
+{
+#ifdef CONFIG_JZ_MSC0
+ jz_add_msc_devices(0, &cygnus_sd_8bit_data);
+#endif
+
+#ifdef CONFIG_JZ_MSC1
+ jz_add_msc_devices(1, &cygnus_sd_4bit_data);
+#endif
+}
+*/
+
+static void f4760_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+// dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4760/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ /*
+ * Initialize SDRAM pins
+ */
+}
+
+void __init jz_board_setup(void)
+{
+ printk("JZ4760 Cygnus board setup\n");
+// jz_restart(NULL);
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = f4760_timer_callback;
+}
+
+/**
+ * Called by arch/mips/kernel/proc.c when 'cat /proc/cpuinfo'.
+ * Android requires the 'Hardware:' field in cpuinfo to setup the init.%hardware%.rc.
+ */
+const char *get_board_type(void)
+{
+ return "Cygnus";
+}
diff --git a/arch/mips/jz4760/board-f4760.c b/arch/mips/jz4760/board-f4760.c
new file mode 100644
index 00000000000..6fb693aa2b5
--- /dev/null
+++ b/arch/mips/jz4760/board-f4760.c
@@ -0,0 +1,352 @@
+/*
+ * linux/arch/mips/jz4760/board-f4760.c
+ *
+ * JZ4760 F4760 board setup routines.
+ *
+ * Copyright (c) 2006-2008 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/jzsoc.h>
+
+/*
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/watchdog.h>
+#include <linux/mfd/wm831x/status.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+*/
+
+#define WM831X_LDO_MAX_NAME 6
+
+extern void (*jz_timer_callback)(void);
+
+static void dancing(void)
+{
+ static unsigned char slash[] = "\\|/-";
+// static volatile unsigned char *p = (unsigned char *)0xb6000058;
+ static volatile unsigned char *p = (unsigned char *)0xb6000016;
+ static unsigned int count = 0;
+ *p = slash[count++];
+ count &= 3;
+}
+
+static void f4760_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+ dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4760/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ /*
+ * Initialize SDRAM pins
+ */
+}
+
+void __init jz_board_setup(void)
+{
+ printk("JZ4760 F4760 board setup\n");
+// jz_restart(NULL);
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = f4760_timer_callback;
+}
+
+/**
+ * Called by arch/mips/kernel/proc.c when 'cat /proc/cpuinfo'.
+ * Android requires the 'Hardware:' field in cpuinfo to setup the init.%hardware%.rc.
+ */
+const char *get_board_type(void)
+{
+ return "f4760";
+}
+
+/*****
+ * Wm831x init
+ *****/
+#if 0
+struct wm831x_ldo {
+ char name[WM831X_LDO_MAX_NAME];
+ struct regulator_desc desc;
+ int base;
+ struct wm831x *wm831x;
+ struct regulator_dev *regulator;
+};
+
+static int wm8310_pre_init(struct wm831x *wm831x){
+
+ int ret;
+
+ /* close all wm831x regulators . */
+ ret = wm831x_set_bits(wm831x,WM831X_LDO_ENABLE,0x7ff,0);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to close all ldo: %d\n",ret);
+
+ return 0;
+}
+
+static int wm8310_post_init(struct wm831x *wm831x){
+
+ int ret;
+
+ ret = wm831x_reg_unlock(wm831x);
+ if (ret != 0) {
+ dev_err(wm831x->dev, "Failed to unlock registers: %d\n", ret);
+ return -1;
+ }
+
+ // close wm831x watchdog
+ ret = wm831x_set_bits(wm831x,WM831X_WATCHDOG,WM831X_WDOG_ENA,0);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to close watchdog: %d\n",ret);
+
+ // set ON pin timeout period and set secondary action as irq
+
+ ret = wm831x_set_bits(wm831x,WM831X_ON_PIN_CONTROL,
+ WM831X_ON_PIN_SECACT_MASK |
+ WM831X_ON_PIN_PRIMACT_MASK |
+ WM831X_ON_PIN_TO_MASK,
+ WM831X_ON_PIN_AS_IRQ );
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to set ON pin timeout period: %d\n",ret);
+
+ wm831x_reg_lock(wm831x);
+ //set wm831x LED1 as a flag of charge status
+ ret = wm831x_set_bits(wm831x,WM831X_STATUS_LED_1,WM831X_LED1_MASK,
+ WM831X_LED1_CHARGE_STATE);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to set status of charge on led1: %d\n",ret);
+
+ return 0;
+}
+
+struct wm831x_backlight_pdata wm8310_backlight = {
+
+ .isink = 1,
+ .max_uA = 3000,
+};
+static struct wm831x_battery_pdata wm8310_battery_data={
+
+ .enable = 1,
+ .fast_enable = 1,
+ .off_mask = 0,
+ .trickle_ilim = 50, /** Trickle charge current limit, in mA */
+ .vsel = 4200, /** Target voltage, in mV */
+ .eoc_iterm = 50, /** End of trickle charge current, in mA */
+ .fast_ilim = 400, /** Fast charge current limit, in mA */
+ .timeout = 300, /** Charge cycle timeout, in minutes */
+};
+
+struct wm831x_status_pdata wm8310_led_status[] = {
+ {
+ .default_src = WM831X_STATUS_CHARGER,
+ .name = "wm831x-status",
+ },
+};
+
+static struct regulator_init_data wm8310_dcdc[]={
+ {
+ .constraints = {
+ .name = "wm831x-dcdc1",
+// .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc2",
+// .boot_on = 1,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc3",
+// .boot_on = 1,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-dcdc4",
+// .boot_on = 1,
+ },
+ },
+};
+
+static int wm8310_ldo1_init( void *driver_data )
+{
+ return 0;
+}
+struct wm831x_ldo ldo1_driver_data = {
+ .base = WM831X_LDO1_CONTROL,
+};
+
+static struct regulator_init_data wm8310_ldo[]={
+ {
+ .constraints = {
+ .name = "wm831x-ldo1",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+ .regulator_init = &wm8310_ldo1_init,
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo2",
+ .apply_uV = 1,
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo3",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo4",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo5",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo6",
+ .apply_uV = 1,
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo7",
+ .apply_uV = 1,
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo8",
+ .apply_uV = 1,
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo9",
+ .apply_uV = 1,
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .boot_on = 0,
+ },
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo10",
+ .apply_uV = 1,
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .boot_on = 0,
+ },
+
+ },
+ {
+ .constraints = {
+ .name = "wm831x-ldo11",
+ .boot_on = 0,
+ },
+
+ },
+
+};
+
+static struct wm831x_pdata wm831x_platform_data = {
+ .pre_init = &wm8310_pre_init,
+ .post_init = &wm8310_post_init,
+ .backlight = &wm8310_backlight,
+ .battery = &wm8310_battery_data,
+ .dcdc = { wm8310_dcdc, wm8310_dcdc+1, wm8310_dcdc+2, wm8310_dcdc+3 },
+ .ldo = {
+ wm8310_ldo, wm8310_ldo+1,wm8310_ldo+2,wm8310_ldo+3,
+ wm8310_ldo+4,wm8310_ldo+5,wm8310_ldo+6,wm8310_ldo+7,
+ wm8310_ldo+8,wm8310_ldo+9,wm8310_ldo+10
+ },
+};
+
+static struct i2c_board_info wm831x_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8310", 0x34),
+// .irq = GPIO_WM831x_IRQ,
+ .platform_data = &wm831x_platform_data,
+ },
+};
+
+static int __init wm831x_platform_init( void )
+{
+ i2c_register_board_info(0,wm831x_i2c_devs,ARRAY_SIZE(wm831x_i2c_devs));
+// platform_add_devices(aquila_platform_devices, ARRAY_SIZE(aquila_platform_devices));
+ return 0;
+}
+
+arch_initcall(wm831x_platform_init);
+#endif
diff --git a/arch/mips/jz4760/board-lepus.c b/arch/mips/jz4760/board-lepus.c
new file mode 100644
index 00000000000..0bc9dcad97a
--- /dev/null
+++ b/arch/mips/jz4760/board-lepus.c
@@ -0,0 +1,466 @@
+/*
+ * linux/arch/mips/jz4760/board-cygnus.c
+ *
+ * JZ4760 Cygnus board setup routines.
+ *
+ * Copyright (c) 2006-2010 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/jzsoc.h>
+#include <linux/i2c.h>
+#include <asm/jzmmc/jz_mmc_platform_data.h>
+
+extern void (*jz_timer_callback)(void);
+extern int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat);
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+/*
+ * __gpio_as_sleep set all pins to pull-disable, and set all pins as input
+ * except sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+#define __gpio_as_sleep() \
+do { \
+ REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXSELC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXPES(1) = 0xffffffff; \
+ REG_GPIO_PXFUNC(2) = ~0x01e00000; \
+ REG_GPIO_PXSELC(2) = ~0x01e00000; \
+ REG_GPIO_PXDIRC(2) = ~0x01e00000; \
+ REG_GPIO_PXPES(2) = 0xffffffff; \
+ REG_GPIO_PXFUNC(4) = 0xffffffff; \
+ REG_GPIO_PXSELC(4) = 0xffffffff; \
+ REG_GPIO_PXDIRC(4) = 0xffffffff; \
+ REG_GPIO_PXPES(4) = 0xffffffff; \
+ REG_GPIO_PXFUNC(5) = 0xffffffff; \
+ REG_GPIO_PXSELC(5) = 0xffffffff; \
+ REG_GPIO_PXDIRC(5) = 0xffffffff; \
+ REG_GPIO_PXPES(5) = 0xffffffff; \
+} while (0)
+
+struct wakeup_key_s {
+ int gpio; /* gpio pin number */
+ int active_low; /* the key interrupt pin is low voltage
+ or fall edge acitve */
+};
+
+/* add wakeup keys here */
+static struct wakeup_key_s wakeup_key[] = {
+ {
+ .gpio = GPIO_HOME,
+ .active_low = ACTIVE_LOW_HOME,
+ },
+ {
+ .gpio = GPIO_BACK,
+ .active_low = ACTIVE_LOW_BACK,
+ },
+ {
+ .gpio = GPIO_ENDCALL,
+ .active_low = ACTIVE_LOW_ENDCALL,
+ },
+ {
+ .gpio = GPIO_ADKEY_INT,
+ .active_low = ACTIVE_LOW_ADKEY,
+ },
+};
+
+static void wakeup_key_setup(void)
+{
+ int i;
+ int num = sizeof(wakeup_key) / sizeof(wakeup_key[0]);
+
+ for(i = 0; i < num; i++) {
+#if 0
+ if(wakeup_key[i].active_low)
+ __gpio_as_irq_fall_edge(wakeup_key[i].gpio);
+ else
+ __gpio_as_irq_rise_edge(wakeup_key[i].gpio);
+#endif
+
+#if 1
+ /* Because GPIO_VOLUMUP, GPIO_VOLUMDOWN and GPIO_MENU are boot_sel pins, and
+ resuming from sleep is implemented by reseting, the values of boot_sel pins
+ will be read at this time to determine boot method. So system couldn't be
+ waken by these keys. */
+ __gpio_as_input(GPIO_MENU);
+ __gpio_as_input(GPIO_VOLUMEDOWN);
+ __gpio_as_input(GPIO_VOLUMEUP);
+#endif
+ __gpio_ack_irq(wakeup_key[i].gpio);
+ __gpio_unmask_irq(wakeup_key[i].gpio);
+ __intc_unmask_irq(IRQ_GPIO0 - (wakeup_key[i].gpio/32)); /* unmask IRQ_GPIOn */
+ }
+}
+
+
+/* NOTES:
+ * 1: Pins that are floated (NC) should be set as input and pull-enable.
+ * 2: Pins that are pull-up or pull-down by outside should be set as input
+ * and pull-disable.
+ * 3: Pins that are connected to a chip except sdram and nand flash
+ * should be set as input and pull-disable, too.
+ */
+void jz_board_do_sleep(unsigned long *ptr)
+{
+ unsigned char i;
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("run dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+
+ /* Save GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ *ptr++ = REG_GPIO_PXFUN(i);
+ *ptr++ = REG_GPIO_PXSEL(i);
+ *ptr++ = REG_GPIO_PXDIR(i);
+ *ptr++ = REG_GPIO_PXPE(i);
+ *ptr++ = REG_GPIO_PXIM(i);
+ *ptr++ = REG_GPIO_PXDAT(i);
+ *ptr++ = REG_GPIO_PXTRG(i);
+ }
+
+ /*
+ * Set all pins to pull-disable, and set all pins as input except
+ * sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+// __gpio_as_sleep();
+
+ /*
+ * Set proper status for GPC21 to GPC24 which can be used as CS1_N to CS4_N.
+ * Keep the pins' function used for chip select(CS) here according to your
+ * system to avoid chip select crashing with sdram when resuming from sleep mode.
+ */
+
+ /*
+ * If you must set some GPIOs as output to high level or low level,
+ * you can set them here, using:
+ * __gpio_as_output(n);
+ * __gpio_set_pin(n); or __gpio_clear_pin(n);
+ */
+
+#ifdef DEBUG
+ /* Keep uart function for printing debug message */
+ __gpio_as_uart0();
+ __gpio_as_uart1();
+ __gpio_as_uart2();
+ __gpio_as_uart3();
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("sleep dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+#endif
+ wakeup_key_setup();
+}
+
+void jz_board_do_resume(unsigned long *ptr)
+{
+ unsigned char i;
+
+ /* Restore GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ REG_GPIO_PXFUNS(i) = *ptr;
+ REG_GPIO_PXFUNC(i) = ~(*ptr++);
+
+ REG_GPIO_PXSELS(i) = *ptr;
+ REG_GPIO_PXSELC(i) = ~(*ptr++);
+
+ REG_GPIO_PXDIRS(i) = *ptr;
+ REG_GPIO_PXDIRC(i) = ~(*ptr++);
+
+ REG_GPIO_PXPES(i) = *ptr;
+ REG_GPIO_PXPEC(i) = ~(*ptr++);
+
+ REG_GPIO_PXIMS(i)=*ptr;
+ REG_GPIO_PXIMC(i)=~(*ptr++);
+
+ REG_GPIO_PXDATS(i)=*ptr;
+ REG_GPIO_PXDATC(i)=~(*ptr++);
+
+ REG_GPIO_PXTRGS(i)=*ptr;
+ REG_GPIO_PXTRGC(i)=~(*ptr++);
+ }
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("resume dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+}
+
+static void lepus_sd_gpio_init(struct device *dev)
+{
+ __gpio_as_msc0_8bit();
+ __gpio_as_output(GPIO_SD0_VCC_EN_N);
+ __gpio_as_input(GPIO_SD0_CD_N);
+}
+
+static void lepus_sd_power_on(struct device *dev)
+{
+ __msc0_enable_power();
+}
+
+static void lepus_sd_power_off(struct device *dev)
+{
+ __msc0_disable_power();
+}
+
+static void lepus_sd_cpm_start(struct device *dev)
+{
+ cpm_start_clock(CGM_MSC0);
+}
+
+static unsigned int lepus_sd_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(GPIO_SD0_CD_N);
+#if ACTIVE_LOW_MSC0_CD
+ return !status;
+#else
+ return status;
+#endif
+}
+
+#if 0
+static void lepus_sd_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_high_level(MSC0_HOTPLUG_PIN); /* wait remove */
+ else
+ __gpio_as_irq_low_level(MSC0_HOTPLUG_PIN); /* wait insert */
+}
+#else
+static void lepus_sd_plug_change(int state)
+{
+ if(state == CARD_INSERTED) /* wait for remove */
+#if ACTIVE_LOW_MSC0_CD
+ __gpio_as_irq_rise_edge(MSC0_HOTPLUG_PIN);
+#else
+ __gpio_as_irq_fall_edge(MSC0_HOTPLUG_PIN);
+#endif
+ else /* wait for insert */
+#if ACTIVE_LOW_MSC0_CD
+ __gpio_as_irq_fall_edge(MSC0_HOTPLUG_PIN);
+#else
+ __gpio_as_irq_rise_edge(MSC0_HOTPLUG_PIN);
+#endif
+}
+#endif
+
+static unsigned int lepus_sd_get_wp(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) __gpio_get_pin(MSC0_WP_PIN);
+ return (status);
+}
+
+struct jz_mmc_platform_data lepus_sd_data = {
+#ifndef CONFIG_JZ_MSC0_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC0_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD0_CD_N,
+ .init = lepus_sd_gpio_init,
+ .power_on = lepus_sd_power_on,
+ .power_off = lepus_sd_power_off,
+ .cpm_start = lepus_sd_cpm_start,
+ .status = lepus_sd_status,
+ .plug_change = lepus_sd_plug_change,
+ .write_protect = lepus_sd_get_wp,
+ .max_bus_width = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC0_BUS_1
+ .bus_width = 1,
+#elif defined CONFIG_JZ_MSC0_BUS_4
+ .bus_width = 4,
+#else
+ .bus_width = 8,
+#endif
+};
+
+static void lepus_tf_gpio_init(struct device *dev)
+{
+ __gpio_as_msc1_4bit();
+ __gpio_as_output(GPIO_SD1_VCC_EN_N);
+ __gpio_as_input(GPIO_SD1_CD_N);
+}
+
+static void lepus_tf_power_on(struct device *dev)
+{
+ __msc1_enable_power();
+}
+
+static void lepus_tf_power_off(struct device *dev)
+{
+ __msc1_disable_power();
+}
+
+static void lepus_tf_cpm_start(struct device *dev)
+{
+ cpm_start_clock(CGM_MSC1);
+}
+
+static unsigned int lepus_tf_status(struct device *dev)
+{
+ unsigned int status = 0;
+ status = (unsigned int) __gpio_get_pin(GPIO_SD1_CD_N);
+#if ACTIVE_LOW_MSC1_CD
+ return !status;
+#else
+ return status;
+#endif
+}
+
+#if 0
+static void lepus_tf_plug_change(int state)
+{
+ if(state == CARD_INSERTED)
+ __gpio_as_irq_low_level(MSC1_HOTPLUG_PIN);
+ else
+ __gpio_as_irq_high_level(MSC1_HOTPLUG_PIN);
+}
+#else
+static void lepus_tf_plug_change(int state)
+{
+ if(state == CARD_INSERTED) /* wait for remove */
+#if ACTIVE_LOW_MSC1_CD
+ __gpio_as_irq_rise_edge(MSC1_HOTPLUG_PIN);
+#else
+ __gpio_as_irq_fall_edge(MSC1_HOTPLUG_PIN);
+#endif
+ else /* wait for insert */
+#if ACTIVE_LOW_MSC1_CD
+ __gpio_as_irq_fall_edge(MSC1_HOTPLUG_PIN);
+#else
+ __gpio_as_irq_rise_edge(MSC1_HOTPLUG_PIN);
+#endif
+}
+#endif
+
+struct jz_mmc_platform_data lepus_tf_data = {
+#ifndef CONFIG_JZ_MSC1_SDIO_SUPPORT
+ .support_sdio = 0,
+#else
+ .support_sdio = 1,
+#endif
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .status_irq = MSC1_HOTPLUG_IRQ,
+ .detect_pin = GPIO_SD1_CD_N,
+ .init = lepus_tf_gpio_init,
+ .power_on = lepus_tf_power_on,
+ .power_off = lepus_tf_power_off,
+ .cpm_start = lepus_tf_cpm_start,
+ .status = lepus_tf_status,
+ .plug_change = lepus_tf_plug_change,
+ .max_bus_width = MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA,
+#ifdef CONFIG_JZ_MSC1_BUS_1
+ .bus_width = 1,
+#else
+ .bus_width = 4,
+#endif
+};
+
+void __init board_msc_init(void)
+{
+#ifdef CONFIG_JZ_MSC0
+ printk("add msc0......\n");
+ jz_add_msc_devices(0, &lepus_sd_data);
+#endif
+
+#ifdef CONFIG_JZ_MSC1
+ printk("add msc1......\n");
+ jz_add_msc_devices(1, &lepus_tf_data);
+#endif
+}
+
+static void f4760_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+// dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4760/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ /*
+ * Initialize SDRAM pins
+ */
+}
+
+static struct i2c_board_info lepus_i2c0_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("cm3511", 0x30),
+ },
+ {
+ I2C_BOARD_INFO("ov3640", 0x3c),
+ },
+ {
+ I2C_BOARD_INFO("ov7690", 0x21),
+ },
+ {
+ },
+};
+
+void __init board_i2c_init(void) {
+ i2c_register_board_info(0, lepus_i2c0_devs, ARRAY_SIZE(lepus_i2c0_devs));
+}
+
+void __init jz_board_setup(void)
+{
+ printk("JZ4760 Lepus board setup\n");
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = f4760_timer_callback;
+}
+
+/**
+ * Called by arch/mips/kernel/proc.c when 'cat /proc/cpuinfo'.
+ */
+const char *get_board_type(void)
+{
+ return "Lepus";
+}
diff --git a/arch/mips/jz4760/cpm.c b/arch/mips/jz4760/cpm.c
new file mode 100644
index 00000000000..25046480d5f
--- /dev/null
+++ b/arch/mips/jz4760/cpm.c
@@ -0,0 +1,517 @@
+/*
+ * linux/arch/mips/jz4760/cpm.c
+ *
+ * jz4760 on-chip modules.
+ *
+ * Copyright (C) 2010 Ingenic Semiconductor Co., Ltd.
+ *
+ * Author: <whxu@ingenic.cn>
+ */
+
+#include <asm/jzsoc.h>
+
+
+#ifndef JZ_EXTAL
+#define JZ_EXTAL (12 * 1000000) /* 12MHz */
+#endif
+
+
+static unsigned int __get_clock_div(unsigned int val);
+
+/*
+ * Get clock div, such as CDIV, HDIV, PDIV, MDIV, H2DIV, SDIV.
+ * Convert the value read from register to the division ratio
+ */
+static unsigned int __get_clock_div(unsigned int val)
+{
+ unsigned int index;
+ unsigned int div[] = {1, 2, 3, 4, 6, 8};
+
+ if (val < (sizeof(div)/div[0]))
+ index = val;
+ else {
+ printk("WARNING: Invalid clock value %d!\n", val);
+ index = 0;
+ }
+
+ return div[index];
+}
+
+/*
+ * Get the external clock
+ */
+static unsigned int get_external_clock(void)
+{
+ return JZ_EXTAL;
+}
+
+/*
+ * Get the PLL clock
+ */
+unsigned int cpm_get_pllout(void)
+{
+ unsigned int exclk = get_external_clock();
+ unsigned int pll_stat, pll_ctrl, pllout;
+ unsigned int m, n, od, no;
+
+ pll_stat = INREG32(CPM_CPPSR);
+ if ((pll_stat & CPPSR_PLLBP) || (pll_stat & CPPSR_PLLOFF)) {
+ pllout = exclk;
+ return pllout;
+ }
+
+ pll_ctrl = INREG32(CPM_CPPCR0);
+ m = ((pll_ctrl & CPPCR0_PLLM_MASK) >> CPPCR0_PLLM_LSB) * 2;
+ n = (pll_ctrl & CPPCR0_PLLN_MASK) >> CPPCR0_PLLN_LSB;
+
+ od = (pll_ctrl & CPPCR0_PLLOD_MASK) >> CPPCR0_PLLOD_LSB;
+ no = 1 << od;
+ pllout = (exclk / (n * no)) * m;
+
+ return pllout;
+}
+
+/*
+ * Get the PLL2 clock
+ */
+unsigned int cpm_get_pllout1(void)
+{
+ unsigned int clock_in, pll_ctrl, pll_out;
+ unsigned int m, n, od, no, val, div;
+
+ pll_ctrl = INREG32(CPM_CPPCR1);
+ if (pll_ctrl & CPPCR1_P1SCS) {
+ val = get_bf_value(pll_ctrl, CPPCR1_P1SDIV_LSB, CPPCR1_P1SDIV_MASK);
+ div = val + 1;
+ clock_in = cpm_get_pllout() / div;
+ } else
+ clock_in = get_external_clock();
+
+ if (pll_ctrl & CPPCR1_PLL1S) {
+ m = ((pll_ctrl & CPPCR1_PLL1M_MASK) >> CPPCR1_PLL1M_LSB) * 2;
+ n = (pll_ctrl & CPPCR1_PLL1N_MASK) >> CPPCR1_PLL1N_LSB;
+
+ od = (pll_ctrl & CPPCR1_PLL1OD_MASK) >> CPPCR1_PLL1OD_LSB;
+ no = 1 << od;
+ pll_out = (clock_in / (n * no)) * m;
+ } else {
+ pll_out = clock_in;
+ }
+
+ return pll_out;
+}
+
+/*
+ * Start the module clock
+ */
+void cpm_start_clock(clock_gate_module module_name)
+{
+ unsigned int cgr_index, module_index;
+
+ if (module_name == CGM_ALL_MODULE) {
+ OUTREG32(CPM_CLKGR0, 0x0);
+ OUTREG32(CPM_CLKGR1, 0x0);
+ return;
+ }
+
+ cgr_index = module_name / 32;
+ module_index = module_name % 32;
+ switch (cgr_index) {
+ case 0:
+ CLRREG32(CPM_CLKGR0, 1 << module_index);
+ break;
+ case 1:
+ CLRREG32(CPM_CLKGR1, 1 << module_index);
+ break;
+ default:
+ printk("WARNING: can NOT start the %d's clock\n",
+ module_name);
+ break;
+ }
+}
+
+/*
+ * Stop the module clock
+ */
+void cpm_stop_clock(clock_gate_module module_name)
+{
+ unsigned int cgr_index, module_index;
+
+ if (module_name == CGM_ALL_MODULE) {
+ OUTREG32(CPM_CLKGR0, 0xffffffff);
+ OUTREG32(CPM_CLKGR1, 0x3ff);
+ return;
+ }
+
+ cgr_index = module_name / 32;
+ module_index = module_name % 32;
+ switch (cgr_index) {
+ case 0:
+ SETREG32(CPM_CLKGR0, 1 << module_index);
+ break;
+
+ case 1:
+ SETREG32(CPM_CLKGR1, 1 << module_index);
+ break;
+
+ default:
+ printk("WARNING: can NOT stop the %d's clock\n",
+ module_name);
+ break;
+ }
+}
+
+/*
+ * Get the clock, assigned by the clock_name, and the return value unit is Hz
+ */
+unsigned int cpm_get_clock(cgu_clock clock_name)
+{
+ unsigned int exclk = get_external_clock();
+ unsigned int pllclk = cpm_get_pllout();
+ unsigned int clock_ctrl = INREG32(CPM_CPCCR);
+ unsigned int clock_hz = exclk;
+ unsigned int val, tmp, div;
+
+ switch (clock_name) {
+ case CGU_CCLK:
+ val = get_bf_value(clock_ctrl, CPCCR_CDIV_LSB, CPCCR_CDIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_HCLK:
+ val = get_bf_value(clock_ctrl, CPCCR_HDIV_LSB, CPCCR_HDIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_PCLK:
+ val = get_bf_value(clock_ctrl, CPCCR_PDIV_LSB, CPCCR_PDIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_MCLK:
+ val = get_bf_value(clock_ctrl, CPCCR_MDIV_LSB, CPCCR_MDIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_H2CLK:
+ val = get_bf_value(clock_ctrl, CPCCR_H2DIV_LSB, CPCCR_H2DIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_SCLK:
+ val = get_bf_value(clock_ctrl, CPCCR_SDIV_LSB, CPCCR_SDIV_MASK);
+ div = __get_clock_div(val);
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_MSCCLK:
+ tmp = INREG32(CPM_MSCCDR);
+ val = get_bf_value(tmp, MSCCDR_MSCDIV_LSB, MSCCDR_MSCDIV_MASK);
+ div = val + 1;
+ if (tmp & MSCCDR_MCS) {
+ if (clock_ctrl & CPCCR_PCS)
+ clock_hz = pllclk / div;
+ else
+ clock_hz = (pllclk / 2) / div;
+ } else {
+ clock_hz = exclk;
+ }
+
+ break;
+
+ case CGU_SSICLK:
+ tmp = INREG32(CPM_SSICDR);
+ val = get_bf_value(tmp, SSICDR_SSIDIV_LSB, SSICDR_SSIDIV_MASK);
+ div = val + 1;
+ if (tmp & SSICDR_SCS) {
+ if (clock_ctrl & CPCCR_PCS)
+ clock_hz = pllclk / div;
+ else
+ clock_hz = (pllclk / 2) / div;
+ } else {
+ clock_hz = exclk;
+ }
+
+ break;
+
+ case CGU_CIMCLK:
+ tmp = INREG32(CPM_CIMCDR);
+ val = get_bf_value(tmp, CIMCDR_CIMDIV_LSB, CIMCDR_CIMDIV_MASK);
+ div = val + 1;
+ if (clock_ctrl & CPCCR_PCS)
+ clock_hz = pllclk / div;
+ else
+ clock_hz = (pllclk / 2) / div;
+
+ break;
+
+ case CGU_LPCLK:
+ case CGU_TVECLK:
+ tmp = INREG32(CPM_LPCDR);
+ val = get_bf_value(tmp, LPCDR_PIXDIV_LSB, LPCDR_PIXDIV_MASK);
+ div = val + 1;
+ if (tmp & LPCDR_LTCS) {
+ if (tmp & LPCDR_LSCS)
+ clock_hz = exclk;
+ else {
+ if (tmp & LPCDR_LPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+ }
+ } else {
+ if (tmp & LPCDR_LPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+ }
+
+ break;
+
+ case CGU_I2SCLK:
+ tmp = INREG32(CPM_I2SCDR);
+ val = get_bf_value(tmp, CIMCDR_CIMDIV_LSB, CIMCDR_CIMDIV_MASK);
+ div = val + 1;
+ if (tmp & I2SCDR_I2CS) {
+ if (tmp & I2SCDR_I2PCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+ } else {
+ if (clock_ctrl & CPCCR_ECS)
+ clock_hz = exclk / 2;
+ else
+ clock_hz = exclk;
+ }
+
+ break;
+
+ case CGU_PCMCLK:
+ tmp = INREG32(CPM_PCMCDR);
+ val = get_bf_value(tmp, PCMCDR_PCMDIV_LSB, PCMCDR_PCMDIV_MASK);
+ div = val + 1;
+ if (tmp & PCMCDR_PCMS) {
+ if (tmp & PCMCDR_PCMPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+ } else {
+ if (clock_ctrl & CPCCR_ECS)
+ clock_hz = exclk / 2;
+ else
+ clock_hz = exclk;
+ }
+
+ break;
+
+ case CGU_OTGCLK:
+ tmp = INREG32(CPM_USBCDR);
+ val = get_bf_value(tmp, USBCDR_OTGDIV_LSB, USBCDR_OTGDIV_MASK);
+ div = val + 1;
+ if (tmp & USBCDR_UCS) {
+ if (tmp & USBCDR_UPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+ } else {
+ if (clock_ctrl & CPCCR_ECS)
+ clock_hz = exclk / 2;
+ else
+ clock_hz = exclk;
+ }
+
+ break;
+
+ case CGU_UHCCLK:
+ tmp = INREG32(CPM_UHCCDR);
+ val = get_bf_value(tmp, UHCCDR_UHCDIV_LSB, UHCCDR_UHCDIV_MASK);
+ div = val + 1;
+ if (tmp & UHCCDR_UHPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_GPSCLK:
+ tmp = INREG32(CPM_GPSCDR);
+ val = get_bf_value(tmp, GPSCDR_GPSDIV_LSB, GSPCDR_GPSDIV_MASK);
+ div = val + 1;
+ if (tmp & GPSCDR_GPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_GPUCLK:
+ tmp = INREG32(CPM_GPUCDR);
+ val = get_bf_value(tmp, GPUCDR_GPUDIV_LSB, GPUCDR_GPUDIV_MASK);
+ div = val + 1;
+ if (tmp & GPUCDR_GPCS)
+ clock_hz = cpm_get_pllout1() / div;
+ else
+ clock_hz = pllclk / div;
+
+ break;
+
+ case CGU_UARTCLK:
+ case CGU_SADCCLK:
+ if (clock_ctrl & CPCCR_ECS)
+ clock_hz = exclk / 2;
+ else
+ clock_hz = exclk;
+
+ break;
+
+ case CGU_TCUCLK:
+ clock_hz = exclk;
+
+ break;
+
+ default:
+ printk("WARNING: can NOT get clock %d!\n", clock_name);
+ clock_hz = exclk;
+ break;
+ }
+
+ return clock_hz;
+}
+
+/*
+ * Check div value whether valid, if invalid, return the max valid value
+ */
+static unsigned int __check_div(unsigned int div, unsigned int lsb, unsigned int mask)
+{
+ if ((div << lsb) > mask) {
+ printk("WARNING: Invalid div %d larger than %d\n", div, mask >> lsb);
+ return mask >> lsb;
+ } else
+ return div;
+}
+
+/*
+ * Set the clock, assigned by the clock_name, and the return value unit is Hz,
+ * which means the actual clock
+ */
+unsigned int cpm_set_clock(cgu_clock clock_name, unsigned int clock_hz)
+{
+ unsigned int actual_clock = 0;
+ unsigned int exclk = get_external_clock();
+ unsigned int pllclk = cpm_get_pllout();
+ unsigned int pllclk1 = cpm_get_pllout1();
+ unsigned int div;
+
+ if (!clock_hz)
+ return actual_clock;
+
+ switch (clock_name) {
+ case CGU_MSCCLK:
+ if (clock_hz == exclk) {
+ /* Select external clock as input*/
+ SETREG32(CPM_MSCCDR, MSCCDR_MCS);
+ } else {
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, MSCCDR_MSCDIV_LSB, MSCCDR_MSCDIV_MASK);
+ OUTREG32(CPM_MSCCDR, div);
+ }
+
+ break;
+
+ case CGU_TVECLK:
+ if (clock_hz == exclk) {
+ /* Select external clock as input */
+ SETREG32(CPM_LPCDR, LPCDR_LSCS | LPCDR_LTCS);
+ } else {
+ div = pllclk1 / clock_hz - 1;
+ div = __check_div(div, LPCDR_PIXDIV_LSB, LPCDR_PIXDIV_MASK);
+ /* Select pll1 clock as input */
+ OUTREG32(CPM_LPCDR, LPCDR_LTCS | LPCDR_LPCS | div);
+ }
+ break;
+
+ case CGU_LPCLK:
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, LPCDR_PIXDIV_LSB, LPCDR_PIXDIV_MASK);
+ /* Select pll0 clock as input */
+ OUTREG32(CPM_LPCDR, div);
+ break;
+
+ case CGU_I2SCLK:
+ if (clock_hz == exclk) {
+ CLRREG32(CPM_CPCCR, CPCCR_ECS);
+ OUTREG32(CPM_I2SCDR, 0);
+ } else if (clock_hz == exclk/2) {
+ SETREG32(CPM_CPCCR, CPCCR_ECS);
+ OUTREG32(CPM_I2SCDR, 0);
+ } else {
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, I2SCDR_I2SDIV_LSB, I2SCDR_I2SDIV_MASK);
+ OUTREG32(CPM_I2SCDR, I2SCDR_I2CS | div);
+ }
+ break;
+
+ case CGU_OTGCLK:
+ if (clock_hz == exclk) {
+ CLRREG32(CPM_CPCCR, CPCCR_ECS);
+ OUTREG32(CPM_USBCDR, 0);
+ } else if (clock_hz == exclk/2) {
+ SETREG32(CPM_CPCCR, CPCCR_ECS);
+ OUTREG32(CPM_USBCDR, 0);
+ } else {
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, USBCDR_OTGDIV_LSB, USBCDR_OTGDIV_MASK);
+ OUTREG32(CPM_USBCDR, USBCDR_UCS | div);
+ }
+ break;
+
+ case CGU_RTCCLK:
+ SETREG32(CPM_OPCR, OPCR_ERCS);
+ break;
+
+ case CGU_CIMCLK:
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, CIMCDR_CIMDIV_LSB, CIMCDR_CIMDIV_MASK);
+ OUTREG32(CPM_CIMCDR, div);
+ break;
+
+ case CGU_UHCCLK:
+ div = pllclk / clock_hz - 1;
+ div = __check_div(div, UHCCDR_UHCDIV_LSB, UHCCDR_UHCDIV_MASK);
+ OUTREG32(CPM_UHCCDR, div);
+ break;
+
+ default:
+ printk("WARNING: can NOT set clock %d!\n", clock_name);
+ break;
+ }
+
+ SETREG32(CPM_CPCCR, CPCCR_CE);
+ /* Get the actual clock */
+ actual_clock = cpm_get_clock(clock_name);
+
+ return actual_clock;
+}
+
+ /*
+ * Control UHC phy, if en is NON-ZERO, enable the UHC phy, otherwise disable
+ */
+void cpm_uhc_phy(unsigned int en)
+{
+ if (en)
+ CLRREG32(CPM_OPCR, OPCR_UHCPHY_DISABLE);
+ else
+ SETREG32(CPM_OPCR, OPCR_UHCPHY_DISABLE);
+}
+
diff --git a/arch/mips/jz4760/cpufreq.c b/arch/mips/jz4760/cpufreq.c
new file mode 100644
index 00000000000..f2a125d4bc3
--- /dev/null
+++ b/arch/mips/jz4760/cpufreq.c
@@ -0,0 +1,598 @@
+/*
+ * linux/arch/mips/jz4760/cpufreq.c
+ *
+ * cpufreq driver for JZ4760
+ *
+ * Copyright (c) 2006-2008 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/cpufreq.h>
+
+#include <asm/jzsoc.h>
+#include <asm/processor.h>
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "cpufreq-jz4760", 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 lcdpix_clk; /* LCD Pixel clock, Hz */
+ unsigned int lcd_clks_initialized;
+} boot_config;
+
+struct jz4760_freq_percpu_info {
+ struct cpufreq_frequency_table table[7];
+};
+
+static struct jz4760_freq_percpu_info jz4760_freq_table;
+
+/*
+ * This contains the registers value for an operating point.
+ * If only part of a register needs to change then there is
+ * a mask value for that register.
+ * When going to a new operating point the current register
+ * value is ANDed with the ~mask and ORed with the new value.
+ */
+struct dpm_regs {
+ u32 cpccr; /* Clock Freq Control Register */
+ u32 cpccr_mask; /* Clock Freq Control Register mask */
+ u32 cppcr; /* PLL1 Control Register */
+ u32 cppcr_mask; /* PLL1 Control Register mask */
+ u32 pll_up_flag; /* New PLL freq is higher than current or not */
+};
+
+extern jz_clocks_t jz_clocks;
+
+static void jz_update_clocks(void)
+{
+ /* Next clocks must be updated if we have changed
+ * the PLL or divisors.
+ */
+ jz_clocks.cclk = __cpm_get_cclk();
+ jz_clocks.hclk = __cpm_get_hclk();
+ jz_clocks.mclk = __cpm_get_mclk();
+ jz_clocks.pclk = __cpm_get_pclk();
+ jz_clocks.pixclk = __cpm_get_pixclk();
+ jz_clocks.i2sclk = __cpm_get_i2sclk();
+ jz_clocks.usbclk = __cpm_get_usbclk();
+ jz_clocks.mscclk = __cpm_get_mscclk(0);
+}
+
+static void
+jz_init_boot_config(void)
+{
+ if (!boot_config.lcd_clks_initialized) {
+ /* the first time to scale pll */
+ 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>>16) & 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 jz4760_transition(struct dpm_regs *regs)
+{
+ /*
+ * Get and save some boot-time conditions.
+ */
+ jz_init_boot_config();
+
+#ifdef CHANGE_PLL
+ /*
+ * Disable LCD before scaling pll.
+ * LCD and LCD pixel clocks should not be changed even if the PLL
+ * output frequency has been changed.
+ */
+ REG_LCD_CTRL &= ~LCD_CTRL_ENA;
+
+ /*
+ * Stop module clocks before scaling PLL
+ */
+ __cpm_stop_eth();
+ __cpm_stop_aic(1);
+ __cpm_stop_aic(2);
+#endif
+
+ /* ... add more as necessary */
+
+ if (regs->pll_up_flag == PLL_GOES_UP) {
+ /* the pll frequency is going up, so change dividors first */
+ jz_scale_divisors(regs);
+#ifdef CHANGE_PLL
+ jz_scale_pll(regs);
+#endif
+ }
+ else if (regs->pll_up_flag == PLL_GOES_DOWN) {
+ /* the pll frequency is going down, so change pll first */
+#ifdef CHANGE_PLL
+ jz_scale_pll(regs);
+#endif
+ jz_scale_divisors(regs);
+ }
+ else {
+ /* the pll frequency is unchanged, so change divisors only */
+ jz_scale_divisors(regs);
+ }
+
+#ifdef CHANGE_PLL
+ /*
+ * Restart module clocks before scaling PLL
+ */
+ __cpm_start_eth();
+ __cpm_start_aic(1);
+ __cpm_start_aic(2);
+
+ /* ... add more as necessary */
+
+ /* Scale the LCD divisors after scaling pll */
+ if (regs->pll_up_flag != PLL_UNCHANGED) {
+ jz_scale_lcd_divisors(regs);
+ }
+
+ /* Enable LCD controller */
+ REG_LCD_CTRL &= ~LCD_CTRL_DIS;
+ REG_LCD_CTRL |= LCD_CTRL_ENA;
+#endif
+
+ /* Update system clocks */
+ jz_update_clocks();
+}
+
+extern unsigned int idle_times;
+static unsigned int jz4760_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 = jz4760_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 jz4760_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)
+ jz4760_transition(&regs);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+}
+
+static int jz4760_freq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int new_index = 0;
+
+ if (cpufreq_frequency_table_target(policy,
+ &jz4760_freq_table.table[0],
+ target_freq, relation, &new_index))
+ return -EINVAL;
+
+ jz4760_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 jz4760_freq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ &jz4760_freq_table.table[0]);
+}
+
+static int __init jz4760_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+
+ struct cpufreq_frequency_table *table = &jz4760_freq_table.table[0];
+ unsigned int MAX_FREQ;
+
+ dprintk(KERN_INFO "Jz4760 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_jz4760_driver = {
+// .flags = CPUFREQ_STICKY,
+ .init = jz4760_cpufreq_driver_init,
+ .verify = jz4760_freq_verify,
+ .target = jz4760_freq_target,
+ .get = jz4760_freq_get,
+ .name = "jz4760",
+};
+
+static int __init jz4760_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&cpufreq_jz4760_driver);
+}
+
+static void __exit jz4760_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&cpufreq_jz4760_driver);
+}
+
+module_init(jz4760_cpufreq_init);
+module_exit(jz4760_cpufreq_exit);
+
+MODULE_AUTHOR("Regen <lhhuang@ingenic.cn>");
+MODULE_DESCRIPTION("cpufreq driver for Jz4760");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/jz4760/dma.c b/arch/mips/jz4760/dma.c
new file mode 100644
index 00000000000..97d35e44107
--- /dev/null
+++ b/arch/mips/jz4760/dma.c
@@ -0,0 +1,852 @@
+/*
+ * linux/arch/mips/jz4760/dma.c
+ *
+ * Support functions for the JZ4760 internal DMA channels.
+ * No-descriptor transfer only.
+ * Descriptor transfer should also call jz_request_dma() to get a free
+ * channel and call jz_free_dma() to free the channel. And driver should
+ * build the DMA descriptor and setup the DMA channel by itself.
+ *
+ * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/soundcard.h>
+
+#include <asm/system.h>
+#include <asm/addrspace.h>
+#include <asm/jzsoc.h>
+
+/*
+ * A note on resource allocation:
+ *
+ * All drivers needing DMA channels, should allocate and release them
+ * through the public routines `jz_request_dma()' and `jz_free_dma()'.
+ *
+ * In order to avoid problems, all processes should allocate resources in
+ * the same sequence and release them in the reverse order.
+ *
+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
+ * When releasing them, first release the IRQ, then release the DMA. The
+ * main reason for this order is that, if you are requesting the DMA buffer
+ * done interrupt, you won't know the irq number until the DMA channel is
+ * returned from jz_request_dma().
+ */
+
+struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = {
+ { dev_id: DMA_ID_BCH_ENC, }, /* DMAC0 channel 0, reserved for BCH */
+ { dev_id: -1, }, /* DMAC0 channel 1 */
+ { dev_id: -1, }, /* DMAC0 channel 2 */
+ { dev_id: -1, }, /* DMAC0 channel 3 */
+ { dev_id: -1, }, /* DMAC0 channel 4 */
+ { dev_id: 0, }, /* DMAC0 channel 5 --- unavailable */
+
+ /* To avoid bug, reserved channel 6 & 7 for AIC_TX & AIC_RX */
+ { dev_id: DMA_ID_AIC_TX, }, /* DMAC1 channel 0 */
+ { dev_id: DMA_ID_AIC_RX, }, /* DMAC1 channel 1 */
+
+ { dev_id: -1, }, /* DMAC1 channel 2 */
+ { dev_id: -1, }, /* DMAC1 channel 3 */
+ { dev_id: -1, }, /* DMAC0 channel 4 */
+ { dev_id: 0, }, /* DMAC0 channel 5 --- unavailable */
+};
+
+// Device FIFO addresses and default DMA modes
+static const struct {
+ unsigned int fifo_addr;
+ unsigned int dma_mode;
+ unsigned int dma_source;
+} dma_dev_table[DMA_ID_MAX] = {
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_EXT}, /* External request with DREQn */
+ {0x18000000, DMA_AUTOINIT, DMAC_DRSR_RS_NAND}, /* NAND request */
+ {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_ENC},
+ {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_DEC},
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO},
+// {CPHYSADDR(TSSI_FIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_TSSIIN},
+ {CPHYSADDR(UART3_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT},
+ {CPHYSADDR(UART3_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART3IN},
+ {CPHYSADDR(UART2_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT},
+ {CPHYSADDR(UART2_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART2IN},
+ {CPHYSADDR(UART1_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT},
+ {CPHYSADDR(UART1_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART1IN},
+ {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT},
+ {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN},
+ {CPHYSADDR(SSI_DR(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI0OUT},
+ {CPHYSADDR(SSI_DR(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI0IN},
+
+ /*spdif used */
+ //{CPHYSADDR(SPDIF_FIFO), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ /*aic unpack used*/
+ {CPHYSADDR(AIC_DR), DMA_AIC_TX_CMD_UNPACK | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ /*aic pack used*/
+ //{CPHYSADDR(AIC_DR), DMA_AIC_TX_CMD_PACK | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN},
+ {CPHYSADDR(MSC_TXFIFO(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC0OUT},
+ {CPHYSADDR(MSC_RXFIFO(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC0IN},
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU},
+ {CPHYSADDR(SADC_ADTCH), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SADC},/* Touch Screen Data Register */
+ {CPHYSADDR(MSC_TXFIFO(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC1OUT}, /* SSC1 TX */
+ {CPHYSADDR(MSC_RXFIFO(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC1IN}, /* SSC1 RX */
+ {CPHYSADDR(SSI_DR(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI1OUT},
+ {CPHYSADDR(SSI_DR(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI1IN},
+ {CPHYSADDR(PCM_PDP), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_PMOUT},
+ {CPHYSADDR(PCM_PDP), DMA_16BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_PMIN},
+ {},
+};
+
+
+int jz_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data)
+{
+ int i, len = 0;
+ struct jz_dma_chan *chan;
+
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if ((chan = get_dma_chan(i)) != NULL) {
+ len += sprintf(buf + len, "%2d: %s\n",
+ i, chan->dev_str);
+ }
+ }
+
+ if (fpos >= len) {
+ *start = buf;
+ *eof = 1;
+ return 0;
+ }
+ *start = buf + fpos;
+ if ((len -= fpos) > length)
+ return length;
+ *eof = 1;
+ return len;
+}
+
+
+void dump_jz_dma_channel(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan;
+
+ if (dmanr > MAX_DMA_NUM)
+ return;
+ chan = &jz_dma_table[dmanr];
+
+ printk("DMA%d Registers:\n", dmanr);
+ printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR(chan->io/HALF_DMA_NUM));
+ printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr));
+ printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr));
+ printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr));
+ printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr));
+ printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr));
+ printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr));
+ printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr));
+ printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR(chan->io/HALF_DMA_NUM));
+}
+
+void dump_jz_bdma_channel(unsigned int dmanr)
+{
+ printk("\n----------chan%d----------------\n",dmanr);
+ printk("DSA: %x\n",REG_BDMAC_DSAR(dmanr));
+ printk("DTA: %x\n",REG_BDMAC_DTAR(dmanr));
+ printk("DTC: %x\n",REG_BDMAC_DTCR(dmanr));
+ printk("DRT: %x\n",REG_BDMAC_DRSR(dmanr));
+ printk("DCS: %x\n",REG_BDMAC_DCCSR(dmanr));
+ printk("DCM: %x\n",REG_BDMAC_DCMD(dmanr));
+ printk("DDA: %x\n",REG_BDMAC_DDA(dmanr));
+ printk("DSD: %x\n",REG_BDMAC_DSD(dmanr));
+ printk("DNT: %x\n",REG_BDMAC_DNT(dmanr));
+ printk("DMAC: %x\n",REG_BDMAC_DMACR);
+ printk("DIRQP: %x\n",REG_BDMAC_DMAIPR);
+ printk("DDR: %x\n",REG_BDMAC_DMADBR);
+ printk("DDRS: %x\n",REG_BDMAC_DMADBSR);
+ printk("DCKE: %x\n",REG_BDMAC_DMACKE);
+ printk("-------------------------\n");
+}
+
+
+/**
+ * jz_request_dma - dynamically allcate an idle DMA channel to return
+ * @dev_id: the specified dma device id or DMA_ID_RAW_SET
+ * @dev_str: the specified dma device string name
+ * @irqhandler: the irq handler, or NULL
+ * @irqflags: the irq handler flags
+ * @irq_dev_id: the irq handler device id for shared irq
+ *
+ * Finds a free channel, and binds the requested device to it.
+ * Returns the allocated channel number, or negative on error.
+ * Requests the DMA done IRQ if irqhandler != NULL.
+ *
+*/
+/*int jz_request_dma(int dev_id, const char *dev_str,
+ void (*irqhandler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ void *irq_dev_id)
+*/
+
+int jz_request_dma(int dev_id, const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags,
+ void *irq_dev_id)
+{
+ struct jz_dma_chan *chan;
+ int i, ret;
+
+ if (dev_id < 0 || dev_id >= DMA_ID_MAX)
+ return -EINVAL;
+
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if (jz_dma_table[i].dev_id < 0)
+ break;
+ }
+ if (i == MAX_DMA_NUM) /* no free channel */
+ return -ENODEV;
+
+ /* we got a free channel */
+ chan = &jz_dma_table[i];
+
+ if (irqhandler) {
+ chan->irq = IRQ_DMA_0 + i; // allocate irq number
+ chan->irq_dev = irq_dev_id;
+ if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+ dev_str, chan->irq_dev))) {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ return ret;
+ }
+ } else {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ }
+
+ // fill it in
+ chan->io = i;
+ chan->dev_id = dev_id;
+ chan->dev_str = dev_str;
+ chan->fifo_addr = dma_dev_table[dev_id].fifo_addr;
+ chan->mode = dma_dev_table[dev_id].dma_mode;
+ chan->source = dma_dev_table[dev_id].dma_source;
+
+ if (i < HALF_DMA_NUM)
+ REG_DMAC_DMACKE(0) = 1 << i;
+ else
+ REG_DMAC_DMACKE(1) = 1 << (i - HALF_DMA_NUM);
+
+ return i;
+}
+
+void jz_free_dma(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan) {
+ printk("Trying to free DMA%d\n", dmanr);
+ return;
+ }
+
+ disable_dma(dmanr);
+ if (chan->irq)
+ free_irq(chan->irq, chan->irq_dev);
+
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ chan->dev_id = -1;
+}
+
+void jz_set_dma_dest_width(int dmanr, int nbit)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_DWDH_MASK;
+ switch (nbit) {
+ case 8:
+ chan->mode |= DMAC_DCMD_DWDH_8;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_DWDH_16;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_DWDH_32;
+ break;
+ }
+}
+
+void jz_set_dma_src_width(int dmanr, int nbit)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_SWDH_MASK;
+ switch (nbit) {
+ case 8:
+ chan->mode |= DMAC_DCMD_SWDH_8;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_SWDH_16;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_SWDH_32;
+ break;
+ }
+}
+
+void jz_set_dma_block_size(int dmanr, int nbyte)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_DS_MASK;
+ switch (nbyte) {
+ case 1:
+ chan->mode |= DMAC_DCMD_DS_8BIT;
+ break;
+ case 2:
+ chan->mode |= DMAC_DCMD_DS_16BIT;
+ break;
+ case 4:
+ chan->mode |= DMAC_DCMD_DS_32BIT;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_DS_16BYTE;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_DS_32BYTE;
+ break;
+ }
+}
+
+unsigned int jz_get_dma_command(int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ return chan->mode;
+}
+
+/**
+ * jz_set_dma_mode - do the raw settings for the specified DMA channel
+ * @dmanr: the specified DMA channel
+ * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE
+ * @dma_mode: dma raw mode
+ * @dma_source: dma raw request source
+ * @fifo_addr: dma raw device fifo address
+ *
+ * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call
+ * jz_set_dma_mode() rather than set_dma_mode() if you work with
+ * and external request dma device.
+ *
+ * NOTE: Don not dynamically allocate dma channel if one external request
+ * dma device will occupy this channel.
+*/
+int jz_set_dma_mode(unsigned int dmanr, unsigned int mode,
+ unsigned int dma_mode, unsigned int dma_source,
+ unsigned int fifo_addr)
+{
+ int dev_id, i;
+ struct jz_dma_chan *chan;
+
+ if (dmanr > MAX_DMA_NUM)
+ return -ENODEV;
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if (jz_dma_table[i].dev_id < 0)
+ break;
+ }
+ if (i == MAX_DMA_NUM)
+ return -ENODEV;
+
+ chan = &jz_dma_table[dmanr];
+ dev_id = chan->dev_id;
+ if (dev_id > 0) {
+ printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n",
+ __FUNCTION__, dmanr);
+ return -ENODEV;
+ }
+
+ /* clone it from the dynamically allocated. */
+ if (i != dmanr) {
+ chan->irq = jz_dma_table[i].irq;
+ chan->irq_dev = jz_dma_table[i].irq_dev;
+ chan->dev_str = jz_dma_table[i].dev_str;
+ jz_dma_table[i].irq = 0;
+ jz_dma_table[i].irq_dev = NULL;
+ jz_dma_table[i].dev_id = -1;
+ }
+ chan->dev_id = DMA_ID_RAW_SET;
+ chan->io = dmanr;
+ chan->fifo_addr = fifo_addr;
+ chan->mode = dma_mode;
+ chan->source = dma_source;
+
+ set_dma_mode(dmanr, dma_mode);
+
+ return dmanr;
+}
+
+void enable_dma(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+ REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */
+ __dmac_enable_channel(dmanr);
+ if (chan->irq)
+ __dmac_channel_enable_irq(dmanr);
+}
+
+#define DMA_DISABLE_POLL 0x10000
+
+void disable_dma(unsigned int dmanr)
+{
+ int i;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ if (!__dmac_channel_enabled(dmanr))
+ return;
+
+ for (i = 0; i < DMA_DISABLE_POLL; i++)
+ if (__dmac_channel_transmit_end_detected(dmanr))
+ break;
+#if 0
+ if (i == DMA_DISABLE_POLL)
+ printk(KERN_INFO "disable_dma: poll expired!\n");
+#endif
+
+ __dmac_disable_channel(dmanr);
+ if (chan->irq)
+ __dmac_channel_disable_irq(dmanr);
+}
+
+/* Note: DMA_MODE_MASK is simulated by sw */
+void set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ if (mode == DMA_MODE_READ) {
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else {
+ printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+ }
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+}
+
+void set_dma_addr(unsigned int dmanr, unsigned int phyaddr)
+{
+ unsigned int mode;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ mode = chan->mode & DMA_MODE_MASK;
+ if (mode == DMA_MODE_READ) {
+ REG_DMAC_DSAR(chan->io) = chan->fifo_addr;
+ REG_DMAC_DTAR(chan->io) = phyaddr;
+ } else if (mode == DMA_MODE_WRITE) {
+ REG_DMAC_DSAR(chan->io) = phyaddr;
+ REG_DMAC_DTAR(chan->io) = chan->fifo_addr;
+ } else
+ printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n");
+}
+
+void set_dma_count(unsigned int dmanr, unsigned int bytecnt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ int dma_ds[] = {4, 1, 2, 16, 32};
+ unsigned int ds;
+
+ if (!chan)
+ return;
+
+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT;
+ REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count
+}
+
+unsigned int get_dma_residue(unsigned int dmanr)
+{
+ unsigned int count, ds;
+ int dma_ds[] = {4, 1, 2, 16, 32};
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+
+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT;
+ count = REG_DMAC_DTCR(chan->io);
+ count = count * dma_ds[ds];
+
+ return count;
+}
+
+void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ switch (audio_fmt) {
+ case AFMT_U8:
+ /* burst mode : 32BIT */
+ break;
+ case AFMT_S16_LE:
+ /* burst mode : 16BYTE */
+ if (mode == DMA_MODE_READ) {
+ chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ //chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else
+ printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+ break;
+ }
+}
+
+void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ switch (audio_fmt) {
+ case 8:
+ /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */
+ break;
+ case 16:
+ /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */
+ if (mode == DMA_MODE_READ) {
+ chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else
+ printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+ break;
+ }
+}
+
+//#define JZ4760_DMAC_TEST_ENABLE
+#undef JZ4760_DMAC_TEST_ENABLE
+
+#ifdef JZ4760_DMAC_TEST_ENABLE
+
+/*
+ * DMA test: external address <--> external address
+ */
+#define TEST_DMA_SIZE 16*1024
+
+static jz_dma_desc *dma_desc;
+
+static int dma_chan;
+static dma_addr_t dma_desc_phys_addr;
+static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr;
+
+static int dma_check_result(void *src, void *dst, int size)
+{
+ unsigned int addr1, addr2, i, err = 0;
+
+ addr1 = (unsigned int)src;
+ addr2 = (unsigned int)dst;
+
+ for (i = 0; i < size; i += 4) {
+ if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) {
+ err++;
+ printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2);
+ }
+ addr1 += 4;
+ addr2 += 4;
+ }
+ printk("check DMA result err=%d\n", err);
+ return err;
+}
+
+static irqreturn_t jz4760_dma_irq(int irq, void *dev_id)
+{
+ printk("jz4760_dma_irq %d\n", irq);
+
+
+ if (__dmac_channel_transmit_halt_detected(dma_chan)) {
+ printk("DMA HALT\n");
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ __dmac_channel_clear_transmit_halt(dma_chan);
+ }
+
+ if (__dmac_channel_address_error_detected(dma_chan)) {
+ printk("DMA ADDR ERROR\n");
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ REG_DMAC_DSAR(dma_chan) = 0; /* clear source address register */
+ REG_DMAC_DTAR(dma_chan) = 0; /* clear target address register */
+ __dmac_channel_clear_address_error(dma_chan);
+ }
+
+ if (__dmac_channel_descriptor_invalid_detected(dma_chan)) {
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ printk("DMA DESC INVALID\n");
+ __dmac_channel_clear_descriptor_invalid(dma_chan);
+ }
+
+ if (__dmac_channel_count_terminated_detected(dma_chan)) {
+ printk("DMA CT\n");
+ __dmac_channel_clear_count_terminated(dma_chan);
+ }
+
+ if (__dmac_channel_transmit_end_detected(dma_chan)) {
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ printk("DMA TT\n");
+ __dmac_channel_clear_transmit_end(dma_chan);
+ dump_jz_dma_channel(dma_chan);
+ dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE);
+ }
+
+ return IRQ_HANDLED;
+}
+
+void dma_nodesc_test(void)
+{
+ unsigned int addr, i;
+
+ printk("dma_nodesc_test\n");
+
+ /* Request DMA channel and setup irq handler */
+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4760_dma_irq,
+ IRQF_DISABLED, NULL);
+ if (dma_chan < 0) {
+ printk("Setup irq failed\n");
+ return;
+ }
+
+ printk("Requested DMA channel = %d\n", dma_chan);
+
+ /* Allocate DMA buffers */
+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+
+ dma_src_phys_addr = CPHYSADDR(dma_src_addr);
+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr);
+
+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr);
+
+ /* Prepare data for source buffer */
+ addr = (unsigned int)dma_src_addr;
+ for (i = 0; i < TEST_DMA_SIZE; i += 4) {
+ *(volatile unsigned int *)addr = addr;
+ addr += 4;
+ }
+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE);
+
+ /* Init target buffer */
+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE);
+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE);
+
+ /* Init DMA module */
+ printk("Starting DMA\n");
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0;
+ REG_DMAC_DCCSR(dma_chan) = 0;
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+ REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
+ REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
+ REG_DMAC_DTCR(dma_chan) = 512;
+ REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE;
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */
+
+ /* wait a long time, ensure transfer end */
+ printk("wait 3s...\n");
+ mdelay(3000); /* wait 3s */
+
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ /* free buffers */
+ printk("free DMA buffers\n");
+ free_pages(dma_src_addr, 2);
+ free_pages(dma_dst_addr, 2);
+
+ if (dma_desc)
+ free_pages((unsigned int)dma_desc, 0);
+
+ /* free dma */
+ jz_free_dma(dma_chan);
+}
+
+void dma_desc_test(void)
+{
+ unsigned int next, addr, i;
+ static jz_dma_desc *desc;
+
+ printk("dma_desc_test\n");
+
+ /* Request DMA channel and setup irq handler */
+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4760_dma_irq,
+ IRQF_DISABLED, NULL);
+ if (dma_chan < 0) {
+ printk("Setup irq failed\n");
+ return;
+ }
+
+ printk("Requested DMA channel = %d\n", dma_chan);
+
+ /* Allocate DMA buffers */
+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+
+ dma_src_phys_addr = CPHYSADDR(dma_src_addr);
+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr);
+
+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr);
+
+ /* Prepare data for source buffer */
+ addr = (unsigned int)dma_src_addr;
+ for (i = 0; i < TEST_DMA_SIZE; i += 4) {
+ *(volatile unsigned int *)addr = addr;
+ addr += 4;
+ }
+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE);
+
+ /* Init target buffer */
+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE);
+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE);
+
+ /* Allocate DMA descriptors */
+ dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0);
+ dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc);
+
+ printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr);
+
+ /* Setup DMA descriptors */
+ desc = dma_desc;
+ next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr; /* DMA target address */
+ desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */
+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */
+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE;
+ desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */
+ desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */
+
+ dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc)));
+
+ /* Setup DMA descriptor address */
+ REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr;
+
+ /* Setup request source */
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+
+ /* Setup DMA channel control/status register */
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */
+
+ /* Enable DMA */
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE;
+
+ /* DMA doorbell set -- start DMA now ... */
+ REG_DMAC_DMADBSR(dma_chan/HALF_DMA_NUM) = 1 << dma_chan;
+
+ /* wait a long time, ensure transfer end */
+ printk("wait 3s...\n");
+ mdelay(3000); /* wait 3s */
+
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ /* free buffers */
+ printk("free DMA buffers\n");
+ free_pages(dma_src_addr, 2);
+ free_pages(dma_dst_addr, 2);
+
+ if (dma_desc)
+ free_pages((unsigned int)dma_desc, 0);
+
+ /* free dma */
+ jz_free_dma(dma_chan);
+}
+
+#endif
+
+//EXPORT_SYMBOL_NOVERS(jz_dma_table);
+EXPORT_SYMBOL(jz_dma_table);
+EXPORT_SYMBOL(jz_request_dma);
+EXPORT_SYMBOL(jz_free_dma);
+EXPORT_SYMBOL(jz_set_dma_src_width);
+EXPORT_SYMBOL(jz_set_dma_dest_width);
+EXPORT_SYMBOL(jz_set_dma_block_size);
+EXPORT_SYMBOL(jz_set_dma_mode);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(jz_set_oss_dma);
+EXPORT_SYMBOL(jz_set_alsa_dma);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(dump_jz_dma_channel);
diff --git a/arch/mips/jz4760/fpu.c b/arch/mips/jz4760/fpu.c
new file mode 100644
index 00000000000..29a1940304f
--- /dev/null
+++ b/arch/mips/jz4760/fpu.c
@@ -0,0 +1,143 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#include <asm/jzsoc.h>
+
+void jz4760_fpu_dump(void)
+{
+ unsigned int fgpr[32];
+ unsigned int fscr, fir, i;
+
+ for (i = 0; i < 32; i ++)
+ fgpr[i] = 0xdeadbeef;
+
+ __asm__ __volatile__(
+ "swc1 $f0, 0(%0)\n\t"
+ "swc1 $f1, 4(%0)\n\t"
+ "swc1 $f2, 8(%0)\n\t"
+ "swc1 $f3, 12(%0)\n\t"
+ "swc1 $f4, 16(%0)\n\t"
+ "swc1 $f4, 20(%0)\n\t"
+ "swc1 $f6, 24(%0)\n\t"
+ "swc1 $f6, 28(%0)\n\t"
+ "swc1 $f8, 32(%0)\n\t"
+ "swc1 $f9, 36(%0)\n\t"
+ "swc1 $f10, 40(%0)\n\t"
+ "swc1 $f11, 44(%0)\n\t"
+ "swc1 $f12, 48(%0)\n\t"
+ "swc1 $f13, 52(%0)\n\t"
+ "swc1 $f14, 56(%0)\n\t"
+ "swc1 $f15, 60(%0)\n\t"
+ "swc1 $f16, 64(%0)\n\t"
+ "swc1 $f17, 68(%0)\n\t"
+ "swc1 $f18, 72(%0)\n\t"
+ "swc1 $f19, 76(%0)\n\t"
+ "swc1 $f20, 80(%0)\n\t"
+ "swc1 $f21, 84(%0)\n\t"
+ "swc1 $f22, 88(%0)\n\t"
+ "swc1 $f23, 92(%0)\n\t"
+ "swc1 $f24, 96(%0)\n\t"
+ "swc1 $f25, 100(%0)\n\t"
+ "swc1 $f26, 104(%0)\n\t"
+ "swc1 $f27, 108(%0)\n\t"
+ "swc1 $f28, 112(%0)\n\t"
+ "swc1 $f29, 116(%0)\n\t"
+ "swc1 $f30, 120(%0)\n\t"
+ "swc1 $f31, 124(%0)\n\t"
+ :
+ :"r"(fgpr)
+ );
+
+ /* Get FPU control and status register */
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(fscr)
+ :
+ );
+
+ /* Get FPU implementation and revision register */
+ __asm__ __volatile__(
+ "cfc1 %0, $0 \n\t"
+ :"=r"(fir)
+ :
+ );
+
+ printk("Dump of FPU: \n");
+
+ for (i = 0; i < 32; i += 4)
+ printk("%08x %08x %08x %08x \n",
+ fgpr[i],fgpr[i+1],fgpr[i+2],fgpr[i+3]);
+ printk("FPU control and status register = %08x \n",fscr);
+ printk("FPU implementation and revision register = %08x \n",fir);
+
+ fscr |= 0x11;
+
+ __asm__ __volatile__(
+ "ctc1 %0, $31 \n\t"
+ :
+ :"r"(fscr)
+ );
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(fscr)
+ :
+ );
+ printk("FPU control and status register = %08x \n",fscr);
+}
+
+void jz4760_fpu_init(unsigned int round)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(tmp)
+ :
+ );
+
+// printk("original jz4760 FCSR value: %8x\n",tmp);
+
+ tmp = 0x0;
+ /* Jz4760 FPU init */
+ /* disable any exception */
+ tmp |= (0x0 << 7);
+ /* Set ronud mode */
+ tmp &= ~0x3;
+ tmp |= (round & 0x3);
+
+// printk("plan to set jz4760 FPU FCSR to %08x \n",tmp);
+ __asm__ __volatile__(
+ "ctc1 %0, $28 \n\t"
+ :
+ :"r"(tmp)
+ );
+
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(tmp)
+ :
+ );
+
+// printk("jz4760 FCSR value after setting: %8x\n",tmp);
+
+}
+
+EXPORT_SYMBOL(jz4760_fpu_init);
diff --git a/arch/mips/jz4760/gpiolib.c b/arch/mips/jz4760/gpiolib.c
new file mode 100644
index 00000000000..df173872508
--- /dev/null
+++ b/arch/mips/jz4760/gpiolib.c
@@ -0,0 +1,208 @@
+
+/* arch/mips/jz4760/gpiolib.c
+ *
+ * hlguo <hlguo@ingenic.cn>
+ *
+ * jz4760 GPIOlib 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/jzsoc.h>
+#include <asm/gpio.h>
+
+#include <linux/gpio.h>
+
+struct jz4760_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *base;
+};
+
+static inline struct jz4760_gpio_chip *to_jz4760_chip(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct jz4760_gpio_chip, chip);
+}
+
+static void jz4760_gpiolib_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base + offset;
+ local_irq_save(flags);
+ if (value)
+ __gpio_set_pin(n);
+ else
+ __gpio_clear_pin(n);
+ local_irq_restore(flags);
+}
+
+static int jz4760_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+ int state = -1;
+
+ n = chip->base + offset;
+ local_irq_save(flags);
+ state = __gpio_get_pin(n);
+ local_irq_restore(flags);
+ return state;
+
+}
+
+static int jz4760_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base + offset;
+ local_irq_save(flags);
+ __gpio_as_input(n);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int jz4760_gpiolib_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base + offset;
+ local_irq_save(flags);
+ __gpio_as_output(n);
+ if (value)
+ __gpio_set_pin(n);
+ else
+ __gpio_clear_pin(n);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int jz4760_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return 0;
+}
+
+static void jz4760_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ return;
+}
+
+static struct jz4760_gpio_chip jz4760_gpios[] = {
+ [0] = {
+ .base = (unsigned *)GPIO_BASEA,
+ .chip = {
+ .base = 0*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOA",
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+ [1] = {
+ .base = (unsigned *)GPIO_BASEB,
+ .chip = {
+ .base = 1*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOB",
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+ [2] = {
+ .base = (unsigned *)GPIO_BASEC,
+ .chip = {
+ .base = 2*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOC",
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+ [3] = {
+ .base = (unsigned *)GPIO_BASED,
+ .chip = {
+ .base = 3*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOD",
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+ [4] = {
+ .base = (unsigned *)GPIO_BASEE,
+ .chip = {
+ .base = 4*32,
+ .label = "GPIOE",
+ .owner = THIS_MODULE,
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+ [5] = {
+ .base = (unsigned *)GPIO_BASEF,
+ .chip = {
+ .base = 5*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOF",
+ .ngpio = 32,
+ .direction_input = jz4760_gpiolib_input,
+ .direction_output = jz4760_gpiolib_output,
+ .set = jz4760_gpiolib_set,
+ .get = jz4760_gpiolib_get,
+ .request = jz4760_gpio_request,
+ .free = jz4760_gpio_free,
+ },
+ },
+};
+
+static __init int jz4760_gpiolib_init(void)
+{
+ struct jz4760_gpio_chip *chip = jz4760_gpios;
+ int gpn;
+
+ for (gpn = 0; gpn < ARRAY_SIZE(jz4760_gpios); gpn++, chip++)
+ gpiochip_add(&chip->chip);
+
+ return 0;
+}
+
+arch_initcall(jz4760_gpiolib_init);
diff --git a/arch/mips/jz4760/i2c.c b/arch/mips/jz4760/i2c.c
new file mode 100644
index 00000000000..4c0bfc787af
--- /dev/null
+++ b/arch/mips/jz4760/i2c.c
@@ -0,0 +1,273 @@
+/*
+ * linux/arch/mips/jz4760/i2c.c
+ *
+ * Jz4760 I2C routines.
+ *
+ * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@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/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+#define TIMEOUT 1000
+
+/*
+ * I2C bus protocol basic routines
+ */
+static int i2c_put_data(unsigned char data)
+{
+ unsigned int timeout = TIMEOUT*10;
+
+ __i2c_write(data);
+ __i2c_set_drf();
+ while (__i2c_check_drf() != 0);
+ while (!__i2c_transmit_ended());
+ while (!__i2c_received_ack() && timeout)
+ timeout--;
+
+ if (timeout)
+ return 0;
+ else
+ return -ETIMEDOUT;
+}
+
+#ifdef CONFIG_JZ_TPANEL_ATA2508
+static int i2c_put_data_nack(unsigned char data)
+{
+ unsigned int timeout = TIMEOUT*10;
+
+ __i2c_write(data);
+ __i2c_set_drf();
+ while (__i2c_check_drf() != 0);
+ while (!__i2c_transmit_ended());
+ while (timeout--);
+ return 0;
+}
+#endif
+
+static int i2c_get_data(unsigned char *data, int ack)
+{
+ int timeout = TIMEOUT*10;
+
+ if (!ack)
+ __i2c_send_nack();
+ else
+ __i2c_send_ack();
+
+ while (__i2c_check_drf() == 0 && timeout)
+ timeout--;
+
+ if (timeout) {
+ if (!ack)
+ __i2c_send_stop();
+ *data = __i2c_read();
+ __i2c_clear_drf();
+ return 0;
+ } else
+ return -ETIMEDOUT;
+}
+
+/*
+ * I2C interface
+ */
+void i2c_open(void)
+{
+ __i2c_set_clk(jz_clocks.extalclk, 10000); /* default 10 KHz */
+ __i2c_enable();
+}
+
+void i2c_close(void)
+{
+ udelay(300); /* wait for STOP goes over. */
+ __i2c_disable();
+}
+
+void i2c_setclk(unsigned int i2cclk)
+{
+ __i2c_set_clk(jz_clocks.extalclk, i2cclk);
+}
+
+int i2c_lseek(unsigned char device, unsigned char offset)
+{
+ __i2c_send_nack(); /* Master does not send ACK, slave sends it */
+ __i2c_send_start();
+ if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
+ goto device_err;
+ if (i2c_put_data(offset) < 0)
+ goto address_err;
+ return 0;
+ device_err:
+ printk(KERN_DEBUG "No I2C device (0x%02x) installed.\n", device);
+ __i2c_send_stop();
+ return -ENODEV;
+ address_err:
+ printk(KERN_DEBUG "No I2C device (0x%02x) response.\n", device);
+ __i2c_send_stop();
+ return -EREMOTEIO;
+}
+
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ int timeout = 5;
+
+L_try_again:
+
+ if (timeout < 0)
+ goto L_timeout;
+
+ __i2c_send_nack(); /* Master does not send ACK, slave sends it */
+ __i2c_send_start();
+ if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
+ goto device_werr;
+ if (i2c_put_data(address) < 0)
+ goto address_err;
+
+ __i2c_send_start();
+ if (i2c_put_data( (device << 1) | I2C_READ ) < 0)
+ goto device_rerr;
+ __i2c_send_ack(); /* Master sends ACK for continue reading */
+ while (cnt) {
+ if (cnt == 1) {
+ if (i2c_get_data(buf, 0) < 0)
+ break;
+ } else {
+ if (i2c_get_data(buf, 1) < 0)
+ break;
+ }
+ cnt--;
+ buf++;
+ }
+
+ __i2c_send_stop();
+ return count - cnt;
+ device_rerr:
+ device_werr:
+ address_err:
+ timeout --;
+ __i2c_send_stop();
+ goto L_try_again;
+
+L_timeout:
+ __i2c_send_stop();
+ printk("Read I2C device 0x%2x failed.\n", device);
+ return -ENODEV;
+}
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ int cnt_in_pg;
+ int timeout = 5;
+ unsigned char *tmpbuf;
+ unsigned char tmpaddr;
+
+ __i2c_send_nack(); /* Master does not send ACK, slave sends it */
+
+ W_try_again:
+ if (timeout < 0)
+ goto W_timeout;
+
+ cnt = count;
+ tmpbuf = (unsigned char *)buf;
+ tmpaddr = address;
+
+ start_write_page:
+ cnt_in_pg = 0;
+ __i2c_send_start();
+ if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0)
+ goto device_err;
+#ifdef CONFIG_JZ_TPANEL_ATA2508
+ if (address == 0xff) {
+ if (i2c_put_data_nack(tmpaddr) < 0)
+ goto address_err;
+ while (cnt) {
+ if (++cnt_in_pg > 8) {
+ __i2c_send_stop();
+ mdelay(1);
+ tmpaddr += 8;
+ goto start_write_page;
+ }
+ if (i2c_put_data_nack(*tmpbuf) < 0)
+ break;
+ cnt--;
+ tmpbuf++;
+ }
+ }
+ else {
+
+ if (i2c_put_data(tmpaddr) < 0)
+ goto address_err;
+ while (cnt) {
+ if (++cnt_in_pg > 8) {
+ __i2c_send_stop();
+ mdelay(1);
+ tmpaddr += 8;
+ goto start_write_page;
+ }
+ if (i2c_put_data(*tmpbuf) < 0)
+ break;
+ cnt--;
+ tmpbuf++;
+ }
+ }
+#else
+ if (i2c_put_data(tmpaddr) < 0)
+ goto address_err;
+ while (cnt) {
+ if (++cnt_in_pg > 8) {
+ __i2c_send_stop();
+ mdelay(1);
+ tmpaddr += 8;
+ goto start_write_page;
+ }
+ if (i2c_put_data(*tmpbuf) < 0)
+ break;
+ cnt--;
+ tmpbuf++;
+ }
+#endif
+ __i2c_send_stop();
+ return count - cnt;
+ device_err:
+ address_err:
+ timeout--;
+ __i2c_send_stop();
+ goto W_try_again;
+
+ W_timeout:
+ printk(KERN_DEBUG "Write I2C device 0x%2x failed.\n", device);
+ __i2c_send_stop();
+ return -ENODEV;
+}
+
+EXPORT_SYMBOL(i2c_open);
+EXPORT_SYMBOL(i2c_close);
+EXPORT_SYMBOL(i2c_setclk);
+EXPORT_SYMBOL(i2c_read);
+EXPORT_SYMBOL(i2c_write);
diff --git a/arch/mips/jz4760/i2c_intr_debug.c b/arch/mips/jz4760/i2c_intr_debug.c
new file mode 100644
index 00000000000..73a8bcb81c2
--- /dev/null
+++ b/arch/mips/jz4760/i2c_intr_debug.c
@@ -0,0 +1,254 @@
+/*
+ * linux/arch/mips/jz4760/i2c.c
+ *
+ * Jz4810 I2C routines.
+ *
+ * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
+ * Author: <cwjia@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/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+#define TIMEOUT 1000
+
+static volatile int w_tfep = 0;
+static volatile int w_rfne = 0;
+static unsigned char *tmpbuf;
+static unsigned char tmpaddr;
+static int cnt;
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x00000c00; \
+ REG_GPIO_PXTRGC(2) = 0x00000c00; \
+ REG_GPIO_PXSELS(2) = 0x00000c00; \
+} while (0)
+
+/*
+ * I2C interface
+ */
+
+static int i2c_disable()
+{
+ int timeout = 0xfffff, i = 100;
+
+ REG_I2C_ENB = 0; /*disable i2c*/
+ while((REG_I2C_ENSTA & 0x1) && (timeout > 0)) {
+ udelay(1);
+ timeout --;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+
+static irqreturn_t jz_i2chander(int irq, void *devid)
+{
+ if (REG_I2C_INTST & I2C_INTST_RXFL) {
+ w_rfne = 1;
+ REG_I2C_INTM = 0;
+ return IRQ_HANDLED;
+ }
+ REG_I2C_INTM = 0;
+ w_tfep = 1;
+ return IRQ_HANDLED;
+}
+
+void i2c_open()
+{
+ __gpio_as_i2c();
+ REG_I2C_RXTL = 0;
+ request_irq(IRQ_I2C,jz_i2chander,IRQF_DISABLED,0,0);
+}
+
+void i2c_close(void)
+{
+}
+
+void i2c_setclk(unsigned int i2cclk)
+{
+
+}
+
+static void i2c_init_as_master(unsigned char address)
+{
+ if(i2c_disable())
+ printk("i2c_disable error\n");
+// REG_I2C_CTRL = 0x43;
+ REG_I2C_CTRL = 0x45;
+ REG_I2C_TAR = address; /* slave id needed write only once */
+ REG_I2C_INTM = 0x10;
+ REG_I2C_FHCNT =49;
+ REG_I2C_FLCNT =62;
+ REG_I2C_RXTL = 0;
+// REG_I2C_SHCNT =0xc80; // 6k
+// REG_I2C_SLCNT =0xeb0; // 6k
+// REG_I2C_SHCNT =0x640; // 12k
+// REG_I2C_SLCNT =0x758; // 12k
+// REG_I2C_SHCNT =0x320; //26k
+// REG_I2C_SLCNT =0x3ac; //26k
+// REG_I2C_SHCNT =0x12c; //71k
+// REG_I2C_SLCNT =0x160; //71k
+// REG_I2C_SHCNT =0xc8;
+// REG_I2C_SLCNT =0xe8;
+ REG_I2C_ENB = 1; /*enable i2c*/
+}
+
+
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ volatile int tmp;
+ int timeout = 0xffff;
+
+ i2c_init_as_master(device);
+
+ address = address & 0xff;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+
+ REG_I2C_DC = (I2C_WRITE << 8) | address;
+
+ while(cnt) {
+ timeout = 0xffff;
+
+ REG_I2C_INTM = 0x10;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+ REG_I2C_DC = (I2C_READ << 8);
+ REG_I2C_INTM = 0x4;
+ while(!w_rfne)
+ ;
+
+ w_rfne = 0;
+
+ *buf = REG_I2C_DC & 0xff;
+
+ cnt--;
+ buf++;
+ }
+ return count - cnt;
+}
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt_in_pg;
+ cnt = count;
+ int timeout = 0xffff;
+
+ tmpbuf = (unsigned char *)buf;
+ tmpaddr = address;
+
+rewrite:
+ i2c_init_as_master(device);
+
+start_write_page:
+ cnt_in_pg = 0;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+
+ REG_I2C_DC = (I2C_WRITE << 8) | tmpaddr;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ REG_I2C_INTM = 0x10;
+
+ while(cnt) {
+
+ if (++cnt_in_pg > 16) { //8 or 16
+ mdelay(3);
+ tmpaddr += 16;
+ goto start_write_page;
+ }
+
+ while(!w_tfep)
+ ;
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK)) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ if(REG_I2C_TXABRT != 0)
+ printk("\n\nREG_I2C_TXABRT==0x%x\n",REG_I2C_TXABRT);
+
+ REG_I2C_DC = (I2C_WRITE << 8) | *tmpbuf;
+ REG_I2C_INTM = 0x10;
+
+ w_tfep = 0;
+ cnt--;
+ tmpbuf++;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ }
+
+ timeout = 0xffff;
+ while(((REG_I2C_STA & I2C_STA_MSTACT)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+ mdelay(2);
+ udelay(450);
+
+ if (REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ return count - cnt;
+}
+
+EXPORT_SYMBOL(i2c_open);
+EXPORT_SYMBOL(i2c_close);
+EXPORT_SYMBOL(i2c_setclk);
+EXPORT_SYMBOL(i2c_read);
+EXPORT_SYMBOL(i2c_write);
diff --git a/arch/mips/jz4760/i2c_pio_debug.c b/arch/mips/jz4760/i2c_pio_debug.c
new file mode 100644
index 00000000000..429d9c6c2c8
--- /dev/null
+++ b/arch/mips/jz4760/i2c_pio_debug.c
@@ -0,0 +1,255 @@
+/*
+ * linux/arch/mips/jz4810/i2c.c
+ *
+ * Jz4810 I2C routines.
+ *
+ * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
+ * Author: <cwjia@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/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+#define TIMEOUT 1000
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x00000c00; \
+ REG_GPIO_PXTRGC(2) = 0x00000c00; \
+ REG_GPIO_PXSELS(2) = 0x00000c00; \
+} while (0)
+
+/*
+ * I2C interface
+ */
+
+static int i2c_disable()
+{
+ int timeout = 0xfffff, i = 100;
+
+ REG_I2C_ENB = 0; /*disable i2c*/
+ while((REG_I2C_ENSTA & 0x1) && (timeout > 0)) {
+ udelay(1);
+ timeout --;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+void i2c_open()
+{
+ __gpio_as_i2c();
+}
+
+void i2c_close(void)
+{
+}
+
+void i2c_setclk(unsigned int i2cclk)
+{
+
+}
+
+static void i2c_init_as_master(unsigned char address)
+{
+// __gpio_as_i2c();
+ if(i2c_disable())
+ printk("i2c not disable\n");
+// REG_I2C_CTRL = 0x43;
+ REG_I2C_CTRL = 0x45;
+ REG_I2C_TAR = address; /* slave id needed write only once */
+ REG_I2C_INTM = 0;
+ REG_I2C_FHCNT =49;
+ REG_I2C_FLCNT =62;
+// REG_I2C_SHCNT =0xc80; // 6k
+// REG_I2C_SLCNT =0xeb0; // 6k
+// REG_I2C_SHCNT =0x640; // 12k
+// REG_I2C_SLCNT =0x758; // 12k
+// REG_I2C_SHCNT =0x320; //26k
+// REG_I2C_SLCNT =0x3ac; //26k
+// REG_I2C_SHCNT =0x12c; //71k
+// REG_I2C_SLCNT =0x160; //71k
+// REG_I2C_SHCNT =0xc8;
+// REG_I2C_SLCNT =0xe8;
+ REG_I2C_ENB = 1; /*enable i2c*/
+}
+
+
+/* now for fpga test , count == 1 */
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ volatile int tmp;
+ int timeout = 0xffff;
+
+ i2c_init_as_master(device);
+
+ address = address & 0xff;
+
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_WRITE << 8) | address;
+
+ while(cnt) {
+ timeout = 0xffff;
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_READ << 8);
+#if 1
+ while((!(REG_I2C_STA & I2C_STA_RFNE)) && timeout) {
+ timeout--;
+ }
+#endif
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ *buf = REG_I2C_DC & 0xff;
+
+ cnt--;
+ buf++;
+ }
+ return count - cnt;
+}
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt_in_pg,cnt = count;
+ unsigned char *tmpbuf;
+ unsigned char tmpaddr;
+ int timeout = 0xffff;
+ int rw = 0;
+
+
+ tmpbuf = (unsigned char *)buf;
+ tmpaddr = address;
+rewrite:
+ i2c_init_as_master(device);
+
+start_write_page:
+ cnt_in_pg = 0;
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("00***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_WRITE << 8) | tmpaddr;
+#if 1
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+ while(cnt) {
+
+ timeout = 0xfffff;
+#if 1
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+
+ if (++cnt_in_pg > 16) { //8 or 16
+ mdelay(3);
+ tmpaddr += 16;
+ goto start_write_page;
+ }
+
+
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && timeout)
+ ;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ if(REG_I2C_TXABRT != 0)
+ printk("\n\nREG_I2C_TXABRT==0x%x\n",REG_I2C_TXABRT);
+
+ REG_I2C_DC = (I2C_WRITE << 8) | *tmpbuf;
+
+ rw = 0;
+ cnt--;
+ tmpbuf++;
+#if 1
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+ }
+
+ timeout = 0xffff;
+ while(((REG_I2C_STA & I2C_STA_MSTACT)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("22***timeout*****************\n");
+
+ mdelay(2);
+ udelay(450);
+
+ if (REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ return count - cnt;
+}
+
+EXPORT_SYMBOL(i2c_open);
+EXPORT_SYMBOL(i2c_close);
+EXPORT_SYMBOL(i2c_setclk);
+EXPORT_SYMBOL(i2c_read);
+EXPORT_SYMBOL(i2c_write);
diff --git a/arch/mips/jz4760/irq.c b/arch/mips/jz4760/irq.c
new file mode 100644
index 00000000000..be5847fc580
--- /dev/null
+++ b/arch/mips/jz4760/irq.c
@@ -0,0 +1,484 @@
+/*
+ * linux/arch/mips/jz4760/irq.c
+ *
+ * JZ4760 interrupt routines.
+ *
+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/jzsoc.h>
+
+/*
+ * INTC irq type
+ */
+
+static void enable_intc_irq(unsigned int irq)
+{
+ __intc_unmask_irq(irq);
+}
+
+static void disable_intc_irq(unsigned int irq)
+{
+ __intc_mask_irq(irq);
+}
+
+static void mask_and_ack_intc_irq(unsigned int irq)
+{
+ __intc_mask_irq(irq);
+ __intc_ack_irq(irq);
+}
+
+static void end_intc_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_intc_irq(irq);
+ }
+}
+
+static unsigned int startup_intc_irq(unsigned int irq)
+{
+ enable_intc_irq(irq);
+ return 0;
+}
+
+static void shutdown_intc_irq(unsigned int irq)
+{
+ disable_intc_irq(irq);
+}
+
+static struct irq_chip intc_irq_type = {
+ .typename = "INTC",
+ .startup = startup_intc_irq,
+ .shutdown = shutdown_intc_irq,
+ .unmask = enable_intc_irq,
+ .mask = disable_intc_irq,
+ .ack = mask_and_ack_intc_irq,
+ .end = end_intc_irq,
+};
+
+/*
+ * GPIO irq type
+ */
+
+static void enable_gpio_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < (IRQ_GPIO_0 + 32)) {
+ intc_irq = IRQ_GPIO0;
+ }
+ else if (irq < (IRQ_GPIO_0 + 64)) {
+ intc_irq = IRQ_GPIO1;
+ }
+ else if (irq < (IRQ_GPIO_0 + 96)) {
+ intc_irq = IRQ_GPIO2;
+ }
+ else if (irq < (IRQ_GPIO_0 + 128)) {
+ intc_irq = IRQ_GPIO3;
+ }
+ else if (irq < (IRQ_GPIO_0 + 160)) {
+ intc_irq = IRQ_GPIO4;
+ }
+ else {
+ intc_irq = IRQ_GPIO5;
+ }
+
+ enable_intc_irq(intc_irq);
+ __gpio_unmask_irq(irq - IRQ_GPIO_0);
+}
+
+static void disable_gpio_irq(unsigned int irq)
+{
+ __gpio_mask_irq(irq - IRQ_GPIO_0);
+}
+
+static void mask_and_ack_gpio_irq(unsigned int irq)
+{
+ __gpio_mask_irq(irq - IRQ_GPIO_0);
+ __gpio_ack_irq(irq - IRQ_GPIO_0);
+}
+
+static void end_gpio_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_gpio_irq(irq);
+ }
+}
+
+static unsigned int startup_gpio_irq(unsigned int irq)
+{
+ enable_gpio_irq(irq);
+ return 0;
+}
+
+static void shutdown_gpio_irq(unsigned int irq)
+{
+ disable_gpio_irq(irq);
+}
+
+static struct irq_chip gpio_irq_type = {
+ .typename = "GPIO",
+ .startup = startup_gpio_irq,
+ .shutdown = shutdown_gpio_irq,
+ .unmask = enable_gpio_irq,
+ .mask = disable_gpio_irq,
+ .ack = mask_and_ack_gpio_irq,
+ .end = end_gpio_irq,
+};
+
+/*
+ * DMA irq type
+ */
+
+static void enable_dma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_DMAC0;
+ else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */
+ intc_irq = IRQ_DMAC1;
+ else {
+ printk("%s, unexpected dma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __dmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_dma_irq(unsigned int irq)
+{
+ __dmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_dma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_DMAC0;
+ else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */
+ intc_irq = IRQ_DMAC1;
+ else {
+ printk("%s, unexpected dma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __dmac_channel_ack_irq(irq-IRQ_DMA_0); /* needed?? add 20080506, Wolfgang */
+ __dmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void end_dma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_dma_irq(irq);
+ }
+}
+
+static unsigned int startup_dma_irq(unsigned int irq)
+{
+ enable_dma_irq(irq);
+ return 0;
+}
+
+static void shutdown_dma_irq(unsigned int irq)
+{
+ disable_dma_irq(irq);
+}
+
+static struct irq_chip dma_irq_type = {
+ .typename = "DMA",
+ .startup = startup_dma_irq,
+ .shutdown = shutdown_dma_irq,
+ .unmask = enable_dma_irq,
+ .mask = disable_dma_irq,
+ .ack = mask_and_ack_dma_irq,
+ .end = end_dma_irq,
+};
+
+/*
+ * MDMA irq type
+ */
+
+static void enable_mdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < IRQ_MDMA_0 + MAX_MDMA_NUM) /* DMAC Group 0 irq */
+ intc_irq = IRQ_MDMA;
+ else {
+ printk("%s, unexpected mdma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __mdmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_mdma_irq(unsigned int irq)
+{
+ __mdmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_mdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < IRQ_MDMA_0 + MAX_MDMA_NUM ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_MDMA;
+ else {
+ printk("%s, unexpected mdma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __mdmac_channel_ack_irq(irq-IRQ_MDMA_0); /* needed?? add 20080506, Wolfgang */
+ __mdmac_channel_disable_irq(irq - IRQ_MDMA_0);
+}
+
+static void end_mdma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_mdma_irq(irq);
+ }
+}
+
+static unsigned int startup_mdma_irq(unsigned int irq)
+{
+ enable_mdma_irq(irq);
+ return 0;
+}
+
+static void shutdown_mdma_irq(unsigned int irq)
+{
+ disable_mdma_irq(irq);
+}
+
+static struct irq_chip mdma_irq_type = {
+ .typename = "MDMA",
+ .startup = startup_mdma_irq,
+ .shutdown = shutdown_mdma_irq,
+ .unmask = enable_mdma_irq,
+ .mask = disable_mdma_irq,
+ .ack = mask_and_ack_mdma_irq,
+ .end = end_mdma_irq,
+};
+
+//----------------------------------------------------------------------
+
+/*
+ * BDMA irq type
+ */
+
+static void enable_bdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < IRQ_BDMA_0 + MAX_BDMA_NUM)
+ intc_irq = IRQ_BDMA;
+ else {
+ printk("%s, unexpected bdma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __bdmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_bdma_irq(unsigned int irq)
+{
+ __bdmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_bdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < IRQ_BDMA_0 + MAX_BDMA_NUM ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_BDMA;
+ else {
+ printk("%s, unexpected bdma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __bdmac_channel_ack_irq(irq - IRQ_BDMA_0);
+ __bdmac_channel_disable_irq(irq - IRQ_BDMA_0);
+}
+
+static void end_bdma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_bdma_irq(irq);
+ }
+}
+
+static unsigned int startup_bdma_irq(unsigned int irq)
+{
+ enable_bdma_irq(irq);
+ return 0;
+}
+
+static void shutdown_bdma_irq(unsigned int irq)
+{
+ disable_bdma_irq(irq);
+}
+
+static struct irq_chip bdma_irq_type = {
+ .typename = "BDMA",
+ .startup = startup_bdma_irq,
+ .shutdown = shutdown_bdma_irq,
+ .unmask = enable_bdma_irq,
+ .mask = disable_bdma_irq,
+ .ack = mask_and_ack_bdma_irq,
+ .end = end_bdma_irq,
+};
+
+//----------------------------------------------------------------------
+void plat_bad_irq(unsigned int irq)
+{
+ printk("INTC Registers:\n");
+ printk("REG_INTC_ICMR0=0x%08x, REG_INTC_ICMR1=0x%08x\n", REG_INTC_IMR(0), REG_INTC_IMR(1));
+ printk("REG_INTC_ICPR0=0x%08x, REG_INTC_ICPR1=0x%08x\n", REG_INTC_IPR(0), REG_INTC_IPR(1));
+}
+
+extern void (*ack_bad_irq_callback)(unsigned int irq);
+void __init arch_init_irq(void)
+{
+ int i;
+
+ clear_c0_status(0xff04); /* clear ERL */
+ set_c0_status(0x0400); /* set IP2 */
+
+ ack_bad_irq_callback = plat_bad_irq;
+
+ /* Set up INTC irq
+ */
+ for (i = 0; i < NUM_INTC; i++) {
+ disable_intc_irq(i);
+ set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+ }
+
+ /* Set up DMAC irq
+ */
+ for (i = 0; i < NUM_DMA; i++) {
+ disable_dma_irq(IRQ_DMA_0 + i);
+ set_irq_chip_and_handler(IRQ_DMA_0 + i, &dma_irq_type, handle_level_irq);
+ }
+
+ /* Set up MDMAC irq
+ */
+ for (i = 0; i < NUM_MDMA; i++) {
+ disable_mdma_irq(IRQ_MDMA_0 + i);
+ set_irq_chip_and_handler(IRQ_MDMA_0 + i, &mdma_irq_type, handle_level_irq);
+ }
+
+ /* Set up BDMA irq
+ */
+ for (i = 0; i < MAX_BDMA_NUM; i++) {
+ disable_bdma_irq(IRQ_BDMA_0 + i);
+ set_irq_chip_and_handler(IRQ_BDMA_0 + i, &bdma_irq_type, handle_level_irq);
+ }
+
+ /* Set up GPIO irq
+ */
+ for (i = 0; i < NUM_GPIO; i++) {
+ disable_gpio_irq(IRQ_GPIO_0 + i);
+ set_irq_chip_and_handler(IRQ_GPIO_0 + i, &gpio_irq_type, handle_level_irq);
+ }
+}
+
+static int plat_real_irq(int irq)
+{
+ switch (irq) {
+#if 0
+ case IRQ_GPIO0:
+ irq = __gpio_group_irq(0) + IRQ_GPIO_0;
+ break;
+ case IRQ_GPIO1:
+ irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32;
+ break;
+ case IRQ_GPIO2:
+ irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64;
+ break;
+ case IRQ_GPIO3:
+ irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96;
+ break;
+ case IRQ_GPIO4:
+ irq = __gpio_group_irq(4) + IRQ_GPIO_0 + 128;
+ break;
+ case IRQ_GPIO5:
+ irq = __gpio_group_irq(5) + IRQ_GPIO_0 + 160;
+ break;
+#endif
+ case IRQ_DMAC0:
+ case IRQ_DMAC1:
+ irq = __dmac_get_irq() + IRQ_DMA_0;
+ break;
+ case IRQ_MDMA:
+ irq = __mdmac_get_irq() + IRQ_MDMA_0;
+ break;
+ case IRQ_BDMA:
+ irq = __bdmac_get_irq() + IRQ_BDMA_0;
+ break;
+ }
+
+ return irq;
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ int irq = 0, group;
+
+ unsigned long intc_ipr0 = 0, intc_ipr1 = 0;
+
+ intc_ipr0 = REG_INTC_IPR(0);
+ intc_ipr1 = REG_INTC_IPR(1);
+
+
+ if (!(intc_ipr0 || intc_ipr1)) return;
+
+ if (intc_ipr0) {
+ irq = ffs(intc_ipr0) - 1;
+ intc_ipr0 &= ~(1<<irq);
+ } else {
+ irq = ffs(intc_ipr1) - 1;
+ intc_ipr1 &= ~(1<<irq);
+ irq += 32;
+ }
+
+ if ((irq >= IRQ_GPIO5) && (irq <= IRQ_GPIO0)) {
+ group = IRQ_GPIO0 - irq;
+ irq = __gpio_group_irq(group);
+ if (irq < 0) {
+ return;
+ }
+
+ irq += IRQ_GPIO_0 + 32 * group;
+ } else {
+ irq = plat_real_irq(irq);
+ }
+
+ do_IRQ(irq);
+}
diff --git a/arch/mips/jz4760/platform.c b/arch/mips/jz4760/platform.c
new file mode 100644
index 00000000000..befea50f656
--- /dev/null
+++ b/arch/mips/jz4760/platform.c
@@ -0,0 +1,332 @@
+/*
+ * Platform device support for Jz4760 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>
+
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+
+#include <asm/jzsoc.h>
+#include <linux/usb/musb.h>
+#include <../sound/oss/jz_audio.h>
+#include <asm/jzmmc/jz_mmc_platform_data.h>
+
+extern void __init board_msc_init(void);
+
+/* OHCI (USB full speed host controller) */
+static struct resource jz_usb_ohci_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap
+ .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_UHC,
+ .end = IRQ_UHC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct platform_device jz_usb_ohci_device = {
+ .name = "jz-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_usb_ohci_resources),
+ .resource = jz_usb_ohci_resources,
+};
+
+/*** LCD controller ***/
+static struct resource jz_lcd_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(LCD_BASE),
+ .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 jz_lcd_dmamask = ~(u32)0;
+
+static struct platform_device jz_lcd_device = {
+ .name = "jz-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_lcd_resources),
+ .resource = jz_lcd_resources,
+};
+
+/* USB OTG Controller */
+static struct platform_device jz_usb_otg_xceiv_device = {
+ .name = "nop_usb_xceiv",
+ .id = 0,
+};
+
+static struct musb_hdrc_config jz_usb_otg_config = {
+ .multipoint = 1,
+ .dyn_fifo = 0,
+ .soft_con = 1,
+ .dma = 1,
+/* Max EPs scanned. Driver will decide which EP can be used automatically. */
+ .num_eps = 16,
+};
+
+static struct musb_hdrc_platform_data jz_usb_otg_platform_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ .config = &jz_usb_otg_config,
+};
+
+static struct resource jz_usb_otg_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(UDC_BASE),
+ .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_OTG,
+ .end = IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 usb_otg_dmamask = ~(u32)0;
+
+static struct platform_device jz_usb_otg_device = {
+ .name = "musb_hdrc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &usb_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &jz_usb_otg_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(jz_usb_otg_resources),
+ .resource = jz_usb_otg_resources,
+};
+
+/** MMC/SD controller MSC0**/
+static struct resource jz_msc0_resources[] = {
+ {
+ .start = CPHYSADDR(MSC0_BASE),
+ .end = CPHYSADDR(MSC0_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC0,
+ .end = IRQ_MSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC0_RX,
+ .end = DMA_ID_MSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 jz_msc0_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc0_device = {
+ .name = "jz-msc0",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_msc0_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc0_resources),
+ .resource = jz_msc0_resources,
+};
+
+/** MMC/SD controller MSC1**/
+static struct resource jz_msc1_resources[] = {
+ {
+ .start = CPHYSADDR(MSC1_BASE),
+ .end = CPHYSADDR(MSC1_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC1,
+ .end = IRQ_MSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC1_RX,
+ .end = DMA_ID_MSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+
+};
+
+static u64 jz_msc1_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc1_device = {
+ .name = "jz-msc1",
+ .id = 1,
+ .dev = {
+ .dma_mask = &jz_msc1_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc1_resources),
+ .resource = jz_msc1_resources,
+};
+
+static struct platform_device *jz_msc_devices[] __initdata = {
+ &jz_msc0_device,
+ &jz_msc1_device,
+};
+
+int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat)
+{
+ struct platform_device *pdev;
+
+ if (controller < 0 || controller > 1)
+ return -EINVAL;
+
+ pdev = jz_msc_devices[controller];
+
+ pdev->dev.platform_data = plat;
+
+ return platform_device_register(pdev);
+}
+
+
+/* + Sound device */
+
+#define SND(num, desc) { .name = desc, .id = num }
+static struct snd_endpoint snd_endpoints_list[] = {
+ SND(0, "HANDSET"),
+ SND(1, "SPEAKER"),
+ SND(2, "HEADSET"),
+};
+#undef SND
+
+static struct jz_snd_endpoints vogue_snd_endpoints = {
+ .endpoints = snd_endpoints_list,
+ .num = ARRAY_SIZE(snd_endpoints_list),
+};
+
+static struct platform_device vogue_snd_device = {
+ .name = "mixer",
+ .id = -1,
+ .dev = {
+ .platform_data = &vogue_snd_device,
+ },
+};
+
+/* - Sound device */
+
+static struct resource jz_i2c0_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(I2C0_BASE),
+ .end = CPHYSADDR(I2C0_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_I2C0,
+ .end = IRQ_I2C0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource jz_i2c1_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(I2C1_BASE),
+ .end = CPHYSADDR(I2C1_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_I2C1,
+ .end = IRQ_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 jz_i2c_dmamask = ~(u32)0;
+
+static struct platform_device jz_i2c0_device = {
+ .name = "jz_i2c0",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_i2c_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_i2c0_resources),
+ .resource = jz_i2c0_resources,
+};
+
+static struct platform_device jz_i2c1_device = {
+ .name = "jz_i2c1",
+ .id = 1,
+ .dev = {
+ .dma_mask = &jz_i2c_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_i2c1_resources),
+ .resource = jz_i2c1_resources,
+};
+
+static struct platform_device rtc_device = {
+ .name = "jz_rtc",
+ .id = 0,
+};
+
+/* All */
+static struct platform_device *jz_platform_devices[] __initdata = {
+ &jz_usb_ohci_device,
+ &jz_usb_otg_xceiv_device,
+ &jz_usb_otg_device,
+ &jz_lcd_device,
+ &vogue_snd_device,
+ &jz_i2c0_device,
+ &jz_i2c1_device,
+ // &jz_msc0_device,
+ // &jz_msc1_device,
+ &rtc_device,
+};
+
+extern void __init board_i2c_init(void);
+static int __init jz_platform_init(void)
+{
+ int ret = 0;
+
+ board_i2c_init();
+
+ ret = platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices));
+#ifdef CONFIG_ANDROID_PMEM
+ platform_pmem_device_setup();
+#endif
+
+ printk("jz_platform_init\n");
+ board_msc_init();
+ return ret;
+}
+
+arch_initcall(jz_platform_init);
diff --git a/arch/mips/jz4760/pm.c b/arch/mips/jz4760/pm.c
new file mode 100644
index 00000000000..030efe9e7e5
--- /dev/null
+++ b/arch/mips/jz4760/pm.c
@@ -0,0 +1,335 @@
+/*
+ * linux/arch/mips/jz4760/pm.c
+ *
+ * JZ4760 Power Management Routines
+ *
+ * Copyright (C) 2006 - 2010 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/pm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/suspend.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+
+#include <asm/cacheops.h>
+#include <asm/jzsoc.h>
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+extern void jz_board_do_sleep(unsigned long *ptr);
+extern void jz_board_do_resume(unsigned long *ptr);
+#if defined(CONFIG_PM_POWERDOWN_P0)
+extern void jz_cpu_sleep(void);
+extern void jz_cpu_resume(void);
+#endif
+#if defined(CONFIG_INPUT_WM831X_ON)
+extern void wm8310_power_off(void);
+#endif
+int jz_pm_do_hibernate(void)
+{
+#if defined(CONFIG_INPUT_WM831X_ON)
+ printk("The power will be off.\n");
+ wm8310_power_off();
+ while(1);
+#else
+
+ printk("Put CPU into hibernate mode.\n");
+
+ /* Mask all interrupts */
+ OUTREG32(INTC_ICMSR(0), 0xffffffff);
+ OUTREG32(INTC_ICMSR(1), 0x7ff);
+
+ /*
+ * RTC Wakeup or 1Hz interrupt can be enabled or disabled
+ * through RTC driver's ioctl (linux/driver/char/rtc_jz.c).
+ */
+
+ /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */
+ rtc_write_reg(RTC_HWFCR, HWFCR_WAIT_TIME(100));
+
+ /* Set reset pin low-level assertion time after wakeup: must > 60ms */
+ rtc_write_reg(RTC_HRCR, HRCR_WAIT_TIME(60));
+
+ /* Scratch pad register to be reserved */
+ rtc_write_reg(RTC_HSPR, HSPR_RTCV);
+
+ /* clear wakeup status register */
+ rtc_write_reg(RTC_HWRSR, 0x0);
+
+ /* Put CPU to hibernate mode */
+ rtc_write_reg(RTC_HCR, HCR_PD);
+
+ while (1) {
+ printk("We should NOT come here, please check the jz4760rtc.h!!!\n");
+ };
+#endif
+
+ /* We can't get here */
+ return 0;
+}
+
+static int jz_pm_do_sleep(void)
+{
+ unsigned long delta;
+ unsigned long nfcsr = REG_NEMC_NFCSR;
+ unsigned long opcr = INREG32(CPM_OPCR);
+ unsigned long icmr0 = INREG32(INTC_ICMR(0));
+ unsigned long icmr1 = INREG32(INTC_ICMR(1));
+ unsigned long sadc = INREG8(SADC_ADENA);
+ unsigned long pmembs0 = REG_EMC_PMEMBS0;
+ unsigned long sleep_gpio_save[7*(GPIO_PORT_NUM-1)];
+ unsigned long cpuflags;
+
+ /* set SLEEP mode */
+ CMSREG32(CPM_LCR, LCR_LPM_SLEEP, LCR_LPM_MASK);
+
+ /* Preserve current time */
+ delta = xtime.tv_sec - rtc_read_reg(RTC_RTCSR);
+
+ /* Save CPU irqs */
+ local_irq_save(cpuflags);
+
+ /* Disable nand flash */
+ REG_NEMC_NFCSR = ~0xff;
+
+ /*pull up enable pin of DQS */
+ REG_EMC_PMEMBS0 |= (0xff << 8);
+
+ /* stop sadc */
+ SETREG8(SADC_ADENA,ADENA_POWER);
+ while ((INREG8(SADC_ADENA) & ADENA_POWER) != ADENA_POWER) {
+ dprintk("INREG8(SADC_ADENA) = 0x%x\n",INREG8(SADC_ADENA));
+ udelay(100);
+ }
+
+ /* stop uhc */
+ SETREG32(CPM_OPCR, OPCR_UHCPHY_DISABLE);
+
+ /* stop otg and gps */
+ CLRREG32(CPM_OPCR, OPCR_OTGPHY_ENABLE | OPCR_GPSEN);
+
+ /*power down gps and ahb1*/
+ SETREG32(CPM_LCR, LCR_PDAHB1 | LCR_PDGPS);
+
+ /* Mask all interrupts except rtc*/
+ OUTREG32(INTC_ICMSR(0), 0xffffffff);
+ OUTREG32(INTC_ICMSR(1), 0x7fe);
+
+#if defined(CONFIG_RTC_DRV_JZ4760)
+ /* unmask rtc interrupts */
+ OUTREG32(INTC_ICMCR(1), 0x1);
+#else
+ /* mask rtc interrupts */
+ OUTREG32(INTC_ICMSR(1), 0x1);
+#endif
+
+ /* Sleep on-board modules */
+ jz_board_do_sleep(sleep_gpio_save);
+
+#if 0
+ /* WAKEUP key */
+ __gpio_as_irq_fall_edge(GPIO_POWER_ON);
+ __gpio_unmask_irq(GPIO_POWER_ON);
+ __intc_unmask_irq(IRQ_GPIO0 - (GPIO_POWER_ON/32)); /* unmask IRQ_GPIOn depends on GPIO_WAKEUP */
+#endif
+
+ /* disable externel clock Oscillator in sleep mode */
+ CLRREG32(CPM_OPCR, OPCR_O1SE);
+
+ /* select 32K crystal as RTC clock in sleep mode */
+ SETREG32(CPM_OPCR, OPCR_ERCS);
+
+#if 0 /*for cpu 336M 1:2:4*/
+ OUTREG32(CPM_PSWC0ST, 0);
+ OUTREG32(CPM_PSWC1ST, 6);
+ OUTREG32(CPM_PSWC2ST, 8);
+ OUTREG32(CPM_PSWC3ST, 0);
+#endif
+
+#if 1 /*for cpu 533M 1:2:4*/
+ OUTREG32(CPM_PSWC0ST, 0);
+ OUTREG32(CPM_PSWC1ST, 8);
+ OUTREG32(CPM_PSWC2ST, 11);
+ OUTREG32(CPM_PSWC3ST, 0);
+#endif
+
+#if defined(CONFIG_PM_POWERDOWN_P0)
+ /* power down the p0 */
+ SETREG32(CPM_OPCR, OPCR_PD);
+
+ /* Clear previous reset status */
+ CLRREG32(CPM_RSR, RSR_PR | RSR_WR | RSR_P0R);
+
+ /* Set resume return address */
+ OUTREG32(CPM_CPSPPR, 0x00005a5a);
+ udelay(1);
+ OUTREG32(CPM_CPSPR, virt_to_phys(jz_cpu_resume));
+
+ /* *** go zzz *** */
+ jz_cpu_sleep();
+#else
+ __asm__(".set\tmips3\n\t"
+ "sync\n\t"
+ "wait\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tmips0");
+#endif
+
+
+ /*if power down p0 ,return from sleep.S*/
+
+ /* Restore to IDLE mode */
+ CMSREG32(CPM_LCR, LCR_LPM_IDLE, LCR_LPM_MASK);
+
+ /* Restore nand flash control register, it must be restored,
+ because it will be clear to 0 in bootrom. */
+ REG_NEMC_NFCSR = nfcsr;
+
+ /*Restore pmembs0*/
+ REG_EMC_PMEMBS0 = pmembs0;
+
+ /* Restore interrupts */
+ OUTREG32(INTC_ICMR(0), icmr0);
+ OUTREG32(INTC_ICMR(1), icmr1);
+
+ /* Restore sadc */
+ OUTREG8(SADC_ADENA, sadc);
+
+ /* Resume on-board modules */
+ jz_board_do_resume(sleep_gpio_save);
+
+ /* Restore Oscillator and Power Control Register */
+ OUTREG32(CPM_OPCR, opcr);
+
+ /* Restore CPU interrupt flags */
+ local_irq_restore(cpuflags);
+
+ /* Restore current time */
+ xtime.tv_sec = rtc_read_reg(RTC_RTCSR) + delta;
+
+ return 0;
+}
+
+#define K0BASE KSEG0
+void jz_flush_cache_all(void)
+{
+ unsigned long addr;
+
+ /* Clear CP0 TagLo */
+ asm volatile ("mtc0 $0, $28\n\t"::);
+
+ for (addr = K0BASE; addr < (K0BASE + 0x4000); addr += 32) {
+ asm volatile (
+ ".set mips3\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips2\n\t"
+ :
+ : "I" (Index_Writeback_Inv_D), "r"(addr));
+
+ asm volatile (
+ ".set mips3\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips2\n\t"
+ :
+ : "I" (Index_Store_Tag_I), "r"(addr));
+ }
+
+ asm volatile ("sync\n\t"::);
+
+ /* invalidate BTB */
+ 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"
+ ".set mips2\n\t"
+ :
+ : "r"(addr));
+}
+
+/* Put CPU to HIBERNATE mode
+ *----------------------------------------------------------------------------
+ * Power Management sleep sysctl interface
+ *
+ * Write "mem" to /sys/power/state invokes this function
+ * which initiates a poweroff.
+ */
+void jz_pm_hibernate(void)
+{
+ jz_pm_do_hibernate();
+}
+
+/* Put CPU to SLEEP mode
+ *----------------------------------------------------------------------------
+ * Power Management sleep sysctl interface
+ *
+ * Write "disk" to /sys/power/state invokes this function
+ * which initiates a sleep.
+ */
+
+int jz_pm_sleep(void)
+{
+ return jz_pm_do_sleep();
+}
+
+/*
+ * valid states, only support mem(sleep) and disk(hibernate)
+ */
+static int jz4760_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM;
+}
+
+/*
+ * Jz CPU enter save power mode
+ */
+static int jz4760_pm_enter(suspend_state_t state)
+{
+ jz_pm_do_sleep();
+ return 0;
+}
+
+static struct platform_suspend_ops jz4760_pm_ops = {
+ .valid = jz4760_pm_valid,
+ .enter = jz4760_pm_enter,
+};
+
+/*
+ * Initialize power interface
+ */
+int __init jz_pm_init(void)
+{
+ printk("Power Management for JZ\n");
+
+ suspend_set_ops(&jz4760_pm_ops);
+ return 0;
+}
+
diff --git a/arch/mips/jz4760/proc.c b/arch/mips/jz4760/proc.c
new file mode 100644
index 00000000000..8578410b3b9
--- /dev/null
+++ b/arch/mips/jz4760/proc.c
@@ -0,0 +1,955 @@
+/*
+ * linux/arch/mips/jz4760/proc.c
+ *
+ * /proc/jz/ procfs for jz4760 on-chip modules.
+ *
+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/page-flags.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/jzsoc.h>
+
+//#define DEBUG 1
+#undef DEBUG
+
+extern void jz4760_fpu_init(unsigned int round);
+
+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-4): 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-4): 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, "REG_EMC_BCR: 0x%08x\n", REG_EMC_BCR);
+ len += sprintf (page+len, "REG_EMC_PMEMBS0: 0x%08x\n", REG_EMC_PMEMBS0);
+ len += sprintf (page+len, "REG_EMC_PMEMBS1: 0x%08x\n", REG_EMC_PMEMBS1);
+ len += sprintf (page+len, "REG_EMC_NFCSR: 0x%08x\n", REG_EMC_NFCSR);
+ len += sprintf (page+len, "REG_EMC_DMAR0: 0x%08x\n", REG_EMC_DMAR0);
+ len += sprintf (page+len, "REG_EMC_DMAR1: 0x%08x\n", REG_EMC_DMAR1);
+ len += sprintf (page+len, "REG_EMC_DMCR: 0x%08x\n", REG_EMC_DMCR);
+ len += sprintf (page+len, "REG_EMC_RTCNT: 0x%04x\n", REG_EMC_RTCNT);
+ len += sprintf (page+len, "REG_EMC_RTCSR: 0x%04x\n", REG_EMC_RTCSR);
+ len += sprintf (page+len, "REG_EMC_RTCOR: 0x%04x\n", REG_EMC_RTCOR);
+
+ return len;
+}
+
+/*
+ * DDRC Modules
+ */
+static int ddrc_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len += sprintf (page+len, "REG_DDRC_ST 0x%08x\n", REG_DDRC_ST);
+ len += sprintf (page+len, "REG_DDRC_CFG 0x%08x\n", REG_DDRC_CFG);
+ len += sprintf (page+len, "REG_DDRC_CTRL 0x%08x\n", REG_DDRC_CTRL);
+ len += sprintf (page+len, "REG_DDRC_LMR 0x%08x\n", REG_DDRC_LMR);
+ len += sprintf (page+len, "REG_DDRC_TIMING1 0x%08x\n", REG_DDRC_TIMING1);
+ len += sprintf (page+len, "REG_DDRC_TIMING2 0x%08x\n", REG_DDRC_TIMING2);
+ len += sprintf (page+len, "REG_DDRC_REFCNT 0x%08x\n", REG_DDRC_REFCNT);
+ len += sprintf (page+len, "REG_DDRC_DQS 0x%08x\n", REG_DDRC_DQS);
+ len += sprintf (page+len, "REG_DDRC_DQS_ADJ 0x%08x\n", REG_DDRC_DQS_ADJ);
+ len += sprintf (page+len, "REG_DDRC_MMAP0 0x%08x\n", REG_DDRC_MMAP0);
+ len += sprintf (page+len, "REG_DDRC_MMAP1 0x%08x\n", REG_DDRC_MMAP1);
+
+ 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 & LCR_LPM_MASK) == (LCR_LPM_IDLE)) ?
+ "IDLE" : (((lcr & LCR_LPM_MASK) == (LCR_LPM_SLEEP)) ?
+ "SLEEP" : "HIBERNATE"));
+ len += sprintf (page+len, "Doze Mode : %s\n",
+ (lcr & LCR_DOZE) ? "on" : "off");
+ if (lcr & LCR_DOZE)
+ len += sprintf (page+len, " duty : %d\n", (int)((lcr & LCR_DUTY_MASK) >> LCR_DUTY_LSB));
+
+/*
+ len += sprintf (page+len, "AUX_CPU : %s\n",
+ (clkgr & CPM_CLKGR_AUX_CPU) ? "stopped" : "running");
+ len += sprintf (page+len, "AHB1 : %s\n",
+ (clkgr & CPM_CLKGR_AHB1) ? "stopped" : "running");
+ len += sprintf (page+len, "IDCT : %s\n",
+ (clkgr & CPM_CLKGR_IDCT) ? "stopped" : "running");
+ len += sprintf (page+len, "DB : %s\n",
+ (clkgr & CPM_CLKGR_DB) ? "stopped" : "running");
+ len += sprintf (page+len, "ME : %s\n",
+ (clkgr & CPM_CLKGR_ME) ? "stopped" : "running");
+ len += sprintf (page+len, "MC : %s\n",
+ (clkgr & CPM_CLKGR_MC) ? "stopped" : "running");
+ len += sprintf (page+len, "TVE : %s\n",
+ (clkgr & CPM_CLKGR_TVE) ? "stopped" : "running");
+ len += sprintf (page+len, "TSSI : %s\n",
+ (clkgr & CPM_CLKGR_TSSI) ? "stopped" : "running");
+ 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, "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, "MSC0 : %s\n",
+ (clkgr & CPM_CLKGR_MSC0) ? "stopped" : "running");
+ len += sprintf (page+len, "MSC1 : %s\n",
+ (clkgr & CPM_CLKGR_MSC1) ? "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_CPPCR0; /* 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 & CPPCR0_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_clock(CGU_CCLK)));
+ len += sprintf (page+len, "HCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_HCLK)));
+ len += sprintf (page+len, "MCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_MCLK)));
+ len += sprintf (page+len, "PCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_PCLK)));
+ len += sprintf (page+len, "H2CLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_H2CLK)));
+ len += sprintf (page+len, "PIXCLK : %3d.%02d KHz\n", TO_KHZ(cpm_get_clock(CGU_TVECLK)));
+ len += sprintf (page+len, "I2SCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_I2SCLK)));
+ len += sprintf (page+len, "USBCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_OTGCLK)));
+ len += sprintf (page+len, "MSC0CLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_MSCCLK)));
+ len += sprintf (page+len, "MSC1CLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_MSCCLK)));
+ // len += sprintf (page+len, "EXTALCLK0 : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_EXTCLK)));
+ // len += sprintf (page+len, "EXTALCLK(by CPM): %3d.%02d MHz\n", TO_MHZ(get_external_clock()));
+ // len += sprintf (page+len, "RTCCLK : %3d.%02d MHz\n", TO_MHZ(cpm_get_clock(CGU_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;
+}
+
+
+/* USAGE:
+ * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages.
+ * echo FF > /proc/jz/ipu // 255, free all buffer
+ * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx
+ * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l)
+ * echo 0 > /proc/jz/ipu // debug, print ipu_buf
+ * od -X /proc/jz/ipu // read mem addr
+ */
+
+typedef struct _ipu_buf {
+ unsigned int addr; /* phys addr */
+ unsigned int page_shift;
+} ipu_buf_t;
+
+#define IPU_BUF_MAX 4 /* 4 buffers */
+
+static struct _ipu_buf ipu_buf[IPU_BUF_MAX];
+static int ipu_buf_cnt = 0;
+static unsigned char g_asid=0;
+
+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);
+}
+
+static void ipu_add_wired_entry(unsigned long pid,
+ unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask)
+{
+ unsigned long flags;
+ unsigned long wired;
+ unsigned long old_pagemask;
+ unsigned long old_ctx;
+ struct task_struct *g, *p;
+
+ /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */
+ wired = read_c0_wired();
+ if (wired) return;
+
+ do_each_thread(g, p) {
+ if (p->pid == pid )
+ g_asid = p->mm->context[0];
+ } while_each_thread(g, p);
+
+
+ local_irq_save(flags);
+
+ entrylo0 = entrylo0 >> 6; /* PFN */
+ entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */
+
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi() & 0xff;
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
+ write_c0_wired(wired + 1);
+ write_c0_index(wired);
+ BARRIER;
+ entryhi &= ~0xff; /* new add, 20070906 */
+ entryhi |= g_asid; /* new add, 20070906 */
+// entryhi |= old_ctx; /* new add, 20070906 */
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
+ BARRIER;
+ tlb_write_indexed();
+ BARRIER;
+
+ write_c0_entryhi(old_ctx);
+ BARRIER;
+ write_c0_pagemask(old_pagemask);
+ local_flush_tlb_all();
+ local_irq_restore(flags);
+#if defined(DEBUG)
+ printk("\nold_ctx=%03d\n", old_ctx);
+
+ show_tlb();
+#endif
+}
+
+static void ipu_del_wired_entry( void )
+{
+ unsigned long flags;
+ unsigned long wired;
+
+ local_irq_save(flags);
+ wired = read_c0_wired();
+ if ( wired > 0 ) {
+ write_c0_wired(wired - 1);
+ }
+ local_irq_restore(flags);
+}
+
+static inline void ipu_buf_get( unsigned int page_shift )
+{
+ unsigned char * virt_addr;
+ int i;
+ for ( i=0; i< IPU_BUF_MAX; ++i ) {
+ if ( ipu_buf[i].addr == 0 ) {
+ break;
+ }
+ }
+
+ if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) {
+ printk("Error, no free ipu buffer.\n");
+ return ;
+ }
+
+ virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);
+
+ if ( virt_addr ) {
+ ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr);
+ ipu_buf[ipu_buf_cnt].page_shift = page_shift;
+
+ for (i = 0; i < (1<<page_shift); i++) {
+ SetPageReserved(virt_to_page(virt_addr));
+ virt_addr += PAGE_SIZE;
+ }
+ }
+ else {
+ printk("get memory Failed.\n");
+ }
+}
+
+static inline void ipu_buf_free( unsigned int phys_addr )
+{
+ unsigned char * virt_addr, *addr;
+ int cnt, i;
+
+ if ( phys_addr == 0 )
+ return ;
+
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt )
+ if ( phys_addr == ipu_buf[cnt].addr )
+ break;
+
+ if ( cnt == IPU_BUF_MAX ) { /* addr not in the ipu buffers */
+ printk("Invalid addr:0x%08x\n", (unsigned int)phys_addr);
+ }
+
+ virt_addr = (unsigned char *)phys_to_virt(ipu_buf[cnt].addr);
+ addr = virt_addr;
+ for (i = 0; i < (1<<ipu_buf[cnt].page_shift); i++) {
+ ClearPageReserved(virt_to_page(addr));
+ addr += PAGE_SIZE;
+ }
+
+ if ( cnt == 0 )
+ ipu_del_wired_entry();
+
+ free_pages((unsigned long )virt_addr, ipu_buf[cnt].page_shift);
+
+ ipu_buf[cnt].addr = 0;
+ ipu_buf[cnt].page_shift = 0;
+}
+
+static int ipu_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ /* read as binary */
+ unsigned int * pint;
+ pint = (unsigned int *) (page+len);
+
+ if ( ipu_buf_cnt >= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */
+ printk("no free buffer.\n");
+ *pint = 0;
+ }
+ else
+ *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */
+ len += sizeof(unsigned int);
+
+#if defined(DEBUG)
+ show_tlb();
+#endif
+ return len;
+
+}
+
+static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ unsigned int val ;
+ int cnt,i;
+ char buf[12];
+ unsigned long pid, entrylo0, entrylo1, entryhi, pagemask;
+#if defined(DEBUG)
+ printk("ipu write count=%u\n", count);
+#endif
+ if (count == (8*5+1)) {
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*0, 8);
+ pid = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*1, 8);
+ entrylo0 = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*2, 8);
+ entrylo1 = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*3, 8);
+ entryhi = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*4, 8);
+ pagemask = simple_strtoul(buf, 0, 16);
+
+#if defined(DEBUG)
+ printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n",
+ pid, entrylo0, entrylo1, entryhi, pagemask);
+#endif
+ ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask);
+ return 41;
+ }
+ else if ( count <= 8+1 ) {
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer, 8);
+ val = simple_strtoul(buf, 0, 16);
+ } else if (count == 44) {
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer, 10);
+ pid = simple_strtoul(buf, 0, 16);
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 11, 10);
+ entryhi = simple_strtoul(buf, 0, 16);//vaddr
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 22, 10);
+ entrylo0 = simple_strtoul(buf, 0, 16);//paddr
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 33, 10);
+ pagemask = simple_strtoul(buf, 0, 16);
+ pagemask = 0x3ff << 13; /* Fixed to 4MB page size */
+ ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask);
+ return 44;
+ } else {
+ printk("ipu write count error, count=%d\n.", (unsigned int)count);
+ return -1;
+ }
+
+ /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */
+ if ( val == 0 ) { /* debug, print ipu_buf info */
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt)
+ printk("ipu_buf[%d]: addr=0x%08x, page_shift=%d\n",
+ cnt, ipu_buf[cnt].addr, ipu_buf[cnt].page_shift );
+#if defined(DEBUG)
+ show_tlb();
+#endif
+ }
+ else if ( 0< val && val < 10 ) {
+ ipu_buf_get(val);
+ }
+ else if ( val == 0xff ) { /* 255: free all ipu_buf */
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt ) {
+ ipu_buf_free(ipu_buf[cnt].addr);
+ }
+ }
+ else {
+ ipu_buf_free(val);
+ }
+
+ return count;
+}
+
+/*
+ * UDC hotplug
+ */
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+extern int jz_udc_active; /* defined in drivers/char/jzchar/jz_udc_hotplug.c */
+#endif
+
+#ifndef GPIO_UDC_HOTPLUG
+#define GPIO_UDC_HOTPLUG 86
+#endif
+
+static int udc_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (__gpio_get_pin(GPIO_UDC_HOTPLUG)) {
+
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+
+ /* Cable has connected, wait for disconnection. */
+ __gpio_as_irq_fall_edge(GPIO_UDC_HOTPLUG);
+
+ if (jz_udc_active)
+ len += sprintf (page+len, "CONNECT_CABLE\n");
+ else
+ len += sprintf (page+len, "CONNECT_POWER\n");
+#else
+ len += sprintf (page+len, "CONNECT\n");
+#endif
+ }
+ else {
+
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+ /* Cable has disconnected, wait for connection. */
+ __gpio_as_irq_rise_edge(GPIO_UDC_HOTPLUG);
+#endif
+
+ len += sprintf (page+len, "REMOVE\n");
+ }
+
+ return len;
+}
+
+/*
+ * MMC/SD hotplug
+ */
+
+#ifndef MSC_HOTPLUG_PIN
+#define MSC_HOTPLUG_PIN 90
+#endif
+
+static int mmc_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (__gpio_get_pin(MSC_HOTPLUG_PIN))
+ len += sprintf (page+len, "REMOVE\n");
+ else
+ len += sprintf (page+len, "INSERT\n");
+
+ return len;
+}
+
+#ifndef CONFIG_ANDROID_PMEM /* /dev/pmem instead /proc/jz/imem on android platform */
+
+/***********************************************************************
+ * IPU memory management (used by mplayer and other apps)
+ *
+ * We reserved 4MB memory for IPU
+ * The memory base address is jz_ipu_framebuf
+ */
+
+/* Usage:
+ *
+ * echo n > /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages
+ * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx
+ * echo FF > /proc/jz/ipu // FF, free all buffers
+ * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer
+ */
+
+//#define DEBUG_IMEM 1
+
+#define IMEM_MAX_ORDER 10 /* max 2^10 * 4096 = 4MB */
+
+static unsigned int jz_imem_base; /* physical base address of ipu memory */
+
+static unsigned int allocated_phys_addr = 0;
+
+/*
+ * Allocated buffer list
+ */
+typedef struct imem_list {
+ unsigned int phys_start; /* physical start addr */
+ unsigned int phys_end; /* physical end addr */
+ struct imem_list *next;
+} imem_list_t;
+
+static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */
+
+#ifdef DEBUG_IMEM
+static void dump_imem_list(void)
+{
+ struct imem_list *imem;
+
+ printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head);
+ imem = imem_list_head;
+ while (imem) {
+ printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next);
+ imem = imem->next;
+ }
+}
+#endif
+
+/* allocate 2^order pages inside the 4MB memory */
+static int imem_alloc(unsigned int order)
+{
+ int alloc_ok = 0;
+ unsigned int start, end;
+ unsigned int size = (1 << order) * PAGE_SIZE;
+ struct imem_list *imem, *imemn, *imemp;
+
+ allocated_phys_addr = 0;
+
+ start = jz_imem_base;
+ end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
+
+ imem = imem_list_head;
+ while (imem) {
+ if ((imem->phys_start - start) >= size) {
+ /* we got a valid address range */
+ alloc_ok = 1;
+ break;
+ }
+
+ start = imem->phys_end + 1;
+ imem = imem->next;
+ }
+
+ if (!alloc_ok) {
+ if ((end - start) >= size)
+ alloc_ok = 1;
+ }
+
+ if (alloc_ok) {
+ end = start + size - 1;
+ allocated_phys_addr = start;
+
+ /* add to imem_list, up sorted by phys_start */
+ imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL);
+ if (!imemn) {
+ return -ENOMEM;
+ }
+ imemn->phys_start = start;
+ imemn->phys_end = end;
+ imemn->next = NULL;
+
+ if (!imem_list_head)
+ imem_list_head = imemn;
+ else {
+ imem = imemp = imem_list_head;
+ while (imem) {
+ if (start < imem->phys_start) {
+ break;
+ }
+
+ imemp = imem;
+ imem = imem->next;
+ }
+
+ if (imem == imem_list_head) {
+ imem_list_head = imemn;
+ imemn->next = imem;
+ }
+ else {
+ imemn->next = imemp->next;
+ imemp->next = imemn;
+ }
+ }
+ }
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+ return 0;
+}
+
+static void imem_free(unsigned int phys_addr)
+{
+ struct imem_list *imem, *imemp;
+
+ imem = imemp = imem_list_head;
+ while (imem) {
+ if (phys_addr == imem->phys_start) {
+ if (imem == imem_list_head) {
+ imem_list_head = imem->next;
+ }
+ else {
+ imemp->next = imem->next;
+ }
+
+ kfree(imem);
+ break;
+ }
+
+ imemp = imem;
+ imem = imem->next;
+ }
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+}
+
+static void imem_free_all(void)
+{
+ struct imem_list *imem;
+
+ imem = imem_list_head;
+ while (imem) {
+ kfree(imem);
+ imem = imem->next;
+ }
+
+ imem_list_head = NULL;
+
+ allocated_phys_addr = 0;
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+}
+
+/*
+ * Return the allocated buffer address and the max order of free buffer
+ */
+static int imem_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned int start_addr, end_addr, max_order, max_size;
+ struct imem_list *imem;
+
+ unsigned int *tmp = (unsigned int *)(page + len);
+
+ start_addr = jz_imem_base;
+ end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
+
+ if (!imem_list_head)
+ max_size = end_addr - start_addr;
+ else {
+ max_size = 0;
+ imem = imem_list_head;
+ while (imem) {
+ if (max_size < (imem->phys_start - start_addr))
+ max_size = imem->phys_start - start_addr;
+
+ start_addr = imem->phys_end + 1;
+ imem = imem->next;
+ }
+
+ if (max_size < (end_addr - start_addr))
+ max_size = end_addr - start_addr;
+ }
+
+ if (max_size > 0) {
+ max_order = get_order(max_size);
+ if (((1 << max_order) * PAGE_SIZE) > max_size)
+ max_order--;
+ }
+ else {
+ max_order = 0xffffffff; /* No any free buffer */
+ }
+
+ *tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */
+ *tmp = max_order; /* max order of current free buffers */
+
+ len += 2 * sizeof(unsigned int);
+
+ return len;
+}
+
+static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ unsigned int val;
+
+ val = simple_strtoul(buffer, 0, 16);
+
+ if (val == 0xff) {
+ /* free all memory */
+ imem_free_all();
+ }
+ else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) {
+ /* allocate 2^val pages */
+ imem_alloc(val);
+ }
+ else {
+ /* free buffer which phys_addr is val */
+ imem_free(val);
+ }
+
+ return count;
+}
+#endif /* #ifndef CONFIG_ANDROID_PMEM */
+
+static int fpu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ printk("user set rounding mode to %x \n",(unsigned int)buffer);
+
+ if ((unsigned int)buffer > 4) {
+ printk("roundind mode error!\n");
+ }
+
+ jz4760_fpu_init((unsigned int)buffer);
+ return count;
+}
+
+/*
+ * /proc/jz/xxx entry
+ *
+ */
+static int __init jz_proc_init(void)
+{
+ struct proc_dir_entry *res;
+#ifndef CONFIG_ANDROID_PMEM
+ unsigned int virt_addr, i;
+#endif
+
+ 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;
+ }
+
+ /* Image process unit */
+ res = create_proc_entry("ipu", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = ipu_read_proc;
+ res->write_proc = ipu_write_proc;
+ res->data = NULL;
+ }
+
+ /* udc hotplug */
+ res = create_proc_entry("udc", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = udc_read_proc;
+ res->write_proc = NULL;
+ res->data = NULL;
+ }
+
+ /* mmc hotplug */
+ res = create_proc_entry("mmc", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = mmc_read_proc;
+ res->write_proc = NULL;
+ res->data = NULL;
+ }
+
+ /* DDR Controller */
+ res = create_proc_entry("ddrc", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = ddrc_read_proc;
+ res->write_proc = NULL;
+ res->data = NULL;
+ }
+
+#ifndef CONFIG_ANDROID_PMEM
+ /*
+ * Reserve a 4MB memory for IPU on JZ4760.
+ */
+ jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER);
+ if (jz_imem_base) {
+ /* imem (IPU memory management) */
+ res = create_proc_entry("imem", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = imem_read_proc;
+ res->write_proc = imem_write_proc;
+ res->data = NULL;
+ }
+
+ /* Set page reserved */
+ virt_addr = jz_imem_base;
+ for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) {
+ SetPageReserved(virt_to_page((void *)virt_addr));
+ virt_addr += PAGE_SIZE;
+ }
+
+ /* Convert to physical address */
+ jz_imem_base = virt_to_phys((void *)jz_imem_base);
+
+ printk("Total %dMB memory at 0x%x was reserved for IPU\n",
+ (unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base);
+ }
+#endif /* #ifdef CONFIG_ANDROID_PMEM */
+
+ /* fpu */
+ res = create_proc_entry("fpu", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = NULL;
+ res->write_proc = fpu_write_proc;
+ res->data = NULL;
+ }
+
+ return 0;
+}
+
+__initcall(jz_proc_init);
diff --git a/arch/mips/jz4760/prom.c b/arch/mips/jz4760/prom.c
new file mode 100644
index 00000000000..f30a77b8c77
--- /dev/null
+++ b/arch/mips/jz4760/prom.c
@@ -0,0 +1,198 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, supports YAMON and U-Boot.
+ *
+ * Copyright 2000, 2001, 2006 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/jzsoc.h>
+
+/* #define DEBUG_CMDLINE */
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+char * prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ if (prom_argc > 1)
+ *cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+#if 0
+ /*
+ * Return a pointer to the given environment variable.
+ * YAMON uses "name", "value" pairs, while U-Boot uses "name=value".
+ */
+
+ char **env = prom_envp;
+ int i = strlen(envname);
+ int yamon = (*env && strchr(*env, '=') == NULL);
+
+ while (*env) {
+ if (yamon) {
+ if (strcmp(envname, *env++) == 0)
+ return *env;
+ } else {
+ if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+ return *env + i + 1;
+ }
+ env++;
+ }
+#endif
+ return NULL;
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for(i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+
+#if 0
+ {
+ int i;
+
+ printk("get_ethernet_addr: ");
+ for (i=0; i<5; i++)
+ printk("%02x:", (unsigned char)*(ethernet_addr+i));
+ printk("%02x\n", *(ethernet_addr+i));
+ }
+#endif
+
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = (int) fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ mips_machtype = MACH_INGENIC_JZ4760;
+
+ prom_init_cmdline();
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ memsize = 0x04000000;
+ } else {
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+/* used by early printk */
+void prom_putchar(char c)
+{
+ volatile u8 *uart_lsr = (volatile u8 *)(UART1_BASE + OFF_LSR);
+ volatile u8 *uart_tdr = (volatile u8 *)(UART1_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 "JZ4760";
+}
+
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/jz4760/reset.c b/arch/mips/jz4760/reset.c
new file mode 100644
index 00000000000..034e2563b61
--- /dev/null
+++ b/arch/mips/jz4760/reset.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/mips/jz4760/reset.c
+ *
+ * JZ4760 reset routines.
+ *
+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc.
+ * Author: <yliu@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/jzsoc.h>
+
+void jz_restart(char *command)
+{
+ printk("Restarting after 4 ms\n");
+ REG_WDT_WCSR = WCSR_PRESCALE4 | WCSR_CLKIN_EXT;
+ REG_WDT_WCNT = 0;
+ REG_WDT_WDR = JZ_EXTAL/1000; /* reset after 4ms */
+ REG_TCU_TSCR = TSCR_WDT; /* enable wdt clock */
+ REG_WDT_WCER = WCER_TCEN; /* wdt start */
+ while (1);
+}
+
+void jz_halt(void)
+{
+ printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+
+ while (1)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+}
+
+void jz_power_off(void)
+{
+ jz_halt();
+}
diff --git a/arch/mips/jz4760/setup.c b/arch/mips/jz4760/setup.c
new file mode 100644
index 00000000000..1806fc30e08
--- /dev/null
+++ b/arch/mips/jz4760/setup.c
@@ -0,0 +1,221 @@
+/*
+ * linux/arch/mips/jz4760/common/setup.c
+ *
+ * JZ4760 common setup routines.
+ *
+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+#include <asm/jzsoc.h>
+
+#ifdef CONFIG_PM
+#include <asm/suspend.h>
+#endif
+
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
+
+jz_clocks_t jz_clocks;
+
+extern char * __init prom_getcmdline(void);
+extern void __init jz_board_setup(void);
+extern void jz_restart(char *);
+extern void jz_halt(void);
+extern void jz_power_off(void);
+extern void jz_time_init(void);
+extern void jz_pm_hibernate(void);
+
+static void __init sysclocks_setup(void)
+{
+#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */
+
+ jz_clocks.cclk = cpm_get_clock(CGU_CCLK);
+ jz_clocks.hclk = cpm_get_clock(CGU_HCLK);
+ jz_clocks.pclk = cpm_get_clock(CGU_PCLK);
+ jz_clocks.mclk = cpm_get_clock(CGU_MCLK);
+ jz_clocks.h1clk = cpm_get_clock(CGU_H2CLK);
+ jz_clocks.pixclk = cpm_get_clock(CGU_LPCLK);
+ jz_clocks.i2sclk = cpm_get_clock(CGU_I2SCLK);
+ jz_clocks.otgclk = cpm_get_clock(CGU_OTGCLK);
+ jz_clocks.mscclk = cpm_get_clock(CGU_MSCCLK);
+ jz_clocks.extalclk = __cpm_get_extalclk();
+ jz_clocks.rtcclk = __cpm_get_rtcclk();
+
+#else
+
+#define FPGACLK 8000000
+
+ jz_clocks.cclk = FPGACLK;
+ jz_clocks.hclk = FPGACLK;
+ jz_clocks.pclk = FPGACLK;
+ jz_clocks.mclk = FPGACLK;
+ jz_clocks.h1clk = FPGACLK;
+ jz_clocks.pixclk = FPGACLK;
+ jz_clocks.i2sclk = FPGACLK;
+ jz_clocks.usbclk = FPGACLK;
+ jz_clocks.mscclk = FPGACLK;
+ jz_clocks.extalclk = FPGACLK;
+ jz_clocks.rtcclk = FPGACLK;
+#endif
+
+ printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n",
+ (jz_clocks.cclk + 500000) / 1000000,
+ (jz_clocks.hclk + 500000) / 1000000,
+ (jz_clocks.pclk + 500000) / 1000000,
+ (jz_clocks.mclk + 500000) / 1000000);
+}
+
+static void __init soc_cpm_setup(void)
+{
+ /* Start all module clocks
+ * cpm_start_clock(CGM_ALL_MODULE);
+ */
+
+ /* Enable device DMA */
+ cpm_start_clock(CGM_DMAC);
+
+ /* CPU enters IDLE mode when executing 'wait' instruction */
+ CMSREG32(CPM_LCR, LCR_LPM_IDLE, LCR_LPM_MASK);
+
+ /* Setup system clocks */
+ sysclocks_setup();
+}
+
+static void __init soc_harb_setup(void)
+{
+// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */
+// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */
+// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */
+}
+
+static void __init soc_emc_setup(void)
+{
+ cpm_start_clock(CGM_EMC);
+
+ OUTREG32(EMC_PMEMBS1, 0xff000000);
+ OUTREG32(EMC_PMEMBS0, 0xff000000);
+}
+
+static void __init soc_dmac_setup(void)
+{
+ __dmac_enable_module(0);
+ __dmac_enable_module(1);
+}
+
+static void __init jz_soc_setup(void)
+{
+ soc_cpm_setup();
+ soc_harb_setup();
+ soc_emc_setup();
+ soc_dmac_setup();
+}
+
+static void __init jz_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port s;
+ REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */
+ memset(&s, 0, sizeof(s));
+ s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ s.iotype = SERIAL_IO_MEM;
+ s.regshift = 2;
+ s.uartclk = jz_clocks.extalclk ;
+
+ s.line = 0;
+ s.membase = (u8 *)UART0_BASE;
+ s.irq = 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 = IRQ_UART1;
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS1 setup failed!\n");
+ }
+
+ s.line = 2;
+ s.membase = (u8 *)UART2_BASE;
+ s.irq = IRQ_UART2;
+
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS2 setup failed!\n");
+ }
+
+ s.line = 3;
+ s.membase = (u8 *)UART3_BASE;
+ s.irq = IRQ_UART3;
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS3 setup failed!\n");
+ }
+
+#endif
+}
+
+void __init plat_mem_setup(void)
+{
+ char *argptr;
+
+ argptr = prom_getcmdline();
+
+ __asm__ (
+ "li $2, 0xa9000000 \n\t"
+ "mtc0 $2, $5, 4 \n\t"
+ "nop \n\t"
+ ::"r"(2));
+
+ /* 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_pm_hibernate;
+
+ jz_soc_setup();
+ jz_serial_setup();
+ jz_board_setup();
+
+#ifdef CONFIG_PM
+ jz_pm_init();
+#endif
+
+}
+
diff --git a/arch/mips/jz4760/sleep.S b/arch/mips/jz4760/sleep.S
new file mode 100644
index 00000000000..9ae1c04b363
--- /dev/null
+++ b/arch/mips/jz4760/sleep.S
@@ -0,0 +1,330 @@
+/*
+ * linux/arch/mips/jz4760/sleep.S
+ *
+ * jz4760 Assembler Sleep/WakeUp Management Routines
+ *
+ * Copyright (C) 2005 - 2010 Ingenic Semiconductor
+ *
+ * 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.
+ */
+
+#define __MIPS_ASSEMBLER
+
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <asm/mach-jz4760/jz4760misc.h>
+#include <asm/mach-jz4760/jz4760cpm.h>
+#include <asm/mach-jz4760/jz4760emc.h>
+#include <asm/mach-jz4760/jz4760gpio.h>
+
+#define K0BASE 0x80000000
+#define CFG_DCACHE_SIZE 16384
+#define CFG_ICACHE_SIZE 16384
+#define CFG_CACHELINE_SIZE 32
+/**********************************************************/
+ .data
+ .align 4
+
+reg_save:
+ .space 70*4
+/*********************************************************/
+ .text
+ .set noreorder
+ .set noat
+ .extern jz_flush_cache_all
+
+/*
+ * jz_cpu_sleep()
+ *
+ * Forces CPU into sleep mode,and we will power down p0 in this mode!
+ */
+
+ .globl jz_cpu_sleep
+jz_cpu_sleep:
+
+ /* save hi, lo and general registers except k0($26) and k1($27) (total 32) */
+ la k0, reg_save
+ mfhi k1
+ sw $0, 0(k0)
+ sw $1, 4(k0)
+ sw k1, 120(k0)
+ mflo k1
+ sw $2, 8(k0)
+ sw $3, 12(k0)
+ sw k1, 124(k0)
+ sw $4, 16(k0)
+ sw $5, 20(k0)
+ sw $6, 24(k0)
+ sw $7, 28(k0)
+ sw $8, 32(k0)
+ sw $9, 36(k0)
+ sw $10, 40(k0)
+ sw $11, 44(k0)
+ sw $12, 48(k0)
+ sw $13, 52(k0)
+ sw $14, 56(k0)
+ sw $15, 60(k0)
+ sw $16, 64(k0)
+ sw $17, 68(k0)
+ sw $18, 72(k0)
+ sw $19, 76(k0)
+ sw $20, 80(k0)
+ sw $21, 84(k0)
+ sw $22, 88(k0)
+ sw $23, 92(k0)
+ sw $24, 96(k0)
+ sw $25, 100(k0)
+ sw $28, 104(k0)
+ sw $29, 108(k0) /* saved sp */
+ sw $30, 112(k0)
+ sw $31, 116(k0) /* saved ra */
+
+ /* save CP0 registers total 31*/
+ mfc0 $1, $0
+ mfc0 $2, $1
+ mfc0 $3, $2
+ mfc0 $4, $3
+ mfc0 $5, $4
+ mfc0 $6, $5
+ mfc0 $7, $6
+ mfc0 $8, $8
+ mfc0 $9, $10
+ mfc0 $10,$12
+ mfc0 $11, $12,1
+ mfc0 $12, $13
+ mfc0 $13, $14
+ mfc0 $14, $15
+ mfc0 $15, $15,1
+ mfc0 $16, $16
+ mfc0 $17, $16,1
+ mfc0 $18, $16,2
+ mfc0 $19, $16,3
+ mfc0 $20, $16, 7
+ mfc0 $21, $17
+
+ sw $1, 128(k0)
+ sw $2, 132(k0)
+ sw $3, 136(k0)
+ sw $4, 140(k0)
+ sw $5, 144(k0)
+ sw $6, 148(k0)
+ sw $7, 152(k0)
+ sw $8, 156(k0)
+ sw $9, 160(k0)
+ sw $10, 164(k0)
+ sw $11, 168(k0)
+ sw $12, 172(k0)
+ sw $13, 176(k0)
+ sw $14, 180(k0)
+ sw $15, 184(k0)
+ sw $16, 188(k0)
+ sw $17, 192(k0)
+ sw $18, 196(k0)
+ sw $19, 200(k0)
+ sw $20, 204(k0)
+ sw $21, 208(k0)
+
+ mfc0 $1, $18
+ mfc0 $2, $19
+ mfc0 $3, $23
+ mfc0 $4, $24
+ mfc0 $5, $26
+ mfc0 $6, $28
+ mfc0 $7, $28,1
+ mfc0 $8, $30
+ mfc0 $9, $31
+ mfc0 $10,$5,4 /*save big page mode register*/
+
+ sw $1, 212(k0)
+ sw $2, 216(k0)
+ sw $3, 220(k0)
+ sw $4, 224(k0)
+ sw $5, 228(k0)
+ sw $6, 232(k0)
+ sw $7, 236(k0)
+ sw $8, 240(k0)
+ sw $9, 244(k0)
+ sw $10, 248(k0)
+
+ /* preserve virtual address of stack */
+ la k0, sleep_save_sp
+ sw sp, 0(k0)
+
+ /* flush caches and write buffers */
+ jal jz_flush_cache_all
+ nop
+
+ /* enter sleep mode */
+ .set mips3
+ sync
+ wait
+ nop
+ nop
+ nop
+ nop
+ .set mips0
+ nop
+9: j 9b
+ nop
+ nop
+
+/*
+ * jz_cpu_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ */
+
+ .align 5
+ .globl jz_cpu_resume
+jz_cpu_resume:
+
+ /* Init caches */
+ .set mips32
+ mtc0 zero, CP0_TAGLO
+
+ li t0, K0BASE
+ ori t1, t0, CFG_DCACHE_SIZE
+1:
+ cache Index_Store_Tag_D, 0(t0)
+ bne t0, t1, 1b
+ addiu t0, t0, CFG_CACHELINE_SIZE
+
+ li t0, K0BASE
+ ori t1, t0, CFG_ICACHE_SIZE
+2:
+ cache Index_Store_Tag_I, 0(t0)
+ bne t0, t1, 2b
+ addiu t0, t0, CFG_CACHELINE_SIZE
+
+ /* Invalidate BTB */
+ mfc0 t0, CP0_CONFIG, 7
+ nop
+ ori t0, 2
+ mtc0 t0, CP0_CONFIG, 7
+ nop
+
+
+ /* restore saved sp */
+ la t0, sleep_save_sp
+ lw sp, 0(t0)
+
+ /* restore CP0 registers(total 26) */
+ la k0, reg_save
+
+ lw $1, 128(k0)
+ lw $2, 132(k0)
+ lw $3, 136(k0)
+ lw $4, 140(k0)
+ lw $5, 144(k0)
+ lw $6, 148(k0)
+ lw $7, 152(k0)
+ lw $8, 156(k0)
+ lw $9, 160(k0)
+ lw $10, 164(k0)
+ lw $11, 168(k0)
+ lw $12, 172(k0)
+ lw $13, 176(k0)
+ lw $14, 180(k0)
+ lw $15, 184(k0)
+ lw $16, 188(k0)
+ lw $17, 192(k0)
+ lw $18, 196(k0)
+ lw $19, 200(k0)
+ lw $20, 204(k0)
+ lw $21, 208(k0)
+
+ mtc0 $1, $0
+ mtc0 $2, $1
+ mtc0 $3, $2
+ mtc0 $4, $3
+ mtc0 $5, $4
+ mtc0 $6, $5
+ mtc0 $7, $6
+ mtc0 $8, $8
+ mtc0 $9, $10
+ mtc0 $10,$12
+ mtc0 $11, $12,1
+ mtc0 $12, $13
+ mtc0 $13, $14
+ mtc0 $14, $15
+ mtc0 $15, $15,1
+ mtc0 $16, $16
+ mtc0 $17, $16,1
+ mtc0 $18, $16,2
+ mtc0 $19, $16,3
+ mtc0 $20, $16,7
+ mtc0 $21, $17
+
+
+ lw $1, 212(k0)
+ lw $2, 216(k0)
+ lw $3, 220(k0)
+ lw $4, 224(k0)
+ lw $5, 228(k0)
+ lw $6, 232(k0)
+ lw $7, 236(k0)
+ lw $8, 240(k0)
+ lw $9, 244(k0)
+ lw $10, 248(k0)
+
+ mtc0 $1, $18
+ mtc0 $2, $19
+ mtc0 $3, $23
+ mtc0 $4, $24
+ mtc0 $5, $26
+ mtc0 $6, $28
+ mtc0 $7, $28,1
+ mtc0 $8, $30
+ mtc0 $9, $31
+ mtc0 $10,$5,4 /*restore big page register*/
+
+ /*Restore cpu registers*/
+ lw k1, 120(k0) /* hi */
+ lw $0, 0(k0)
+ lw $1, 4(k0)
+ mthi k1
+ lw k1, 124(k0) /* lo */
+ lw $2, 8(k0)
+ lw $3, 12(k0)
+ mtlo k1
+ lw $4, 16(k0)
+ lw $5, 20(k0)
+ lw $6, 24(k0)
+ lw $7, 28(k0)
+ lw $8, 32(k0)
+ lw $9, 36(k0)
+ lw $10, 40(k0)
+ lw $11, 44(k0)
+ lw $12, 48(k0)
+ lw $13, 52(k0)
+ lw $14, 56(k0)
+ lw $15, 60(k0)
+ lw $16, 64(k0)
+ lw $17, 68(k0)
+ lw $18, 72(k0)
+ lw $19, 76(k0)
+ lw $20, 80(k0)
+ lw $21, 84(k0)
+ lw $22, 88(k0)
+ lw $23, 92(k0)
+ lw $24, 96(k0)
+ lw $25, 100(k0)
+ lw $28, 104(k0)
+ lw $29, 108(k0) /* restore sp */
+ lw $30, 112(k0)
+ lw $31, 116(k0) /* restore ra */
+
+ /* return to caller */
+ jr ra
+ nop
+ nop
+ nop
+
+sleep_save_sp:
+ .word 0 /* preserve sp here */
+
+ .set reorder
diff --git a/arch/mips/jz4760/time.c b/arch/mips/jz4760/time.c
new file mode 100644
index 00000000000..86ff7af848d
--- /dev/null
+++ b/arch/mips/jz4760/time.c
@@ -0,0 +1,218 @@
+/*
+ * linux/arch/mips/jz4760/time.c
+ *
+ * Setting up the clock on the JZ4760 boards.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/clockchips.h>
+
+#include <asm/time.h>
+#include <asm/jzsoc.h>
+
+/* This is for machines which generate the exact clock. */
+
+#define JZ_TIMER_TCU_CH 5
+#define JZ_TIMER_IRQ IRQ_TCU1
+
+#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */
+
+static struct clocksource clocksource_jz; /* Jz clock source */
+static struct clock_event_device jz_clockevent_device; /* Jz clock event */
+
+void (*jz_timer_callback)(void);
+
+static irqreturn_t jz_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
+
+ if (jz_timer_callback)
+ jz_timer_callback();
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz_irqaction = {
+ .handler = jz_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "jz-timerirq",
+};
+
+static unsigned int current_cycle_high = 0;
+
+union clycle_type
+{
+ cycle_t cycle64;
+ unsigned int cycle32[2];
+};
+
+cycle_t jz_get_cycles(void)
+{
+ /* convert jiffes to jz timer cycles */
+ unsigned int ostcount;
+ unsigned long cpuflags;
+ unsigned int current_cycle;
+ unsigned int flag;
+ union clycle_type old_cycle;
+
+ local_irq_save(cpuflags);
+ current_cycle = current_cycle_high;
+ ostcount = REG_OST_OSTCNT;
+ flag = (REG_TCU_TFR & TFCR_OSTFLAG) ? 1: 0;
+ if(flag)
+ ostcount = REG_OST_OSTCNT;
+ local_irq_restore(cpuflags);
+
+ old_cycle.cycle32[0] = ostcount;
+ old_cycle.cycle32[1] = current_cycle + flag;
+
+ return (old_cycle.cycle64);
+}
+
+static struct clocksource clocksource_jz = {
+ .name = "jz_clocksource",
+ .rating = 300,
+ .read = jz_get_cycles,
+ .mask = 0xFFFFFFFF,
+ .shift = 10,
+ .flags = CLOCK_SOURCE_WATCHDOG,
+};
+
+static irqreturn_t jzclock_handler(int irq, void *dev_id)
+{
+ REG_TCU_TFCR = TFCR_OSTFLAG; /* ACK timer */
+ current_cycle_high++;
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz_clockaction = {
+ .handler = jzclock_handler,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "jz-clockcycle",
+};
+static int __init jz_clocksource_init(void)
+{
+ unsigned int latch;
+
+ /* Init timer */
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
+ clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift);
+ clocksource_register(&clocksource_jz);
+
+ //---------------------init sys clock -----------------
+ REG_OST_OSTCSR = OSTCSR_PRESCALE16 | OSTCSR_EXT_EN;
+ REG_OST_OSTDR = 0xffffffff;
+ REG_OST_OSTCNT = 0;
+
+ jz_clockaction.dev_id = &clocksource_jz;
+
+ setup_irq(IRQ_TCU0, &jz_clockaction);
+ REG_TCU_TMCR = TMCR_OSTMASK; /* unmask match irq */
+ REG_TCU_TSCR = TSCR_OST; /* enable timer clock */
+ REG_TCU_TESR = TESR_OST; /* start counting up */
+
+ //---------------------endif init sys clock -----------------
+
+ return 0;
+}
+
+static int jz_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ return 0;
+}
+
+static void jz_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device jz_clockevent_device = {
+ .name = "jz-clockenvent",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz4740 not support dynamic clock now */
+
+ /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+ .mult = 1,
+ .rating = 300,
+ .irq = JZ_TIMER_IRQ,
+ .set_mode = jz_set_mode,
+ .set_next_event = jz_set_next_event,
+};
+
+static void __init jz_clockevent_init(void)
+{
+ struct clock_event_device *cd = &jz_clockevent_device;
+ unsigned int cpu = smp_processor_id();
+
+ cd->cpumask = cpumask_of(cpu);
+ clockevents_register_device(cd);
+}
+
+static void __init jz_timer_setup(void)
+{
+ unsigned int latch;
+
+ jz_clocksource_init(); /* init jz clock source */
+ jz_clockevent_init(); /* init jz clock event */
+
+ //---------------------init sys tick -----------------
+ /* Init timer */
+ __tcu_stop_counter(JZ_TIMER_TCU_CH);
+// __cpm_start_tcu();
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
+ REG_TCU_TMSR = ((1 << JZ_TIMER_TCU_CH) | (1 << (JZ_TIMER_TCU_CH + 16)));
+
+ REG_TCU_TCSR(JZ_TIMER_TCU_CH) = TCSR_PRESCALE16 | TCSR_EXT_EN;
+ REG_TCU_TDFR(JZ_TIMER_TCU_CH) = latch - 1;
+ REG_TCU_TDHR(JZ_TIMER_TCU_CH) = latch + 1;
+ REG_TCU_TCNT(JZ_TIMER_TCU_CH) = 0;
+ /*
+ * Make irqs happen for the system timer
+ */
+ jz_irqaction.dev_id = &jz_clockevent_device;
+ setup_irq(JZ_TIMER_IRQ, &jz_irqaction);
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
+ __tcu_unmask_full_match_irq(JZ_TIMER_TCU_CH);
+ __tcu_start_counter(JZ_TIMER_TCU_CH);}
+
+
+void __init plat_time_init(void)
+{
+ jz_timer_setup();
+}
diff --git a/arch/mips/jz4810/Makefile b/arch/mips/jz4810/Makefile
new file mode 100644
index 00000000000..e189f5d52e4
--- /dev/null
+++ b/arch/mips/jz4810/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for the Ingenic JZ4810.
+#
+
+# Object file lists.
+
+obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
+ platform.o #i2c.o
+
+obj-$(CONFIG_PROC_FS) += proc.o
+
+# board specific support
+obj-$(CONFIG_JZ4810_F4810) += board-f4810.o
+obj-$(CONFIG_SOC_JZ4810) += fpu.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o sleep.o
+
+# CPU Frequency scaling support
+
+obj-$(CONFIG_CPU_FREQ_JZ) += cpufreq.o
+
+#obj-$(CONFIG_JZ4760_ALTAIR) += gpiolib.o
+
diff --git a/arch/mips/jz4810/board-f4810.c b/arch/mips/jz4810/board-f4810.c
new file mode 100644
index 00000000000..676cde06021
--- /dev/null
+++ b/arch/mips/jz4810/board-f4810.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/mips/jz4760/board-f4760.c
+ *
+ * JZ4760 F4760 board setup routines.
+ *
+ * Copyright (c) 2006-2008 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/jzsoc.h>
+
+
+#define WM831X_LDO_MAX_NAME 6
+
+extern void (*jz_timer_callback)(void);
+
+static void dancing(void)
+{
+ static unsigned char slash[] = "\\|/-";
+// static volatile unsigned char *p = (unsigned char *)0xb6000058;
+ static volatile unsigned char *p = (unsigned char *)0xb6000016;
+ static unsigned int count = 0;
+ *p = slash[count++];
+ count &= 3;
+}
+
+static void f4810_timer_callback(void)
+{
+ static unsigned long count = 0;
+
+ if ((++count) % 50 == 0) {
+ dancing();
+ count = 0;
+ }
+}
+
+static void __init board_cpm_setup(void)
+{
+ /* Stop unused module clocks here.
+ * We have started all module clocks at arch/mips/jz4760/setup.c.
+ */
+}
+
+static void __init board_gpio_setup(void)
+{
+ /*
+ * Initialize SDRAM pins
+ */
+}
+
+void __init jz_board_setup(void)
+{
+
+ printk("JZ4810 F4810 board setup\n");
+// jz_restart(NULL);
+ board_cpm_setup();
+ board_gpio_setup();
+
+ jz_timer_callback = f4810_timer_callback;
+}
+
+/**
+ * Called by arch/mips/kernel/proc.c when 'cat /proc/cpuinfo'.
+ * Android requires the 'Hardware:' field in cpuinfo to setup the init.%hardware%.rc.
+ */
+const char *get_board_type(void)
+{
+ return "f4810";
+}
+
+/*****
+ * Wm831x init
+ *****/
diff --git a/arch/mips/jz4810/cpufreq.c b/arch/mips/jz4810/cpufreq.c
new file mode 100644
index 00000000000..6e537c8f132
--- /dev/null
+++ b/arch/mips/jz4810/cpufreq.c
@@ -0,0 +1,598 @@
+/*
+ * linux/arch/mips/jz4810/cpufreq.c
+ *
+ * cpufreq driver for JZ4810
+ *
+ * Copyright (c) 2006-2008 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/cpufreq.h>
+
+#include <asm/jzsoc.h>
+#include <asm/processor.h>
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "cpufreq-jz4810", 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 lcdpix_clk; /* LCD Pixel clock, Hz */
+ unsigned int lcd_clks_initialized;
+} boot_config;
+
+struct jz4810_freq_percpu_info {
+ struct cpufreq_frequency_table table[7];
+};
+
+static struct jz4810_freq_percpu_info jz4810_freq_table;
+
+/*
+ * This contains the registers value for an operating point.
+ * If only part of a register needs to change then there is
+ * a mask value for that register.
+ * When going to a new operating point the current register
+ * value is ANDed with the ~mask and ORed with the new value.
+ */
+struct dpm_regs {
+ u32 cpccr; /* Clock Freq Control Register */
+ u32 cpccr_mask; /* Clock Freq Control Register mask */
+ u32 cppcr; /* PLL1 Control Register */
+ u32 cppcr_mask; /* PLL1 Control Register mask */
+ u32 pll_up_flag; /* New PLL freq is higher than current or not */
+};
+
+extern jz_clocks_t jz_clocks;
+
+static void jz_update_clocks(void)
+{
+ /* Next clocks must be updated if we have changed
+ * the PLL or divisors.
+ */
+ jz_clocks.cclk = __cpm_get_cclk();
+ jz_clocks.hclk = __cpm_get_hclk();
+ jz_clocks.mclk = __cpm_get_mclk();
+ jz_clocks.pclk = __cpm_get_pclk();
+ jz_clocks.pixclk = __cpm_get_pixclk();
+ jz_clocks.i2sclk = __cpm_get_i2sclk();
+ jz_clocks.usbclk = __cpm_get_usbclk();
+ jz_clocks.mscclk = __cpm_get_mscclk(0);
+}
+
+static void
+jz_init_boot_config(void)
+{
+ if (!boot_config.lcd_clks_initialized) {
+ /* the first time to scale pll */
+ 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>>16) & 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 jz4810_transition(struct dpm_regs *regs)
+{
+ /*
+ * Get and save some boot-time conditions.
+ */
+ jz_init_boot_config();
+
+#ifdef CHANGE_PLL
+ /*
+ * Disable LCD before scaling pll.
+ * LCD and LCD pixel clocks should not be changed even if the PLL
+ * output frequency has been changed.
+ */
+ REG_LCD_CTRL &= ~LCD_CTRL_ENA;
+
+ /*
+ * Stop module clocks before scaling PLL
+ */
+ __cpm_stop_eth();
+ __cpm_stop_aic(1);
+ __cpm_stop_aic(2);
+#endif
+
+ /* ... add more as necessary */
+
+ if (regs->pll_up_flag == PLL_GOES_UP) {
+ /* the pll frequency is going up, so change dividors first */
+ jz_scale_divisors(regs);
+#ifdef CHANGE_PLL
+ jz_scale_pll(regs);
+#endif
+ }
+ else if (regs->pll_up_flag == PLL_GOES_DOWN) {
+ /* the pll frequency is going down, so change pll first */
+#ifdef CHANGE_PLL
+ jz_scale_pll(regs);
+#endif
+ jz_scale_divisors(regs);
+ }
+ else {
+ /* the pll frequency is unchanged, so change divisors only */
+ jz_scale_divisors(regs);
+ }
+
+#ifdef CHANGE_PLL
+ /*
+ * Restart module clocks before scaling PLL
+ */
+ __cpm_start_eth();
+ __cpm_start_aic(1);
+ __cpm_start_aic(2);
+
+ /* ... add more as necessary */
+
+ /* Scale the LCD divisors after scaling pll */
+ if (regs->pll_up_flag != PLL_UNCHANGED) {
+ jz_scale_lcd_divisors(regs);
+ }
+
+ /* Enable LCD controller */
+ REG_LCD_CTRL &= ~LCD_CTRL_DIS;
+ REG_LCD_CTRL |= LCD_CTRL_ENA;
+#endif
+
+ /* Update system clocks */
+ jz_update_clocks();
+}
+
+extern unsigned int idle_times;
+static unsigned int jz4810_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 = jz4810_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 jz4810_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)
+ jz4810_transition(&regs);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+}
+
+static int jz4810_freq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int new_index = 0;
+
+ if (cpufreq_frequency_table_target(policy,
+ &jz4810_freq_table.table[0],
+ target_freq, relation, &new_index))
+ return -EINVAL;
+
+ jz4810_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 jz4810_freq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ &jz4810_freq_table.table[0]);
+}
+
+static int __init jz4810_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+
+ struct cpufreq_frequency_table *table = &jz4810_freq_table.table[0];
+ unsigned int MAX_FREQ;
+
+ dprintk(KERN_INFO "Jz4810 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_jz4810_driver = {
+// .flags = CPUFREQ_STICKY,
+ .init = jz4810_cpufreq_driver_init,
+ .verify = jz4810_freq_verify,
+ .target = jz4810_freq_target,
+ .get = jz4810_freq_get,
+ .name = "jz4810",
+};
+
+static int __init jz4810_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&cpufreq_jz4810_driver);
+}
+
+static void __exit jz4810_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&cpufreq_jz4810_driver);
+}
+
+module_init(jz4810_cpufreq_init);
+module_exit(jz4810_cpufreq_exit);
+
+MODULE_AUTHOR("Regen <lhhuang@ingenic.cn>");
+MODULE_DESCRIPTION("cpufreq driver for Jz4810");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/jz4810/dma.c b/arch/mips/jz4810/dma.c
new file mode 100644
index 00000000000..d6e4dd281b2
--- /dev/null
+++ b/arch/mips/jz4810/dma.c
@@ -0,0 +1,848 @@
+/*
+ * linux/arch/mips/jz4810/dma.c
+ *
+ * Support functions for the JZ4810 internal DMA channels.
+ * No-descriptor transfer only.
+ * Descriptor transfer should also call jz_request_dma() to get a free
+ * channel and call jz_free_dma() to free the channel. And driver should
+ * build the DMA descriptor and setup the DMA channel by itself.
+ *
+ * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/soundcard.h>
+
+#include <asm/system.h>
+#include <asm/addrspace.h>
+#include <asm/jzsoc.h>
+
+/*
+ * A note on resource allocation:
+ *
+ * All drivers needing DMA channels, should allocate and release them
+ * through the public routines `jz_request_dma()' and `jz_free_dma()'.
+ *
+ * In order to avoid problems, all processes should allocate resources in
+ * the same sequence and release them in the reverse order.
+ *
+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
+ * When releasing them, first release the IRQ, then release the DMA. The
+ * main reason for this order is that, if you are requesting the DMA buffer
+ * done interrupt, you won't know the irq number until the DMA channel is
+ * returned from jz_request_dma().
+ */
+
+struct jz_dma_chan jz_dma_table[MAX_DMA_NUM] = {
+ {dev_id:DMA_ID_BCH_ENC,}, /* DMAC0 channel 0, reserved for BCH */
+ {dev_id:-1,}, /* DMAC0 channel 1 */
+ {dev_id:-1,}, /* DMAC0 channel 2 */
+ {dev_id:-1,}, /* DMAC0 channel 3 */
+ {dev_id:-1,}, /* DMAC1 channel 0 */
+ {dev_id:-1,}, /* DMAC1 channel 1 */
+ {dev_id:-1,}, /* DMAC1 channel 2 */
+ {dev_id:-1,}, /* DMAC1 channel 3 */
+};
+
+// Device FIFO addresses and default DMA modes
+static const struct {
+ unsigned int fifo_addr;
+ unsigned int dma_mode;
+ unsigned int dma_source;
+} dma_dev_table[DMA_ID_MAX] = {
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_EXT}, /* External request with DREQn */
+ {0x18000000, DMA_AUTOINIT, DMAC_DRSR_RS_NAND}, /* NAND request */
+ {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_ENC},
+ {CPHYSADDR(BCH_DR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_BCH_DEC},
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_AUTO},
+// {CPHYSADDR(TSSI_FIFO), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_TSSIIN},
+ {CPHYSADDR(UART3_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART3OUT},
+ {CPHYSADDR(UART3_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART3IN},
+ {CPHYSADDR(UART2_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART2OUT},
+ {CPHYSADDR(UART2_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART2IN},
+ {CPHYSADDR(UART1_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART1OUT},
+ {CPHYSADDR(UART1_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART1IN},
+ {CPHYSADDR(UART0_TDR), DMA_8BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_UART0OUT},
+ {CPHYSADDR(UART0_RDR), DMA_8BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_UART0IN},
+ {CPHYSADDR(SSI_DR(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI0OUT},
+ {CPHYSADDR(SSI_DR(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI0IN},
+
+ /*spdif used */
+ //{CPHYSADDR(SPDIF_FIFO), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ /*aic unpack used*/
+ {CPHYSADDR(AIC_DR), DMA_AIC_TX_CMD_UNPACK | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ /*aic pack used*/
+ //{CPHYSADDR(AIC_DR), DMA_AIC_TX_CMD_PACK | DMA_MODE_WRITE, DMAC_DRSR_RS_AICOUT},
+ {CPHYSADDR(AIC_DR), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_AICIN},
+ {CPHYSADDR(MSC_TXFIFO(0)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC0OUT},
+ {CPHYSADDR(MSC_RXFIFO(0)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC0IN},
+ {0, DMA_AUTOINIT, DMAC_DRSR_RS_TCU},
+ {SADC_TSDAT, DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SADC},/* Touch Screen Data Register */
+ {CPHYSADDR(MSC_TXFIFO(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_MSC1OUT}, /* SSC1 TX */
+ {CPHYSADDR(MSC_RXFIFO(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_MSC1IN}, /* SSC1 RX */
+ {CPHYSADDR(SSI_DR(1)), DMA_32BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_SSI1OUT},
+ {CPHYSADDR(SSI_DR(1)), DMA_32BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_SSI1IN},
+ {CPHYSADDR(PCM_DP), DMA_16BIT_TX_CMD | DMA_MODE_WRITE, DMAC_DRSR_RS_PMOUT},
+ {CPHYSADDR(PCM_DP), DMA_16BIT_RX_CMD | DMA_MODE_READ, DMAC_DRSR_RS_PMIN},
+ {},
+};
+
+
+int jz_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data)
+{
+ int i, len = 0;
+ struct jz_dma_chan *chan;
+
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if ((chan = get_dma_chan(i)) != NULL) {
+ len += sprintf(buf + len, "%2d: %s\n",
+ i, chan->dev_str);
+ }
+ }
+
+ if (fpos >= len) {
+ *start = buf;
+ *eof = 1;
+ return 0;
+ }
+ *start = buf + fpos;
+ if ((len -= fpos) > length)
+ return length;
+ *eof = 1;
+ return len;
+}
+
+
+void dump_jz_dma_channel(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan;
+
+ if (dmanr > MAX_DMA_NUM)
+ return;
+ chan = &jz_dma_table[dmanr];
+
+ printk("DMA%d Registers:\n", dmanr);
+ printk(" DMACR = 0x%08x\n", REG_DMAC_DMACR(chan->io/HALF_DMA_NUM));
+ printk(" DSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr));
+ printk(" DTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr));
+ printk(" DTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr));
+ printk(" DRSR = 0x%08x\n", REG_DMAC_DRSR(dmanr));
+ printk(" DCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr));
+ printk(" DCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr));
+ printk(" DDA = 0x%08x\n", REG_DMAC_DDA(dmanr));
+ printk(" DMADBR = 0x%08x\n", REG_DMAC_DMADBR(chan->io/HALF_DMA_NUM));
+}
+
+void dump_jz_bdma_channel(unsigned int dmanr)
+{
+ printk("\n----------chan%d----------------\n",dmanr);
+ printk("DSA: %x\n",REG_BDMAC_DSAR(dmanr));
+ printk("DTA: %x\n",REG_BDMAC_DTAR(dmanr));
+ printk("DTC: %x\n",REG_BDMAC_DTCR(dmanr));
+ printk("DRT: %x\n",REG_BDMAC_DRSR(dmanr));
+ printk("DCS: %x\n",REG_BDMAC_DCCSR(dmanr));
+ printk("DCM: %x\n",REG_BDMAC_DCMD(dmanr));
+ printk("DDA: %x\n",REG_BDMAC_DDA(dmanr));
+ printk("DSD: %x\n",REG_BDMAC_DSD(dmanr));
+ printk("DNT: %x\n",REG_BDMAC_DNT(dmanr));
+ printk("DMAC: %x\n",REG_BDMAC_DMACR);
+ printk("DIRQP: %x\n",REG_BDMAC_DMAIPR);
+ printk("DDR: %x\n",REG_BDMAC_DMADBR);
+ printk("DDRS: %x\n",REG_BDMAC_DMADBSR);
+ printk("DCKE: %x\n",REG_BDMAC_DMACKE);
+ printk("-------------------------\n");
+}
+
+
+/**
+ * jz_request_dma - dynamically allcate an idle DMA channel to return
+ * @dev_id: the specified dma device id or DMA_ID_RAW_SET
+ * @dev_str: the specified dma device string name
+ * @irqhandler: the irq handler, or NULL
+ * @irqflags: the irq handler flags
+ * @irq_dev_id: the irq handler device id for shared irq
+ *
+ * Finds a free channel, and binds the requested device to it.
+ * Returns the allocated channel number, or negative on error.
+ * Requests the DMA done IRQ if irqhandler != NULL.
+ *
+*/
+/*int jz_request_dma(int dev_id, const char *dev_str,
+ void (*irqhandler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ void *irq_dev_id)
+*/
+
+int jz_request_dma(int dev_id, const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags,
+ void *irq_dev_id)
+{
+ struct jz_dma_chan *chan;
+ int i, ret;
+
+ if (dev_id < 0 || dev_id >= DMA_ID_MAX)
+ return -EINVAL;
+
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if (jz_dma_table[i].dev_id < 0)
+ break;
+ }
+ if (i == MAX_DMA_NUM) /* no free channel */
+ return -ENODEV;
+
+ /* we got a free channel */
+ chan = &jz_dma_table[i];
+
+ if (irqhandler) {
+ chan->irq = IRQ_DMA_0 + i; // allocate irq number
+ chan->irq_dev = irq_dev_id;
+ if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+ dev_str, chan->irq_dev))) {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ return ret;
+ }
+ } else {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ }
+
+ // fill it in
+ chan->io = i;
+ chan->dev_id = dev_id;
+ chan->dev_str = dev_str;
+ chan->fifo_addr = dma_dev_table[dev_id].fifo_addr;
+ chan->mode = dma_dev_table[dev_id].dma_mode;
+ chan->source = dma_dev_table[dev_id].dma_source;
+
+ if (i < HALF_DMA_NUM)
+ REG_DMAC_DMACKE(0) = 1 << i;
+ else
+ REG_DMAC_DMACKE(1) = 1 << (i - HALF_DMA_NUM);
+
+ return i;
+}
+
+void jz_free_dma(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan) {
+ printk("Trying to free DMA%d\n", dmanr);
+ return;
+ }
+
+ disable_dma(dmanr);
+ if (chan->irq)
+ free_irq(chan->irq, chan->irq_dev);
+
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ chan->dev_id = -1;
+}
+
+void jz_set_dma_dest_width(int dmanr, int nbit)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_DWDH_MASK;
+ switch (nbit) {
+ case 8:
+ chan->mode |= DMAC_DCMD_DWDH_8;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_DWDH_16;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_DWDH_32;
+ break;
+ }
+}
+
+void jz_set_dma_src_width(int dmanr, int nbit)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_SWDH_MASK;
+ switch (nbit) {
+ case 8:
+ chan->mode |= DMAC_DCMD_SWDH_8;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_SWDH_16;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_SWDH_32;
+ break;
+ }
+}
+
+void jz_set_dma_block_size(int dmanr, int nbyte)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode &= ~DMAC_DCMD_DS_MASK;
+ switch (nbyte) {
+ case 1:
+ chan->mode |= DMAC_DCMD_DS_8BIT;
+ break;
+ case 2:
+ chan->mode |= DMAC_DCMD_DS_16BIT;
+ break;
+ case 4:
+ chan->mode |= DMAC_DCMD_DS_32BIT;
+ break;
+ case 16:
+ chan->mode |= DMAC_DCMD_DS_16BYTE;
+ break;
+ case 32:
+ chan->mode |= DMAC_DCMD_DS_32BYTE;
+ break;
+ }
+}
+
+unsigned int jz_get_dma_command(int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ return chan->mode;
+}
+
+/**
+ * jz_set_dma_mode - do the raw settings for the specified DMA channel
+ * @dmanr: the specified DMA channel
+ * @mode: dma operate mode, DMA_MODE_READ or DMA_MODE_WRITE
+ * @dma_mode: dma raw mode
+ * @dma_source: dma raw request source
+ * @fifo_addr: dma raw device fifo address
+ *
+ * Ensure call jz_request_dma(DMA_ID_RAW_SET, ...) first, then call
+ * jz_set_dma_mode() rather than set_dma_mode() if you work with
+ * and external request dma device.
+ *
+ * NOTE: Don not dynamically allocate dma channel if one external request
+ * dma device will occupy this channel.
+*/
+int jz_set_dma_mode(unsigned int dmanr, unsigned int mode,
+ unsigned int dma_mode, unsigned int dma_source,
+ unsigned int fifo_addr)
+{
+ int dev_id, i;
+ struct jz_dma_chan *chan;
+
+ if (dmanr > MAX_DMA_NUM)
+ return -ENODEV;
+ for (i = 0; i < MAX_DMA_NUM; i++) {
+ if (jz_dma_table[i].dev_id < 0)
+ break;
+ }
+ if (i == MAX_DMA_NUM)
+ return -ENODEV;
+
+ chan = &jz_dma_table[dmanr];
+ dev_id = chan->dev_id;
+ if (dev_id > 0) {
+ printk(KERN_DEBUG "%s sets the allocated DMA channel %d!\n",
+ __FUNCTION__, dmanr);
+ return -ENODEV;
+ }
+
+ /* clone it from the dynamically allocated. */
+ if (i != dmanr) {
+ chan->irq = jz_dma_table[i].irq;
+ chan->irq_dev = jz_dma_table[i].irq_dev;
+ chan->dev_str = jz_dma_table[i].dev_str;
+ jz_dma_table[i].irq = 0;
+ jz_dma_table[i].irq_dev = NULL;
+ jz_dma_table[i].dev_id = -1;
+ }
+ chan->dev_id = DMA_ID_RAW_SET;
+ chan->io = dmanr;
+ chan->fifo_addr = fifo_addr;
+ chan->mode = dma_mode;
+ chan->source = dma_source;
+
+ set_dma_mode(dmanr, dma_mode);
+
+ return dmanr;
+}
+
+void enable_dma(unsigned int dmanr)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ REG_DMAC_DCCSR(dmanr) &= ~(DMAC_DCCSR_HLT | DMAC_DCCSR_TT | DMAC_DCCSR_AR);
+ REG_DMAC_DCCSR(dmanr) |= DMAC_DCCSR_NDES; /* No-descriptor transfer */
+ __dmac_enable_channel(dmanr);
+ if (chan->irq)
+ __dmac_channel_enable_irq(dmanr);
+}
+
+#define DMA_DISABLE_POLL 0x10000
+
+void disable_dma(unsigned int dmanr)
+{
+ int i;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ if (!__dmac_channel_enabled(dmanr))
+ return;
+
+ for (i = 0; i < DMA_DISABLE_POLL; i++)
+ if (__dmac_channel_transmit_end_detected(dmanr))
+ break;
+#if 0
+ if (i == DMA_DISABLE_POLL)
+ printk(KERN_INFO "disable_dma: poll expired!\n");
+#endif
+
+ __dmac_disable_channel(dmanr);
+ if (chan->irq)
+ __dmac_channel_disable_irq(dmanr);
+}
+
+/* Note: DMA_MODE_MASK is simulated by sw */
+void set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ if (mode == DMA_MODE_READ) {
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else {
+ printk(KERN_DEBUG "set_dma_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+ }
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+}
+
+void set_dma_addr(unsigned int dmanr, unsigned int phyaddr)
+{
+ unsigned int mode;
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ mode = chan->mode & DMA_MODE_MASK;
+ if (mode == DMA_MODE_READ) {
+ REG_DMAC_DSAR(chan->io) = chan->fifo_addr;
+ REG_DMAC_DTAR(chan->io) = phyaddr;
+ } else if (mode == DMA_MODE_WRITE) {
+ REG_DMAC_DSAR(chan->io) = phyaddr;
+ REG_DMAC_DTAR(chan->io) = chan->fifo_addr;
+ } else
+ printk(KERN_DEBUG "Driver should call set_dma_mode() ahead set_dma_addr()!\n");
+}
+
+void set_dma_count(unsigned int dmanr, unsigned int bytecnt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ int dma_ds[] = {4, 1, 2, 16, 32};
+ unsigned int ds;
+
+ if (!chan)
+ return;
+
+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT;
+ REG_DMAC_DTCR(chan->io) = bytecnt / dma_ds[ds]; // transfer count
+}
+
+unsigned int get_dma_residue(unsigned int dmanr)
+{
+ unsigned int count, ds;
+ int dma_ds[] = {4, 1, 2, 16, 32};
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+
+ ds = (chan->mode & DMAC_DCMD_DS_MASK) >> DMAC_DCMD_DS_BIT;
+ count = REG_DMAC_DTCR(chan->io);
+ count = count * dma_ds[ds];
+
+ return count;
+}
+
+void jz_set_oss_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ switch (audio_fmt) {
+ case AFMT_U8:
+ /* burst mode : 32BIT */
+ break;
+ case AFMT_S16_LE:
+ /* burst mode : 16BYTE */
+ if (mode == DMA_MODE_READ) {
+ chan->mode = DMA_AIC_32_16BYTE_RX_CMD | DMA_MODE_READ;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode = DMA_AIC_32_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ //chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else
+ printk("oss_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+ break;
+ }
+}
+
+void jz_set_alsa_dma(unsigned int dmanr, unsigned int mode, unsigned int audio_fmt)
+{
+ struct jz_dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ switch (audio_fmt) {
+ case 8:
+ /* SNDRV_PCM_FORMAT_S8 burst mode : 32BIT */
+ break;
+ case 16:
+ /* SNDRV_PCM_FORMAT_S16_LE burst mode : 16BYTE */
+ if (mode == DMA_MODE_READ) {
+ chan->mode = DMA_AIC_16BYTE_RX_CMD | DMA_MODE_READ;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_DAI;
+ chan->mode &= ~DMAC_DCMD_SAI;
+ } else if (mode == DMA_MODE_WRITE) {
+ chan->mode = DMA_AIC_16BYTE_TX_CMD | DMA_MODE_WRITE;
+ chan->mode |= mode & ~(DMAC_DCMD_SAI | DMAC_DCMD_DAI);
+ mode &= DMA_MODE_MASK;
+ chan->mode |= DMAC_DCMD_SAI;
+ chan->mode &= ~DMAC_DCMD_DAI;
+ } else
+ printk("alsa_dma_burst_mode() just supports DMA_MODE_READ or DMA_MODE_WRITE!\n");
+
+ REG_DMAC_DCMD(chan->io) = chan->mode & ~DMA_MODE_MASK;
+ REG_DMAC_DRSR(chan->io) = chan->source;
+ break;
+ }
+}
+
+//#define JZ4810_DMAC_TEST_ENABLE
+#undef JZ4810_DMAC_TEST_ENABLE
+
+#ifdef JZ4810_DMAC_TEST_ENABLE
+
+/*
+ * DMA test: external address <--> external address
+ */
+#define TEST_DMA_SIZE 16*1024
+
+static jz_dma_desc *dma_desc;
+
+static int dma_chan;
+static dma_addr_t dma_desc_phys_addr;
+static unsigned int dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr;
+
+static int dma_check_result(void *src, void *dst, int size)
+{
+ unsigned int addr1, addr2, i, err = 0;
+
+ addr1 = (unsigned int)src;
+ addr2 = (unsigned int)dst;
+
+ for (i = 0; i < size; i += 4) {
+ if (*(volatile unsigned int *)addr1 != *(volatile unsigned int *)addr2) {
+ err++;
+ printk("wrong data at 0x%08x: src 0x%08x dst 0x%08x\n", addr2, *(volatile unsigned int *)addr1, *(volatile unsigned int *)addr2);
+ }
+ addr1 += 4;
+ addr2 += 4;
+ }
+ printk("check DMA result err=%d\n", err);
+ return err;
+}
+
+static irqreturn_t jz4810_dma_irq(int irq, void *dev_id)
+{
+ printk("jz4810_dma_irq %d\n", irq);
+
+
+ if (__dmac_channel_transmit_halt_detected(dma_chan)) {
+ printk("DMA HALT\n");
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ __dmac_channel_clear_transmit_halt(dma_chan);
+ }
+
+ if (__dmac_channel_address_error_detected(dma_chan)) {
+ printk("DMA ADDR ERROR\n");
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ REG_DMAC_DSAR(dma_chan) = 0; /* clear source address register */
+ REG_DMAC_DTAR(dma_chan) = 0; /* clear target address register */
+ __dmac_channel_clear_address_error(dma_chan);
+ }
+
+ if (__dmac_channel_descriptor_invalid_detected(dma_chan)) {
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ printk("DMA DESC INVALID\n");
+ __dmac_channel_clear_descriptor_invalid(dma_chan);
+ }
+
+ if (__dmac_channel_count_terminated_detected(dma_chan)) {
+ printk("DMA CT\n");
+ __dmac_channel_clear_count_terminated(dma_chan);
+ }
+
+ if (__dmac_channel_transmit_end_detected(dma_chan)) {
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ printk("DMA TT\n");
+ __dmac_channel_clear_transmit_end(dma_chan);
+ dump_jz_dma_channel(dma_chan);
+ dma_check_result((void *)dma_src_addr, (void *)dma_dst_addr, TEST_DMA_SIZE);
+ }
+
+ return IRQ_HANDLED;
+}
+
+void dma_nodesc_test(void)
+{
+ unsigned int addr, i;
+
+ printk("dma_nodesc_test\n");
+
+ /* Request DMA channel and setup irq handler */
+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4810_dma_irq,
+ IRQF_DISABLED, NULL);
+ if (dma_chan < 0) {
+ printk("Setup irq failed\n");
+ return;
+ }
+
+ printk("Requested DMA channel = %d\n", dma_chan);
+
+ /* Allocate DMA buffers */
+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+
+ dma_src_phys_addr = CPHYSADDR(dma_src_addr);
+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr);
+
+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr);
+
+ /* Prepare data for source buffer */
+ addr = (unsigned int)dma_src_addr;
+ for (i = 0; i < TEST_DMA_SIZE; i += 4) {
+ *(volatile unsigned int *)addr = addr;
+ addr += 4;
+ }
+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE);
+
+ /* Init target buffer */
+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE);
+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE);
+
+ /* Init DMA module */
+ printk("Starting DMA\n");
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = 0;
+ REG_DMAC_DCCSR(dma_chan) = 0;
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+ REG_DMAC_DSAR(dma_chan) = dma_src_phys_addr;
+ REG_DMAC_DTAR(dma_chan) = dma_dst_phys_addr;
+ REG_DMAC_DTCR(dma_chan) = 512;
+ REG_DMAC_DCMD(dma_chan) = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_TIE;
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE; /* global DMA enable bit */
+
+ printk("DMA started. IMR=%08x\n", REG_INTC_IMR);
+
+ /* wait a long time, ensure transfer end */
+ printk("wait 3s...\n");
+ mdelay(3000); /* wait 3s */
+
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ /* free buffers */
+ printk("free DMA buffers\n");
+ free_pages(dma_src_addr, 2);
+ free_pages(dma_dst_addr, 2);
+
+ if (dma_desc)
+ free_pages((unsigned int)dma_desc, 0);
+
+ /* free dma */
+ jz_free_dma(dma_chan);
+}
+
+void dma_desc_test(void)
+{
+ unsigned int next, addr, i;
+ static jz_dma_desc *desc;
+
+ printk("dma_desc_test\n");
+
+ /* Request DMA channel and setup irq handler */
+ dma_chan = jz_request_dma(DMA_ID_AUTO, "auto", jz4810_dma_irq,
+ IRQF_DISABLED, NULL);
+ if (dma_chan < 0) {
+ printk("Setup irq failed\n");
+ return;
+ }
+
+ printk("Requested DMA channel = %d\n", dma_chan);
+
+ /* Allocate DMA buffers */
+ dma_src_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+ dma_dst_addr = __get_free_pages(GFP_KERNEL, 2); /* 16KB */
+
+ dma_src_phys_addr = CPHYSADDR(dma_src_addr);
+ dma_dst_phys_addr = CPHYSADDR(dma_dst_addr);
+
+ printk("Buffer addresses: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ dma_src_addr, dma_src_phys_addr, dma_dst_addr, dma_dst_phys_addr);
+
+ /* Prepare data for source buffer */
+ addr = (unsigned int)dma_src_addr;
+ for (i = 0; i < TEST_DMA_SIZE; i += 4) {
+ *(volatile unsigned int *)addr = addr;
+ addr += 4;
+ }
+ dma_cache_wback((unsigned long)dma_src_addr, TEST_DMA_SIZE);
+
+ /* Init target buffer */
+ memset((void *)dma_dst_addr, 0, TEST_DMA_SIZE);
+ dma_cache_wback((unsigned long)dma_dst_addr, TEST_DMA_SIZE);
+
+ /* Allocate DMA descriptors */
+ dma_desc = (jz_dma_desc *)__get_free_pages(GFP_KERNEL, 0);
+ dma_desc_phys_addr = CPHYSADDR((unsigned long)dma_desc);
+
+ printk("DMA descriptor address: 0x%08x 0x%08x\n", (u32)dma_desc, dma_desc_phys_addr);
+
+ /* Setup DMA descriptors */
+ desc = dma_desc;
+ next = (dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr; /* DMA target address */
+ desc->ddadr = (next << 24) + 128; /* size: 128*32 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 2*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr + 4096; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 4096; /* DMA target address */
+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 3*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_16BYTE | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE | DMAC_DCMD_LINK;
+ desc->dsadr = dma_src_phys_addr + 8192; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 8192; /* DMA target address */
+ desc->ddadr = (next << 24) + 256; /* size: 256*16 bytes = 4096 bytes */
+
+ desc++;
+ next = (dma_desc_phys_addr + 4*(sizeof(jz_dma_desc))) >> 4;
+
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_DAI | DMAC_DCMD_RDIL_IGN | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT | DMAC_DCMD_DES_V | DMAC_DCMD_DES_VM | DMAC_DCMD_DES_VIE | DMAC_DCMD_TIE;
+ desc->dsadr = dma_src_phys_addr + 12*1024; /* DMA source address */
+ desc->dtadr = dma_dst_phys_addr + 12*1024; /* DMA target address */
+ desc->ddadr = (next << 24) + 1024; /* size: 1024*4 bytes = 4096 bytes */
+
+ dma_cache_wback((unsigned long)dma_desc, 4*(sizeof(jz_dma_desc)));
+
+ /* Setup DMA descriptor address */
+ REG_DMAC_DDA(dma_chan) = dma_desc_phys_addr;
+
+ /* Setup request source */
+ REG_DMAC_DRSR(dma_chan) = DMAC_DRSR_RS_AUTO;
+
+ /* Setup DMA channel control/status register */
+ REG_DMAC_DCCSR(dma_chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */
+
+ /* Enable DMA */
+ REG_DMAC_DMACR(dma_chan/HALF_DMA_NUM) = DMAC_DMACR_DMAE;
+
+ /* DMA doorbell set -- start DMA now ... */
+ REG_DMAC_DMADBSR(dma_chan/HALF_DMA_NUM) = 1 << dma_chan;
+
+ printk("DMA started. IMR=%08x\n", REG_INTC_IMR);
+ /* wait a long time, ensure transfer end */
+ printk("wait 3s...\n");
+ mdelay(3000); /* wait 3s */
+
+ REG_DMAC_DCCSR(dma_chan) &= ~DMAC_DCCSR_EN; /* disable DMA */
+ /* free buffers */
+ printk("free DMA buffers\n");
+ free_pages(dma_src_addr, 2);
+ free_pages(dma_dst_addr, 2);
+
+ if (dma_desc)
+ free_pages((unsigned int)dma_desc, 0);
+
+ /* free dma */
+ jz_free_dma(dma_chan);
+}
+
+#endif
+
+//EXPORT_SYMBOL_NOVERS(jz_dma_table);
+EXPORT_SYMBOL(jz_dma_table);
+EXPORT_SYMBOL(jz_request_dma);
+EXPORT_SYMBOL(jz_free_dma);
+EXPORT_SYMBOL(jz_set_dma_src_width);
+EXPORT_SYMBOL(jz_set_dma_dest_width);
+EXPORT_SYMBOL(jz_set_dma_block_size);
+EXPORT_SYMBOL(jz_set_dma_mode);
+EXPORT_SYMBOL(set_dma_mode);
+EXPORT_SYMBOL(jz_set_oss_dma);
+EXPORT_SYMBOL(jz_set_alsa_dma);
+EXPORT_SYMBOL(set_dma_addr);
+EXPORT_SYMBOL(set_dma_count);
+EXPORT_SYMBOL(get_dma_residue);
+EXPORT_SYMBOL(enable_dma);
+EXPORT_SYMBOL(disable_dma);
+EXPORT_SYMBOL(dump_jz_dma_channel);
diff --git a/arch/mips/jz4810/fpu.c b/arch/mips/jz4810/fpu.c
new file mode 100644
index 00000000000..cb780b5456a
--- /dev/null
+++ b/arch/mips/jz4810/fpu.c
@@ -0,0 +1,143 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#include <asm/jzsoc.h>
+
+void jz4810_fpu_dump(void)
+{
+ unsigned int fgpr[32];
+ unsigned int fscr, fir, i;
+
+ for (i = 0; i < 32; i ++)
+ fgpr[i] = 0xdeadbeef;
+
+ __asm__ __volatile__(
+ "swc1 $f0, 0(%0)\n\t"
+ "swc1 $f1, 4(%0)\n\t"
+ "swc1 $f2, 8(%0)\n\t"
+ "swc1 $f3, 12(%0)\n\t"
+ "swc1 $f4, 16(%0)\n\t"
+ "swc1 $f4, 20(%0)\n\t"
+ "swc1 $f6, 24(%0)\n\t"
+ "swc1 $f6, 28(%0)\n\t"
+ "swc1 $f8, 32(%0)\n\t"
+ "swc1 $f9, 36(%0)\n\t"
+ "swc1 $f10, 40(%0)\n\t"
+ "swc1 $f11, 44(%0)\n\t"
+ "swc1 $f12, 48(%0)\n\t"
+ "swc1 $f13, 52(%0)\n\t"
+ "swc1 $f14, 56(%0)\n\t"
+ "swc1 $f15, 60(%0)\n\t"
+ "swc1 $f16, 64(%0)\n\t"
+ "swc1 $f17, 68(%0)\n\t"
+ "swc1 $f18, 72(%0)\n\t"
+ "swc1 $f19, 76(%0)\n\t"
+ "swc1 $f20, 80(%0)\n\t"
+ "swc1 $f21, 84(%0)\n\t"
+ "swc1 $f22, 88(%0)\n\t"
+ "swc1 $f23, 92(%0)\n\t"
+ "swc1 $f24, 96(%0)\n\t"
+ "swc1 $f25, 100(%0)\n\t"
+ "swc1 $f26, 104(%0)\n\t"
+ "swc1 $f27, 108(%0)\n\t"
+ "swc1 $f28, 112(%0)\n\t"
+ "swc1 $f29, 116(%0)\n\t"
+ "swc1 $f30, 120(%0)\n\t"
+ "swc1 $f31, 124(%0)\n\t"
+ :
+ :"r"(fgpr)
+ );
+
+ /* Get FPU control and status register */
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(fscr)
+ :
+ );
+
+ /* Get FPU implementation and revision register */
+ __asm__ __volatile__(
+ "cfc1 %0, $0 \n\t"
+ :"=r"(fir)
+ :
+ );
+
+ printk("Dump of FPU: \n");
+
+ for (i = 0; i < 32; i += 4)
+ printk("%08x %08x %08x %08x \n",
+ fgpr[i],fgpr[i+1],fgpr[i+2],fgpr[i+3]);
+ printk("FPU control and status register = %08x \n",fscr);
+ printk("FPU implementation and revision register = %08x \n",fir);
+
+ fscr |= 0x11;
+
+ __asm__ __volatile__(
+ "ctc1 %0, $31 \n\t"
+ :
+ :"r"(fscr)
+ );
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(fscr)
+ :
+ );
+ printk("FPU control and status register = %08x \n",fscr);
+}
+
+void jz4810_fpu_init(unsigned int round)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(tmp)
+ :
+ );
+
+// printk("original jz4810 FCSR value: %8x\n",tmp);
+
+ tmp = 0x0;
+ /* Jz4810 FPU init */
+ /* disable any exception */
+ tmp |= (0x0 << 7);
+ /* Set ronud mode */
+ tmp &= ~0x3;
+ tmp |= (round & 0x3);
+
+// printk("plan to set jz4810 FPU FCSR to %08x \n",tmp);
+ __asm__ __volatile__(
+ "ctc1 %0, $28 \n\t"
+ :
+ :"r"(tmp)
+ );
+
+ __asm__ __volatile__(
+ "cfc1 %0, $31 \n\t"
+ :"=r"(tmp)
+ :
+ );
+
+// printk("jz4810 FCSR value after setting: %8x\n",tmp);
+
+}
+
+EXPORT_SYMBOL(jz4810_fpu_init);
diff --git a/arch/mips/jz4810/gpiolib.c b/arch/mips/jz4810/gpiolib.c
new file mode 100644
index 00000000000..d8f12aa8a40
--- /dev/null
+++ b/arch/mips/jz4810/gpiolib.c
@@ -0,0 +1,205 @@
+
+/* arch/mips/jz4810/gpiolib.c
+ *
+ * hlguo <hlguo@ingenic.cn>
+ *
+ * jz4810 GPIOlib 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/jzsoc.h>
+#include <asm/gpio.h>
+
+//#include <linux/gpio.h>
+
+struct jz4810_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *base;
+};
+
+static inline struct jz4810_gpio_chip *to_jz4810_chip(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct jz4810_gpio_chip, chip);
+}
+
+static void jz4810_gpiolib_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base +offset;
+ local_irq_save(flags);
+ __gpio_set_pin(n);
+ local_irq_restore(flags);
+}
+
+static int jz4810_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+ int state = -1;
+
+ n = chip->base +offset;
+ local_irq_save(flags);
+ state = __gpio_get_pin(n);
+ local_irq_restore(flags);
+ return state;
+
+}
+
+static int jz4810_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base +offset;
+ local_irq_save(flags);
+ __gpio_as_input(n);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int jz4810_gpiolib_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned long flags;
+ unsigned int n = 0;
+
+ n = chip->base +offset;
+ local_irq_save(flags);
+ __gpio_as_output(n);
+ if( value )
+ __gpio_set_pin(n);
+ else
+ __gpio_clear_pin(n);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int jz4810_gpio_request(struct gpio_chip *chip, const char *label)
+{
+ return 0;
+}
+
+static void jz4810_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ return;
+}
+
+static struct jz4810_gpio_chip jz4810_gpios[] = {
+ [0] = {
+ .base = (unsigned *)GPIO_BASEA,
+ .chip = {
+ .base = 0*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOA",
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+ [1] = {
+ .base = (unsigned *)GPIO_BASEB,
+ .chip = {
+ .base = 1*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOB",
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+ [2] = {
+ .base = (unsigned *)GPIO_BASEC,
+ .chip = {
+ .base = 2*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOC",
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+ [3] = {
+ .base = (unsigned *)GPIO_BASED,
+ .chip = {
+ .base = 3*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOD",
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+ [4] = {
+ .base = (unsigned *)GPIO_BASEE,
+ .chip = {
+ .base = 4*32,
+ .label = "GPIOE",
+ .owner = THIS_MODULE,
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+ [5] = {
+ .base = (unsigned *)GPIO_BASEF,
+ .chip = {
+ .base = 5*32,
+ .owner = THIS_MODULE,
+ .label = "GPIOF",
+ .ngpio = 32,
+ .direction_input = jz4810_gpiolib_input,
+ .direction_output = jz4810_gpiolib_output,
+ .set = jz4810_gpiolib_set,
+ .get = jz4810_gpiolib_get,
+ .request = jz4810_gpio_request,
+ .free = jz4810_gpio_free,
+ },
+ },
+};
+
+static __init int jz4810_gpiolib_init(void)
+{
+ struct jz4810_gpio_chip *chip = jz4810_gpios;
+ int gpn;
+
+ for (gpn = 0; gpn < ARRAY_SIZE(jz4810_gpios); gpn++, chip++)
+ gpiochip_add(&chip->chip);
+
+ return 0;
+}
+
+arch_initcall(jz4810_gpiolib_init);
diff --git a/arch/mips/jz4810/i2c.c b/arch/mips/jz4810/i2c.c
new file mode 100644
index 00000000000..429d9c6c2c8
--- /dev/null
+++ b/arch/mips/jz4810/i2c.c
@@ -0,0 +1,255 @@
+/*
+ * linux/arch/mips/jz4810/i2c.c
+ *
+ * Jz4810 I2C routines.
+ *
+ * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
+ * Author: <cwjia@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/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+#define TIMEOUT 1000
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x00000c00; \
+ REG_GPIO_PXTRGC(2) = 0x00000c00; \
+ REG_GPIO_PXSELS(2) = 0x00000c00; \
+} while (0)
+
+/*
+ * I2C interface
+ */
+
+static int i2c_disable()
+{
+ int timeout = 0xfffff, i = 100;
+
+ REG_I2C_ENB = 0; /*disable i2c*/
+ while((REG_I2C_ENSTA & 0x1) && (timeout > 0)) {
+ udelay(1);
+ timeout --;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+void i2c_open()
+{
+ __gpio_as_i2c();
+}
+
+void i2c_close(void)
+{
+}
+
+void i2c_setclk(unsigned int i2cclk)
+{
+
+}
+
+static void i2c_init_as_master(unsigned char address)
+{
+// __gpio_as_i2c();
+ if(i2c_disable())
+ printk("i2c not disable\n");
+// REG_I2C_CTRL = 0x43;
+ REG_I2C_CTRL = 0x45;
+ REG_I2C_TAR = address; /* slave id needed write only once */
+ REG_I2C_INTM = 0;
+ REG_I2C_FHCNT =49;
+ REG_I2C_FLCNT =62;
+// REG_I2C_SHCNT =0xc80; // 6k
+// REG_I2C_SLCNT =0xeb0; // 6k
+// REG_I2C_SHCNT =0x640; // 12k
+// REG_I2C_SLCNT =0x758; // 12k
+// REG_I2C_SHCNT =0x320; //26k
+// REG_I2C_SLCNT =0x3ac; //26k
+// REG_I2C_SHCNT =0x12c; //71k
+// REG_I2C_SLCNT =0x160; //71k
+// REG_I2C_SHCNT =0xc8;
+// REG_I2C_SLCNT =0xe8;
+ REG_I2C_ENB = 1; /*enable i2c*/
+}
+
+
+/* now for fpga test , count == 1 */
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ volatile int tmp;
+ int timeout = 0xffff;
+
+ i2c_init_as_master(device);
+
+ address = address & 0xff;
+
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_WRITE << 8) | address;
+
+ while(cnt) {
+ timeout = 0xffff;
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_READ << 8);
+#if 1
+ while((!(REG_I2C_STA & I2C_STA_RFNE)) && timeout) {
+ timeout--;
+ }
+#endif
+ if (!(timeout))
+ printk("***timeout*****************\n");
+
+ *buf = REG_I2C_DC & 0xff;
+
+ cnt--;
+ buf++;
+ }
+ return count - cnt;
+}
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt_in_pg,cnt = count;
+ unsigned char *tmpbuf;
+ unsigned char tmpaddr;
+ int timeout = 0xffff;
+ int rw = 0;
+
+
+ tmpbuf = (unsigned char *)buf;
+ tmpaddr = address;
+rewrite:
+ i2c_init_as_master(device);
+
+start_write_page:
+ cnt_in_pg = 0;
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("00***timeout*****************\n");
+
+ REG_I2C_DC = (I2C_WRITE << 8) | tmpaddr;
+#if 1
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+ while(cnt) {
+
+ timeout = 0xfffff;
+#if 1
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+
+ if (++cnt_in_pg > 16) { //8 or 16
+ mdelay(3);
+ tmpaddr += 16;
+ goto start_write_page;
+ }
+
+
+ while((!(REG_I2C_STA & I2C_STA_TFNF)) && timeout)
+ ;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ if(REG_I2C_TXABRT != 0)
+ printk("\n\nREG_I2C_TXABRT==0x%x\n",REG_I2C_TXABRT);
+
+ REG_I2C_DC = (I2C_WRITE << 8) | *tmpbuf;
+
+ rw = 0;
+ cnt--;
+ tmpbuf++;
+#if 1
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+#endif
+ }
+
+ timeout = 0xffff;
+ while(((REG_I2C_STA & I2C_STA_MSTACT)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("22***timeout*****************\n");
+
+ mdelay(2);
+ udelay(450);
+
+ if (REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) {
+ mdelay(3);
+ rw = 1;
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ return count - cnt;
+}
+
+EXPORT_SYMBOL(i2c_open);
+EXPORT_SYMBOL(i2c_close);
+EXPORT_SYMBOL(i2c_setclk);
+EXPORT_SYMBOL(i2c_read);
+EXPORT_SYMBOL(i2c_write);
diff --git a/arch/mips/jz4810/i2c_intr_debug.c b/arch/mips/jz4810/i2c_intr_debug.c
new file mode 100644
index 00000000000..73a8bcb81c2
--- /dev/null
+++ b/arch/mips/jz4810/i2c_intr_debug.c
@@ -0,0 +1,254 @@
+/*
+ * linux/arch/mips/jz4760/i2c.c
+ *
+ * Jz4810 I2C routines.
+ *
+ * Copyright (C) 2005,2006 Ingenic Semiconductor Inc.
+ * Author: <cwjia@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/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+
+#define TIMEOUT 1000
+
+static volatile int w_tfep = 0;
+static volatile int w_rfne = 0;
+static unsigned char *tmpbuf;
+static unsigned char tmpaddr;
+static int cnt;
+
+/*
+ * I2C_SCK, I2C_SDA
+ */
+#define __gpio_as_i2c() \
+do { \
+ REG_GPIO_PXFUNS(2) = 0x00000c00; \
+ REG_GPIO_PXTRGC(2) = 0x00000c00; \
+ REG_GPIO_PXSELS(2) = 0x00000c00; \
+} while (0)
+
+/*
+ * I2C interface
+ */
+
+static int i2c_disable()
+{
+ int timeout = 0xfffff, i = 100;
+
+ REG_I2C_ENB = 0; /*disable i2c*/
+ while((REG_I2C_ENSTA & 0x1) && (timeout > 0)) {
+ udelay(1);
+ timeout --;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+
+static irqreturn_t jz_i2chander(int irq, void *devid)
+{
+ if (REG_I2C_INTST & I2C_INTST_RXFL) {
+ w_rfne = 1;
+ REG_I2C_INTM = 0;
+ return IRQ_HANDLED;
+ }
+ REG_I2C_INTM = 0;
+ w_tfep = 1;
+ return IRQ_HANDLED;
+}
+
+void i2c_open()
+{
+ __gpio_as_i2c();
+ REG_I2C_RXTL = 0;
+ request_irq(IRQ_I2C,jz_i2chander,IRQF_DISABLED,0,0);
+}
+
+void i2c_close(void)
+{
+}
+
+void i2c_setclk(unsigned int i2cclk)
+{
+
+}
+
+static void i2c_init_as_master(unsigned char address)
+{
+ if(i2c_disable())
+ printk("i2c_disable error\n");
+// REG_I2C_CTRL = 0x43;
+ REG_I2C_CTRL = 0x45;
+ REG_I2C_TAR = address; /* slave id needed write only once */
+ REG_I2C_INTM = 0x10;
+ REG_I2C_FHCNT =49;
+ REG_I2C_FLCNT =62;
+ REG_I2C_RXTL = 0;
+// REG_I2C_SHCNT =0xc80; // 6k
+// REG_I2C_SLCNT =0xeb0; // 6k
+// REG_I2C_SHCNT =0x640; // 12k
+// REG_I2C_SLCNT =0x758; // 12k
+// REG_I2C_SHCNT =0x320; //26k
+// REG_I2C_SLCNT =0x3ac; //26k
+// REG_I2C_SHCNT =0x12c; //71k
+// REG_I2C_SLCNT =0x160; //71k
+// REG_I2C_SHCNT =0xc8;
+// REG_I2C_SLCNT =0xe8;
+ REG_I2C_ENB = 1; /*enable i2c*/
+}
+
+
+int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt = count;
+ volatile int tmp;
+ int timeout = 0xffff;
+
+ i2c_init_as_master(device);
+
+ address = address & 0xff;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+
+ REG_I2C_DC = (I2C_WRITE << 8) | address;
+
+ while(cnt) {
+ timeout = 0xffff;
+
+ REG_I2C_INTM = 0x10;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+ REG_I2C_DC = (I2C_READ << 8);
+ REG_I2C_INTM = 0x4;
+ while(!w_rfne)
+ ;
+
+ w_rfne = 0;
+
+ *buf = REG_I2C_DC & 0xff;
+
+ cnt--;
+ buf++;
+ }
+ return count - cnt;
+}
+
+int i2c_write(unsigned char device, unsigned char *buf,
+ unsigned char address, int count)
+{
+ int cnt_in_pg;
+ cnt = count;
+ int timeout = 0xffff;
+
+ tmpbuf = (unsigned char *)buf;
+ tmpaddr = address;
+
+rewrite:
+ i2c_init_as_master(device);
+
+start_write_page:
+ cnt_in_pg = 0;
+
+ while(!w_tfep)
+ ;
+ w_tfep = 0;
+
+ REG_I2C_DC = (I2C_WRITE << 8) | tmpaddr;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ REG_I2C_INTM = 0x10;
+
+ while(cnt) {
+
+ if (++cnt_in_pg > 16) { //8 or 16
+ mdelay(3);
+ tmpaddr += 16;
+ goto start_write_page;
+ }
+
+ while(!w_tfep)
+ ;
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK)) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ if(REG_I2C_TXABRT != 0)
+ printk("\n\nREG_I2C_TXABRT==0x%x\n",REG_I2C_TXABRT);
+
+ REG_I2C_DC = (I2C_WRITE << 8) | *tmpbuf;
+ REG_I2C_INTM = 0x10;
+
+ w_tfep = 0;
+ cnt--;
+ tmpbuf++;
+
+ if ((REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) || ( REG_I2C_STA & I2C_STA_TFE)) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+ }
+
+ timeout = 0xffff;
+ while(((REG_I2C_STA & I2C_STA_MSTACT)) && --timeout)
+ ;
+ if (!(timeout))
+ printk("***timeout*****************\n");
+ mdelay(2);
+ udelay(450);
+
+ if (REG_I2C_TXABRT & I2C_TXABRT_ABRT_7B_ADDR_NOACK) {
+ mdelay(3);
+ tmpbuf = (unsigned char *)buf;
+ cnt = 16;
+ int a = REG_I2C_CINTR;
+ goto rewrite;
+ }
+
+ return count - cnt;
+}
+
+EXPORT_SYMBOL(i2c_open);
+EXPORT_SYMBOL(i2c_close);
+EXPORT_SYMBOL(i2c_setclk);
+EXPORT_SYMBOL(i2c_read);
+EXPORT_SYMBOL(i2c_write);
diff --git a/arch/mips/jz4810/irq.c b/arch/mips/jz4810/irq.c
new file mode 100644
index 00000000000..dd83b7a153f
--- /dev/null
+++ b/arch/mips/jz4810/irq.c
@@ -0,0 +1,465 @@
+/*
+ * linux/arch/mips/jz4810/irq.c
+ *
+ * JZ4810 interrupt routines.
+ *
+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/jzsoc.h>
+
+/*
+ * INTC irq type
+ */
+
+static void enable_intc_irq(unsigned int irq)
+{
+ __intc_unmask_irq(irq);
+}
+
+static void disable_intc_irq(unsigned int irq)
+{
+ __intc_mask_irq(irq);
+}
+
+static void mask_and_ack_intc_irq(unsigned int irq)
+{
+ __intc_mask_irq(irq);
+ __intc_ack_irq(irq);
+}
+
+static void end_intc_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_intc_irq(irq);
+ }
+}
+
+static unsigned int startup_intc_irq(unsigned int irq)
+{
+ enable_intc_irq(irq);
+ return 0;
+}
+
+static void shutdown_intc_irq(unsigned int irq)
+{
+ disable_intc_irq(irq);
+}
+
+static struct irq_chip intc_irq_type = {
+ .typename = "INTC",
+ .startup = startup_intc_irq,
+ .shutdown = shutdown_intc_irq,
+ .unmask = enable_intc_irq,
+ .mask = disable_intc_irq,
+ .ack = mask_and_ack_intc_irq,
+ .end = end_intc_irq,
+};
+
+/*
+ * GPIO irq type
+ */
+
+static void enable_gpio_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < (IRQ_GPIO_0 + 32)) {
+ intc_irq = IRQ_GPIO0;
+ }
+ else if (irq < (IRQ_GPIO_0 + 64)) {
+ intc_irq = IRQ_GPIO1;
+ }
+ else if (irq < (IRQ_GPIO_0 + 96)) {
+ intc_irq = IRQ_GPIO2;
+ }
+ else if (irq < (IRQ_GPIO_0 + 128)) {
+ intc_irq = IRQ_GPIO3;
+ }
+ else if (irq < (IRQ_GPIO_0 + 160)) {
+ intc_irq = IRQ_GPIO4;
+ }
+ else {
+ intc_irq = IRQ_GPIO5;
+ }
+
+ enable_intc_irq(intc_irq);
+ __gpio_unmask_irq(irq - IRQ_GPIO_0);
+}
+
+static void disable_gpio_irq(unsigned int irq)
+{
+ __gpio_mask_irq(irq - IRQ_GPIO_0);
+}
+
+static void mask_and_ack_gpio_irq(unsigned int irq)
+{
+ __gpio_mask_irq(irq - IRQ_GPIO_0);
+ __gpio_ack_irq(irq - IRQ_GPIO_0);
+}
+
+static void end_gpio_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_gpio_irq(irq);
+ }
+}
+
+static unsigned int startup_gpio_irq(unsigned int irq)
+{
+ enable_gpio_irq(irq);
+ return 0;
+}
+
+static void shutdown_gpio_irq(unsigned int irq)
+{
+ disable_gpio_irq(irq);
+}
+
+static struct irq_chip gpio_irq_type = {
+ .typename = "GPIO",
+ .startup = startup_gpio_irq,
+ .shutdown = shutdown_gpio_irq,
+ .unmask = enable_gpio_irq,
+ .mask = disable_gpio_irq,
+ .ack = mask_and_ack_gpio_irq,
+ .end = end_gpio_irq,
+};
+
+/*
+ * DMA irq type
+ */
+
+static void enable_dma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_DMAC0;
+ else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */
+ intc_irq = IRQ_DMAC1;
+ else {
+ printk("%s, unexpected dma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __dmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_dma_irq(unsigned int irq)
+{
+ __dmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_dma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < (IRQ_DMA_0 + HALF_DMA_NUM) ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_DMAC0;
+ else if ( irq < (IRQ_DMA_0 + MAX_DMA_NUM) ) /* DMAC Group 1 irq */
+ intc_irq = IRQ_DMAC1;
+ else {
+ printk("%s, unexpected dma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __dmac_channel_ack_irq(irq-IRQ_DMA_0); /* needed?? add 20080506, Wolfgang */
+ __dmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void end_dma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_dma_irq(irq);
+ }
+}
+
+static unsigned int startup_dma_irq(unsigned int irq)
+{
+ enable_dma_irq(irq);
+ return 0;
+}
+
+static void shutdown_dma_irq(unsigned int irq)
+{
+ disable_dma_irq(irq);
+}
+
+static struct irq_chip dma_irq_type = {
+ .typename = "DMA",
+ .startup = startup_dma_irq,
+ .shutdown = shutdown_dma_irq,
+ .unmask = enable_dma_irq,
+ .mask = disable_dma_irq,
+ .ack = mask_and_ack_dma_irq,
+ .end = end_dma_irq,
+};
+
+/*
+ * MDMA irq type
+ */
+
+static void enable_mdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < IRQ_MDMA_0 + MAX_MDMA_NUM) /* DMAC Group 0 irq */
+ intc_irq = IRQ_MDMA;
+ else {
+ printk("%s, unexpected mdma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __mdmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_mdma_irq(unsigned int irq)
+{
+ __mdmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_mdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < IRQ_MDMA_0 + MAX_MDMA_NUM ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_MDMA;
+ else {
+ printk("%s, unexpected mdma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __mdmac_channel_ack_irq(irq-IRQ_MDMA_0); /* needed?? add 20080506, Wolfgang */
+ __mdmac_channel_disable_irq(irq - IRQ_MDMA_0);
+}
+
+static void end_mdma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_mdma_irq(irq);
+ }
+}
+
+static unsigned int startup_mdma_irq(unsigned int irq)
+{
+ enable_mdma_irq(irq);
+ return 0;
+}
+
+static void shutdown_mdma_irq(unsigned int irq)
+{
+ disable_mdma_irq(irq);
+}
+
+static struct irq_chip mdma_irq_type = {
+ .typename = "MDMA",
+ .startup = startup_mdma_irq,
+ .shutdown = shutdown_mdma_irq,
+ .unmask = enable_mdma_irq,
+ .mask = disable_mdma_irq,
+ .ack = mask_and_ack_mdma_irq,
+ .end = end_mdma_irq,
+};
+
+//----------------------------------------------------------------------
+
+/*
+ * BDMA irq type
+ */
+
+static void enable_bdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if (irq < IRQ_BDMA_0 + MAX_BDMA_NUM)
+ intc_irq = IRQ_BDMA;
+ else {
+ printk("%s, unexpected bdma irq #%d\n", __FILE__, irq);
+ return;
+ }
+ __intc_unmask_irq(intc_irq);
+ __bdmac_channel_enable_irq(irq - IRQ_DMA_0);
+}
+
+static void disable_bdma_irq(unsigned int irq)
+{
+ __bdmac_channel_disable_irq(irq - IRQ_DMA_0);
+}
+
+static void mask_and_ack_bdma_irq(unsigned int irq)
+{
+ unsigned int intc_irq;
+
+ if ( irq < IRQ_BDMA_0 + MAX_BDMA_NUM ) /* DMAC Group 0 irq */
+ intc_irq = IRQ_BDMA;
+ else {
+ printk("%s, unexpected bdma irq #%d\n", __FILE__, irq);
+ return ;
+ }
+ __intc_ack_irq(intc_irq);
+ __bdmac_channel_ack_irq(irq - IRQ_BDMA_0);
+ __bdmac_channel_disable_irq(irq - IRQ_BDMA_0);
+}
+
+static void end_bdma_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+ enable_bdma_irq(irq);
+ }
+}
+
+static unsigned int startup_bdma_irq(unsigned int irq)
+{
+ enable_bdma_irq(irq);
+ return 0;
+}
+
+static void shutdown_bdma_irq(unsigned int irq)
+{
+ disable_bdma_irq(irq);
+}
+
+static struct irq_chip bdma_irq_type = {
+ .typename = "BDMA",
+ .startup = startup_bdma_irq,
+ .shutdown = shutdown_bdma_irq,
+ .unmask = enable_bdma_irq,
+ .mask = disable_bdma_irq,
+ .ack = mask_and_ack_bdma_irq,
+ .end = end_bdma_irq,
+};
+
+//----------------------------------------------------------------------
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ clear_c0_status(0xff04); /* clear ERL */
+ set_c0_status(0x0400); /* set IP2 */
+
+ /* Set up INTC irq
+ */
+ for (i = 0; i < NUM_INTC; i++) {
+ disable_intc_irq(i);
+ set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+ }
+
+ /* Set up DMAC irq
+ */
+ for (i = 0; i < NUM_DMA; i++) {
+ disable_dma_irq(IRQ_DMA_0 + i);
+ set_irq_chip_and_handler(IRQ_DMA_0 + i, &dma_irq_type, handle_level_irq);
+ }
+
+ /* Set up MDMAC irq
+ */
+ for (i = 0; i < NUM_MDMA; i++) {
+ disable_mdma_irq(IRQ_MDMA_0 + i);
+ set_irq_chip_and_handler(IRQ_MDMA_0 + i, &mdma_irq_type, handle_level_irq);
+ }
+
+ /* Set up BDMA irq
+ */
+ for (i = 0; i < MAX_BDMA_NUM; i++) {
+ disable_bdma_irq(IRQ_BDMA_0 + i);
+ set_irq_chip_and_handler(IRQ_MDMA_0 + i, &bdma_irq_type, handle_level_irq);
+ }
+
+ /* Set up GPIO irq
+ */
+#if 1
+// for (i = 0; i < NUM_GPIO; i++) {
+ for (i = 0; i < 90; i++) {
+ disable_gpio_irq(IRQ_GPIO_0 + i);
+ set_irq_chip_and_handler(IRQ_GPIO_0 + i, &gpio_irq_type, handle_level_irq);
+ }
+#endif
+
+}
+
+static int plat_real_irq(int irq)
+{
+ switch (irq) {
+ case IRQ_GPIO0:
+ irq = __gpio_group_irq(0) + IRQ_GPIO_0;
+ break;
+ case IRQ_GPIO1:
+ irq = __gpio_group_irq(1) + IRQ_GPIO_0 + 32;
+ break;
+ case IRQ_GPIO2:
+ irq = __gpio_group_irq(2) + IRQ_GPIO_0 + 64;
+ break;
+ case IRQ_GPIO3:
+ irq = __gpio_group_irq(3) + IRQ_GPIO_0 + 96;
+ break;
+ case IRQ_GPIO4:
+ irq = __gpio_group_irq(4) + IRQ_GPIO_0 + 128;
+ break;
+ case IRQ_GPIO5:
+ irq = __gpio_group_irq(5) + IRQ_GPIO_0 + 160;
+ break;
+ case IRQ_DMAC0:
+ case IRQ_DMAC1:
+ irq = __dmac_get_irq() + IRQ_DMA_0;
+ break;
+ case IRQ_MDMA:
+ irq = __mdmac_get_irq() + IRQ_MDMA_0;
+ break;
+ case IRQ_BDMA:
+ irq = __bdmac_get_irq() + IRQ_BDMA_0;
+ break;
+ }
+
+ return irq;
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ int irq = 0;
+
+ static unsigned long intc_ipr0 = 0, intc_ipr1 = 0;
+
+ intc_ipr0 |= REG_INTC_IPR(0);
+ intc_ipr1 |= REG_INTC_IPR(1);
+
+ if (!(intc_ipr0 || intc_ipr1)) return;
+
+ if (intc_ipr0) {
+ irq = ffs(intc_ipr0) - 1;
+ intc_ipr0 &= ~(1<<irq);
+ } else {
+ irq = ffs(intc_ipr1) - 1;
+ intc_ipr1 &= ~(1<<irq);
+ irq += 32;
+ }
+
+ irq = plat_real_irq(irq);
+ do_IRQ(irq);
+}
diff --git a/arch/mips/jz4810/platform.c b/arch/mips/jz4810/platform.c
new file mode 100644
index 00000000000..fccb72b91c3
--- /dev/null
+++ b/arch/mips/jz4810/platform.c
@@ -0,0 +1,364 @@
+/*
+ * Platform device support for Jz4810 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>
+
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+
+#include <asm/jzsoc.h>
+
+#include <linux/usb/musb.h>
+
+extern void __init board_msc_init(void);
+
+
+/* OHCI (USB full speed host controller) */
+static struct resource jz_usb_ohci_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(UHC_BASE), // phys addr for ioremap
+ .end = CPHYSADDR(UHC_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_UHC,
+ .end = IRQ_UHC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct platform_device jz_usb_ohci_device = {
+ .name = "jz-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_usb_ohci_resources),
+ .resource = jz_usb_ohci_resources,
+};
+
+/*** LCD controller ***/
+static struct resource jz_lcd_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(LCD_BASE),
+ .end = CPHYSADDR(LCD_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 jz_lcd_dmamask = ~(u32)0;
+
+static struct platform_device jz_lcd_device = {
+ .name = "jz-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_lcd_resources),
+ .resource = jz_lcd_resources,
+};
+
+/* USB OTG Controller */
+static struct platform_device jz_usb_otg_xceiv_device = {
+ .name = "nop_usb_xceiv",
+ .id = 0,
+};
+
+static struct musb_hdrc_config jz_usb_otg_config = {
+ .multipoint = 1,
+ .dyn_fifo = 0,
+ .soft_con = 1,
+ .dma = 1,
+/* Max EPs scanned. Driver will decide which EP can be used automatically. */
+ .num_eps = 16,
+};
+
+static struct musb_hdrc_platform_data jz_usb_otg_platform_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ .config = &jz_usb_otg_config,
+};
+
+static struct resource jz_usb_otg_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(UDC_BASE),
+ .end = CPHYSADDR(UDC_BASE) + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_OTG,
+ .end = IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 usb_otg_dmamask = ~(u32)0;
+
+static struct platform_device jz_usb_otg_device = {
+ .name = "musb_hdrc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &usb_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &jz_usb_otg_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(jz_usb_otg_resources),
+ .resource = jz_usb_otg_resources,
+};
+
+/** MMC/SD controller MSC0**/
+static struct resource jz_msc0_resources[] = {
+ {
+ .start = CPHYSADDR(MSC0_BASE),
+ .end = CPHYSADDR(MSC0_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC0,
+ .end = IRQ_MSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC0_RX,
+ .end = DMA_ID_MSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 jz_msc0_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc0_device = {
+ .name = "jz-msc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_msc0_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc0_resources),
+ .resource = jz_msc0_resources,
+};
+
+/** MMC/SD controller MSC1**/
+static struct resource jz_msc1_resources[] = {
+ {
+ .start = CPHYSADDR(MSC1_BASE),
+ .end = CPHYSADDR(MSC1_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_MSC1,
+ .end = IRQ_MSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DMA_ID_MSC1_RX,
+ .end = DMA_ID_MSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+
+};
+
+static u64 jz_msc1_dmamask = ~(u32)0;
+
+static struct platform_device jz_msc1_device = {
+ .name = "jz-msc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &jz_msc1_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_msc1_resources),
+ .resource = jz_msc1_resources,
+};
+
+static struct platform_device *jz_msc_devices[] __initdata = {
+ &jz_msc0_device,
+ &jz_msc1_device,
+};
+
+/*
+int __init jz_add_msc_devices(unsigned int controller, struct jz_mmc_platform_data *plat)
+{
+ struct platform_device *pdev;
+
+ if (controller < 0 || controller > 1)
+ return -EINVAL;
+
+ pdev = jz_msc_devices[controller];
+
+ pdev->dev.platform_data = plat;
+
+ return platform_device_register(pdev);
+}
+*/
+
+/* + Sound device */
+/*
+#define SND(num, desc) { .name = desc, .id = num }
+static struct snd_endpoint snd_endpoints_list[] = {
+ SND(0, "HANDSET"),
+ SND(1, "SPEAKER"),
+ SND(2, "HEADSET"),
+};
+#undef SND
+*/
+
+/*
+static struct msm_snd_endpoints jz_snd_endpoints = {
+ .endpoints = snd_endpoints_list,
+ .num = ARRAY_SIZE(snd_endpoints_list),
+};
+*/
+
+/*
+static struct platform_device jz_snd_device = {
+ .name = "mixer",
+ .id = -1,
+ .dev = {
+ .platform_data = &jz_snd_endpoints,
+ },
+};
+*/
+/* - Sound device */
+
+static struct resource jz_i2c0_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(I2C0_BASE),
+ .end = CPHYSADDR(I2C0_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource jz_i2c1_resources[] = {
+ [0] = {
+ .start = CPHYSADDR(I2C1_BASE),
+ .end = CPHYSADDR(I2C1_BASE) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 jz_i2c_dmamask = ~(u32)0;
+
+static struct platform_device jz_i2c0_device = {
+ .name = "jz_i2c0",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz_i2c_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_i2c0_resources),
+ .resource = jz_i2c0_resources,
+};
+
+static struct platform_device jz_i2c1_device = {
+ .name = "jz_i2c1",
+ .id = 1,
+ .dev = {
+ .dma_mask = &jz_i2c_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(jz_i2c1_resources),
+ .resource = jz_i2c1_resources,
+};
+
+/* All */
+static struct platform_device *jz_platform_devices[] __initdata = {
+ &jz_usb_ohci_device,
+ &jz_usb_otg_xceiv_device,
+ &jz_usb_otg_device,
+ &jz_lcd_device,
+// &jz_snd_device,
+ &jz_i2c0_device,
+ &jz_i2c1_device,
+};
+
+#ifdef CONFIG_ANDROID_PMEM
+/* ================================================================== */
+/* pmem */
+#if 0
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 1,
+ .start = 0x07800000, /* Low 512M mem */
+// .start = 0x2F800000, /* upper 512M mem */
+ .size = 0x1000000, /* pmem size 16M */
+};
+#else
+/* [VIVANTE] PMEM devices. */
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 1,
+};
+
+static struct android_pmem_platform_data pmem_adsp_pdata = {
+ .name = "pmem_adsp",
+ .no_allocator = 0,
+ .cached = 1,
+};
+
+#endif
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = { .platform_data = &pmem_pdata },
+};
+
+static struct platform_device pmem_adsp_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = { .platform_data = &pmem_adsp_pdata },
+};
+
+
+static void platform_pmem_device_setup(void)
+{
+// platform_device_register(&pmem_device);
+ platform_device_register(&pmem_adsp_device);
+}
+
+#endif /* #ifdef CONFIG_ANDROID_PMEM */
+
+
+static int __init jz_platform_init(void)
+{
+ int ret = platform_add_devices(jz_platform_devices, ARRAY_SIZE(jz_platform_devices));
+#ifdef CONFIG_ANDROID_PMEM
+ platform_pmem_device_setup();
+#endif
+
+ printk("jz_platform_init\n");
+// board_msc_init();
+ return ret;
+}
+
+arch_initcall(jz_platform_init);
diff --git a/arch/mips/jz4810/pm.c b/arch/mips/jz4810/pm.c
new file mode 100644
index 00000000000..c0ce01f3086
--- /dev/null
+++ b/arch/mips/jz4810/pm.c
@@ -0,0 +1,518 @@
+/*
+ * linux/arch/mips/jz4810/common/pm.c
+ *
+ * JZ4810 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/sched.h>
+#include <linux/interrupt.h>
+#include <linux/suspend.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+
+#include <asm/cacheops.h>
+#include <asm/jzsoc.h>
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+#define GPIO_PORT_NUM 6
+
+extern void jz_cpu_sleep(void);
+extern void jz_cpu_resume(void);
+
+/*
+ * __gpio_as_sleep set all pins to pull-disable, and set all pins as input
+ * except sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+#define __gpio_as_sleep() \
+do { \
+ REG_GPIO_PXFUNC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXSELC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXDIRC(1) = ~0x03ff7fff; \
+ REG_GPIO_PXPES(1) = 0xffffffff; \
+ REG_GPIO_PXFUNC(2) = ~0x01e00000; \
+ REG_GPIO_PXSELC(2) = ~0x01e00000; \
+ REG_GPIO_PXDIRC(2) = ~0x01e00000; \
+ REG_GPIO_PXPES(2) = 0xffffffff; \
+ REG_GPIO_PXFUNC(3) = 0xffffffff; \
+ REG_GPIO_PXSELC(3) = 0xffffffff; \
+ REG_GPIO_PXDIRC(3) = 0xffffffff; \
+ REG_GPIO_PXPES(3) = 0xffffffff; \
+ REG_GPIO_PXFUNC(4) = 0xffffffff; \
+ REG_GPIO_PXSELC(4) = 0xffffffff; \
+ REG_GPIO_PXDIRC(4) = 0xffffffff; \
+ REG_GPIO_PXPES(4) = 0xffffffff; \
+ REG_GPIO_PXFUNC(5) = 0xffffffff; \
+ REG_GPIO_PXSELC(5) = 0xffffffff; \
+ REG_GPIO_PXDIRC(5) = 0xffffffff; \
+ REG_GPIO_PXPES(5) = 0xffffffff; \
+} while (0)
+
+
+static int jz_pm_do_hibernate(void)
+{
+ printk("Put CPU into hibernate mode.\n");
+
+ /* Mask all interrupts */
+ REG_INTC_IMSR(0) = 0xffffffff;
+ REG_INTC_IMSR(1) = 0xffffffff;
+
+ /*
+ * RTC Wakeup or 1Hz interrupt can be enabled or disabled
+ * through RTC driver's ioctl (linux/driver/char/rtc_jz.c).
+ */
+#if 0
+ /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ REG_RTC_HWFCR = (100 << RTC_HWFCR_BIT);
+
+ /* Set reset pin low-level assertion time after wakeup: must > 60ms */
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ REG_RTC_HRCR = (60 << RTC_HRCR_BIT); /* 60 ms */
+
+ /* Scratch pad register to be reserved */
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ REG_RTC_HSPR = 0x12345678;
+
+ /* clear wakeup status register */
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ REG_RTC_HWRSR = 0x0;
+
+ /* Put CPU to power down mode */
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ REG_RTC_HCR = RTC_HCR_PD;
+
+ while (!(REG_RTC_RCR & RTC_RCR_WRDY));
+ while(1);
+#endif
+
+ /* We can't get here */
+ return 0;
+}
+
+/* NOTES:
+ * 1: Pins that are floated (NC) should be set as input and pull-enable.
+ * 2: Pins that are pull-up or pull-down by outside should be set as input
+ * and pull-disable.
+ * 3: Pins that are connected to a chip except sdram and nand flash
+ * should be set as input and pull-disable, too.
+ */
+static void jz_board_do_sleep(unsigned long *ptr)
+{
+#if 0
+ unsigned char i;
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("run dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+
+ /* Save GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ *ptr++ = REG_GPIO_PXFUN(i);
+ *ptr++ = REG_GPIO_PXSEL(i);
+ *ptr++ = REG_GPIO_PXDIR(i);
+ *ptr++ = REG_GPIO_PXPE(i);
+ *ptr++ = REG_GPIO_PXIM(i);
+ *ptr++ = REG_GPIO_PXDAT(i);
+ *ptr++ = REG_GPIO_PXTRG(i);
+ }
+
+ /*
+ * Set all pins to pull-disable, and set all pins as input except
+ * sdram and the pins which can be used as CS1_N to CS4_N for chip select.
+ */
+ __gpio_as_sleep();
+
+ /*
+ * Set proper status for GPC21 to GPC24 which can be used as CS1_N to CS4_N.
+ * Keep the pins' function used for chip select(CS) here according to your
+ * system to avoid chip select crashing with sdram when resuming from sleep mode.
+ */
+
+#if defined(CONFIG_JZ4810_APUS)
+ /* GPB25/CS1_N is used as chip select for nand flash, shouldn't be change. */
+
+ /* GPB26/CS2_N is connected to nand flash, needn't be changed. */
+
+ /* GPB28/CS3_N is used as cs8900's chip select, shouldn't be changed. */
+
+ /* GPB27/CS4_N is used as NOR's chip select, shouldn't be changed. */
+#endif
+
+ /*
+ * Enable pull for NC pins here according to your system
+ */
+
+#if defined(CONFIG_JZ4810_APUS)
+#endif
+
+ /*
+ * If you must set some GPIOs as output to high level or low level,
+ * you can set them here, using:
+ * __gpio_as_output(n);
+ * __gpio_set_pin(n); or __gpio_clear_pin(n);
+ */
+
+#if defined(CONFIG_JZ4810_APUS)
+ /* GPC7 which is used as AMPEN_N should be set to high to disable audio amplifier */
+ __gpio_as_output(32*2+7);
+ __gpio_set_pin(32*2+7);
+#endif
+
+#ifdef DEBUG
+ /* Keep uart function for printing debug message */
+ __gpio_as_uart0();
+ __gpio_as_uart1();
+ __gpio_as_uart2();
+ __gpio_as_uart3();
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("sleep dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+#endif
+#endif
+}
+
+static void jz_board_do_resume(unsigned long *ptr)
+{
+#if 0
+ unsigned char i;
+
+ /* Restore GPIO registers */
+ for(i = 1; i < GPIO_PORT_NUM; i++) {
+ REG_GPIO_PXFUNS(i) = *ptr;
+ REG_GPIO_PXFUNC(i) = ~(*ptr++);
+
+ REG_GPIO_PXSELS(i) = *ptr;
+ REG_GPIO_PXSELC(i) = ~(*ptr++);
+
+ REG_GPIO_PXDIRS(i) = *ptr;
+ REG_GPIO_PXDIRC(i) = ~(*ptr++);
+
+ REG_GPIO_PXPES(i) = *ptr;
+ REG_GPIO_PXPEC(i) = ~(*ptr++);
+
+ REG_GPIO_PXIMS(i)=*ptr;
+ REG_GPIO_PXIMC(i)=~(*ptr++);
+
+ REG_GPIO_PXDATS(i)=*ptr;
+ REG_GPIO_PXDATC(i)=~(*ptr++);
+
+ REG_GPIO_PXTRGS(i)=*ptr;
+ REG_GPIO_PXTRGC(i)=~(*ptr++);
+ }
+
+ /* Print messages of GPIO registers for debug */
+ for(i=0;i<GPIO_PORT_NUM;i++) {
+ dprintk("resume dat:%x pin:%x fun:%x sel:%x dir:%x pull:%x msk:%x trg:%x\n", \
+ REG_GPIO_PXDAT(i),REG_GPIO_PXPIN(i),REG_GPIO_PXFUN(i),REG_GPIO_PXSEL(i), \
+ REG_GPIO_PXDIR(i),REG_GPIO_PXPE(i),REG_GPIO_PXIM(i),REG_GPIO_PXTRG(i));
+ }
+#endif
+}
+
+static int jz_pm_do_sleep(void)
+{
+#if 0
+ unsigned long delta;
+ unsigned long nfcsr = REG_EMC_NFCSR;
+ unsigned long opcr = REG_CPM_OPCR;
+ unsigned long imr0 = REG_INTC_IMR(0);
+ unsigned long imr1 = REG_INTC_IMR(1);
+ unsigned long sadc = REG_SADC_ENA;
+ unsigned long pmembs0 = REG_EMC_PMEMBS0;
+ unsigned long sleep_gpio_save[7*(GPIO_PORT_NUM-1)];
+ unsigned long cpuflags;
+
+ printk("Put CPU into sleep mode.\n");
+#if 0
+ /* Enter SLEEP mode */
+ lcr &= ~CPM_LCR_LPM_MASK;
+ lcr |= CPM_LCR_LPM_SLEEP;
+ REG_CPM_LCR = lcr;
+#endif
+ /* Preserve current time */
+ delta = xtime.tv_sec - REG_RTC_RSR;
+
+ /* Save CPU irqs */
+ local_irq_save(cpuflags);
+
+ /* Disable nand flash */
+ REG_EMC_NFCSR = ~0xff;
+
+ /*pull up enable pin of DQS */
+ REG_EMC_PMEMBS0 |= (0xff << 8);
+
+ /* stop sadc */
+ REG_SADC_ENA &= ~0x7;
+ while((REG_SADC_ENA & 0x7) != 0);
+ udelay(100);
+
+ /*stop udc and usb*/
+ __cpm_suspend_uhc_phy();
+ __cpm_suspend_otg_phy();
+
+ /*stop gps*/
+ __cpm_suspend_gps();
+
+ /* Mask all interrupts */
+ REG_INTC_IMSR(0) = 0xffffffff;
+ REG_INTC_IMSR(1) = 0xffffffff;
+
+ /* Sleep on-board modules */
+ jz_board_do_sleep(sleep_gpio_save);
+
+#if 0
+ /* Just allow following interrupts to wakeup the system.
+ * Note: modify this according to your system.
+ */
+
+ /* enable RTC alarm */
+ __intc_unmask_irq(IRQ_RTC);
+
+ /* make system wake up after n seconds by RTC alarm */
+ unsigned int v, n;
+ n = 5;
+ while (!__rtc_write_ready());
+ __rtc_enable_alarm();
+ while (!__rtc_write_ready());
+ __rtc_enable_alarm_irq();
+ while (!__rtc_write_ready());
+ v = __rtc_get_second();
+ while (!__rtc_write_ready());
+ __rtc_set_alarm_second(v+n);
+
+
+#endif
+ /* WAKEUP key */
+ __gpio_as_irq_rise_edge(GPIO_WAKEUP);
+ __gpio_unmask_irq(GPIO_WAKEUP);
+ __intc_unmask_irq(IRQ_GPIO0 - (GPIO_WAKEUP/32)); /* unmask IRQ_GPIOn depends on GPIO_WAKEUP */
+
+ /*power down the p0*/
+ REG_CPM_OPCR |= CPM_OPCR_PD;
+
+ /* disable externel clock Oscillator in sleep mode */
+ __cpm_disable_osc_in_sleep();
+ /* select 32K crystal as RTC clock in sleep mode */
+ __cpm_select_rtcclk_rtc();
+
+ /* Clear previous reset status */
+ REG_CPM_RSR &= ~(CPM_RSR_PR | CPM_RSR_WR | CPM_RSR_P0R);
+
+ /* Set resume return address */
+ REG_CPM_CPPSR = virt_to_phys(jz_cpu_resume);
+
+ /* *** go zzz *** */
+ jz_cpu_sleep();
+
+#if 0
+ __asm__(".set\tmips3\n\t"
+ "sync\n\t"
+ "wait\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tmips0");
+
+ /* Restore to IDLE mode */
+ lcr = REG_CPM_LCR;
+ lcr &= ~CPM_LCR_LPM_MASK;
+ lcr |= CPM_LCR_LPM_IDLE;
+ REG_CPM_LCR = lcr;
+#endif
+
+ /*return from sleep.S*/
+
+ /* Restore nand flash control register */
+ REG_EMC_NFCSR = nfcsr;
+
+ /*Restore pmembs0*/
+ REG_EMC_PMEMBS0 = pmembs0;
+
+ /* Restore interrupts */
+ REG_INTC_IMSR(0) = imr0;
+ REG_INTC_IMSR(1) = imr1;
+
+ REG_INTC_IMCR(0) = ~imr0;
+ REG_INTC_IMCR(1) = ~imr1;
+
+ /* Restore sadc */
+ REG_SADC_ENA = sadc;
+
+ /* Resume on-board modules */
+ jz_board_do_resume(sleep_gpio_save);
+
+ /* Restore Oscillator and Power Control Register */
+ REG_CPM_OPCR = opcr;
+
+ /* Restore CPU interrupt flags */
+ local_irq_restore(cpuflags);
+
+ /* Restore current time */
+ xtime.tv_sec = REG_RTC_RSR + delta;
+
+ printk("Resume CPU from sleep mode.\n");
+#endif
+ return 0;
+}
+
+#define K0BASE KSEG0
+void jz_flush_cache_all(void)
+{
+ unsigned long addr;
+
+ /* Clear CP0 TagLo */
+ asm volatile ("mtc0 $0, $28\n\t"::);
+
+ for (addr = K0BASE; addr < (K0BASE + 0x4000); addr += 32) {
+ asm volatile (
+ ".set mips3\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips2\n\t"
+ :
+ : "I" (Index_Writeback_Inv_D), "r"(addr));
+
+ asm volatile (
+ ".set mips3\n\t"
+ " cache %0, 0(%1)\n\t"
+ ".set mips2\n\t"
+ :
+ : "I" (Index_Store_Tag_I), "r"(addr));
+ }
+
+ asm volatile ("sync\n\t"::);
+
+ /* invalidate BTB */
+ 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"
+ ".set mips2\n\t"
+ :
+ : "r"(addr));
+}
+
+#if 0
+#ifndef CONFIG_JZ_POWEROFF
+static irqreturn_t pm_irq_handler (int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+#endif
+
+/* Put CPU to SLEEP mode */
+int jz_pm_sleep(void)
+{
+ int retval;
+
+#ifndef CONFIG_JZ_POWEROFF
+ if ((retval = request_irq (IRQ_GPIO_0 + GPIO_WAKEUP, pm_irq_handler, IRQF_DISABLED,
+ "PM", NULL))) {
+ printk ("PM could not get IRQ for GPIO_WAKEUP\n");
+ return retval;
+ }
+#endif
+
+ retval = jz_pm_do_sleep();
+
+#ifndef CONFIG_JZ_POWEROFF
+ free_irq (IRQ_GPIO_0 + GPIO_WAKEUP, NULL);
+#endif
+
+ return retval;
+}
+#endif
+
+/* Put CPU to HIBERNATE mode
+ *----------------------------------------------------------------------------
+ * Power Management sleep sysctl interface
+ *
+ * Write "mem" to /sys/power/state invokes this function
+ * which initiates a poweroff.
+ */
+void jz_pm_hibernate(void)
+{
+ jz_pm_do_hibernate();
+}
+
+/* Put CPU to SLEEP mode
+ *----------------------------------------------------------------------------
+ * Power Management sleep sysctl interface
+ *
+ * Write "standby" to /sys/power/state invokes this function
+ * which initiates a sleep.
+ */
+
+int jz_pm_sleep(void)
+{
+ return jz_pm_do_sleep();
+}
+
+/*
+ * valid states, only support standby(sleep) and mem(hibernate)
+ */
+static int jz4810_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM;
+}
+
+/*
+ * Jz CPU enter save power mode
+ */
+static int jz4810_pm_enter(suspend_state_t state)
+{
+ return jz_pm_do_sleep();
+}
+
+static struct platform_suspend_ops jz4810_pm_ops = {
+ .valid = jz4810_pm_valid,
+ .enter = jz4810_pm_enter,
+};
+
+/*
+ * Initialize power interface
+ */
+int __init jz_pm_init(void)
+{
+ printk("Power Management for JZ\n");
+
+ suspend_set_ops(&jz4810_pm_ops);
+ return 0;
+}
+
diff --git a/arch/mips/jz4810/proc.c b/arch/mips/jz4810/proc.c
new file mode 100644
index 00000000000..ba84579b1d8
--- /dev/null
+++ b/arch/mips/jz4810/proc.c
@@ -0,0 +1,916 @@
+/*
+ * linux/arch/mips/jz4810/proc.c
+ *
+ * /proc/jz/ procfs for jz4810 on-chip modules.
+ *
+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/page-flags.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/jzsoc.h>
+
+//#define DEBUG 1
+#undef DEBUG
+
+extern void jz4810_fpu_init(unsigned int round);
+
+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, "AUX_CPU : %s\n",
+ (clkgr & CPM_CLKGR_AUX_CPU) ? "stopped" : "running");
+ len += sprintf (page+len, "AHB1 : %s\n",
+ (clkgr & CPM_CLKGR_AHB1) ? "stopped" : "running");
+ len += sprintf (page+len, "IDCT : %s\n",
+ (clkgr & CPM_CLKGR_IDCT) ? "stopped" : "running");
+ len += sprintf (page+len, "DB : %s\n",
+ (clkgr & CPM_CLKGR_DB) ? "stopped" : "running");
+ len += sprintf (page+len, "ME : %s\n",
+ (clkgr & CPM_CLKGR_ME) ? "stopped" : "running");
+ len += sprintf (page+len, "MC : %s\n",
+ (clkgr & CPM_CLKGR_MC) ? "stopped" : "running");
+ len += sprintf (page+len, "TVE : %s\n",
+ (clkgr & CPM_CLKGR_TVE) ? "stopped" : "running");
+ len += sprintf (page+len, "TSSI : %s\n",
+ (clkgr & CPM_CLKGR_TSSI) ? "stopped" : "running");
+ 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, "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, "MSC0 : %s\n",
+ (clkgr & CPM_CLKGR_MSC0) ? "stopped" : "running");
+ len += sprintf (page+len, "MSC1 : %s\n",
+ (clkgr & CPM_CLKGR_MSC1) ? "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, "H2CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_h2clk()));
+ 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_otgclk()));
+ len += sprintf (page+len, "MSC0CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(0)));
+ len += sprintf (page+len, "MSC1CLK : %3d.%02d MHz\n", TO_MHZ(__cpm_get_mscclk(1)));
+ len += sprintf (page+len, "EXTALCLK0 : %3d.%02d MHz\n", TO_MHZ(__cpm_get_extalclk0()));
+ len += sprintf (page+len, "EXTALCLK(by CPM): %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;
+}
+
+
+/* USAGE:
+ * echo n > /proc/jz/ipu // n = [1,...,9], alloc mem, 2^n pages.
+ * echo FF > /proc/jz/ipu // 255, free all buffer
+ * echo xxxx > /proc/jz/ipu // free buffer which addr is xxxx
+ * echo llll > /proc/jz/ipu // add_wired_entry(l,l,l,l)
+ * echo 0 > /proc/jz/ipu // debug, print ipu_buf
+ * od -X /proc/jz/ipu // read mem addr
+ */
+
+typedef struct _ipu_buf {
+ unsigned int addr; /* phys addr */
+ unsigned int page_shift;
+} ipu_buf_t;
+
+#define IPU_BUF_MAX 4 /* 4 buffers */
+
+static struct _ipu_buf ipu_buf[IPU_BUF_MAX];
+static int ipu_buf_cnt = 0;
+static unsigned char g_asid=0;
+
+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);
+}
+
+static void ipu_add_wired_entry(unsigned long pid,
+ unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask)
+{
+ unsigned long flags;
+ unsigned long wired;
+ unsigned long old_pagemask;
+ unsigned long old_ctx;
+ struct task_struct *g, *p;
+
+ /* We will lock an 4MB page size entry to map the 4MB reserved IPU memory */
+ wired = read_c0_wired();
+ if (wired) return;
+
+ do_each_thread(g, p) {
+ if (p->pid == pid )
+ g_asid = p->mm->context[0];
+ } while_each_thread(g, p);
+
+
+ local_irq_save(flags);
+
+ entrylo0 = entrylo0 >> 6; /* PFN */
+ entrylo0 |= 0x6 | (0 << 3); /* Write-through cacheable, dirty, valid */
+
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi() & 0xff;
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
+ write_c0_wired(wired + 1);
+ write_c0_index(wired);
+ BARRIER;
+ entryhi &= ~0xff; /* new add, 20070906 */
+ entryhi |= g_asid; /* new add, 20070906 */
+// entryhi |= old_ctx; /* new add, 20070906 */
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
+ BARRIER;
+ tlb_write_indexed();
+ BARRIER;
+
+ write_c0_entryhi(old_ctx);
+ BARRIER;
+ write_c0_pagemask(old_pagemask);
+ local_flush_tlb_all();
+ local_irq_restore(flags);
+#if defined(DEBUG)
+ printk("\nold_ctx=%03d\n", old_ctx);
+
+ show_tlb();
+#endif
+}
+
+static void ipu_del_wired_entry( void )
+{
+ unsigned long flags;
+ unsigned long wired;
+
+ local_irq_save(flags);
+ wired = read_c0_wired();
+ if ( wired > 0 ) {
+ write_c0_wired(wired - 1);
+ }
+ local_irq_restore(flags);
+}
+
+static inline void ipu_buf_get( unsigned int page_shift )
+{
+ unsigned char * virt_addr;
+ int i;
+ for ( i=0; i< IPU_BUF_MAX; ++i ) {
+ if ( ipu_buf[i].addr == 0 ) {
+ break;
+ }
+ }
+
+ if ( (ipu_buf_cnt = i) == IPU_BUF_MAX ) {
+ printk("Error, no free ipu buffer.\n");
+ return ;
+ }
+
+ virt_addr = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);
+
+ if ( virt_addr ) {
+ ipu_buf[ipu_buf_cnt].addr = (unsigned int)virt_to_phys((void *)virt_addr);
+ ipu_buf[ipu_buf_cnt].page_shift = page_shift;
+
+ for (i = 0; i < (1<<page_shift); i++) {
+ SetPageReserved(virt_to_page(virt_addr));
+ virt_addr += PAGE_SIZE;
+ }
+ }
+ else {
+ printk("get memory Failed.\n");
+ }
+}
+
+static inline void ipu_buf_free( unsigned int phys_addr )
+{
+ unsigned char * virt_addr, *addr;
+ int cnt, i;
+
+ if ( phys_addr == 0 )
+ return ;
+
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt )
+ if ( phys_addr == ipu_buf[cnt].addr )
+ break;
+
+ if ( cnt == IPU_BUF_MAX ) { /* addr not in the ipu buffers */
+ printk("Invalid addr:0x%08x\n", (unsigned int)phys_addr);
+ }
+
+ virt_addr = (unsigned char *)phys_to_virt(ipu_buf[cnt].addr);
+ addr = virt_addr;
+ for (i = 0; i < (1<<ipu_buf[cnt].page_shift); i++) {
+ ClearPageReserved(virt_to_page(addr));
+ addr += PAGE_SIZE;
+ }
+
+ if ( cnt == 0 )
+ ipu_del_wired_entry();
+
+ free_pages((unsigned long )virt_addr, ipu_buf[cnt].page_shift);
+
+ ipu_buf[cnt].addr = 0;
+ ipu_buf[cnt].page_shift = 0;
+}
+
+static int ipu_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ /* read as binary */
+ unsigned int * pint;
+ pint = (unsigned int *) (page+len);
+
+ if ( ipu_buf_cnt >= IPU_BUF_MAX ) { /* failed alloc mem, rturn 0 */
+ printk("no free buffer.\n");
+ *pint = 0;
+ }
+ else
+ *pint = (unsigned int )ipu_buf[ipu_buf_cnt].addr; /* phys addr */
+ len += sizeof(unsigned int);
+
+#if defined(DEBUG)
+ show_tlb();
+#endif
+ return len;
+
+}
+
+static int ipu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ unsigned int val ;
+ int cnt,i;
+ char buf[12];
+ unsigned long pid, entrylo0, entrylo1, entryhi, pagemask;
+#if defined(DEBUG)
+ printk("ipu write count=%u\n", count);
+#endif
+ if (count == (8*5+1)) {
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*0, 8);
+ pid = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*1, 8);
+ entrylo0 = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*2, 8);
+ entrylo1 = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*3, 8);
+ entryhi = simple_strtoul(buf, 0, 16);
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer+8*4, 8);
+ pagemask = simple_strtoul(buf, 0, 16);
+
+#if defined(DEBUG)
+ printk("pid=0x%08x, entrylo0=0x%08x, entrylo1=0x%08x, entryhi=0x%08x, pagemask=0x%08x\n",
+ pid, entrylo0, entrylo1, entryhi, pagemask);
+#endif
+ ipu_add_wired_entry( pid, entrylo0, entrylo1, entryhi, pagemask);
+ return 41;
+ }
+ else if ( count <= 8+1 ) {
+ for (i=0;i<12;i++) buf[i]=0;
+ strncpy(buf, buffer, 8);
+ val = simple_strtoul(buf, 0, 16);
+ } else if (count == 44) {
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer, 10);
+ pid = simple_strtoul(buf, 0, 16);
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 11, 10);
+ entryhi = simple_strtoul(buf, 0, 16);//vaddr
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 22, 10);
+ entrylo0 = simple_strtoul(buf, 0, 16);//paddr
+ for (i = 0; i < 12; i++)
+ buf[i] = 0;
+ strncpy(buf, buffer + 33, 10);
+ pagemask = simple_strtoul(buf, 0, 16);
+ pagemask = 0x3ff << 13; /* Fixed to 4MB page size */
+ ipu_add_wired_entry(pid, entrylo0, 0, entryhi, pagemask);
+ return 44;
+ } else {
+ printk("ipu write count error, count=%d\n.", (unsigned int)count);
+ return -1;
+ }
+
+ /* val: 1-9, page_shift, val>= 10: ipu_buf.addr */
+ if ( val == 0 ) { /* debug, print ipu_buf info */
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt)
+ printk("ipu_buf[%d]: addr=0x%08x, page_shift=%d\n",
+ cnt, ipu_buf[cnt].addr, ipu_buf[cnt].page_shift );
+#if defined(DEBUG)
+ show_tlb();
+#endif
+ }
+ else if ( 0< val && val < 10 ) {
+ ipu_buf_get(val);
+ }
+ else if ( val == 0xff ) { /* 255: free all ipu_buf */
+ for ( cnt=0; cnt<IPU_BUF_MAX; ++cnt ) {
+ ipu_buf_free(ipu_buf[cnt].addr);
+ }
+ }
+ else {
+ ipu_buf_free(val);
+ }
+
+ return count;
+}
+
+/*
+ * UDC hotplug
+ */
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+extern int jz_udc_active; /* defined in drivers/char/jzchar/jz_udc_hotplug.c */
+#endif
+
+#ifndef GPIO_UDC_HOTPLUG
+#define GPIO_UDC_HOTPLUG 86
+#endif
+
+static int udc_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (__gpio_get_pin(GPIO_UDC_HOTPLUG)) {
+
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+
+ /* Cable has connected, wait for disconnection. */
+ __gpio_as_irq_fall_edge(GPIO_UDC_HOTPLUG);
+
+ if (jz_udc_active)
+ len += sprintf (page+len, "CONNECT_CABLE\n");
+ else
+ len += sprintf (page+len, "CONNECT_POWER\n");
+#else
+ len += sprintf (page+len, "CONNECT\n");
+#endif
+ }
+ else {
+
+#ifdef CONFIG_JZ_UDC_HOTPLUG
+ /* Cable has disconnected, wait for connection. */
+ __gpio_as_irq_rise_edge(GPIO_UDC_HOTPLUG);
+#endif
+
+ len += sprintf (page+len, "REMOVE\n");
+ }
+
+ return len;
+}
+
+/*
+ * MMC/SD hotplug
+ */
+
+#ifndef MSC_HOTPLUG_PIN
+#define MSC_HOTPLUG_PIN 90
+#endif
+
+static int mmc_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ if (__gpio_get_pin(MSC_HOTPLUG_PIN))
+ len += sprintf (page+len, "REMOVE\n");
+ else
+ len += sprintf (page+len, "INSERT\n");
+
+ return len;
+}
+
+#ifndef CONFIG_ANDROID_PMEM /* /dev/pmem instead /proc/jz/imem on android platform */
+
+/***********************************************************************
+ * IPU memory management (used by mplayer and other apps)
+ *
+ * We reserved 4MB memory for IPU
+ * The memory base address is jz_ipu_framebuf
+ */
+
+/* Usage:
+ *
+ * echo n > /proc/jz/imem // n = [0,...,10], allocate memory, 2^n pages
+ * echo xxxxxxxx > /proc/jz/imem // free buffer which addr is xxxxxxxx
+ * echo FF > /proc/jz/ipu // FF, free all buffers
+ * od -X /proc/jz/imem // return the allocated buffer address and the max order of free buffer
+ */
+
+//#define DEBUG_IMEM 1
+
+#define IMEM_MAX_ORDER 10 /* max 2^10 * 4096 = 4MB */
+
+static unsigned int jz_imem_base; /* physical base address of ipu memory */
+
+static unsigned int allocated_phys_addr = 0;
+
+/*
+ * Allocated buffer list
+ */
+typedef struct imem_list {
+ unsigned int phys_start; /* physical start addr */
+ unsigned int phys_end; /* physical end addr */
+ struct imem_list *next;
+} imem_list_t;
+
+static struct imem_list *imem_list_head = NULL; /* up sorted by phys_start */
+
+#ifdef DEBUG_IMEM
+static void dump_imem_list(void)
+{
+ struct imem_list *imem;
+
+ printk("*** dump_imem_list 0x%x ***\n", (u32)imem_list_head);
+ imem = imem_list_head;
+ while (imem) {
+ printk("imem=0x%x phys_start=0x%x phys_end=0x%x next=0x%x\n", (u32)imem, imem->phys_start, imem->phys_end, (u32)imem->next);
+ imem = imem->next;
+ }
+}
+#endif
+
+/* allocate 2^order pages inside the 4MB memory */
+static int imem_alloc(unsigned int order)
+{
+ int alloc_ok = 0;
+ unsigned int start, end;
+ unsigned int size = (1 << order) * PAGE_SIZE;
+ struct imem_list *imem, *imemn, *imemp;
+
+ allocated_phys_addr = 0;
+
+ start = jz_imem_base;
+ end = start + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
+
+ imem = imem_list_head;
+ while (imem) {
+ if ((imem->phys_start - start) >= size) {
+ /* we got a valid address range */
+ alloc_ok = 1;
+ break;
+ }
+
+ start = imem->phys_end + 1;
+ imem = imem->next;
+ }
+
+ if (!alloc_ok) {
+ if ((end - start) >= size)
+ alloc_ok = 1;
+ }
+
+ if (alloc_ok) {
+ end = start + size - 1;
+ allocated_phys_addr = start;
+
+ /* add to imem_list, up sorted by phys_start */
+ imemn = kmalloc(sizeof(struct imem_list), GFP_KERNEL);
+ if (!imemn) {
+ return -ENOMEM;
+ }
+ imemn->phys_start = start;
+ imemn->phys_end = end;
+ imemn->next = NULL;
+
+ if (!imem_list_head)
+ imem_list_head = imemn;
+ else {
+ imem = imemp = imem_list_head;
+ while (imem) {
+ if (start < imem->phys_start) {
+ break;
+ }
+
+ imemp = imem;
+ imem = imem->next;
+ }
+
+ if (imem == imem_list_head) {
+ imem_list_head = imemn;
+ imemn->next = imem;
+ }
+ else {
+ imemn->next = imemp->next;
+ imemp->next = imemn;
+ }
+ }
+ }
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+ return 0;
+}
+
+static void imem_free(unsigned int phys_addr)
+{
+ struct imem_list *imem, *imemp;
+
+ imem = imemp = imem_list_head;
+ while (imem) {
+ if (phys_addr == imem->phys_start) {
+ if (imem == imem_list_head) {
+ imem_list_head = imem->next;
+ }
+ else {
+ imemp->next = imem->next;
+ }
+
+ kfree(imem);
+ break;
+ }
+
+ imemp = imem;
+ imem = imem->next;
+ }
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+}
+
+static void imem_free_all(void)
+{
+ struct imem_list *imem;
+
+ imem = imem_list_head;
+ while (imem) {
+ kfree(imem);
+ imem = imem->next;
+ }
+
+ imem_list_head = NULL;
+
+ allocated_phys_addr = 0;
+
+#ifdef DEBUG_IMEM
+ dump_imem_list();
+#endif
+}
+
+/*
+ * Return the allocated buffer address and the max order of free buffer
+ */
+static int imem_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned int start_addr, end_addr, max_order, max_size;
+ struct imem_list *imem;
+
+ unsigned int *tmp = (unsigned int *)(page + len);
+
+ start_addr = jz_imem_base;
+ end_addr = start_addr + (1 << IMEM_MAX_ORDER) * PAGE_SIZE;
+
+ if (!imem_list_head)
+ max_size = end_addr - start_addr;
+ else {
+ max_size = 0;
+ imem = imem_list_head;
+ while (imem) {
+ if (max_size < (imem->phys_start - start_addr))
+ max_size = imem->phys_start - start_addr;
+
+ start_addr = imem->phys_end + 1;
+ imem = imem->next;
+ }
+
+ if (max_size < (end_addr - start_addr))
+ max_size = end_addr - start_addr;
+ }
+
+ if (max_size > 0) {
+ max_order = get_order(max_size);
+ if (((1 << max_order) * PAGE_SIZE) > max_size)
+ max_order--;
+ }
+ else {
+ max_order = 0xffffffff; /* No any free buffer */
+ }
+
+ *tmp++ = allocated_phys_addr; /* address allocated by 'echo n > /proc/jz/imem' */
+ *tmp = max_order; /* max order of current free buffers */
+
+ len += 2 * sizeof(unsigned int);
+
+ return len;
+}
+
+static int imem_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ unsigned int val;
+
+ val = simple_strtoul(buffer, 0, 16);
+
+ if (val == 0xff) {
+ /* free all memory */
+ imem_free_all();
+ }
+ else if ((val >= 0) && (val <= IMEM_MAX_ORDER)) {
+ /* allocate 2^val pages */
+ imem_alloc(val);
+ }
+ else {
+ /* free buffer which phys_addr is val */
+ imem_free(val);
+ }
+
+ return count;
+}
+#endif /* #ifndef CONFIG_ANDROID_PMEM */
+
+static int fpu_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ printk("user set rounding mode to %x \n",(unsigned int)buffer);
+
+ if ((unsigned int)buffer > 4) {
+ printk("roundind mode error!\n");
+ }
+
+ jz4810_fpu_init((unsigned int)buffer);
+ return count;
+}
+
+/*
+ * /proc/jz/xxx entry
+ *
+ */
+static int __init jz_proc_init(void)
+{
+ struct proc_dir_entry *res;
+#ifndef CONFIG_ANDROID_PMEM
+ unsigned int virt_addr, i;
+#endif
+
+ 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;
+ }
+
+ /* Image process unit */
+ res = create_proc_entry("ipu", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = ipu_read_proc;
+ res->write_proc = ipu_write_proc;
+ res->data = NULL;
+ }
+
+ /* udc hotplug */
+ res = create_proc_entry("udc", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = udc_read_proc;
+ res->write_proc = NULL;
+ res->data = NULL;
+ }
+
+ /* mmc hotplug */
+ res = create_proc_entry("mmc", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = mmc_read_proc;
+ res->write_proc = NULL;
+ res->data = NULL;
+ }
+
+#ifndef CONFIG_ANDROID_PMEM
+ /*
+ * Reserve a 4MB memory for IPU on JZ4810.
+ */
+ jz_imem_base = (unsigned int)__get_free_pages(GFP_KERNEL, IMEM_MAX_ORDER);
+ if (jz_imem_base) {
+ /* imem (IPU memory management) */
+ res = create_proc_entry("imem", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = imem_read_proc;
+ res->write_proc = imem_write_proc;
+ res->data = NULL;
+ }
+
+ /* Set page reserved */
+ virt_addr = jz_imem_base;
+ for (i = 0; i < (1 << IMEM_MAX_ORDER); i++) {
+ SetPageReserved(virt_to_page((void *)virt_addr));
+ virt_addr += PAGE_SIZE;
+ }
+
+ /* Convert to physical address */
+ jz_imem_base = virt_to_phys((void *)jz_imem_base);
+
+ printk("Total %dMB memory at 0x%x was reserved for IPU\n",
+ (unsigned int)((1 << IMEM_MAX_ORDER) * PAGE_SIZE)/1000000, jz_imem_base);
+ }
+#endif /* #ifdef CONFIG_ANDROID_PMEM */
+
+ /* fpu */
+ res = create_proc_entry("fpu", 0644, proc_jz_root);
+ if (res) {
+ res->read_proc = NULL;
+ res->write_proc = fpu_write_proc;
+ res->data = NULL;
+ }
+
+ return 0;
+}
+
+__initcall(jz_proc_init);
diff --git a/arch/mips/jz4810/prom.c b/arch/mips/jz4810/prom.c
new file mode 100644
index 00000000000..1d01082b4e1
--- /dev/null
+++ b/arch/mips/jz4810/prom.c
@@ -0,0 +1,198 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, supports YAMON and U-Boot.
+ *
+ * Copyright 2000, 2001, 2006 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/jzsoc.h>
+
+/* #define DEBUG_CMDLINE */
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+char * prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ if (prom_argc > 1)
+ *cp = '\0';
+
+}
+
+
+char *prom_getenv(char *envname)
+{
+#if 0
+ /*
+ * Return a pointer to the given environment variable.
+ * YAMON uses "name", "value" pairs, while U-Boot uses "name=value".
+ */
+
+ char **env = prom_envp;
+ int i = strlen(envname);
+ int yamon = (*env && strchr(*env, '=') == NULL);
+
+ while (*env) {
+ if (yamon) {
+ if (strcmp(envname, *env++) == 0)
+ return *env;
+ } else {
+ if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+ return *env + i + 1;
+ }
+ env++;
+ }
+#endif
+ return NULL;
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for(i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+
+#if 0
+ {
+ int i;
+
+ printk("get_ethernet_addr: ");
+ for (i=0; i<5; i++)
+ printk("%02x:", (unsigned char)*(ethernet_addr+i));
+ printk("%02x\n", *(ethernet_addr+i));
+ }
+#endif
+
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = (int) fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ mips_machtype = MACH_INGENIC_JZ4810;
+
+ prom_init_cmdline();
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ memsize = 0x04000000;
+ } else {
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+/* used by early printk */
+void prom_putchar(char c)
+{
+ volatile u8 *uart_lsr = (volatile u8 *)(UART2_BASE + OFF_LSR);
+ volatile u8 *uart_tdr = (volatile u8 *)(UART2_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 "JZ4810";
+}
+
+EXPORT_SYMBOL(prom_getcmdline);
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/jz4810/reset.c b/arch/mips/jz4810/reset.c
new file mode 100644
index 00000000000..66b6000dda3
--- /dev/null
+++ b/arch/mips/jz4810/reset.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/mips/jz4810/reset.c
+ *
+ * JZ4810 reset routines.
+ *
+ * Copyright (c) 2006-2007 Ingenic Semiconductor Inc.
+ * Author: <yliu@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/jzsoc.h>
+
+void jz_restart(char *command)
+{
+ printk("Restarting after 4 ms\n");
+ REG_WDT_TCSR = WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN;
+ REG_WDT_TCNT = 0;
+ REG_WDT_TDR = JZ_EXTAL/1000; /* reset after 4ms */
+ REG_TCU_TSCR = TCU_TSCR_WDTSC; /* enable wdt clock */
+ REG_WDT_TCER = WDT_TCER_TCEN; /* wdt start */
+ while (1);
+}
+
+void jz_halt(void)
+{
+ printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+
+ while (1)
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+}
+
+void jz_power_off(void)
+{
+ jz_halt();
+}
diff --git a/arch/mips/jz4810/setup.c b/arch/mips/jz4810/setup.c
new file mode 100644
index 00000000000..5a097f578d0
--- /dev/null
+++ b/arch/mips/jz4810/setup.c
@@ -0,0 +1,326 @@
+/*
+ * linux/arch/mips/jz4810/common/setup.c
+ *
+ * JZ4810 common setup routines.
+ *
+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+#include <asm/jzsoc.h>
+
+#ifdef CONFIG_PC_KEYB
+#include <asm/keyboard.h>
+#endif
+
+jz_clocks_t jz_clocks;
+
+extern char * __init prom_getcmdline(void);
+extern void __init jz_board_setup(void);
+extern void jz_restart(char *);
+extern void jz_halt(void);
+extern void jz_power_off(void);
+extern void jz_time_init(void);
+
+#if 1
+static void serial_putc (const char c)
+{
+ volatile u8 *uart_lsr = (volatile u8 *)(UART2_BASE + OFF_LSR);
+ volatile u8 *uart_tdr = (volatile u8 *)(UART2_BASE + OFF_TDR);
+
+ if (c == '\n') serial_putc ('\r');
+
+ /* Wait for fifo to shift out some bytes */
+ while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) );
+
+ *uart_tdr = (u8)c;
+}
+
+static void serial_puts (const char *s)
+{
+ while (*s) {
+ serial_putc (*s++);
+ }
+}
+#endif
+
+static void __init sysclocks_setup(void)
+{
+#ifndef CONFIG_MIPS_JZ_EMURUS /* FPGA */
+ jz_clocks.cclk = __cpm_get_cclk();
+ jz_clocks.hclk = __cpm_get_h0clk();
+ jz_clocks.pclk = __cpm_get_pclk();
+ jz_clocks.mclk = __cpm_get_mclk();
+ jz_clocks.h1clk = __cpm_get_h1clk();
+ jz_clocks.pixclk = __cpm_get_pixclk();
+ jz_clocks.i2sclk = __cpm_get_i2sclk();
+ jz_clocks.otgclk = __cpm_get_otgclk();
+ jz_clocks.mscclk = __cpm_get_mscclk(0);
+ jz_clocks.extalclk = __cpm_get_extalclk();
+ jz_clocks.rtcclk = __cpm_get_rtcclk();
+#else
+
+#define FPGACLK 8000000
+
+ jz_clocks.cclk = FPGACLK;
+ jz_clocks.hclk = FPGACLK;
+ jz_clocks.pclk = FPGACLK;
+ jz_clocks.mclk = FPGACLK;
+ jz_clocks.h1clk = FPGACLK;
+ jz_clocks.pixclk = FPGACLK;
+ jz_clocks.i2sclk = FPGACLK;
+ jz_clocks.usbclk = FPGACLK;
+ jz_clocks.mscclk = FPGACLK;
+ jz_clocks.extalclk = FPGACLK;
+ jz_clocks.rtcclk = FPGACLK;
+#endif
+
+ printk("CPU clock: %dMHz, System clock: %dMHz, Peripheral clock: %dMHz, Memory clock: %dMHz\n",
+ (jz_clocks.cclk + 500000) / 1000000,
+ (jz_clocks.hclk + 500000) / 1000000,
+ (jz_clocks.pclk + 500000) / 1000000,
+ (jz_clocks.mclk + 500000) / 1000000);
+}
+
+static void __init soc_cpm_setup(void)
+{
+ /* Start all module clocks
+ */
+ __cpm_start_all();
+
+ /* Enable CKO to external memory */
+ __cpm_enable_cko();
+
+ /* CPU enters IDLE mode when executing 'wait' instruction */
+ __cpm_idle_mode();
+
+ /* Setup system clocks */
+ sysclocks_setup();
+}
+
+static void __init soc_harb_setup(void)
+{
+// __harb_set_priority(0x00); /* CIM>LCD>DMA>ETH>PCI>USB>CBB */
+// __harb_set_priority(0x03); /* LCD>CIM>DMA>ETH>PCI>USB>CBB */
+// __harb_set_priority(0x0a); /* ETH>LCD>CIM>DMA>PCI>USB>CBB */
+}
+
+static void __init soc_emc_setup(void)
+{
+ __cpm_start_emc();
+ int haili = 10000;
+ while(haili --);
+
+// REG_EMC_PMEMBS1 = 0;
+// REG_EMC_PMEMBS0 = 0;
+
+ REG_EMC_PMEMBS1 = 0xff000000;
+ REG_EMC_PMEMBS0 = 0xff000000;
+}
+
+static void __init soc_dmac_setup(void)
+{
+ __dmac_enable_module(0);
+ __dmac_enable_module(1);
+}
+
+static void __init jz_soc_setup(void)
+{
+ soc_cpm_setup();
+ soc_harb_setup();
+// soc_emc_setup();
+ soc_dmac_setup();
+}
+
+static void __init jz_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port s;
+
+ REG8(UART0_FCR) |= UARTFCR_UUE; /* enable UART module */
+ memset(&s, 0, sizeof(s));
+ s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ s.iotype = SERIAL_IO_MEM;
+ s.regshift = 2;
+ s.uartclk = jz_clocks.extalclk ;
+
+ s.line = 0;
+ s.membase = (u8 *)UART0_BASE;
+ s.irq = 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 = IRQ_UART1;
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS1 setup failed!\n");
+ }
+ s.line = 2;
+ s.membase = (u8 *)UART2_BASE;
+ s.irq = IRQ_UART2;
+
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS2 setup failed!\n");
+ }
+
+ s.line = 3;
+ s.membase = (u8 *)UART3_BASE;
+ s.irq = IRQ_UART3;
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial ttyS3 setup failed!\n");
+ }
+#endif
+}
+
+void __init jz_test_setup(void)
+{
+ int volatile x = 1000;
+ int i;
+
+ printk(":111%s:%d\n",__FUNCTION__,__LINE__);
+
+ printk("kernel test cs1");
+#if 1
+// for (i = 0; i < 1000; i++) {
+ while(1) {
+ __gpio_as_output0(21);
+
+ x = 10000;
+ while(x--)
+ ;
+ __gpio_as_output1(21);
+ }
+#endif
+ printk("kernel test cs1 ok");
+
+#if 0
+
+ REG_CPM_CPCCR |= CPM_CPCCR_CE;
+ REG_CPM_LPCDR = 7;
+ REG_CPM_UHCCDR = 7;
+ REG_CPM_GPSCDR = 2;
+ REG_CPM_GPUCDR = 1;
+
+
+ REG_CPM_PSWC0ST = 0;
+ REG_CPM_PSWC1ST = 8;
+ REG_CPM_PSWC2ST = 10;
+ REG_CPM_PSWC3ST = 0;
+
+ REG_CPM_OPCR &= ~CPM_OPCR_UHCPHY_DISABLE;
+ REG_CPM_OPCR |= CPM_OPCR_UDCPHY_ENABLE;
+#endif
+
+#if 0
+ /*stop some clk*/
+ __cpm_stop_ipu();
+ __cpm_stop_lcd();
+ __cpm_stop_tve();
+ __cpm_stop_Cim();
+ __cpm_stop_mdma();
+ __cpm_stop_uhc();
+ __cpm_stop_gps();
+ __cpm_stop_ssi2();
+ __cpm_stop_ssi1();
+
+ __cpm_stop_uart3();
+ __cpm_stop_uart2();
+ __cpm_stop_uart0();
+
+ __cpm_stop_sadc();
+ REG_CPM_CLKGR0 |= (0xfff < 2);
+ REG_CPM_CLKGR1 = 0xffffffff;
+ __cpm_stop_bch();
+ __cpm_stop_dmac();
+ printk("some clk have been stop!\n");
+
+#endif
+#if 0
+ __cpm_start_emc();
+ printk("\n-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=\nREG_CPM_CLKGR0=0x%x\n",REG_CPM_CLKGR0);
+ int haili = 10000;
+ while(haili --);
+ printk("===================\n");
+ REG_EMC_PMEMBS1 = 0;
+ REG_EMC_PMEMBS0 = 0;
+
+ REG_EMC_PMEMBS1 |= (0xff << 24);
+ REG_EMC_PMEMBS0 |= (0xff << 24);
+ REG_EMC_PMEMBS0 |= (0xff << 8);
+
+ printk("---------------PMEMBS1=0x%x,PMEMBS0=0x%x\n",REG_EMC_PMEMBS1,REG_EMC_PMEMBS0);
+#endif
+}
+
+void __init plat_mem_setup(void)
+{
+ char *argptr;
+
+ serial_puts("jz plat_mem_setup \n");
+ argptr = prom_getcmdline();
+ serial_puts("jz plat_mem_setup 002\n");
+
+#if 1
+ __asm__ (
+ "li $2, 0xa9000000 \n\t"
+ "mtc0 $2, $5, 4 \n\t"
+ "nop \n\t"
+ ::"r"(2));
+#endif
+
+ /* IO/MEM resources. Which will be the addtion value in `inX' and
+ * `outX' macros defined in asm/io.h */
+ serial_puts("jz plat_mem_setup 003\n");
+
+ 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;
+ serial_puts("jz plat_mem_setup 004\n");
+
+ jz_soc_setup();
+
+ serial_puts("jz plat_mem_setup 005\n");
+ jz_serial_setup();
+ serial_puts("jz plat_mem_setup 006\n");
+ jz_board_setup();
+ serial_puts("jz plat_mem_setup 007\n");
+}
+
diff --git a/arch/mips/jz4810/sleep.S b/arch/mips/jz4810/sleep.S
new file mode 100644
index 00000000000..39639c2645e
--- /dev/null
+++ b/arch/mips/jz4810/sleep.S
@@ -0,0 +1,311 @@
+/*
+ * linux/arch/mips/jz4810/sleep.S
+ *
+ * jz4730 Assembler Sleep/WakeUp Management Routines
+ *
+ * Copyright (C) 2005 Ingenic Semiconductor
+ * 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.
+ */
+
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/mach-jz4810/jz4810cpm.h>
+#inclede <asm/mach-jz4810/jz4810emc.h>
+ .text
+ .set noreorder
+ .set noat
+
+ .extern jz_flush_cache_all
+
+/*
+ * jz_cpu_sleep()
+ *
+ * Forces CPU into sleep mode,and we will power down p0 in this mode!
+ */
+
+ .globl jz_cpu_sleep
+jz_cpu_sleep:
+
+ /* save hi, lo and general registers except k0($26) and k1($27) (total 32) */
+ move k0, sp
+ addiu k0, k0, -(32*4)
+ mfhi k1
+ sw $0, 0(k0)
+ sw $1, 4(k0)
+ sw k1, 120(k0) /* hi */
+ mflo k1
+ sw $2, 8(k0)
+ sw $3, 12(k0)
+ sw k1, 124(k0) /* lo */
+ sw $4, 16(k0)
+ sw $5, 20(k0)
+ sw $6, 24(k0)
+ sw $7, 28(k0)
+ sw $8, 32(k0)
+ sw $9, 36(k0)
+ sw $10, 40(k0)
+ sw $11, 44(k0)
+ sw $12, 48(k0)
+ sw $13, 52(k0)
+ sw $14, 56(k0)
+ sw $15, 60(k0)
+ sw $16, 64(k0)
+ sw $17, 68(k0)
+ sw $18, 72(k0)
+ sw $19, 76(k0)
+ sw $20, 80(k0)
+ sw $21, 84(k0)
+ sw $22, 88(k0)
+ sw $23, 92(k0)
+ sw $24, 96(k0)
+ sw $25, 100(k0)
+ sw $28, 104(k0)
+ sw $29, 108(k0) /* saved sp */
+ sw $30, 112(k0)
+ sw $31, 116(k0) /* saved ra */
+ move sp, k0
+
+ /* save CP0 registers and sp (total 26) */
+ move k0, sp
+ addiu k0, k0, -(26*4)
+
+ mfc0 $1, CP0_INDEX
+ mfc0 $2, CP0_RANDOM
+ mfc0 $3, CP0_ENTRYLO0
+ mfc0 $4, CP0_ENTRYLO1
+ mfc0 $5, CP0_CONTEXT
+ mfc0 $6, CP0_PAGEMASK
+ mfc0 $7, CP0_WIRED
+ mfc0 $8, CP0_BADVADDR
+ mfc0 $9, CP0_ENTRYHI
+ mfc0 $10, CP0_STATUS
+/* mfc0 $11, $12, 1*/ /* IntCtl */
+ mfc0 $12, CP0_CAUSE
+ mfc0 $13, CP0_EPC
+/* mfc0 $14, $15, 1*/ /* EBase */
+ mfc0 $15, CP0_CONFIG
+/* mfc0 $16, CP0_CONFIG, 7*/ /* Config 7 */
+ mfc0 $17, CP0_LLADDR
+ mfc0 $18, CP0_WATCHLO
+ mfc0 $19, CP0_WATCHHI
+ mfc0 $20, CP0_DEBUG
+ mfc0 $21, CP0_DEPC
+ mfc0 $22, CP0_ECC
+ mfc0 $23, CP0_TAGLO
+ mfc0 $24, CP0_ERROREPC
+ mfc0 $25, CP0_DESAVE
+
+ sw $1, 0(k0)
+ sw $2, 4(k0)
+ sw $3, 8(k0)
+ sw $4, 12(k0)
+ sw $5, 16(k0)
+ sw $6, 20(k0)
+ sw $7, 24(k0)
+ sw $8, 28(k0)
+ sw $9, 32(k0)
+ sw $10, 36(k0)
+ sw $11, 40(k0)
+ sw $12, 44(k0)
+ sw $13, 48(k0)
+ sw $14, 52(k0)
+ sw $15, 56(k0)
+ sw $16, 60(k0)
+ sw $17, 64(k0)
+ sw $18, 68(k0)
+ sw $19, 72(k0)
+ sw $20, 76(k0)
+ sw $21, 80(k0)
+ sw $22, 84(k0)
+ sw $23, 88(k0)
+ sw $24, 92(k0)
+ sw $25, 96(k0)
+ sw $29, 100(k0) /* saved sp */
+ move sp, k0
+
+ /* preserve virtual address of stack */
+ la k0, sleep_save_sp
+ sw sp, 0(k0)
+
+ /* flush caches and write buffers */
+ jal jz_flush_cache_all
+ nop
+#if 0
+ /* set new sdram refresh constant */
+ li t0, 1
+ la t1, EMC_RTCOR
+ sh t0, 0(t1)
+
+
+
+ /* disable PLL */
+ la t0, CPM_PLCR1
+ sw $0, 0(t0)
+#endif
+ /* put CPU to sleep mode */
+ la t0, CPM_LCR
+ lw t1, 0(t0)
+ li t2, ~CPM_LCR_LPM_MASK
+ and t1, t2
+ ori t1, CPM_LCR_LPM_SLEEP
+
+ .align 5
+ /* align execution to a cache line */
+ j 1f
+
+ .align 5
+1:
+ /* all needed values are now in registers.
+ * These last instructions should be in cache
+ */
+ nop
+ nop
+
+ /* set sleep mode */
+ sw t1, 0(t0)
+ nop
+
+ /* enter sleep mode */
+ .set mips3
+ wait
+ nop
+ .set mips0
+
+2: j 2b /* loop waiting for suspended */
+ nop
+
+/*
+ * jz_cpu_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ */
+
+ .align 5
+ .globl jz_cpu_resume
+jz_cpu_resume:
+#if 0 /*60 no have */
+
+ /* clear SCR.HGP */
+ la t0, CPM_SCR
+ lw t1, 0(t0)
+ li t2, ~CPM_SCR_HGP
+ and t1, t2
+ sw t1, 0(t0)
+#endif
+ /* restore LCR.LPM to IDLE mode */
+ la t0, CPM_LCR
+ lw t1, 0(t0)
+ li t2, ~CPM_LCR_LPM_MASK
+ and t1, t2
+ ori t1, CPM_LCR_LPM_IDLE
+ sw t1, 0(t0)
+
+ /* restore saved sp */
+ la t0, sleep_save_sp
+ lw sp, 0(t0)
+
+ /* restore CP0 registers */
+ move k0, sp
+ lw $1, 0(k0)
+ lw $2, 4(k0)
+ lw $3, 8(k0)
+ lw $4, 12(k0)
+ lw $5, 16(k0)
+ lw $6, 20(k0)
+ lw $7, 24(k0)
+ lw $8, 28(k0)
+ lw $9, 32(k0)
+ lw $10, 36(k0)
+ lw $11, 40(k0)
+ lw $12, 44(k0)
+ lw $13, 48(k0)
+ lw $14, 52(k0)
+ lw $15, 56(k0)
+ lw $16, 60(k0)
+ lw $17, 64(k0)
+ lw $18, 68(k0)
+ lw $19, 72(k0)
+ lw $20, 76(k0)
+ lw $21, 80(k0)
+ lw $22, 84(k0)
+ lw $23, 88(k0)
+ lw $24, 92(k0)
+ lw $25, 96(k0)
+ lw $29, 100(k0) /* saved sp */
+
+ mtc0 $1, CP0_INDEX
+ mtc0 $2, CP0_RANDOM
+ mtc0 $3, CP0_ENTRYLO0
+ mtc0 $4, CP0_ENTRYLO1
+ mtc0 $5, CP0_CONTEXT
+ mtc0 $6, CP0_PAGEMASK
+ mtc0 $7, CP0_WIRED
+ mtc0 $8, CP0_BADVADDR
+ mtc0 $9, CP0_ENTRYHI
+ mtc0 $10, CP0_STATUS
+/* mtc0 $11, $12, 1*/ /* IntCtl */
+ mtc0 $12, CP0_CAUSE
+ mtc0 $13, CP0_EPC
+/* mtc0 $14, $15, 1*/ /* EBase */
+ mtc0 $15, CP0_CONFIG
+/* mtc0 $16, CP0_CONFIG, 7*/ /* Config 7 */
+ mtc0 $17, CP0_LLADDR
+ mtc0 $18, CP0_WATCHLO
+ mtc0 $19, CP0_WATCHHI
+ mtc0 $20, CP0_DEBUG
+ mtc0 $21, CP0_DEPC
+ mtc0 $22, CP0_ECC
+ mtc0 $23, CP0_TAGLO
+ mtc0 $24, CP0_ERROREPC
+ mtc0 $25, CP0_DESAVE
+
+ /* restore general registers */
+ move k0, sp
+ lw k1, 120(k0) /* hi */
+ lw $0, 0(k0)
+ lw $1, 4(k0)
+ mthi k1
+ lw k1, 124(k0) /* lo */
+ lw $2, 8(k0)
+ lw $3, 12(k0)
+ mtlo k1
+ lw $4, 16(k0)
+ lw $5, 20(k0)
+ lw $6, 24(k0)
+ lw $7, 28(k0)
+ lw $8, 32(k0)
+ lw $9, 36(k0)
+ lw $10, 40(k0)
+ lw $11, 44(k0)
+ lw $12, 48(k0)
+ lw $13, 52(k0)
+ lw $14, 56(k0)
+ lw $15, 60(k0)
+ lw $16, 64(k0)
+ lw $17, 68(k0)
+ lw $18, 72(k0)
+ lw $19, 76(k0)
+ lw $20, 80(k0)
+ lw $21, 84(k0)
+ lw $22, 88(k0)
+ lw $23, 92(k0)
+ lw $24, 96(k0)
+ lw $25, 100(k0)
+ lw $28, 104(k0)
+ lw $29, 108(k0) /* saved sp */
+ lw $30, 112(k0)
+ lw $31, 116(k0) /* saved ra */
+
+ /* return to caller */
+ jr ra
+ nop
+
+sleep_save_sp:
+ .word 0 /* preserve sp here */
+
+ .set reorder
diff --git a/arch/mips/jz4810/time.c b/arch/mips/jz4810/time.c
new file mode 100644
index 00000000000..04037264f71
--- /dev/null
+++ b/arch/mips/jz4810/time.c
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/mips/jz4810/time.c
+ *
+ * Setting up the clock on the JZ4810 boards.
+ *
+ * Copyright (C) 2008 Ingenic Semiconductor Inc.
+ * Author: <jlwei@ingenic.cn>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/clockchips.h>
+
+#include <asm/time.h>
+#include <asm/jzsoc.h>
+
+/* This is for machines which generate the exact clock. */
+
+#define JZ_TIMER_TCU_CH 5
+#define JZ_TIMER_IRQ IRQ_TCU1
+
+#define JZ_TIMER_CLOCK (JZ_EXTAL>>4) /* Jz timer clock frequency */
+
+static struct clocksource clocksource_jz; /* Jz clock source */
+static struct clock_event_device jz_clockevent_device; /* Jz clock event */
+
+void (*jz_timer_callback)(void);
+
+static irqreturn_t jz_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
+
+ if (jz_timer_callback)
+ jz_timer_callback();
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz_irqaction = {
+ .handler = jz_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "jz-timerirq",
+};
+
+static unsigned int current_cycle_high = 0;
+
+union clycle_type
+{
+ cycle_t cycle64;
+ unsigned int cycle32[2];
+};
+
+cycle_t jz_get_cycles(void)
+{
+ /* convert jiffes to jz timer cycles */
+ unsigned int ostcount;
+ unsigned long cpuflags;
+ unsigned int current_cycle;
+ unsigned int flag;
+ union clycle_type old_cycle;
+ local_irq_save(cpuflags);
+ current_cycle = current_cycle_high;
+ ostcount = REG_TCU_OSTCNT;
+ flag = (REG_TCU_TFR & TCU_TFCR_OSTFCL) ? 1: 0;
+ if(flag)
+ ostcount = REG_TCU_OSTCNT;
+ local_irq_restore(cpuflags);
+
+ old_cycle.cycle32[0] = ostcount;
+ old_cycle.cycle32[1] = current_cycle + flag;
+
+ return (old_cycle.cycle64);
+
+}
+
+static struct clocksource clocksource_jz = {
+ .name = "jz_clocksource",
+ .rating = 300,
+ .read = jz_get_cycles,
+ .mask = 0xFFFFFFFF,
+ .shift = 10,
+ .flags = CLOCK_SOURCE_WATCHDOG,
+};
+
+static irqreturn_t jzclock_handler(int irq, void *dev_id)
+{
+ REG_TCU_TFCR = TCU_TFCR_OSTFCL; /* ACK timer */
+ current_cycle_high++;
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz_clockaction = {
+ .handler = jzclock_handler,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "jz-clockcycle",
+};
+static int __init jz_clocksource_init(void)
+{
+ unsigned int latch;
+
+ /* Init timer */
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
+ clocksource_jz.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, clocksource_jz.shift);
+ clocksource_register(&clocksource_jz);
+
+ //---------------------init sys clock -----------------
+
+ REG_TCU_OSTCSR = TCU_OSTCSR_PRESCALE16 | TCU_OSTCSR_EXT_EN;
+
+ REG_TCU_OSTCNT = 0;
+ REG_TCU_OSTDR = 0xffffffff;
+
+ jz_clockaction.dev_id = &clocksource_jz;
+
+ setup_irq(IRQ_TCU0, &jz_clockaction);
+ REG_TCU_TMCR = TCU_TMCR_OSTMCL; /* unmask match irq */
+ REG_TCU_TSCR = TCU_TSCR_OSTSC; /* enable timer clock */
+ REG_TCU_TESR = TCU_TESR_OSTST; /* start counting up */
+
+ //---------------------endif init sys clock -----------------
+
+ return 0;
+}
+
+static int jz_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ return 0;
+}
+
+static void jz_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device jz_clockevent_device = {
+ .name = "jz-clockenvent",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+// .features = CLOCK_EVT_FEAT_ONESHOT, /* Jz47XX not support dynamic clock now */
+
+ /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+ .mult = 1,
+ .rating = 300,
+ .irq = JZ_TIMER_IRQ,
+ .set_mode = jz_set_mode,
+ .set_next_event = jz_set_next_event,
+};
+
+static void __init jz_clockevent_init(void)
+{
+ struct clock_event_device *cd = &jz_clockevent_device;
+ unsigned int cpu = smp_processor_id();
+
+ cd->cpumask = cpumask_of(cpu);
+ clockevents_register_device(cd);
+}
+
+static void __init jz_timer_setup(void)
+{
+ unsigned int latch;
+
+ jz_clocksource_init(); /* init jz clock source */
+ jz_clockevent_init(); /* init jz clock event */
+
+ //---------------------init sys tick -----------------
+ /* Init timer */
+ __tcu_stop_counter(JZ_TIMER_TCU_CH);
+// __cpm_start_tcu();
+ latch = (JZ_TIMER_CLOCK + (HZ>>1)) / HZ;
+
+ REG_TCU_TMSR = ((1 << JZ_TIMER_TCU_CH) | (1 << (JZ_TIMER_TCU_CH + 16)));
+
+ REG_TCU_TCSR(JZ_TIMER_TCU_CH) = TCU_TCSR_PRESCALE16 | TCU_TCSR_EXT_EN;
+ REG_TCU_TDFR(JZ_TIMER_TCU_CH) = latch - 1;
+ REG_TCU_TDHR(JZ_TIMER_TCU_CH) = latch + 1;
+ REG_TCU_TCNT(JZ_TIMER_TCU_CH) = 0;
+ /*
+ * Make irqs happen for the system timer
+ */
+ jz_irqaction.dev_id = &jz_clockevent_device;
+ setup_irq(JZ_TIMER_IRQ, &jz_irqaction);
+ __tcu_clear_full_match_flag(JZ_TIMER_TCU_CH);
+ __tcu_unmask_full_match_irq(JZ_TIMER_TCU_CH);
+ __tcu_start_counter(JZ_TIMER_TCU_CH);}
+
+
+void __init plat_time_init(void)
+{
+ jz_timer_setup();
+}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index a77732cf7ae..0c9d2ff6d79 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -280,7 +280,13 @@ static inline unsigned long cpu_get_fpu_id(void)
*/
static inline int __cpu_has_fpu(void)
{
- return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+ return 0;
+#ifndef CONFIG_SOC_JZ4760
+ return 0; // need fix !!!
+// return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+#else
+ return 1;
+#endif
}
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
@@ -901,6 +907,20 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
__cpu_name[cpu] = "Ingenic JZRISC";
+ if (__cpu_has_fpu())
+ {
+ unsigned int tmp,mask;
+ mask = 1 << 26;
+ c->options |= MIPS_CPU_FPU;
+ /* Set floating mode to 32*32bit mode */
+ tmp = read_c0_status();
+ tmp &= ~mask;
+ printk("Jz4760 Floating coprocessor work on %s mode\n",
+ (tmp & mask) ? "32*64bit" : "32*32bit");
+ write_c0_status(tmp);
+ }
+
+
break;
default:
panic("Unknown Ingenic Processor ID!");
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 7b845ba9dff..c1cf08d73bd 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -73,10 +73,17 @@ void free_irqno(unsigned int irq)
* 'what should we do if we get a hw irq event on an illegal vector'.
* each architecture has to answer this themselves.
*/
+void (*ack_bad_irq_callback)(unsigned int irq) = 0;
+
void ack_bad_irq(unsigned int irq)
{
+ if (ack_bad_irq_callback) {
+ ack_bad_irq_callback(irq);
+ }
smtc_im_ack_irq(irq);
printk("unexpected IRQ # %d\n", irq);
+
+ while (1);
}
atomic_t irq_err_count;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 02d1d4077fa..433f4a688d2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1229,7 +1229,9 @@ static void __cpuinit setup_scache(void)
loongson2_sc_init();
return;
#endif
-
+ case CPU_JZRISC:
+ sc_present = 0;
+ return;
default:
if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
c->isa_level == MIPS_CPU_ISA_M32R2 ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index b06e2c81006..87a1672e63f 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -805,9 +805,17 @@ config RTC_PCF8563
config RTC_JZ
bool 'Jz47XX On-Chip Real Time Clock'
+ depends on SOC_JZ4750 || SOC_JZ4750D
help
Jz47XX On-Chip Real Time Clock
+
+config RTC_JZ4760
+ bool 'Jz4760 On-Chip Real Time Clock'
+ depends on SOC_JZ4760
+ help
+ Jz4760 On-Chip Real Time Clock
+
#
# These legacy RTC drivers just cause too many conflicts with the generic
# RTC framework ... let's not even try to coexist any more.
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index ae98c77267d..dc7c4eab2f6 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o
obj-$(CONFIG_RTC_PCF8563) += rtc_pcf8563.o
obj-$(CONFIG_RTC_JZ) += rtc_jz.o
+obj-$(CONFIG_RTC_JZ4760) += rtc-jz4760.o
obj-$(CONFIG_JZCHAR) += jzchar/
obj-$(CONFIG_MWAVE) += mwave/
diff --git a/drivers/char/jzchar/Kconfig b/drivers/char/jzchar/Kconfig
index 12116c7396c..fbcecdb9cf9 100644
--- a/drivers/char/jzchar/Kconfig
+++ b/drivers/char/jzchar/Kconfig
@@ -3,25 +3,23 @@
#
menu "JZSOC char device support"
- depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D
+ depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760
config JZCHAR
tristate 'JzSOC char device support'
+ depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760
config JZ_SIMPLE_I2C
tristate 'Ingenic Simple I2C Userspace Driver'
+ depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D
-config JZ_CAMERA_SENSOR
- bool
-
-config JZ_CIM
- tristate 'JzSOC Camera Interface Module (CIM) support'
- depends on JZCHAR
- select JZ_CAMERA_SENSOR
+config JZ_GPIO_PM_KEY
+ tristate 'Ingenic GPIO PM Key Driver'
+ depends on SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D
config JZ_TPANEL_ATA2508
tristate 'JzSOC MPEG4 TOUCH PANEL ATA2508 support'
- depends on JZCHAR
+ depends on JZCHAR && (SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D)
#config JZ_TPANEL
# tristate 'JzSOC touchpanel driver support'
@@ -50,21 +48,13 @@ config JZ_TPANEL_WM9712
endchoice
-#config JZ_UDC_HOTPLUG
-# tristate 'JZ UDC hotplug driver support'
-# depends on JZCHAR
-
-config JZ_POWEROFF
- tristate 'JZ board poweroff support'
- depends on JZCHAR
-
config JZ_OW
tristate 'JZ One-wire bus support'
- depends on JZCHAR
+ depends on JZCHAR && (SOC_JZ4740 || SOC_JZ4730 || SOC_JZ4750 || SOC_JZ4750D)
config JZ_TCSM
tristate 'JZ TCSM support'
- depends on JZCHAR
+ depends on JZCHAR && (SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760)
config JZ_TSSI
tristate 'JZ MPEG2-TS interface support'
diff --git a/drivers/char/jzchar/Makefile b/drivers/char/jzchar/Makefile
index 1e4ca0ebbec..487de64b967 100644
--- a/drivers/char/jzchar/Makefile
+++ b/drivers/char/jzchar/Makefile
@@ -3,23 +3,16 @@
#
obj-$(CONFIG_JZCHAR) += jzchars.o
-obj-$(CONFIG_JZ_SCC) += scc.o
-obj-$(CONFIG_JZ_CIM) += cim.o
-obj-$(CONFIG_JZ_TPANEL_ATA2508) += ata2508.o
-obj-$(CONFIG_JZ_CAMERA_SENSOR) += sensor.o
-obj-$(CONFIG_JZ_I2C_EEPROM) += eeprom.o
-obj-$(CONFIG_JZ_EJTAG) += ejtag.o
-obj-$(CONFIG_JZ_POWEROFF) += poweroff.o
-
#obj-$(CONFIG_JZ_TPANEL) += jz_ts.o
obj-$(CONFIG_JZ_TPANEL_UCB1400) += ucb1400.o
obj-$(CONFIG_JZ_TPANEL_WM9712) += wm9712.o
obj-$(CONFIG_JZ_TPANEL_AK4182) += ak4182.o
+obj-$(CONFIG_JZ_TPANEL_ATA2508) += ata2508.o
obj-$(CONFIG_JZ_SADC) += sadc.o
-obj-$(CONFIG_JZ_SMART_LCD) += slcd.o
-#obj-$(CONFIG_JZ_UDC_HOTPLUG) += udc_hotplug.o
obj-$(CONFIG_JZ_OW) += jz_ow.o
obj-$(CONFIG_JZ_TCSM) += tcsm.o
obj-$(CONFIG_JZ_TSSI) += jz_tssi.o
-obj-$(CONFIG_JZ_SIMPLE_I2C) += i_i2c.o \ No newline at end of file
+
+obj-$(CONFIG_JZ_SIMPLE_I2C) += i_i2c.o
+obj-$(CONFIG_JZ_GPIO_PM_KEY) += i_gpio_pm_key.o
diff --git a/drivers/char/jzchar/cim.c b/drivers/char/jzchar/cim.c
deleted file mode 100644
index c320d6798c9..00000000000
--- a/drivers/char/jzchar/cim.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * linux/drivers/char/jzchar/cim.c
- *
- * Camera Interface Module (CIM) driver for JzSOC
- * This driver is independent of the camera sensor
- *
- * Copyright (C) 2005 JunZheng semiconductor
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/jzsoc.h>
-
-#include "jzchars.h"
-
-#define CIM_NAME "cim"
-
-MODULE_AUTHOR("Jianli Wei<jlwei@ingenic.cn>");
-MODULE_DESCRIPTION("JzSOC Camera Interface Module driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Define the Max Image Size
- */
-#define MAX_IMAGE_WIDTH 640
-#define MAX_IMAGE_HEIGHT 480
-#define MAX_IMAGE_BPP 16
-#define MAX_FRAME_SIZE (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * MAX_IMAGE_BPP / 8)
-
-typedef struct
-{
- u32 width;
- u32 height;
- u32 bpp;
-} img_param_t;
-
-typedef struct
-{
- u32 cfg;
- u32 ctrl;
- u32 mclk;
-} cim_config_t;
-
-/*
- * IOCTL_XXX commands
- */
-#define IOCTL_SET_IMG_PARAM 0 // arg type: img_param_t *
-#define IOCTL_CIM_CONFIG 1 // arg type: cim_config_t *
-
-/* Actual image size, must less than max values */
-static int img_width = MAX_IMAGE_WIDTH, img_height = MAX_IMAGE_HEIGHT, img_bpp = MAX_IMAGE_BPP;
-
-/*
- * CIM DMA descriptor
- */
-struct cim_desc {
- u32 nextdesc; /* Physical address of next desc */
- u32 framebuf; /* Physical address of frame buffer */
- u32 frameid; /* Frame ID */
- u32 dmacmd; /* DMA command */
-};
-
-/*
- * CIM device structure
- */
-struct cim_device {
- unsigned char *framebuf;
- unsigned int frame_size;
- unsigned int page_order;
- wait_queue_head_t wait_queue;
- struct cim_desc frame_desc __attribute__ ((aligned (16)));
-};
-
-// global
-static struct cim_device *cim_dev;
-
-/*==========================================================================
- * CIM init routines
- *========================================================================*/
-
-static void cim_config(cim_config_t *c)
-{
- REG_CIM_CFG = c->cfg;
- REG_CIM_CTRL = c->ctrl;
- // Set the master clock output
-#if defined(CONFIG_SOC_JZ4730)
- __cim_set_master_clk(__cpm_get_sclk(), c->mclk);
-#elif defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750)
- __cim_set_master_clk(__cpm_get_hclk(), c->mclk);
-#else
- __cim_set_master_clk(__cpm_get_sclk(), c->mclk);
-#endif
- // Enable sof, eof and stop interrupts
- __cim_enable_sof_intr();
- __cim_enable_eof_intr();
- __cim_enable_stop_intr();
-}
-
-/*==========================================================================
- * CIM start/stop operations
- *========================================================================*/
-
-static int cim_start_dma(char *ubuf)
-{
- __cim_disable();
-
- dma_cache_wback((unsigned long)cim_dev->framebuf, (2 ^ (cim_dev->page_order)) * 4096);
-
- // set the desc addr
- __cim_set_da(virt_to_phys(&(cim_dev->frame_desc)));
-
- __cim_clear_state(); // clear state register
- __cim_reset_rxfifo(); // resetting rxfifo
- __cim_unreset_rxfifo();
- __cim_enable_dma(); // enable dma
-
- // start
- __cim_enable();
-
- // wait for interrupts
- interruptible_sleep_on(&cim_dev->wait_queue);
-
- // copy frame data to user buffer
- memcpy(ubuf, cim_dev->framebuf, cim_dev->frame_size);
-
- return cim_dev->frame_size;
-}
-
-static void cim_stop(void)
-{
- __cim_disable();
- __cim_clear_state();
-}
-
-/*==========================================================================
- * Framebuffer allocation and destroy
- *========================================================================*/
-
-static void cim_fb_destroy(void)
-{
- if (cim_dev->framebuf) {
- free_pages((unsigned long)(cim_dev->framebuf), cim_dev->page_order);
- cim_dev->framebuf = NULL;
- }
-}
-
-static int cim_fb_alloc(void)
-{
- cim_dev->frame_size = img_width * img_height * (img_bpp/8);
- cim_dev->page_order = get_order(cim_dev->frame_size);
-
- /* frame buffer */
- cim_dev->framebuf = (unsigned char *)__get_free_pages(GFP_KERNEL, cim_dev->page_order);
- if ( !(cim_dev->framebuf) ) {
- return -ENOMEM;
- }
-
- cim_dev->frame_desc.nextdesc = virt_to_phys(&(cim_dev->frame_desc));
- cim_dev->frame_desc.framebuf = virt_to_phys(cim_dev->framebuf);
- cim_dev->frame_desc.frameid = 0x52052018;
- cim_dev->frame_desc.dmacmd = CIM_CMD_EOFINT | CIM_CMD_STOP | (cim_dev->frame_size >> 2); // stop after capturing a frame
-
- dma_cache_wback((unsigned long)(&(cim_dev->frame_desc)), 16);
-
- return 0;
-}
-
-/*==========================================================================
- * File operations
- *========================================================================*/
-
-static int cim_open(struct inode *inode, struct file *filp);
-static int cim_release(struct inode *inode, struct file *filp);
-static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l);
-static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l);
-static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-
-static struct file_operations cim_fops =
-{
- open: cim_open,
- release: cim_release,
- read: cim_read,
- write: cim_write,
- ioctl: cim_ioctl
-};
-
-static int cim_open(struct inode *inode, struct file *filp)
-{
- try_module_get(THIS_MODULE);
- return 0;
-}
-
-static int cim_release(struct inode *inode, struct file *filp)
-{
- cim_stop();
-
- module_put(THIS_MODULE);
- return 0;
-}
-
-static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l)
-{
- if (size < cim_dev->frame_size)
- return -EINVAL;
-
- return cim_start_dma(buf);
-}
-
-static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l)
-{
- printk("cim error: write is not implemented\n");
- return -1;
-}
-
-static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
- case IOCTL_SET_IMG_PARAM:
- {
- img_param_t i;
-
- if (copy_from_user((void *)&i, (void *)arg, sizeof(img_param_t)))
- return -EFAULT;
-
- img_width = i.width;
- img_height = i.height;
- img_bpp = i.bpp;
-
- if ((img_width * img_height * img_bpp/8) > MAX_FRAME_SIZE) {
- /* realloc the buffer */
- cim_fb_destroy();
- if (cim_fb_alloc() < 0)
- return -ENOMEM;
- }
-
- cim_dev->frame_size = img_width * img_height * (img_bpp/8);
-
- cim_dev->frame_desc.dmacmd = CIM_CMD_EOFINT | CIM_CMD_STOP | (cim_dev->frame_size >> 2); // stop after capturing a frame
-
- dma_cache_wback((unsigned long)(&(cim_dev->frame_desc)), 16);
-
- break;
- }
- case IOCTL_CIM_CONFIG:
- {
- cim_config_t c;
-
- if (copy_from_user((void *)&c, (void *)arg, sizeof(cim_config_t)))
- return -EFAULT;
-
- cim_config(&c);
-
- break;
- }
- default:
- printk("Not supported command: 0x%x\n", cmd);
- return -EINVAL;
- break;
- }
- return 0;
-}
-
-/*==========================================================================
- * Interrupt handler
- *========================================================================*/
-
-static irqreturn_t cim_irq_handler(int irq, void *dev_id)
-{
- u32 state = REG_CIM_STATE;
-#if 0
- if (state & CIM_STATE_DMA_EOF) {
- wake_up_interruptible(&cim_dev->wait_queue);
- }
-#endif
- if (state & CIM_STATE_DMA_STOP) {
- // Got a frame, wake up wait routine
- wake_up_interruptible(&cim_dev->wait_queue);
- }
-
- // clear status flags
- REG_CIM_STATE = 0;
- return IRQ_HANDLED;
-}
-
-/*==========================================================================
- * Module init and exit
- *========================================================================*/
-
-static int __init cim_init(void)
-{
- struct cim_device *dev;
- int ret;
-
- /* allocate device */
- dev = kmalloc(sizeof(struct cim_device), GFP_KERNEL);
- if (!dev) return -ENOMEM;
-
- /* record device */
- cim_dev = dev;
-
- /* allocate a frame buffer */
- if (cim_fb_alloc() < 0) {
- kfree(dev);
- return -ENOMEM;
- }
-
- init_waitqueue_head(&dev->wait_queue);
-
- ret = jz_register_chrdev(CIM_MINOR, CIM_NAME, &cim_fops, dev);
- if (ret < 0) {
- cim_fb_destroy();
- kfree(dev);
- return ret;
- }
-
- if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED,
- CIM_NAME, dev))) {
- cim_fb_destroy();
- kfree(dev);
- printk(KERN_ERR "CIM could not get IRQ");
- return ret;
- }
-
- printk("JzSOC Camera Interface Module (CIM) driver registered\n");
-
- return 0;
-}
-
-static void __exit cim_exit(void)
-{
- free_irq(IRQ_CIM, cim_dev);
- jz_unregister_chrdev(CIM_MINOR, CIM_NAME);
- cim_fb_destroy();
- kfree(cim_dev);
-}
-
-module_init(cim_init);
-module_exit(cim_exit);
diff --git a/drivers/char/jzchar/cim.h b/drivers/char/jzchar/cim.h
deleted file mode 100644
index c21431bc710..00000000000
--- a/drivers/char/jzchar/cim.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * JzSOC CIM driver
- *
- * Copyright (C) 2005 Ingenic Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __CIM_H__
-#define __CIM_H__
-
-typedef struct
-{
- u32 width;
- u32 height;
- u32 bpp;
-} IMG_PARAM;
-
-/*
- * IOCTL_XXX commands
- */
-#define IOCTL_SET_IMG_PARAM 0 // arg type: IMG_PARAM *
-
-#endif /* __CIM_H__ */
diff --git a/drivers/char/jzchar/i_gpio_pm_key.c b/drivers/char/jzchar/i_gpio_pm_key.c
new file mode 100644
index 00000000000..c616e85d430
--- /dev/null
+++ b/drivers/char/jzchar/i_gpio_pm_key.c
@@ -0,0 +1,307 @@
+/*
+ * linux/drivers/char/jzchar/i_gpio_pm_key.c
+ *
+ * GPIO PM Key Handling.
+ *
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 2009-03-07 River Wang:
+ * Code clean #1 for iRiver D8.
+ * Timer rountines has been re-written.
+ * Now only 1 timer is used to count down.
+ * GPIO pin reading routines has been improved.
+ *
+ * 2010-03-29 River Wang:
+ * Code clean & refactor #2 for Noah.
+ * Board definations may need some more works.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/jzsoc.h>
+
+#define D(fmt, args...) \
+ printk(KERN_ERR "%s(): LINE: %d "fmt"\n", __func__, __LINE__, ##args)
+
+/* ------------ CUSTOM: Modify these as your need. ----------------- */
+#define GPIO_PM_DETECT_PERIOD (HZ / 2) /* unit: jiffies.*/
+#define GPIO_PM_INT_REACTIVE_DELAY 2 /* unit: period. */
+#define GPIO_PM_TOTAL_COUNT 4 /* unit: period. */
+#define GPIO_PM_SHORT_PRESS_COUNT 4 /* unit: period. */
+/* ------------------------------------------------------------------*/
+
+enum {
+ GPIO_PM_SHORT_PRESSED = KOBJ_REMOVE,
+ GPIO_PM_LONG_PRESSED = KOBJ_ADD,
+};
+
+/* ---------------- CUSTOM: Board Definations. ----------- */
+#if defined (CONFIG_SOC_JZ4750) || (CONFIG_SOC_JZ4750D)
+#define GPIO_PW_I GPIO_WAKEUP
+#endif
+
+#define GPIO_PM_PIN GPIO_PW_I
+#define GPIO_PM_IRQ (IRQ_GPIO_0 + GPIO_PM_PIN)
+
+#define gpio_pm_pin_as_irq() __gpio_as_irq_fall_edge(GPIO_PM_PIN)
+
+#define GPIO_PM_PIN_DOWN 0
+/* ------------------------------------------------------- */
+
+#define DRV_NAME "gpio-pm"
+
+MODULE_AUTHOR("River Wang <zwang@ingenic.cn>");
+MODULE_DESCRIPTION("GPIO PM Key Handling.");
+MODULE_LICENSE("GPL");
+
+struct drv_data {
+ struct timer_list suspend_timer;
+ struct timer_list int_reactive_timer;
+
+ unsigned int suspend_timer_count;
+ unsigned int int_reactive_timer_count;
+
+ unsigned int suspend_active;
+
+ int action;
+ struct work_struct work;
+
+ struct platform_device *pdev;
+};
+
+static struct drv_data g_drv_data;
+
+static unsigned int read_gpio_pin(void)
+{
+ unsigned int try_loop = 1000;
+
+ unsigned int t, v;
+ unsigned int i;
+
+ i = try_loop;
+
+ v = t = 0;
+
+ while (i--) {
+ t = __gpio_get_pin(GPIO_PM_PIN);
+ if (v != t)
+ i = try_loop;
+
+ v = t;
+ }
+
+ return v;
+}
+
+static void int_reactive_timer_routine(unsigned long data)
+{
+ struct drv_data *drv = (struct drv_data *)data;
+
+ if (drv->int_reactive_timer_count) {
+ drv->int_reactive_timer_count --;
+ mod_timer(&drv->int_reactive_timer, jiffies + GPIO_PM_DETECT_PERIOD);
+ }else{
+ D("Timeout.");
+
+ drv->suspend_active = 0;
+ }
+
+ return;
+}
+
+static void start_int_reactive(struct drv_data *drv)
+{
+ gpio_pm_pin_as_irq();
+
+ drv->int_reactive_timer_count = GPIO_PM_INT_REACTIVE_DELAY;
+
+ mod_timer(&drv->int_reactive_timer, jiffies + 1);
+
+ return;
+}
+
+static void suspend_timer_routine(unsigned long data)
+{
+ struct drv_data *drv = (struct drv_data *)data;
+
+ if (read_gpio_pin() == GPIO_PM_PIN_DOWN) {
+ if (drv->suspend_timer_count == 0) {
+ D("Long Pressed.");
+
+ drv->action = GPIO_PM_LONG_PRESSED;
+
+ schedule_work(&drv->work);
+ }else{
+ drv->suspend_timer_count --;
+ mod_timer(&drv->suspend_timer, jiffies + GPIO_PM_DETECT_PERIOD);
+ }
+ }else{
+ if (drv->suspend_timer_count <= GPIO_PM_SHORT_PRESS_COUNT) {
+ D("Short Pressed.");
+
+ drv->action = GPIO_PM_SHORT_PRESSED;
+
+ schedule_work(&drv->work);
+ }else{
+ D("Dummy Key.");
+
+ start_int_reactive(drv);
+ }
+ }
+
+ return;
+}
+
+static void start_suspend(struct drv_data *drv)
+{
+ __gpio_as_input(GPIO_PM_PIN);
+
+ del_timer(&drv->int_reactive_timer);
+
+ drv->suspend_timer_count = GPIO_PM_TOTAL_COUNT;
+ drv->suspend_active = 1;
+
+ mod_timer(&drv->suspend_timer, jiffies + 1);
+
+ return;
+}
+
+static void gpio_pm_work(struct work_struct *work)
+{
+ struct drv_data *drv = (struct drv_data*)container_of(work, struct drv_data, work);
+
+ D("Action: %d.", drv->action);
+
+ kobject_uevent(&drv->pdev->dev.kobj, drv->action);
+
+ return;
+}
+
+static irqreturn_t gpio_pm_irq(int irq, void *dev_id)
+{
+ struct drv_data *drv = (struct drv_data *)dev_id;
+
+ D("Called.");
+
+ if (!drv->suspend_active)
+ start_suspend(drv);
+
+ return IRQ_HANDLED;
+}
+
+static int gpio_pm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ D("Called.");
+
+ return 0;
+}
+
+static int gpio_pm_resume(struct platform_device *pdev)
+{
+ struct drv_data *drv = (struct drv_data *)platform_get_drvdata(pdev);
+
+ D("Called.");
+
+ start_int_reactive(drv);
+
+ return 0;
+}
+
+static int gpio_pm_probe(struct platform_device *pdev)
+{
+ struct drv_data *drv = &g_drv_data;
+
+ int rv;
+
+ setup_timer(&drv->suspend_timer,
+ suspend_timer_routine, (unsigned long)drv);
+
+ setup_timer(&drv->int_reactive_timer,
+ int_reactive_timer_routine, (unsigned long)drv);
+
+ INIT_WORK(&drv->work, gpio_pm_work);
+
+ platform_set_drvdata(pdev, drv);
+
+ rv = request_irq(GPIO_PM_IRQ, gpio_pm_irq, IRQF_DISABLED, DRV_NAME, drv);
+ if (rv) {
+ printk("Could not get IRQ %d\n", GPIO_PM_IRQ);
+
+ return rv;
+ }
+
+ drv->pdev = pdev;
+
+ gpio_pm_pin_as_irq();
+
+ printk(KERN_INFO JZ_SOC_NAME": GPIO PM Key Driver Registered.");
+
+ return rv;
+}
+
+static int gpio_pm_remove(struct platform_device *pdev)
+{
+ struct drv_data *drv = (struct drv_data *)platform_get_drvdata(pdev);
+
+ free_irq(GPIO_PM_IRQ, drv);
+
+ del_timer(&drv->suspend_timer);
+ del_timer(&drv->int_reactive_timer);
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_device gpio_pm_platform_device = {
+ .name = (char *) DRV_NAME,
+};
+
+static struct platform_driver gpio_pm_platform_driver = {
+ .probe = gpio_pm_probe,
+ .remove = gpio_pm_remove,
+ .suspend = gpio_pm_suspend,
+ .resume = gpio_pm_resume,
+ .driver = {
+ .name = DRV_NAME,
+ },
+};
+
+static int __init gpio_pm_setup(void)
+{
+ platform_driver_register(&gpio_pm_platform_driver);
+
+ return platform_device_register(&gpio_pm_platform_device);
+}
+
+static void __exit gpio_pm_cleanup(void)
+{
+ platform_driver_unregister(&gpio_pm_platform_driver);
+ platform_device_unregister(&gpio_pm_platform_device);
+
+ return;
+}
+
+module_init(gpio_pm_setup);
+module_exit(gpio_pm_cleanup);
diff --git a/drivers/char/jzchar/poweroff.c b/drivers/char/jzchar/poweroff.c
deleted file mode 100644
index e8d1c24a3df..00000000000
--- a/drivers/char/jzchar/poweroff.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * linux/drivers/char/jzchar/poweroff.c
- *
- * Power off handling.
- *
- * Copyright (C) 2005-2007 Ingenic Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * Porting to Linux-2.6.31.3,
- * Use platform suspend/resume PM API.
- * - River <zwang@ingenic.cn>
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-#include <linux/pm.h>
-#include <linux/platform_device.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/jzsoc.h>
-
-#include "jzchars.h"
-
-MODULE_AUTHOR("Jianli Wei <jlwei@ingenic.cn>");
-MODULE_DESCRIPTION("Poweroff handling");
-MODULE_LICENSE("GPL");
-
-#undef DEBUG
-//#define DEBUG
-#ifdef DEBUG
-#define dprintk(x...) printk(x)
-#else
-#define dprintk(x...)
-#endif
-
-//#define USE_SUSPEND_HOTPLUG
-
-#ifdef CONFIG_SOC_JZ4730
-#define GPIO_PW_I 97
-#define GPIO_PW_O 66
-#define POWEROFF_PIN_DOWN 1
-#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_rise_edge(POWEROFF_PIN)
-#define DO_SHUTDOWN_SYSTEM __gpio_clear_pin(GPIO_PW_O)
-#define DO_SUSPEND jz_pm_suspend()
-
-#define GPIO_DISP_OFF_N 93
-#define __lcd_set_backlight_level(n) \
-do { \
- REG_PWM_DUT(0) = n; \
- REG_PWM_PER(0) = 7; \
- REG_PWM_CTR(0) = 0x81; \
-} while (0)
-#define __lcd_close_backlight() \
-do { \
- __lcd_set_backlight_level(0); \
-} while (0)
-#endif
-
-#ifdef CONFIG_SOC_JZ4740
-#define GPIO_PW_I 125
-#define POWEROFF_PIN_DOWN 0
-#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN)
-#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate()
-#define DO_SUSPEND { \
- jz_pm_sleep();\
- suspend_flag = 0;\
- SET_POWEROFF_PIN_AS_IRQ;\
- }
-
-#define GPIO_DISP_OFF_N 118
-#define GPIO_PWM 123
-#define __lcd_close_backlight() \
-do { \
-__gpio_as_output(GPIO_PWM); \
-__gpio_clear_pin(GPIO_PWM); \
-} while (0)
-#endif
-
-#ifdef CONFIG_SOC_JZ4750
-#define GPIO_PW_I GPIO_WAKEUP
-#define POWEROFF_PIN_DOWN 0
-#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN)
-#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate()
-#define DO_SUSPEND { \
- jz_pm_sleep();\
- suspend_flag = 0;\
- SET_POWEROFF_PIN_AS_IRQ;\
- }
-#endif
-
-#ifdef CONFIG_SOC_JZ4750D
-#define GPIO_PW_I GPIO_WAKEUP
-#define POWEROFF_PIN_DOWN 0
-#define SET_POWEROFF_PIN_AS_IRQ __gpio_as_irq_fall_edge(POWEROFF_PIN)
-#define DO_SHUTDOWN_SYSTEM jz_pm_hibernate()
-#define DO_SUSPEND { \
- jz_pm_sleep();\
- suspend_flag = 0;\
- SET_POWEROFF_PIN_AS_IRQ;\
- }
-#endif
-
-
-#define POWEROFF_PIN GPIO_PW_I
-#define POWEROFF_IRQ (IRQ_GPIO_0 + POWEROFF_PIN)
-
-#define POWEROFF_PERIOD 1000 /* unit: ms */
-#define POWEROFF_DELAY 100 /* unit: ms */
-
-static struct timer_list poweroff_timer;
-static struct timer_list poweroff_delaytimer;
-static struct work_struct suspend_work;
-
-static int poweroff_flag = 0;
-static int suspend_flag = 0;
-static int num_seconds = 0;
-
-#ifdef CONFIG_JZ_UDC_HOTPLUG
-extern int jz_udc_active;
-#endif
-
-extern void jz_pm_suspend(void);
-extern int jz_pm_hibernate(void);
-extern int jz_pm_sleep(void);
-
-static void poweroff_timer_routine(unsigned long dummy)
-{
- if (__gpio_get_pin(POWEROFF_PIN) == POWEROFF_PIN_DOWN) {
- if (++num_seconds > 3)
- {
- printk("\nShutdown system now ..\n");
-
-#ifndef USE_SUSPEND_HOTPLUG
- /* Turn off LCD to inform user that the system is shutting down.
- * But the information of shutting down system will be shown
- * by userspace program if hotplug is used.
- */
- __lcd_close_backlight();
-#endif
-
- /*
- * Wait until the power key is up, or the system will reset with
- * power key down after entering hibernate.
- */
- while(__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN);
-
- poweroff_flag = 1;
- schedule_work(&suspend_work); /* inform user to poweroff */
- }
- else {
- del_timer(&poweroff_timer);
- init_timer(&poweroff_timer);
- poweroff_timer.expires = jiffies + POWEROFF_PERIOD/10;
- poweroff_timer.data = 0;
- poweroff_timer.function = poweroff_timer_routine;
- add_timer(&poweroff_timer);
- }
- }
- else
- {
- printk("\nSuspend system now ..\n");
- num_seconds = 0;
- suspend_flag = 1;
- poweroff_flag = 0;
- schedule_work(&suspend_work); /* we are entering suspend */
- }
-}
-
-static void poweroff_delaytimer_routine(unsigned long dummy)
-{
- __gpio_as_input(POWEROFF_PIN);
- if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN) {
- if (suspend_flag) {
- suspend_flag = 0;
- del_timer(&poweroff_delaytimer);
- SET_POWEROFF_PIN_AS_IRQ;
- __gpio_unmask_irq(POWEROFF_PIN);
- return;
- }
- del_timer(&poweroff_delaytimer);
- del_timer(&poweroff_timer);
- init_timer(&poweroff_timer);
- poweroff_timer.expires = jiffies + POWEROFF_PERIOD/100;
- poweroff_timer.data = 0;
- poweroff_timer.function = poweroff_timer_routine;
- add_timer(&poweroff_timer);
- }
- else {
- del_timer(&poweroff_delaytimer);
- SET_POWEROFF_PIN_AS_IRQ;
- __gpio_unmask_irq(POWEROFF_PIN);
-
- printk("This is a dummy key\n");
- }
-}
-
-/*
- * Poweroff pin interrupt handler
- */
-static irqreturn_t poweroff_irq(int irq, void *dev_id)
-{
- __gpio_ack_irq(POWEROFF_PIN);
- __gpio_mask_irq(POWEROFF_PIN);
- __gpio_as_input(POWEROFF_PIN);
-#ifdef CONFIG_JZ_UDC_HOTPLUG
- if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN && jz_udc_active == 0){
-#else
- if (__gpio_get_pin(POWEROFF_PIN)==POWEROFF_PIN_DOWN){
-#endif
- del_timer(&poweroff_delaytimer);
- init_timer(&poweroff_delaytimer);
- poweroff_delaytimer.expires = jiffies + POWEROFF_DELAY/10;
- poweroff_delaytimer.data = 0;
- poweroff_delaytimer.function = poweroff_delaytimer_routine;
- add_timer(&poweroff_delaytimer);
- }
- else {
-
-/*
- * If it reaches here without jz_udc_active == 0, then it indicates POWEROFF_PIN was
- * changed to WAKEUP key in pm.c for hand is not able to rise up so quickly, so the
- * irq handler entered because of WAKEUP key not POWEROFF_PIN.
- */
-
-#ifdef CONFIG_JZ_UDC_HOTPLUG
- if (jz_udc_active == 1)
- printk("\nUSB is working; Operation is denied\n");
-#endif
- SET_POWEROFF_PIN_AS_IRQ;
- __gpio_unmask_irq(POWEROFF_PIN);
- }
-
- return IRQ_HANDLED;
-}
-
-#ifdef USE_SUSPEND_HOTPLUG
-static void run_sbin_hotplug(int state)
-{
- int i;
- char *argv[3], *envp[8];
- char media[64], slotnum[16];
- if (!uevent_helper[0])
- return;
-
- i = 0;
- argv[i++] = uevent_helper;
- //argv[i++] = "home/lhhuang/hotplug";
-
- if ( poweroff_flag == 1 )
- argv[i++] = "poweroff";
- else
- argv[i++] = "suspend";
-
- argv[i] = 0;
-
- /* minimal command environment */
- i = 0;
- envp[i++] = "HOME=/";
- envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
- /* other stuff we want to pass to /sbin/hotplug */
- sprintf(slotnum, "SLOT=0");
-
- if ( poweroff_flag == 1 )
- sprintf(media, "MEDIA=poweroff");
- else
- sprintf(media, "MEDIA=suspend");
-
- envp[i++] = slotnum;
- envp[i++] = media;
-
- if (state)
- envp[i++] = "ACTION=enter";
- else
- envp[i++] = "ACTION=exit";
-
- envp[i] = 0;
-
- dprintk("SUSPEND: hotplug path=%s state=%d\n", argv[0], state);
-
- SET_POWEROFF_PIN_AS_IRQ;
- __gpio_unmask_irq(POWEROFF_PIN); /* set it because call hotplug with call_usermodehelper() \
- might failed, especially when using nfsroot */
-
- call_usermodehelper (argv [0], argv, envp, -1);
-}
-#endif
-
-static void suspend_handler(struct work_struct *work)
-{
-#ifdef USE_SUSPEND_HOTPLUG
- int state = 1;
- run_sbin_hotplug(state);
-#else
- if (poweroff_flag) {
- dprintk("DO_SHUTDOWN_SYSTEM\n");
- DO_SHUTDOWN_SYSTEM;
- } else {
- dprintk("DO_SUSPEND\n");
- DO_SUSPEND;
- }
-#endif
-}
-
-#ifdef CONFIG_PM
-static int poweroff_suspend(struct platform_device *pdev, pm_message_t state)
-{
- printk("%s(): Called.\n", __func__);
-
- suspend_flag = 1;
- poweroff_flag = 0;
-
- return 0;
-}
-
-static int poweroff_resume(struct platform_device *pdev)
-{
- printk("%s(): Called.\n", __func__);
-
- suspend_flag = 0;
- SET_POWEROFF_PIN_AS_IRQ;
- __gpio_unmask_irq(POWEROFF_PIN);
-
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static int __devinit poweroff_probe(struct platform_device *pdev)
-{
- int retval;
-
- retval = request_irq(POWEROFF_IRQ, poweroff_irq,
- IRQF_DISABLED, "poweroff", NULL);
-
- SET_POWEROFF_PIN_AS_IRQ;
-
- if (retval) {
- printk("Could not get poweroff irq %d\n", POWEROFF_IRQ);
- return retval;
- }
-
- INIT_WORK(&suspend_work, suspend_handler);
-
- printk(KERN_INFO JZ_SOC_NAME": Power GPIO Button driver registered.\n");
- return 0;
-}
-
-static int __devexit poweroff_remove(struct platform_device *pdev)
-{
- free_irq(POWEROFF_IRQ, NULL);
-
- return 0;
-}
-
-static void jz_poweroff_release(struct device *dev)
-{
- return;
-}
-
-static struct platform_device jz_poweroff_device = {
- .name = "jz-poweroff",
- .id = -1,
- .dev = {
- .release = jz_poweroff_release,
- },
-};
-
-static struct platform_driver jz_poweroff_driver = {
- .probe = poweroff_probe,
- .remove = __devexit_p(poweroff_remove),
- .suspend = poweroff_suspend,
- .resume = poweroff_resume,
- .driver = {
- .name = "jz-poweroff",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init jz_poweroff_init(void)
-{
- int rv;
- rv = platform_driver_register(&jz_poweroff_driver);
- if (rv)
- return rv;
-
- return platform_device_register(&jz_poweroff_device);
-}
-
-static void __exit jz_poweroff_cleanup(void)
-{
- platform_driver_unregister(&jz_poweroff_driver);
-}
-
-module_init(jz_poweroff_init);
-module_exit(jz_poweroff_cleanup);
-
diff --git a/drivers/char/jzchar/sensor.c b/drivers/char/jzchar/sensor.c
deleted file mode 100644
index 8ad08203cad..00000000000
--- a/drivers/char/jzchar/sensor.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * linux/drivers/char/jzchar/sensor.c
- *
- * Common CMOS Camera Sensor Driver
- *
- * Copyright (C) 2006 Ingenic Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/jzsoc.h>
-
-#include "jzchars.h"
-
-MODULE_AUTHOR("Jianli Wei<jlwei@ingenic.cn>");
-MODULE_DESCRIPTION("Common CMOS Camera Sensor Driver");
-MODULE_LICENSE("GPL");
-
-/*
- * ioctl commands
- */
-#define IOCTL_SET_ADDR 0 /* set i2c address */
-#define IOCTL_SET_CLK 1 /* set i2c clock */
-#define IOCTL_WRITE_REG 2 /* write sensor register */
-#define IOCTL_READ_REG 3 /* read sensor register */
-
-/*
- * i2c related
- */
-static unsigned int i2c_addr = 0x42;
-static unsigned int i2c_clk = 100000;
-
-static void write_reg(u8 reg, u8 val)
-{
- i2c_open();
- i2c_setclk(i2c_clk);
- i2c_write((i2c_addr >> 1), &val, reg, 1);
- i2c_close();
-}
-
-static u8 read_reg(u8 reg)
-{
- u8 val;
-
- i2c_open();
- i2c_setclk(i2c_clk);
- i2c_read((i2c_addr >> 1), &val, reg, 1);
- i2c_close();
- return val;
-}
-
-/*
- * fops routines
- */
-
-static int sensor_open(struct inode *inode, struct file *filp);
-static int sensor_release(struct inode *inode, struct file *filp);
-static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l);
-static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l);
-static int sensor_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
-
-static struct file_operations sensor_fops =
-{
- open: sensor_open,
- release: sensor_release,
- read: sensor_read,
- write: sensor_write,
- ioctl: sensor_ioctl,
-};
-
-static int sensor_open(struct inode *inode, struct file *filp)
-{
- try_module_get(THIS_MODULE);
- return 0;
-}
-
-static int sensor_release(struct inode *inode, struct file *filp)
-{
- module_put(THIS_MODULE);
- return 0;
-}
-
-static ssize_t sensor_read(struct file *filp, char *buf, size_t size, loff_t *l)
-{
- printk("sensor: read is not implemented\n");
- return -1;
-}
-
-static ssize_t sensor_write(struct file *filp, const char *buf, size_t size, loff_t *l)
-{
- printk("sensor: write is not implemented\n");
- return -1;
-}
-
-static int sensor_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
- int ret = 0;
-
- switch (cmd) {
- case IOCTL_SET_ADDR:
- if (copy_from_user(&i2c_addr, (void *)arg, 4))
- return -EFAULT;
- break;
- case IOCTL_SET_CLK:
- if (copy_from_user(&i2c_clk, (void *)arg, 4))
- return -EFAULT;
- break;
- case IOCTL_WRITE_REG:
- {
- u8 regval[2];
-
- if (copy_from_user(regval, (void *)arg, 2))
- return -EFAULT;
-
- write_reg(regval[0], regval[1]);
- break;
- }
- case IOCTL_READ_REG:
- {
- u8 reg, val;
-
- if (copy_from_user(&reg, (void *)arg, 1))
- return -EFAULT;
-
- val = read_reg(reg);
-
- if (copy_to_user((void *)(arg + 1), &val, 1))
- return -EFAULT;
- break;
- }
- default:
- printk("Not supported command: 0x%x\n", cmd);
- return -EINVAL;
- break;
- }
- return ret;
-}
-
-/*
- * Module init and exit
- */
-
-static int __init sensor_init(void)
-{
- int ret;
-
- ret = jz_register_chrdev(SENSOR_MINOR, "sensor", &sensor_fops, NULL);
- if (ret < 0) {
- return ret;
- }
-
- printk(JZ_SOC_NAME ": Ingenic CMOS camera sensor driver registered\n");
-
- return 0;
-}
-
-static void __exit sensor_exit(void)
-{
- jz_unregister_chrdev(SENSOR_MINOR, "sensor");
-}
-
-module_init(sensor_init);
-module_exit(sensor_exit);
diff --git a/drivers/char/jzchar/udc_hotplug.c b/drivers/char/jzchar/udc_hotplug.c
deleted file mode 100644
index 5115033c634..00000000000
--- a/drivers/char/jzchar/udc_hotplug.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * linux/drivers/char/jzchar/udc_hotplug.c
- *
- * New UDC hotplug driver.
- *
- * Copyright (C) 2007 Ingenic Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/kthread.h>
-#include <linux/socket.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-#include <linux/kobject.h>
-#include <linux/miscdevice.h>
-
-#include <asm/jzsoc.h>
-#include "jzchars.h"
-
-#ifndef GPIO_UDC_HOTPLUG
-#define GPIO_UDC_HOTPLUG 86
-#endif
-
-#define UDC_HOTPLUG_PIN GPIO_UDC_HOTPLUG
-#define UDC_HOTPLUG_IRQ (IRQ_GPIO_0 + UDC_HOTPLUG_PIN)
-
-#define dprintk(x,...)
-
-//simple meaning define
-#define NOT_CONNECT 0
-#define YES_CONNECT 1
-#define MAX_GPIO_TIME 50
-
-#define EVENT_USB_ADD 1
-#define EVENT_USB_REMOVE 2
-#define EVENT_POWER_ADD 3
-#define EVENT_POWER_REMOVE 4
-#define EVENT_POWER_TO_USB 5
-#define EVENT_USB_SUSPEND_POWER 6
-
-struct udc_pnp_stat
-{
- char cable_stat, old_cable_stat;
- char protl_stat, old_protl_stat;
- char object_stat1;
- char object_stat2;
-};
-
-static struct udc_pnp_stat cur_pnp_stat;
-
-static struct file_operations cable_fops = {
- owner: THIS_MODULE,
-};
-
-static struct miscdevice cable_dev=
-{
- 231,
- "udc_cable",
- &cable_fops
-};
-
-static struct file_operations power_fops = {
- owner: THIS_MODULE,
-};
-
-static struct miscdevice power_dev=
-{
- 232,
- "power_cable",
- &power_fops
-};
-
-int jz_udc_active = 0; /* 0: Have no actions; 1: Have actions */
-
-static int udc_pin_level;
-static int udc_old_state;
-static int udc_pin_time;
-
-static struct timer_list udc_long_timer, udc_gpio_timer;
-
-/* Kernel thread to deliver event to user space */
-static struct task_struct *kudcd_task;
-
-static void udc_gpio_timer_routine(unsigned long data)
-{
- wake_up_process(kudcd_task);
-}
-
-static void udc_long_timer_routine(unsigned long data)
-{
- dprintk("udc_timer\n");
- if (jz_udc_active)
- udc_old_state = 1;
- if (!jz_udc_active && udc_old_state) //udc irq timeout! do suspend
- {
- dprintk("udc suspend!\n");
- udc_old_state = 0;
- cur_pnp_stat.protl_stat = NOT_CONNECT;
- del_timer(&udc_long_timer);
- wake_up_process(kudcd_task);
- return;
- }
- jz_udc_active = 0;
- udc_long_timer.expires = jiffies + 3 * HZ; /* about 3 s */
- add_timer(&udc_long_timer);
-}
-
-static int udc_get_pnp_stat(void)
-{
- udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN);
- udc_pin_time = 1;
-
- init_timer(&udc_gpio_timer);
- del_timer(&udc_gpio_timer);
- udc_gpio_timer.function = udc_gpio_timer_routine;
- udc_gpio_timer.expires = jiffies + 1; /* about 10 ms */
- add_timer(&udc_gpio_timer);
-
- while(1)
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
-
- if (__gpio_get_pin(UDC_HOTPLUG_PIN) != udc_pin_level)
- {
- udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN);
- udc_pin_time = 1;
- dprintk("udc gpio detect restart! \n");
- }
-
- udc_pin_time ++;
- if (udc_pin_time > MAX_GPIO_TIME)
- break;
-
- del_timer(&udc_gpio_timer);
- udc_gpio_timer.function = udc_gpio_timer_routine;
- udc_gpio_timer.expires = jiffies + 1; /* about 10 ms */
- add_timer(&udc_gpio_timer);
- }
-
- del_timer(&udc_gpio_timer);
- if (__gpio_get_pin(UDC_HOTPLUG_PIN))
- return YES_CONNECT;
- else
- return NOT_CONNECT;
-}
-
-static void udc_get_cable(void)
-{
- u32 intr_usb;
-
- __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;
-
- dprintk("enable phy! %x %x %x %x %x\n",
- REG8(USB_REG_POWER),
- REG_CPM_SCR,
- REG16(USB_REG_INTRINE),
- REG16(USB_REG_INTROUTE),
- REG8(USB_REG_INTRUSBE));
-
- init_timer(&udc_gpio_timer);
- del_timer(&udc_gpio_timer);
- udc_gpio_timer.function = udc_gpio_timer_routine;
- udc_gpio_timer.expires = jiffies + 11; /* about 100 ms */
- add_timer(&udc_gpio_timer);
- /* Sleep a short time to see result */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
-
- del_timer(&udc_gpio_timer);
- intr_usb = REG8(USB_REG_INTRUSB);
- if ((intr_usb & USB_INTR_RESET) ||
- (intr_usb & USB_INTR_RESUME) ||
- (intr_usb & USB_INTR_SUSPEND))
- {
- cur_pnp_stat.protl_stat = YES_CONNECT;
- dprintk("cable is usb! \n");
- }
- else
- {
- cur_pnp_stat.protl_stat = NOT_CONNECT;
- dprintk("cable is power! \n");
- }
-
- /* 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);
-}
-
-static void send_event_udev(int event)
-{
- dprintk("Send udev message: cable=%d old=%d protl=%d old=%d \n",
- cur_pnp_stat.cable_stat,
- cur_pnp_stat.old_cable_stat,
- cur_pnp_stat.protl_stat,
- cur_pnp_stat.old_protl_stat);
-
- switch (event)
- {
- case EVENT_USB_ADD:
- printk("usb cable insert! \n");
- misc_register(&cable_dev);
- kobject_uevent(&cable_dev.this_device->kobj, KOBJ_ADD);
- init_timer(&udc_long_timer);
- del_timer(&udc_long_timer);
- udc_long_timer.function = udc_long_timer_routine;
- udc_long_timer.expires = jiffies + 3 * HZ; /* about 3 s */
- add_timer(&udc_long_timer);
- break;
- case EVENT_USB_REMOVE:
- printk("usb cable remove! \n");
- kobject_uevent(&cable_dev.this_device->kobj, KOBJ_REMOVE);
- misc_deregister(&cable_dev);
- del_timer(&udc_long_timer);
- break;
- case EVENT_POWER_ADD:
- printk("power cable insert! \n");
- misc_register(&power_dev);
- kobject_uevent(&power_dev.this_device->kobj, KOBJ_ADD);
- break;
- case EVENT_POWER_REMOVE:
- printk("power cable remove! \n");
- kobject_uevent(&power_dev.this_device->kobj, KOBJ_REMOVE);
- misc_deregister(&power_dev);
- break;
- case EVENT_POWER_TO_USB:
- printk("change power cable to usb! \n");
- kobject_uevent(&power_dev.this_device->kobj, KOBJ_REMOVE);
- misc_deregister(&power_dev);
- misc_register(&cable_dev);
- kobject_uevent(&cable_dev.this_device->kobj, KOBJ_ADD);
- break;
- case EVENT_USB_SUSPEND_POWER:
- printk("usb cable suspend! \n");
- printk("as power cable insert! \n");
- kobject_uevent(&cable_dev.this_device->kobj, KOBJ_REMOVE);
- misc_deregister(&cable_dev);
- misc_register(&power_dev);
- kobject_uevent(&power_dev.this_device->kobj, KOBJ_ADD);
- break;
- };
-}
-
-static void udc_pnp_detect(void)
-{
- if (cur_pnp_stat.cable_stat == YES_CONNECT) /* already connected! */
- {
- if (udc_get_pnp_stat() == NOT_CONNECT)
- {
- dprintk("cable real out! \n");
- cur_pnp_stat.cable_stat = NOT_CONNECT;
- cur_pnp_stat.protl_stat = NOT_CONNECT;
- /* Deliver this event to user space in udev model */
- if (cur_pnp_stat.old_protl_stat)
- send_event_udev(EVENT_USB_REMOVE);
- else
- send_event_udev(EVENT_POWER_REMOVE);
- cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat;
- cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat;
- }
- else
- {
- if (cur_pnp_stat.old_protl_stat != cur_pnp_stat.protl_stat)
- {
- send_event_udev(EVENT_USB_SUSPEND_POWER);
- cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat;
- cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat;
- }
- else //change power to cable
- {
-#if 0 //not support yet!
- udc_get_cable();
- if (cur_pnp_stat.old_protl_stat != cur_pnp_stat.protl_stat)
- send_event_udev(EVENT_POWER_TO_USB);
- cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat;
- cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat;
-#endif
- }
- }
- }
- else
- {
- if (udc_get_pnp_stat() == YES_CONNECT)
- {
- dprintk("cable real in! \n");
- cur_pnp_stat.cable_stat = YES_CONNECT;
- udc_get_cable();
- /* Deliver this event to user space in udev model */
- if (cur_pnp_stat.protl_stat)
- send_event_udev(EVENT_USB_ADD);
- else
- send_event_udev(EVENT_POWER_ADD);
- cur_pnp_stat.old_cable_stat = cur_pnp_stat.cable_stat;
- cur_pnp_stat.old_protl_stat = cur_pnp_stat.protl_stat;
- }
- else
- dprintk("cable false in! \n");
-
- }
-}
-
-static void udc_pnp_set_gpio(void)
-{
- if (cur_pnp_stat.cable_stat == YES_CONNECT)
- __gpio_as_irq_fall_edge(UDC_HOTPLUG_PIN);
- else
- __gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN);
-
- /* clear interrupt pending status */
- __gpio_ack_irq(UDC_HOTPLUG_PIN);
- /* unmask interrupt */
- __gpio_unmask_irq(UDC_HOTPLUG_PIN);
-}
-
-static int udc_pnp_thread(void *unused)
-{
- printk(KERN_NOTICE "UDC starting pnp monitor thread\n");
-
- while(1)
- {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
-
- dprintk("pnp thread wake up! \n");
- /* wake up here */
- udc_pnp_detect();
- /* Reset gpio state last */
- udc_pnp_set_gpio();
- }
-}
-
-static irqreturn_t udc_pnp_irq(int irq, void *dev_id)
-{
- printk("udc_pnp_irq----\n");
- /* clear interrupt pending status */
- __gpio_ack_irq(UDC_HOTPLUG_PIN);
- /* mask interrupt */
- __gpio_mask_irq(UDC_HOTPLUG_PIN);
- /* wake up pnp detect thread */
- wake_up_process(kudcd_task);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Module init and exit
- */
-static int __init udc_hotplug_init(void)
-{
- int retval;
- /* Init pnp stat first */
- cur_pnp_stat.cable_stat = NOT_CONNECT;
- cur_pnp_stat.protl_stat = NOT_CONNECT;
- cur_pnp_stat.old_cable_stat = NOT_CONNECT;
- cur_pnp_stat.old_protl_stat = NOT_CONNECT;
- cur_pnp_stat.object_stat1 = NOT_CONNECT;
- cur_pnp_stat.object_stat2 = NOT_CONNECT;
- udc_old_state = 0;
-
- /* create pnp thread and register IRQ */
- kudcd_task = kthread_run(udc_pnp_thread, NULL, "kudcd");
- if (IS_ERR(kudcd_task)) {
- printk(KERN_ERR "jz_udc_hotplug: Failed to create system monitor thread.\n");
- return PTR_ERR(kudcd_task);
- }
-
- retval = request_irq(UDC_HOTPLUG_IRQ, udc_pnp_irq,
- IRQF_DISABLED, "udc_pnp", NULL);
- if (retval) {
- printk("Could not get udc hotplug irq %d\n", UDC_HOTPLUG_IRQ);
- return retval;
- }
-
- /* get current pin level */
- __gpio_disable_pull(UDC_HOTPLUG_PIN);
- __gpio_as_input(UDC_HOTPLUG_PIN);
- udelay(1);
- udc_pin_level = __gpio_get_pin(UDC_HOTPLUG_PIN);
-
- if (udc_pin_level) {
- dprintk("Cable already in! \n");
- /* Post a event */
- wake_up_process(kudcd_task);
- }
- else {
- __gpio_as_irq_rise_edge(UDC_HOTPLUG_PIN);
- dprintk("Cable not in! \n");
- }
-
- printk(JZ_SOC_NAME": UDC hotplug driver registered.\n");
-
- return 0;
-}
-
-static void __exit udc_hotplug_exit(void)
-{
- free_irq(UDC_HOTPLUG_IRQ, NULL);
-}
-
-module_init(udc_hotplug_init);
-module_exit(udc_hotplug_exit);
-
-EXPORT_SYMBOL(jz_udc_active);
-
-MODULE_AUTHOR("Lucifer <yliu@ingenic.cn>");
-MODULE_DESCRIPTION("JzSOC OnChip udc hotplug driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/char/rtc-jz4760.c b/drivers/char/rtc-jz4760.c
new file mode 100644
index 00000000000..2d4356a9f6f
--- /dev/null
+++ b/drivers/char/rtc-jz4760.c
@@ -0,0 +1,470 @@
+/*
+ * Real Time Clock interface for Jz4760.
+ *
+ * Copyright (C) 2005-2009, Ingenic Semiconductor Inc.
+ *
+ * Author: Richard Feng <cjfeng@ingenic.cn>
+ * Regen Huang <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+
+#include <asm/irq.h>
+#include <asm/jzsoc.h>
+
+#define TIMER_FREQ CLOCK_TICK_RATE
+
+/* The divider is decided by the RTC clock frequency. */
+#define RTC_FREQ_DIVIDER (32768 - 1)
+
+#define ms2clycle(x) (((x) * RTC_FREQ_DIVIDER) / 1000)
+
+/* Default time for the first-time power on */
+static struct rtc_time default_tm = {
+ .tm_year = (2010 - 1900), // year 2010
+ .tm_mon = (10 - 1), // month 10
+ .tm_mday = 1, // day 1
+ .tm_hour = 12,
+ .tm_min = 0,
+ .tm_sec = 0
+};
+
+static unsigned long rtc_freq = 1024;
+static struct rtc_time rtc_alarm;
+static DEFINE_SPINLOCK(jz4760_rtc_lock);
+
+static inline int rtc_periodic_alarm(struct rtc_time *tm)
+{
+ return (tm->tm_year == -1) ||
+ ((unsigned)tm->tm_mon >= 12) ||
+ ((unsigned)(tm->tm_mday - 1) >= 31) ||
+ ((unsigned)tm->tm_hour > 23) ||
+ ((unsigned)tm->tm_min > 59) ||
+ ((unsigned)tm->tm_sec > 59);
+}
+
+/*
+ * Calculate the next alarm time given the requested alarm time mask
+ * and the current time.
+ */
+static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
+{
+ unsigned long next_time;
+ unsigned long now_time;
+
+ next->tm_year = now->tm_year;
+ next->tm_mon = now->tm_mon;
+ next->tm_mday = now->tm_mday;
+ next->tm_hour = alrm->tm_hour;
+ next->tm_min = alrm->tm_min;
+ next->tm_sec = alrm->tm_sec;
+
+ rtc_tm_to_time(now, &now_time);
+ rtc_tm_to_time(next, &next_time);
+
+ if (next_time < now_time) {
+ /* Advance one day */
+ next_time += 60 * 60 * 24;
+ rtc_time_to_tm(next_time, next);
+ }
+}
+static int rtc_update_alarm(unsigned int now,struct rtc_time *alrm,unsigned long *time)
+{
+ struct rtc_time alarm_tm, now_tm;
+ rtc_time_to_tm(now, &now_tm);
+ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); //?
+ return rtc_tm_to_time(&alarm_tm, time);
+}
+
+#define IS_RTC_IRQ(x,y) (((x) & (y)) == (y))
+
+static irqreturn_t jz4760_rtc_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = to_platform_device(dev_id);
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+ unsigned int rtsr,save_rtsr;
+ unsigned long events;
+
+ spin_lock(&jz4760_rtc_lock);
+
+ rtsr = rtc_read_reg(RTC_RTCCR);
+ save_rtsr = rtsr;
+ //is rtc interrupt
+ events = 0;
+ if(IS_RTC_IRQ(rtsr,RTCCR_AF))
+ {
+ events = RTC_AF | RTC_IRQF;
+ rtsr &= ~RTCCR_AF;
+
+ if(rtc_periodic_alarm(&rtc_alarm) == 0)
+ rtsr &= ~(RTCCR_AIE | RTCCR_AE);
+ else
+ {
+ unsigned int now = rtc_read_reg(RTC_RTCSR);
+ unsigned long time;
+ rtc_update_alarm(now,&rtc_alarm,&time);
+ rtc_write_reg(RTC_RTCSAR,time);
+
+ }
+ }
+ if(IS_RTC_IRQ(rtsr,RTCCR_1HZ))
+ {
+ rtsr &= ~(RTCCR_1HZ);
+ events = RTC_UF | RTC_IRQF;
+ }
+ if(events != 0)
+ rtc_update_irq(rtc, 1, events);
+ if(rtsr != save_rtsr)
+ rtc_write_reg(RTC_RTCCR,rtsr);
+ spin_unlock(&jz4760_rtc_lock);
+ return IRQ_HANDLED;
+}
+
+#if 0
+static int rtc_timer1_count;
+static irqreturn_t timer1_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = to_platform_device(dev_id);
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ /*
+ * If we match for the first time, rtc_timer1_count will be 1.
+ * Otherwise, we wrapped around (very unlikely but
+ * still possible) so compute the amount of missed periods.
+ * The match reg is updated only when the data is actually retrieved
+ * to avoid unnecessary interrupts.
+ */
+ OSSR = OSSR_M1; /* clear match on timer1 */
+
+ rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
+
+ if (rtc_timer1_count == 1)
+ rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
+
+ return IRQ_HANDLED;
+}
+#endif
+
+#if 0
+static int jz4760_rtc_read_callback(struct device *dev, int data)
+{
+ if (data & RTC_PF) {
+ /* interpolate missed periods and set match for the next */
+ unsigned long period = TIMER_FREQ/rtc_freq;
+ unsigned long oscr = OSCR;
+ unsigned long osmr1 = OSMR1;
+ unsigned long missed = (oscr - osmr1)/period;
+ data += missed << 8;
+ OSSR = OSSR_M1; /* clear match on timer 1 */
+ OSMR1 = osmr1 + (missed + 1)*period;
+ /* Ensure we didn't miss another match in the mean time.
+ * Here we compare (match - OSCR) 8 instead of 0 --
+ * see comment in pxa_timer_interrupt() for explanation.
+ */
+ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
+ data += 0x100;
+ OSSR = OSSR_M1; /* clear match on timer 1 */
+ OSMR1 = osmr1 + period;
+ }
+ }
+ return data;
+}
+#endif
+
+static int jz4760_rtc_open(struct device *dev)
+{
+ int ret;
+
+ ret = request_irq(IRQ_RTC, jz4760_rtc_interrupt, IRQF_DISABLED,
+ "rtc 1Hz and alarm", dev);
+ if (ret) {
+ dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC);
+ goto fail_ui;
+ }
+
+ /*ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED,
+ "rtc timer", dev);
+ if (ret) {
+ dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1);
+ goto fail_pi;
+ }*/
+
+ return 0;
+
+ fail_ui:
+ free_irq(IRQ_RTC, dev);
+ return ret;
+}
+
+static void jz4760_rtc_release(struct device *dev)
+{
+ spin_lock_irq(&jz4760_rtc_lock);
+
+ spin_unlock_irq(&jz4760_rtc_lock);
+ //free_irq(IRQ_OST1, dev);
+ free_irq(IRQ_RTC, dev);
+}
+
+static int jz4760_rtc_ioctl(struct device *dev, unsigned int cmd,
+ unsigned long arg)
+{
+ unsigned int tmp;
+ switch(cmd) {
+ case RTC_AIE_OFF:
+ spin_lock_irq(&jz4760_rtc_lock);
+ rtc_clr_reg(RTC_RTCCR, RTCCR_AIE | RTCCR_AE | RTCCR_AF);
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_AIE_ON:
+ spin_lock_irq(&jz4760_rtc_lock);
+ tmp = rtc_read_reg(RTC_RTCCR);
+ tmp &= ~RTCCR_AF;
+ tmp |= RTCCR_AIE | RTCCR_AE;
+ rtc_write_reg(RTC_RTCCR, tmp);
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_UIE_OFF:
+ spin_lock_irq(&jz4760_rtc_lock);
+ rtc_clr_reg(RTC_RTCCR, RTCCR_1HZ | RTCCR_1HZIE);
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_UIE_ON:
+ spin_lock_irq(&jz4760_rtc_lock);
+ tmp = rtc_read_reg(RTC_RTCCR);
+ tmp &= ~RTCCR_1HZ;
+ tmp |= RTCCR_1HZIE;
+ rtc_write_reg(RTC_RTCCR, tmp);
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_PIE_OFF:
+ spin_lock_irq(&jz4760_rtc_lock);
+ printk("no implement!\n");
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_PIE_ON:
+ spin_lock_irq(&jz4760_rtc_lock);
+ printk("no implement!\n");
+ spin_unlock_irq(&jz4760_rtc_lock);
+ return 0;
+ case RTC_IRQP_READ:
+ return put_user(rtc_freq, (unsigned long *)arg);
+ case RTC_IRQP_SET:
+ if (arg < 1 || arg > TIMER_FREQ)
+ return -EINVAL;
+ rtc_freq = arg;
+ return 0;
+ }
+ return -ENOIOCTLCMD;
+}
+
+static int jz4760_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long time;
+ int ret;
+
+ ret = rtc_tm_to_time(tm, &time);
+ if (ret == 0) {
+ rtc_write_reg(RTC_RTCSR, time);
+ }
+ return ret;
+}
+
+static int jz4760_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned int tmp;
+ tmp = rtc_read_reg(RTC_RTCSR);
+ rtc_time_to_tm(tmp, tm);
+
+ if (rtc_valid_tm(tm) < 0) {
+ /* Set the default time */
+ jz4760_rtc_set_time(dev, &default_tm);
+ tmp = rtc_read_reg(RTC_RTCSR);
+ rtc_time_to_tm(tmp, tm);
+ }
+ return 0;
+}
+
+static int jz4760_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ unsigned int rtc_rcr,tmp;
+ tmp = rtc_read_reg(RTC_RTCSAR);
+ rtc_time_to_tm(tmp, &rtc_alarm);
+ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
+ rtc_rcr = rtc_read_reg(RTC_RTCCR);
+ alrm->enabled = (rtc_rcr & RTCCR_AIE) ? 1 : 0;
+ alrm->pending = (rtc_rcr & RTCCR_AF) ? 1 : 0;
+ return 0;
+}
+
+static int jz4760_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ int ret = 0;
+ unsigned int now;
+ unsigned long time;
+ unsigned int tmp;
+ spin_lock_irq(&jz4760_rtc_lock);
+ now = rtc_read_reg(RTC_RTCSR);
+ rtc_update_alarm(now,&alrm->time,&time);
+ rtc_write_reg(RTC_RTCSAR, time);
+ if(alrm->enabled)
+ {
+ tmp = rtc_read_reg(RTC_RTCCR);
+ tmp &= ~RTCCR_AF;
+ tmp |= RTCCR_AIE | RTCCR_AE;
+ rtc_write_reg(RTC_RTCCR, tmp);
+ }else
+ {
+ rtc_clr_reg(RTC_RTCCR, RTCCR_AIE | RTCCR_AE | RTCCR_AF);
+ }
+ spin_unlock_irq(&jz4760_rtc_lock);
+
+ return ret;
+}
+
+static int jz4760_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+ seq_printf(seq, "RTC regulator\t: 0x%08x\n", rtc_read_reg(RTC_RTCGR));
+ seq_printf(seq, "update_IRQ\t: %s\n",
+ (rtc_read_reg(RTC_RTCCR) & RTCCR_1HZIE) ? "yes" : "no");
+ /*seq_printf(seq, "periodic_IRQ\t: %s\n",
+ (OIER & OIER_E1) ? "yes" : "no");*/
+ seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq);
+
+ return 0;
+}
+
+static const struct rtc_class_ops jz4760_rtc_ops = {
+ .open = jz4760_rtc_open,
+ //.read_callback = jz4760_rtc_read_callback,
+ .release = jz4760_rtc_release,
+ .ioctl = jz4760_rtc_ioctl,
+ .read_time = jz4760_rtc_read_time,
+ .set_time = jz4760_rtc_set_time,
+ .read_alarm = jz4760_rtc_read_alarm,
+ .set_alarm = jz4760_rtc_set_alarm,
+ .proc = jz4760_rtc_proc,
+};
+
+static int jz4760_rtc_probe(struct platform_device *pdev)
+{
+ struct rtc_device *rtc;
+ unsigned int cfc,hspr,rgr_1hz;
+ /*
+ * When we are powered on for the first time, init the rtc and reset time.
+ *
+ * For other situations, we remain the rtc status unchanged.
+ */
+ cpm_set_clock(CGU_RTCCLK, 32768);
+
+ //unsigned int ppr = IN_RTC_REG(REG_RTC_HWRSR);
+ cfc = HSPR_RTCV;
+ hspr = rtc_read_reg(RTC_HSPR);
+ rgr_1hz = rtc_read_reg(RTC_RTCGR) & RTCGR_NC1HZ_MASK;
+
+ if((hspr != cfc) || (rgr_1hz != RTC_FREQ_DIVIDER))
+ {
+ //if ((ppr >> RTC_HWRSR_PPR) & 0x1) {
+ /* We are powered on for the first time !!! */
+
+ printk("jz4760-rtc: rtc status reset by power-on\n");
+
+ /* Set 32768 rtc clocks per seconds */
+ rtc_write_reg(RTC_RTCGR, RTC_FREQ_DIVIDER);
+
+ /* Set minimum wakeup_n pin low-level assertion time for wakeup: 100ms */
+ rtc_write_reg(RTC_HWFCR, HWFCR_WAIT_TIME(100));
+ rtc_write_reg(RTC_HRCR, HRCR_WAIT_TIME(60));
+
+ /* Reset to the default time */
+ jz4760_rtc_set_time(NULL, &default_tm);
+
+ /* start rtc */
+ rtc_write_reg(RTC_RTCCR, RTCCR_RTCE);
+ rtc_write_reg(RTC_HSPR, cfc);
+ }
+
+ /* clear all rtc flags */
+ rtc_write_reg(RTC_HWRSR, 0);
+
+ device_init_wakeup(&pdev->dev, 1);
+ rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4760_rtc_ops,
+ THIS_MODULE);
+
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(pdev, rtc);
+
+ return 0;
+}
+
+static int jz4760_rtc_remove(struct platform_device *pdev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+ rtc_write_reg(RTC_RTCCR, 0);
+ if (rtc)
+ rtc_device_unregister(rtc);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int jz4760_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+// if (device_may_wakeup(&pdev->dev))
+// enable_irq_wake(IRQ_RTC);
+ return 0;
+}
+
+static int jz4760_rtc_resume(struct platform_device *pdev)
+{
+// if (device_may_wakeup(&pdev->dev))
+// disable_irq_wake(IRQ_RTC);
+ return 0;
+}
+#else
+#define jz4760_rtc_suspend NULL
+#define jz4760_rtc_resume NULL
+#endif
+
+static struct platform_driver jz4760_rtc_driver = {
+ .probe = jz4760_rtc_probe,
+ .remove = jz4760_rtc_remove,
+ .suspend = jz4760_rtc_suspend,
+ .resume = jz4760_rtc_resume,
+ .driver = {
+ .name = "jz4760-rtc",
+ },
+};
+
+static int __init jz4760_rtc_init(void)
+{
+ return platform_driver_register(&jz4760_rtc_driver);
+}
+
+static void __exit jz4760_rtc_exit(void)
+{
+ platform_driver_unregister(&jz4760_rtc_driver);
+}
+
+module_init(jz4760_rtc_init);
+module_exit(jz4760_rtc_exit);
+
+MODULE_AUTHOR("James Jia <ljia@ingenic.cn>");
+MODULE_DESCRIPTION("JZ4760 Realtime Clock Driver (RTC)");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:jz4760-rtc");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 8e44f4b1f83..918fc832349 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -14,6 +14,20 @@ config I2C_JZ47XX
this option. This driver can also be built as a module. If so, the
module will be called i2c-jz47xx.
+config I2C0_JZ4760
+ tristate "JZ4760 I2C controler 0 Interface support"
+ depends on JZSOC
+ help
+ If you have devices in the Ingenic JZ4760 I2C controler 0 bus, say yes to
+ this option. This driver can also be built as a module.
+
+config I2C1_JZ4760
+ tristate "JZ4760 I2C controler 1 Interface support"
+ depends on JZSOC
+ help
+ If you have devices in the Ingenic JZ4760 I2C controler 1 bus, say yes to
+ this option. This driver can also be built as a module.
+
config I2C_ALI1535
tristate "ALI 1535"
depends on PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 10649f97366..61260779319 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -5,6 +5,8 @@
# PC SMBus host controller drivers
#
obj-$(CONFIG_I2C_JZ47XX) += i2c-jz47xx.o
+obj-$(CONFIG_I2C0_JZ4760) += i2c-jz4760.o
+obj-$(CONFIG_I2C1_JZ4760) += i2c-jz4760.o
obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o
obj-$(CONFIG_I2C_ALI1563) += i2c-ali1563.o
obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o
diff --git a/drivers/i2c/busses/i2c-jz4760.c b/drivers/i2c/busses/i2c-jz4760.c
new file mode 100644
index 00000000000..7d71799aa16
--- /dev/null
+++ b/drivers/i2c/busses/i2c-jz4760.c
@@ -0,0 +1,634 @@
+
+/*
+ * I2C adapter for the INGENIC I2C bus access.
+ *
+ * Copyright (C) 2006 - 2009 Ingenic Semiconductor Inc.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <linux/module.h>
+#include <asm/addrspace.h>
+
+#include <asm/jzsoc.h>
+#include "i2c-jz4760.h"
+
+/* I2C protocol */
+#define I2C_READ 1
+#define I2C_WRITE 0
+#define I2C_CLIENT_NUM 20
+#define TIMEOUT 0xffff
+
+//#undef DEBUG
+#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...) do{}while(0)
+#endif
+
+#define __reg_printk() \
+do { \
+dprintk(" cmd_flag=%d,cmd_cnt=%d,r_cnt=%d length=%d",cmd_flag[I2C_ID],cmd_cnt[I2C_ID],r_cnt[I2C_ID],length); \
+dprintk(" REG_I2C_STA(%d)=0x%x",I2C_ID,REG_I2C_STA(I2C_ID)); \
+dprintk(" REG_I2C_TXTL(%d)=0x%x",I2C_ID,REG_I2C_TXTL(I2C_ID)); \
+dprintk(" REG_I2C_INTST(%d)=0x%x",I2C_ID,REG_I2C_INTST(I2C_ID)); \
+dprintk(" REG_I2C_TXABRT(%d)=0x%x\n",I2C_ID,REG_I2C_TXABRT(I2C_ID)); \
+dprintk("------------------%s:%d\n",__FUNCTION__,__LINE__); \
+} while(0)
+/* The value of the most significant byte of sub_addr
+ * indicate the length of sub address:
+ * zero:1 byte, non-zero:2 bytes
+ */
+
+struct i2c_speed {
+ unsigned int speed;
+ unsigned char slave_addr;
+};
+static struct i2c_speed jz4760_i2c_speed[I2C_CLIENT_NUM];
+static unsigned char current_device;
+static int client_cnt = 0;
+static int i2c_ctrl_rest[2] = {0,0};
+struct jz_i2c {
+ spinlock_t lock;
+ wait_queue_head_t wait;
+ int id;
+ unsigned int irq;
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int slave_addr;
+ struct i2c_adapter adap;
+ struct clk *clk;
+};
+
+void i2c_jz_setclk(struct i2c_client *client,unsigned long i2cclk)
+{
+ if (i2cclk > 0 && i2cclk <= 400000) {
+ jz4760_i2c_speed[client_cnt].slave_addr = client->addr;
+ jz4760_i2c_speed[client_cnt].speed = i2cclk/1000;
+ } else if (i2cclk <= 0) {
+ jz4760_i2c_speed[client_cnt].slave_addr = client->addr;
+ jz4760_i2c_speed[client_cnt].speed = 100;
+ } else {
+ jz4760_i2c_speed[client_cnt].slave_addr = client->addr;
+ jz4760_i2c_speed[client_cnt].speed = 400;
+ }
+
+ printk("Device 0x%2x with i2c speed:%dK\n",jz4760_i2c_speed[client_cnt].slave_addr,
+ jz4760_i2c_speed[client_cnt].speed );
+
+ client_cnt++;
+}
+EXPORT_SYMBOL_GPL(i2c_jz_setclk);
+
+/*
+ *jz_i2c_irq
+*/
+static unsigned char *msg_buf0,*msg_buf1;
+static int cmd_cnt[2];
+static volatile int cmd_flag[2];
+static int r_cnt[2];
+
+static irqreturn_t jz_i2c_irq(int irqno, void *dev_id)
+{
+ struct jz_i2c *i2c = dev_id;
+ int I2C_ID = i2c->id;
+ int flags = i2c->msg->flags;
+ int timeout = TIMEOUT;
+
+ if (__i2c_abrt_7b_addr_nack(I2C_ID)) {
+ int ret;
+ cmd_flag[I2C_ID] = -1;
+ __i2c_clear_interrupts(ret,I2C_ID);
+ REG_I2C_INTM(I2C_ID) = 0x0;
+ return IRQ_HANDLED;
+ }
+ /* first byte,when length > 1 */
+ if (cmd_flag[I2C_ID] == 0 && cmd_cnt[I2C_ID] > 1) {
+ cmd_flag[I2C_ID] = 1;
+ if (flags & I2C_M_RD) {
+ REG_I2C_DC(I2C_ID) = I2C_READ << 8;
+ } else {
+ if (I2C_ID == 0) {
+ REG_I2C_DC(I2C_ID) = (I2C_WRITE << 8) | *msg_buf0++;
+ } else {
+ REG_I2C_DC(I2C_ID) = (I2C_WRITE << 8) | *msg_buf1++;
+ }
+ }
+ cmd_cnt[I2C_ID]--;
+ }
+
+ if (flags & I2C_M_RD) {
+ if (REG_I2C_STA(I2C_ID) & I2C_STA_RFNE) {
+ if (I2C_ID == 0) {
+ *msg_buf0++ = REG_I2C_DC(I2C_ID) & 0xff;
+ } else {
+ *msg_buf1++ = REG_I2C_DC(I2C_ID) & 0xff;
+ }
+ r_cnt[I2C_ID]--;
+ }
+
+ REG_I2C_DC(I2C_ID) = I2C_READ << 8;
+ } else {
+ if (I2C_ID == 0) {
+ REG_I2C_DC(I2C_ID) = (I2C_WRITE << 8) | *msg_buf0++;
+ } else {
+ REG_I2C_DC(I2C_ID) = (I2C_WRITE << 8) | *msg_buf1++;
+ }
+ }
+
+ cmd_cnt[I2C_ID]--;
+ if (!(cmd_cnt[I2C_ID])) {
+ REG_I2C_INTM(I2C_ID) = 0x0;
+ cmd_flag[I2C_ID] = 2;
+ if (flags & I2C_M_RD){
+ while (r_cnt[I2C_ID] > 2) {
+ if ((REG_I2C_STA(I2C_ID) & I2C_STA_RFNE) && timeout) {
+ if (I2C_ID == 0) {
+ *msg_buf0++ = REG_I2C_DC(I2C_ID) & 0xff;
+ } else {
+ *msg_buf1++ = REG_I2C_DC(I2C_ID) & 0xff;
+ }
+ r_cnt[I2C_ID]--;
+ }
+ if (!(timeout--)) {
+ cmd_flag[I2C_ID] = -1;
+ return IRQ_HANDLED;
+ }
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int i2c_disable(int I2C_ID)
+{
+ int timeout = TIMEOUT;
+
+ __i2c_disable(I2C_ID);
+ while(__i2c_is_enable(I2C_ID) && (timeout > 0)) {
+ udelay(1);
+ timeout--;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+#if 0
+static int i2c_enable(int I2C_ID)
+{
+ int timeout = TIMEOUT;
+
+ __i2c_enable(I2C_ID);
+ while(__i2c_is_disable(I2C_ID) && (timeout > 0)) {
+ mdelay(1);
+ timeout--;
+ }
+ if(timeout)
+ return 0;
+ else
+ return 1;
+}
+#endif
+#if 0
+static int i2c_set_F_clk(int i2c_clk, int I2C_ID)
+{
+ int dev_clk = __cpm_get_pclk();
+ int count = 0;
+
+ REG_I2C_CTRL(I2C_ID) = 0x45 | i2c_ctrl_rest[I2C_ID]; /* high speed mode*/
+ if (i2c_clk < 100 || i2c_clk > 400)
+ goto Set_fclk_err;
+
+ count = dev_clk/(i2c_clk*1000) - 23;
+
+ if (count < 0)
+ goto Set_fclk_err;
+ if (count%2 == 0) {
+ REG_I2C_FHCNT(I2C_ID) = count/2 + 6;
+ REG_I2C_FLCNT(I2C_ID) = count/2 + 8;
+ } else {
+ REG_I2C_FHCNT(I2C_ID) = count/2 + 6;
+ REG_I2C_FLCNT(I2C_ID) = count/2 + 8 + 1;
+ }
+ return 0;
+
+Set_fclk_err:
+
+ printk("i2c set fclk faild,dev_clk=%d.\n",dev_clk);
+ return -1;
+}
+#endif
+
+static int i2c_set_clk(int i2c_clk, int I2C_ID)
+{
+ int dev_clk = cpm_get_clock(CGU_PCLK);
+ int count = 0;
+
+ if (i2c_clk < 0 || i2c_clk > 400)
+ goto Set_clk_err;
+
+ count = dev_clk/(i2c_clk*1000) - 23;
+ if (count < 0)
+ goto Set_clk_err;
+
+ if (i2c_clk <= 100) {
+ REG_I2C_CTRL(I2C_ID) = 0x43 | i2c_ctrl_rest[I2C_ID]; /* standard speed mode*/
+ if (count%2 == 0) {
+ REG_I2C_SHCNT(I2C_ID) = count/2 + 6 - 5;
+ REG_I2C_SLCNT(I2C_ID) = count/2 + 8 + 5;
+ } else {
+ REG_I2C_SHCNT(I2C_ID) = count/2 + 6 -5;
+ REG_I2C_SLCNT(I2C_ID) = count/2 + 8 +5 + 1;
+ }
+ } else {
+ REG_I2C_CTRL(I2C_ID) = 0x45 | i2c_ctrl_rest[I2C_ID]; /* high speed mode*/
+ if (count%2 == 0) {
+ REG_I2C_FHCNT(I2C_ID) = count/2 + 6;
+ REG_I2C_FLCNT(I2C_ID) = count/2 + 8;
+ } else {
+ REG_I2C_FHCNT(I2C_ID) = count/2 + 6;
+ REG_I2C_FLCNT(I2C_ID) = count/2 + 8 + 1;
+ }
+ }
+ /* printk("i2c controler %d speed:%d\n",I2C_ID,i2c_speed[I2C_ID]); */
+ return 0;
+
+Set_clk_err:
+
+ printk("i2c set sclk faild,i2c_clk=%d,dev_clk=%d.\n",i2c_clk,dev_clk);
+ return -1;
+}
+
+static void i2c_set_target(unsigned char address,int I2C_ID)
+{
+ while (!__i2c_txfifo_is_empty(I2C_ID) || __i2c_master_active(I2C_ID));
+ REG_I2C_TAR(I2C_ID) = address; /* slave id needed write only once */
+}
+
+static void i2c_init_as_master(int I2C_ID,unsigned char device)
+{
+ int i;
+ if(i2c_disable(I2C_ID))
+ printk("i2c not disable\n");
+
+ for (i = 0; i < I2C_CLIENT_NUM; i++) {
+ if(device == jz4760_i2c_speed[i].slave_addr) {
+ i2c_set_clk(jz4760_i2c_speed[i].speed,I2C_ID);
+ printk("----------------------Device 0x%2x with i2c speed:%dK\n",jz4760_i2c_speed[i].slave_addr,
+ jz4760_i2c_speed[i].speed );
+ break;
+ }
+ }
+ if (i == I2C_CLIENT_NUM) {
+ printk("+++++++++++++++++++++++++++++++i2c speed 100K.\n");
+ i2c_set_clk(100,I2C_ID);
+ }
+ REG_I2C_INTM(I2C_ID) = 0x0; /*mask all interrupt*/
+ REG_I2C_TXTL(I2C_ID) = 0x1;
+ REG_I2C_ENB(I2C_ID) = 1; /*enable i2c*/
+}
+
+static int xfer_read(unsigned char device, unsigned char *buf,
+ int length, struct jz_i2c *i2c)
+{
+ int timeout,r_i = 0;
+ int I2C_ID = i2c->id;
+
+#if defined(CONFIG_TOUCHSCREEN_JZ_MT4D)
+ if ((device == 0x40) && __gpio_get_pin(GPIO_ATTN)) {
+ return -87;
+ }
+#endif
+
+ i2c_set_target(device,I2C_ID);
+ cmd_flag[I2C_ID] = 0;
+ REG_I2C_INTM(I2C_ID) = 0x10;
+ timeout = TIMEOUT;
+ while (cmd_flag[I2C_ID] != 2 && --timeout) {
+ if (cmd_flag[I2C_ID] == -1) {
+ r_i = 1;
+ goto R_dev_err;
+ }
+ udelay(1);
+ }
+ if (!timeout) {
+ r_i = 4;
+ goto R_timeout;
+ }
+
+ while (r_cnt[I2C_ID]) {
+ while (!(REG_I2C_STA(I2C_ID) & I2C_STA_RFNE)) {
+ if ((cmd_flag[I2C_ID] == -1) ||
+ (REG_I2C_INTST(I2C_ID) & I2C_INTST_TXABT) ||
+ REG_I2C_TXABRT(I2C_ID)) {
+ int ret;
+ r_i = 2;
+ __reg_printk();
+ __i2c_clear_interrupts(ret,I2C_ID);
+ goto R_dev_err;
+ }
+ }
+ if (I2C_ID == 0) {
+ *msg_buf0++ = REG_I2C_DC(I2C_ID) & 0xff;
+ } else {
+ *msg_buf1++ = REG_I2C_DC(I2C_ID) & 0xff;
+ }
+ r_cnt[I2C_ID]--;
+ }
+
+ timeout = TIMEOUT;
+ while ((REG_I2C_STA(I2C_ID) & I2C_STA_MSTACT) && --timeout)
+ udelay(10);
+ if (!timeout){
+ r_i = 3;
+ goto R_timeout;
+ }
+
+ return 0;
+
+R_dev_err:
+R_timeout:
+
+ i2c_init_as_master(I2C_ID,device);
+ if (r_i == 1) {
+ printk("Read i2c device 0x%2x failed in r_i = %d :device no ack.\n",device,r_i);
+ } else if (r_i == 2) {
+ printk("Read i2c device 0x%2x failed in r_i = %d :i2c abort.\n",device,r_i);
+ } else if (r_i == 3) {
+ printk("Read i2c device 0x%2x failed in r_i = %d :waite master inactive timeout.\n",device,r_i);
+ } else {
+ printk("Read i2c device 0x%2x failed in r_i = %d.\n",device,r_i);
+ }
+ return -ETIMEDOUT;
+}
+
+static int xfer_write(unsigned char device, unsigned char *buf,
+ int length, struct jz_i2c *i2c)
+{
+ int timeout,w_i = 0;
+ int I2C_ID = i2c->id;
+
+ i2c_set_target(device,I2C_ID);
+ cmd_flag[I2C_ID] = 0;
+ REG_I2C_INTM(I2C_ID) = 0x10;
+
+ while (cmd_flag[I2C_ID] != 2){
+ if (cmd_flag[I2C_ID] == -1){
+ w_i = 1;
+ goto W_dev_err;
+ }
+ udelay(1);
+ }
+
+ timeout = TIMEOUT;
+ while((!(REG_I2C_STA(I2C_ID) & I2C_STA_TFE)) && --timeout){
+ udelay(10);
+ }
+ if (!timeout){
+ w_i = 2;
+ goto W_timeout;
+ }
+
+ timeout = TIMEOUT;
+ while (__i2c_master_active(I2C_ID) && --timeout);
+ if (!timeout){
+ w_i = 3;
+ goto W_timeout;
+ }
+
+ if ((length == 1)&&
+ ((cmd_flag[I2C_ID] == -1) ||
+ (REG_I2C_INTST(I2C_ID) & I2C_INTST_TXABT) ||
+ REG_I2C_TXABRT(I2C_ID))) {
+ int ret;
+ w_i = 5;
+ __reg_printk();
+ __i2c_clear_interrupts(ret,I2C_ID);
+ goto W_dev_err;
+ }
+
+ return 0;
+
+W_dev_err:
+W_timeout:
+
+ i2c_init_as_master(I2C_ID,device);
+ if (w_i == 1) {
+ printk("Write i2c device 0x%2x failed in w_i=%d:device no ack.\n",device,w_i);
+ } else if (w_i == 2) {
+ printk("Write i2c device 0x%2x failed in w_i=%d:waite TF buff empty timeout.\n",device,w_i);
+ } else if (w_i == 3) {
+ printk("Write i2c device 0x%2x failed in w_i=%d:waite master inactive timeout.\n",device,w_i);
+ } else if (w_i == 5) {
+ printk("Write i2c device 0x%2x failed in w_i=%d:device no ack or abort.\n",device,w_i);
+ } else {
+ printk("Write i2c device 0x%2x failed in w_i=%d.\n",device,w_i);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int i2c_jz_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
+{
+ int ret, i;
+ struct jz_i2c *i2c = adap->algo_data;
+
+ dev_dbg(&adap->dev, "jz4760_xfer: processing %d messages:\n", num);
+ for (i = 0; i < num; i++) {
+ dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
+ pmsg->flags & I2C_M_RD ? "read" : "writ",
+ pmsg->len, pmsg->len > 1 ? "s" : "",
+ pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr);
+
+ if (num != 1) {
+ if (i == (num -1))
+ i2c_ctrl_rest[i2c->id] = 0;
+ else
+ i2c_ctrl_rest[i2c->id] = I2C_CTRL_REST;
+
+ i2c_init_as_master(i2c->id,pmsg->addr);
+ } else {
+ if (pmsg->addr != current_device) {
+ current_device = pmsg->addr;
+ i2c_init_as_master(i2c->id,pmsg->addr);
+ }
+ }
+
+ if (pmsg->len && pmsg->buf) { /* sanity check */
+ i2c->msg = pmsg;
+ if (i2c->id == 0) {
+ msg_buf0 = pmsg->buf;
+ } else {
+ msg_buf1 = pmsg->buf;
+ }
+ cmd_cnt[i2c->id] = pmsg->len;
+ r_cnt[i2c->id] = pmsg->len;
+
+ if (pmsg->flags & I2C_M_RD){
+ ret = xfer_read(pmsg->addr, pmsg->buf, pmsg->len,i2c);
+ } else {
+ ret = xfer_write(pmsg->addr, pmsg->buf, pmsg->len,i2c);
+ }
+ if (ret)
+ return ret;
+ /* Wait until transfer is finished */
+ }
+ dev_dbg(&adap->dev, "transfer complete\n");
+ pmsg++; /* next message */
+ }
+
+ return i;
+}
+
+static u32 i2c_jz_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm i2c_jz_algorithm = {
+ .master_xfer = i2c_jz_xfer,
+ .functionality = i2c_jz_functionality,
+};
+
+static int i2c_jz_probe(struct platform_device *pdev)
+{
+ struct jz_i2c *i2c;
+ struct i2c_jz_platform_data *plat = pdev->dev.platform_data;
+ int ret;
+
+ i2c = kzalloc(sizeof(struct jz_i2c), GFP_KERNEL);
+ if (!i2c) {
+ printk("There is no enough memory\n");
+ ret = -ENOMEM;
+ goto emalloc;
+ }
+
+ cpm_start_clock(CGM_I2C0);
+ cpm_start_clock(CGM_I2C1);
+
+ i2c->id = pdev->id;
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &i2c_jz_algorithm;
+ i2c->adap.retries = 5;
+ spin_lock_init(&i2c->lock);
+ init_waitqueue_head(&i2c->wait);
+ sprintf(i2c->adap.name, "jz_i2c-i2c.%u", pdev->id);
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = &pdev->dev;
+
+ __gpio_as_i2c(i2c->id);
+ i2c_init_as_master(i2c->id,0xff);
+
+ if (plat) {
+ i2c->adap.class = plat->class;
+ }
+
+ i2c->irq = platform_get_irq(pdev, 0);
+ ret = request_irq(i2c->irq, jz_i2c_irq, IRQF_DISABLED,
+ dev_name(&pdev->dev), i2c);
+
+ if (ret != 0) {
+ dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
+ goto emalloc;
+ }
+
+ /*
+ * If "dev->id" is negative we consider it as zero.
+ * The reason to do so is to avoid sysfs names that only make
+ * sense when there are multiple adapters.
+ */
+ i2c->adap.nr = pdev->id != -1 ? pdev->id : 0;
+ /* ret = i2c_add_adapter(&i2c->adap); */
+ ret = i2c_add_numbered_adapter(&i2c->adap);
+ if (ret < 0) {
+ printk(KERN_INFO "I2C: Failed to add bus\n");
+ goto eadapt;
+ }
+
+ platform_set_drvdata(pdev, i2c);
+ dev_info(&pdev->dev, "JZ4760 i2c bus driver.\n");
+ return 0;
+
+eadapt:
+emalloc:
+ kfree(i2c);
+ return ret;
+}
+
+static int i2c_jz_remove(struct platform_device *pdev)
+{
+ struct i2c_adapter *adapter = platform_get_drvdata(pdev);
+ int rc;
+
+ rc = i2c_del_adapter(adapter);
+ platform_set_drvdata(pdev, NULL);
+ return rc;
+}
+
+#ifdef CONFIG_I2C0_JZ4760
+static struct platform_driver i2c_0_jz_driver = {
+ .probe = i2c_jz_probe,
+ .remove = i2c_jz_remove,
+ .driver = {
+ .name = "jz_i2c0",
+ },
+};
+#endif
+
+#ifdef CONFIG_I2C1_JZ4760
+static struct platform_driver i2c_1_jz_driver = {
+ .probe = i2c_jz_probe,
+ .remove = i2c_jz_remove,
+ .driver = {
+ .name = "jz_i2c1",
+ },
+};
+#endif
+
+static int __init i2c_adap_jz_init(void)
+{
+ int ret = 0;
+
+#ifdef CONFIG_I2C0_JZ4760
+ ret = platform_driver_register(&i2c_0_jz_driver);
+#endif
+
+#ifdef CONFIG_I2C1_JZ4760
+ ret = platform_driver_register(&i2c_1_jz_driver);
+#endif
+ return ret;
+}
+
+static void __exit i2c_adap_jz_exit(void)
+{
+#ifdef CONFIG_I2C0_JZ4760
+ platform_driver_unregister(&i2c_0_jz_driver);
+#endif
+
+#ifdef CONFIG_I2C1_JZ4760
+ platform_driver_unregister(&i2c_1_jz_driver);
+#endif
+}
+
+MODULE_LICENSE("GPL");
+subsys_initcall(i2c_adap_jz_init);
+module_exit(i2c_adap_jz_exit);
diff --git a/drivers/i2c/busses/i2c-jz4760.h b/drivers/i2c/busses/i2c-jz4760.h
new file mode 100644
index 00000000000..eb8611067f9
--- /dev/null
+++ b/drivers/i2c/busses/i2c-jz4760.h
@@ -0,0 +1,20 @@
+/*
+ * i2c_jz47xx.h
+ *
+ * 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 _I2C_JZ_H_
+#define _I2C_JZ_H_
+
+struct i2c_slave_client;
+
+struct i2c_jz_platform_data {
+ unsigned int slave_addr;
+ struct i2c_slave_client *slave;
+ unsigned int class;
+};
+
+extern void jz_set_i2c_info(struct i2c_jz_platform_data *info);
+#endif
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index b62d134eaa0..654820d51b6 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -436,12 +436,15 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
case I2C_SET_SUB_ADDRESS:
+#if defined(CONFIG_SOC_JZ4750)
sub_addr = *(unsigned long *)arg;
break;
-
+#endif
case I2C_SET_CLOCK:
+#if defined(CONFIG_SOC_JZ4750)
arg = *(unsigned long *)arg;
i2c_jz_setclk(arg);
+#endif
break;
default:
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 1c3e88389de..b37a45052f8 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -225,6 +225,21 @@ config KEYBOARD_LOCOMO
To compile this driver as a module, choose M here: the
module will be called locomokbd.
+config KEYBOARD_JZ_GPIO
+ tristate "JZ keypad driver based on GPIO Buttons"
+ depends on JZSOC
+ help
+ This driver implements support for buttons connected
+ to GPIO pins of various CPUs (and some other chips).
+
+ Say Y here if your device has buttons connected
+ directly to such GPIO pins. Your board-specific
+ setup logic must also provide a platform device,
+ with configuration data saying which GPIOs are used.
+
+ To compile this driver as a module, choose M here: the
+ module will be called jz_gpio_keypad.
+
config KEYBOARD_JZ
tristate "JZ keypad support"
depends on JZSOC
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 75c6ab1c660..37edba0a202 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o
obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o
obj-$(CONFIG_KEYBOARD_JZ) += jz_keypad.o
obj-$(CONFIG_5x5_KEYBOARD_JZ) += jz_keypad_5x5.o
+obj-$(CONFIG_KEYBOARD_JZ_GPIO) += jz_gpio_keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
diff --git a/drivers/input/keyboard/jz_gpio_keypad.c b/drivers/input/keyboard/jz_gpio_keypad.c
new file mode 100644
index 00000000000..febfe5bd223
--- /dev/null
+++ b/drivers/input/keyboard/jz_gpio_keypad.c
@@ -0,0 +1,399 @@
+/*
+ * linux/drivers/input/keyboard/jz_gpio_keys.c
+ *
+ * Keypad driver based on GPIO pins for Jz4750 APUS board.
+ *
+ * User applications can access to this device via /dev/input/eventX.
+ *
+ * Copyright (c) 2005 - 2009 Ingenic Semiconductor Inc.
+ *
+ * Author: Richard <cjfeng@ingenic.cn>
+ * Regen <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/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/gpio.h>
+#include <asm/jzsoc.h>
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+/* Device name */
+#if defined(CONFIG_JZ4750_APUS)
+#define DEV_NAME "apus-keypad"
+#elif defined(CONFIG_JZ4750D_CETUS)
+#define DEV_NAME "cetus-keypad"
+#else
+#define DEV_NAME "jz-keypad"
+#endif
+
+/* Timer interval */
+#define SCAN_INTERVAL 5
+#define KEY_NUM ARRAY_SIZE(board_buttons)
+/*
+ * GPIO Buttons,
+ * .code conforms with android/build/target/board/<boardname>/<boardname>-keypad.kl
+ */
+static struct gpio_keys_button board_buttons[] = {
+ {
+ .gpio = GPIO_MP_VOLUMEUP,
+ .code = KEY_VOLUMEUP,
+ .desc = "volume up key",
+ .active_low = ACTIVE_LOW_VOLUMEUP,
+ },
+ {
+ .gpio = GPIO_MP_VOLUMEDOWN,
+ .code = KEY_VOLUMEDOWN,
+ .desc = "volume down key",
+ .active_low = ACTIVE_LOW_VOLUMEDOWN,
+ },
+ {
+ .gpio = GPIO_MP_MUTE,
+ .code = KEY_MUTE,
+ .desc = "mute key",
+ .active_low = ACTIVE_LOW_MUTE,
+ },
+ {
+ .gpio = GPIO_MP_PAUSE,
+ .code = KEY_PAUSE,
+ .desc = "pause key",
+ .active_low = ACTIVE_LOW_PUASE,
+ },
+ {
+ .gpio = GPIO_MP_PLAY,
+ .code = KEY_PLAY,
+ .desc = "play key",
+ .active_low = ACTIVE_LOW_PLAY,
+ },
+ {
+ .gpio = GPIO_MP_REWIND,
+ .code = KEY_REWIND,
+ .desc = "rewind key",
+ .active_low = ACTIVE_LOW_REWIND,
+ },
+ {
+ .gpio = GPIO_MP_FORWARD,
+ .code = KEY_FORWARD,
+ .desc = "volum up key",
+ .active_low = ACTIVE_LOW_FORWARD,
+ },
+};
+
+static struct timer_list kbd_timer[KEY_NUM];
+static int current_key[KEY_NUM];
+struct semaphore sem;
+
+static struct gpio_keys_platform_data board_button_data = {
+ .buttons = board_buttons,
+ .nbuttons = KEY_NUM,
+};
+
+static struct platform_device board_button_device = {
+ .name = DEV_NAME,
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &board_button_data,
+ }
+};
+
+static void enable_gpio_irqs(struct gpio_keys_platform_data *pdata)
+{
+ int i;
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+
+ if (button->active_low)
+ __gpio_as_irq_fall_edge(button->gpio);
+ else
+ __gpio_as_irq_rise_edge(button->gpio);
+ }
+}
+
+static void button_timer_callback(unsigned long data)
+{
+ int gpio;
+ int code;
+ int active_low;
+ struct platform_device *pdev = (struct platform_device *)data;
+ struct input_dev *input = platform_get_drvdata(pdev);
+ int state, i;
+ static int button_pressed[KEY_NUM] = { 0, 0, 0, 0, 0 };
+
+ down(&sem);
+
+ for (i = 0; i < KEY_NUM; i++) {
+ if (1 == current_key[i]) {
+ gpio = board_buttons[i].gpio;
+ code = board_buttons[i].code;
+ active_low = board_buttons[i].active_low;
+
+ state = __gpio_get_pin(gpio);
+
+ if (active_low ^ state) {
+ printk("===>%d pressed!\n", gpio);
+ /* button pressed */
+ button_pressed[i] = 1;
+ input_report_key(input, code, 1);
+ //input_sync(input);
+ mod_timer(&kbd_timer[i],
+ jiffies + SCAN_INTERVAL);
+ dprintk("gpio %d down, code:%d \n",
+ gpio, code);
+ } else {
+ printk("===>%d pressed!\n", gpio);
+ /* button released */
+ if (1 == button_pressed[i]) {
+ input_report_key(input, code, 0);
+ //input_sync(input);
+ button_pressed[i] = 0;
+ current_key[i] = 0;
+ dprintk("gpio %d up, code:%d \n",
+ gpio, code);
+ }
+ }
+ }
+ }
+ up(&sem);
+
+}
+
+static irqreturn_t jz_gpio_interrupt(int irq, void *dev_id)
+{
+ int i;
+ struct platform_device *pdev = dev_id;
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+
+ dprintk("--irq of gpio:%d\n", irq - IRQ_GPIO_0);
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ int gpio = button->gpio;
+
+ if (irq == (gpio + IRQ_GPIO_0) ) {
+ current_key[i] = 1;
+ /* start timer */
+ mod_timer(&kbd_timer[i], jiffies + SCAN_INTERVAL);
+ dprintk("--mod_timer for gpio:%d\n", gpio);
+ break;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit gpio_keys_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input;
+ int i, error;
+ int wakeup = 0;
+
+ input = input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+
+ init_MUTEX(&sem);
+
+ platform_set_drvdata(pdev, input);
+
+ input->name = pdev->name;
+ input->dev.parent = &pdev->dev;
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_SYN);
+
+ set_bit(KEY_MENU, input->keybit);
+ set_bit(KEY_HOME, input->keybit);
+ set_bit(KEY_SEND, input->keybit);
+ set_bit(KEY_BACK, input->keybit);
+ set_bit(KEY_END, input->keybit);
+ set_bit(KEY_VOLUMEDOWN, input->keybit);
+ set_bit(KEY_VOLUMEUP, input->keybit);
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ int irq;
+ unsigned int type = button->type ?: EV_KEY;
+
+ /* Init timer */
+ setup_timer(&kbd_timer[i],
+ button_timer_callback,
+ (unsigned long)&board_button_device);
+
+ irq = IRQ_GPIO_0 + button->gpio;
+ if (irq < 0) {
+ error = irq;
+ pr_err("%s: Unable to get irq number"
+ " for GPIO %d, error %d\n", DEV_NAME,
+ button->gpio, error);
+ goto fail;
+ }
+
+ error = request_irq(irq, jz_gpio_interrupt,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+ button->desc ? button->desc : "gpio_keys",
+ pdev);
+ if (error) {
+ pr_err("%s: Unable to claim irq %d; error %d\n",
+ DEV_NAME, irq, error);
+ goto fail;
+ }
+
+ if (button->wakeup)
+ wakeup = 1;
+
+ input_set_capability(input, type, button->code);
+ }
+
+ /* Enable all GPIO irqs */
+ enable_gpio_irqs(pdata);
+
+ error = input_register_device(input);
+ if (error) {
+ pr_err("%s: Unable to register input device, "
+ "error: %d\n", DEV_NAME, error);
+ goto fail;
+ }
+
+ device_init_wakeup(&pdev->dev, wakeup);
+
+ return 0;
+
+ fail:
+ while (--i >= 0) {
+ free_irq(pdata->buttons[i].gpio + IRQ_GPIO_0 , pdev);
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ input_free_device(input);
+
+ return error;
+}
+
+static int __devexit gpio_keys_remove(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input = platform_get_drvdata(pdev);
+ int i;
+
+ device_init_wakeup(&pdev->dev, 0);
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ int irq = pdata->buttons[i].gpio + IRQ_GPIO_0;
+ free_irq(irq, pdev);
+ }
+
+ input_unregister_device(input);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
+{
+#if 0
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ int i;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ if (button->wakeup) {
+ int irq = button->gpio + IRQ_GPIO_0;
+ enable_irq_wake(irq);
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+static int gpio_keys_resume(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+#if 0
+ int i;
+
+ if (device_may_wakeup(&pdev->dev)) {
+ for (i = 0; i < pdata->nbuttons; i++) {
+ struct gpio_keys_button *button = &pdata->buttons[i];
+ if (button->wakeup) {
+ int irq = button->gpio + IRQ_GPIO_0;
+ disable_irq_wake(irq);
+ }
+ }
+ }
+#endif
+
+ /* Enable all GPIO irqs */
+ enable_gpio_irqs(pdata);
+
+ return 0;
+}
+#else
+#define gpio_keys_suspend NULL
+#define gpio_keys_resume NULL
+#endif
+
+static struct platform_driver gpio_keys_device_driver = {
+ .probe = gpio_keys_probe,
+ .remove = __devexit_p(gpio_keys_remove),
+ .suspend = gpio_keys_suspend,
+ .resume = gpio_keys_resume,
+ .driver = {
+ .name = DEV_NAME,
+ }
+};
+
+static int __init gpio_keys_init(void)
+{
+ int ret;
+
+ printk("=======>gpio_keys_init!!!\n");
+ platform_device_register(&board_button_device);
+ ret = platform_driver_register(&gpio_keys_device_driver);
+
+ return ret;
+}
+
+static void __exit gpio_keys_exit(void)
+{
+ platform_device_unregister(&board_button_device);
+ platform_driver_unregister(&gpio_keys_device_driver);
+}
+
+module_init(gpio_keys_init);
+module_exit(gpio_keys_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Regen Huang <lhhuang@ingenic.cn>");
+MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index cd07ee4317b..dbb109f1a72 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -3,7 +3,7 @@
#
menuconfig INPUT_TOUCHSCREEN
bool "Touchscreens"
- help
+ help
Say Y here, and a list of supported touchscreens will be displayed.
This option doesn't affect the kernel.
@@ -33,7 +33,7 @@ config TOUCHSCREEN_ADS7846
config TOUCHSCREEN_JZ
tristate "JZ touchscreen"
- default y
+ depends on SOC_JZ4730||SOC_JZ4740||SOC_JZ4750||SOC_JZ4750D
help
Say Y here to enable JZ SAR A/D controller if you use touchscreen
on JZ platform.
@@ -48,7 +48,11 @@ config JZ_ADKEY
The AD value of the key is get by JZ SAR A/D controller when any ad key
is pressed down.
-
+config TOUCHSCREEN_JZ4760
+ tristate "JZ4760 TOUCHSREEN"
+ depends on SOC_JZ4760
+ help
+ choose the jz4760 touchscreen
config TOUCHSCREEN_AD7877
tristate "AD7877 based touchscreens"
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 54c27f19e1b..5770fc9222a 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
obj-$(CONFIG_TOUCHSCREEN_JZ) += jz_ts.o
+obj-$(CONFIG_TOUCHSCREEN_JZ4760) += jz4760_ts.o
obj-$(CONFIG_TOUCHSCREEN_MIGOR) += migor_ts.o
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
diff --git a/drivers/input/touchscreen/jz4760_ts.c b/drivers/input/touchscreen/jz4760_ts.c
new file mode 100644
index 00000000000..8f791a1065d
--- /dev/null
+++ b/drivers/input/touchscreen/jz4760_ts.c
@@ -0,0 +1,816 @@
+/*
+ * JZ Touch Screen Driver
+ *
+ * Copyright (c) 2005 - 2009 Ingenic Semiconductor Inc.
+ *
+ * Author: Jason <xwang@ingenic.cn> 20090219
+ * Regen <lhhuang@ingenic.cn> 20090324 add adkey
+ *
+ * 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/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+
+#include <asm/irq.h>
+#include <asm/gpio.h>
+#include <asm/jzsoc.h>
+
+#undef DEBUG
+//#define DEBUG
+
+#ifdef DEBUG
+#define dprintk(msg...) printk("jz-sadc: " msg)
+#else
+#define dprintk(msg...)
+#endif
+
+#define TS_NAME "jz-ts"
+
+#define KEY_AUX_INDEX 1
+#define KEY_SCAN_INTERVAL 5
+#define TS_SCAN_INTERVAL 0
+
+/* from qwerty.kl of android */
+#define DPAD_CENTER 232
+#define DPAD_DOWN 108
+#define DPAD_UP 103
+#define DPAD_LEFT 105
+#define DPAD_RIGHT 106
+
+/* TS event status */
+#define PENUP 0x00
+#define PENDOWN 0x01
+
+/* Sample times in one sample process */
+//#define SAMPLE_TIMES 3
+
+#define SAMPLE_TIMES 5
+#define DROP_SAMPLE_TIMES 1 /* min drop 1 sample */
+#define CAL_SAMPLE_TIMES (SAMPLE_TIMES - DROP_SAMPLE_TIMES)
+#define VIRTUAL_SAMPLE 3 /* min >= 2 */
+/* Min pressure value. If less than it, filt the point.
+ * Mask it if it is not useful for you
+ */
+//#define MIN_PRESSURE 0x100
+
+/* Max delta x distance between current point and last point. */
+#define MAX_DELTA_X_OF_2_POINTS 200
+/* Max delta x distance between current point and last point. */
+#define MAX_DELTA_Y_OF_2_POINTS 120
+
+/* Max delta between points in one sample process
+ * Verify method :
+ * (diff value / min value) * 100 <= MAX_DELTA_OF_SAMPLING
+ */
+#define MAX_DELTA_OF_SAMPLING 20
+
+
+#define TS_ABS(x) ((x) > 0 ? (x): -(x))
+#define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a)))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+
+/************************************************************************/
+/* SAR ADC OPS */
+/************************************************************************/
+
+typedef struct datasource {
+ u16 xbuf;
+ u16 ybuf;
+ u16 zbuf;
+ u16 reserve;
+}datasource_t;
+struct ts_event {
+ u16 status;
+ u16 x;
+ u16 y;
+ u16 pressure;
+ u16 pad;
+};
+#define TOUCH_TYPE 1
+
+//sadc touch fifo size 2 * 32bit
+#define FIFO_MAX_SIZE 2
+
+/*
+ * TS deriver
+ */
+struct jz_ts_t {
+ int touch_cal_count;
+
+ unsigned int ts_fifo[FIFO_MAX_SIZE][CAL_SAMPLE_TIMES];
+ datasource_t data_s;
+ struct ts_event event;
+ int event_valid;
+
+ int cal_type; /* current calibrate type */
+ //struct timer_list acq_timer; // Timer for triggering acquisitions
+#ifdef CONFIG_JZ_ADKEY
+ struct timer_list key_timer; // for adkey
+ int active_low; // for adkey's interrupt pin
+#endif
+ wait_queue_head_t wait; // read wait queue
+ spinlock_t lock;
+
+ /* Following 4 members use to pass arguments from u-boot to tell us the ts data.
+ * But in Android we do not use them.
+ */
+ /*
+ int minx, miny, maxx, maxy;
+ */
+ int first_read;
+
+ char phys[32];
+ struct input_dev *input_dev; /* for touch screen */
+ struct input_dev *input_dev1; /* for adkey */
+};
+
+static struct jz_ts_t *jz_ts;
+
+/*
+ * TS Event type
+ */
+
+#ifdef CONFIG_JZ_ADKEY
+struct ad_keys_button {
+ int code; /* input event code */
+ int val; /* the ad value of the key */
+ int fuzz; /* the error(+-fuzz) allowed of the ad value of the key */
+};
+static struct ad_keys_button ad_buttons[] = {
+ {
+ .code = DPAD_LEFT,
+ .val = DPAD_LEFT_LEVEL,
+ .fuzz = 40,
+ },
+ {
+ .code = DPAD_DOWN,
+ .val = DPAD_DOWN_LEVEL,
+ .fuzz = 40,
+ },
+ {
+ .code = DPAD_UP,
+ .val = DPAD_UP_LEVEL,
+ .fuzz = 40,
+ },
+ {
+ .code = DPAD_CENTER,
+ .val = DPAD_CENTER_LEVEL,
+ .fuzz = 40,
+ },
+ {
+ .code = DPAD_RIGHT,
+ .val = DPAD_RIGHT_LEVEL,
+ .fuzz = 40,
+ },
+};
+#define KEY_NUM (sizeof(ad_buttons) / sizeof(struct ad_keys_button))
+#endif
+
+static DECLARE_WAIT_QUEUE_HEAD (sadc_wait_queue);
+
+extern unsigned int (*codec_read_battery)(void);
+#if 0
+static void reg_debug(void)
+{
+ printk("\t####CTRL####################################################\n");
+ printk("\tPEND %s, ", REG_SADC_CTRL & SADC_CTRL_PENDM ? "masked" : "enabled");
+ printk("PENU %s, ", REG_SADC_CTRL & SADC_CTRL_PENUM ? "masked" : "enabled");
+ printk("TSRDY %s\n", REG_SADC_CTRL & SADC_CTRL_TSRDYM ? "masked" : "enabled");
+ printk("\t----STATE---------------------------------------------------\n");
+ printk("\tIRQ actived: %s, %s, %s\n",
+ REG_SADC_STATE & SADC_STATE_PEND ? "pen down" : " ",
+ REG_SADC_STATE & SADC_STATE_PENU ? "pen up " : " ",
+ REG_SADC_STATE & SADC_STATE_TSRDY ? "sample " : " ");
+ printk("\t############################################################\n");
+}
+#endif
+/*
+ * set adc clock to 24MHz/div. A/D works at freq between 500KHz to 8MHz.
+ */
+static void sadc_init_clock(int div)
+{
+ cpm_start_clock(CGM_SADC);
+
+ div = 120 - 1; /* working at 100 KHz */
+ CMSREG32(SADC_ADCLK, div, ADCLK_CLKDIV_MASK);
+}
+
+static inline void sadc_start_aux(void)
+{
+ SETREG8(SADC_ADENA, ADENA_AUXEN);
+}
+
+static inline void sadc_start_pbat(void)
+{
+ SETREG8(SADC_ADENA, ADENA_VBATEN); /* Enable pbat adc */
+}
+
+static inline void ts_enable_pendown_irq(void)
+{
+ CLRREG8(SADC_ADCTRL, ADCTRL_PENDM);
+}
+
+static inline void ts_enable_penup_irq(void)
+{
+ CLRREG8(SADC_ADCTRL, ADCTRL_PENUM);
+}
+
+static inline void ts_disable_pendown_irq(void)
+{
+ SETREG8(SADC_ADCTRL, ADCTRL_PENDM);
+}
+
+static inline void ts_disable_penup_irq(void)
+{
+ SETREG8(SADC_ADCTRL, ADCTRL_PENUM);
+}
+
+static inline void sadc_enable_ts(void)
+{
+ SETREG8(SADC_ADENA, ADENA_TCHEN);
+}
+
+static inline void sadc_disable_ts(void)
+{
+ CLRREG8(SADC_ADENA, ADENA_TCHEN);
+}
+
+static inline void sadc_start_ts(void)
+{
+ unsigned int tmp;
+
+ OUTREG16(SADC_ADSAME, 1); /* about 0.02 ms,you can change it */
+ OUTREG16(SADC_ADWAIT, 500); /* about 3.33 ms,you can change it */
+
+ /* set ts mode and sample times */
+ tmp = ADCFG_SPZZ | ADCFG_XYZ_XYZ1Z2 | ADCFG_SNUM(SAMPLE_TIMES);
+ OUTREG32(SADC_ADCFG, tmp);
+
+ /* mask all the intr except PEN-DOWN */
+ tmp = ADCTRL_SLPENDM | ADCTRL_PENUM | ADCTRL_DTCHM | ADCTRL_VRDYM | ADCTRL_ARDYM;
+ OUTREG8(SADC_ADCTRL, tmp);
+
+ /* clear all the intr status if needed*/
+ OUTREG8(SADC_ADSTATE, INREG8(SADC_ADSTATE));
+
+ sadc_enable_ts();
+}
+
+/**
+ * Read the battery voltage
+ */
+unsigned int jz_read_battery(void)
+{
+ unsigned int timeout = 0x3fff;
+ u16 pbat;
+
+ sadc_start_pbat();
+ udelay(300);
+
+ while(!(INREG8(SADC_ADSTATE) & ADSTATE_VRDY) && --timeout);
+
+ if (!timeout)
+ printk(KERN_ERR "Reading battery timeout!");
+
+ pbat = INREG16(SADC_ADVDAT) & ADVDAT_VDATA_MASK;
+
+ OUTREG8(SADC_ADSTATE, ADSTATE_VRDY);
+ CLRREG8(SADC_ADENA, ADENA_VBATEN); // hardware may not shut down really
+
+ return pbat;
+}
+
+/**
+ * Read the aux voltage
+ */
+unsigned short jz_read_aux(int index)
+{
+ unsigned int timeout = 0x3ff;
+ u16 val;
+
+ CMSREG32(SADC_ADCFG, index, ADCFG_CMD_MASK);
+ sadc_start_aux();
+ udelay(300);
+
+ while(!(INREG8(SADC_ADSTATE) & ADSTATE_ARDY) && --timeout);
+
+ if (!timeout)
+ printk(KERN_ERR "Reading aux timeout!");
+
+ val = INREG16(SADC_ADADAT) & ADADAT_ADATA_MASK;
+
+ OUTREG8(SADC_ADSTATE, ADSTATE_ARDY);
+ CLRREG8(SADC_ADENA, ADENA_AUXEN); // hardware may not shut down really
+
+ dprintk("read aux val=%d\n", val);
+ return val;
+}
+
+static inline void ts_data_ready(void)
+{
+ SETREG8(SADC_ADCTRL, ADCTRL_DTCHM);
+}
+
+#ifdef CONFIG_JZ_ADKEY
+
+static unsigned int key_scan(int ad_val)
+{
+ int i;
+
+ for(i = 0; i<KEY_NUM; i++) {
+ if((ad_buttons[i].val + ad_buttons[i].fuzz >= ad_val) &&
+ (ad_val >=ad_buttons[i].val - ad_buttons[i].fuzz)) {
+ return ad_buttons[i].code;
+ }
+ }
+ return -1;
+}
+
+static void key_timer_callback(unsigned long data)
+{
+ struct jz_ts_t *ts = (struct jz_ts_t *)data;
+ int state;
+ int active_low = ts->active_low;
+ int ad_val, code;
+ static int old_code;
+
+ state = __gpio_get_pin(GPIO_ADKEY_INT);
+ ad_val = jz_read_aux(KEY_AUX_INDEX);
+
+ if (active_low) {
+ if (state == 0) {
+ /* press down */
+ code = key_scan(ad_val);
+ old_code = code;
+ input_report_key(ts->input_dev1, code, 1);
+ dprintk("code=%d\n",code);
+ //input_sync(ts->input_dev1);
+ mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL);
+ } else {
+ /* up */
+ input_report_key(ts->input_dev1, old_code, 0);
+ //input_sync(ts->input_dev1);
+ //udelay(1000);
+ __gpio_as_irq_fall_edge(GPIO_ADKEY_INT);
+ }
+ } else {
+ if (state == 1) {
+ /* press down */
+ code = key_scan(ad_val);
+ old_code = code;
+ input_report_key(ts->input_dev1, code, 1);
+ //input_sync(ts->input_dev1);
+ mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL);
+ } else {
+ /* up */
+ input_report_key(ts->input_dev1, old_code, 0);
+ //input_sync(ts->input_dev1);
+ //udelay(1000);
+ __gpio_as_irq_rise_edge(GPIO_ADKEY_INT);
+ }
+ }
+}
+
+static irqreturn_t key_interrupt(int irq, void * dev_id)
+{
+ struct jz_ts_t *ts = dev_id;
+
+ dprintk("key_interrup entered.\n");
+
+ __gpio_as_input(GPIO_ADKEY_INT);
+
+ if (!timer_pending(&ts->key_timer))
+ mod_timer(&ts->key_timer, jiffies + KEY_SCAN_INTERVAL);
+ return IRQ_HANDLED;
+}
+#endif
+
+/************************************************************************/
+/* Touch Screen module */
+/************************************************************************/
+
+#define TSMAXX 3920
+#define TSMAXY 3700
+#define TSMAXZ (1024) /* measure data */
+
+#define TSMINX 150
+#define TSMINY 270
+#define TSMINZ 0
+
+
+#define SCREEN_MAXX 1023
+#define SCREEN_MAXY 1023
+#define PRESS_MAXZ 256
+
+static unsigned long transform_to_screen_x(struct jz_ts_t *ts, unsigned long x )
+{
+ /* Now we don't need u-boot to tell us the ts data. */
+ /*
+ if (ts->minx)
+ {
+ if (x < ts->minx) x = ts->minx;
+ if (x > ts->maxx) x = ts->maxx;
+
+ return (x - ts->minx) * SCREEN_MAXX / (ts->maxx - ts->minx);
+ }
+ else
+ {
+ */
+ if (x < TSMINX) x = TSMINX;
+ if (x > TSMAXX) x = TSMAXX;
+
+ return (x - TSMINX) * SCREEN_MAXX / (TSMAXX - TSMINX);
+ /*
+ }
+ */
+}
+
+static unsigned long transform_to_screen_y(struct jz_ts_t *ts, unsigned long y)
+{
+ /* Now we don't need u-boot to tell us the ts data. */
+ /*
+ if (ts->miny)
+ {
+ if (y < ts->miny) y = ts->miny;
+ if (y > ts->maxy) y = ts->maxy;
+
+ return (ts->maxy - y) * SCREEN_MAXY / (ts->maxy - ts->miny);
+ }
+ else
+ {
+ */
+ if (y < TSMINY) y = TSMINY;
+ if (y > TSMAXY) y = TSMAXY;
+
+ return (TSMAXY - y) * SCREEN_MAXY / (TSMAXY - TSMINY);
+ /*
+ }
+ */
+}
+static unsigned long transform_to_screen_z(struct jz_ts_t *ts, unsigned long z){
+ if(z < TSMINZ) z = TSMINZ;
+ if (z > TSMAXY) z = TSMAXY;
+ return (TSMAXZ - z) * PRESS_MAXZ / (TSMAXZ - TSMINZ);
+}
+/* R plane calibrate,please look up spec 11th page*/
+
+#define Yr_PLANE 272
+#define Xr_PLANE 480
+
+#define Touch_Formula_One(z1,z2,ref,r) ({ \
+ int z; \
+ if((z1) > 0){ \
+ z = ((ref) * (z2)) / (z1); \
+ if((z2) > (z1)) z = (z * r - (ref) * r) / (4096); \
+ else z = 0; \
+ }else \
+ z = 4095; \
+ z; \
+ })
+
+
+static int ts_data_filter(struct jz_ts_t *ts){
+ int i,xt = 0,yt = 0,zt1 = 0,zt2 = 0,zt3 = 0,zt4 = 0,t1_count = 0,t2_count = 0,z;
+
+ datasource_t *ds = &ts->data_s;
+ int t,xmin = 0x0fff,ymin = 0x0fff,xmax = 0,ymax = 0;//,z1min = 0xfff,z1max = 0,z2min = 0xfff,z2max = 0;
+
+ /* fifo high 16 bit = y,fifo low 16 bit = x */
+
+ for(i = 0;i < CAL_SAMPLE_TIMES;i++){
+
+ t = (ts->ts_fifo[0][i] & 0x0fff);
+#if (CAL_SAMPLE_TIMES >= 3)
+ if(t > xmax) xmax = t;
+ if(t < xmin) xmin = t;
+#endif
+ xt += t;
+ t = (ts->ts_fifo[0][i] >> 16) & 0x0fff;
+#if (CAL_SAMPLE_TIMES >= 3)
+ if(t > ymax) ymax = t;
+ if(t < ymin) ymin = t;
+#endif
+
+ yt += t;
+ if(ts->ts_fifo[1][i] & 0x8000)
+ {
+ t = (ts->ts_fifo[1][i] & 0x0fff);
+ zt1 += t;
+
+ t = (ts->ts_fifo[1][i] >> 16) & 0x0fff;
+ zt2 += t;
+
+ t1_count++;
+ }else
+ {
+ t = (ts->ts_fifo[1][i] & 0x0fff);
+ zt3 += t;
+
+ t = (ts->ts_fifo[1][i] >> 16) & 0x0fff;
+ zt4 += t;
+
+ t2_count++;
+ }
+ }
+#if (CAL_SAMPLE_TIMES >= 3)
+ xt = xt - xmin - xmax;
+ yt = yt - ymin - ymax;
+#endif
+
+ xt /= (CAL_SAMPLE_TIMES - 2);
+ yt /= (CAL_SAMPLE_TIMES - 2);
+ if(t1_count > 0)
+ {
+ zt1 /= t1_count;
+ zt2 /= t1_count;
+ zt1 = Touch_Formula_One(zt1,zt2,xt,Xr_PLANE);
+ }
+ if(t2_count)
+ {
+ zt3 /= t2_count;
+ zt4 /= t2_count;
+ zt3 = Touch_Formula_One(zt3,zt4,yt,Yr_PLANE);
+ }
+ if((t1_count) && (t2_count))
+ z = (zt1 + zt3) / 2;
+ else if(t1_count)
+ z = zt1;
+ else if(t2_count)
+ z = zt3;
+ else
+ z = 0;
+
+ ds->xbuf = xt;
+ ds->ybuf = yt;
+ ds->zbuf = z;
+ return 1;
+
+}
+static void ts_transform_data(struct jz_ts_t *ts){
+ struct ts_event *event = &ts->event;
+ event->x = transform_to_screen_x(ts,ts->data_s.xbuf);
+ event->y = transform_to_screen_y(ts,ts->data_s.ybuf);
+ event->pressure = transform_to_screen_z(ts,ts->data_s.zbuf);
+ if(event->pressure == 0) event->pressure = 1;
+}
+static void handle_ts_event(struct jz_ts_t *ts){
+ struct ts_event *event = &ts->event;
+ input_report_abs(ts->input_dev, ABS_X, event->x);
+ input_report_abs(ts->input_dev, ABS_Y, event->y);
+ input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);
+
+ /* Android need it ... */
+ input_report_key(ts->input_dev, BTN_TOUCH, 1);
+ input_sync(ts->input_dev);
+
+ //printk("event->x = %d,event->y = %d event->pressure = %d\n",event->x,event->y,event->pressure);
+}
+
+static void handle_touch(struct jz_ts_t *ts, unsigned int *data, int size){
+ /* drop no touch calibrate points */
+ if(ts->cal_type & (~TOUCH_TYPE))
+ ts->cal_type |= ~TOUCH_TYPE;
+ if(ts->event_valid){
+ handle_ts_event(ts);
+ ts->event_valid = 0;
+ }
+
+ if(ts->touch_cal_count >= DROP_SAMPLE_TIMES)
+ {
+ if(ts->touch_cal_count < SAMPLE_TIMES){
+ ts->ts_fifo[0][ts->touch_cal_count - DROP_SAMPLE_TIMES] = data[0];
+ ts->ts_fifo[1][ts->touch_cal_count - DROP_SAMPLE_TIMES] = data[1];
+ }else
+ {
+ /* drop sample*/
+ if(ts->cal_type & TOUCH_TYPE){
+ if(ts_data_filter(ts)){
+ ts->event_valid = 1;
+ ts_transform_data(ts);
+ }
+
+ }
+ ts->touch_cal_count = 0;
+ }
+ }
+ ts->touch_cal_count++;
+}
+
+static irqreturn_t sadc_interrupt(int irq, void * dev_id)
+{
+ unsigned char tmp;
+ struct jz_ts_t *ts = dev_id;
+ unsigned int state;
+ unsigned int fifo[FIFO_MAX_SIZE];
+ static int pen_is_down = 0;
+
+ spin_lock_irq(&ts->lock);
+
+ state = INREG8(SADC_ADSTATE) & (~INREG8(SADC_ADCTRL));
+ /* first handle pen up interrupt */
+ if(state & ADSTATE_PENU){
+ /* REG_SADC_CTRL used in pendown & penup mutex */
+
+ /* mask pen up and wait pen down */
+ tmp = INREG8(SADC_ADCTRL);
+ tmp = (tmp | ADCTRL_PENUM) & ~ADCTRL_PENDM;
+ OUTREG8(SADC_ADCTRL, tmp);
+
+ if(pen_is_down == 1)
+ {
+ SETREG8(SADC_ADCTRL, ADCTRL_DTCHM);
+ {
+ input_report_abs(ts->input_dev, ABS_PRESSURE, 0);
+ /* Android need it ... */
+ input_report_key(ts->input_dev, BTN_TOUCH, 0);
+ input_sync(ts->input_dev);
+ ts->cal_type &= ~TOUCH_TYPE;
+ ts->event_valid = 0;
+ }
+
+ }
+ pen_is_down = 0;
+ }else if(state & ADSTATE_PEND){
+ /* REG_SADC_CTRL used in pendown & penup mutex */
+ tmp = INREG8(SADC_ADCTRL);
+ tmp = (tmp | ADCTRL_PENDM) & ~(ADCTRL_PENUM | ADCTRL_DTCHM);
+ OUTREG8(SADC_ADCTRL, tmp);
+
+ if(pen_is_down == 0){
+ /* mask pen down and wait pen up */
+ pen_is_down = 1;
+ ts->event_valid = 0;
+ ts->cal_type |= TOUCH_TYPE;
+ ts->touch_cal_count = 0;
+ }
+ state |= ADSTATE_PENU;
+ state |= ADSTATE_SLPEND;
+ }else if(state & ADSTATE_DTCH){
+
+ fifo[0] = INREG32(SADC_ADTCH);
+ fifo[1] = INREG32(SADC_ADTCH);
+
+ /* alone here clear state */
+ OUTREG8(SADC_ADSTATE, ADSTATE_DTCH);
+
+ if(pen_is_down)
+ handle_touch(ts,fifo,2);
+
+ }else if(state & ADSTATE_SLPEND){
+ SETREG8(SADC_ADCTRL, ADSTATE_SLPEND);
+
+ }
+ //when data count not is set_count penup is not clear;
+ if(!(state & ADSTATE_DTCH))
+ OUTREG8(SADC_ADSTATE, state);
+
+ spin_unlock_irq(&ts->lock);
+
+ return IRQ_HANDLED;
+}
+
+static int __init jz_ts_init(void)
+{
+ struct input_dev *input_dev;
+ struct jz_ts_t *ts;
+ int error;
+
+ ts = jz_ts = kzalloc(sizeof(struct jz_ts_t), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ts || !input_dev)
+ return -ENOMEM;
+
+ input_dev->name = "touchscreen"; /* Android will load /system/usr/keychars/qwerty.kcm.bin by default */
+ input_dev->phys = ts->phys;
+
+ /*
+old:
+input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+*/
+
+ /* For Android */
+ set_bit(EV_ABS, input_dev->evbit);
+ set_bit(ABS_X, input_dev->absbit);
+ set_bit(ABS_Y, input_dev->absbit);
+ set_bit(ABS_PRESSURE, input_dev->absbit);
+ set_bit(EV_KEY, input_dev->evbit);
+ set_bit(BTN_TOUCH, input_dev->keybit);
+
+ input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAXX + 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAXY + 1, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAXZ + 1, 0, 0);
+ input_set_drvdata(input_dev, ts);
+ error = input_register_device(input_dev);
+
+ strcpy(ts->phys, "input/ts0");
+ spin_lock_init(&ts->lock);
+
+ ts->input_dev = input_dev;
+
+#ifdef CONFIG_JZ_ADKEY
+ ts->input_dev1 = input_allocate_device();
+ if (!ts->input_dev1)
+ return -ENOMEM;
+
+ ts->input_dev1->name = "adkey";
+ set_bit(EV_KEY, ts->input_dev1->evbit);
+ set_bit(DPAD_CENTER, ts->input_dev1->keybit);
+ set_bit(DPAD_DOWN, ts->input_dev1->keybit);
+ set_bit(DPAD_UP, ts->input_dev1->keybit);
+ set_bit(DPAD_LEFT, ts->input_dev1->keybit);
+ set_bit(DPAD_RIGHT, ts->input_dev1->keybit);
+ error = input_register_device(ts->input_dev1);
+#endif
+
+ if (error) {
+ printk("Input device register failed !\n");
+ goto err_free_dev;
+ }
+
+ sadc_init_clock(6);
+
+#if defined(CONFIG_SOC_JZ4760)
+ CLRREG8(SADC_ADENA, ADENA_POWER);
+ CLRREG32(CPM_LCR, LCR_VBATIR);
+ mdelay(50);
+#endif
+
+ OUTREG8(SADC_ADCTRL, ADCTRL_MASK_ALL);
+
+ error = request_irq(IRQ_SADC, sadc_interrupt, IRQF_DISABLED, TS_NAME, ts);
+ if (error) {
+ pr_err("unable to get PenDown IRQ %d", IRQ_SADC);
+ goto err_free_irq;
+ }
+ ts->cal_type = 0;
+
+#ifdef CONFIG_JZ_ADKEY
+ // Init key acquisition timer function
+ init_timer(&ts->key_timer);
+ ts->key_timer.function = key_timer_callback;
+ ts->key_timer.data = (unsigned long)ts;
+ ts->active_low = ACTIVE_LOW_ADKEY;
+
+ error = request_irq(IRQ_GPIO_0 + GPIO_ADKEY_INT, key_interrupt, IRQF_DISABLED, "jz-adkey", ts);
+ if (error) {
+ pr_err("unable to get AD KEY IRQ %d", IRQ_GPIO_0 + GPIO_ADKEY_INT);
+ goto err_free_irq;
+ }
+
+ __gpio_disable_pull(GPIO_ADKEY_INT);
+
+ if(ts->active_low)
+ __gpio_as_irq_fall_edge(GPIO_ADKEY_INT);
+ else
+ __gpio_as_irq_rise_edge(GPIO_ADKEY_INT);
+
+#endif
+ sadc_start_ts();
+
+ printk("input: JZ Touch Screen registered.\n");
+
+ return 0;
+
+err_free_irq:
+ free_irq(IRQ_SADC, ts);
+#ifdef CONFIG_JZ_ADKEY
+ free_irq(IRQ_GPIO_0 + GPIO_ADKEY_INT, ts);
+#endif
+err_free_dev:
+ input_free_device(ts->input_dev);
+ kfree(ts);
+ return 0;
+}
+
+static void __exit jz_ts_exit(void)
+{
+ ts_disable_pendown_irq();
+ ts_disable_penup_irq();
+ sadc_disable_ts();
+ free_irq(IRQ_SADC, jz_ts);
+ input_unregister_device(jz_ts->input_dev);
+
+}
+
+module_init(jz_ts_init);
+module_exit(jz_ts_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("JZ TouchScreen Driver");
+MODULE_AUTHOR("Jason <xwang@ingenic.com>");
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 68ab39d7cb3..9a3fec42c9d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -13,6 +13,38 @@ menuconfig MISC_DEVICES
if MISC_DEVICES
+config JZ_I2C_SIMULATE
+ bool "i2c simulate need by isp sensor on aquila_board"
+
+config JZ_CIM
+ bool "JZ CIM for Camera driver"
+
+config OV3640
+ bool "OmniVision OV3640 sensor support (3.1 MegaPixel)"
+ depends on JZ_CIM
+config OV2655
+ bool "OmniVision OV2655 sensor support (2.0 MegaPixel)"
+ depends on JZ_CIM
+config CM3511
+ bool "CM3511 sensor support (0.3 MegaPixel)"
+ depends on JZ_CIM
+
+config OV2640
+ bool "OmniVision OV2640 sensor support (2.0 MegaPixel)"
+ depends on JZ_CIM
+config OV9650
+ bool "OmniVision OV9650 sensor support (1.3 MegaPixel)"
+ depends on JZ_CIM
+config OV7690
+ bool "OmniVision OV7690 sensor support (0.3 MegaPixel)"
+ depends on JZ_CIM
+config ISP
+ bool "Corelogic isp with SamSung S5K sensor support (3.1 MegaPixel)"
+ depends on JZ_CIM && JZ_I2C_SIMULATE
+config JZ_FAKE_SENSOR
+ bool "jz fake sensor support (3.1 MegaPixel)"
+ depends on JZ_CIM
+
config ATMEL_PWM
tristate "Atmel AT32/AT91 PWM support"
depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 36f733cd60e..e396e909316 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -22,3 +22,6 @@ obj-$(CONFIG_ISL29003) += isl29003.o
obj-$(CONFIG_C2PORT) += c2port/
obj-y += eeprom/
obj-y += cb710/
+
+obj-$(CONFIG_JZ_CIM) += jz_cim/
+obj-$(CONFIG_JZ_I2C_SIMULATE) += i2c_simulate.o
diff --git a/drivers/misc/i2c_simulate.c b/drivers/misc/i2c_simulate.c
new file mode 100644
index 00000000000..a2f4031dc8e
--- /dev/null
+++ b/drivers/misc/i2c_simulate.c
@@ -0,0 +1,508 @@
+//
+// Copyright (c) Ingenic Semiconductor Co., Ltd. 2007.
+//
+
+#include <asm/jzsoc.h>
+
+
+#define I2CSim_READ_WRITE_RETRY_TIMES 5
+#define SDA_PIN (5*32 + 17)
+#define SCL_PIN (5*32 + 16)
+
+
+#define __gpio_out_to_in(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDIRC(p) = (1 << (o)); \
+} while (0)
+
+#define __gpio_in_to_out(n) \
+do { \
+ unsigned int p, o; \
+ p = (n) / 32; \
+ o = (n) % 32; \
+ REG_GPIO_PXDIRS(p) = (1 << (o)); \
+} while (0)
+
+#define SDA_HIGH __gpio_set_pin(SDA_PIN)
+#define SDA_LOW __gpio_clear_pin(SDA_PIN)
+
+#define SCL_HIGH __gpio_set_pin(SCL_PIN)
+#define SCL_LOW __gpio_clear_pin(SCL_PIN)
+
+#define SDA_DATA __gpio_get_pin(SDA_PIN)
+
+#define SDA_OUT __gpio_in_to_out(SDA_PIN)
+#define SDA_IN __gpio_out_to_in(SDA_PIN)
+#define SCL_OUT __gpio_in_to_out(SCL_PIN)
+
+#define SDA_OUT_INIT __gpio_as_output(SDA_PIN)
+#define SDA_IN_INIT __gpio_as_input(SDA_PIN)
+#define SCL_OUT_INIT __gpio_as_output(SCL_PIN)
+
+#define TRUE 1
+#define FALSE 0
+
+unsigned char g_bi2cInited = FALSE;
+//-----------------------------------------------------------------------------
+
+void I2CSim_Delay(volatile unsigned int delay)
+{
+ volatile unsigned int i;
+ for ( i = 0; i < delay; i++ );
+}
+void I2CSim_Start( void )
+{
+ SDA_HIGH;
+ I2CSim_Delay(500);
+ SCL_HIGH;
+ I2CSim_Delay(500);
+ SDA_LOW;
+ I2CSim_Delay(500);
+ SCL_LOW;
+ I2CSim_Delay(500);
+}
+void I2CSim_Stop( void )
+{
+ SCL_HIGH;
+}
+//------------------------------------------------------------------------------
+
+void I2CSim_Init(void)
+{
+ if ( !g_bi2cInited )
+ {
+ SDA_OUT_INIT;
+ SCL_OUT_INIT;
+ g_bi2cInited = TRUE;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+char I2CSim_ReadByte(unsigned char * pucOut, char bAck)
+{
+ unsigned char i;
+
+ SDA_IN;
+ I2CSim_Delay(100);
+ *pucOut = 0;
+ for ( i = 0; i < 8; i ++ )
+ {
+ SCL_HIGH;
+ *pucOut |= (unsigned char )((SDA_DATA & 0x1) << (7-i));
+ I2CSim_Delay(500);
+ SCL_LOW;
+ I2CSim_Delay(500);
+ }
+ if( bAck)
+ {
+ SDA_OUT;
+ I2CSim_Delay(500);
+ SDA_LOW;
+ I2CSim_Delay(500);
+ SCL_HIGH;
+ I2CSim_Delay(500);
+ SCL_LOW;
+ I2CSim_Delay(500);
+ return ( TRUE );
+
+ }
+ return ( TRUE );
+}
+
+//------------------------------------------------------------------------------
+
+char I2CSim_WriteByte(unsigned char data)
+{
+ unsigned char i;
+
+ for ( i = 0; i < 8; i ++ )
+ {
+ if(data & 0x80)
+ SDA_HIGH;
+ else
+ SDA_LOW;
+ I2CSim_Delay(200);
+ SCL_HIGH;
+ I2CSim_Delay(200);
+ SCL_LOW;
+ I2CSim_Delay(200);
+ data = (data << 1);
+ }
+ SDA_IN;
+ SCL_HIGH;
+ I2CSim_Delay(200);
+ i = 10;
+ while(i)
+ {
+ if (!(SDA_DATA & 1))
+ {
+ SCL_LOW;
+ I2CSim_Delay(200);
+ SDA_OUT;
+ return ( TRUE );
+ }
+ SCL_LOW;
+ I2CSim_Delay(200);
+ SCL_HIGH;
+ I2CSim_Delay(200);
+ i--;
+ }
+ SCL_LOW;
+ I2CSim_Delay(200);
+ SDA_OUT;
+ return ( FALSE );
+}
+
+//------------------------------------------------------------------------------
+
+void I2CSim_Disable(void)
+{
+ SDA_HIGH;
+ SCL_HIGH;
+ g_bi2cInited = FALSE;
+}
+
+//------------------------------------------------------------------------------
+
+unsigned char I2CSim_Read8(unsigned char ucSlaveID, char address)
+{
+ unsigned char usRetryTimes = 0, usErr = 0;
+ unsigned char value=0;
+
+CR_Retry:
+ I2CSim_Init();
+
+ if ( usRetryTimes > I2CSim_READ_WRITE_RETRY_TIMES )
+ goto CR_Exit;
+ I2CSim_Start();
+ if ( !I2CSim_WriteByte(ucSlaveID) )
+ {
+ usErr = 1;
+ goto CR_W_Err;
+ }
+ if ( !I2CSim_WriteByte(address) )
+ {
+ usErr = 2;
+ goto CR_W_Err;
+ }
+ I2CSim_Start();
+ if ( !I2CSim_WriteByte(ucSlaveID|1) )
+ {
+ usErr = 3;
+ goto CR_W_Err;
+ }
+ if ( !I2CSim_ReadByte(&value, TRUE) )
+ {
+ usErr = 4;
+ goto CR_R_Err;
+ }
+
+ I2CSim_Stop();
+ I2CSim_Delay(500);
+ I2CSim_Disable();
+ I2CSim_Delay(500);
+
+
+ return (value);
+
+CR_W_Err:
+CR_R_Err:
+ usRetryTimes ++;
+ I2CSim_Stop();
+ I2CSim_Delay(50);
+ goto CR_Retry;
+
+CR_Exit:
+ I2CSim_Stop();
+ I2CSim_Delay(50);
+ I2CSim_Disable();
+ printk("I2CSimLIB : I2C Read ERROR, Err = %d!\r\n", usErr);
+ return (value);
+}
+
+//------------------------------------------------------------------------------
+
+void I2CSim_Write8(unsigned char ucSlaveID, char address ,char value)
+{
+ unsigned short usWriteRetryTimes = 0;
+
+CW_Retry:
+ I2CSim_Init();
+
+ if ( usWriteRetryTimes > I2CSim_READ_WRITE_RETRY_TIMES )
+ goto CW_Exit;
+ I2CSim_Start();
+
+ if ( !I2CSim_WriteByte(ucSlaveID) )
+ goto CW_Err;
+
+ if ( !I2CSim_WriteByte(address) )
+ goto CW_Err;
+
+ if ( !I2CSim_WriteByte(value) )
+ goto CW_Err;
+
+ I2CSim_Stop();
+ I2CSim_Delay(500);
+ I2CSim_Disable();
+ return ;
+
+CW_Err:
+ usWriteRetryTimes ++;
+ goto CW_Retry;
+
+CW_Exit:
+ I2CSim_Stop();
+ I2CSim_Delay(500);
+ I2CSim_Disable();
+ printk("I2CLIB : I2C Write ERROR!\r\n");
+}
+//------------------------------------------------------------------------------
+
+
+
+
+#define SDA_HIGH __gpio_set_pin(SDA_PIN)
+#define SDA_LOW __gpio_clear_pin(SDA_PIN)
+
+#define SCL_HIGH __gpio_set_pin(SCL_PIN)
+#define SCL_LOW __gpio_clear_pin(SCL_PIN)
+
+#define SDA_DATA __gpio_get_pin(SDA_PIN)
+
+#define SDA_OUT __gpio_in_to_out(SDA_PIN)
+#define SDA_IN __gpio_out_to_in(SDA_PIN)
+#define SCL_OUT __gpio_in_to_out(SCL_PIN)
+
+#define SDA_OUT_INIT __gpio_as_output(SDA_PIN)
+#define SDA_IN_INIT __gpio_as_input(SDA_PIN)
+#define SCL_OUT_INIT __gpio_as_output(SCL_PIN)
+
+#define TRUE 1
+#define FALSE 0
+#define GPIO_IIC_JACKY // Jacky for test
+
+#ifdef GPIO_IIC_JACKY
+
+#define SET_SCCB_DATA_HIGH SDA_HIGH // Jacky for test
+#define SET_SCCB_DATA_LOW SDA_LOW // Jacky for test
+#define SET_SCCB_CLK_HIGH SCL_HIGH // Jacky for test
+#define SET_SCCB_CLK_LOW SCL_LOW // Jacky for test
+#define SET_SCCB_DATA_INPUT SDA_IN // Jacky for test
+#define SET_SCCB_DATA_OUTPUT SDA_OUT // Jacky for test
+#define GET_SCCB_DATA_BIT SDA_DATA
+
+#define SET_SCCB_CLK_OUTPUT SCL_OUT_INIT // SDA_OUT_Mode(); // Jacky for test
+
+#define SENSOR_I2C_DELAY (250) // 80KHz for iic speed.... 100 92KHz
+
+#define I2C_READ 0x01
+#define READ_CMD 1
+#define WRITE_CMD 0
+
+#define I2C_START_TRANSMISSION \
+{ \
+ volatile unsigned char j; \
+ SDA_OUT_INIT; \
+ SCL_OUT_INIT; \
+ SET_SCCB_CLK_OUTPUT; \
+ SET_SCCB_DATA_OUTPUT; \
+ SET_SCCB_CLK_HIGH; \
+ SET_SCCB_DATA_HIGH; \
+ for (j = 0; j < SENSOR_I2C_DELAY; j++); \
+ SET_SCCB_DATA_LOW; \
+ for (j = 0; j < SENSOR_I2C_DELAY; j++); \
+ SET_SCCB_CLK_LOW; \
+}
+
+#define I2C_STOP_TRANSMISSION \
+{ \
+ volatile unsigned char j; \
+ SET_SCCB_CLK_OUTPUT; \
+ SET_SCCB_DATA_OUTPUT; \
+ SET_SCCB_CLK_LOW; \
+ SET_SCCB_DATA_LOW; \
+ for (j = 0; j < SENSOR_I2C_DELAY; j++); \
+ SET_SCCB_CLK_HIGH; \
+ for (j = 0; j < SENSOR_I2C_DELAY; j++); \
+ SET_SCCB_DATA_HIGH; \
+}
+
+static void SCCB_send_byte(unsigned char send_byte)
+{
+ volatile signed char i;
+ volatile unsigned char j;
+
+ for (i = 7; i >= 0; i--) { /* data bit 7~0 */
+ if (send_byte & (1 << i)) {
+ SET_SCCB_DATA_HIGH;
+ }else {
+ SET_SCCB_DATA_LOW;
+ }
+
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_HIGH;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_LOW;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ }
+ /* don't care bit, 9th bit */
+ SET_SCCB_DATA_LOW;
+ SET_SCCB_DATA_INPUT;
+ SET_SCCB_CLK_HIGH;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_LOW;
+ SET_SCCB_DATA_OUTPUT;
+} /* SCCB_send_byte() */
+
+
+static unsigned char SCCB_get_byte(void)
+{
+ volatile signed char i;
+ volatile unsigned char j;
+ unsigned char get_byte = 0;
+
+ SET_SCCB_DATA_INPUT;
+
+ for (i = 7; i >= 0; i--) { /* data bit 7~0 */
+ SET_SCCB_CLK_HIGH;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ if (GET_SCCB_DATA_BIT)
+ get_byte |= (1 << i);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_LOW;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ }
+ /* don't care bit, 9th bit */
+ SET_SCCB_DATA_HIGH;
+ SET_SCCB_DATA_OUTPUT;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_HIGH;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SET_SCCB_CLK_LOW;
+
+ return get_byte;
+} /* SCCB_get_byte() */
+
+#endif
+
+
+unsigned short I2C_ReadControl(unsigned char IICID, unsigned short regaddr) // dhlee @ 2005.10.08 support 2Byte read
+{
+ unsigned short readdata1 = 0, readdata = 0;
+ unsigned char returnack;
+
+#ifdef GPIO_IIC_JACKY
+ volatile unsigned char j;
+
+ I2C_START_TRANSMISSION;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(IICID&(~I2C_READ));
+
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(regaddr);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+
+ I2C_START_TRANSMISSION;
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(IICID |I2C_READ);
+
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ readdata = SCCB_get_byte();
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ I2C_STOP_TRANSMISSION;
+#else
+
+ I2C_PortInitial();
+ I2C_StartCondition();
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+ I2C_SlaveAddress(IICID, WRITE_CMD);
+ returnack = I2C_CheckAck();
+ SWI2C_TIMER_Wait_us(SLOW_IIC_10);
+
+ I2C_RegisterAddress(regaddr);
+ returnack = I2C_CheckAck();
+ TIMER_Wait_us(1);
+
+ I2C_StartCondition();
+ I2C_SlaveAddress(IICID, READ_CMD);
+ returnack = I2C_CheckAck();
+ TIMER_Wait_us(1);
+
+ if (SI2CRWCNTL & 0x0002)
+ {
+ readdata1 = I2C_ReadData();
+ I2C_SendAck();
+ TIMER_Wait_us(1);
+ }
+
+ readdata = (unsigned short)((readdata1 << 8) | I2C_ReadData());
+
+ I2C_CheckNotAck();
+ SWI2C_TIMER_Wait_us(4);
+ I2C_StopCondition();
+
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+#endif
+ return readdata;
+}
+unsigned short I2C_WriteControl(unsigned char IICID, unsigned short regaddr, unsigned short data)
+{
+ unsigned char returnack = TRUE;
+
+#ifdef GPIO_IIC_JACKY
+
+ volatile unsigned char j;
+
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+ I2C_START_TRANSMISSION;
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(IICID&(~I2C_READ));
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(regaddr);
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ SCCB_send_byte(data);
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+ for (j = 0; j < SENSOR_I2C_DELAY; j++);
+ I2C_STOP_TRANSMISSION;
+// printk("%s %d \n",__FUNCTION__,__LINE__);
+#else
+
+ I2C_StartCondition();
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+ I2C_SlaveAddress(IICID, WRITE_CMD);
+
+ if (!I2C_CheckAck()) returnack = FALSE;
+
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+ I2C_RegisterAddress( regaddr );
+
+ if (!I2C_CheckAck()) returnack = FALSE;
+
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+ I2C_WriteData( data );
+
+ if (!I2C_CheckAck()) returnack = FALSE;
+
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+ I2C_StopCondition();
+ SWI2C_TIMER_Wait_us(SLOW_IIC_4);
+#endif
+
+ return returnack;
+}
+
+
+
+
+
+
+
+
diff --git a/drivers/misc/jz_cim/Makefile b/drivers/misc/jz_cim/Makefile
new file mode 100644
index 00000000000..998d04c1341
--- /dev/null
+++ b/drivers/misc/jz_cim/Makefile
@@ -0,0 +1,18 @@
+
+obj-$(CONFIG_ISP) += camera_source/isp/
+obj-$(CONFIG_OV2640) += camera_source/ov2640/
+obj-$(CONFIG_OV9650) += camera_source/ov9650/
+
+obj-$(CONFIG_JZ_CIM) += jz_cim_core.o jz_sensor.o
+
+obj-$(CONFIG_JZ4750_APUS) += jz_cim_board_apus.o
+obj-$(CONFIG_JZ4750_AQUILA) += jz_cim_board_aquila.o
+obj-$(CONFIG_JZ4760_ALTAIR) += jz_cim_board_altair.o
+obj-$(CONFIG_JZ4760_PT701) += jz_cim_board_pt701.o
+obj-$(CONFIG_JZ4760_LEPUS) += jz_cim_board_lepus.o
+
+obj-$(CONFIG_OV7690) += camera_source/ov7690/
+obj-$(CONFIG_OV3640) += camera_source/ov3640/
+obj-$(CONFIG_OV2655) += camera_source/ov2655/
+obj-$(CONFIG_CM3511) += camera_source/cm3511/
+obj-$(CONFIG_JZ_FAKE_SENSOR) += camera_source/fake/
diff --git a/drivers/misc/jz_cim/camera_source/cm3511/Makefile b/drivers/misc/jz_cim/camera_source/cm3511/Makefile
new file mode 100644
index 00000000000..f8467840dfe
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/cm3511/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_CM3511) += cm3511_camera.o cm3511_set.o
+
diff --git a/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.c b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.c
new file mode 100644
index 00000000000..392070b53f5
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.c
@@ -0,0 +1,570 @@
+#include <asm/jzsoc.h>
+#include <linux/i2c.h>
+#include "cm3511_camera.h"
+#include "cm3511_set.h"
+
+#define cm3511_DEBUG
+//#undef DEBUG
+
+#ifdef cm3511_DEBUG
+#define dprintk(x...) do{printk("cm3511---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+/* gpio init */
+#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) || defined(CONFIG_JZ4750_AQUILA)/* board APUS */
+#define GPIO_CAMERA_RST (32*4+8)
+#elif defined(CONFIG_JZ4760_ALTAIR)
+#define GPIO_CAMERA_RST (32*4+13) /*GPE13*/
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32*1 + 26) /* GPB26 */
+#else
+#error "cm3511/cm3511_camera.c , please define camera for your board."
+#endif
+
+
+struct cm3511_sensor cm3511;
+
+void cm3511_power_down(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(4*32+23);
+ __gpio_clear_pin(4*32+23);
+#elif defined(CONFIG_JZ4760_ALTAIR)
+ __gpio_as_output(0*32+27);
+ __gpio_clear_pin(0*32+27);
+#elif defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27); /* GPB27 */
+ __gpio_clear_pin(32 * 1 + 27);
+#endif
+ mdelay(5);
+}
+
+void cm3511_power_up(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(4*32+23);
+ __gpio_set_pin(4*32+23);
+#elif defined(CONFIG_JZ4760_ALTAIR)
+ __gpio_as_output(0*32+27); /* GPA27 */
+ __gpio_set_pin(0*32+27);
+#elif defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27); /* GPB27 */
+ __gpio_set_pin(32 * 1 + 27);
+#endif
+ mdelay(5);
+}
+
+int cm3511_set_mclk(unsigned int mclk)
+{
+ return 0;//in this board use the extra osc - -20MHZ
+}
+
+void cm3511_reset(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(5*32+23); /* GPIO_IO_SWETCH_EN */
+ __gpio_clear_pin(5*32+23);
+ __gpio_as_output(2*32+31); /* GPIO_BOOTSEL1 for camera rest*/
+ __gpio_set_pin(2*32+31);
+ mdelay(5);
+ __gpio_clear_pin(2*32+31);
+ mdelay(5);
+ __gpio_set_pin(2*32+31);
+#else
+ __gpio_as_output(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+#endif
+}
+
+int cm3511_set_balance(balance_flag_t balance_flag,int arg)
+{
+ dprintk("cm3511_set_balance");
+ switch(balance_flag)
+ {
+ case WHITE_BALANCE_AUTO:
+ cm3511_set_wb_auto(cm3511.client);
+ dprintk("WHITE_BALANCE_AUTO");
+ break;
+ case WHITE_BALANCE_INCANDESCENT :
+ cm3511_set_wb_incandescence(cm3511.client);
+ dprintk("WHITE_BALANCE_INCANDESCENT ");
+ break;
+ case WHITE_BALANCE_FLUORESCENT ://ying guang
+ cm3511_set_wb_fluorescent(cm3511.client);
+ dprintk("WHITE_BALANCE_FLUORESCENT ");
+ break;
+ case WHITE_BALANCE_WARM_FLUORESCENT :
+ dprintk("WHITE_BALANCE_WARM_FLUORESCENT ");
+ break;
+ case WHITE_BALANCE_DAYLIGHT ://ri guang
+ cm3511_set_wb_daylight(cm3511.client);
+ dprintk("WHITE_BALANCE_DAYLIGHT ");
+ break;
+ case WHITE_BALANCE_CLOUDY_DAYLIGHT ://ying tian
+ cm3511_set_wb_cloud(cm3511.client);
+ dprintk("WHITE_BALANCE_CLOUDY_DAYLIGHT ");
+ break;
+ case WHITE_BALANCE_TWILIGHT :
+ dprintk("WHITE_BALANCE_TWILIGHT ");
+ break;
+ case WHITE_BALANCE_SHADE :
+ dprintk("WHITE_BALANCE_SHADE ");
+ break;
+ }
+
+ return 0;
+}
+
+int cm3511_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ dprintk("cm3511_set_antibanding");
+ switch(antibanding_flag)
+ {
+ case ANTIBANDING_AUTO :
+ dprintk("ANTIBANDING_AUTO ");
+ break;
+ case ANTIBANDING_50HZ :
+ cm3511_set_ab_50hz(cm3511.client);
+ dprintk("ANTIBANDING_50HZ ");
+ break;
+ case ANTIBANDING_60HZ :
+ cm3511_set_ab_60hz(cm3511.client);
+ dprintk("ANTIBANDING_60HZ ");
+ break;
+ case ANTIBANDING_OFF :
+ dprintk("ANTIBANDING_OFF ");
+ break;
+ }
+ return 0;
+}
+
+int cm3511_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("cm3511_set_flash_mode");
+ switch(flash_mode_flag)
+ {
+ case FLASH_MODE_OFF :
+ dprintk("FLASH_MODE_OFF");
+ break;
+ case FLASH_MODE_AUTO :
+ dprintk("FLASH_MODE_AUTO ");
+ break;
+ case FLASH_MODE_ON :
+ dprintk("FLASH_MODE_ON ");
+ break;
+ case FLASH_MODE_RED_EYE:
+ dprintk("FLASH_MODE_RED_EYE ");
+ break;
+ case FLASH_MODE_TORCH:
+ dprintk("FLASH_MODE_TORCH ");
+ break;
+ }
+ return 0;
+
+}
+
+int cm3511_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ dprintk("cm3511_set_scene_mode");
+ switch(scene_mode_flag)
+ {
+ case SCENE_MODE_AUTO :
+ dprintk("SCENE_MODE_AUTO ");
+ break;
+ case SCENE_MODE_ACTION :
+ dprintk("SCENE_MODE_ACTION ");
+ break;
+ case SCENE_MODE_PORTRAIT :
+ dprintk("SCENE_MODE_PORTRAIT ");
+ break;
+ case SCENE_MODE_LANDSCAPE :
+ dprintk("SCENE_MODE_LANDSCAPE ");
+ break;
+ case SCENE_MODE_NIGHT :
+ dprintk("SCENE_MODE_NIGHT ");
+ break;
+ case SCENE_MODE_NIGHT_PORTRAIT :
+ dprintk("SCENE_MODE_NIGHT_PORTRAIT ");
+ break;
+ case SCENE_MODE_THEATRE :
+ dprintk("SCENE_MODE_THEATRE ");
+ break;
+ case SCENE_MODE_BEACH :
+ dprintk("SCENE_MODE_BEACH ");
+ break;
+ case SCENE_MODE_SNOW :
+ dprintk("SCENE_MODE_SNOW ");
+ break;
+ case SCENE_MODE_SUNSET :
+ dprintk("SCENE_MODE_SUNSET ");
+ break;
+ case SCENE_MODE_STEADYPHOTO :
+ dprintk("SCENE_MODE_STEADYPHOTO ");
+ break;
+ case SCENE_MODE_FIREWORKS :
+ dprintk("SCENE_MODE_FIREWORKS ");
+ break;
+ case SCENE_MODE_SPORTS :
+ dprintk("SCENE_MODE_SPORTS ");
+ break;
+ case SCENE_MODE_PARTY :
+ dprintk("SCENE_MODE_PARTY ");
+ break;
+ case SCENE_MODE_CANDLELIGHT :
+ dprintk("SCENE_MODE_CANDLELIGHT ");
+ break;
+ }
+ return 0;
+}
+
+int cm3511_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("cm3511_set_focus_mode");
+ switch(flash_mode_flag)
+ {
+ case FOCUS_MODE_AUTO:
+ dprintk("FOCUS_MODE_AUTO");
+ break;
+ case FOCUS_MODE_INFINITY:
+ dprintk("FOCUS_MODE_INFINITY");
+ break;
+ case FOCUS_MODE_MACRO:
+ dprintk("FOCUS_MODE_MACRO");
+ break;
+ case FOCUS_MODE_FIXED:
+ dprintk("FOCUS_MODE_FIXED");
+ break;
+ }
+
+ return 0;
+}
+
+int cm3511_set_power(int state)
+{
+ switch (state)
+ {
+ case 0:
+ /* hardware power up first */
+ cm3511_power_up();
+ /* software power up later if it implemented */
+ break;
+ case 1:
+ cm3511_power_down();
+ break;
+ case 2:
+ break;
+ default:
+ printk("%s : EINVAL! \n",__FUNCTION__);
+ }
+ return 0;
+}
+
+/* sensor_set_function use for init preview or capture.
+ * there may be some difference between preview and capture.
+ * so we divided it into two sequences.
+ * param: function indicated which function
+ * 0: preview
+ * 1: capture
+ * 2: recording
+ */
+int cm3511_set_effect(effect_flag_t effect_flag,int arg)
+{
+ dprintk("cm3511_set_effect");
+ switch(effect_flag)
+ {
+ case EFFECT_NONE:
+ cm3511_set_effect_normal(cm3511.client);
+ dprintk("EFFECT_NONE");
+ break;
+ case EFFECT_MONO :
+ cm3511_set_effect_grayscale(cm3511.client);
+ dprintk("EFFECT_MONO ");
+ break;
+ case EFFECT_NEGATIVE :
+ cm3511_set_effect_colorinv(cm3511.client);
+ dprintk("EFFECT_NEGATIVE ");
+ break;
+ case EFFECT_SOLARIZE ://bao guang
+ dprintk("EFFECT_SOLARIZE ");
+ break;
+ case EFFECT_SEPIA :
+ cm3511_set_effect_sepia(cm3511.client);
+ dprintk("EFFECT_SEPIA ");
+ break;
+ case EFFECT_POSTERIZE ://se diao fen li
+ dprintk("EFFECT_POSTERIZE ");
+ break;
+ case EFFECT_WHITEBOARD :
+ dprintk("EFFECT_WHITEBOARD ");
+ break;
+ case EFFECT_BLACKBOARD :
+ dprintk("EFFECT_BLACKBOARD ");
+ break;
+ case EFFECT_AQUA ://qian lv se
+ cm3511_set_effect_sepiagreen(cm3511.client);
+ dprintk("EFFECT_AQUA ");
+ break;
+ case EFFECT_PASTEL:
+ dprintk("EFFECT_PASTEL");
+ break;
+ case EFFECT_MOSAIC:
+ dprintk("EFFECT_MOSAIC");
+ break;
+ case EFFECT_RESIZE:
+ dprintk("EFFECT_RESIZE");
+ break;
+ }
+
+ return 0;
+}
+
+int cm3511_set_output_format(pixel_format_flag_t pixel_format_flag,int arg)
+{
+ switch(pixel_format_flag)
+ {
+ case PIXEL_FORMAT_JPEG:
+ printk("cm3511 set output format to jepg");
+ break;
+ case PIXEL_FORMAT_YUV422SP:
+ printk("cm3511 set output format to yuv422sp");
+ break;
+ case PIXEL_FORMAT_YUV420SP:
+ printk("cm3511 set output format to yuv420sp");
+ break;
+ case PIXEL_FORMAT_YUV422I:
+ printk("cm3511 set output format to yuv422i");
+ break;
+ case PIXEL_FORMAT_RGB565:
+ printk("cm3511 set output format to rgb565");
+ break;
+ }
+ return 0;
+}
+
+int cm3511_set_function(int function)
+{
+ switch (function)
+ {
+ case 0:
+ cm3511_set_preview_mode(cm3511.client);
+ break;
+ case 1:
+ cm3511_set_capture_mode(cm3511.client);
+ break;
+ case 2:
+ break;
+ case 3:
+ dprintk("---- do focus ---");
+ break;
+ }
+
+ return 0;
+}
+
+int cm3511_set_fps(int fps)
+{
+ dprintk("set fps : %d",fps);
+ return 0;
+}
+
+int cm3511_set_night_mode(int enable)
+{
+ if(enable)
+ dprintk("nightshot_mode enable!");
+ else
+ dprintk("nightshot_mode disable!");
+
+ cm3511_set_nightmode(cm3511.client,enable);
+ return 0;
+}
+
+int cm3511_set_luma_adaptation(int arg)
+{
+ dprintk("luma_adaptation : %d",arg);
+ return 0;
+}
+
+int cm3511_set_parameter(int cmd, int mode, int arg)
+{
+ switch(cmd)
+ {
+ case CPCMD_SET_BALANCE :
+ cm3511_set_balance(mode,arg);
+ break;
+ case CPCMD_SET_EFFECT :
+ cm3511_set_effect(mode,arg);
+ break;
+ case CPCMD_SET_ANTIBANDING :
+ cm3511_set_antibanding(mode,arg);
+ break;
+ case CPCMD_SET_FLASH_MODE :
+ cm3511_set_flash_mode(mode,arg);
+ break;
+ case CPCMD_SET_SCENE_MODE :
+ cm3511_set_scene_mode(mode,arg);
+ break;
+ case CPCMD_SET_PIXEL_FORMAT :
+ cm3511_set_output_format(mode,arg);
+ break;
+ case CPCMD_SET_FOCUS_MODE :
+ cm3511_set_focus_mode(mode,arg);
+ break;
+ case CPCMD_SET_PREVIEW_FPS:
+ cm3511_set_fps(arg);
+ break;
+ case CPCMD_SET_NIGHTSHOT_MODE:
+ cm3511_set_night_mode(arg);
+ break;
+ case CPCMD_SET_LUMA_ADAPTATION:
+ cm3511_set_luma_adaptation(arg);
+ break;
+ }
+ return 0;
+}
+
+int cm3511_sensor_init(void)
+{
+ cm3511_set_mclk(0);
+ cm3511_reset();
+
+ sensor_write_reg(cm3511.client,0x03, 0x00);//
+ sensor_write_reg(cm3511.client,0x01, 0xC1);
+ sensor_write_reg(cm3511.client,0x01, 0xC3);//
+ sensor_write_reg(cm3511.client,0x01, 0xC1);
+
+ mdelay(50);
+ sensor_write_reg(cm3511.client,0x03, 0x00);//
+
+ cm3511_init_setting(cm3511.client);
+ return 0;
+}
+
+int cm3511_sensor_probe(void)
+{
+ int sensor_id=0;
+ cm3511_power_up();
+ cm3511_reset();
+
+ sensor_write_reg(cm3511.client,0x03, 0x00);//
+ sensor_write_reg(cm3511.client,0x01, 0xC1);
+ sensor_write_reg(cm3511.client,0x01, 0xC3);//
+ sensor_write_reg(cm3511.client,0x01, 0xC1);
+
+ mdelay(50);
+ sensor_write_reg(cm3511.client,0x03, 0x00);//
+ sensor_id = sensor_read_reg(cm3511.client,0x04);
+
+ cm3511_power_down();
+ if(sensor_id == 0x81)
+ return 0;
+
+ dprintk("sensor read is %d",sensor_id);
+ return -1;
+}
+
+int cm3511_set_resolution(int width,int height,int bpp,pixel_format_flag_t fmt,camera_mode_t mode)
+{
+ return 0;
+}
+
+struct camera_sensor_ops cm3511_sensor_ops = {
+ .sensor_init = cm3511_sensor_init,
+ .camera_sensor_probe = cm3511_sensor_probe,
+ .sensor_set_function = cm3511_set_function,
+ .sensor_set_resolution = cm3511_set_resolution,
+ .sensor_set_parameter = cm3511_set_parameter,
+ .sensor_set_power = cm3511_set_power,
+};
+
+struct resolution_info cm3511_resolution_table[] = {
+ {640,480,16,PIXEL_FORMAT_YUV422I},
+// {352,288,16,PIXEL_FORMAT_YUV422I},
+};
+
+struct cm3511_sensor cm3511 = {
+ .desc = {
+ .name = "cm3511",
+ .wait_frames = 4,
+
+ .ops = &cm3511_sensor_ops,
+
+ .resolution_table = cm3511_resolution_table,
+ .resolution_table_nr=ARRAY_SIZE(cm3511_resolution_table),
+
+ .capture_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+
+ .preview_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+
+ .cfg_info = {
+ .configure_register= 0x0
+ |CIM_CFG_PACK_4 /* pack mode : 4 3 2 1 */
+ |CIM_CFG_BYPASS /* Bypass Mode */
+ // |CIM_CFG_VSP /* VSYNC Polarity:1-falling edge active */
+ // |CIM_CFG_PCP /* PCLK working edge:1-falling */
+ |CIM_CFG_DSM_GCM, /* Gated Clock Mode */
+ },
+
+ .flags = {
+ .pixel_format_flag = PIXEL_FORMAT_YUV422SP,
+
+ .scene_mode_flag = ~0,
+
+ .effect_flag = 0
+ |EFFECT_NONE
+ |EFFECT_MONO
+ |EFFECT_SEPIA
+ |EFFECT_NEGATIVE
+ |EFFECT_AQUA,
+
+ .balance_flag = 0
+ | WHITE_BALANCE_AUTO
+ | WHITE_BALANCE_DAYLIGHT
+ | WHITE_BALANCE_CLOUDY_DAYLIGHT
+ | WHITE_BALANCE_INCANDESCENT
+ | WHITE_BALANCE_FLUORESCENT,
+
+ .antibanding_flag = 0
+ |ANTIBANDING_50HZ
+ |ANTIBANDING_60HZ,
+ },
+
+ },
+};
+
+static int cm3511_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ dprintk("cm3511_i2c_probe!\n");
+ cm3511.client = client;
+ return camera_sensor_register(&cm3511.desc);
+}
+
+static const struct i2c_device_id cm3511_id[] = {
+ { "cm3511", 0 },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(i2c, cm3511_id);
+
+static struct i2c_driver cm3511_driver = {
+ .probe = cm3511_i2c_probe,
+ .id_table = cm3511_id,
+ .driver = {
+ .name = "cm3511",
+ },
+};
+
+static int __init cm3511_i2c_register(void)
+{
+ return i2c_add_driver(&cm3511_driver);
+}
+
+module_init(cm3511_i2c_register);
+
+
diff --git a/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.h b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.h
new file mode 100644
index 00000000000..808f1c6e228
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_camera.h
@@ -0,0 +1,26 @@
+/*
+ * linux/drivers/misc/camera_source/cm3511/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef CM3511_CAMERA_H
+#define CM3511_CAMERA_H
+
+
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+
+
+struct cm3511_sensor
+{
+ struct i2c_client *client;
+ struct camera_sensor_desc desc;
+};
+
+#endif
diff --git a/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.c b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.c
new file mode 100644
index 00000000000..1b339b39675
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.c
@@ -0,0 +1,595 @@
+
+#include <asm/jzsoc.h>
+#include "../../jz_sensor.h"
+#include <linux/i2c.h>
+
+#define cm3511_DEBUG
+//#undef DEBUG
+
+#ifdef cm3511_DEBUG
+#define dprintk(x...) do{printk("cm3511---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+
+
+void cm3511_set_preview_mode(struct i2c_client *client)
+{
+}
+
+void cm3511_set_capture_mode(struct i2c_client *client)
+{
+}
+
+void cm3511_set_nightmode(struct i2c_client *client,int enable)
+{
+ if (!enable)
+ {
+
+ sensor_write_reg(client,0x01, 0xf1);
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x1c);
+ sensor_write_reg(client,0x18, 0x38);
+ sensor_write_reg(client,0x83, 0x01);//20fps
+ sensor_write_reg(client,0x84, 0x24);
+ sensor_write_reg(client,0x85, 0xf8);
+ sensor_write_reg(client,0x88, 0x02);//10fps
+ sensor_write_reg(client,0x89, 0x49);
+ sensor_write_reg(client,0x8a, 0xf0);
+ sensor_write_reg(client,0x70, 0x42);
+ sensor_write_reg(client,0xb2, 0xd0);//AGMAX
+ sensor_write_reg(client,0x01, 0xf0);
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x9c);
+ sensor_write_reg(client,0x18, 0x30);
+ }
+ else
+ {
+
+ sensor_write_reg(client,0x01, 0xf1);
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x1c);
+ sensor_write_reg(client,0x18, 0x38);
+ sensor_write_reg(client,0x83, 0x01);//20fps
+ sensor_write_reg(client,0x84, 0x24);
+ sensor_write_reg(client,0x85, 0xf8);
+ sensor_write_reg(client,0x88, 0x06); // 3.333fps
+ sensor_write_reg(client,0x89, 0xdd);
+ sensor_write_reg(client,0x8a, 0xd0);
+ sensor_write_reg(client,0x70, 0x48);
+ sensor_write_reg(client,0xb2, 0xd0);//AGMAX
+ sensor_write_reg(client,0x01, 0xf0);
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x9c);
+ sensor_write_reg(client,0x18, 0x30);
+ }
+} /* CM3511_NightMode */
+
+void cm3511_set_ab_50hz(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x9c);
+}
+
+void cm3511_set_ab_60hz(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x8c);
+}
+
+void cm3511_set_effect_normal(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x30);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_grayscale(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x23);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_sepia(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x23);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x70);
+ sensor_write_reg(client,0x45, 0x98);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_colorinv(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x28);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_sepiagreen(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x33);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x30);
+ sensor_write_reg(client,0x45, 0x50);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_sepiablue(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x33);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0xb0);
+ sensor_write_reg(client,0x45, 0x40);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_grayinv(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x28);
+ sensor_write_reg(client,0x13, 0x00);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x03);
+}
+
+void cm3511_set_effect_embossment(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x23);
+ sensor_write_reg(client,0x12, 0x33);
+ sensor_write_reg(client,0x13, 0x02);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x07);
+}
+
+void cm3511_set_effect_sketch(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03, 0x10);
+ sensor_write_reg(client,0x11, 0x13);
+ sensor_write_reg(client,0x12, 0x38);
+ sensor_write_reg(client,0x13, 0x02);
+ sensor_write_reg(client,0x44, 0x80);
+ sensor_write_reg(client,0x45, 0x80);
+ sensor_write_reg(client,0x47, 0x7f);
+ sensor_write_reg(client,0x20, 0x07);
+ sensor_write_reg(client,0x21, 0x07);
+}
+
+
+void cm3511_set_wb_auto(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03,0x22); // AUTO 3000K~7000K
+ sensor_write_reg(client,0x10,0x6a);
+ //sensor_write_reg(client,0x80,0x3a);
+ //sensor_write_reg(client,0x81,0x20);
+ //sensor_write_reg(client,0x82,0x32);
+ sensor_write_reg(client,0x83,0x65);
+ sensor_write_reg(client,0x84,0x1a);
+ sensor_write_reg(client,0x85,0x58);
+ sensor_write_reg(client,0x86,0x22);
+ sensor_write_reg(client,0x03,0x22);
+ sensor_write_reg(client,0x10,0xea);
+}
+
+void cm3511_set_wb_cloud(struct i2c_client *client)
+{
+ // NOON130PC20_reg_WB_cloudy ÒõÌì
+ sensor_write_reg(client,0x03,0x22); //7000K
+ sensor_write_reg(client,0x10,0x6a);
+ sensor_write_reg(client,0x80,0x50);
+ sensor_write_reg(client,0x81,0x20);
+ sensor_write_reg(client,0x82,0x24);
+ sensor_write_reg(client,0x83,0x6d);
+ sensor_write_reg(client,0x84,0x65);
+ sensor_write_reg(client,0x85,0x24);
+ sensor_write_reg(client,0x86,0x1c);
+ //sensor_write_reg(client,0x03,0x22);
+ //sensor_write_reg(client,0x10,0xea);
+}
+
+
+void cm3511_set_wb_daylight(struct i2c_client *client)
+{
+ // NOON130PC20_reg_WB_daylight °×Ìì
+ sensor_write_reg(client,0x03,0x22); //6500K
+ sensor_write_reg(client,0x10,0x6a);
+ sensor_write_reg(client,0x80,0x40);
+ sensor_write_reg(client,0x81,0x20);
+ sensor_write_reg(client,0x82,0x28);
+ sensor_write_reg(client,0x83,0x45);
+ sensor_write_reg(client,0x84,0x35);
+ sensor_write_reg(client,0x85,0x2d);
+ sensor_write_reg(client,0x86,0x1c);
+}
+
+
+void cm3511_set_wb_incandescence(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03,0x22); //2800K~3000K
+ sensor_write_reg(client,0x10,0x6a);
+ sensor_write_reg(client,0x80,0x25);
+ sensor_write_reg(client,0x81,0x20);
+ sensor_write_reg(client,0x82,0x44);
+ sensor_write_reg(client,0x83,0x24);
+ sensor_write_reg(client,0x84,0x1e);
+ sensor_write_reg(client,0x85,0x50);
+ sensor_write_reg(client,0x86,0x45);
+}
+
+
+void cm3511_set_wb_fluorescent(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03,0x22); //4200K~5000K
+ sensor_write_reg(client,0x10,0x6a);
+ sensor_write_reg(client,0x80,0x35);
+ sensor_write_reg(client,0x81,0x20);
+ sensor_write_reg(client,0x82,0x32);
+ sensor_write_reg(client,0x83,0x3c);
+ sensor_write_reg(client,0x84,0x2c);
+ sensor_write_reg(client,0x85,0x45);
+ sensor_write_reg(client,0x86,0x35);
+}
+
+
+void cm3511_set_wb_tungsten(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x03,0x22); //4000K
+ sensor_write_reg(client,0x10,0x6a);
+ sensor_write_reg(client,0x80,0x33);
+ sensor_write_reg(client,0x81,0x20);
+ sensor_write_reg(client,0x82,0x3d);
+ sensor_write_reg(client,0x83,0x2e);
+ sensor_write_reg(client,0x84,0x24);
+ sensor_write_reg(client,0x85,0x43);
+ sensor_write_reg(client,0x86,0x3d);
+}
+
+
+void cm3511_init_setting(struct i2c_client *client)
+{
+ dprintk("-------------sensor init!");
+ sensor_write_reg(client,0x01, 0xf1);
+ sensor_write_reg(client,0x01, 0xf3);
+ sensor_write_reg(client,0x01, 0xf1);
+
+ sensor_write_reg(client,0x03, 0x20);
+ sensor_write_reg(client,0x10, 0x1c);//AE off
+ sensor_write_reg(client,0x03, 0x22);
+ sensor_write_reg(client,0x10, 0x6a);//AWB off
+
+ sensor_write_reg(client,0x03, 0x00);//Page 0
+ sensor_write_reg(client,0x10, 0x00);
+ sensor_write_reg(client,0x11, 0x90);
+ sensor_write_reg(client,0x12, 0x04);//Pclk inversion
+ sensor_write_reg(client,0x20, 0x00);
+ sensor_write_reg(client,0x21, 0x05);
+ sensor_write_reg(client,0x22, 0x00);
+ sensor_write_reg(client,0x23, 0x07);
+ sensor_write_reg(client,0x24, 0x01);
+ sensor_write_reg(client,0x25, 0xe0);
+ sensor_write_reg(client,0x26, 0x02);
+ sensor_write_reg(client,0x27, 0x80);
+
+ sensor_write_reg(client,0x40, 0x01);
+ sensor_write_reg(client,0x41, 0x50);
+ sensor_write_reg(client,0x42, 0x00);
+ sensor_write_reg(client,0x43, 0x14);
+
+ sensor_write_reg(client,0x80, 0x0e);
+ sensor_write_reg(client,0x90, 0x0a);
+ sensor_write_reg(client,0x91, 0x0a);
+ sensor_write_reg(client,0x92, 0x60);
+
+ sensor_write_reg(client,0xa0, 0x10);
+ sensor_write_reg(client,0xa1, 0x10);
+ sensor_write_reg(client,0xa2, 0x10);
+ sensor_write_reg(client,0xa3, 0x10);
+ sensor_write_reg(client,0xa4, 0x10);
+ sensor_write_reg(client,0xa5, 0x10);
+ sensor_write_reg(client,0xa6, 0x10);
+ sensor_write_reg(client,0xa7, 0x10);
+
+ sensor_write_reg(client,0xa8, 0x48);
+ sensor_write_reg(client,0xa9, 0x48);
+ sensor_write_reg(client,0xaa, 0x47);
+ sensor_write_reg(client,0xab, 0x47);
+ sensor_write_reg(client,0xac, 0x47);
+ sensor_write_reg(client,0xad, 0x47);
+ sensor_write_reg(client,0xae, 0x46);
+ sensor_write_reg(client,0xaf, 0x46);
+
+ sensor_write_reg(client,0x03, 0x02 );//Page 2
+ sensor_write_reg(client,0x1a, 0x31 );
+ sensor_write_reg(client,0x1c, 0x00 );
+ sensor_write_reg(client,0x1d, 0x03 );
+
+ sensor_write_reg(client,0x20, 0x33 );
+ sensor_write_reg(client,0x21, 0x77 );
+ sensor_write_reg(client,0x22, 0xad );
+ sensor_write_reg(client,0x34, 0xff );
+ sensor_write_reg(client,0x54, 0x30 );
+
+ sensor_write_reg(client,0x62, 0x78 );
+ sensor_write_reg(client,0x63, 0x7a );
+ sensor_write_reg(client,0x64, 0x7d );
+ sensor_write_reg(client,0x65, 0x88 );
+
+ sensor_write_reg(client,0x72, 0x78 );
+ sensor_write_reg(client,0x73, 0x8b );
+ sensor_write_reg(client,0x74, 0x78 );
+ sensor_write_reg(client,0x75, 0x8b );
+
+ sensor_write_reg(client,0xa0, 0x03 );
+ sensor_write_reg(client,0xa8, 0x03 );
+ sensor_write_reg(client,0xaa, 0x03 );
+
+ sensor_write_reg(client,0x03, 0x10 );//Page 10
+ sensor_write_reg(client,0x10, 0x01);//ISPCTL1(Control the format of image data) : YUV order for Lot51 by NHJ
+ sensor_write_reg(client,0x11, 0x03);
+ sensor_write_reg(client,0x12, 0x30);
+
+ //sensor_write_reg(client,0x40, 0x18);
+ sensor_write_reg(client,0x41, 0x05);
+ sensor_write_reg(client,0x50, 0x50);
+
+ sensor_write_reg(client,0x60, 0x1f);
+ sensor_write_reg(client,0x61, 0xa8);
+ sensor_write_reg(client,0x62, 0xaa);
+ sensor_write_reg(client,0x63, 0x50);
+ sensor_write_reg(client,0x64, 0x60);
+ sensor_write_reg(client,0x65, 0x90);
+
+ sensor_write_reg(client,0x03, 0x11);//Page 11
+ sensor_write_reg(client,0x10, 0x1d);
+ sensor_write_reg(client,0x11, 0x0a); //open LPF in dark, 0x0a close
+ sensor_write_reg(client,0x21, 0x28);
+ sensor_write_reg(client,0x60, 0x12);
+ sensor_write_reg(client,0x61, 0x83);
+ sensor_write_reg(client,0x62, 0x43);
+ sensor_write_reg(client,0x63, 0x53);
+
+ sensor_write_reg(client,0x03, 0x12);//Page 12
+ sensor_write_reg(client,0x40, 0x21);
+ sensor_write_reg(client,0x41, 0x07);
+ sensor_write_reg(client,0x42, 0x0f); //add
+ sensor_write_reg(client,0x50, 0x0d);
+ sensor_write_reg(client,0x70, 0x1d);
+ sensor_write_reg(client,0x74, 0x04);
+ sensor_write_reg(client,0x75, 0x06);
+ sensor_write_reg(client,0x90, 0x5d);
+ sensor_write_reg(client,0x91, 0x10);
+ sensor_write_reg(client,0xb0, 0xc9);
+
+ sensor_write_reg(client,0x03, 0x13);//Page 13
+ sensor_write_reg(client,0x10, 0x19);
+ sensor_write_reg(client,0x11, 0x07);
+ sensor_write_reg(client,0x12, 0x01);
+ sensor_write_reg(client,0x13, 0x02);
+ sensor_write_reg(client,0x20, 0x06);
+ sensor_write_reg(client,0x21, 0x05);
+ sensor_write_reg(client,0x23, 0x18);
+ sensor_write_reg(client,0x24, 0x03);
+
+ sensor_write_reg(client,0x80, 0x0d);
+ sensor_write_reg(client,0x81, 0x01);
+ sensor_write_reg(client,0x83, 0x5d);
+
+ sensor_write_reg(client,0x90, 0x02);
+ sensor_write_reg(client,0x91, 0x02);
+ sensor_write_reg(client,0x93, 0x19);
+ sensor_write_reg(client,0x94, 0x03);
+ sensor_write_reg(client,0x95, 0x00);
+
+ sensor_write_reg(client,0x03, 0x14);//Page 14
+ sensor_write_reg(client,0x10, 0x07);
+ sensor_write_reg(client,0x20, 0x80);
+ sensor_write_reg(client,0x21, 0x80);
+ sensor_write_reg(client,0x22, 0x80);
+ sensor_write_reg(client,0x23, 0x64);
+ sensor_write_reg(client,0x24, 0x52);
+ sensor_write_reg(client,0x25, 0x78);
+ sensor_write_reg(client,0x26, 0x70);
+
+ sensor_write_reg(client,0x03, 0x15);//Page 15
+ sensor_write_reg(client,0x10, 0x0f);
+ sensor_write_reg(client,0x14, 0x36);
+ sensor_write_reg(client,0x16, 0x28);
+ sensor_write_reg(client,0x17, 0x2f);
+
+ sensor_write_reg(client,0x30, 0x5b);
+ sensor_write_reg(client,0x31, 0x26);
+ sensor_write_reg(client,0x32, 0x0a);
+ sensor_write_reg(client,0x33, 0x11);
+ sensor_write_reg(client,0x34, 0x65);
+ sensor_write_reg(client,0x35, 0x14);
+ sensor_write_reg(client,0x36, 0x01);
+ sensor_write_reg(client,0x37, 0x33);
+ sensor_write_reg(client,0x38, 0x74);
+
+ sensor_write_reg(client,0x40, 0x00);
+ sensor_write_reg(client,0x41, 0x00);
+ sensor_write_reg(client,0x42, 0x00);
+ sensor_write_reg(client,0x43, 0x8b);
+ sensor_write_reg(client,0x44, 0x07);
+ sensor_write_reg(client,0x45, 0x04);
+ sensor_write_reg(client,0x46, 0x84);
+ sensor_write_reg(client,0x47, 0xa1);
+ sensor_write_reg(client,0x48, 0x25);
+
+ sensor_write_reg(client,0x03, 0x16);//Page 16
+ sensor_write_reg(client,0x10, 0x01);
+ sensor_write_reg(client,0x30, 0x00);// original
+ sensor_write_reg(client,0x31, 0x0d);
+ sensor_write_reg(client,0x32, 0x16);
+ sensor_write_reg(client,0x33, 0x2a);
+ sensor_write_reg(client,0x34, 0x44);
+ sensor_write_reg(client,0x35, 0x62);
+ sensor_write_reg(client,0x36, 0x7d);
+ sensor_write_reg(client,0x37, 0x97);
+ sensor_write_reg(client,0x38, 0xa9);
+ sensor_write_reg(client,0x39, 0xba);
+ sensor_write_reg(client,0x3a, 0xc8);
+ sensor_write_reg(client,0x3b, 0xdd);
+ sensor_write_reg(client,0x3c, 0xec);
+ sensor_write_reg(client,0x3d, 0xf8);
+ sensor_write_reg(client,0x3e, 0xff);
+
+ sensor_write_reg(client,0x03, 0x17);
+ sensor_write_reg(client,0xc0, 0x03);
+ sensor_write_reg(client,0xc4, 0x23);
+ sensor_write_reg(client,0xc5, 0x1d);
+ sensor_write_reg(client,0xc6, 0x02);
+ sensor_write_reg(client,0xc7, 0x20);
+
+ sensor_write_reg(client,0x03, 0x20);//page 20
+ sensor_write_reg(client,0x10, 0x1c);
+ sensor_write_reg(client,0x11, 0x00);
+ sensor_write_reg(client,0x20, 0x00);
+ sensor_write_reg(client,0x28, 0x0b);
+ sensor_write_reg(client,0x29, 0xaf);
+ sensor_write_reg(client,0x2a, 0xf0);
+ sensor_write_reg(client,0x2b, 0x34);
+ sensor_write_reg(client,0x30, 0xf8); //new add by peter
+
+ sensor_write_reg(client,0x60, 0x00);
+ //sensor_write_reg(client,0x70, 0x42);
+ sensor_write_reg(client,0x7a, 0x34);
+
+
+ sensor_write_reg(client,0x83, 0x01); //;;ExpNormal 20Fps
+ sensor_write_reg(client,0x84, 0x24);
+ sensor_write_reg(client,0x85, 0xf8);
+
+ sensor_write_reg(client,0x86, 0x01);
+ sensor_write_reg(client,0x87, 0xf4);
+
+ //sensor_write_reg(client,0x88, 0x06);//ExpMin 3.3333Fps
+ //sensor_write_reg(client,0x89, 0xdd);
+ //sensor_write_reg(client,0x8a, 0xd0);
+
+ //sensor_write_reg(client,0x88, 0x02);//ExpMin 10Fps
+ //sensor_write_reg(client,0x89, 0x49);
+ //sensor_write_reg(client,0x8a, 0xf0);
+
+ sensor_write_reg(client,0x8b, 0x3a);//EXP100
+ sensor_write_reg(client,0x8c, 0x98);
+ sensor_write_reg(client,0x8d, 0x30);//EXP120
+ sensor_write_reg(client,0x8e, 0xd4);
+
+ sensor_write_reg(client,0x8f, 0xc4);
+ sensor_write_reg(client,0x90, 0x68);
+
+ sensor_write_reg(client,0x9c, 0x04);//new add by peter
+ sensor_write_reg(client,0x9d, 0x65);
+ sensor_write_reg(client,0x9e, 0x00);
+ sensor_write_reg(client,0x9f, 0xfa);
+
+ sensor_write_reg(client,0xb0, 0x1a);//AG
+ sensor_write_reg(client,0xb1, 0x1a);//AGMIN
+ //sensor_write_reg(client,0xb2, 0x80);//AGMAX
+ sensor_write_reg(client,0xb3, 0x1a);//AGLVL
+ sensor_write_reg(client,0xb4, 0x1a);//AGTH1
+ sensor_write_reg(client,0xb5, 0x45);//AGTH2
+ sensor_write_reg(client,0xb6, 0x2f);//AGBTH1
+ sensor_write_reg(client,0xb7, 0x28);//AGBTH2
+ sensor_write_reg(client,0xb8, 0x24);//AGBTH3
+ sensor_write_reg(client,0xb9, 0x22);//AGBTH4
+ sensor_write_reg(client,0xba, 0x21);//AGBTH5
+ sensor_write_reg(client,0xbb, 0x20);//AGBTH6
+ sensor_write_reg(client,0xbc, 0x1f);//AGBTH7
+ sensor_write_reg(client,0xbd, 0x1e);//AGBTH8
+ sensor_write_reg(client,0xc0, 0x14);//PGA_Sky_gain
+ sensor_write_reg(client,0xc3, 0x60);
+ sensor_write_reg(client,0xc4, 0x58);
+ sensor_write_reg(client,0xc8, 0x78);
+
+ sensor_write_reg(client,0x03, 0x22);//page 22
+ //sensor_write_reg(client,0x10, 0x6a);
+ sensor_write_reg(client,0x11, 0x2c);
+ sensor_write_reg(client,0x21, 0x01);
+ sensor_write_reg(client,0x38, 0x12);
+ sensor_write_reg(client,0x40, 0xe3);
+ sensor_write_reg(client,0x41, 0x88);
+ sensor_write_reg(client,0x42, 0x44);
+ sensor_write_reg(client,0x46, 0x0a);
+
+ sensor_write_reg(client,0x80, 0x38);//R Gain
+ sensor_write_reg(client,0x81, 0x20);//G Gain
+ sensor_write_reg(client,0x82, 0x30);//B Gain
+
+ sensor_write_reg(client,0x83, 0x65);//RMAX
+ sensor_write_reg(client,0x84, 0x1a);//RMIN
+ sensor_write_reg(client,0x85, 0x58);//BMAX
+ sensor_write_reg(client,0x86, 0x22);//BMIN
+
+ sensor_write_reg(client,0x87, 0x50);//RMAXB
+ sensor_write_reg(client,0x88, 0x20);//RMINB
+ sensor_write_reg(client,0x89, 0x50);//BMAXB
+ sensor_write_reg(client,0x8a, 0x20);//BMINB
+ sensor_write_reg(client,0x8b, 0x08);
+ sensor_write_reg(client,0x8d, 0x14);
+ sensor_write_reg(client,0x8e, 0x61);
+
+ sensor_write_reg(client,0x8f, 0x58);
+ sensor_write_reg(client,0x90, 0x54);
+ sensor_write_reg(client,0x91, 0x50);
+ sensor_write_reg(client,0x92, 0x4b);
+ sensor_write_reg(client,0x93, 0x46);
+ sensor_write_reg(client,0x94, 0x43);
+ sensor_write_reg(client,0x95, 0x40);
+ sensor_write_reg(client,0x96, 0x3c);
+ sensor_write_reg(client,0x97, 0x38);
+ sensor_write_reg(client,0x98, 0x34);
+ sensor_write_reg(client,0x99, 0x2e);
+ sensor_write_reg(client,0x9a, 0x26);
+ sensor_write_reg(client,0x9b, 0x07);
+
+ sensor_write_reg(client,0x10, 0xea);//AWB ON
+ //sensor_write_reg(client,0x03, 0x20);//page 20
+ //sensor_write_reg(client,0x10, 0x9c);//AE ON
+
+ sensor_write_reg(client,0x01, 0xf0);
+
+
+} /* CM3511_Write_Sensor_Initial_Setting */
+
diff --git a/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.h b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.h
new file mode 100644
index 00000000000..c16855d906a
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/cm3511/cm3511_set.h
@@ -0,0 +1,32 @@
+
+#ifndef CM3511_SET_H
+#define CM3511_SET_H
+
+
+void cm3511_set_preview_mode(struct i2c_client *client);
+void cm3511_set_capture_mode(struct i2c_client *client);
+
+void cm3511_init_setting(struct i2c_client *client);
+void cm3511_set_nightmode(struct i2c_client *client,int enable);
+
+void cm3511_set_ab_50hz(struct i2c_client *client);
+void cm3511_set_ab_60hz(struct i2c_client *client);
+
+void cm3511_set_wb_auto(struct i2c_client *client);
+void cm3511_set_wb_cloud(struct i2c_client *client);
+void cm3511_set_wb_daylight(struct i2c_client *client);
+void cm3511_set_wb_incandescence(struct i2c_client *client);
+void cm3511_set_wb_fluorescent(struct i2c_client *client);
+void cm3511_set_wb_tungsten(struct i2c_client *client);
+
+void cm3511_set_effect_normal(struct i2c_client *client);
+void cm3511_set_effect_grayscale(struct i2c_client *client);
+void cm3511_set_effect_sepia(struct i2c_client *client);
+void cm3511_set_effect_colorinv(struct i2c_client *client);
+void cm3511_set_effect_sepiagreen(struct i2c_client *client);
+void cm3511_set_effect_sepiablue(struct i2c_client *client);
+void cm3511_set_effect_grayinv(struct i2c_client *client);
+void cm3511_set_effect_embossment(struct i2c_client *client);
+void cm3511_set_effect_sketch(struct i2c_client *client);
+
+#endif
diff --git a/drivers/misc/jz_cim/camera_source/fake/Makefile b/drivers/misc/jz_cim/camera_source/fake/Makefile
new file mode 100644
index 00000000000..e141c80c622
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/fake/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_JZ_FAKE_SENSOR) += fake_camera.o
+
diff --git a/drivers/misc/jz_cim/camera_source/fake/fake_camera.c b/drivers/misc/jz_cim/camera_source/fake/fake_camera.c
new file mode 100644
index 00000000000..d307ca31262
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/fake/fake_camera.c
@@ -0,0 +1,312 @@
+#include <asm/jzsoc.h>
+
+#include "fake_camera.h"
+#include "../../jz_cim_core.h"
+
+unsigned int current_frame_count = 0;
+unsigned int off_set = 4;
+
+unsigned char yuv422i_color_odd[3][4] = {{0xd6, 0x97, 0xca,0x97}, {0x5f, 0x25, 0x6e, 0x25}, {0x73, 0x8e, 0x37, 0x8e}};
+unsigned char yuv422i_color_even[3][4] = {{0x5f, 0x25, 0x6e, 0x25}, {0x73, 0x8e, 0x37, 0x8e}, {0xd6, 0x97, 0xca, 0x97}};
+
+struct fake_sensor_info{
+ struct camera_sensor_desc fake_sensor_desc;
+ unsigned int current_calc_width;
+ unsigned int current_calc_height;
+ pixel_format_flag_t current_pixel_format;
+};
+
+struct fake_sensor_info *current_fake_sensor = NULL;
+
+//*current_fake_sensor;
+
+
+
+void fake_power_down(void)
+{
+}
+
+void fake_power_up(void)
+{
+}
+
+
+void fake_reset(void)
+{
+}
+
+void fake_init(void)
+{
+ // current_format = PIXEL_FORMAT_YUV422I;
+}
+
+void fake_hw_init(void)
+{
+}
+
+int fake_sensor_probe(void)
+{
+ return 0;
+}
+
+int fake_set_balance(balance_flag_t balance_flag,int arg)
+{
+ return 0;
+}
+
+int fake_set_effect(effect_flag_t effect_flag,int arg)
+{
+ return 0;
+}
+
+int fake_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ return 0;
+}
+
+int fake_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+
+}
+
+int fake_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ return 0;
+}
+
+int fake_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+}
+
+int fake_set_output_format(pixel_format_flag_t pixel_format_flag,int arg)
+{
+ switch(pixel_format_flag){
+ case PIXEL_FORMAT_JPEG:
+ printk("pixel_format_jpeg");
+ break;
+ case PIXEL_FORMAT_YUV422SP:
+ printk("pixel_format_yuv422sp");
+ break;
+ case PIXEL_FORMAT_YUV420SP:
+ printk("pixel_format_yuv420sp");
+ break;
+ case PIXEL_FORMAT_YUV422I:
+ if (current_fake_sensor->current_pixel_format == PIXEL_FORMAT_RGB565)
+ current_fake_sensor->current_calc_width /= 2;
+ off_set = 4;
+ break;
+ case PIXEL_FORMAT_RGB565:
+ if (current_fake_sensor->current_pixel_format == PIXEL_FORMAT_YUV422I)
+ current_fake_sensor->current_calc_width *= 2;
+ off_set = 2;
+ break;
+ default:
+ printk("unsupport format");
+ return -1;
+ }
+ current_fake_sensor->current_pixel_format = pixel_format_flag;
+ return 0;
+}
+
+int fake_sensor_init(void)
+{
+ return 1;
+}
+
+
+int fake_set_resolution(int width,int height,int bpp,pixel_format_flag_t fmt,camera_mode_t mode)
+{
+ switch(current_fake_sensor->current_pixel_format){
+ case PIXEL_FORMAT_YUV422I:
+ current_fake_sensor->current_calc_width = width / 2;
+ current_fake_sensor->current_calc_height = height;
+ break;
+ case PIXEL_FORMAT_RGB565:
+ current_fake_sensor->current_calc_width = width;
+ current_fake_sensor->current_calc_height = height;
+ break;
+ }
+
+ fake_set_output_format(PIXEL_FORMAT_YUV422I,0);
+
+ return 0;
+}
+
+int fill_frame(unsigned int distination_addr, unsigned int current_frame_count)
+{
+ unsigned int width_count, height_count, calc_width, calc_height;
+ unsigned char (*start_color)[4], (*source_color)[4], (*color_even)[4], (*color_odd)[4];
+ pixel_format_flag_t current_format;
+
+ calc_width = current_fake_sensor->current_calc_width;
+ calc_height = current_fake_sensor->current_calc_height;
+ color_even = &yuv422i_color_even[current_frame_count];
+ color_odd = &yuv422i_color_odd[current_frame_count];
+ current_format = current_fake_sensor->current_pixel_format;
+ start_color = NULL;
+
+ for (height_count = 0; height_count < calc_height; height_count++){
+ if ((height_count % UNIT_HEIGHT) == 0){
+ if ((height_count / UNIT_HEIGHT) % 2)
+ start_color = color_even;
+ else
+ start_color = color_odd;
+ }
+ source_color = start_color;
+ for (width_count = 0; width_count < calc_width; width_count++){
+ switch (current_format) {
+
+ case PIXEL_FORMAT_YUV422I:
+ if (((width_count * 2 % UNIT_WIDTH) == 0)&&width_count){
+ if (source_color == color_odd)
+ source_color = color_even;
+ else
+ source_color = color_odd;
+ }
+ break;
+ case PIXEL_FORMAT_RGB565:
+ printk("rgb565");
+ }
+ memcpy((unsigned char *)distination_addr, source_color, off_set);
+ distination_addr += off_set;
+ }
+ }
+
+ return 0;
+}
+
+int fake_set_mclk(unsigned int mclk)
+{
+ return 0;
+}
+
+int fake_fill_buffer(unsigned int distination_addr,void *desc)
+{
+ current_fake_sensor = container_of((struct camera_sensor_desc *)desc, struct fake_sensor_info, fake_sensor_desc);
+
+ fill_frame(distination_addr, current_frame_count);
+ current_frame_count++;
+ if (current_frame_count == COLOR_NUM)
+ current_frame_count = 0;
+ return 0;
+}
+
+int fake_set_parameter(int cmd, int mode, int arg)
+{
+ switch(cmd)
+ {
+ case CPCMD_SET_BALANCE :
+ fake_set_balance(mode,arg);
+ break;
+ case CPCMD_SET_EFFECT :
+ fake_set_effect(mode,arg);
+ break;
+ case CPCMD_SET_ANTIBANDING :
+ fake_set_antibanding(mode,arg);
+ break;
+ case CPCMD_SET_FLASH_MODE :
+ fake_set_flash_mode(mode,arg);
+ break;
+ case CPCMD_SET_SCENE_MODE :
+ fake_set_scene_mode(mode,arg);
+ break;
+ case CPCMD_SET_PIXEL_FORMAT :
+ fake_set_output_format(mode,arg);
+ break;
+ case CPCMD_SET_FOCUS_MODE :
+ fake_set_focus_mode(mode,arg);
+ break;
+ }
+}
+
+int fake_set_function(int function)
+{
+ return 0;
+}
+
+int fake_set_power(int state)
+{
+ switch (state)
+ {
+ case 0:
+ /* hardware power up first */
+ fake_power_up();
+ /* software power up later if it implemented */
+ break;
+ case 1:
+ fake_power_down();
+ break;
+ case 2:
+ break;
+ default:
+ printk("%s : EINVAL! \n",__FUNCTION__);
+ }
+ return 0;
+}
+
+
+struct camera_sensor_ops fake_sensor_ops = {
+ .sensor_init = fake_sensor_init,
+ .sensor_set_function = fake_set_function,
+ .sensor_set_resolution = fake_set_resolution,
+ .sensor_set_parameter = fake_set_parameter,
+ .sensor_set_power = fake_set_power,
+
+ .camera_sensor_probe = fake_sensor_probe,
+ .camera_fill_buffer = fake_fill_buffer,
+};
+
+struct resolution_info fake_resolution_table[] = {
+ {2048,1536,16,PIXEL_FORMAT_YUV422I},
+ {1024,768,16,PIXEL_FORMAT_YUV422I},
+ {640,480,16,PIXEL_FORMAT_YUV422I},
+ {352,288,16,PIXEL_FORMAT_YUV422I},
+ {320,240,16,PIXEL_FORMAT_YUV422I},
+ {176,144,16,PIXEL_FORMAT_YUV422I}
+};
+
+struct fake_sensor_info fake_sensor = {
+ .fake_sensor_desc={
+ .name = "fake",
+ .camera_clock = CAM_CLOCK,
+ .no_dma = 1,
+ .ops = &fake_sensor_ops,
+ .flags = {
+ .pixel_format_flag = PIXEL_FORMAT_YUV422I | PIXEL_FORMAT_RGB565,
+ },
+ .resolution_table = fake_resolution_table,
+ .resolution_table_nr=ARRAY_SIZE(fake_resolution_table),
+
+ .preview_parm = {1024,768, DEF_PRE_BPP,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {1024,768, MAX_PRE_BPP,PIXEL_FORMAT_YUV422I},
+
+ .capture_parm = {2048,1536 , DEF_CAP_BPP,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {2048,1536, MAX_CAP_BPP,PIXEL_FORMAT_YUV422I},
+ },
+ .current_calc_width = DEF_PRE_WIDTH / 2,
+ .current_calc_height = DEF_PRE_HEIGHT,
+ .current_pixel_format = PIXEL_FORMAT_YUV422I,
+};
+
+int fake_register(void)
+{
+ unsigned int i;
+ unsigned char *name = "fake ";
+ struct fake_sensor_info *fake_info_tmp;
+
+ for ( i = 0; i < MAX_SENSOR_NUM; i++){
+ name[4] = i + '0';
+ fake_info_tmp = (struct fake_sensor_info *)kmalloc(sizeof(struct fake_sensor_info), GFP_KERNEL);
+ memcpy(fake_info_tmp, &fake_sensor, sizeof(struct fake_sensor_info));
+ memcpy(fake_info_tmp->fake_sensor_desc.name, name, 15);
+ if (i == 0)
+ current_fake_sensor = fake_info_tmp;
+ camera_sensor_register(&(fake_info_tmp->fake_sensor_desc));
+ }
+
+ return 0;
+}
+
+module_init(fake_register);
diff --git a/drivers/misc/jz_cim/camera_source/fake/fake_camera.h b/drivers/misc/jz_cim/camera_source/fake/fake_camera.h
new file mode 100644
index 00000000000..a50d4ba2d69
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/fake/fake_camera.h
@@ -0,0 +1,62 @@
+/*
+ * linux/drivers/misc/camera_source/ov3640/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET--------------------
+
+#define CAM_CLOCK 24000000
+
+// MAX SIZE---------------------
+#define MAX_CAP_WIDTH 2048
+#define MAX_CAP_HEIGHT 1536
+
+#define MAX_PRE_WIDTH 1024
+#define MAX_PRE_HEIGHT 768
+
+#define MAX_CAP_BPP 16
+#define MAX_PRE_BPP 16
+
+// DEFAULT SIZE-----------------
+#define DEF_CAP_WIDTH 640
+#define DEF_CAP_HEIGHT 480
+
+#define DEF_PRE_WIDTH 640
+#define DEF_PRE_HEIGHT 480
+
+#define DEF_CAP_BPP 16
+#define DEF_PRE_BPP 16
+
+
+// DATA SAMPLE------------------
+
+#define CAM_DATA_PACK_MODE 4
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 1
+#define CAM_DATA_INV 0
+
+//UNIT-----------------------------------------
+#define UNIT_WIDTH 160
+#define UNIT_HEIGHT 120
+
+#define MAX_SENSOR_NUM 1
+
+#define COLOR_NUM 3
diff --git a/drivers/misc/jz_cim/camera_source/isp/Makefile b/drivers/misc/jz_cim/camera_source/isp/Makefile
new file mode 100644
index 00000000000..524f9977c10
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_ISP) += isp_camera.o isp.o
+
diff --git a/drivers/misc/jz_cim/camera_source/isp/camera_ifc.h b/drivers/misc/jz_cim/camera_source/isp/camera_ifc.h
new file mode 100644
index 00000000000..9bb05fe23ea
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/camera_ifc.h
@@ -0,0 +1,449 @@
+#ifndef CAMERA_IFC_H
+#define CAMERA_IFC_H
+
+
+#define FEATURE_CAMERA_V7
+#define FEATURE_NATIVELINUX
+#define FEATURE_CAMERA_ENCODE_PROPERTIES
+
+typedef enum {
+ QDSP_MODULE_KERNEL,
+ QDSP_MODULE_AFETASK,
+ QDSP_MODULE_AUDPLAY0TASK,
+ QDSP_MODULE_AUDPLAY1TASK,
+ QDSP_MODULE_AUDPPTASK,
+ QDSP_MODULE_VIDEOTASK,
+ QDSP_MODULE_VIDEO_AAC_VOC,
+ QDSP_MODULE_PCM_DEC,
+ QDSP_MODULE_AUDIO_DEC_MP3,
+ QDSP_MODULE_AUDIO_DEC_AAC,
+ QDSP_MODULE_AUDIO_DEC_WMA,
+ QDSP_MODULE_HOSTPCM,
+ QDSP_MODULE_DTMF,
+ QDSP_MODULE_AUDRECTASK,
+ QDSP_MODULE_AUDPREPROCTASK,
+ QDSP_MODULE_SBC_ENC,
+ QDSP_MODULE_VOC,
+ QDSP_MODULE_VOC_PCM,
+ QDSP_MODULE_VOCENCTASK,
+ QDSP_MODULE_VOCDECTASK,
+ QDSP_MODULE_VOICEPROCTASK,
+ QDSP_MODULE_VIDEOENCTASK,
+ QDSP_MODULE_VFETASK,
+ QDSP_MODULE_WAV_ENC,
+ QDSP_MODULE_AACLC_ENC,
+ QDSP_MODULE_VIDEO_AMR,
+ QDSP_MODULE_VOC_AMR,
+ QDSP_MODULE_VOC_EVRC,
+ QDSP_MODULE_VOC_13K,
+ QDSP_MODULE_VOC_FGV,
+ QDSP_MODULE_DIAGTASK,
+ QDSP_MODULE_JPEGTASK,
+ QDSP_MODULE_LPMTASK,
+ QDSP_MODULE_QCAMTASK,
+ QDSP_MODULE_MODMATHTASK,
+ QDSP_MODULE_AUDPLAY2TASK,
+ QDSP_MODULE_AUDPLAY3TASK,
+ QDSP_MODULE_AUDPLAY4TASK,
+ QDSP_MODULE_GRAPHICSTASK,
+ QDSP_MODULE_MIDI,
+ QDSP_MODULE_GAUDIO,
+ QDSP_MODULE_VDEC_LP_MODE,
+ QDSP_MODULE_JPEG,
+ QDSP_MODULE_MAX,
+
+ /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
+ QDSP_MODULE_32BIT_DUMMY = 0x10000
+} qdsp_module_type;
+
+typedef enum
+{
+ CAMERA_SUCCESS = 0,
+ CAMERA_INVALID_STATE,
+ CAMERA_INVALID_PARM,
+ CAMERA_INVALID_FORMAT,
+ CAMERA_NO_SENSOR,
+ CAMERA_NO_MEMORY,
+ CAMERA_NOT_SUPPORTED,
+ CAMERA_FAILED,
+ CAMERA_INVALID_STAND_ALONE_FORMAT,
+ CAMERA_MALLOC_FAILED_STAND_ALONE,
+ CAMERA_RET_CODE_MAX
+} camera_ret_code_type;
+
+typedef enum
+{
+ /* YCbCr, each pixel is two bytes. Two pixels form a unit.
+ * MSB is Y, LSB is CB for the first pixel and CR for the second pixel. */
+ CAMERA_YCBCR,
+#ifdef FEATURE_CAMERA_V7
+ CAMERA_YCBCR_4_2_0,
+ CAMERA_YCBCR_4_2_2,
+ CAMERA_H1V1,
+ CAMERA_H2V1,
+ CAMERA_H1V2,
+ CAMERA_H2V2,
+ CAMERA_BAYER_8BIT,
+ CAMERA_BAYER_10BIT,
+#endif /* FEATURE_CAMERA_V7 */
+ /* RGB565, each pixel is two bytes.
+ * MS 5-bit is red, the next 6-bit is green. LS 5-bit is blue. */
+ CAMERA_RGB565,
+ /* RGB666, each pixel is four bytes.
+ * MS 14 bits are zeros, the next 6-bit is red, then 6-bit of green.
+ * LS 5-bit is blue. */
+ CAMERA_RGB666,
+ /* RGB444, each pixel is 2 bytes. The MS 4 bits are zeros, the next
+ * 4 bits are red, the next 4 bits are green. The LS 4 bits are blue. */
+ CAMERA_RGB444,
+ /* Bayer, each pixel is 1 bytes. 2x2 pixels form a unit.
+ * First line: first byte is blue, second byte is green.
+ * Second line: first byte is green, second byte is red. */
+ CAMERA_BAYER_BGGR,
+ /* Bayer, each pixel is 1 bytes. 2x2 pixels form a unit.
+ * First line: first byte is green, second byte is blue.
+ * Second line: first byte is red, second byte is green. */
+ CAMERA_BAYER_GBRG,
+ /* Bayer, each pixel is 1 bytes. 2x2 pixels form a unit.
+ * First line: first byte is green, second byte is red.
+ * Second line: first byte is blue, second byte is green. */
+ CAMERA_BAYER_GRBG,
+ /* Bayer, each pixel is 1 bytes. 2x2 pixels form a unit.
+ * First line: first byte is red, second byte is green.
+ * Second line: first byte is green, second byte is blue. */
+ CAMERA_BAYER_RGGB,
+ /* RGB888, each pixel is 3 bytes. R is 8 bits, G is 8 bits,
+ * B is 8 bits*/
+ CAMERA_RGB888
+} camera_format_type;
+
+typedef struct
+{
+ /* Format of the frame */
+ camera_format_type format;
+
+ /* For pre-V7, Width and height of the picture.
+ * For V7:
+ * Snapshot: thumbnail dimension
+ * Raw Snapshot: not applicable
+ * Preview: not applicable
+ */
+ uint16_t dx;
+ uint16_t dy;
+ /* For pre_V7: For BAYER format, RAW data before scaling.
+ * For V7:
+ * Snapshot: Main image dimension
+ * Raw snapshot: raw image dimension
+ * Preview: preview image dimension
+ */
+ uint16_t captured_dx;
+ uint16_t captured_dy;
+ /* it indicates the degree of clockwise rotation that should be
+ * applied to obtain the exact view of the captured image. */
+ uint16_t rotation;
+
+#ifdef FEATURE_CAMERA_V7
+ /* Preview: not applicable
+ * Raw shapshot: not applicable
+ * Snapshot: thumbnail image buffer
+ */
+ uint8_t *thumbnail_image;
+#endif /* FEATURE_CAMERA_V7 */
+
+ /* For pre-V7:
+ * Image buffer ptr
+ * For V7:
+ * Preview: preview image buffer ptr
+ * Raw snapshot: Raw image buffer ptr
+ * Shapshot: Main image buffer ptr
+ */
+ uint8_t *buffer;
+
+#ifdef FEATURE_NATIVELINUX
+ uint8_t *Y_Addr;
+ uint8_t *CbCr_Addr;
+ uint32_t *buf_Virt_Addr;
+ uint32_t header_size;
+
+ /*
+ * For JPEG encoding
+ */
+ uint32_t buffer_phy_addr;
+ uint32_t thumbnail_phy_addr;
+
+ uint32_t pmem_id;
+#endif
+} camera_frame_type;
+
+typedef enum
+{
+ CAMERA_DEVICE_MEM,
+ CAMERA_DEVICE_EFS,
+ CAMERA_DEVICE_MAX
+} camera_device_type;
+
+typedef enum
+{
+ CAMERA_RAW,
+ CAMERA_JPEG,
+ CAMERA_PNG,
+ CAMERA_YCBCR_ENCODE,
+ CAMERA_ENCODE_TYPE_MAX
+} camera_encode_type;
+
+typedef struct {
+ uint32_t buf_len;/* Length of each buffer */
+ uint32_t used_len;
+ uint8_t *buffer;
+} camera_encode_mem_type;
+
+#define MAX_JPEG_ENCODE_BUF_NUM 1
+#define MAX_JPEG_ENCODE_BUF_LEN (1024*16)
+
+typedef struct {
+ camera_device_type device;
+#ifndef FEATURE_CAMERA_ENCODE_PROPERTIES
+ int32_t quality;
+ camera_encode_type format;
+#endif /* nFEATURE_CAMERA_ENCODE_PROPERTIES */
+ int32_t encBuf_num;
+ camera_encode_mem_type encBuf[MAX_JPEG_ENCODE_BUF_NUM];
+} camera_handle_mem_type;
+
+typedef union
+{
+ camera_device_type device;
+ camera_handle_mem_type mem;
+} camera_handle_type;
+
+typedef enum
+{
+ CAMERA_RSP_CB_SUCCESS, /* Function is accepted */
+ CAMERA_EXIT_CB_DONE, /* Function is executed */
+ CAMERA_EXIT_CB_FAILED, /* Execution failed or rejected */
+ CAMERA_EXIT_CB_DSP_IDLE, /* DSP is in idle state */
+ CAMERA_EXIT_CB_DSP_ABORT, /* Abort due to DSP failure */
+ CAMERA_EXIT_CB_ABORT, /* Function aborted */
+ CAMERA_EXIT_CB_ERROR, /* Failed due to resource */
+ CAMERA_EVT_CB_FRAME, /* Preview or video frame ready */
+ CAMERA_EVT_CB_PICTURE, /* Picture frame ready for multi-shot */
+ CAMERA_STATUS_CB, /* Status updated */
+ CAMERA_EXIT_CB_FILE_SIZE_EXCEEDED, /* Specified file size not achieved,
+ encoded file written & returned anyway */
+ CAMERA_EXIT_CB_BUFFER, /* A buffer is returned */
+ CAMERA_EVT_CB_SNAPSHOT_DONE,/* Snapshot updated */
+ CAMERA_CB_MAX
+} camera_cb_type;
+
+typedef enum
+{
+ CAMERA_FUNC_START,
+ CAMERA_FUNC_STOP,
+ CAMERA_FUNC_SET_DIMENSIONS,
+ CAMERA_FUNC_START_PREVIEW,
+ CAMERA_FUNC_TAKE_PICTURE,
+ CAMERA_FUNC_ENCODE_PICTURE,
+ CAMERA_FUNC_COLOR_CONVERT,
+ CAMERA_FUNC_START_RECORD,
+ CAMERA_FUNC_START_FOCUS,
+ CAMERA_FUNC_SET_OVERLAY,
+ CAMERA_FUNC_CLR_OVERLAY,
+ CAMERA_FUNC_SET_ICON_ARRAY,
+ CAMERA_FUNC_CLR_ICON_ARRAY,
+ CAMERA_FUNC_SET_POSITION,
+ CAMERA_FUNC_SET_EXIF_TAG,
+ CAMERA_FUNC_SET_PARM,
+#ifdef FEATURE_QVPHONE
+ CAMERA_FUNC_ENABLE_QVP,
+ CAMERA_FUNC_DISABLE_QVP,
+ CAMERA_FUNC_START_QVP_ENCODE,
+ CAMERA_FUNC_STOP_QVP_ENCODE,
+ CAMERA_FUNC_QVP_RESET,
+#endif /* FEATURE_QVPHONE */
+ CAMERA_FUNC_RELEASE_ENCODE_BUFFER,
+ CAMERA_FUNC_MAX,
+
+ /*==========================================================================
+ * The followings are for internal use only
+ ==========================================================================*/
+#ifdef FEATURE_CAMERA_MULTI_SENSOR
+ CAMERA_FUNC_SELECT_SENSOR,
+#endif /* FEATURE_CAMERA_MULTI_SENSOR */
+ CAMERA_FUNC_STOP_PREVIEW,
+ CAMERA_FUNC_RELEASE_PICTURE,
+ CAMERA_FUNC_PAUSE_RECORD,
+ CAMERA_FUNC_RESUME_RECORD,
+ CAMERA_FUNC_STOP_RECORD,
+ CAMERA_FUNC_STOP_FOCUS,
+ CAMERA_FUNC_ENABLE_FRAME_CALLBACK,
+ CAMERA_FUNC_DISABLE_FRAME_CALLBACK,
+ CAMERA_FUNC_RELEASE_FRAME,
+#ifdef FEATURE_VIDEO_ENCODE
+ CAMERA_FUNC_VIDEO_ENGINE_CB,
+ CAMERA_FUNC_VIDEO_HANDSHAKE,
+#endif /* FEATURE_VIDEO_ENCODE */
+ CAMERA_FUNC_BLT,
+ CAMERA_FUNC_GET_INFO,
+ CAMERA_FUNC_GET_PARM,
+ CAMERA_FUNC_SET_REFLECT,
+#ifdef FEATURE_CAMERA_V7
+ CAMERA_FUNC_INIT_RECORD,
+ CAMERA_FUNC_OFFLINE_SNAPSHOT,
+#endif /* FEATURE_CAMERA_V7 */
+ CAMERA_FUNC_TAKE_MULTIPLE_PICTURES,
+ CAMERA_FUNC_PRVW_HISTOGRAM,
+ CAMERA_FUNC_SET_ZOOM,
+ CAMERA_FUNC_MAX1,
+
+} camera_func_type;
+
+typedef void (*camera_cb_f_type)(camera_cb_type cb,
+ const void *client_data,
+ camera_func_type func,
+ int32_t parm4);
+
+typedef struct {
+ int32_t quality;
+ camera_encode_type format;
+ int32_t file_size;
+} camera_encode_properties_type;
+
+typedef enum
+{
+ CAMERA_PARM_STATE,
+ CAMERA_PARM_CONTRAST,
+ CAMERA_PARM_BRIGHTNESS,
+ CAMERA_PARM_HUE,
+ CAMERA_PARM_SATURATION,
+ CAMERA_PARM_WB,
+ CAMERA_PARM_EFFECT,
+ //CAMERA_PARM_FOCUS_USER,
+ CAMERA_PARM_AF_MODE,
+ CAMERA_PARM_FACETRACKING,
+} camera_parm_type;
+
+typedef struct
+{
+ uint32_t timestamp; /* seconds since 1/6/1980 */
+ double latitude; /* degrees, WGS ellipsoid */
+ double longitude; /* degrees */
+ int16_t altitude; /* meters */
+} camera_position_type;
+
+typedef enum
+{
+ CAMERA_AUTO_FOCUS,
+ CAMERA_MANUAL_FOCUS
+} camera_focus_e_type;
+
+typedef enum
+{
+ JPEGENC_DSP_FAIL,
+ JPEGENC_DSP_SUCCESS,
+ JPEGENC_DSP_BAD_CMD,
+ JPEGENC_IMG_DONE,
+ JPEGENC_IMG_ABORT,
+ JPEGENC_IMG_FAIL,
+ JPEGENC_FILE_SIZE_FAIL,
+ JPEGENC_FILLED_BUFFER
+} JPEGENC_msgType;
+
+typedef enum
+{
+#ifdef FEATURE_EFS
+ JPEGENC_EFS,
+#endif /* FEATURE_EFS */
+ JPEGENC_MEM
+} JPEGENC_outputType;
+
+typedef struct
+{
+ int32_t clientId;
+ /* Client ID */
+ JPEGENC_msgType status;
+ uint32_t dcBitCnt;
+ /* bit count for DC, used by filesize control */
+ uint32_t header_size;
+ /* Actual size of JPEG header */
+ JPEGENC_outputType mode;
+ /*camera_encode_mem_type*/ void *outPtr;
+ /* These two are valid only when */
+ uint32_t size;
+ /* output mode is JPEGENC_MEM */
+} JPEGENC_CBrtnType;
+
+/* White balancing type, used for CAMERA_PARM_WHITE_BALANCING */
+typedef enum
+{
+ CAMERA_WB_MIN_MINUS_1,
+ CAMERA_WB_AUTO = 1, /* This list must match aeecamera.h */
+ CAMERA_WB_CUSTOM,
+ CAMERA_WB_INCANDESCENT,
+ CAMERA_WB_FLUORESCENT,
+ CAMERA_WB_DAYLIGHT,
+ CAMERA_WB_CLOUDY_DAYLIGHT,
+ CAMERA_WB_TWILIGHT,
+ CAMERA_WB_SHADE,
+ CAMERA_WB_MAX_PLUS_1
+} camera_wb_type;
+
+
+/* Effect type, used for CAMERA_PARM_EFFECT */
+typedef enum
+{
+ CAMERA_EFFECT_MIN_MINUS_1,
+ CAMERA_EFFECT_OFF = 1, /* This list must match aeecamera.h */
+ CAMERA_EFFECT_MONO,
+ CAMERA_EFFECT_NEGATIVE,
+ CAMERA_EFFECT_SOLARIZE,
+ CAMERA_EFFECT_PASTEL,
+ CAMERA_EFFECT_MOSAIC,
+ CAMERA_EFFECT_RESIZE,
+ CAMERA_EFFECT_SEPIA,
+ CAMERA_EFFECT_POSTERIZE,
+ CAMERA_EFFECT_WHITEBOARD,
+ CAMERA_EFFECT_BLACKBOARD,
+ CAMERA_EFFECT_AQUA,
+ CAMERA_EFFECT_MAX_PLUS_1
+} camera_effect_type;
+
+typedef enum
+{
+ CAMERA_ANTIBANDING_OFF,
+ CAMERA_ANTIBANDING_60HZ,
+ CAMERA_ANTIBANDING_50HZ,
+ CAMERA_ANTIBANDING_AUTO,
+ CAMERA_MAX_ANTIBANDING,
+} camera_antibanding_type;
+
+typedef enum
+{
+ CAMERA_PREVIEW_MODE_SNAPSHOT,
+ CAMERA_PREVIEW_MODE_MOVIE,
+ CAMERA_MAX_PREVIEW_MODE
+} camera_preview_mode_type;
+
+
+typedef enum
+{
+ CAMERA_ERROR_NO_MEMORY,
+ CAMERA_ERROR_EFS_FAIL, /* Low-level operation failed */
+ CAMERA_ERROR_EFS_FILE_OPEN, /* File already opened */
+ CAMERA_ERROR_EFS_FILE_NOT_OPEN, /* File not opened */
+ CAMERA_ERROR_EFS_FILE_ALREADY_EXISTS, /* File already exists */
+ CAMERA_ERROR_EFS_NONEXISTENT_DIR, /* User directory doesn't exist */
+ CAMERA_ERROR_EFS_NONEXISTENT_FILE, /* User directory doesn't exist */
+ CAMERA_ERROR_EFS_BAD_FILE_NAME, /* Client specified invalid file/directory name*/
+ CAMERA_ERROR_EFS_BAD_FILE_HANDLE, /* Client specified invalid file/directory name*/
+ CAMERA_ERROR_EFS_SPACE_EXHAUSTED, /* Out of file system space */
+ CAMERA_ERROR_EFS_OPEN_TABLE_FULL, /* Out of open-file table slots */
+ CAMERA_ERROR_EFS_OTHER_ERROR, /* Other error */
+ CAMERA_ERROR_CONFIG,
+ CAMERA_ERROR_EXIF_ENCODE,
+ CAMERA_ERROR_VIDEO_ENGINE,
+ CAMERA_ERROR_IPL,
+ CAMERA_ERROR_INVALID_FORMAT,
+ CAMERA_ERROR_MAX
+} camera_error_type;
+
+#endif//CAMERA_IFC_H
diff --git a/drivers/misc/jz_cim/camera_source/isp/data.h b/drivers/misc/jz_cim/camera_source/isp/data.h
new file mode 100644
index 00000000000..fe9f1080862
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/data.h
@@ -0,0 +1,2887 @@
+char ISP3BinaryDataMcu[]={
+0x02,0x8b,0x03,0x02,0x8e,0x43,0x02,0x97,0x08,0x22,0x22,0x02,0x92,0x39,0xe4,0x90,
+0x03,0xe0,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x05,0x50,0xe0,0xff,0xa3,0xe0,
+0x90,0x04,0xc9,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0x52,0xe0,0xff,0xa3,0xe0,0x90,
+0x04,0x99,0xcf,0xf0,0xa3,0xef,0xf0,0x7f,0x03,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0xaf,0xef,0xf0,0x7f,0x04,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0xb0,0xef,0xf0,0x90,
+0x04,0x9d,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x05,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0xb1,0xef,0xf0,0x90,0x04,0x9f,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x06,0x7e,0xec,0x12,
+0x96,0x64,0x90,0x04,0xb2,0xef,0xf0,0x90,0x04,0xa1,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,
+0x07,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0xb3,0xef,0xf0,0x90,0x04,0xa3,0xe4,0xf0,
+0xa3,0xef,0xf0,0x7f,0x08,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0xb4,0xef,0xf0,0x90,
+0x04,0xa5,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x09,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0xb5,0xef,0xf0,0x90,0x04,0xa7,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x0a,0x7e,0xec,0x12,
+0x96,0x64,0x90,0x04,0xb6,0xef,0xf0,0x90,0x04,0xa9,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,
+0x0b,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0xb7,0xef,0xf0,0x90,0x04,0xab,0xe4,0xf0,
+0xa3,0xef,0xf0,0x7f,0x0c,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0xb8,0xef,0xf0,0x90,
+0x04,0xad,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x13,0x7e,0xe6,0x12,0x96,0x64,0x90,0x04,
+0x7a,0xe0,0xfd,0x33,0x95,0xe0,0xfc,0xef,0x2d,0xfe,0xe4,0x3c,0x90,0x04,0x87,0xf0,
+0xa3,0xce,0xf0,0x90,0x03,0xdf,0x74,0x05,0xf0,0x90,0x03,0xdf,0xe0,0xff,0x24,0x7c,
+0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0xfe,0x74,0x7d,0x2f,0xf5,0x82,0xe4,0x34,
+0x04,0xf5,0x83,0xee,0xf0,0x90,0x03,0xdf,0xe0,0x14,0xf0,0xe0,0x70,0xdb,0x90,0x03,
+0xdf,0x74,0x03,0xf0,0x90,0x03,0xdf,0xe0,0xff,0x25,0xe0,0x24,0xe2,0xf5,0x82,0xe4,
+0x34,0x04,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x25,0xe0,0x24,0xe4,0xf5,0x82,
+0xe4,0x34,0x04,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xdf,0xe0,0x14,0xf0,
+0xe0,0x70,0xd1,0x12,0x79,0xd6,0x90,0x04,0x97,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x6b,
+0xd7,0x90,0x04,0xc6,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0xe4,0xee,0xf0,0xa3,0xef,
+0xf0,0x90,0x04,0xe7,0xe0,0x2f,0xff,0x90,0x04,0xe6,0xe0,0x3e,0xfe,0x90,0x04,0xe9,
+0xe0,0x2f,0xff,0x90,0x04,0xe8,0xe0,0x3e,0xfe,0x7c,0x00,0x7d,0x03,0x12,0x1c,0x62,
+0x90,0x04,0xc6,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x60,0x35,0x90,0x03,0xe0,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0xb9,0xe0,0xff,0x7e,0x00,0x90,0x04,0xcb,0xee,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0x95,0xe0,0x70,0x03,0xa3,0xe0,0x6f,0x60,0x03,0x12,0x86,0x14,
+0x90,0x04,0xcb,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x95,0xcf,0xf0,0xa3,0xef,0xf0,0x90,
+0x04,0x6f,0xe0,0x14,0x60,0x31,0x14,0x60,0x33,0x14,0x70,0x38,0x90,0x05,0x02,0xe0,
+0x60,0x1f,0x30,0x03,0x1c,0x90,0x04,0xb5,0xe0,0xff,0x90,0x03,0xe1,0xe0,0x2f,0xff,
+0x90,0x03,0xe0,0xe0,0x34,0x00,0xc3,0x13,0xfe,0xef,0x13,0xff,0xee,0xf0,0xa3,0xef,
+0xf0,0x90,0x03,0xe0,0xa3,0x80,0x08,0x90,0x04,0xaf,0x80,0x03,0x90,0x04,0xb0,0xe0,
+0x90,0x04,0x7d,0xf0,0xe4,0x90,0x03,0xdf,0xf0,0x90,0x03,0xdf,0xe0,0xff,0x24,0xba,
+0xf5,0x82,0xe4,0x34,0x04,0xf5,0x83,0xe0,0xfd,0x74,0x7d,0x2f,0xf5,0x82,0xe4,0x34,
+0x04,0xf5,0x83,0xe0,0x8d,0xf0,0xa4,0xff,0xae,0xf0,0x90,0x04,0x8a,0xe0,0x2f,0xf0,
+0x90,0x04,0x89,0xe0,0x3e,0xf0,0xed,0xff,0x90,0x03,0xe3,0xe0,0x2f,0xf0,0x90,0x03,
+0xe2,0xe0,0x34,0x00,0xf0,0x90,0x03,0xdf,0xe0,0x04,0xf0,0xe0,0xb4,0x06,0xba,0x90,
+0x04,0x89,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xe2,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,
+0x1c,0x62,0x90,0x04,0x89,0xee,0xf0,0xa3,0xef,0xf0,0xc3,0x94,0x01,0xee,0x94,0x00,
+0x50,0x08,0x90,0x04,0x89,0xe4,0xf0,0xa3,0x04,0xf0,0xd3,0x90,0x04,0xc5,0xe0,0x94,
+0x00,0x90,0x04,0xc4,0xe0,0x94,0x00,0x40,0x0d,0xa3,0xe0,0x24,0xff,0xf0,0x90,0x04,
+0xc4,0xe0,0x34,0xff,0xf0,0x22,0x90,0x04,0x70,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,
+0x04,0x9a,0xe0,0x9f,0x90,0x04,0x99,0xe0,0x9e,0x40,0x05,0xd2,0x0a,0x02,0x03,0x65,
+0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0x79,
+0xc0,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,
+0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,
+0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x60,0x02,0x50,
+0x3e,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xe4,0xfb,0xfa,
+0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,
+0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,
+0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x50,0x04,0xc2,
+0x0a,0x80,0x02,0xd2,0x0a,0xe4,0x90,0x04,0xd7,0xf0,0x90,0x04,0xc9,0xe0,0xfe,0xa3,
+0xe0,0xff,0xc3,0x94,0x05,0xee,0x94,0x00,0x50,0x0b,0x90,0x03,0xe4,0xe4,0xf0,0xa3,
+0x74,0x0a,0xf0,0x80,0x13,0x90,0x03,0xe4,0xe4,0x30,0x09,0x07,0xf0,0xa3,0x74,0x05,
+0xf0,0x80,0x05,0xf0,0xa3,0x74,0x14,0xf0,0x90,0x04,0xda,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xd3,0xef,0x9d,0xee,0x9c,0x40,0x06,0x30,0x09,0x03,0x02,0x06,0x4a,0x30,0x09,0x0f,
+0x90,0x04,0x6d,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x99,0xcf,0xf0,0xa3,0xef,0xf0,0x90,
+0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,
+0x06,0xc0,0x07,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,
+0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,
+0x19,0x41,0x74,0x33,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x19,0xde,0x60,0x2a,0x40,0x28,
+0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,
+0xc0,0x01,0xc0,0x02,0xc0,0x03,0x7f,0x9a,0x7e,0x99,0x7d,0x19,0x7c,0x3e,0x90,0x04,
+0x8b,0xa3,0xa3,0xa3,0xe0,0x02,0x05,0x5a,0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x87,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,
+0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x7b,0x66,0x7a,0x66,0x79,
+0xa6,0x78,0x3f,0x12,0x19,0xde,0x50,0x45,0x90,0x04,0x8b,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x7f,0x9a,
+0x7e,0x99,0x7d,0x19,0x7c,0x3e,0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,
+0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x17,0x43,0x02,0x05,0x68,0x90,0x03,0xe4,
+0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x04,0x88,0xe0,0x9f,0xff,0x90,0x04,0x87,0xe0,
+0x9e,0xfe,0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,0x40,0x1e,
+0x90,0x03,0xe4,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x88,0xe0,0x2f,0xff,0x90,0x04,
+0x87,0xe0,0x3e,0xfe,0xd3,0xed,0x9f,0xec,0x9e,0x50,0x03,0x02,0x05,0xa6,0x90,0x04,
+0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,0xc0,0x01,
+0xc0,0x02,0xc0,0x03,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,
+0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0xe4,0xfb,0xfa,0x79,0x80,0x78,0xbf,0x12,0x17,
+0x47,0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,
+0x18,0x38,0x7b,0xcd,0x7a,0xcc,0x79,0x4c,0x78,0x3d,0x12,0x18,0x38,0xd0,0x03,0xd0,
+0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x90,0x04,0x8b,0x12,0x1f,0xa6,0x90,0x04,
+0x72,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,
+0xab,0x07,0x90,0x04,0x8b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,
+0x12,0x19,0x41,0x12,0x1a,0x9a,0x90,0x04,0x76,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,
+0xc9,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0xda,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,
+0x04,0xca,0xe0,0x9f,0x90,0x04,0xc9,0xe0,0x9e,0x40,0x3b,0xef,0x24,0x01,0xff,0xe4,
+0x3e,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x72,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,
+0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0xc9,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,
+0x90,0x04,0x8b,0x12,0x1f,0xa6,0xd3,0x90,0x04,0xca,0xe0,0x94,0x01,0x90,0x04,0xc9,
+0xe0,0x94,0x00,0x50,0x05,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x04,0x72,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x50,0x18,0x90,0x04,0x73,0xe0,0x24,0x01,0xfd,
+0x90,0x04,0x72,0xe0,0x34,0x00,0xfc,0xe4,0x12,0x1a,0x61,0x90,0x04,0x8b,0x12,0x1f,
+0xa6,0x90,0x04,0xd7,0x74,0x01,0xf0,0x02,0x0d,0x1c,0x90,0x05,0x47,0xe0,0xf9,0xb4,
+0xd0,0x3e,0x90,0x04,0xdb,0xe0,0x24,0x01,0xff,0x90,0x04,0xda,0xe0,0x34,0x00,0xfe,
+0xc3,0x90,0x04,0xca,0xe0,0x9f,0x90,0x04,0xc9,0xe0,0x9e,0x40,0x23,0x90,0x04,0x99,
+0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x04,0x6e,0xe0,0x9f,0x90,0x04,0x6d,0xe0,0x9e,
+0x50,0x0e,0x90,0x04,0x70,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x9d,0xee,0x9c,0x40,0x08,
+0xe9,0x64,0xd0,0x70,0x03,0x02,0x0a,0x8b,0x90,0x04,0xdb,0xe0,0x24,0x01,0xfe,0x90,
+0x04,0xda,0xe0,0x34,0x00,0x90,0x04,0xc9,0xf0,0xa3,0xce,0xf0,0x90,0x04,0x72,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,
+0x90,0x04,0xc9,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,0x90,0x04,0x8b,0x12,0x1f,0xa6,0x90,0x04,0x89,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,
+0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,
+0x74,0x33,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x19,0xde,0x60,0x18,0x40,0x16,0x90,0x04,
+0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x7b,0xcd,0x7a,0xcc,0x79,0x4c,
+0x78,0xbe,0x80,0x54,0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,
+0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x7b,0x66,0x7a,0x66,0x79,0xa6,0x78,0x3f,0x12,
+0x19,0xde,0x50,0x20,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0x7b,0xcd,0x7a,0xcc,0x79,0x4c,0x78,0x3e,0x12,0x18,0x38,0x90,0x04,0xc0,0x12,0x1f,
+0xa6,0x02,0x09,0x85,0x90,0x04,0x87,0xe0,0xfe,0xa3,0xe0,0xff,0x24,0xfd,0xfd,0xee,
+0x34,0xff,0xfc,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x9d,0xea,0x9c,0x40,0x11,0xef,
+0x24,0x03,0xff,0xe4,0x3e,0xfe,0xd3,0xeb,0x9f,0xea,0x9e,0x50,0x03,0x02,0x08,0x60,
+0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,
+0xc0,0x06,0xc0,0x07,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,
+0x12,0x19,0x41,0xe4,0xfb,0xfa,0x79,0x80,0x78,0xbf,0x12,0x17,0x47,0x7b,0xcd,0x7a,
+0xcc,0x79,0x4c,0x78,0x3d,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,
+0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,0x90,0x04,0xc0,0x12,0x1f,0xa6,0x90,0x04,0xc0,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0xfb,0xfa,0xf9,0xf8,
+0x12,0x19,0xde,0x50,0x21,0x7f,0x9a,0x7e,0x99,0x7d,0x99,0x7c,0x3e,0x90,0x04,0xc0,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x50,0x06,
+0x90,0x04,0xc0,0x02,0x09,0x7e,0x90,0x04,0xc0,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,
+0xfe,0xa3,0xe0,0xff,0x7b,0x9a,0x7a,0x99,0x79,0x99,0x78,0x3e,0x12,0x19,0xde,0x60,
+0x02,0x50,0x6e,0xe4,0xff,0xfe,0x7d,0x80,0x7c,0x3f,0x90,0x04,0xc0,0xe0,0xf8,0xa3,
+0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x50,0x54,0x90,0x04,0x69,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0xc0,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x17,0x47,0x90,0x04,0x69,0x12,
+0x1f,0xa6,0xe4,0xff,0xfe,0x7d,0x80,0x7c,0x3f,0x90,0x04,0x69,0xe0,0xf8,0xa3,0xe0,
+0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x60,0x02,0x50,0x03,0x02,0x09,
+0x85,0x90,0x04,0xc0,0x12,0x1f,0xb2,0x3f,0x80,0x00,0x00,0x90,0x04,0x69,0x02,0x09,
+0x7e,0x90,0x04,0xc0,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,
+0xfb,0xfa,0x79,0x80,0x78,0xbf,0x12,0x19,0xde,0x50,0x7a,0x7f,0x9a,0x7e,0x99,0x7d,
+0x99,0x7c,0xbe,0x90,0x04,0xc0,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xfb,0x12,0x19,0xde,0x60,0x02,0x50,0x5d,0x90,0x04,0x69,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0xc0,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xfb,0x12,0x17,0x47,0x90,0x04,0x69,0x12,0x1f,0xa6,0xe4,0xff,0xfe,
+0x7d,0x80,0x7c,0xbf,0x90,0x04,0x69,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xfb,0x12,0x19,0xde,0x50,0x1e,0x90,0x04,0x69,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0xc0,0x12,0x1f,0xa6,0x90,0x04,0x69,0x12,0x1f,
+0xb2,0x00,0x00,0x00,0x00,0x20,0x09,0x20,0x90,0x04,0xca,0xe0,0x24,0xff,0xf0,0x90,
+0x04,0xc9,0xe0,0x34,0xff,0xf0,0x90,0x04,0x99,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x99,
+0xcf,0xf0,0xa3,0xef,0xf0,0x02,0x0a,0x82,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0x90,0x04,0xc0,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xfb,0x12,0x17,0x43,0x12,0x1a,0x9a,0x90,0x04,0x99,0xee,0xf0,0xa3,0xef,0xf0,
+0x90,0x04,0x70,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,0x50,0x09,0xed,0x24,
+0x01,0xff,0xe4,0x3c,0xfe,0x80,0x08,0x90,0x04,0x99,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x04,0x99,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x6d,0xe0,0xfc,0xa3,0xe0,0xfd,0xd3,
+0x9f,0xec,0x9e,0x40,0x06,0xae,0x04,0xaf,0x05,0x80,0x08,0x90,0x04,0x99,0xe0,0xfe,
+0xa3,0xe0,0xff,0x90,0x04,0x99,0xee,0xf0,0xa3,0xef,0xf0,0xc3,0x90,0x04,0x6e,0xe0,
+0x9f,0x90,0x04,0x6d,0xe0,0x9e,0x40,0x5a,0xe4,0xff,0xfe,0xfd,0xfc,0x90,0x04,0xc0,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x60,0x42,
+0x40,0x40,0x90,0x04,0xda,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xc9,0xcf,0xf0,0xa3,0xef,
+0xf0,0x90,0x04,0x72,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,
+0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0xc9,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,
+0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,0x90,0x04,0x8b,0x12,
+0x1f,0xa6,0x90,0x04,0xd7,0x74,0x02,0xf0,0x02,0x0d,0x1c,0x90,0x04,0x71,0xe0,0x24,
+0x01,0xff,0x90,0x04,0x70,0xe0,0x34,0x00,0xfe,0xd3,0x90,0x04,0x9a,0xe0,0x9f,0x90,
+0x04,0x99,0xe0,0x9e,0x40,0x03,0x02,0x0c,0xf3,0x90,0x05,0x47,0xe0,0x64,0xd0,0x60,
+0x03,0x02,0x0c,0xf3,0x90,0x04,0x99,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x89,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,
+0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,
+0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x7b,
+0x9a,0x7a,0x99,0x79,0x99,0x78,0x3e,0x12,0x19,0xde,0x60,0x38,0x40,0x36,0x90,0x04,
+0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,0xc0,0x01,
+0xc0,0x02,0xc0,0x03,0x7f,0x9a,0x7e,0x99,0x7d,0x99,0x7c,0x3e,0x90,0x04,0x8b,0xa3,
+0xa3,0xa3,0xe0,0x12,0x18,0x38,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,
+0x47,0x02,0x0c,0x2e,0x90,0x04,0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x87,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,
+0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x7b,0x9a,0x7a,0x99,0x79,0xd9,0x78,0x3f,0x12,
+0x19,0xde,0x90,0x04,0x8b,0xe0,0x50,0x40,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,
+0xe0,0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x7f,0x9a,0x7e,0x99,0x7d,0x99,
+0x7c,0x3e,0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,
+0x12,0x18,0x38,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,
+0x05,0xd0,0x04,0x12,0x17,0x43,0x80,0x76,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0x90,0x04,0x87,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,
+0x89,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,
+0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0xe4,0xfb,0xfa,
+0x79,0x80,0x78,0xbf,0x12,0x17,0x47,0x90,0x04,0x8b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x7b,0x9a,0x7a,0x99,0x79,0x99,0x78,0x3e,
+0x12,0x18,0x38,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x90,0x04,
+0x8b,0x12,0x1f,0xa6,0x90,0x04,0x72,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x04,0x8b,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,0x41,0x12,0x1a,0x9a,0x90,0x04,0x76,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0xc9,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0xe1,0xe0,
+0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x04,0xca,0xe0,0x9f,0x90,0x04,0xc9,0xe0,0x9e,0x40,
+0x08,0xef,0x24,0x01,0xff,0xe4,0x3e,0x80,0x2d,0x90,0x04,0xda,0xe0,0xfe,0xa3,0xe0,
+0xff,0xd3,0x90,0x04,0xca,0xe0,0x9f,0x90,0x04,0xc9,0xe0,0x9e,0x50,0x4d,0x90,0x04,
+0x70,0xe0,0xfd,0xa3,0xe0,0x90,0x04,0x99,0xcd,0xf0,0xa3,0xed,0xf0,0xef,0x24,0x01,
+0xff,0xe4,0x3e,0x90,0x04,0xc9,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x72,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,
+0xc9,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0x12,0x18,0x38,0x90,0x04,0x8b,0x12,0x1f,0xa6,0x90,0x04,0xd7,0x74,0x03,
+0xf0,0x80,0x29,0x90,0x04,0x70,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x99,0xcf,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0xdb,0xe0,0x24,0x01,0xfe,0x90,0x04,0xda,0xe0,0x34,0x00,0x90,
+0x04,0xc9,0xf0,0xa3,0xce,0xf0,0x90,0x04,0xd7,0x74,0x04,0xf0,0x90,0x04,0xc9,0xe0,
+0xfe,0xa3,0xe0,0xff,0x90,0x05,0x50,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x99,0xe0,
+0xfc,0xa3,0xe0,0xfd,0x90,0x05,0x52,0xec,0xf0,0xa3,0xed,0xf0,0x12,0x6e,0xf9,0x22,
+0x90,0x03,0xf6,0xe4,0xf0,0xa3,0x74,0x08,0xf0,0x90,0x04,0x0c,0x74,0xf3,0xf0,0xa3,
+0x74,0xf1,0xf0,0x7f,0x68,0x7e,0xed,0x12,0x96,0x64,0x90,0x03,0xe0,0xef,0xf0,0x90,
+0x03,0xe4,0xbf,0x04,0x19,0x12,0x1f,0xb2,0x40,0x4c,0xcc,0xcd,0x90,0x03,0xfe,0x74,
+0x04,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,0x03,0xf0,0xa3,0xe4,0xf0,0x80,0x18,0x12,0x1f,
+0xb2,0x40,0x80,0x00,0x00,0x90,0x03,0xfe,0x74,0x05,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,
+0x03,0xf0,0xa3,0x74,0xc0,0xf0,0xe4,0x90,0x03,0xdf,0xf0,0x90,0x03,0xdf,0xe0,0xff,
+0xc3,0x94,0x0a,0x50,0x18,0xef,0x25,0xe0,0x24,0x6d,0xf5,0x82,0xe4,0x34,0x02,0xf5,
+0x83,0xe4,0xf0,0xa3,0xf0,0x90,0x03,0xdf,0xe0,0x04,0xf0,0x80,0xde,0xe4,0x90,0x02,
+0x81,0xf0,0x7f,0x0a,0x7e,0xf2,0x12,0x96,0x64,0xef,0x54,0x03,0x90,0x03,0xe2,0xf0,
+0x7f,0x0b,0x7e,0xf2,0x12,0x96,0x64,0xef,0x90,0x03,0xe1,0xf0,0xa3,0xe0,0xfe,0x90,
+0x03,0xe1,0xe0,0xfd,0xed,0xff,0x12,0x8b,0x8f,0x7f,0x09,0x7e,0xf2,0x12,0x96,0x64,
+0x90,0x03,0xe0,0xef,0xf0,0x64,0x01,0x60,0x03,0x02,0x17,0x15,0x90,0x04,0xec,0xe0,
+0x70,0x04,0xa3,0xe0,0x64,0x01,0x60,0x03,0x02,0x17,0x15,0x7b,0x01,0x90,0x04,0x17,
+0x04,0xf0,0xa3,0x74,0x03,0xf0,0xa3,0x74,0xe2,0xf0,0x7a,0x03,0x79,0xe1,0x7d,0x01,
+0x7c,0x00,0xe4,0xff,0xfe,0x12,0x8a,0x94,0x7f,0x05,0x7e,0xf2,0x12,0x96,0x64,0x90,
+0x03,0xe3,0xef,0xf0,0x90,0x03,0x19,0xe0,0xfe,0xef,0xd3,0x9e,0x40,0x05,0x90,0x03,
+0xe3,0xee,0xf0,0xe4,0x90,0x03,0xdf,0xf0,0x90,0x03,0xe3,0xe0,0xff,0x90,0x03,0xdf,
+0xe0,0xf9,0xc3,0x9f,0x40,0x03,0x02,0x10,0x5e,0xe9,0x75,0xf0,0x04,0xa4,0xae,0xf0,
+0xfd,0xac,0x06,0x12,0x8a,0x7c,0x90,0x03,0xe2,0xe0,0xfe,0x90,0x03,0xe1,0xe0,0x7c,
+0x00,0x24,0x00,0xff,0xec,0x3e,0x90,0x03,0xe8,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe8,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,0xe4,0xe0,0xf8,0xa3,0xe0,
+0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x03,0xe8,
+0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xdf,0xe0,0x75,0xf0,0x04,0xa4,0x24,0x01,0x12,
+0x8a,0x75,0x90,0x03,0xe1,0xe0,0xff,0x90,0x03,0xea,0xe4,0xf0,0xa3,0xef,0xf0,0x90,
+0x03,0xea,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,0xe4,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,
+0x03,0xea,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xdf,0xe0,0x75,0xf0,0x04,0xa4,0x24,
+0x02,0x12,0x8a,0x75,0x90,0x03,0xe1,0xe0,0xff,0x90,0x03,0xec,0xe4,0xf0,0xa3,0xef,
+0xf0,0x90,0x03,0xec,0xe0,0xfc,0xa3,0xe0,0xfd,0x25,0xe0,0xfe,0xec,0x33,0xa3,0xf0,
+0xa3,0xce,0xf0,0xec,0x12,0x1a,0x61,0x90,0x03,0xe4,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x03,0xec,0xee,0xf0,
+0xa3,0xef,0xf0,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xe8,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xc3,0x9f,0xff,0xec,0x9e,0x90,0x03,0xf0,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xee,
+0xa3,0xe0,0xff,0x90,0x03,0xea,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x9f,0xff,0xea,0x9e,
+0x90,0x03,0xf2,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xee,0xa3,0xe0,0xff,0xed,0x2f,0xff,
+0xec,0x3e,0x90,0x03,0xf4,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xee,0xa3,0xe0,0xff,0xeb,
+0x2f,0xff,0xea,0x3e,0xfe,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x03,0xdf,0xe0,0xfb,
+0x75,0xf0,0x0a,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,
+0xed,0xf0,0x90,0x03,0xf2,0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,0x75,0xf0,0x0a,0xa4,0x24,
+0x0b,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xf4,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x0d,0xf5,0x82,0xe4,0x34,
+0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe8,0xe0,0xfe,
+0xa3,0xe0,0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x71,0xe2,0x90,0x03,0x0e,0xe0,
+0xff,0x90,0x03,0xdf,0xe0,0xfe,0x75,0xf0,0x0a,0xa4,0x24,0x11,0xf5,0x82,0xe4,0x34,
+0x02,0xf5,0x83,0xef,0xf0,0x90,0x03,0x07,0xe0,0xff,0xee,0x75,0xf0,0x0a,0xa4,0x24,
+0x12,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xef,0xf0,0x30,0x01,0x28,0xee,0xff,0x7e,
+0x00,0xc0,0x07,0x90,0x03,0xec,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x03,0xe8,0xe0,0xfa,
+0xa3,0xe0,0xfb,0xa3,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x14,0xcf,0xf0,0xa3,0xef,0xf0,
+0xd0,0x07,0x12,0x27,0x60,0x90,0x03,0xdf,0xe0,0x04,0xf0,0x02,0x0e,0x48,0x90,0x03,
+0xe3,0xe0,0xff,0xd3,0x94,0x00,0x50,0x03,0x02,0x12,0x72,0x30,0x01,0x05,0x7e,0x00,
+0x12,0x6d,0x6b,0x30,0x06,0x0a,0x90,0x03,0xe3,0xe0,0xff,0x7e,0x00,0x12,0x48,0xe6,
+0x20,0x00,0x03,0x02,0x12,0x72,0x7f,0x58,0x7e,0xed,0x12,0x96,0x64,0x90,0x03,0xe2,
+0xef,0xf0,0x7f,0x59,0x7e,0xed,0x12,0x96,0x64,0x90,0x03,0xe1,0xef,0xf0,0xa3,0xe0,
+0xfe,0x90,0x03,0xe1,0xe0,0xfd,0xed,0xff,0x90,0x03,0xf8,0xee,0xf0,0xa3,0xef,0xf0,
+0x7f,0x5a,0x7e,0xed,0x12,0x96,0x64,0x90,0x03,0xe2,0xef,0xf0,0x7f,0x5b,0x7e,0xed,
+0x12,0x96,0x64,0x90,0x03,0xe1,0xef,0xf0,0xa3,0xe0,0xfe,0x90,0x03,0xe1,0xe0,0xfd,
+0xed,0xfb,0xaa,0x06,0x90,0x02,0x09,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x02,0x0e,
+0xe0,0x9f,0xff,0x90,0x02,0x0d,0xe0,0x9e,0xfe,0x7c,0x00,0x7d,0x02,0x12,0x1c,0xb7,
+0x90,0x02,0x0a,0xe0,0x2f,0xff,0x90,0x02,0x09,0xe0,0x3e,0x90,0x03,0xe8,0xf0,0xa3,
+0xef,0xf0,0x90,0x02,0x0b,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x02,0x10,0xe0,0x9f,
+0xff,0x90,0x02,0x0f,0xe0,0x9e,0xfe,0x7c,0x00,0x7d,0x02,0x12,0x1c,0xb7,0x90,0x02,
+0x0c,0xe0,0x2f,0xff,0x90,0x02,0x0b,0xe0,0x3e,0x90,0x03,0xea,0xf0,0xa3,0xef,0xf0,
+0x90,0x03,0xf8,0xe0,0xfe,0xa3,0xe0,0xff,0x7c,0x00,0x7d,0x02,0x12,0x1c,0xb7,0xc3,
+0x90,0x03,0xe9,0xe0,0x9f,0xff,0x90,0x03,0xe8,0xe0,0x9e,0x90,0x04,0x02,0xf0,0xa3,
+0xef,0xf0,0x7c,0x00,0x7d,0x02,0xaf,0x03,0xae,0x02,0x12,0x1c,0xb7,0xc3,0x90,0x03,
+0xeb,0xe0,0x9f,0xff,0x90,0x03,0xea,0xe0,0x9e,0x90,0x04,0x04,0xf0,0xa3,0xef,0xf0,
+0x90,0x03,0xf8,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x03,0xe0,0x2f,0xff,0x90,0x04,
+0x02,0xe0,0x3e,0x90,0x04,0x06,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x04,0xe0,0xfc,0xa3,
+0xe0,0x2b,0xfe,0xec,0x3a,0x90,0x04,0x08,0xf0,0xa3,0xce,0xf0,0xc3,0x90,0x04,0x02,
+0xe0,0x64,0x80,0x94,0x80,0x50,0x13,0xe4,0xf0,0xa3,0xf0,0x90,0x03,0xf8,0xe0,0xff,
+0xa3,0xe0,0x90,0x04,0x06,0xcf,0xf0,0xa3,0xef,0xf0,0xc3,0xec,0x64,0x80,0x94,0x80,
+0x50,0x0f,0xe4,0x90,0x04,0x04,0xf0,0xa3,0xf0,0x90,0x04,0x08,0xea,0xf0,0xa3,0xeb,
+0xf0,0x90,0x03,0xfe,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x04,0x07,0xe0,0x9f,0xee,
+0x64,0x80,0xf8,0x90,0x04,0x06,0xe0,0x64,0x80,0x98,0x40,0x1c,0x90,0x04,0x06,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x03,0xf8,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x9d,0xff,0xee,
+0x9c,0x90,0x04,0x02,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x00,0xe0,0xfe,0xa3,0xe0,0xff,
+0xd3,0x90,0x04,0x09,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x04,0x08,0xe0,0x64,0x80,
+0x98,0x40,0x13,0x90,0x04,0x08,0xee,0xf0,0xa3,0xef,0xf0,0x9b,0xff,0xee,0x9a,0x90,
+0x04,0x04,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x02,0xe0,0xff,0x33,0x95,0xe0,0xad,0x07,
+0x7f,0x50,0x7e,0xed,0x12,0x96,0xbd,0x90,0x04,0x02,0xa3,0xe0,0xfd,0x7f,0x51,0x7e,
+0xed,0x12,0x96,0xbd,0x90,0x04,0x04,0xe0,0xff,0x33,0x95,0xe0,0xad,0x07,0x7f,0x52,
+0x7e,0xed,0x12,0x96,0xbd,0x90,0x04,0x04,0xa3,0xe0,0xfd,0x7f,0x53,0x7e,0xed,0x12,
+0x96,0xbd,0xe4,0x90,0x03,0xdf,0xf0,0x90,0x03,0xe3,0xe0,0xff,0x90,0x03,0xdf,0xe0,
+0xc3,0x9f,0x40,0x03,0x02,0x15,0xb1,0xe0,0xf9,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,
+0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0x90,0x04,0x0d,0xe0,0x2f,0xfb,0x90,0x04,0x0c,
+0xe0,0x3e,0xfa,0xe9,0x75,0xf0,0x0a,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0x02,0xf5,
+0x83,0xe0,0xff,0x33,0x95,0xe0,0xad,0x07,0xaf,0x03,0xae,0x02,0x12,0x96,0xbd,0x90,
+0x03,0xdf,0xe0,0xfb,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,
+0x1c,0x50,0x90,0x04,0x0d,0xe0,0x2f,0xff,0x90,0x04,0x0c,0xe0,0x3e,0xcf,0x24,0x01,
+0xcf,0x34,0x00,0xfe,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0x02,
+0xf5,0x83,0xa3,0xe0,0xfd,0x12,0x96,0xbd,0x90,0x03,0xdf,0xe0,0xf9,0xff,0x7e,0x00,
+0x90,0x03,0xf6,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0x90,0x04,0x0d,0xe0,0x2f,
+0xff,0x90,0x04,0x0c,0xe0,0x3e,0xcf,0x24,0x02,0xfb,0xe4,0x3f,0xfa,0xe9,0x75,0xf0,
+0x0a,0xa4,0x24,0x0b,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xff,0x33,0x95,0xe0,
+0xad,0x07,0xaf,0x03,0xae,0x02,0x12,0x96,0xbd,0x90,0x03,0xdf,0xe0,0xfb,0xff,0x7e,
+0x00,0x90,0x03,0xf6,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0x90,0x04,0x0d,0xe0,
+0x2f,0xff,0x90,0x04,0x0c,0xe0,0x3e,0xcf,0x24,0x03,0xcf,0x34,0x00,0xfe,0xeb,0x75,
+0xf0,0x0a,0xa4,0x24,0x0b,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xa3,0xe0,0xfd,0x12,
+0x96,0xbd,0x90,0x03,0xdf,0xe0,0xf9,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x12,0x1c,0x50,0x90,0x04,0x0d,0xe0,0x2f,0xff,0x90,0x04,0x0c,0xe0,0x3e,
+0xcf,0x24,0x04,0xfb,0xe4,0x3f,0xfa,0xe9,0x75,0xf0,0x0a,0xa4,0x24,0x0d,0xf5,0x82,
+0xe4,0x34,0x02,0xf5,0x83,0xe0,0xff,0x33,0x95,0xe0,0xad,0x07,0xaf,0x03,0xae,0x02,
+0x12,0x96,0xbd,0x90,0x03,0xdf,0xe0,0xfb,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,0xfc,
+0xa3,0xe0,0xfd,0x12,0x1c,0x50,0x90,0x04,0x0d,0xe0,0x2f,0xff,0x90,0x04,0x0c,0xe0,
+0x3e,0xcf,0x24,0x05,0xcf,0x34,0x00,0xfe,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x0d,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xa3,0xe0,0xfd,0x12,0x96,0xbd,0x90,0x03,0xdf,0xe0,
+0xf9,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0x90,
+0x04,0x0d,0xe0,0x2f,0xff,0x90,0x04,0x0c,0xe0,0x3e,0xcf,0x24,0x06,0xfb,0xe4,0x3f,
+0xfa,0xe9,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,
+0xff,0x33,0x95,0xe0,0xad,0x07,0xaf,0x03,0xae,0x02,0x12,0x96,0xbd,0x90,0x03,0xdf,
+0xe0,0xfb,0xff,0x7e,0x00,0x90,0x03,0xf6,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,
+0x90,0x04,0x0d,0xe0,0x2f,0xff,0x90,0x04,0x0c,0xe0,0x3e,0xcf,0x24,0x07,0xcf,0x34,
+0x00,0xfe,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,
+0xa3,0xe0,0xfd,0x12,0x96,0xbd,0x30,0x04,0x64,0x90,0x02,0x09,0xe0,0xfe,0xa3,0xe0,
+0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0x34,0x7e,0xea,0x12,
+0x96,0xbd,0x90,0x02,0x0b,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,
+0x13,0xd8,0xf8,0xfd,0x7f,0x35,0x7e,0xea,0x12,0x96,0xbd,0x90,0x02,0x0d,0xe0,0xfe,
+0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0x36,0x7e,
+0xea,0x12,0x96,0xbd,0x90,0x02,0x0f,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,
+0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0x37,0x7e,0xea,0x12,0x96,0xbd,0x20,0x03,0x03,
+0x02,0x15,0xa8,0x90,0x04,0x6f,0xe0,0x64,0x03,0x70,0x61,0x90,0x02,0x09,0xe0,0xfe,
+0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xd8,0x7e,
+0xe6,0x12,0x96,0xbd,0x90,0x02,0x0b,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,
+0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xd9,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x0d,
+0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,
+0xda,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x0f,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,
+0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xdb,0x80,0x67,0x90,0x04,0x6f,0xe0,
+0x64,0x01,0x70,0x64,0x90,0x02,0x09,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,
+0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xc0,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x0b,
+0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,
+0xc1,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x0d,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,
+0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xc2,0x7e,0xe6,0x12,0x96,0xbd,0x90,
+0x02,0x0f,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,
+0xfd,0x7f,0xc3,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0xdf,0xe0,0x04,0xf0,0x02,0x12,
+0x77,0x30,0x05,0x09,0x90,0x03,0xe3,0xe0,0x70,0x03,0x12,0x8e,0x9f,0x90,0x03,0xe3,
+0xe0,0xfd,0x7f,0x12,0x7e,0xf2,0x12,0x96,0xbd,0x12,0x8d,0x77,0xe4,0x90,0x04,0xec,
+0xf0,0xa3,0xf0,0x20,0x01,0x03,0x02,0x17,0x3f,0x90,0x03,0xdf,0xf0,0x90,0x03,0xdf,
+0xe0,0xff,0xc3,0x94,0x0a,0x40,0x03,0x02,0x17,0x3f,0x90,0x03,0xe3,0xe0,0xfe,0xef,
+0xc3,0x9e,0x90,0x03,0xdf,0xe0,0x40,0x03,0x02,0x16,0xb4,0x75,0xf0,0x0a,0xa4,0x24,
+0x09,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x75,0xf0,
+0x0b,0xa4,0x24,0x9a,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,
+0x90,0x03,0xdf,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0x0b,0xf5,0x82,0xe4,0x34,0x02,
+0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x75,0xf0,0x0b,0xa4,0x24,0x9c,0xf5,0x82,
+0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xdf,0xe0,0xff,0x75,
+0xf0,0x0a,0xa4,0x24,0x0d,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xef,0x75,0xf0,0x0b,0xa4,0x24,0x9e,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,
+0xf0,0xa3,0xed,0xf0,0x90,0x03,0xdf,0xe0,0xff,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x75,0xf0,0x0b,0xa4,
+0x24,0xa0,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,
+0xdf,0xe0,0x75,0xf0,0x0b,0xa4,0x24,0x99,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0x74,
+0x01,0xf0,0x80,0x58,0xff,0x75,0xf0,0x0b,0xa4,0x24,0x9a,0xf5,0x82,0xe4,0x34,0x02,
+0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xef,0x75,0xf0,0x0b,0xa4,0x24,0x9c,0xf5,0x82,0xe4,
+0x34,0x02,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xef,0x75,0xf0,0x0b,0xa4,0x24,0x9e,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xef,0x75,0xf0,0x0b,0xa4,0x24,
+0xa0,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0xef,0x75,0xf0,0x0b,
+0xa4,0x24,0x99,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe4,0xf0,0x90,0x03,0xdf,0xe0,
+0x04,0xf0,0x02,0x15,0xdd,0x7f,0x08,0x7e,0xf2,0x12,0x96,0x64,0x90,0x03,0xe0,0xef,
+0xf0,0xbf,0x01,0x1b,0x90,0x04,0xec,0xe0,0x70,0x02,0xa3,0xe0,0x70,0x11,0x90,0x04,
+0x16,0xf0,0x74,0x02,0x12,0x8d,0x7e,0x90,0x04,0xec,0xe4,0xf0,0xa3,0x04,0xf0,0x22,
+0x02,0x1b,0x06,0xe8,0x64,0x80,0xf8,0xe9,0x33,0xe8,0x33,0x60,0x11,0x04,0x60,0xf0,
+0xed,0x33,0xec,0x33,0x70,0x09,0xe8,0xfc,0xe9,0xfd,0xea,0xfe,0xeb,0xff,0x22,0x04,
+0x60,0xde,0xd3,0xeb,0x9f,0xea,0x9e,0xe9,0x9d,0xe8,0xc2,0xe7,0x8c,0xf0,0xc2,0xf7,
+0x95,0xf0,0x40,0x0c,0xe8,0xcc,0xf8,0xe9,0xcd,0xf9,0xea,0xce,0xfa,0xeb,0xcf,0xfb,
+0x12,0x1a,0xd1,0x85,0xd0,0xf0,0x58,0x04,0x70,0x03,0x20,0xd5,0xb3,0xe8,0x04,0x70,
+0x07,0x50,0x02,0xb2,0xd5,0x02,0x1b,0x10,0x92,0xd5,0xec,0x04,0x60,0xf7,0xe4,0xcc,
+0xc0,0xe0,0xc3,0x98,0xf8,0x60,0x3b,0x94,0x18,0x60,0x08,0x40,0x0d,0xd0,0xe0,0xfb,
+0x02,0x1a,0xe8,0xe4,0xfb,0xfa,0xc9,0xfc,0x80,0x28,0xe8,0x30,0xe4,0x06,0xe4,0xc9,
+0xfb,0xe4,0xca,0xfc,0xe8,0x30,0xe3,0x05,0xe4,0xc9,0xca,0xcb,0xfc,0xe8,0x54,0x07,
+0x60,0x10,0xf8,0xc3,0xe9,0x13,0xf9,0xea,0x13,0xfa,0xeb,0x13,0xfb,0xec,0x13,0xfc,
+0xd8,0xf1,0x30,0xf5,0x2f,0xc3,0xe4,0x9c,0xfc,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,
+0x99,0xfd,0xd0,0xe0,0xfb,0xef,0x4e,0x4d,0x4c,0x70,0x12,0x22,0xdb,0x03,0x02,0x1b,
+0x0d,0xec,0x2c,0xfc,0xef,0x33,0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0xed,0x30,0xe7,
+0xeb,0x02,0x1a,0xe8,0xef,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xd0,0xe0,0xfb,
+0x50,0x13,0x0b,0xbb,0x00,0x03,0x02,0x1b,0x10,0xed,0x13,0xfd,0xee,0x13,0xfe,0xef,
+0x13,0xff,0xec,0x13,0xfc,0x02,0x1a,0xe8,0xec,0x4d,0x60,0x11,0xe8,0x49,0x70,0x17,
+0xed,0x33,0xec,0x33,0x04,0x60,0x0d,0xe4,0xfc,0xff,0xfe,0xfd,0x22,0xe9,0x33,0xe8,
+0x33,0x04,0x70,0xf8,0x02,0x1b,0x06,0x12,0x1a,0xd1,0x58,0x04,0x60,0x09,0xe4,0xcc,
+0x24,0x81,0x50,0x06,0x28,0x50,0x09,0x02,0x1b,0x10,0x28,0x40,0x03,0x02,0x1b,0x0d,
+0xc0,0xe0,0xeb,0x4a,0x70,0x44,0xb9,0x80,0x06,0xd0,0xe0,0xfb,0x02,0x1a,0xfc,0xef,
+0x4e,0x70,0x1c,0xbd,0x80,0x08,0xeb,0xff,0xea,0xfe,0xe9,0xfd,0x80,0xeb,0xe9,0x8d,
+0xf0,0xa4,0xfe,0xe5,0xf0,0x02,0x19,0x21,0xe9,0xcd,0xf9,0xea,0xfe,0xeb,0xff,0xef,
+0x89,0xf0,0xa4,0xfc,0xe5,0xf0,0xce,0x89,0xf0,0xa4,0x2e,0xff,0xe4,0x35,0xf0,0xcd,
+0x89,0xf0,0xa4,0x2d,0xfe,0xe4,0x35,0xf0,0x80,0x67,0xef,0x4e,0x70,0x05,0xbd,0x80,
+0xd7,0x80,0xc3,0xef,0x8b,0xf0,0xa4,0xac,0xf0,0xee,0x8b,0xf0,0xa4,0x2c,0xfc,0xe4,
+0x35,0xf0,0xf8,0xef,0x8a,0xf0,0xa4,0x2c,0xe5,0xf0,0x38,0xfc,0xe4,0x33,0xcb,0x8d,
+0xf0,0xa4,0x2c,0xfc,0xe5,0xf0,0x3b,0xf8,0xee,0x8a,0xf0,0xa4,0x2c,0xfc,0xe5,0xf0,
+0x38,0xf8,0xe4,0x33,0xcf,0x89,0xf0,0xa4,0x2c,0xfc,0xe5,0xf0,0x38,0xcf,0x34,0x00,
+0xce,0x89,0xf0,0xa4,0x2f,0xff,0xe5,0xf0,0x3e,0xfe,0xe4,0x33,0xc9,0x8d,0xf0,0xa4,
+0x2e,0xfe,0xe5,0xf0,0x39,0xcd,0x8a,0xf0,0xa4,0x2f,0xff,0xe5,0xf0,0x3e,0xfe,0xe4,
+0x3d,0xfd,0x33,0xd0,0xe0,0xfb,0x50,0x07,0x0b,0xbb,0x00,0x0f,0x02,0x1b,0x10,0xec,
+0x2c,0xfc,0xef,0x33,0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0x02,0x1a,0xe8,0x02,0x1b,
+0x10,0xec,0x5d,0x04,0x60,0x05,0xe8,0x59,0x04,0x70,0x03,0x02,0x1b,0x06,0x12,0x1a,
+0xd1,0x58,0x04,0x60,0xf6,0xec,0x48,0x60,0xf2,0xec,0x70,0x04,0xfd,0xfe,0xff,0x22,
+0xc8,0x60,0xdb,0x24,0x81,0xc8,0x50,0x09,0xc3,0x98,0x60,0x02,0x50,0x06,0x02,0x1b,
+0x0d,0x98,0x50,0xca,0xf5,0x82,0xe9,0x29,0x4b,0x4a,0x70,0x05,0xab,0x82,0x02,0x1a,
+0xfc,0x75,0xf0,0x00,0x7c,0x1a,0x78,0x80,0xc3,0xef,0x9b,0xee,0x9a,0xed,0x99,0x40,
+0x0d,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xe8,0x42,0xf0,0xdc,0x23,
+0xac,0xf0,0xd0,0xe0,0xff,0xd0,0xe0,0xfe,0xd0,0xe0,0xfd,0xab,0x82,0x20,0xe7,0x10,
+0x1b,0xeb,0x60,0xba,0xec,0x2c,0xfc,0xef,0x33,0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,
+0x02,0x1a,0xe8,0xe8,0x03,0xf8,0x30,0xe7,0x05,0xc0,0xf0,0x75,0xf0,0x00,0xef,0x2f,
+0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0x40,0xb8,0x30,0xe7,0xc2,0x80,0xaa,0x74,0xf8,
+0xcc,0x64,0x80,0xcc,0xc8,0x64,0x80,0xc8,0xf5,0x82,0x04,0x60,0x43,0xc3,0xeb,0x9f,
+0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0,0x60,0x30,
+0x50,0x18,0xe5,0x82,0x5f,0xff,0xe5,0x82,0xf4,0x2b,0x55,0x82,0xfb,0x50,0x21,0x0a,
+0xba,0x00,0x1d,0x09,0xb9,0x00,0x19,0x08,0x80,0x16,0xe5,0x82,0x5b,0xfb,0xe5,0x82,
+0xf4,0x2f,0x55,0x82,0xff,0x50,0x09,0x0e,0xbe,0x00,0x05,0x0d,0xbd,0x00,0x01,0x0c,
+0xc3,0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,
+0xf0,0x60,0x07,0xcc,0x48,0x20,0xe7,0x01,0xb3,0xec,0x22,0xed,0x33,0xec,0x33,0x60,
+0x0a,0x04,0x70,0x03,0xbd,0x80,0x04,0xec,0xb2,0xe7,0xfc,0x22,0x75,0xf0,0x20,0x80,
+0x0e,0x75,0xf0,0x10,0x80,0x05,0x75,0xf0,0x08,0x7d,0x00,0x7e,0x00,0x7f,0x00,0x33,
+0x92,0xd5,0x30,0xd5,0x03,0x12,0x1e,0xc6,0xec,0x33,0x40,0x10,0xef,0x33,0xff,0xee,
+0x33,0xfe,0xed,0x33,0xfd,0xec,0x33,0xfc,0xd5,0xf0,0xed,0x22,0xe5,0xf0,0x24,0x7e,
+0xa2,0xd5,0x13,0xcc,0x92,0xe7,0xcd,0xce,0xff,0x22,0xed,0xd2,0xe7,0xcd,0x33,0xec,
+0x33,0x92,0xd5,0x24,0x81,0x40,0x06,0xe4,0xff,0xfe,0xfd,0xfc,0x22,0xfc,0xe4,0xcf,
+0xce,0xcd,0xcc,0x24,0xe0,0x50,0x11,0x74,0xff,0x80,0xed,0xc3,0xcc,0x13,0xcc,0xcd,
+0x13,0xcd,0xce,0x13,0xce,0xcf,0x13,0xcf,0x04,0x70,0xf0,0x30,0xd5,0xde,0x02,0x1e,
+0xc6,0xe9,0xd2,0xe7,0xc9,0x33,0xe8,0x33,0xf8,0x92,0xd5,0xed,0xd2,0xe7,0xcd,0x33,
+0xec,0x33,0xfc,0x50,0x02,0xb2,0xd5,0x22,0xec,0x30,0xe7,0x10,0x0f,0xbf,0x00,0x0c,
+0x0e,0xbe,0x00,0x08,0x0d,0xbd,0x00,0x04,0x0b,0xeb,0x60,0x14,0xa2,0xd5,0xeb,0x13,
+0xfc,0xed,0x92,0xe7,0xfd,0x22,0x74,0xff,0xfc,0xfd,0xfe,0xff,0x22,0xe4,0x80,0xf8,
+0xa2,0xd5,0x74,0xff,0x13,0xfc,0x7d,0x80,0xe4,0x80,0xef,0xe7,0x09,0xf6,0x08,0xdf,
+0xfa,0x80,0x46,0xe7,0x09,0xf2,0x08,0xdf,0xfa,0x80,0x3e,0x88,0x82,0x8c,0x83,0xe7,
+0x09,0xf0,0xa3,0xdf,0xfa,0x80,0x32,0xe3,0x09,0xf6,0x08,0xdf,0xfa,0x80,0x78,0xe3,
+0x09,0xf2,0x08,0xdf,0xfa,0x80,0x70,0x88,0x82,0x8c,0x83,0xe3,0x09,0xf0,0xa3,0xdf,
+0xfa,0x80,0x64,0x89,0x82,0x8a,0x83,0xe0,0xa3,0xf6,0x08,0xdf,0xfa,0x80,0x58,0x89,
+0x82,0x8a,0x83,0xe0,0xa3,0xf2,0x08,0xdf,0xfa,0x80,0x4c,0x80,0xd2,0x80,0xfa,0x80,
+0xc6,0x80,0xd4,0x80,0x69,0x80,0xf2,0x80,0x33,0x80,0x10,0x80,0xa6,0x80,0xea,0x80,
+0x9a,0x80,0xa8,0x80,0xda,0x80,0xe2,0x80,0xca,0x80,0x33,0x89,0x82,0x8a,0x83,0xec,
+0xfa,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xf0,0xa3,0xc8,0xc5,
+0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xdf,0xe9,0xde,0xe7,0x80,0x0d,0x89,0x82,0x8a,0x83,
+0xe4,0x93,0xa3,0xf6,0x08,0xdf,0xf9,0xec,0xfa,0xa9,0xf0,0xed,0xfb,0x22,0x89,0x82,
+0x8a,0x83,0xec,0xfa,0xe0,0xa3,0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xf0,0xa3,
+0xc8,0xc5,0x82,0xc8,0xcc,0xc5,0x83,0xcc,0xdf,0xea,0xde,0xe8,0x80,0xdb,0x89,0x82,
+0x8a,0x83,0xe4,0x93,0xa3,0xf2,0x08,0xdf,0xf9,0x80,0xcc,0x88,0xf0,0xef,0x60,0x01,
+0x0e,0x4e,0x60,0xc3,0x88,0xf0,0xed,0x24,0x02,0xb4,0x04,0x00,0x50,0xb9,0xf5,0x82,
+0xeb,0x24,0x02,0xb4,0x04,0x00,0x50,0xaf,0x23,0x23,0x45,0x82,0x23,0x90,0x1b,0x6b,
+0x73,0xbb,0x01,0x0c,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe0,0x22,
+0x50,0x06,0xe9,0x25,0x82,0xf8,0xe6,0x22,0xbb,0xfe,0x06,0xe9,0x25,0x82,0xf8,0xe2,
+0x22,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe4,0x93,0x22,0xbb,0x01,
+0x06,0x89,0x82,0x8a,0x83,0xf0,0x22,0x50,0x02,0xf7,0x22,0xbb,0xfe,0x01,0xf3,0x22,
+0xef,0x8d,0xf0,0xa4,0xa8,0xf0,0xcf,0x8c,0xf0,0xa4,0x28,0xce,0x8d,0xf0,0xa4,0x2e,
+0xfe,0x22,0xbc,0x00,0x0b,0xbe,0x00,0x29,0xef,0x8d,0xf0,0x84,0xff,0xad,0xf0,0x22,
+0xe4,0xcc,0xf8,0x75,0xf0,0x08,0xef,0x2f,0xff,0xee,0x33,0xfe,0xec,0x33,0xfc,0xee,
+0x9d,0xec,0x98,0x40,0x05,0xfc,0xee,0x9d,0xfe,0x0f,0xd5,0xf0,0xe9,0xe4,0xce,0xfd,
+0x22,0xed,0xf8,0xf5,0xf0,0xee,0x84,0x20,0xd2,0x1c,0xfe,0xad,0xf0,0x75,0xf0,0x08,
+0xef,0x2f,0xff,0xed,0x33,0xfd,0x40,0x07,0x98,0x50,0x06,0xd5,0xf0,0xf2,0x22,0xc3,
+0x98,0xfd,0x0f,0xd5,0xf0,0xea,0x22,0xc2,0xd5,0xec,0x30,0xe7,0x09,0xb2,0xd5,0xe4,
+0xc3,0x9d,0xfd,0xe4,0x9c,0xfc,0xee,0x30,0xe7,0x15,0xb2,0xd5,0xe4,0xc3,0x9f,0xff,
+0xe4,0x9e,0xfe,0x12,0x1c,0x62,0xc3,0xe4,0x9d,0xfd,0xe4,0x9c,0xfc,0x80,0x03,0x12,
+0x1c,0x62,0x30,0xd5,0x07,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,0x22,0xbb,0x01,0x0a,
+0x89,0x82,0x8a,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x06,0x87,0xf0,0x09,0xe7,
+0x19,0x22,0xbb,0xfe,0x07,0xe3,0xf5,0xf0,0x09,0xe3,0x19,0x22,0x89,0x82,0x8a,0x83,
+0xe4,0x93,0xf5,0xf0,0x74,0x01,0x93,0x22,0xbb,0x01,0x10,0xe5,0x82,0x29,0xf5,0x82,
+0xe5,0x83,0x3a,0xf5,0x83,0xe0,0xf5,0xf0,0xa3,0xe0,0x22,0x50,0x09,0xe9,0x25,0x82,
+0xf8,0x86,0xf0,0x08,0xe6,0x22,0xbb,0xfe,0x0a,0xe9,0x25,0x82,0xf8,0xe2,0xf5,0xf0,
+0x08,0xe2,0x22,0xe5,0x83,0x2a,0xf5,0x83,0xe9,0x93,0xf5,0xf0,0xa3,0xe9,0x93,0x22,
+0xbb,0x01,0x0a,0x89,0x82,0x8a,0x83,0xf0,0xe5,0xf0,0xa3,0xf0,0x22,0x50,0x06,0xf7,
+0x09,0xa7,0xf0,0x19,0x22,0xbb,0xfe,0x06,0xf3,0xe5,0xf0,0x09,0xf3,0x19,0x22,0xf8,
+0xbb,0x01,0x11,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0xe8,0xf0,0xe5,
+0xf0,0xa3,0xf0,0x22,0x50,0x09,0xe9,0x25,0x82,0xc8,0xf6,0x08,0xa6,0xf0,0x22,0xbb,
+0xfe,0x09,0xe9,0x25,0x82,0xc8,0xf2,0xe5,0xf0,0x08,0xf2,0x22,0xe8,0x8f,0xf0,0xa4,
+0xcc,0x8b,0xf0,0xa4,0x2c,0xfc,0xe9,0x8e,0xf0,0xa4,0x2c,0xfc,0x8a,0xf0,0xed,0xa4,
+0x2c,0xfc,0xea,0x8e,0xf0,0xa4,0xcd,0xa8,0xf0,0x8b,0xf0,0xa4,0x2d,0xcc,0x38,0x25,
+0xf0,0xfd,0xe9,0x8f,0xf0,0xa4,0x2c,0xcd,0x35,0xf0,0xfc,0xeb,0x8e,0xf0,0xa4,0xfe,
+0xa9,0xf0,0xeb,0x8f,0xf0,0xa4,0xcf,0xc5,0xf0,0x2e,0xcd,0x39,0xfe,0xe4,0x3c,0xfc,
+0xea,0xa4,0x2d,0xce,0x35,0xf0,0xfd,0xe4,0x3c,0xfc,0x22,0x75,0xf0,0x08,0x75,0x82,
+0x00,0xef,0x2f,0xff,0xee,0x33,0xfe,0xcd,0x33,0xcd,0xcc,0x33,0xcc,0xc5,0x82,0x33,
+0xc5,0x82,0x9b,0xed,0x9a,0xec,0x99,0xe5,0x82,0x98,0x40,0x0c,0xf5,0x82,0xee,0x9b,
+0xfe,0xed,0x9a,0xfd,0xec,0x99,0xfc,0x0f,0xd5,0xf0,0xd6,0xe4,0xce,0xfb,0xe4,0xcd,
+0xfa,0xe4,0xcc,0xf9,0xa8,0x82,0x22,0xb8,0x00,0xc1,0xb9,0x00,0x59,0xba,0x00,0x2d,
+0xec,0x8b,0xf0,0x84,0xcf,0xce,0xcd,0xfc,0xe5,0xf0,0xcb,0xf9,0x78,0x18,0xef,0x2f,
+0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0xec,0x33,0xfc,0xeb,0x33,0xfb,0x10,0xd7,0x03,
+0x99,0x40,0x04,0xeb,0x99,0xfb,0x0f,0xd8,0xe5,0xe4,0xf9,0xfa,0x22,0x78,0x18,0xef,
+0x2f,0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0xec,0x33,0xfc,0xc9,0x33,0xc9,0x10,0xd7,
+0x05,0x9b,0xe9,0x9a,0x40,0x07,0xec,0x9b,0xfc,0xe9,0x9a,0xf9,0x0f,0xd8,0xe0,0xe4,
+0xc9,0xfa,0xe4,0xcc,0xfb,0x22,0x75,0xf0,0x10,0xef,0x2f,0xff,0xee,0x33,0xfe,0xed,
+0x33,0xfd,0xcc,0x33,0xcc,0xc8,0x33,0xc8,0x10,0xd7,0x07,0x9b,0xec,0x9a,0xe8,0x99,
+0x40,0x0a,0xed,0x9b,0xfd,0xec,0x9a,0xfc,0xe8,0x99,0xf8,0x0f,0xd5,0xf0,0xda,0xe4,
+0xcd,0xfb,0xe4,0xcc,0xfa,0xe4,0xc8,0xf9,0x22,0xcf,0xf4,0xcf,0xce,0xf4,0xce,0xcd,
+0xf4,0xcd,0xcc,0xf4,0xcc,0x22,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,0xe4,0x9d,0xfd,
+0xe4,0x9c,0xfc,0x22,0xeb,0x9f,0xf5,0xf0,0xea,0x9e,0x42,0xf0,0xe9,0x9d,0x42,0xf0,
+0xec,0x64,0x80,0xc8,0x64,0x80,0x98,0x45,0xf0,0x22,0xeb,0x9f,0xf5,0xf0,0xea,0x9e,
+0x42,0xf0,0xe9,0x9d,0x42,0xf0,0xe8,0x9c,0x45,0xf0,0x22,0xe8,0x60,0x0f,0xec,0xc3,
+0x13,0xfc,0xed,0x13,0xfd,0xee,0x13,0xfe,0xef,0x13,0xff,0xd8,0xf1,0x22,0xe8,0x60,
+0x0f,0xef,0xc3,0x33,0xff,0xee,0x33,0xfe,0xed,0x33,0xfd,0xec,0x33,0xfc,0xd8,0xf1,
+0x22,0xbb,0x01,0x07,0x89,0x82,0x8a,0x83,0x02,0x20,0xcb,0x50,0x05,0xe9,0xf8,0x02,
+0x20,0xbf,0xbb,0xfe,0x05,0xe9,0xf8,0x02,0x20,0xd7,0x89,0x82,0x8a,0x83,0x02,0x20,
+0xe3,0xbb,0x01,0x0d,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x20,
+0xcb,0x50,0x07,0xe9,0x25,0x82,0xf8,0x02,0x20,0xbf,0xbb,0xfe,0x07,0xe9,0x25,0x82,
+0xf8,0x02,0x20,0xd7,0xe5,0x82,0x29,0xf5,0x82,0xe5,0x83,0x3a,0xf5,0x83,0x02,0x20,
+0xe3,0x74,0x01,0xff,0x33,0x95,0xe0,0xfe,0xfd,0xfc,0xa3,0xa3,0xa3,0xe0,0xcf,0x2f,
+0xf0,0xe5,0x82,0x15,0x82,0x70,0x02,0x15,0x83,0xe0,0xce,0x3e,0xf0,0xe5,0x82,0x15,
+0x82,0x70,0x02,0x15,0x83,0xe0,0xcd,0x3d,0xf0,0xe5,0x82,0x15,0x82,0x70,0x02,0x15,
+0x83,0xe0,0xcc,0x3c,0xf0,0x22,0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xee,0xf0,0xa3,0xef,
+0xf0,0x22,0xa8,0x82,0x85,0x83,0xf0,0xd0,0x83,0xd0,0x82,0x12,0x1f,0xc9,0x12,0x1f,
+0xc9,0x12,0x1f,0xc9,0x12,0x1f,0xc9,0xe4,0x73,0xe4,0x93,0xa3,0xc5,0x83,0xc5,0xf0,
+0xc5,0x83,0xc8,0xc5,0x82,0xc8,0xf0,0xa3,0xc5,0x83,0xc5,0xf0,0xc5,0x83,0xc8,0xc5,
+0x82,0xc8,0x22,0xf5,0xf0,0xc5,0x82,0xa4,0xc5,0x82,0xc5,0xf0,0xc5,0x83,0xa4,0x25,
+0x83,0xf5,0x83,0x22,0xa4,0x25,0x82,0xf5,0x82,0xe5,0xf0,0x35,0x83,0xf5,0x83,0x22,
+0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,0xa3,0xa3,
+0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,0x68,0x60,
+0xef,0xa3,0xa3,0xa3,0x80,0xdf,0xd0,0x83,0xd0,0x82,0xf8,0xe4,0x93,0x70,0x12,0x74,
+0x01,0x93,0x70,0x0d,0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,
+0x73,0x74,0x02,0x93,0xb5,0xf0,0x06,0x74,0x03,0x93,0x68,0x60,0xe9,0xa3,0xa3,0xa3,
+0xa3,0x80,0xd8,0xd0,0x83,0xd0,0x82,0xe4,0x93,0x70,0x12,0x74,0x01,0x93,0x70,0x0d,
+0xa3,0xa3,0x93,0xf8,0x74,0x01,0x93,0xf5,0x82,0x88,0x83,0xe4,0x73,0x74,0x02,0x93,
+0x6c,0x70,0x12,0x74,0x03,0x93,0x6d,0x70,0x0c,0x74,0x04,0x93,0x6e,0x70,0x06,0x74,
+0x05,0x93,0x6f,0x60,0xdd,0xa3,0xa3,0xa3,0xa3,0xa3,0xa3,0x80,0xca,0x8a,0x83,0x89,
+0x82,0xe4,0x73,0xef,0x4e,0x60,0x12,0xef,0x60,0x01,0x0e,0xed,0xbb,0x01,0x0b,0x89,
+0x82,0x8a,0x83,0xf0,0xa3,0xdf,0xfc,0xde,0xfa,0x22,0x89,0xf0,0x50,0x07,0xf7,0x09,
+0xdf,0xfc,0xa9,0xf0,0x22,0xbb,0xfe,0xfc,0xf3,0x09,0xdf,0xfc,0xa9,0xf0,0x22,0xe6,
+0xfc,0x08,0xe6,0xfd,0x08,0xe6,0xfe,0x08,0xe6,0xff,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xe2,0xfc,0x08,0xe2,0xfd,0x08,0xe2,0xfe,0x08,
+0xe2,0xff,0x22,0xe4,0x93,0xfc,0x74,0x01,0x93,0xfd,0x74,0x02,0x93,0xfe,0x74,0x03,
+0x93,0xff,0x22,0x90,0x03,0xfe,0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xec,0xf0,0xa3,0xed,
+0xf0,0xe4,0x90,0x04,0x04,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0x74,
+0xeb,0xf0,0xa3,0x74,0x90,0xf0,0x90,0x04,0x1f,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,
+0x90,0x04,0x23,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x04,0x27,0x12,0x1f,0xb2,
+0x00,0x00,0x00,0x00,0x7f,0xa1,0x7e,0xe8,0x12,0x96,0x64,0x90,0x04,0x0b,0xef,0xf0,
+0x7d,0xff,0x7f,0xa1,0x7e,0xe8,0x12,0x96,0xbd,0x90,0x04,0x1b,0x12,0x1f,0xb2,0x00,
+0x00,0x00,0x00,0x90,0x01,0xbb,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0xe4,0x90,0x04,
+0x02,0xf0,0xa3,0xf0,0x90,0x04,0x02,0xe0,0xfc,0xa3,0xe0,0xfd,0x25,0xe0,0xff,0xec,
+0x33,0xfe,0x74,0xd8,0x2f,0xf5,0x82,0x74,0x01,0x3e,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,
+0x74,0x05,0x2f,0xf5,0x82,0x74,0x00,0x3e,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,
+0x04,0x02,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xfb,
+0xaa,0x06,0x24,0x5b,0xf5,0x82,0x74,0x01,0x3a,0xf5,0x83,0x12,0x1f,0xb2,0x00,0x00,
+0x00,0x00,0x74,0xf5,0x2b,0xf5,0x82,0x74,0x00,0x3a,0xf5,0x83,0x12,0x1f,0xb2,0x00,
+0x00,0x00,0x00,0x90,0x04,0x02,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,
+0xce,0xd8,0xf9,0xfb,0xaa,0x06,0x24,0x95,0xf5,0x82,0x74,0x00,0x3a,0xf5,0x83,0x12,
+0x1f,0xb2,0x00,0x00,0x00,0x00,0x74,0x35,0x2b,0xf5,0x82,0x74,0x00,0x3a,0xf5,0x83,
+0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x04,0x03,0xe0,0x04,0xf0,0x70,0x06,0x90,
+0x04,0x02,0xe0,0x04,0xf0,0x90,0x04,0x02,0xe0,0x70,0x04,0xa3,0xe0,0x64,0x18,0x60,
+0x03,0x02,0x21,0x64,0x90,0x03,0xfe,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x02,0xcf,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0x01,0xe0,0x24,0x01,0xff,0x90,0x04,0x00,0xe0,0x34,0x00,
+0xfe,0x90,0x04,0x02,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xee,0x64,0x80,0xf8,0xec,
+0x64,0x80,0x98,0x40,0x03,0x02,0x25,0xee,0x7f,0xa2,0x7e,0xe8,0x12,0x96,0xbd,0x7f,
+0x5c,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x0c,0xef,0xf0,0x7f,0x5d,0x7e,0xec,0x12,
+0x96,0x64,0x90,0x04,0x0d,0xef,0xf0,0x7f,0x5e,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0x0e,0xef,0xf0,0x90,0x04,0x0d,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x08,0x12,0x1f,
+0x0e,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x0c,0xe0,0xff,0xe4,0xfc,
+0xfd,0xfe,0x78,0x10,0x12,0x1f,0x0e,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xef,
+0x2b,0xfb,0xee,0x3a,0xfa,0xed,0x39,0xf9,0xec,0x38,0xf8,0x90,0x04,0x0e,0xe0,0xff,
+0xe4,0xfc,0xfd,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,
+0x90,0x04,0x1b,0x12,0x1f,0xa6,0x7f,0x50,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x0f,
+0xef,0xf0,0x7f,0x51,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x10,0xef,0xf0,0x7f,0x52,
+0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x11,0xef,0xf0,0x7f,0x53,0x7e,0xec,0x12,0x96,
+0x64,0x90,0x04,0x12,0xef,0xf0,0x7f,0x54,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x13,
+0xef,0xf0,0x7f,0x55,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x14,0xef,0xf0,0x7f,0x56,
+0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x15,0xef,0xf0,0x7f,0x57,0x7e,0xec,0x12,0x96,
+0x64,0x90,0x04,0x16,0xef,0xf0,0x7f,0x58,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x17,
+0xef,0xf0,0x7f,0x59,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x18,0xef,0xf0,0x7f,0x5a,
+0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x19,0xef,0xf0,0x7f,0x5b,0x7e,0xec,0x12,0x96,
+0x64,0x90,0x04,0x1a,0xef,0xf0,0x90,0x04,0x10,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,
+0x10,0x12,0x1f,0x0e,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x0f,0xe0,
+0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x1f,0x0e,0xd0,0x03,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0xef,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0xc0,0x04,
+0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x11,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,
+0x08,0x12,0x1f,0x0e,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xeb,0x2f,0xfb,0xea,
+0x3e,0xfa,0xe9,0x3d,0xf9,0xe8,0x3c,0xf8,0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xeb,
+0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x04,0x1f,0x12,0x1f,
+0xa6,0x90,0x04,0x14,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x10,0x12,0x1f,0x0e,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x13,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,
+0x78,0x18,0x12,0x1f,0x0e,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xef,0x2b,0xff,
+0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x15,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x08,0x12,0x1f,0x0e,0xd0,
+0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xeb,0x2f,0xfb,0xea,0x3e,0xfa,0xe9,0x3d,0xf9,
+0xe8,0x3c,0xf8,0xa3,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,
+0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x04,0x27,0x12,0x1f,0xa6,0x90,0x04,0x18,0xe0,
+0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x10,0x12,0x1f,0x0e,0xc0,0x04,0xc0,0x05,0xc0,0x06,
+0xc0,0x07,0x90,0x04,0x17,0xe0,0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x18,0x12,0x1f,0x0e,
+0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xef,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,
+0xfd,0xec,0x38,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x19,0xe0,
+0xff,0xe4,0xfc,0xfd,0xfe,0x78,0x08,0x12,0x1f,0x0e,0xd0,0x03,0xd0,0x02,0xd0,0x01,
+0xd0,0x00,0xeb,0x2f,0xfb,0xea,0x3e,0xfa,0xe9,0x3d,0xf9,0xe8,0x3c,0xf8,0xa3,0xe0,
+0xff,0xe4,0xfc,0xfd,0xfe,0xeb,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,
+0xfc,0x90,0x04,0x23,0x12,0x1f,0xa6,0x90,0x04,0x1b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x02,
+0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x5b,0xf5,
+0x82,0x74,0x01,0x3e,0xf5,0x83,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x1f,
+0xa6,0x90,0x04,0x1f,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x02,0xe0,0xfe,0xa3,0xe0,0x78,0x02,
+0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0xf5,0xf5,0x82,0x74,0x00,0x3e,0xf5,0x83,
+0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x1f,0xa6,0x90,0x04,0x27,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x02,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,
+0xf9,0x24,0x95,0xf5,0x82,0x74,0x00,0x3e,0xf5,0x83,0xd0,0x07,0xd0,0x06,0xd0,0x05,
+0xd0,0x04,0x12,0x1f,0xa6,0x90,0x04,0x23,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,
+0xa3,0xe0,0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x02,0xe0,0xfe,
+0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x35,0xf5,0x82,0x74,
+0x00,0x3e,0xf5,0x83,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x1f,0xa6,0x90,
+0x01,0xbb,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x1b,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xef,0x2b,0xff,0xee,0x3a,
+0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x01,0xbb,0x12,0x1f,0xa6,0x90,0x04,0x03,
+0xe0,0x04,0xf0,0x70,0x06,0x90,0x04,0x02,0xe0,0x04,0xf0,0x02,0x22,0x23,0x90,0x01,
+0xbb,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x00,0x01,0x12,
+0x1f,0xa6,0xe4,0x90,0x04,0x02,0xf0,0xa3,0xf0,0x90,0x04,0x02,0xe0,0xfc,0xa3,0xe0,
+0xfd,0x25,0xe0,0xff,0xec,0x33,0xfe,0x74,0x05,0x2f,0xf5,0x82,0x74,0x00,0x3e,0xf5,
+0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x01,0xbb,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,
+0xfe,0xa3,0xe0,0x24,0x01,0xff,0xe4,0x3e,0xfe,0xe4,0x3d,0xfd,0xe4,0x3c,0xfc,0xe4,
+0x12,0x1a,0x5c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x02,0xe0,0xfe,
+0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x5b,0xf5,0x82,0x74,
+0x01,0x3e,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,
+0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,0xe4,0xfb,
+0xfa,0x79,0xc8,0x78,0x42,0x12,0x18,0x38,0x12,0x1a,0x9a,0xef,0xfd,0x90,0x04,0x02,
+0xe0,0xfa,0xa3,0xe0,0xfb,0x25,0xe0,0xff,0xea,0x33,0xfe,0x74,0xd8,0x2f,0xf5,0x82,
+0x74,0x01,0x3e,0xf5,0x83,0xe4,0xf0,0xa3,0xed,0xf0,0xc3,0xeb,0x94,0x08,0xea,0x64,
+0x80,0x94,0x80,0x50,0x0e,0x90,0x04,0x02,0xe0,0xfc,0xa3,0xe0,0xfd,0x24,0x90,0xff,
+0xec,0x80,0x42,0x90,0x04,0x02,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0x07,0xee,0x64,
+0x80,0x94,0x80,0x40,0x1e,0xef,0x94,0x10,0xee,0x64,0x80,0x94,0x80,0x50,0x14,0x90,
+0x04,0x02,0xe0,0xfc,0xa3,0xe0,0xfd,0x24,0xf8,0x90,0x04,0x08,0xf0,0x24,0xd0,0xff,
+0xe4,0x80,0x12,0x90,0x04,0x02,0xe0,0xfc,0xa3,0xe0,0xfd,0x24,0xef,0x90,0x04,0x08,
+0xf0,0x24,0xb0,0xff,0xe4,0x34,0xeb,0xfe,0xc0,0x06,0xc0,0x07,0xed,0x25,0xe0,0xff,
+0xec,0x33,0xfe,0x74,0xd8,0x2f,0xf5,0x82,0x74,0x01,0x3e,0xf5,0x83,0xa3,0xe0,0xfd,
+0xd0,0x07,0xd0,0x06,0x12,0x96,0xbd,0x90,0x04,0x03,0xe0,0x04,0xf0,0x70,0x06,0x90,
+0x04,0x02,0xe0,0x04,0xf0,0xc3,0x90,0x04,0x03,0xe0,0x94,0x18,0x90,0x04,0x02,0xe0,
+0x64,0x80,0x94,0x80,0x50,0x03,0x02,0x26,0x09,0x90,0x04,0x2e,0x74,0x01,0xf0,0xa3,
+0x74,0x00,0xf0,0xa3,0x74,0x05,0xf0,0x7b,0x01,0x7a,0x01,0x79,0xd8,0x02,0x68,0x53,
+0x90,0x04,0x0e,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x12,0xea,0xf0,0xa3,0xeb,0xf0,
+0xae,0x04,0xaf,0x05,0xec,0x12,0x1a,0x61,0x7b,0xcd,0x7a,0xcc,0x79,0x4c,0x78,0x3e,
+0x12,0x18,0x38,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0xee,
+0x33,0x95,0xe0,0xfd,0xfc,0x90,0x04,0x18,0x12,0x1f,0xa6,0x90,0x04,0x18,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xfb,
+0x12,0x1d,0x9c,0x90,0x04,0x18,0x12,0x1f,0xa6,0xe4,0x90,0x04,0x16,0xf0,0xa3,0xf0,
+0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x94,0x0a,0xee,0x64,0x80,0x94,0x80,
+0x40,0x03,0x02,0x2c,0x3e,0x90,0x02,0x99,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,
+0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0x64,0x01,0x60,0x03,0x02,0x2c,0x2a,
+0x90,0x04,0x16,0xa3,0xe0,0x90,0x02,0x9a,0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,
+0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,
+0x95,0xe0,0xf9,0xf8,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x9e,0x75,0xf0,
+0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,
+0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,
+0x99,0xfd,0xec,0x98,0xfc,0x12,0x1a,0x5c,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,
+0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,
+0x90,0x02,0x9a,0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,
+0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,
+0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x04,
+0x24,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x9c,
+0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfe,0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,0xf9,0xf8,0x90,0x04,0x16,0xe0,
+0xfe,0xa3,0xe0,0x90,0x02,0xa0,0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,
+0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,
+0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0x12,0x1a,0x5c,
+0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x9c,0x75,0xf0,0x0b,0x12,0x1f,
+0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,
+0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,
+0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x04,0x26,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,
+0x14,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,0x07,
+0x90,0x04,0x26,0xe0,0xfe,0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,0xf9,0xf8,
+0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,
+0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x14,0xe0,0xfe,0xa3,0xe0,
+0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,0x07,0x90,0x04,0x26,0xa3,0xea,
+0x33,0x95,0xe0,0xf9,0xf8,0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,
+0xed,0x99,0xfd,0xec,0x98,0xfc,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x1d,
+0x9c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x12,0xe0,0xfe,0xa3,0xe0,
+0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,0x07,0x90,0x04,0x24,0xe0,0xfe,
+0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,0xf9,0xf8,0xd0,0x07,0xd0,0x06,0xc3,
+0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0xc0,0x04,0xc0,0x05,
+0xc0,0x06,0xc0,0x07,0x90,0x04,0x12,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,
+0xfd,0xfc,0xc0,0x06,0xc0,0x07,0x90,0x04,0x24,0xa3,0xea,0x33,0x95,0xe0,0xf9,0xf8,
+0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,
+0xfc,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x1d,0x9c,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0xef,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,
+0x90,0x04,0x1c,0x12,0x1f,0xa6,0x90,0x04,0x16,0xe0,0x70,0x02,0xa3,0xe0,0x60,0x03,
+0x02,0x2b,0x32,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,0x9a,0x75,0xf0,
+0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x90,0x02,0x9e,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,
+0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xc3,0x9d,0xff,0xee,0x9c,0xab,0x07,
+0xfa,0x33,0x95,0xe0,0xf9,0xf8,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,
+0x9a,0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,
+0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x02,0x9e,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,
+0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xc3,0x9d,0xff,0xee,
+0x9c,0xfe,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1d,0x9c,0x90,0x04,0x20,0x12,0x1f,0xa6,
+0x90,0x04,0x20,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xec,0x33,
+0x50,0x15,0x90,0x04,0x20,0xa3,0xa3,0xa3,0x74,0xff,0xfb,0xfa,0xf9,0xf8,0x12,0x1d,
+0x9c,0x90,0x04,0x20,0x12,0x1f,0xa6,0x90,0x04,0x20,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x1c,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xfb,0xc3,0x12,0x1e,0xd4,0x50,0x09,0x90,0x04,0x0e,0xa3,0xe0,0x90,0x02,
+0x81,0xf0,0x90,0x04,0x18,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,
+0xa3,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,0xd4,
+0x40,0x03,0x02,0x2c,0x2a,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,0x9a,
+0x75,0xf0,0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfc,0xa3,0xe0,0xfd,0x90,0x04,0x0e,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x02,0x09,0x75,
+0xf0,0x0a,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xec,0xf0,
+0xa3,0xed,0xf0,0x90,0x02,0x9c,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,
+0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,0x0b,0x75,0xf0,
+0x0a,0xeb,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,0x9e,0x75,0xf0,
+0x0b,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x90,0x02,0x0d,0x75,0xf0,0x0a,0xeb,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x02,0xa0,0x75,0xf0,0x0b,
+0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x02,0x0f,0x75,0xf0,0x0a,0xeb,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x17,0xe0,0x04,0xf0,
+0x60,0x03,0x02,0x27,0xc0,0x90,0x04,0x16,0xe0,0x04,0xf0,0x02,0x27,0xc0,0x22,0xa3,
+0xf0,0x7b,0x01,0x7a,0x03,0x79,0xf7,0x90,0x03,0xfd,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,
+0xe9,0xf0,0x90,0x04,0x03,0xe0,0x24,0xc4,0x60,0x17,0x24,0x0a,0x70,0x32,0x90,0x04,
+0x12,0x74,0xff,0xf0,0xa3,0x74,0xab,0xf0,0xa3,0x74,0x85,0xf0,0x90,0xac,0x15,0x80,
+0x11,0x90,0x04,0x12,0x74,0xff,0xf0,0xa3,0x74,0xab,0xf0,0xa3,0x74,0xd5,0xf0,0x90,
+0xac,0x17,0xe4,0x93,0xff,0x74,0x01,0x93,0x90,0x04,0x06,0xcf,0xf0,0xa3,0xef,0xf0,
+0x90,0x04,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1f,0x21,0x90,0x04,
+0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xf9,0x12,0x1c,0xed,0xfd,0xac,0xf0,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,
+0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x40,
+0x28,0x90,0x04,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1f,0x21,0x90,
+0x04,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,
+0x12,0x1a,0x9a,0x90,0x04,0x04,0xee,0x80,0x7a,0x90,0x04,0x06,0xe0,0xfe,0xa3,0xe0,
+0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x04,0x12,0xe0,0xfb,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xf9,0x8f,0x82,0x8e,0x83,0x12,0x1f,0x41,0x90,0x04,0x83,0xe0,
+0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,0xc0,0x04,0xc0,
+0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,
+0x12,0x1c,0xed,0xfd,0xac,0xf0,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,
+0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x50,0x1b,0x90,
+0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xff,0x90,0x04,
+0x04,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x02,0x2e,0xd3,0xe4,0x90,0x04,0x08,0xf0,0xa3,
+0xf0,0x90,0x04,0x06,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,
+0x9f,0xec,0x9e,0x40,0x03,0x02,0x2e,0xd3,0xed,0xae,0x04,0x78,0x02,0xc3,0x33,0xce,
+0x33,0xce,0xd8,0xf9,0xff,0x90,0x04,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,
+0x8f,0x82,0x8e,0x83,0x12,0x1f,0x41,0x90,0x04,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,
+0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xfd,0xac,
+0xf0,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,
+0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x40,0x03,0x02,0x2e,0xc2,0x90,0x04,0x09,
+0xe0,0x24,0x01,0xff,0x90,0x04,0x08,0xe0,0x34,0x00,0xfe,0xef,0x78,0x02,0xc3,0x33,
+0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,0x04,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x8f,0x82,0x8e,0x83,0x12,0x1f,0x41,0x90,0x04,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xfd,
+0xac,0xf0,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,
+0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0xde,0x40,0x47,0x90,0x04,0x09,0xe0,0x24,
+0x01,0xff,0x90,0x04,0x08,0xe0,0x34,0x00,0xfe,0xef,0x78,0x02,0xc3,0x33,0xce,0x33,
+0xce,0xd8,0xf9,0xff,0x90,0x04,0x12,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x8f,
+0x82,0x8e,0x83,0x12,0x1f,0x41,0x90,0x04,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xfb,0x12,0x19,0x41,0x12,0x1a,0x9a,0x90,0x04,0x04,0xee,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0x09,0xe0,0x04,0xf0,0x70,0x06,0x90,0x04,0x08,0xe0,0x04,0xf0,
+0x02,0x2d,0x91,0x90,0x04,0x04,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xf9,0x12,0x1c,0xed,0xfd,0xac,0xf0,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,
+0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x90,
+0x04,0x0a,0x12,0x1f,0xa6,0x90,0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,
+0x12,0x1c,0xed,0xfd,0xac,0xf0,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,
+0xc0,0x07,0x90,0x05,0x58,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,
+0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,
+0x41,0x90,0x04,0x0e,0x12,0x1f,0xa6,0x90,0x04,0x0e,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x0a,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xfb,0x12,0x19,0x41,0x90,0x04,0x0e,0x12,0x1f,0xa6,0x90,0x05,0x58,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x90,0x04,0x0e,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x04,0x00,0xe0,
+0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xee,0x8f,0xf0,0x12,0x1d,0x50,0x90,0x04,0x04,
+0xe0,0xf9,0xa3,0xe0,0xff,0x90,0x03,0xfd,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xc9,
+0x8f,0xf0,0x12,0x1d,0x50,0x90,0x05,0x47,0xe0,0x64,0xdb,0x70,0x5d,0x90,0x04,0x00,
+0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xff,0xae,0xf0,0x90,0x04,
+0x6d,0xe0,0xfc,0xa3,0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x06,0xae,0x04,0xaf,0x05,
+0x80,0x00,0x90,0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xee,0x8f,0xf0,
+0x12,0x1d,0x50,0x90,0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,
+0xed,0xff,0xae,0xf0,0x90,0x05,0xde,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,
+0x50,0x06,0xae,0x04,0xaf,0x05,0x80,0x5d,0x80,0x5b,0x90,0x04,0x00,0xe0,0xfb,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xff,0xae,0xf0,0x90,0x04,0x6d,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x06,0xae,0x04,0xaf,0x05,0x80,0x00,0x90,
+0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xee,0x8f,0xf0,0x12,0x1d,0x50,
+0x90,0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x1c,0xed,0xff,0xae,
+0xf0,0x90,0x04,0xdc,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,0x50,0x06,0xae,
+0x04,0xaf,0x05,0x80,0x00,0x90,0x04,0x00,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,
+0xee,0x8f,0xf0,0x12,0x1d,0x50,0x90,0x04,0x03,0xe0,0x90,0x05,0xca,0xf0,0x22,0x90,
+0x06,0x13,0xee,0xf0,0xa3,0xef,0xf0,0x20,0x02,0x03,0x02,0x32,0x8b,0xe4,0x90,0x02,
+0x95,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,0x02,0x82,0xf0,0xa3,0xf0,0x7f,0x40,
+0x7e,0xe6,0x12,0x96,0x64,0xef,0x54,0x0f,0xfe,0x90,0x06,0x23,0xf0,0xef,0x54,0xf0,
+0xc4,0x54,0x0f,0xa3,0xf0,0xfb,0xee,0x25,0xe0,0xff,0xe4,0x33,0xfe,0x74,0x6d,0x2f,
+0xf5,0x82,0x74,0x02,0x3e,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,0xff,0x7e,0x00,
+0x12,0x1c,0xb7,0xed,0x04,0x90,0x06,0x24,0xf0,0xe4,0x90,0x06,0x15,0xf0,0xa3,0xf0,
+0x90,0x06,0x13,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,
+0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x40,0x03,0x02,0x32,0x89,0x90,0x02,0x11,
+0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,
+0xe0,0xff,0x90,0x06,0x23,0xe0,0xfd,0xef,0x6d,0x70,0x01,0xe4,0x60,0x03,0x02,0x32,
+0x75,0x90,0x06,0x15,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x12,0x75,0xf0,0x0a,0x12,0x1f,
+0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xff,0x90,0x06,0x24,0xe0,
+0xfd,0xef,0x6d,0x70,0x01,0xe4,0x60,0x03,0x02,0x32,0x75,0x90,0x06,0x15,0xa3,0xe0,
+0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,
+0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xab,0x07,0xaa,0x06,0x90,0x06,0x15,0xe0,0xfe,
+0xa3,0xe0,0x90,0x02,0x0d,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,
+0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,
+0x90,0x02,0x82,0xf0,0xa3,0xef,0xf0,0xfd,0xac,0x06,0xec,0x12,0x1a,0x61,0xe4,0xfb,
+0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,
+0x06,0x15,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,
+0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,
+0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,
+0x47,0x12,0x1a,0x9a,0x90,0x02,0x95,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x82,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,
+0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x06,0x15,0xe0,0xfe,0xa3,0xe0,
+0x90,0x02,0x0b,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,
+0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,
+0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x02,
+0x97,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x06,0x15,0xe0,0xff,0xa3,0xe0,0x90,0x06,0x19,
+0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x06,0x16,0xe0,0x04,0xf0,0x60,0x03,0x02,0x31,0x00,
+0x90,0x06,0x15,0xe0,0x04,0xf0,0x02,0x31,0x00,0xc2,0x02,0x90,0x02,0x97,0xe0,0xfc,
+0xa3,0xe0,0xfd,0x90,0x02,0x82,0xe0,0xfa,0xa3,0xe0,0x90,0x06,0x13,0x12,0x4c,0x6d,
+0x90,0x06,0x17,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x09,0xe0,0xfd,0xa3,0xe0,0x90,
+0x06,0x1b,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0b,0xe0,0xfd,0xa3,0xe0,0x90,0x06,
+0x1d,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0d,0xe0,0xfd,0xa3,0xe0,0x90,0x06,0x1f,
+0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0f,0xe0,0xfd,0xa3,0xe0,0x90,0x06,0x21,0xcd,
+0xf0,0xa3,0xed,0xf0,0x90,0x06,0x17,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x02,0x09,0x75,
+0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfb,
+0xa3,0xe0,0x90,0x02,0x09,0xcb,0xf0,0xa3,0xeb,0xf0,0xa3,0x75,0xf0,0x0a,0xed,0x12,
+0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x90,
+0x02,0x0b,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x06,0x17,0xa3,0xe0,0xfd,0x90,0x02,0x0d,
+0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfb,0xa3,0xe0,0x90,0x02,0x0d,0xcb,0xf0,0xa3,0xeb,0xf0,0xa3,0x75,0xf0,0x0a,0xed,
+0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,
+0x90,0x02,0x0f,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x09,0x75,0xf0,0x0a,0xef,0x12,
+0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,
+0xab,0x07,0xaa,0x06,0x90,0x06,0x17,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x0d,0x75,0xf0,
+0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,
+0xe0,0xff,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0x90,0x02,0x82,0xf0,0xa3,0xef,0xf0,
+0xfd,0xac,0x06,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x06,0x17,0xe0,0xfe,0xa3,0xe0,0x90,
+0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,
+0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x02,0x95,
+0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x82,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,
+0x61,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,
+0xc0,0x07,0x90,0x06,0x17,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x0b,0x75,0xf0,0x0a,0x12,
+0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,
+0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,
+0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x02,0x97,0xee,0xf0,0xa3,0xef,0xf0,0x90,
+0x06,0x1b,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x06,0x17,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,
+0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x06,0x1d,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,
+0x0b,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x06,0x1f,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,
+0x0d,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x06,0x21,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x02,
+0x0f,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xee,0xf0,0xa3,0xef,0xf0,0x22,0xe4,0x90,0x03,0xdf,0xf0,0xa3,0xf0,0xa3,0x12,
+0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0xe5,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,
+0x90,0x03,0xe9,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0xed,0x12,0x1f,0xb2,
+0x3f,0x80,0x00,0x00,0xe4,0x90,0x03,0xf2,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,
+0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xff,
+0x7e,0xe8,0x12,0x96,0x64,0x90,0x03,0xf1,0xef,0xf0,0x7f,0x98,0x7e,0xeb,0x12,0x96,
+0x64,0x90,0x02,0x08,0xef,0xf0,0x12,0x93,0xdd,0x12,0x8d,0xe1,0x7f,0x90,0x7e,0xe6,
+0x12,0x96,0x64,0xef,0xc4,0x54,0x0f,0xfe,0xef,0xc4,0x54,0xf0,0xc4,0x54,0x0f,0xff,
+0xee,0x60,0x05,0x90,0x01,0xc1,0xef,0xf0,0x90,0x00,0x05,0xa3,0xe0,0xfd,0x7f,0x91,
+0x7e,0xe6,0x12,0x96,0xbd,0x90,0x01,0xc1,0xe0,0xfd,0x7f,0x92,0x7e,0xe6,0x12,0x96,
+0xbd,0x90,0x05,0x47,0xe0,0x90,0x01,0x55,0xb4,0xd5,0x08,0xe4,0xf0,0xa3,0x74,0x02,
+0xf0,0x80,0x06,0xe4,0xf0,0xa3,0x74,0x0f,0xf0,0x90,0x03,0xf1,0xe0,0x64,0x80,0x70,
+0x0f,0x90,0x02,0x08,0xe0,0x70,0x03,0x02,0x39,0x2c,0x12,0x7e,0x25,0x02,0x38,0xe0,
+0x90,0x03,0xf1,0xe0,0x64,0x82,0x60,0x03,0x02,0x39,0x2c,0x20,0x0a,0x03,0x02,0x39,
+0x2c,0x90,0x02,0x08,0xe0,0x60,0x0a,0x12,0x7e,0x25,0xe4,0x90,0x00,0x00,0xf0,0x80,
+0x09,0x12,0x66,0x5a,0x90,0x00,0x00,0x74,0x01,0xf0,0x90,0x00,0x00,0xe0,0x64,0x01,
+0x60,0x03,0x02,0x38,0xe0,0x90,0x01,0xc4,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x01,0xc2,
+0xe0,0xfc,0xa3,0xe0,0xc3,0x9f,0xff,0xec,0x9e,0x90,0x03,0xf6,0xf0,0xfa,0xa3,0xef,
+0xf0,0xfb,0x90,0x01,0x59,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x01,0x57,0xe0,0xfc,0xa3,
+0xe0,0xc3,0x9f,0xff,0xec,0x9e,0x90,0x03,0xf8,0xf0,0xa3,0xef,0xf0,0xaf,0x03,0xae,
+0x02,0x12,0x97,0x95,0x90,0x03,0xfa,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xf8,0xe0,
+0xfe,0xa3,0xe0,0xff,0x12,0x97,0x95,0x90,0x03,0xfc,0xee,0xf0,0xa3,0xef,0xf0,0xd3,
+0x90,0x03,0xfb,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0xfa,0xe0,0x64,0x80,0x98,
+0x50,0x03,0x02,0x37,0x7d,0x90,0x03,0xfc,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,
+0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfa,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xec,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,
+0x90,0x03,0xed,0x12,0x1f,0xa6,0x90,0x01,0x55,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,
+0x03,0xfb,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0xfa,0xe0,0x64,0x80,0x98,0x50,
+0x03,0x02,0x38,0xac,0xd3,0x90,0x03,0xfd,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,
+0xfc,0xe0,0x64,0x80,0x98,0x50,0x03,0x02,0x38,0xac,0x90,0x03,0xf8,0xe0,0xfa,0xa3,
+0xe0,0xfb,0xea,0x64,0x80,0x94,0x80,0x50,0x0d,0x7c,0xff,0x7d,0xff,0x12,0x1c,0x50,
+0x90,0x03,0xf8,0xee,0x80,0x16,0xd3,0xeb,0x94,0x00,0xea,0x64,0x80,0x94,0x80,0x40,
+0x11,0x90,0x01,0x55,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xf8,0xcf,0xf0,0xa3,0xef,0xf0,
+0x80,0x07,0xe4,0x90,0x03,0xf8,0xf0,0xa3,0xf0,0xc3,0x90,0x03,0xf6,0xe0,0x64,0x80,
+0x94,0x80,0x50,0x32,0x90,0x01,0x55,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,
+0x90,0x03,0xed,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,
+0x38,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x7c,0xff,0x7d,
+0xff,0x12,0x1c,0x50,0x80,0x3a,0xd3,0x90,0x03,0xf7,0xe0,0x94,0x00,0x90,0x03,0xf6,
+0xe0,0x64,0x80,0x94,0x80,0x40,0x2f,0x90,0x01,0x55,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,
+0x12,0x1a,0x61,0x90,0x03,0xed,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xfb,0x12,0x18,0x38,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,
+0x90,0x03,0xf6,0x02,0x38,0x9e,0xe4,0x90,0x03,0xf6,0x02,0x38,0xa9,0x90,0x03,0xfa,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x03,0xfc,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0xd0,0x03,0xd0,
+0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,0x90,0x03,0xed,0x12,0x1f,0xa6,0x90,0x01,
+0x55,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x03,0xfb,0xe0,0x9f,0xee,0x64,0x80,0xf8,
+0x90,0x03,0xfa,0xe0,0x64,0x80,0x98,0x50,0x03,0x02,0x38,0xac,0xd3,0x90,0x03,0xfd,
+0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0xfc,0xe0,0x64,0x80,0x98,0x50,0x03,0x02,
+0x38,0xac,0x90,0x03,0xf6,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x64,0x80,0x94,0x80,0x50,
+0x0d,0x7c,0xff,0x7d,0xff,0x12,0x1c,0x50,0x90,0x03,0xf6,0xee,0x80,0x16,0xd3,0xeb,
+0x94,0x00,0xea,0x64,0x80,0x94,0x80,0x40,0x11,0x90,0x01,0x55,0xe0,0xff,0xa3,0xe0,
+0x90,0x03,0xf6,0xcf,0xf0,0xa3,0xef,0xf0,0x80,0x07,0xe4,0x90,0x03,0xf6,0xf0,0xa3,
+0xf0,0xc3,0x90,0x03,0xf8,0xe0,0x64,0x80,0x94,0x80,0x50,0x35,0x90,0x01,0x55,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,0xed,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,
+0x17,0x47,0x12,0x1a,0x9a,0x7c,0xff,0x7d,0xff,0x12,0x1c,0x50,0x90,0x03,0xf8,0x80,
+0x3d,0xd3,0x90,0x03,0xf9,0xe0,0x94,0x00,0x90,0x03,0xf8,0xe0,0x64,0x80,0x94,0x80,
+0x40,0x33,0x90,0x01,0x55,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,
+0xed,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0xe4,
+0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x03,0xf8,0xee,0xf0,
+0xa3,0xef,0xf0,0x80,0x07,0xe4,0x90,0x03,0xf8,0xf0,0xa3,0xf0,0x90,0x01,0xc4,0xe0,
+0xfe,0xa3,0xe0,0xff,0x90,0x03,0xf7,0xe0,0x2f,0xff,0x90,0x03,0xf6,0xe0,0x3e,0x90,
+0x01,0xc4,0xf0,0xa3,0xef,0xf0,0x90,0x01,0x59,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,
+0xf9,0xe0,0x2f,0xff,0x90,0x03,0xf8,0xe0,0x3e,0x90,0x01,0x59,0xf0,0xa3,0xef,0xf0,
+0x90,0x01,0xc4,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x03,0xf2,0xf0,0xfd,0xeb,0xa3,
+0xf0,0x90,0x01,0x59,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x03,0xf4,0xf0,0xeb,0xa3,
+0xf0,0x7f,0xb8,0x7e,0xe1,0x12,0x96,0xbd,0x90,0x03,0xf3,0xe0,0xfd,0x7f,0xb9,0x7e,
+0xe1,0x12,0x96,0xbd,0x90,0x03,0xf4,0xe0,0xfd,0x7f,0xbc,0x7e,0xe1,0x12,0x96,0xbd,
+0x90,0x03,0xf5,0xe0,0xfd,0x7f,0xbd,0x7e,0xe1,0x12,0x96,0xbd,0x22,0x7f,0x58,0x7e,
+0xe6,0x12,0x96,0x64,0x90,0x04,0xc8,0xef,0xf0,0x7f,0x5a,0x7e,0xe6,0x12,0x96,0x64,
+0x90,0x04,0x91,0xef,0xf0,0x12,0x86,0x14,0x90,0x04,0xc8,0xe0,0xb4,0x07,0x00,0x40,
+0x03,0x02,0x3a,0xb6,0x90,0x39,0x5b,0xf8,0x28,0x28,0x73,0x02,0x39,0x70,0x02,0x39,
+0x73,0x02,0x39,0x9d,0x02,0x39,0xde,0x02,0x3a,0x06,0x02,0x3a,0x45,0x02,0x3a,0x77,
+0x02,0x3a,0xb6,0x90,0x05,0xf9,0xe0,0xc3,0x13,0xf0,0xa3,0xe0,0x13,0xf0,0x90,0x04,
+0x7b,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xe1,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0xfc,
+0xe0,0x25,0xe0,0xf0,0x90,0x05,0xfb,0xe0,0x33,0xf0,0x02,0x3a,0xd4,0x90,0x05,0xfa,
+0xe0,0x25,0xe0,0xff,0x90,0x05,0xf9,0xe0,0x33,0xfe,0x7c,0x00,0x7d,0x03,0x12,0x1c,
+0x62,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x7b,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xe1,
+0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0xfb,0xe0,0xfe,0xa3,0xe0,0xff,0x7c,0x00,0x7d,
+0x03,0x12,0x1c,0x50,0xee,0xc3,0x13,0xfe,0xef,0x13,0xff,0x02,0x3a,0xb0,0x90,0x05,
+0x50,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xf9,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x7c,
+0xe0,0x25,0xe0,0xfe,0x90,0x04,0x7b,0xe0,0x33,0x90,0x04,0xe1,0xf0,0xa3,0xce,0xf0,
+0x90,0x05,0x52,0x02,0x3a,0xc8,0x90,0x05,0xf9,0xe0,0xfe,0xa3,0xe0,0xff,0x7c,0x00,
+0x7d,0x03,0x12,0x1c,0x50,0xee,0xc3,0x13,0xfe,0xef,0x13,0xff,0x90,0x05,0xf9,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0x7b,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xe1,0xcf,0xf0,
+0xa3,0xef,0xf0,0x90,0x05,0xfc,0xe0,0x25,0xe0,0xff,0x90,0x05,0xfb,0xe0,0x33,0xfe,
+0x12,0x1c,0x62,0x80,0x6e,0x90,0x04,0x79,0xe0,0xc4,0xf8,0x54,0x0f,0xc8,0x68,0xfe,
+0x90,0x04,0x78,0xe0,0xc4,0x54,0xf0,0x48,0x90,0x05,0xf9,0xf0,0xa3,0xce,0xf0,0x90,
+0x04,0x7c,0xe0,0x25,0xe0,0xfe,0x90,0x04,0x7b,0xe0,0x33,0x90,0x04,0xe1,0xf0,0xa3,
+0xce,0xf0,0x90,0x05,0x58,0x80,0x51,0x90,0x05,0xf9,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x06,0x35,0xe0,0xfb,0xfd,0x7c,0x00,0x12,0x1c,0x62,0x90,0x05,0xf9,0xee,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0x7b,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xe1,0xcf,0xf0,0xa3,0xef,
+0xf0,0x90,0x05,0xfb,0xe0,0xfe,0xa3,0xe0,0xff,0xad,0x03,0x7c,0x00,0x12,0x1c,0x50,
+0x90,0x05,0xfb,0xee,0x80,0x1a,0x90,0x04,0x7b,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xe1,
+0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0xfb,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xfb,0xcf,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0x91,0xe0,0xb4,0x09,0x00,0x40,0x03,0x02,0x3b,0xc2,
+0x90,0x3a,0xe7,0xf8,0x28,0x28,0x73,0x02,0x3b,0x02,0x02,0x3b,0x10,0x02,0x3b,0x27,
+0x02,0x3b,0x3e,0x02,0x3b,0x54,0x02,0x3b,0x6a,0x02,0x3b,0x80,0x02,0x3b,0x96,0x02,
+0x3b,0xac,0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x0d,0xf0,0xd2,0x09,0x02,0x3b,0xc4,
+0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,
+0xa3,0x74,0x08,0xf0,0x02,0x3b,0xc4,0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x26,0xf0,
+0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,0xa3,0x74,0x10,0xf0,0x02,0x3b,0xc4,0x90,0x04,
+0x99,0xe4,0xf0,0xa3,0x74,0x2c,0xf0,0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,0xa3,0x74,
+0x18,0xf0,0x80,0x70,0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x32,0xf0,0xc2,0x09,0x90,
+0x04,0x8f,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0x80,0x5a,0x90,0x04,0x99,0xe4,0xf0,0xa3,
+0x74,0x38,0xf0,0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,0xa3,0x74,0x28,0xf0,0x80,0x44,
+0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x3e,0xf0,0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,
+0xa3,0x74,0x30,0xf0,0x80,0x2e,0x90,0x04,0x99,0xe4,0xf0,0xa3,0x74,0x44,0xf0,0xc2,
+0x09,0x90,0x04,0x8f,0xe4,0xf0,0xa3,0x74,0x38,0xf0,0x80,0x18,0x90,0x04,0x99,0xe4,
+0xf0,0xa3,0x74,0x4a,0xf0,0xc2,0x09,0x90,0x04,0x8f,0xe4,0xf0,0xa3,0x74,0x40,0xf0,
+0x80,0x02,0xd2,0x09,0x90,0x05,0x52,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xe8,0xcf,0xf0,
+0xa3,0xef,0xf0,0x90,0x05,0x50,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xea,0xcf,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,
+0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xe8,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,
+0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,0x90,0x03,0xec,
+0x12,0x1f,0xa6,0x90,0x03,0xea,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x90,
+0x03,0xec,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,
+0x12,0x1a,0x9a,0x90,0x05,0x50,0xee,0xf0,0xa3,0xef,0xf0,0xc3,0x90,0x04,0xdb,0xe0,
+0x9f,0x90,0x04,0xda,0xe0,0x9e,0x40,0x03,0x02,0x3d,0x0a,0x20,0x09,0x03,0x02,0x3d,
+0x0a,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x90,0x05,0x51,0xe0,0x9d,0xfe,0x90,0x05,0x50,
+0xe0,0x9c,0x90,0x03,0xf0,0xf0,0xa3,0xce,0xf0,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,
+0x05,0xc0,0x06,0xc0,0x07,0x90,0x05,0x50,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,
+0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,0x90,0x03,0xec,0x12,
+0x1f,0xa6,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,
+0xc0,0x05,0xc0,0x06,0xc0,0x07,0x7f,0xcd,0x7e,0xcc,0x7d,0x4c,0x7c,0x3f,0x90,0x03,
+0xec,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0xd0,
+0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,
+0xc0,0x07,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,
+0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x04,0x99,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0xdb,0xe0,0x24,0x01,0xfe,0x90,0x04,0xda,0xe0,0x34,
+0x00,0x90,0x05,0x50,0xf0,0xa3,0xce,0xf0,0x80,0x1a,0x90,0x04,0xda,0xe0,0xfe,0xa3,
+0xe0,0xff,0xd3,0x90,0x05,0x51,0xe0,0x9f,0x90,0x05,0x50,0xe0,0x9e,0x40,0x05,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0x72,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x05,0x50,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x18,0x38,0x90,
+0x04,0x8b,0x12,0x1f,0xa6,0x90,0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x05,0x52,
+0xec,0xf0,0xa3,0xed,0xf0,0x90,0x05,0x50,0xe0,0xfe,0xa3,0xe0,0xff,0x02,0x6e,0xf9,
+0xef,0x12,0x20,0x00,0x40,0x43,0x01,0x40,0x53,0x02,0x40,0x63,0x03,0x40,0x73,0x04,
+0x40,0x83,0x05,0x40,0x93,0x06,0x40,0xa3,0x07,0x40,0xb3,0x08,0x40,0xc3,0x09,0x40,
+0xd3,0x0a,0x40,0xe3,0x0c,0x40,0xf3,0x0d,0x41,0x03,0x0e,0x3e,0x8b,0x11,0x3e,0x8e,
+0x12,0x3e,0x91,0x13,0x3e,0x59,0x14,0x41,0x13,0x20,0x3f,0xe6,0x32,0x3f,0xec,0x33,
+0x3f,0xef,0x34,0x3f,0xf2,0x35,0x3f,0xf5,0x36,0x3f,0xff,0x37,0x3f,0xe0,0x38,0x3f,
+0xe3,0x39,0x3e,0xff,0x4f,0x40,0x3d,0x9c,0x40,0x40,0x9d,0x40,0x08,0xa0,0x40,0x0b,
+0xa1,0x40,0x0e,0xa2,0x40,0x37,0xa3,0x40,0x05,0xa8,0x40,0x02,0xa9,0x3e,0x9c,0xb0,
+0x41,0x0d,0xb4,0x41,0x10,0xb5,0x3f,0x02,0xb7,0x41,0x22,0xbe,0x3f,0x16,0xc0,0x3f,
+0x08,0xc1,0x3f,0x23,0xc2,0x3f,0x2a,0xc3,0x3f,0x30,0xc4,0x3f,0x37,0xc5,0x3f,0x4f,
+0xc7,0x3e,0xb1,0xc8,0x3e,0xae,0xc9,0x3f,0x52,0xca,0x3f,0x55,0xcb,0x3e,0x9f,0xd0,
+0x3e,0xa2,0xd5,0x3e,0xa5,0xdb,0x3e,0xa8,0xdc,0x3e,0xab,0xdd,0x3f,0x58,0xe3,0x3f,
+0x5e,0xe4,0x3f,0xbc,0xe6,0x3f,0xc2,0xe7,0x3f,0x64,0xe8,0x3f,0xc8,0xec,0x3f,0xce,
+0xed,0x3f,0xd4,0xee,0x3f,0xda,0xef,0x3e,0xdf,0xf0,0x3f,0x05,0xf1,0x3e,0xe2,0xf2,
+0x3e,0xe5,0xf3,0x3e,0xec,0xf4,0x3e,0xba,0xf5,0x3e,0xc4,0xf6,0x3e,0xb4,0xf7,0x3e,
+0xb7,0xf8,0x3e,0xf7,0xfb,0x00,0x00,0x41,0x64,0x90,0x05,0x35,0xe0,0xfd,0x7f,0x28,
+0x7e,0xe6,0x12,0x96,0xbd,0x90,0x05,0x35,0xa3,0xe0,0xfd,0x7f,0x29,0x7e,0xe6,0x12,
+0x96,0xbd,0x90,0x05,0x5a,0xe0,0xfd,0x7f,0x2a,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x05,
+0x5a,0xa3,0xe0,0xfd,0x7f,0x2b,0x7e,0xe6,0x02,0x41,0x61,0xd2,0xaf,0x22,0xc2,0xaf,
+0x22,0x90,0x06,0x3e,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x22,0x02,0x90,0x3e,0x02,
+0x88,0xa9,0x02,0x7f,0xba,0x02,0x95,0x70,0x02,0x97,0xe7,0x02,0x97,0xf5,0x02,0x94,
+0x72,0x02,0x96,0x1d,0x02,0x97,0x4c,0x02,0x97,0x5c,0x90,0x03,0xdc,0xe0,0xfe,0xa3,
+0xe0,0xff,0x80,0x0f,0x90,0x03,0xdc,0xe0,0xfe,0xa3,0xe0,0xff,0x7c,0xff,0x7d,0xff,
+0x12,0x1c,0x50,0x12,0x91,0xf3,0x90,0x03,0xdf,0xee,0xf0,0xa3,0xef,0xf0,0x22,0x02,
+0x97,0xa1,0x02,0x97,0xac,0x90,0x03,0xd9,0x74,0x01,0x80,0x0f,0x7d,0xdc,0x7c,0x00,
+0x7f,0x14,0x7e,0x00,0x02,0x92,0xbc,0xe4,0x90,0x03,0xd9,0xf0,0x02,0x97,0xcd,0x02,
+0x83,0x43,0x02,0x8d,0x07,0x02,0x95,0xfe,0x90,0x04,0xf3,0x74,0x01,0xf0,0xfd,0x7f,
+0x50,0x7e,0xe5,0x02,0x41,0x61,0xe4,0x90,0x04,0xf3,0xf0,0xfd,0x7f,0x50,0x7e,0xe5,
+0x02,0x41,0x61,0x90,0x04,0x6f,0x74,0x03,0xf0,0x22,0x90,0x04,0x6f,0x02,0x40,0x33,
+0x90,0x04,0x6f,0x74,0x02,0xf0,0x22,0x7f,0xb6,0x7e,0xeb,0x12,0x96,0x64,0x7e,0x00,
+0x90,0x03,0xdf,0xee,0xf0,0xa3,0xef,0xf0,0x7d,0x01,0x7c,0x00,0x02,0x6e,0xf9,0x02,
+0x39,0x2d,0x02,0x92,0xfd,0x02,0x96,0x72,0x90,0x04,0xfd,0x02,0x40,0x33,0xe4,0x90,
+0x04,0xfd,0xf0,0x22,0x12,0x7e,0x25,0x90,0x02,0x08,0xe0,0x70,0x03,0x02,0x41,0x64,
+0x90,0x01,0xc4,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x03,0xe1,0xf0,0xfd,0xeb,0xa3,
+0xf0,0x90,0x01,0x59,0xe0,0xfa,0xa3,0xe0,0xfb,0xea,0x90,0x03,0xe3,0xf0,0xeb,0xa3,
+0xf0,0x7f,0xb8,0x7e,0xe1,0x12,0x96,0xbd,0x90,0x03,0xe2,0xe0,0xfd,0x7f,0xb9,0x7e,
+0xe1,0x12,0x96,0xbd,0x90,0x03,0xe3,0xe0,0xfd,0x7f,0xbc,0x7e,0xe1,0x12,0x96,0xbd,
+0x90,0x03,0xe4,0xe0,0xfd,0x7f,0xbd,0x7e,0xe1,0x02,0x41,0x61,0x12,0x8c,0x17,0xd2,
+0x01,0x22,0x12,0x77,0xe8,0xc2,0x01,0x22,0x12,0x98,0x01,0xd2,0x04,0x22,0x12,0x98,
+0x02,0xc2,0x04,0x22,0x12,0x00,0x0a,0xd2,0x03,0x22,0x12,0x91,0x64,0xc2,0x03,0x22,
+0xd2,0x01,0x22,0xc2,0x01,0x22,0x12,0x98,0x03,0xd2,0x00,0x22,0xc2,0x00,0x22,0xd2,
+0x05,0x22,0xc2,0x05,0x22,0x7f,0x01,0x7e,0x00,0x12,0x94,0x9f,0xd2,0x06,0x22,0xc2,
+0x06,0x22,0xd2,0x02,0x22,0x02,0x85,0x63,0x02,0x8f,0xee,0x02,0x96,0x3c,0x7f,0x28,
+0x7e,0xe6,0x12,0x96,0x64,0x90,0x05,0xcb,0xef,0xf0,0x14,0x70,0x03,0x02,0x41,0x64,
+0x24,0xcf,0x70,0x03,0x02,0x41,0x64,0x24,0xf6,0x70,0x03,0x02,0x41,0x64,0x80,0x00,
+0x90,0x05,0xcb,0x74,0x01,0xf0,0x22,0xe4,0x90,0x05,0xcb,0xf0,0x22,0x02,0x97,0xee,
+0x02,0x97,0xd6,0x90,0x04,0xf2,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x04,0xf2,
+0xef,0xf0,0x22,0x90,0x04,0xf7,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x04,0xf7,
+0xef,0xf0,0x22,0x90,0x04,0xfc,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x04,0xfc,
+0xef,0xf0,0x22,0x90,0x05,0x01,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x01,
+0xef,0xf0,0x22,0x90,0x05,0x06,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x06,
+0xef,0xf0,0x22,0x90,0x05,0x0b,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x0b,
+0xef,0xf0,0x22,0x90,0x05,0x10,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x10,
+0xef,0xf0,0x22,0x90,0x05,0x15,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x15,
+0xef,0xf0,0x22,0x90,0x05,0x1a,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x1a,
+0xef,0xf0,0x22,0x90,0x05,0x1f,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x1f,
+0xef,0xf0,0x22,0x90,0x05,0x24,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x24,
+0xef,0xf0,0x22,0x90,0x05,0x34,0xe0,0x7f,0x00,0x70,0x02,0x7f,0x01,0x90,0x05,0x34,
+0xef,0xf0,0x22,0x7f,0x80,0x7e,0xe6,0x12,0x96,0x64,0x8f,0x8d,0x22,0x02,0x97,0xb7,
+0x02,0x97,0xc2,0x7f,0x28,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,0xe1,0xef,0xf0,0x02,
+0x5e,0x07,0x7d,0xff,0x7f,0x71,0x7e,0xed,0x12,0x96,0xbd,0x7f,0xe8,0x7e,0x03,0x7d,
+0x00,0x7c,0x00,0x12,0x96,0xcb,0x7f,0x28,0x7e,0xe6,0x12,0x96,0x64,0x90,0x05,0xd8,
+0xef,0xf0,0x12,0x89,0x46,0x7f,0xe8,0x7e,0x03,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,
+0x7f,0xe8,0x7e,0x03,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0xe4,0xfd,0x7f,0x71,0x7e,
+0xed,0x12,0x96,0xbd,0x22,0x90,0x03,0xe9,0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xec,0xf0,
+0xa3,0xed,0xf0,0xeb,0x60,0x03,0x02,0x42,0xa6,0x90,0x05,0x47,0xe0,0x64,0xdb,0x60,
+0x03,0x02,0x42,0x05,0x90,0x03,0xeb,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0xfd,0xee,
+0x94,0x01,0x50,0x0e,0x90,0x06,0x34,0xe0,0x70,0x08,0x90,0x03,0xed,0x04,0xf0,0x02,
+0x42,0xab,0xc3,0xef,0x94,0xfa,0xee,0x94,0x03,0x50,0x09,0x90,0x06,0x34,0xe0,0x70,
+0x03,0x02,0x42,0x9e,0x90,0x03,0xe9,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0x0d,0xee,
+0x94,0x00,0x40,0x0b,0xd3,0xef,0x94,0x50,0xee,0x94,0x00,0x50,0x02,0x80,0x4f,0xd3,
+0xef,0x94,0x50,0xee,0x94,0x00,0x40,0x0b,0xd3,0xef,0x94,0xa0,0xee,0x94,0x00,0x50,
+0x02,0x80,0x56,0xd3,0xef,0x94,0xa0,0xee,0x94,0x00,0x40,0x0b,0xd3,0xef,0x94,0xe0,
+0xee,0x94,0x00,0x50,0x02,0x80,0x5c,0xd3,0xef,0x94,0xe0,0xee,0x94,0x00,0x50,0x03,
+0x02,0x42,0xab,0x80,0x5f,0x90,0x03,0xe9,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0x0d,
+0xee,0x94,0x00,0x40,0x12,0xd3,0xef,0x94,0x50,0xee,0x94,0x00,0x50,0x09,0x90,0x03,
+0xed,0x74,0x03,0xf0,0x02,0x42,0xab,0xd3,0xef,0x94,0x50,0xee,0x94,0x00,0x40,0x11,
+0xd3,0xef,0x94,0xa0,0xee,0x94,0x00,0x50,0x08,0x90,0x03,0xed,0x74,0x04,0xf0,0x80,
+0x6a,0xd3,0xef,0x94,0xa0,0xee,0x94,0x00,0x40,0x11,0xd3,0xef,0x94,0xe0,0xee,0x94,
+0x00,0x50,0x08,0x90,0x03,0xed,0x74,0x05,0xf0,0x80,0x50,0xd3,0xef,0x94,0xe0,0xee,
+0x94,0x00,0x40,0x08,0x90,0x03,0xed,0x74,0x06,0xf0,0x80,0x3f,0x90,0x04,0xe1,0xe0,
+0xfe,0xa3,0xe0,0xff,0x7c,0x00,0x7d,0x03,0x12,0x1c,0x62,0x90,0x03,0xeb,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xd3,0x9f,0xec,0x9e,0x50,0x06,0xa3,0x74,0x01,0xf0,0x80,0x1c,0x90,
+0x04,0xe1,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0xed,0x9f,0xec,0x9e,0x50,0x0d,0x90,0x03,
+0xed,0x74,0x02,0xf0,0x80,0x05,0x90,0x03,0xed,0xeb,0xf0,0x90,0x03,0xed,0xe0,0x24,
+0xfe,0x60,0x23,0x14,0x70,0x03,0x02,0x43,0x47,0x14,0x70,0x03,0x02,0x43,0xb7,0x14,
+0x70,0x03,0x02,0x44,0x31,0x14,0x70,0x03,0x02,0x44,0xaa,0x24,0x05,0x60,0x03,0x02,
+0x45,0x28,0x7d,0xfd,0x80,0x02,0x7d,0x80,0x7f,0xe3,0x7e,0xe1,0x12,0x96,0xbd,0x7d,
+0x26,0x7f,0xea,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0xe1,0x7f,0xee,0x7e,0xe1,0x12,0x96,
+0xbd,0x7d,0x66,0x7f,0xf2,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x88,0x7f,0xf3,0x7e,0xe1,
+0x12,0x96,0xbd,0x7d,0x28,0x7f,0x18,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x32,0x7f,0x1b,
+0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x0a,0x7f,0x1f,0x7e,0xe5,0x12,0x96,0xbd,0xe4,0xfd,
+0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,
+0xe4,0xfd,0x7f,0x52,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x64,0x7f,0x21,0x7e,0xf0,0x12,
+0x96,0xbd,0x7d,0x01,0x02,0x44,0x25,0x7d,0x80,0x7f,0xe3,0x7e,0xe1,0x12,0x96,0xbd,
+0x7d,0x26,0x7f,0xea,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0xe1,0x7f,0xee,0x7e,0xe1,0x12,
+0x96,0xbd,0x7d,0x66,0x7f,0xf2,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x88,0x7f,0xf3,0x7e,
+0xe1,0x12,0x96,0xbd,0x7d,0x28,0x7f,0x18,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x32,0x7f,
+0x1b,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x0a,0x7f,0x1f,0x7e,0xe5,0x12,0x96,0xbd,0xe4,
+0xfd,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,
+0xbd,0xe4,0xfd,0x7f,0x52,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x64,0x7f,0x21,0x7e,0xf0,
+0x12,0x96,0xbd,0x7d,0x04,0x80,0x6e,0x7d,0x80,0x7f,0xe3,0x7e,0xe1,0x12,0x96,0xbd,
+0x7d,0x26,0x7f,0xea,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0xd9,0x7f,0xee,0x7e,0xe1,0x12,
+0x96,0xbd,0x7d,0x51,0x7f,0xf2,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x88,0x7f,0xf3,0x7e,
+0xe1,0x12,0x96,0xbd,0x7d,0x28,0x7f,0x18,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x32,0x7f,
+0x1b,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x0a,0x7f,0x1f,0x7e,0xe5,0x12,0x96,0xbd,0xe4,
+0xfd,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,
+0xbd,0xe4,0xfd,0x7f,0x52,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0xff,0x7f,0x21,0x7e,0xf0,
+0x12,0x96,0xbd,0x7d,0x20,0x7f,0x23,0x7e,0xf0,0x12,0x96,0xbd,0x7d,0x20,0x02,0x45,
+0x21,0x7d,0x80,0x7f,0xe3,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x26,0x7f,0xea,0x7e,0xe1,
+0x12,0x96,0xbd,0x7d,0xd9,0x7f,0xee,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x51,0x7f,0xf2,
+0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x88,0x7f,0xf3,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x28,
+0x7f,0x18,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x32,0x7f,0x1b,0x7e,0xe5,0x12,0x96,0xbd,
+0x7d,0x0a,0x7f,0x1f,0x7e,0xe5,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x50,0x7e,0xe3,0x12,
+0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x52,0x7e,
+0xe3,0x12,0x96,0xbd,0x7d,0xff,0x7f,0x21,0x7e,0xf0,0x12,0x96,0xbd,0x7d,0x30,0x7f,
+0x23,0x7e,0xf0,0x12,0x96,0xbd,0x7d,0x22,0x80,0x77,0x7d,0x80,0x7f,0xe3,0x7e,0xe1,
+0x12,0x96,0xbd,0x7d,0x80,0x7f,0xea,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x80,0x7f,0xee,
+0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x51,0x7f,0xf2,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x76,
+0x7f,0xf3,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x66,0x7f,0x18,0x7e,0xe5,0x12,0x96,0xbd,
+0x7d,0x14,0x7f,0x1b,0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x01,0x7f,0x1f,0x7e,0xe5,0x12,
+0x96,0xbd,0xe4,0xfd,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,
+0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x52,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0xff,0x7f,
+0x21,0x7e,0xf0,0x12,0x96,0xbd,0x7d,0x40,0x7f,0x23,0x7e,0xf0,0x12,0x96,0xbd,0x7d,
+0x22,0x7f,0x04,0x7e,0xe0,0x12,0x96,0xbd,0x22,0x90,0x04,0xfc,0xe0,0x60,0x03,0x02,
+0x48,0xdd,0x90,0x03,0xc9,0xe0,0xc3,0x94,0x02,0x50,0x03,0x02,0x48,0xdd,0x90,0x03,
+0x2a,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xfb,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x03,0x32,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0x2c,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0x2f,0xff,0xea,0x3e,0xfe,0xe9,0x3d,0xfd,
+0xe8,0x3c,0xfc,0xe4,0x7b,0x03,0xfa,0xf9,0xf8,0x12,0x1d,0x9c,0xe4,0x7b,0x02,0xfa,
+0xf9,0xf8,0x12,0x1e,0x27,0x90,0x03,0xfd,0x12,0x1f,0xa6,0xe4,0x90,0x03,0xf9,0xf0,
+0xa3,0xf0,0x90,0x03,0x2a,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x01,0xcf,0xf0,0xa3,0xef,
+0xf0,0x90,0x03,0x32,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x03,0x2c,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0x2f,0xff,0xea,0x3e,
+0xfe,0xe9,0x3d,0xfd,0xe8,0x3c,0xfc,0xe4,0x7b,0x03,0xfa,0xf9,0xf8,0x12,0x1d,0x9c,
+0xe4,0x7b,0x02,0xfa,0xf9,0xf8,0x12,0x1e,0x27,0x90,0x04,0x03,0x12,0x1f,0xa6,0x90,
+0x03,0xf7,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xc6,0xe0,0x24,0xff,0xff,0x90,0x03,
+0xc5,0xe0,0x34,0xff,0xfe,0x90,0x03,0xf7,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xee,
+0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x40,0x03,0x02,0x47,0x54,0x90,0x03,0x2c,0x75,
+0xf0,0x06,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x03,0x26,0x75,0xf0,0x06,
+0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,
+0x38,0xfc,0x90,0x03,0xf7,0xe0,0xfa,0xa3,0xe0,0x90,0x03,0x32,0x75,0xf0,0x06,0x12,
+0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0x2f,0xff,0xea,0x3e,0xfe,0xe9,0x3d,0xfd,0xe8,0x3c,0xfc,
+0x90,0x04,0x07,0x12,0x1f,0xa6,0x90,0x03,0xfd,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,
+0xfe,0xa3,0xe0,0xff,0x90,0x04,0x07,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x40,0x42,0x90,0x03,0xf7,0xe0,0xfa,0xa3,0xe0,0xfb,
+0x90,0x03,0x2a,0x75,0xf0,0x06,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,0x25,0x83,
+0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xfb,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x04,
+0x07,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xfd,0x12,
+0x1f,0xa6,0x90,0x03,0xf9,0xea,0xf0,0xa3,0xeb,0xf0,0x90,0x04,0x03,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,0xea,0x50,0x39,0x90,0x03,0xf7,0xe0,0xfe,0xa3,
+0xe0,0x90,0x03,0x2a,0x75,0xf0,0x06,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x06,0xa4,0x25,
+0x83,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x01,0xcf,0xf0,0xa3,0xef,0xf0,0x90,
+0x04,0x07,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x03,
+0x12,0x1f,0xa6,0x90,0x03,0xf8,0xe0,0x04,0xf0,0x70,0x06,0x90,0x03,0xf7,0xe0,0x04,
+0xf0,0x02,0x45,0xe7,0x90,0x03,0xf7,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0x2c,0x75,
+0xf0,0x06,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x03,0x26,0x75,0xf0,0x06,0xef,
+0x12,0x1f,0xf4,0xee,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0x2b,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,
+0xfc,0xe4,0x7b,0x03,0xfa,0xf9,0xf8,0x12,0x1d,0x9c,0xe4,0x7b,0x02,0xfa,0xf9,0xf8,
+0x12,0x1e,0x27,0x90,0x04,0x07,0x12,0x1f,0xa6,0x90,0x03,0xfd,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x07,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x40,0x48,0x90,0x03,0xf7,0xe0,0xfe,
+0xa3,0xe0,0x90,0x03,0x2a,0x75,0xf0,0x06,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x06,0xa4,
+0x25,0x83,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xfb,0xcf,0xf0,0xa3,0xef,0xf0,
+0x90,0x04,0x07,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,
+0xfd,0x12,0x1f,0xa6,0x90,0x03,0xc5,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xf9,0xcf,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0x03,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0xa3,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,
+0xea,0x50,0x39,0x90,0x03,0xf7,0xe0,0xfe,0xa3,0xe0,0x90,0x03,0x2a,0x75,0xf0,0x06,
+0x12,0x1f,0xf4,0xee,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xff,0xa3,0xe0,
+0x90,0x04,0x01,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x07,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x03,0x12,0x1f,0xa6,0x90,0x03,0xc9,0xe0,
+0x24,0xfd,0x50,0x02,0x80,0x57,0x90,0x04,0x03,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,
+0xfe,0xa3,0xe0,0xff,0x90,0x04,0x13,0x12,0x1f,0xa6,0x90,0x03,0xfd,0x12,0x70,0x88,
+0xe4,0xfb,0xfa,0x79,0xa0,0x78,0x41,0x12,0x19,0xde,0x60,0x31,0x40,0x2f,0xe4,0xff,
+0xfe,0x7d,0x20,0xfc,0x90,0x03,0xfd,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,
+0xe0,0xfb,0xc3,0x12,0x1e,0xea,0x50,0x15,0x90,0x03,0xdb,0xe0,0x94,0x19,0x90,0x03,
+0xda,0xe0,0x64,0x80,0x94,0x80,0x40,0x05,0xe4,0x90,0x03,0xca,0xf0,0x90,0x03,0xc0,
+0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x90,0x04,0x0e,0xee,0xf0,0xa3,0xef,0xf0,0x20,0x02,
+0x03,0x02,0x4c,0x6c,0x90,0x04,0x0e,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x7c,0x73,0x90,
+0x04,0x10,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0x90,0x02,0x95,0xf0,0xa3,0xf0,0xa3,0xf0,
+0xa3,0xf0,0x90,0x02,0x82,0xf0,0xa3,0xf0,0x90,0x04,0x10,0xe0,0xfe,0xa3,0xe0,0x90,
+0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xab,0x07,0xaa,0x06,0x90,0x04,0x10,0xe0,0xfe,0xa3,
+0xe0,0x90,0x02,0x0d,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,
+0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0x90,
+0x02,0x82,0xf0,0xa3,0xef,0xf0,0xfd,0xac,0x06,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,
+0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,
+0x10,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,
+0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,
+0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,
+0x12,0x1a,0x9a,0x90,0x02,0x95,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x82,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,
+0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x10,0xe0,0xfe,0xa3,0xe0,0x90,
+0x02,0x0b,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,
+0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x02,0x97,
+0xee,0xf0,0xfc,0xa3,0xef,0xf0,0xfd,0x90,0x02,0x82,0xe0,0xfa,0xa3,0xe0,0x90,0x04,
+0x0e,0x12,0x4c,0x6d,0x90,0x04,0x14,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x09,0xe0,
+0xfd,0xa3,0xe0,0x90,0x04,0x16,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0b,0xe0,0xfd,
+0xa3,0xe0,0x90,0x04,0x18,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0d,0xe0,0xfd,0xa3,
+0xe0,0x90,0x04,0x1a,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x0f,0xe0,0xfd,0xa3,0xe0,
+0x90,0x04,0x1c,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x14,0xe0,0xfc,0xa3,0xe0,0xfd,
+0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,
+0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x02,0x09,0xcb,0xf0,0xa3,0xeb,0xf0,0xa3,0x75,
+0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfd,0xa3,0xe0,0x90,0x02,0x0b,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x14,0xa3,0xe0,
+0xfd,0x90,0x02,0x0d,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,
+0x83,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x02,0x0d,0xcb,0xf0,0xa3,0xeb,0xf0,0xa3,
+0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,
+0xe0,0xfd,0xa3,0xe0,0x90,0x02,0x0f,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x09,0x75,
+0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfe,0xa3,0xe0,0xff,0xab,0x07,0xaa,0x06,0x90,0x04,0x14,0xe0,0xfe,0xa3,0xe0,0x90,
+0x02,0x0d,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,
+0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0x90,0x02,0x82,
+0xf0,0xa3,0xef,0xf0,0xfd,0xac,0x06,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0xf9,0x78,
+0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x14,0xe0,
+0xfe,0xa3,0xe0,0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,
+0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,
+0x9a,0x90,0x02,0x95,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x82,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xec,0x12,0x1a,0x61,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,
+0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x14,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x0b,
+0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,
+0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,
+0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x02,0x97,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0x16,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x14,0xe0,0xfc,
+0xa3,0xe0,0xfd,0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x18,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x02,0x0b,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x1a,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x02,0x0d,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x1c,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x02,0x0f,0x75,0xf0,0x0a,0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,0xa3,0xef,0xf0,0xc2,0x02,0x22,0xfb,0xe0,0xff,
+0xa3,0xe0,0x90,0x04,0x29,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x95,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x04,0x23,0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xec,0xf0,0xa3,0xed,0xf0,
+0x90,0x04,0x3d,0xe4,0xf0,0xa3,0x74,0x0b,0xf0,0xae,0x02,0xaf,0x03,0xad,0x07,0xac,
+0x06,0xec,0x12,0x1a,0x61,0x7b,0xcd,0x7a,0xcc,0x79,0x4c,0x78,0x3e,0x12,0x18,0x38,
+0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0xee,0x33,0x95,0xe0,
+0xfd,0xfc,0x90,0x04,0x2d,0x12,0x1f,0xa6,0x90,0x04,0x2d,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xfb,0x12,0x1d,0x9c,
+0x90,0x04,0x2d,0x12,0x1f,0xa6,0xe4,0x90,0x04,0x2b,0xf0,0xa3,0xf0,0x90,0x04,0x29,
+0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xee,0x64,0x80,
+0xf8,0xec,0x64,0x80,0x98,0x40,0x03,0x02,0x4f,0x9f,0x90,0x02,0x09,0x75,0xf0,0x0a,
+0xed,0x12,0x1f,0xf4,0xec,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,
+0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,0xf9,0xf8,0x90,0x04,0x2b,0xe0,0xfe,0xa3,
+0xe0,0x90,0x02,0x0d,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,
+0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc3,0xef,
+0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0x12,0x1a,0x5c,0xe4,0xfb,
+0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,
+0x04,0x2b,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x09,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,
+0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,
+0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,
+0x47,0x12,0x1a,0x9a,0x90,0x04,0x39,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x2b,0xe0,
+0xfe,0xa3,0xe0,0x90,0x02,0x0b,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,
+0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,
+0xf9,0xf8,0x90,0x04,0x2b,0xe0,0xfe,0xa3,0xe0,0x90,0x02,0x0f,0x75,0xf0,0x0a,0x12,
+0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,
+0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,
+0xec,0x98,0xfc,0x12,0x1a,0x5c,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,0x18,0x38,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x2b,0xe0,0xfe,0xa3,0xe0,0x90,0x02,
+0x0b,0x75,0xf0,0x0a,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,
+0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0x12,0x1a,0x5c,0xd0,0x03,
+0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x04,0x3b,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x04,0x25,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,
+0xfd,0xfc,0xc0,0x06,0xc0,0x07,0x90,0x04,0x3b,0xe0,0xfe,0xa3,0xe0,0xfb,0xaa,0x06,
+0xea,0x33,0x95,0xe0,0xf9,0xf8,0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,
+0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,
+0x04,0x25,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x3b,0xa3,0xea,0x33,0x95,0xe0,0xf9,0xf8,0xd0,0x07,0xd0,0x06,0xc3,
+0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0x12,0x1d,0x9c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,
+0x04,0x23,0xe0,0xfe,0xa3,0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x39,0xe0,0xfe,0xa3,0xe0,0xfb,0xaa,0x06,0xea,0x33,0x95,0xe0,0xf9,
+0xf8,0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,0xfe,0xed,0x99,0xfd,0xec,
+0x98,0xfc,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x23,0xe0,0xfe,0xa3,
+0xe0,0xff,0xee,0x33,0x95,0xe0,0xfd,0xfc,0xc0,0x06,0xc0,0x07,0x90,0x04,0x39,0xa3,
+0xea,0x33,0x95,0xe0,0xf9,0xf8,0xd0,0x07,0xd0,0x06,0xc3,0xef,0x9b,0xff,0xee,0x9a,
+0xfe,0xed,0x99,0xfd,0xec,0x98,0xfc,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,
+0x1d,0x9c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0xef,0x2b,0xff,0xee,0x3a,0xfe,
+0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x04,0x31,0x12,0x1f,0xa6,0x90,0x04,0x2d,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,0xd4,0x50,0x0f,0x90,0x04,0x2b,0xe0,
+0xff,0xa3,0xe0,0x90,0x04,0x3d,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x2c,0xe0,0x04,
+0xf0,0x60,0x03,0x02,0x4c,0xed,0x90,0x04,0x2b,0xe0,0x04,0xf0,0x02,0x4c,0xed,0x90,
+0x04,0x3d,0xe0,0x70,0x04,0xa3,0xe0,0x64,0x0b,0x70,0x06,0x90,0x04,0x3d,0xf0,0xa3,
+0xf0,0x90,0x04,0x3d,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x41,0x05,0x34,0x01,0xc1,0x0b,
+0x42,0x05,0x35,0x00,0x00,0x42,0x05,0x5a,0x50,0x00,0x60,0x64,0x01,0x5b,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x60,0x60,0x00,0xf5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x95,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x35,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x01,
+0xc2,0x06,0xa8,0x42,0x01,0x57,0x05,0x6f,0x42,0x01,0xc4,0x06,0xa8,0x42,0x01,0x59,
+0x05,0x6f,0x60,0x30,0x01,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x02,
+0x00,0x03,0x00,0x04,0x00,0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0a,
+0x00,0x0b,0x00,0x0c,0x00,0x0d,0x00,0x0e,0x00,0x0f,0x00,0x10,0x00,0x11,0x00,0x12,
+0x00,0x13,0x00,0x14,0x00,0x15,0x00,0x16,0x00,0x17,0x42,0x01,0x55,0x00,0x00,0x41,
+0x01,0xc1,0x00,0x41,0x00,0x00,0x01,0x42,0x04,0xe1,0x03,0xff,0x42,0x04,0xc9,0x01,
+0xf4,0x42,0x04,0x6d,0x00,0x20,0x42,0x04,0x70,0x02,0x00,0x42,0x04,0x99,0x00,0x20,
+0x48,0x04,0xe4,0x00,0x14,0x00,0x14,0x00,0x14,0x00,0x14,0x42,0x04,0x97,0x00,0x00,
+0x42,0x04,0xc6,0x00,0x00,0x42,0x04,0x87,0x00,0x38,0x42,0x04,0x89,0x00,0x00,0x44,
+0x04,0x8b,0x4a,0x37,0x1b,0x00,0x44,0x04,0x69,0x00,0x00,0x00,0x00,0x44,0x04,0x83,
+0x00,0x00,0x00,0x00,0x41,0x04,0x7a,0x00,0x41,0x04,0xb9,0x00,0xc1,0x08,0x46,0x04,
+0xba,0x1f,0x01,0x00,0x00,0x00,0x00,0x41,0x04,0x6f,0x03,0xc1,0x89,0x42,0x04,0x74,
+0x00,0x00,0x42,0x04,0x93,0x00,0x01,0x42,0x04,0xcb,0x00,0x01,0x42,0x04,0x95,0x00,
+0x00,0x42,0x04,0xd8,0x00,0x00,0x42,0x04,0x8f,0x00,0x00,0x41,0x04,0x92,0x01,0x42,
+0x04,0xdc,0x02,0x00,0x41,0x04,0xe0,0x01,0x41,0x04,0xe3,0x00,0x42,0x04,0xc4,0x00,
+0x00,0x42,0x04,0x9b,0x00,0x00,0x41,0x03,0xd5,0x00,0x41,0x03,0xd6,0x00,0x42,0x03,
+0xdc,0x00,0x01,0x41,0x03,0xd9,0x01,0x41,0x03,0xca,0x00,0x41,0x05,0xca,0x00,0x41,
+0x05,0xd9,0x3c,0x41,0x05,0xc7,0x00,0x41,0x05,0xcb,0x01,0x41,0x05,0xd8,0x00,0x41,
+0x05,0xd2,0x00,0x41,0x06,0x5f,0x01,0x41,0x06,0x33,0x00,0x41,0x06,0x31,0x00,0x41,
+0x06,0x34,0x00,0x41,0x06,0x3d,0x01,0x44,0x06,0x3e,0x00,0x00,0x00,0x00,0x41,0x06,
+0x42,0x00,0x42,0x06,0x43,0x00,0x00,0xc1,0x04,0xc1,0x03,0xc1,0x01,0xc1,0x06,0xc1,
+0x02,0xc1,0x05,0xc1,0x00,0x42,0x03,0x1a,0x00,0x00,0x42,0x03,0x0c,0x00,0x00,0x42,
+0x03,0x17,0x00,0x00,0x00,0xe4,0x90,0x03,0xeb,0xf0,0xa3,0xf0,0x90,0x03,0xdb,0xe0,
+0x04,0xf0,0x70,0x06,0x90,0x03,0xda,0xe0,0x04,0xf0,0xd3,0x90,0x03,0xd8,0xe0,0x94,
+0x00,0x90,0x03,0xd7,0xe0,0x64,0x80,0x94,0x80,0x40,0x0d,0xa3,0xe0,0x24,0xff,0xf0,
+0x90,0x03,0xd7,0xe0,0x34,0xff,0xf0,0x22,0x12,0x6a,0x41,0x90,0x05,0xf5,0x12,0x1f,
+0xa6,0x90,0x03,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x05,0xf5,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,
+0xea,0x40,0x23,0x90,0x05,0xf5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0x90,0x03,0x22,0x12,0x1f,0xa6,0x90,0x03,0x1c,0xe0,0xff,0xa3,0xe0,0x90,0x03,
+0xc0,0xcf,0xf0,0xa3,0xef,0xf0,0x12,0x73,0x4c,0xef,0x60,0x0e,0x90,0x03,0xd9,0xe0,
+0x60,0x08,0x90,0x03,0xeb,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xd1,0xe0,0xfe,0xa3,
+0xe0,0xff,0xc3,0x90,0x03,0x1d,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0x1c,0xe0,
+0x64,0x80,0x98,0x40,0x08,0x90,0x03,0xeb,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xeb,
+0xe0,0x70,0x02,0xa3,0xe0,0x70,0x03,0x02,0x55,0x97,0x90,0x03,0xc9,0xe0,0x24,0xfe,
+0x70,0x67,0x12,0x45,0x29,0x90,0x03,0xed,0x12,0x95,0x49,0x90,0x03,0xc1,0xe0,0x2f,
+0xff,0x90,0x03,0xc0,0xe0,0x3e,0xfe,0x90,0x03,0xe9,0xf0,0xa3,0xef,0xf0,0x90,0x03,
+0xc0,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x82,0x8e,0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,
+0xf0,0x12,0x95,0xfe,0x90,0x03,0xd6,0x74,0x02,0xf0,0x90,0x05,0xd2,0xe0,0x24,0xfb,
+0x24,0xfd,0x50,0x03,0x02,0x56,0x0d,0x90,0x04,0x78,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,
+0x05,0x50,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x9d,0xee,0x9c,0x50,0x03,0x02,0x56,0x0d,
+0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x02,0x6e,0xf9,0x90,0x03,0xc9,0xe0,0x04,0xff,0x12,
+0x96,0x89,0x90,0x03,0xf3,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xc9,0xe0,0x04,0xff,
+0x12,0x95,0xde,0x90,0x03,0xc3,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x45,0x29,0x90,0x03,
+0xf1,0x12,0x95,0x49,0xaa,0x06,0xab,0x07,0x90,0x03,0xf3,0xe0,0xfe,0xa3,0xe0,0xff,
+0x7c,0x00,0x7d,0x02,0x12,0x1c,0xb7,0xc3,0x90,0x03,0xc1,0xe0,0x9f,0xff,0x90,0x03,
+0xc0,0xe0,0x9e,0xcf,0x2b,0xcf,0x3a,0x90,0x03,0xed,0xf0,0xfc,0xa3,0xef,0xf0,0xfd,
+0x90,0x03,0xf4,0xe0,0x2d,0xfe,0x90,0x03,0xf3,0xe0,0x3c,0x90,0x03,0xef,0xf0,0xa3,
+0xce,0xf0,0xd3,0x90,0x03,0xcc,0xe0,0x9d,0xec,0x64,0x80,0xf8,0x90,0x03,0xcb,0xe0,
+0x64,0x80,0x98,0x50,0x0f,0x90,0x03,0xed,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xcb,0xcf,
+0xf0,0xa3,0xef,0xf0,0x90,0x03,0xd1,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xef,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xd3,0x9f,0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x50,0x08,
+0x90,0x03,0xd1,0xec,0xf0,0xa3,0xed,0xf0,0xd3,0x90,0x03,0xc4,0xe0,0x94,0x00,0x90,
+0x03,0xc3,0xe0,0x64,0x80,0x94,0x80,0x40,0x05,0x90,0x03,0xcb,0x80,0x03,0x90,0x03,
+0xd1,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xe9,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xd7,
+0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xe9,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xff,0xec,0x9e,0xfe,0xc3,0x64,0x80,0x94,0x80,
+0x50,0x09,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,0x80,0x0f,0x90,0x03,0x1c,0xe0,0xfe,
+0xa3,0xe0,0xff,0xc3,0xed,0x9f,0xff,0xec,0x9e,0xfe,0x90,0x03,0xf5,0xee,0xf0,0xa3,
+0xef,0xf0,0xd3,0x94,0x50,0xee,0x64,0x80,0x94,0x80,0x40,0x10,0x90,0x03,0xd8,0xe0,
+0x04,0xf0,0x70,0x27,0x90,0x03,0xd7,0xe0,0x04,0xf0,0x80,0x1f,0xd3,0x90,0x03,0xf6,
+0xe0,0x94,0x96,0x90,0x03,0xf5,0xe0,0x64,0x80,0x94,0x80,0x40,0x0e,0x90,0x03,0xd8,
+0xe0,0x24,0x02,0xf0,0x90,0x03,0xd7,0xe0,0x34,0x00,0xf0,0x90,0x03,0x22,0x12,0x1f,
+0xb2,0x00,0x00,0x00,0x00,0xe4,0x90,0x03,0xd3,0xf0,0xa3,0xf0,0x90,0x03,0xc9,0xe0,
+0x04,0xf0,0x12,0x91,0xac,0x80,0x62,0x90,0x03,0xc3,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,
+0x03,0x1d,0xe0,0x2b,0xfe,0x90,0x03,0x1c,0xe0,0x3a,0x90,0x03,0xe9,0xf0,0xa3,0xce,
+0xf0,0xd3,0xeb,0x94,0x00,0xea,0x64,0x80,0x94,0x80,0x40,0x1d,0x90,0x03,0xd1,0xe0,
+0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x03,0xea,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,
+0xe9,0xe0,0x64,0x80,0x98,0x40,0x22,0x80,0x1b,0x90,0x03,0xcb,0xe0,0xfe,0xa3,0xe0,
+0xff,0xc3,0x90,0x03,0xea,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0xe9,0xe0,0x64,
+0x80,0x98,0x50,0x05,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe9,0x12,0x82,0x89,0x90,
+0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xd6,0x74,0x01,0xf0,0x22,0x90,0x05,
+0xf5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf1,0x12,
+0x1f,0xa6,0x12,0x6a,0x41,0x90,0x05,0xf5,0x12,0x1f,0xa6,0xd3,0x90,0x03,0xc8,0xe0,
+0x94,0x00,0x90,0x03,0xc7,0xe0,0x64,0x80,0x94,0x80,0x40,0x0d,0xa3,0xe0,0x24,0xff,
+0xf0,0x90,0x03,0xc7,0xe0,0x34,0xff,0xf0,0x22,0x90,0x03,0xc2,0xe0,0x14,0x70,0x03,
+0x02,0x56,0xe2,0x14,0x70,0x03,0x02,0x56,0xff,0x14,0x70,0x03,0x02,0x57,0x45,0x24,
+0x03,0x60,0x03,0x02,0x58,0xdb,0x90,0x03,0x20,0xe4,0xf0,0xa3,0x74,0x08,0xf0,0x90,
+0x03,0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0x32,0xee,0x64,0x80,0x94,0x80,0x40,
+0x08,0x90,0x03,0x28,0x74,0x01,0xf0,0x80,0x05,0xe4,0x90,0x03,0x28,0xf0,0xe4,0x90,
+0x03,0xd3,0xf0,0xa3,0xf0,0x90,0x03,0xc5,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x90,
+0x03,0x29,0xf0,0x90,0x03,0xc0,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x05,0xf5,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf1,0x12,0x1f,0xa6,0x90,
+0x03,0x22,0x12,0x1f,0xa6,0x90,0x03,0xcd,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0xe4,
+0x90,0x03,0x26,0xf0,0xa3,0xf0,0x12,0x91,0xac,0x90,0x03,0x1e,0xe0,0x90,0x03,0xc2,
+0xf0,0x22,0x12,0x94,0x45,0x12,0x78,0xe7,0x90,0x03,0xe5,0xe0,0x70,0x03,0x02,0x58,
+0xdb,0x90,0x03,0xc7,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xc2,0x04,0xf0,0x22,0x12,
+0x94,0x45,0x12,0x78,0xe7,0x90,0x03,0xe5,0xe0,0x70,0x32,0x90,0x03,0x27,0xe0,0x04,
+0xf0,0x70,0x06,0x90,0x03,0x26,0xe0,0x04,0xf0,0xd3,0x90,0x03,0x27,0xe0,0x94,0x05,
+0x90,0x03,0x26,0xe0,0x64,0x80,0x94,0x80,0x50,0x03,0x02,0x58,0xdb,0x90,0x03,0xc7,
+0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xc2,0x74,0x03,0xf0,0x80,0x00,0xe4,0x90,0x03,
+0x26,0xf0,0xa3,0xf0,0x22,0x12,0x94,0x45,0x90,0x03,0xe5,0xef,0xf0,0x60,0x30,0x90,
+0x03,0xc7,0xe4,0xf0,0xa3,0x04,0xf0,0xe4,0x90,0x03,0xc2,0xf0,0x90,0x03,0x1e,0x74,
+0x02,0xf0,0x12,0x82,0x86,0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0x90,0x03,
+0xc0,0xf0,0xa3,0xf0,0x90,0x03,0x22,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x22,0x90,
+0x03,0x22,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf5,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x40,
+0x23,0x90,0x05,0xf5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x03,0x22,0x12,0x1f,0xa6,0x90,0x03,0x1c,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xc0,0xcf,
+0xf0,0xa3,0xef,0xf0,0x12,0x89,0xe1,0xef,0x60,0x2f,0xe4,0x90,0x03,0xd3,0xf0,0xa3,
+0xf0,0x90,0x03,0x29,0xe0,0xc3,0x94,0x02,0x40,0x02,0x80,0x2c,0x90,0x03,0x28,0xe0,
+0xff,0x12,0x97,0x88,0xef,0xf0,0xe4,0x90,0x03,0xc0,0xf0,0xa3,0xf0,0x90,0x03,0x22,
+0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x80,0x49,0x12,0x90,0x8a,0xef,0x60,0x49,0x90,
+0x03,0x29,0xe0,0xc3,0x94,0x02,0x40,0x1f,0x12,0x82,0x86,0x90,0x03,0x1c,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x03,0xc7,0xe4,0xf0,0xa3,0x74,0x04,0xf0,0xe4,0x90,0x03,0xc2,
+0xf0,0x90,0x03,0x1e,0x04,0xf0,0x22,0x90,0x03,0x28,0xe0,0xff,0x12,0x97,0x88,0xef,
+0xf0,0xe4,0x90,0x03,0xc0,0xf0,0xa3,0xf0,0x90,0x03,0x22,0x12,0x1f,0xb2,0x00,0x00,
+0x00,0x00,0x90,0x03,0x29,0xe0,0x04,0xf0,0x90,0x03,0x28,0xe0,0x14,0x60,0x3d,0x04,
+0x70,0x72,0x90,0x03,0x20,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0x1c,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x2f,0xff,0xec,0x3e,0x90,0x03,0xe6,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xd1,
+0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0xed,0x9f,0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,
+0x40,0x42,0x90,0x03,0xe6,0xee,0xf0,0xa3,0xef,0xf0,0x80,0x38,0x90,0x03,0x20,0xe0,
+0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x03,0x1d,0xe0,0x9f,0xff,0x90,0x03,0x1c,0xe0,0x9e,
+0xfe,0x90,0x03,0xe6,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xcb,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xc3,0x9f,0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x40,0x08,0x90,0x03,0xe6,0xec,
+0xf0,0xa3,0xed,0xf0,0x90,0x03,0xe6,0x12,0x82,0x89,0x90,0x03,0x1c,0xee,0xf0,0xa3,
+0xef,0xf0,0x90,0x03,0xc7,0xe4,0xf0,0xa3,0x74,0x02,0xf0,0x22,0x90,0x03,0xe4,0x74,
+0x07,0xf0,0xd3,0x90,0x05,0xbc,0xe0,0x94,0x00,0x90,0x05,0xbb,0xe0,0x64,0x80,0x94,
+0x80,0x40,0x0d,0xa3,0xe0,0x24,0xff,0xf0,0x90,0x05,0xbb,0xe0,0x34,0xff,0xf0,0x22,
+0x20,0x0a,0x03,0x02,0x5b,0x82,0x90,0x05,0xbe,0xe0,0x04,0xf0,0x70,0x06,0x90,0x05,
+0xbd,0xe0,0x04,0xf0,0x90,0x04,0xf8,0xe0,0x70,0x1d,0x90,0x05,0xf5,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf1,0x12,0x1f,0xa6,0x12,0x6a,
+0x41,0x90,0x05,0xf5,0x12,0x1f,0xa6,0x90,0x05,0xd7,0xe0,0x24,0xfb,0x24,0xfd,0x50,
+0x02,0x80,0x0a,0x90,0x05,0xc1,0xe4,0xf0,0xa3,0x04,0xf0,0x80,0x15,0xe4,0x90,0x05,
+0xc1,0xf0,0xa3,0xf0,0x90,0x05,0xc0,0xe0,0x04,0xf0,0x70,0x06,0x90,0x05,0xbf,0xe0,
+0x04,0xf0,0xe4,0x90,0x03,0xdf,0xf0,0x7f,0x57,0x7e,0xe2,0x12,0x96,0x64,0x90,0x03,
+0xe0,0xef,0xf0,0x7f,0x59,0x7e,0xe2,0x12,0x96,0x64,0x90,0x03,0xe1,0xef,0xf0,0x7f,
+0x58,0x7e,0xe2,0x12,0x96,0x64,0x90,0x03,0xe2,0xef,0xf0,0x7f,0x5a,0x7e,0xe2,0x12,
+0x96,0x64,0x90,0x03,0xe3,0xef,0xf0,0xfe,0x90,0x03,0xe0,0xe0,0xff,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfb,0x90,0x03,0xe8,0xee,0xf0,0x12,0x7a,0xba,0x90,0x05,0xbd,0xe0,0xfe,
+0xa3,0xe0,0xff,0xd3,0x94,0x0a,0xee,0x64,0x80,0x94,0x80,0x40,0x7e,0x7c,0x00,0x7d,
+0x05,0x12,0x1c,0xb7,0xed,0x4c,0x60,0x03,0x02,0x5a,0x61,0x7b,0x01,0x90,0x03,0xe8,
+0x04,0xf0,0xa3,0x74,0x05,0xf0,0xa3,0x74,0xb2,0xf0,0xa3,0xeb,0xf0,0xa3,0x74,0x05,
+0xf0,0xa3,0x74,0x5d,0xf0,0xa3,0xeb,0xf0,0xa3,0x74,0x05,0xf0,0xa3,0x74,0xb3,0xf0,
+0x7a,0x05,0x79,0x5c,0x12,0x5b,0x83,0x90,0x05,0x5c,0xe0,0xfe,0x24,0xfd,0x90,0x05,
+0x5e,0xf0,0xee,0x24,0x03,0xa3,0xf0,0x90,0x05,0xb2,0xe0,0xfe,0x24,0xfd,0x90,0x05,
+0xb4,0xf0,0xee,0x24,0x03,0xa3,0xf0,0x90,0x05,0x5d,0xe0,0xfe,0x24,0xfd,0x90,0x05,
+0x60,0xf0,0xee,0x24,0x03,0xa3,0xf0,0x90,0x05,0xb3,0xe0,0xfe,0x24,0xfd,0x90,0x05,
+0xb6,0xf0,0xee,0x24,0x03,0x90,0x05,0xb9,0xf0,0x80,0x26,0xe4,0x90,0x05,0x5e,0xf0,
+0xa3,0x74,0xff,0xf0,0xe4,0x90,0x05,0xb4,0xf0,0xa3,0x74,0xff,0xf0,0xe4,0x90,0x05,
+0x60,0xf0,0xa3,0x74,0xff,0xf0,0xe4,0x90,0x05,0xb6,0xf0,0x90,0x05,0xb9,0x74,0xff,
+0xf0,0x90,0x03,0xe0,0xe0,0xff,0x60,0x67,0x90,0x03,0xe2,0xe0,0xfe,0x60,0x60,0xa3,
+0xe0,0x70,0x02,0x80,0x5a,0x90,0x05,0x5e,0xe0,0xfd,0xef,0xc3,0x9d,0x40,0x50,0xa3,
+0xe0,0xff,0x90,0x03,0xe0,0xe0,0xd3,0x9f,0x50,0x45,0x90,0x05,0xb4,0xe0,0xff,0x90,
+0x03,0xe1,0xe0,0xfd,0xc3,0x9f,0x40,0x37,0x90,0x05,0xb5,0xe0,0xff,0xed,0xd3,0x9f,
+0x50,0x2d,0x90,0x05,0x60,0xe0,0xff,0xee,0xc3,0x9f,0x40,0x23,0xa3,0xe0,0xff,0x90,
+0x03,0xe2,0xe0,0xd3,0x9f,0x50,0x18,0x90,0x05,0xb6,0xe0,0xff,0x90,0x03,0xe3,0xe0,
+0xfe,0xc3,0x9f,0x40,0x0a,0x90,0x05,0xb9,0xe0,0xff,0xee,0xd3,0x9f,0x40,0x07,0xe4,
+0x90,0x03,0xdf,0xf0,0x80,0x3e,0x7f,0x60,0x7e,0xe2,0x12,0x96,0x64,0x90,0x03,0xe3,
+0xe0,0xfd,0xc3,0x9f,0xe4,0x94,0x00,0x50,0x02,0x80,0x16,0x90,0x03,0xe1,0xe0,0xd3,
+0x9d,0x50,0x0e,0x90,0x03,0xdf,0x74,0x01,0xf0,0x90,0x05,0xba,0xe0,0x04,0xf0,0x80,
+0x05,0xe4,0x90,0x03,0xdf,0xf0,0x90,0x05,0xc4,0xe0,0x04,0xf0,0x70,0x06,0x90,0x05,
+0xc3,0xe0,0x04,0xf0,0xc3,0x90,0x05,0xc4,0xe0,0x94,0x0a,0x90,0x05,0xc3,0xe0,0x64,
+0x80,0x94,0x80,0x40,0x5d,0xd3,0x90,0x05,0xc0,0xe0,0x94,0x06,0x90,0x05,0xbf,0xe0,
+0x64,0x80,0x94,0x80,0x40,0x07,0xe4,0x90,0x05,0xee,0xf0,0x80,0x34,0x90,0x03,0xe4,
+0xe0,0xff,0x90,0x05,0xba,0xe0,0xd3,0x9f,0x40,0x27,0x90,0x05,0xee,0xe0,0xb4,0x01,
+0x1a,0x90,0x05,0xca,0xe0,0x24,0xc4,0x60,0x0c,0x24,0x0a,0x70,0x0e,0x90,0x05,0xd9,
+0x74,0x3c,0xf0,0x80,0x06,0x90,0x05,0xd9,0x74,0x32,0xf0,0x90,0x05,0xee,0x74,0x01,
+0xf0,0xe4,0x90,0x05,0xc3,0xf0,0xa3,0xf0,0x90,0x05,0xba,0xf0,0x90,0x05,0xbf,0xf0,
+0xa3,0xf0,0x22,0x90,0x03,0xe5,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x90,0x03,
+0xf3,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0xf7,0x12,0x1f,0xb2,0x00,0x00,
+0x00,0x00,0x90,0x03,0xfb,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0xff,0x12,
+0x1f,0xb2,0x00,0x00,0x00,0x00,0xe4,0x90,0x03,0xf1,0xf0,0xa3,0xf0,0x90,0x05,0xb7,
+0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x03,0xf2,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,
+0x03,0xf1,0xe0,0x64,0x80,0x98,0x40,0x03,0x02,0x5d,0x07,0x90,0x03,0xf3,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,
+0x03,0x90,0x03,0xf1,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,
+0xf9,0x24,0x62,0xf5,0x82,0x74,0x05,0x3e,0xf5,0x83,0xe0,0xfc,0xe4,0x12,0x1a,0x66,
+0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x90,0x03,0xf3,0x12,0x1f,
+0xa6,0x90,0x03,0xf7,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,
+0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0x90,0x03,0xf1,0xe0,0xfe,0xa3,0xe0,0x78,0x02,
+0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x63,0xf5,0x82,0x74,0x05,0x3e,0xf5,0x83,
+0xe0,0xfc,0xe4,0x12,0x1a,0x66,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,
+0x47,0x90,0x03,0xf7,0x12,0x1f,0xa6,0x90,0x03,0xfb,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0x90,0x03,0xf1,
+0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x64,0xf5,
+0x82,0x74,0x05,0x3e,0xf5,0x83,0xe0,0xfc,0xe4,0x12,0x1a,0x66,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x90,0x03,0xfb,0x12,0x1f,0xa6,0x90,0x03,0xff,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc0,0x00,0xc0,0x01,0xc0,
+0x02,0xc0,0x03,0x90,0x03,0xf1,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,0xce,0x33,
+0xce,0xd8,0xf9,0x24,0x65,0xf5,0x82,0x74,0x05,0x3e,0xf5,0x83,0xe0,0xfc,0xe4,0x12,
+0x1a,0x66,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x47,0x90,0x03,0xff,
+0x12,0x1f,0xa6,0x90,0x03,0xf2,0xe0,0x04,0xf0,0x60,0x03,0x02,0x5b,0xbd,0x90,0x03,
+0xf1,0xe0,0x04,0xf0,0x02,0x5b,0xbd,0x90,0x05,0xb7,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,
+0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x03,0xf3,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,0x41,0xe4,0xfb,0xfa,0xf9,
+0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x03,0xe5,0xe0,0xfb,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xf9,0xef,0x12,0x1c,0x3e,0x90,0x05,0xb7,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,
+0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x03,0xf7,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,0x41,0xe4,0xfb,0xfa,0xf9,
+0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x03,0xe8,0xe0,0xfb,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xf9,0xef,0x12,0x1c,0x3e,0x90,0x05,0xb7,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,
+0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x03,0xfb,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,0x41,0xe4,0xfb,0xfa,0xf9,
+0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x03,0xeb,0xe0,0xfb,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xf9,0xef,0x12,0x1c,0x3e,0x90,0x05,0xb7,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,
+0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x03,0xff,0xe0,0xfc,
+0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,0x41,0xe4,0xfb,0xfa,0xf9,
+0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x03,0xee,0xe0,0xfb,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xf9,0xef,0x02,0x1c,0x3e,0x90,0x05,0xd2,0xef,0xf0,0xb4,0x0f,0x00,0x40,
+0x03,0x02,0x60,0x34,0x90,0x5e,0x1b,0xf8,0x28,0x28,0x73,0x02,0x5e,0x48,0x02,0x5e,
+0x58,0x02,0x5e,0x6d,0x02,0x5e,0x82,0x02,0x5e,0x9a,0x02,0x5e,0xc2,0x02,0x5e,0xea,
+0x02,0x5f,0x12,0x02,0x5f,0x3a,0x02,0x5f,0x63,0x02,0x5f,0x8c,0x02,0x5f,0x8c,0x02,
+0x5f,0xbb,0x02,0x5f,0xe3,0x02,0x60,0x09,0xe4,0x90,0x04,0x7a,0xf0,0xfd,0x7f,0x58,
+0x7e,0xe6,0x12,0x96,0xbd,0x02,0x39,0x2d,0xe4,0x90,0x04,0x7a,0xf0,0xfd,0x7f,0x58,
+0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x2f,0x02,0x5e,0xfd,0xe4,0x90,0x04,
+0x7a,0xf0,0x7d,0x04,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0xc0,
+0x80,0x7b,0xe4,0x90,0x04,0x7a,0xf0,0x7d,0x02,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,
+0x12,0x39,0x2d,0x12,0x95,0xfe,0x7d,0x04,0x80,0x63,0xe4,0x90,0x04,0x7a,0xf0,0x7d,
+0x01,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x90,0x7f,0x50,0x7e,
+0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x1f,0x02,
+0x60,0x2d,0xe4,0x90,0x04,0x7a,0xf0,0x7d,0x03,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,
+0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,
+0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x30,0x02,0x60,0x2d,0xe4,0x90,0x04,0x7a,0xf0,0x7d,
+0x07,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,
+0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,0x02,
+0x60,0x2d,0xe4,0x90,0x04,0x7a,0xf0,0x7d,0x05,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,
+0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,
+0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,0x02,0x60,0x2d,0x90,0x04,0x7a,0x74,0x14,0xf0,
+0xe4,0xfd,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,
+0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,
+0x02,0x60,0x2d,0x90,0x04,0x7a,0x74,0xec,0xf0,0xe4,0xfd,0x7f,0x58,0x7e,0xe6,0x12,
+0x96,0xbd,0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,
+0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,0x02,0x60,0x2d,0xe4,0x90,0x04,0x7a,
+0xf0,0xfd,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0xe4,0xfd,0x7f,0xe1,
+0x7e,0xe5,0x12,0x96,0xbd,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,
+0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,0x80,0x72,0x90,0x04,0x7a,0x74,0x0a,
+0xf0,0xe4,0xfd,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x04,0x7f,
+0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,
+0x04,0x80,0x4a,0xe4,0x90,0x04,0x7a,0xf0,0xfd,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,
+0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x51,
+0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x10,0x80,0x24,0xe4,0x90,0x04,0x7a,0xf0,0xfd,0x7f,
+0x58,0x7e,0xe6,0x12,0x96,0xbd,0x12,0x39,0x2d,0x7d,0x04,0x7f,0x50,0x7e,0xe3,0x12,
+0x96,0xbd,0xe4,0xfd,0x7f,0x51,0x7e,0xe3,0x12,0x96,0xbd,0x7d,0x04,0x7f,0x52,0x7e,
+0xe3,0x12,0x96,0xbd,0x22,0xe4,0x90,0x03,0xe7,0xf0,0xa3,0xf0,0x90,0x03,0xed,0xf0,
+0x90,0x04,0xc6,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x04,0x97,0xe0,0xfa,0xa3,0xe0,0xfb,
+0xd3,0x94,0x1a,0xea,0x94,0x00,0x40,0x04,0x7b,0x1a,0x80,0x0b,0xc3,0xeb,0x94,0x06,
+0xea,0x94,0x00,0x50,0x02,0x7b,0x06,0xd3,0xed,0x94,0x39,0xec,0x94,0x00,0x40,0x06,
+0x7c,0x00,0x7d,0x39,0x80,0x0d,0xc3,0xed,0x94,0x06,0xec,0x94,0x00,0x50,0x04,0x7c,
+0x00,0x7d,0x06,0xaf,0x03,0xef,0x24,0xfa,0x90,0x03,0xe9,0xf0,0xef,0x24,0x06,0xa3,
+0xf0,0xaf,0x05,0xef,0x24,0xfa,0xa3,0xf0,0xef,0x24,0x06,0xa3,0xf0,0x7e,0x00,0x7f,
+0x0a,0x7d,0x00,0x7b,0x01,0x7a,0x04,0x79,0xcd,0x12,0x20,0x93,0x90,0x03,0xeb,0xe0,
+0xff,0x90,0x03,0xec,0xe0,0xfe,0xef,0xc3,0x9e,0x50,0x48,0x90,0x03,0xe9,0xe0,0x90,
+0x03,0xe6,0xf0,0x90,0x03,0xea,0xe0,0xfe,0x90,0x03,0xe6,0xe0,0xfd,0xc3,0x9e,0x50,
+0x2f,0x75,0xf0,0x20,0xef,0xa4,0x24,0x19,0xf5,0x82,0xe5,0xf0,0x34,0xac,0xf5,0x83,
+0xe5,0x82,0x2d,0xf5,0x82,0xe4,0x35,0x83,0xf5,0x83,0xe4,0x93,0x24,0xcd,0xf5,0x82,
+0xe4,0x34,0x04,0xf5,0x83,0xe0,0x04,0xf0,0x90,0x03,0xe6,0xe0,0x04,0xf0,0x80,0xc3,
+0x0f,0x80,0xae,0x90,0x04,0xce,0xe0,0xff,0x7e,0x00,0x90,0x04,0x9d,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x12,0x1c,0x50,0xac,0x06,0xad,0x07,0x90,0x04,0xaf,0xe0,0xff,0x90,0x04,
+0xcd,0xe0,0x8f,0xf0,0xa4,0x2d,0xfb,0xe5,0xf0,0x3c,0xfa,0x90,0x04,0xcf,0xe0,0xff,
+0x7e,0x00,0x90,0x04,0x9f,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,
+0xee,0x3a,0xfa,0x90,0x04,0xd0,0xe0,0xff,0x7e,0x00,0x90,0x04,0xa1,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x04,0xd1,0xe0,0xff,
+0x7e,0x00,0x90,0x04,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,
+0xee,0x3a,0xfa,0x90,0x04,0xd2,0xe0,0xff,0x7e,0x00,0x90,0x04,0xa5,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x04,0xd3,0xe0,0xff,
+0x7e,0x00,0x90,0x04,0xa7,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,
+0xee,0x3a,0xfa,0x90,0x04,0xd4,0xe0,0xff,0x7e,0x00,0x90,0x04,0xa9,0xe0,0xfc,0xa3,
+0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfb,0xee,0x3a,0xfa,0x90,0x04,0xd5,0xe0,0xff,
+0x7e,0x00,0x90,0x04,0xab,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0xef,0x2b,0xfd,
+0xee,0x3a,0xfc,0x90,0x04,0xb0,0xe0,0xff,0x90,0x04,0xd6,0xe0,0x8f,0xf0,0xa4,0x2d,
+0xfe,0xe5,0xf0,0x3c,0x90,0x03,0xe7,0xf0,0xa3,0xce,0xf0,0xe4,0x90,0x03,0xe6,0xf0,
+0x90,0x03,0xe6,0xe0,0xff,0xc3,0x94,0x0a,0x50,0x1a,0x74,0xcd,0x2f,0xf5,0x82,0xe4,
+0x34,0x04,0xf5,0x83,0xe0,0xff,0x90,0x03,0xed,0xe0,0x2f,0xf0,0x90,0x03,0xe6,0xe0,
+0x04,0xf0,0x80,0xdc,0x90,0x03,0xe7,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xed,0xe0,
+0xfd,0x7c,0x00,0x12,0x1c,0x62,0x90,0x03,0xe7,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x04,
+0xaf,0xe0,0x2f,0xff,0xe4,0x3e,0xfe,0xa3,0xe0,0x7c,0x00,0x2f,0xff,0xec,0x3e,0xfe,
+0x7d,0x03,0x12,0x1c,0x62,0x90,0x03,0xe7,0xee,0xf0,0xa3,0xef,0xf0,0x22,0x12,0x7e,
+0xf0,0x90,0x05,0x50,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xc8,0xee,0xf0,0xa3,0xef,
+0xf0,0x90,0x05,0x52,0xe0,0xfd,0xa3,0xe0,0x90,0x05,0xce,0xcd,0xf0,0xa3,0xed,0xf0,
+0xad,0x07,0xac,0x06,0xe4,0x12,0x1a,0x61,0x90,0x05,0xda,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x05,0xf9,0xee,
+0xf0,0xa3,0xef,0xf0,0x90,0x05,0x58,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x05,0xfe,
+0xe0,0x9f,0xfd,0x90,0x05,0xfd,0xe0,0x9e,0xfc,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,
+0x05,0xc0,0x06,0xc0,0x07,0x90,0x05,0x58,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x05,
+0xcf,0xe0,0x9f,0xfd,0x90,0x05,0xce,0xe0,0x9e,0xfc,0xe4,0x12,0x1a,0x61,0xd0,0x03,
+0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x19,0x41,0x90,0x06,0x45,0x12,0x1f,0xa6,0x20,
+0x09,0x06,0x90,0x05,0xce,0x02,0x63,0xde,0x90,0x04,0xd7,0xe0,0x64,0x03,0x60,0x03,
+0x02,0x63,0x8c,0x90,0x06,0x49,0x04,0xf0,0x90,0x04,0xda,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x05,0xc8,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,
+0x12,0x19,0x41,0x90,0x06,0x45,0x12,0x1f,0xa6,0x74,0x01,0x70,0x15,0x90,0x05,0xcc,
+0xe0,0xff,0xa3,0xe0,0x90,0x05,0xf9,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0xd5,0x02,
+0x63,0xde,0x90,0x06,0x49,0xe0,0x64,0x01,0x60,0x03,0x02,0x64,0x54,0x90,0x05,0xd5,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x90,0x06,0x45,0xe0,0xf8,0xa3,0xe0,
+0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x7b,0x9a,0x7a,0x99,0x79,0x19,
+0x78,0x3f,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x05,0xfb,0xee,0xf0,0xa3,0xef,0xf0,
+0x90,0x05,0xcc,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xf9,0x80,0x59,0x90,0x05,0xce,0xe0,
+0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x05,0x59,0xe0,0x9f,0x90,0x05,0x58,0xe0,0x9e,0x50,
+0x47,0x90,0x05,0xfd,0xe0,0xfc,0xa3,0xe0,0xfd,0xef,0x9d,0xee,0x9c,0x50,0x39,0x90,
+0x05,0xf9,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0x90,0x06,0x45,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,
+0x05,0xfa,0xe0,0x2f,0xf0,0x90,0x05,0xf9,0xe0,0x3e,0xf0,0x90,0x05,0x58,0xe0,0xff,
+0xa3,0xe0,0x90,0x05,0xfb,0xcf,0x80,0x68,0x90,0x05,0xce,0xe0,0xfe,0xa3,0xe0,0xff,
+0x90,0x05,0xfd,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,0x50,0x47,0x90,0x05,
+0xcc,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xf9,0xcf,0xf0,0xa3,0xef,0xf0,0xc3,0x90,0x05,
+0xcf,0xe0,0x9d,0xfd,0x90,0x05,0xce,0xe0,0x9c,0xfc,0xe4,0x12,0x1a,0x61,0x7b,0x9a,
+0x7a,0x99,0x79,0x19,0x78,0x3f,0x12,0x18,0x38,0xe4,0xfb,0xfa,0xf9,0x78,0x3f,0x12,
+0x17,0x47,0x12,0x1a,0x9a,0x90,0x05,0x59,0xe0,0x2f,0xff,0x90,0x05,0x58,0xe0,0x3e,
+0x90,0x05,0xfb,0x80,0x0b,0x90,0x05,0x58,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xfb,0xcf,
+0xf0,0xa3,0xef,0xf0,0x22,0x90,0x03,0xe5,0xee,0xf0,0xa3,0xef,0xf0,0xab,0x05,0xaa,
+0x04,0x90,0x03,0x22,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x05,0xf1,0x12,0x1f,
+0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0xe5,0xe0,0xff,0xa3,0xe0,0x90,0x03,0xcb,0xcf,
+0xf0,0xa3,0xef,0xf0,0xaf,0x03,0x90,0x03,0xd1,0xea,0xf0,0xa3,0xef,0xf0,0x90,0x03,
+0xd6,0x74,0x01,0xf0,0xe4,0x90,0x03,0xc9,0xf0,0xff,0x12,0x95,0xde,0x90,0x03,0xc3,
+0xee,0xf0,0xa3,0xef,0xf0,0x12,0x91,0xac,0xe4,0x90,0x03,0xda,0xf0,0xa3,0xf0,0x90,
+0x03,0xd3,0xf0,0xa3,0xf0,0x90,0x03,0xd7,0xf0,0xa3,0x74,0x02,0xf0,0x90,0x03,0xca,
+0x14,0xf0,0x90,0x05,0xd2,0xe0,0x24,0xfb,0x24,0xfd,0x50,0x02,0x80,0x55,0x90,0x04,
+0x78,0xe0,0xfc,0xa3,0xe0,0xfd,0xd3,0x90,0x05,0x51,0xe0,0x9d,0x90,0x05,0x50,0xe0,
+0x9c,0x40,0x40,0x74,0x02,0xff,0xfe,0x12,0x93,0xa8,0x7f,0x2c,0x7e,0x01,0x7d,0x00,
+0x7c,0x00,0x12,0x96,0xcb,0x90,0x04,0x79,0xe0,0x24,0x0a,0xfd,0x90,0x04,0x78,0xe0,
+0x34,0x00,0xfc,0x7f,0x40,0x7e,0x03,0x12,0x93,0xa8,0x7f,0x2c,0x7e,0x01,0x7d,0x00,
+0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xd8,0xe0,0x04,0xf0,0x70,0x06,0x90,0x03,0xd7,
+0xe0,0x04,0xf0,0x7f,0x28,0x7e,0xe6,0x12,0x96,0x64,0xef,0xb4,0x01,0x08,0x90,0x03,
+0xd5,0x74,0x02,0xf0,0x80,0x23,0x90,0x05,0x02,0xe0,0x60,0x18,0x30,0x04,0x15,0x7f,
+0x12,0x7e,0xf2,0x12,0x96,0x64,0xef,0xd3,0x94,0x00,0x40,0x08,0x90,0x03,0xd5,0x74,
+0x01,0xf0,0x80,0x05,0xe4,0x90,0x03,0xd5,0xf0,0xd3,0x90,0x03,0xc4,0xe0,0x94,0x00,
+0x90,0x03,0xc3,0xe0,0x64,0x80,0x94,0x80,0x40,0x05,0x90,0x03,0xcb,0x80,0x03,0x90,
+0x03,0xd1,0x12,0x82,0x89,0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0xd3,0x90,0x03,
+0xc4,0xe0,0x94,0x00,0x90,0x03,0xc3,0xe0,0x64,0x80,0x94,0x80,0x40,0x36,0x90,0x03,
+0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xcb,0xe0,0xfc,0xa3,0xe0,0xfd,0x9f,0xff,
+0xec,0x9e,0xfe,0xc3,0x64,0x80,0x94,0x80,0x50,0x09,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,
+0xfe,0x80,0x46,0x90,0x03,0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0xed,0x9f,0xff,0xec,
+0x9e,0xfe,0x80,0x35,0x90,0x03,0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xd1,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xff,0xec,0x9e,0xfe,0xc3,0x64,0x80,0x94,0x80,0x50,
+0x09,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,0x80,0x0f,0x90,0x03,0x1c,0xe0,0xfe,0xa3,
+0xe0,0xff,0xc3,0xed,0x9f,0xff,0xec,0x9e,0xfe,0x90,0x03,0xe7,0xee,0xf0,0xa3,0xef,
+0xf0,0x90,0x03,0xe7,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x94,0x96,0xee,0x64,0x80,0x94,
+0x80,0x40,0x10,0x90,0x03,0xd8,0xe0,0x24,0x02,0xf0,0x90,0x03,0xd7,0xe0,0x34,0x00,
+0xf0,0x80,0x19,0xd3,0xef,0x94,0x50,0xee,0x64,0x80,0x94,0x80,0x40,0x0e,0x90,0x03,
+0xd8,0xe0,0x04,0xf0,0x70,0x06,0x90,0x03,0xd7,0xe0,0x04,0xf0,0x7d,0x23,0x7f,0x61,
+0x7e,0xe6,0x12,0x96,0xbd,0x90,0x04,0xf9,0x74,0xff,0xf0,0xa3,0x74,0x52,0xf0,0xa3,
+0x74,0xf5,0xf0,0x90,0x04,0xf8,0x74,0x01,0xf0,0x22,0x90,0x04,0x00,0x12,0x1f,0xb2,
+0x00,0x00,0x00,0x00,0x90,0x04,0x04,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x04,
+0x08,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0xe4,0x90,0x03,0xfe,0xf0,0xa3,0xf0,0x90,
+0x04,0x00,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xc0,0x04,0xc0,
+0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfe,0xe0,0xfe,0xa3,0xe0,0x78,0x02,0xc3,0x33,
+0xce,0x33,0xce,0xd8,0xf9,0x24,0xf5,0xf5,0x82,0x74,0x00,0x3e,0xf5,0x83,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,
+0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x04,0x00,0x12,0x1f,
+0xa6,0x90,0x04,0x04,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfe,0xe0,0xfe,0xa3,0xe0,0x78,0x02,
+0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x95,0xf5,0x82,0x74,0x00,0x3e,0xf5,0x83,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xd0,0x07,0xd0,0x06,0xd0,0x05,
+0xd0,0x04,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,0x04,0x04,
+0x12,0x1f,0xa6,0x90,0x04,0x08,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xfe,0xe0,0xfe,0xa3,0xe0,
+0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0x24,0x35,0xf5,0x82,0x74,0x00,0x3e,
+0xf5,0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xd0,0x07,0xd0,0x06,
+0xd0,0x05,0xd0,0x04,0x2f,0xff,0xee,0x3a,0xfe,0xed,0x39,0xfd,0xec,0x38,0xfc,0x90,
+0x04,0x08,0x12,0x1f,0xa6,0x90,0x03,0xff,0xe0,0x04,0xf0,0x70,0x06,0x90,0x03,0xfe,
+0xe0,0x04,0xf0,0x90,0x03,0xfe,0xe0,0x70,0x04,0xa3,0xe0,0x64,0x18,0x60,0x03,0x02,
+0x66,0x7f,0x90,0x04,0x00,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0x24,
+0x01,0xff,0xe4,0x3e,0xfe,0xe4,0x3d,0xfd,0xe4,0x3c,0xfc,0xe4,0x12,0x1a,0x5c,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x04,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,
+0x00,0x12,0x19,0x41,0xe4,0xfb,0xfa,0x79,0x80,0x78,0x44,0x12,0x18,0x38,0xe4,0xfb,
+0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x01,0xc2,0xee,0xf0,0xa3,
+0xef,0xf0,0x90,0x04,0x08,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0x24,
+0x01,0xff,0xe4,0x3e,0xfe,0xe4,0x3d,0xfd,0xe4,0x3c,0xfc,0xe4,0x12,0x1a,0x5c,0xc0,
+0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x04,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,
+0x00,0x12,0x19,0x41,0xe4,0xfb,0xfa,0x79,0x80,0x78,0x44,0x12,0x18,0x38,0xe4,0xfb,
+0xfa,0xf9,0x78,0x3f,0x12,0x17,0x47,0x12,0x1a,0x9a,0x90,0x01,0x57,0xee,0xf0,0xa3,
+0xef,0xf0,0x22,0x90,0x04,0x2b,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x90,0x04,
+0x37,0xe4,0xf0,0xa3,0x74,0x18,0xf0,0x78,0x39,0x7c,0x04,0x7d,0x01,0x7b,0xff,0x7a,
+0xb4,0x79,0x19,0x7e,0x00,0x7f,0x30,0x12,0x1b,0xeb,0xe4,0x90,0x04,0x31,0xf0,0xa3,
+0xf0,0x90,0x04,0x37,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x31,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xc3,0x9f,0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x50,0x3a,0xed,0x25,0xe0,
+0xff,0xec,0x33,0xfe,0x90,0x04,0x2b,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x8f,
+0x82,0x8e,0x83,0x12,0x1d,0x18,0xfd,0x74,0x39,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,
+0x83,0xe5,0xf0,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x32,0xe0,0x04,0xf0,0x70,0xb2,0x90,
+0x04,0x31,0xe0,0x04,0xf0,0x80,0xaa,0xe4,0x90,0x04,0x31,0xf0,0xa3,0xf0,0x90,0x04,
+0x38,0xe0,0x24,0xff,0xff,0x90,0x04,0x37,0xe0,0x34,0xff,0xfe,0x90,0x04,0x31,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x40,0x03,
+0x02,0x6a,0x40,0xed,0x24,0x01,0xfe,0xe4,0x3c,0xa3,0xf0,0xa3,0xce,0xf0,0x90,0x04,
+0x37,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x33,0xe0,0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,
+0xee,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x40,0x03,0x02,0x6a,0x2f,0xed,0x25,0xe0,
+0xff,0xec,0x33,0xfe,0x74,0x39,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xfc,
+0xa3,0xe0,0xfd,0x90,0x04,0x32,0xe0,0x25,0xe0,0xff,0x90,0x04,0x31,0xe0,0x33,0xfe,
+0x74,0x39,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,
+0x9d,0xec,0x64,0x80,0xf8,0xee,0x64,0x80,0x98,0x40,0x03,0x02,0x6a,0x1e,0xab,0x07,
+0xaa,0x06,0x90,0x04,0x32,0xe0,0x25,0xe0,0xff,0x90,0x04,0x31,0xe0,0x33,0xfe,0x74,
+0x39,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0xad,0x03,
+0x90,0x04,0x34,0xe0,0x25,0xe0,0xff,0x90,0x04,0x33,0xe0,0x33,0xfe,0x74,0x39,0x2f,
+0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xea,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x32,0xe0,
+0x25,0xe0,0xff,0x90,0x04,0x31,0xe0,0x33,0xfe,0x90,0x04,0x2e,0xe0,0xfb,0xa3,0xe0,
+0xfa,0xa3,0xe0,0xf9,0x8f,0x82,0x8e,0x83,0x12,0x1d,0x18,0xff,0x90,0x04,0x35,0xe5,
+0xf0,0xf0,0xa3,0xef,0xf0,0x90,0x04,0x34,0xe0,0x25,0xe0,0xff,0x90,0x04,0x33,0xe0,
+0x33,0x8f,0x82,0xf5,0x83,0x12,0x1d,0x18,0xfd,0x90,0x04,0x32,0xe0,0x25,0xe0,0xff,
+0x90,0x04,0x31,0xe0,0x33,0x8f,0x82,0xf5,0x83,0xe5,0xf0,0x8d,0xf0,0x12,0x1d,0x6f,
+0x90,0x04,0x35,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x04,0x34,0xe0,0x25,0xe0,0xff,0x90,
+0x04,0x33,0xe0,0x33,0x8f,0x82,0xf5,0x83,0xec,0x8d,0xf0,0x12,0x1d,0x6f,0x90,0x04,
+0x34,0xe0,0x04,0xf0,0x70,0x06,0x90,0x04,0x33,0xe0,0x04,0xf0,0x02,0x69,0x0e,0x90,
+0x04,0x32,0xe0,0x04,0xf0,0x70,0x06,0x90,0x04,0x31,0xe0,0x04,0xf0,0x02,0x68,0xde,
+0x22,0x90,0x03,0xd5,0xe0,0x14,0x70,0x03,0x02,0x6b,0x11,0x14,0x70,0x03,0x02,0x6b,
+0x6f,0x24,0x02,0x60,0x03,0x02,0x6b,0xd6,0xe4,0x90,0x03,0xff,0xf0,0xa3,0xf0,0xa3,
+0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x7f,0xbc,0x7e,0xec,0x12,
+0x96,0x64,0x90,0x04,0x02,0xef,0xf0,0x7f,0xbd,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0x01,0xef,0xf0,0x7f,0xbe,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x00,0xef,0xf0,0x7f,
+0xbf,0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xff,0xef,0xf0,0x7f,0xc0,0x7e,0xec,0x12,
+0x96,0x64,0x90,0x04,0x06,0xef,0xf0,0x7f,0xc1,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,
+0x05,0xef,0xf0,0x7f,0xc2,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x04,0xef,0xf0,0x7f,
+0xc3,0x7e,0xec,0x12,0x96,0x64,0x90,0x04,0x03,0xef,0xf0,0x90,0x04,0x02,0xe0,0xff,
+0x90,0x04,0x01,0xe0,0xfd,0x90,0x04,0x00,0xe0,0xfb,0x90,0x03,0xff,0xe0,0x90,0x04,
+0x0a,0xf0,0x12,0x95,0xbc,0x90,0x03,0xf7,0x12,0x1f,0xa6,0x90,0x04,0x06,0xe0,0xff,
+0x90,0x04,0x05,0xe0,0xfd,0x90,0x04,0x04,0xe0,0xfb,0x90,0x04,0x03,0xe0,0x90,0x04,
+0x0a,0xf0,0x12,0x95,0xbc,0x90,0x03,0xfb,0x12,0x1f,0xa6,0x90,0x03,0xfb,0x02,0x6b,
+0xcb,0xe4,0x90,0x03,0xfb,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x7f,0xd0,0x7e,0xec,
+0x12,0x96,0x64,0x90,0x03,0xfe,0xef,0xf0,0x7f,0xd1,0x7e,0xec,0x12,0x96,0x64,0x90,
+0x03,0xfd,0xef,0xf0,0x7f,0xd2,0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xfc,0xef,0xf0,
+0x7f,0xd3,0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xfb,0xef,0xf0,0xfe,0x90,0x03,0xfe,
+0xe0,0xff,0x90,0x03,0xfd,0xe0,0xfd,0x90,0x03,0xfc,0xe0,0xfb,0x90,0x04,0x0a,0xee,
+0xf0,0x12,0x95,0xbc,0x90,0x03,0xf7,0x12,0x1f,0xa6,0x90,0x03,0xf7,0x80,0x5c,0xe4,
+0x90,0x03,0xfb,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x7f,0xcc,0x7e,0xec,0x12,0x96,
+0x64,0x90,0x03,0xfe,0xef,0xf0,0x7f,0xcd,0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xfd,
+0xef,0xf0,0x7f,0xce,0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xfc,0xef,0xf0,0x7f,0xcf,
+0x7e,0xec,0x12,0x96,0x64,0x90,0x03,0xfb,0xef,0xf0,0xfe,0x90,0x03,0xfe,0xe0,0xff,
+0x90,0x03,0xfd,0xe0,0xfd,0x90,0x03,0xfc,0xe0,0xfb,0x90,0x04,0x0a,0xee,0xf0,0x12,
+0x95,0xbc,0x90,0x03,0xf7,0x12,0x1f,0xa6,0x90,0x03,0xf7,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xe4,0x90,0x03,0xe8,0xf0,0xa3,0xf0,0xa3,0xf0,
+0xa3,0xf0,0x90,0x03,0xe6,0xf0,0xa3,0xf0,0x90,0x03,0xe6,0xe0,0xfe,0xa3,0xe0,0xff,
+0xc3,0x94,0x08,0xee,0x64,0x80,0x94,0x80,0x40,0x03,0x02,0x6c,0xd5,0xef,0x24,0x01,
+0xfb,0xe4,0x3e,0xfa,0xc3,0xeb,0x94,0x09,0xea,0x64,0x80,0x94,0x80,0x40,0x03,0x02,
+0x6c,0xc4,0xeb,0x25,0xe0,0xff,0xea,0x33,0xfe,0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,
+0x3e,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x03,0xe7,0xe0,0x25,0xe0,0xff,0x90,
+0x03,0xe6,0xe0,0x33,0xfe,0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,
+0xfe,0xa3,0xe0,0xc3,0x9d,0xee,0x9c,0x50,0x73,0xeb,0x25,0xe0,0xff,0xea,0x33,0xfe,
+0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xff,0xa3,0xe0,0x90,0x03,
+0xe8,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe7,0xe0,0x25,0xe0,0xff,0x90,0x03,0xe6,
+0xe0,0x33,0xfe,0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xeb,0x25,0xe0,0xff,0xea,0x33,0xfe,0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,
+0x3e,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xe8,0xe0,0xfc,0xa3,0xe0,0xfd,
+0x90,0x03,0xe7,0xe0,0x25,0xe0,0xff,0x90,0x03,0xe6,0xe0,0x33,0xfe,0x74,0x9d,0x2f,
+0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x0b,0xbb,0x00,0x01,
+0x0a,0x02,0x6c,0x04,0x90,0x03,0xe7,0xe0,0x04,0xf0,0x70,0x06,0x90,0x03,0xe6,0xe0,
+0x04,0xf0,0x02,0x6b,0xe8,0xe4,0xfa,0xfb,0xeb,0x25,0xe0,0xff,0xea,0x33,0xfe,0x74,
+0x9d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,
+0xaf,0xe0,0xfd,0x7c,0x00,0xc3,0xef,0x9d,0xff,0xee,0x9c,0xfe,0xc3,0x64,0x80,0x94,
+0x80,0x50,0x09,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,0x80,0x1b,0xeb,0x25,0xe0,0xff,
+0xea,0x33,0xfe,0x74,0x9d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,0xfe,0xa3,
+0xe0,0xc3,0x9d,0xff,0xee,0x9c,0xfe,0x90,0x03,0xeb,0xe0,0x2f,0xf0,0x90,0x03,0xea,
+0xe0,0x3e,0xf0,0x0b,0xbb,0x00,0x01,0x0a,0xeb,0x64,0x09,0x4a,0x70,0x9a,0x90,0x03,
+0xea,0xe0,0xfe,0xa3,0xe0,0xff,0x7c,0x00,0x7d,0x09,0x12,0x1c,0x62,0x90,0x03,0xea,
+0xee,0xf0,0xa3,0xef,0xf0,0xc3,0xee,0x94,0x00,0x50,0x07,0xe4,0x90,0x03,0xea,0xf0,
+0xa3,0xf0,0x90,0x03,0xea,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x90,0x04,0x0e,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x04,0x1a,0xe4,0xf0,0xa3,0x04,0xf0,0xa3,0xe4,0xf0,0xa3,0x04,
+0xf0,0x90,0x02,0x81,0xe0,0x70,0x03,0x02,0x6e,0xf8,0x90,0x02,0x09,0xe0,0xff,0xa3,
+0xe0,0x90,0x04,0x12,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x0b,0xe0,0xff,0xa3,0xe0,
+0x90,0x04,0x14,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x0d,0xe0,0xff,0xa3,0xe0,0x90,
+0x04,0x16,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x0f,0xe0,0xff,0xa3,0xe0,0x90,0x04,
+0x18,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x02,0x11,0xe0,0xff,0xa3,0xe0,0xfe,0x90,0x02,
+0x81,0xe0,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,
+0xe0,0xfb,0xa3,0xe0,0x90,0x02,0x09,0xcb,0xf0,0xa3,0xeb,0xf0,0xed,0x75,0xf0,0x0a,
+0xa4,0x24,0x0b,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x90,0x02,
+0x0b,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,0x81,0xe0,0xfd,0x75,0xf0,0x0a,0xa4,0x24,
+0x0d,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xe0,0xfb,0xa3,0xe0,0x90,0x02,0x0d,0xcb,
+0xf0,0xa3,0xeb,0xf0,0xed,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,0x02,
+0xf5,0x83,0xe0,0xfd,0xa3,0xe0,0x90,0x02,0x0f,0xcd,0xf0,0xa3,0xed,0xf0,0x90,0x02,
+0x81,0xe0,0xfd,0x75,0xf0,0x0a,0xa4,0x24,0x11,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,
+0xe0,0x90,0x02,0x11,0xf0,0xed,0x75,0xf0,0x0a,0xa4,0x24,0x12,0xf5,0x82,0xe4,0x34,
+0x02,0xf5,0x83,0xe0,0x90,0x02,0x12,0xf0,0x90,0x04,0x12,0xe0,0xfc,0xa3,0xe0,0xfd,
+0x90,0x02,0x81,0xe0,0xfb,0x75,0xf0,0x0a,0xa4,0x24,0x09,0xf5,0x82,0xe4,0x34,0x02,
+0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x14,0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,
+0x75,0xf0,0x0a,0xa4,0x24,0x0b,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,
+0xed,0xf0,0x90,0x04,0x16,0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,0x75,0xf0,0x0a,0xa4,0x24,
+0x0d,0xf5,0x82,0xe4,0x34,0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x04,0x18,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x0f,0xf5,0x82,0xe4,0x34,
+0x02,0xf5,0x83,0xec,0xf0,0xa3,0xed,0xf0,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x11,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xef,0xf0,0xeb,0x75,0xf0,0x0a,0xa4,0x24,0x12,0xf5,
+0x82,0xe4,0x34,0x02,0xf5,0x83,0xee,0xf0,0x22,0x90,0x03,0xf7,0xee,0xf0,0xa3,0xef,
+0xf0,0xa3,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x05,0x47,0xe0,0xfd,0xb4,0xd0,0x1c,0x90,
+0x04,0x7c,0xe0,0x25,0xe0,0xff,0x90,0x04,0x7b,0xe0,0x33,0xfe,0xc3,0x90,0x03,0xf8,
+0xe0,0x9f,0x90,0x03,0xf7,0xe0,0x9e,0x40,0x02,0x80,0x19,0xed,0xb4,0xdb,0x1c,0x90,
+0x05,0xcc,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x03,0xf8,0xe0,0x9f,0x90,0x03,0xf7,
+0xe0,0x9e,0x40,0x07,0xe4,0x90,0x05,0xcb,0xf0,0x80,0x06,0x90,0x05,0xcb,0x74,0x01,
+0xf0,0x90,0x05,0xcb,0xe0,0x14,0x60,0x15,0x24,0xcf,0x60,0x11,0x24,0xf6,0x60,0x2a,
+0x24,0x3c,0x70,0x41,0xc2,0x08,0xe4,0x90,0x05,0xca,0xf0,0x80,0x38,0x90,0x04,0x00,
+0x74,0x01,0xf0,0xa3,0x74,0x03,0xf0,0xa3,0x74,0xf9,0xf0,0x74,0x32,0x12,0x2c,0x3f,
+0xd2,0x08,0x90,0x05,0xca,0x74,0x32,0xf0,0x80,0x1b,0x90,0x04,0x00,0x74,0x01,0xf0,
+0xa3,0x74,0x03,0xf0,0xa3,0x74,0xf9,0xf0,0x74,0x3c,0x12,0x2c,0x3f,0xd2,0x08,0x90,
+0x05,0xca,0x74,0x3c,0xf0,0x90,0x05,0xcb,0xe0,0xfd,0x7f,0x16,0x7e,0xe6,0x12,0x96,
+0xbd,0x90,0x04,0xde,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x04,0xc9,0xe0,0xfe,0xa3,0xe0,
+0xff,0xd3,0x9b,0xee,0x9a,0x40,0x0f,0xef,0x24,0x0a,0xff,0xe4,0x3e,0x90,0x03,0xfb,
+0xf0,0xa3,0xef,0xf0,0x80,0x08,0x90,0x03,0xfb,0xea,0xf0,0xa3,0xeb,0xf0,0x7c,0x00,
+0x90,0x03,0xfc,0xe0,0xfd,0x7f,0x21,0x7e,0x00,0x12,0x93,0xa8,0x7f,0x05,0x7e,0x00,
+0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xfb,0xe0,0xfd,0x7c,0x00,0x7f,0x20,
+0x7e,0x00,0x12,0x93,0xa8,0x7f,0x05,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,
+0x7c,0x00,0x90,0x03,0xf8,0xe0,0xfd,0x7f,0x1f,0x7e,0x00,0x12,0x93,0xa8,0x7f,0x05,
+0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xf7,0xe0,0xfd,0x7c,0x00,
+0x7f,0x1e,0x7e,0x00,0x12,0x93,0xa8,0x7f,0x05,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,
+0x96,0xcb,0x7c,0x00,0x90,0x03,0xfa,0xe0,0xfd,0x7f,0x12,0x7e,0x00,0x12,0x93,0xa8,
+0x7f,0x05,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xf9,0xe0,0xfd,
+0x7c,0x00,0x7f,0x11,0x7e,0x00,0x12,0x93,0xa8,0x7f,0x05,0x7e,0x00,0x7d,0x00,0x7c,
+0x00,0x02,0x96,0xcb,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x04,0x13,0x12,0x1f,0xa6,0x90,0x05,0xf5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,
+0xa3,0xe0,0xff,0x90,0x04,0x0f,0x12,0x1f,0xa6,0x90,0x04,0x13,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,0x0f,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,
+0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x40,0x05,0x90,0x04,0x0f,0x80,0x03,
+0x90,0x04,0x13,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x04,
+0x17,0x12,0x1f,0xa6,0xe4,0xff,0xfe,0xfd,0xfc,0x90,0x04,0x17,0xe0,0xf8,0xa3,0xe0,
+0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x50,0x0a,0x90,0x04,0x17,
+0x12,0x1f,0xb2,0x00,0x00,0x00,0x01,0x90,0x04,0x13,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,
+0x07,0x90,0x04,0x0f,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,
+0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x43,0xe4,0xfb,
+0xfa,0xf9,0xf8,0x12,0x19,0xde,0x90,0x04,0x13,0x60,0x3b,0x40,0x39,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xc0,0x04,0xc0,0x05,
+0xc0,0x06,0xc0,0x07,0x90,0x04,0x0f,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,
+0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,
+0x43,0x12,0x1a,0x4b,0x80,0x34,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0xe4,0x12,0x1a,0x5c,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x0f,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xd0,
+0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,0x17,0x43,0xe4,0xfb,0xfa,0x79,0xc8,0x78,
+0x42,0x12,0x18,0x38,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0x17,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0xe4,0x12,0x1a,0x5c,0xa8,0x04,
+0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,
+0x41,0x22,0xc3,0xee,0x64,0x80,0x94,0x80,0x40,0x76,0xef,0x94,0xab,0xee,0x64,0x80,
+0x94,0x81,0x50,0x6c,0xc3,0xec,0x64,0x80,0x94,0x80,0x40,0x21,0xed,0x94,0x40,0xec,
+0x64,0x80,0x94,0x81,0x50,0x17,0x90,0x03,0x0e,0x74,0x01,0xf0,0x90,0x02,0x6f,0xa3,
+0xe0,0x04,0xff,0x90,0x03,0x07,0xf0,0x90,0x02,0x6f,0x02,0x73,0x46,0xc3,0xed,0x94,
+0x40,0xec,0x64,0x80,0x94,0x81,0x40,0x21,0xed,0x94,0x80,0xec,0x64,0x80,0x94,0x82,
+0x50,0x17,0x90,0x03,0x0e,0x74,0x04,0xf0,0x90,0x02,0x75,0xa3,0xe0,0x04,0xff,0x90,
+0x03,0x07,0xf0,0x90,0x02,0x75,0x02,0x73,0x46,0x90,0x03,0x0e,0x74,0x07,0xf0,0x90,
+0x02,0x7b,0xa3,0xe0,0x04,0xff,0x90,0x03,0x07,0xf0,0x90,0x02,0x7b,0x02,0x73,0x46,
+0xc3,0xef,0x94,0xab,0xee,0x64,0x80,0x94,0x81,0x40,0x74,0xef,0x94,0x55,0xee,0x64,
+0x80,0x94,0x83,0x50,0x6a,0xc3,0xec,0x64,0x80,0x94,0x80,0x40,0x21,0xed,0x94,0x40,
+0xec,0x64,0x80,0x94,0x81,0x50,0x17,0x90,0x03,0x0e,0x74,0x02,0xf0,0x90,0x02,0x71,
+0xa3,0xe0,0x04,0xff,0x90,0x03,0x07,0xf0,0x90,0x02,0x71,0x02,0x73,0x46,0xc3,0xed,
+0x94,0x40,0xec,0x64,0x80,0x94,0x81,0x40,0x20,0xed,0x94,0x80,0xec,0x64,0x80,0x94,
+0x82,0x50,0x16,0x90,0x03,0x0e,0x74,0x05,0xf0,0x90,0x02,0x77,0xa3,0xe0,0x04,0xff,
+0x90,0x03,0x07,0xf0,0x90,0x02,0x77,0x80,0x7d,0x90,0x03,0x0e,0x74,0x08,0xf0,0x90,
+0x02,0x7d,0xa3,0xe0,0x04,0xff,0x90,0x03,0x07,0xf0,0x90,0x02,0x7d,0x80,0x67,0xc3,
+0xec,0x64,0x80,0x94,0x80,0x40,0x20,0xed,0x94,0x40,0xec,0x64,0x80,0x94,0x81,0x50,
+0x16,0x90,0x03,0x0e,0x74,0x03,0xf0,0x90,0x02,0x73,0xa3,0xe0,0x04,0xff,0x90,0x03,
+0x07,0xf0,0x90,0x02,0x73,0x80,0x3f,0xc3,0xed,0x94,0x40,0xec,0x64,0x80,0x94,0x81,
+0x40,0x20,0xed,0x94,0x80,0xec,0x64,0x80,0x94,0x82,0x50,0x16,0x90,0x03,0x0e,0x74,
+0x06,0xf0,0x90,0x02,0x79,0xa3,0xe0,0x04,0xff,0x90,0x03,0x07,0xf0,0x90,0x02,0x79,
+0x80,0x14,0x90,0x03,0x0e,0x74,0x09,0xf0,0x90,0x02,0x7f,0xa3,0xe0,0x04,0xff,0x90,
+0x03,0x07,0xf0,0x90,0x02,0x7f,0xe4,0xf0,0xa3,0xef,0xf0,0x22,0xe4,0x90,0x03,0xf7,
+0xf0,0x90,0x03,0xc9,0xe0,0x24,0xfd,0x50,0x03,0x02,0x74,0x81,0x90,0x05,0xf1,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf5,0xe0,0xf8,0xa3,
+0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,0xea,0x50,0x10,0x90,0x03,
+0xd4,0xe0,0x04,0xf0,0x70,0x0f,0x90,0x03,0xd3,0xe0,0x04,0xf0,0x80,0x07,0xe4,0x90,
+0x03,0xd3,0xf0,0xa3,0xf0,0x90,0x03,0xd3,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x94,0x03,
+0xee,0x64,0x80,0x94,0x80,0x40,0x03,0x02,0x74,0x67,0xc3,0xef,0x94,0x02,0xee,0x64,
+0x80,0x94,0x80,0x40,0x53,0xe4,0xff,0xfe,0xfd,0x7c,0x01,0x90,0x05,0xf5,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x50,0x03,0x02,
+0x74,0x6d,0xe4,0x7f,0x09,0xfe,0xfd,0xfc,0x90,0x03,0x22,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x1d,0x9c,0xe4,0x7b,0x0a,0xfa,0xf9,0xf8,0x12,
+0x1e,0x27,0x90,0x05,0xf5,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,
+0xc3,0x12,0x1e,0xea,0x50,0x67,0x80,0x5f,0xc3,0x90,0x03,0xd4,0xe0,0x94,0x01,0x90,
+0x03,0xd3,0xe0,0x64,0x80,0x94,0x80,0x40,0x54,0xe4,0xff,0xfe,0xfd,0x7c,0x01,0x90,
+0x05,0xf5,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,
+0xea,0x40,0x3a,0xe4,0x7f,0x09,0xfe,0xfd,0xfc,0x90,0x03,0x22,0xe0,0xf8,0xa3,0xe0,
+0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x1d,0x9c,0xe4,0x7b,0x0a,0xfa,0xf9,0xf8,
+0x12,0x1e,0x27,0x90,0x05,0xf5,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xfb,0xc3,0x12,0x1e,0xea,0x50,0x06,0x90,0x03,0xf7,0x74,0x01,0xf0,0x90,0x05,0xf5,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf1,0x12,0x1f,
+0xa6,0x90,0x03,0xf7,0xe0,0xff,0x22,0xe4,0xff,0xfe,0x90,0x02,0x09,0x75,0xf0,0x0a,
+0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,
+0xf0,0x90,0x02,0x0b,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,
+0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0x02,0x0d,0x75,0xf0,0x0a,0xef,0x12,
+0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,
+0x02,0x0f,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,
+0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0x02,0x11,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,
+0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0x90,0x02,0x12,0x75,0xf0,
+0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,
+0x90,0x02,0x99,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,
+0x83,0xf5,0x83,0xe4,0xf0,0x90,0x02,0x9a,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,
+0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0x02,0x9c,0x75,
+0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe4,
+0xf0,0xa3,0xf0,0x90,0x02,0x9e,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,
+0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,0x90,0x02,0xa0,0x75,0xf0,0x0b,
+0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,
+0xf0,0x90,0x02,0xa2,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0b,0xa4,
+0x25,0x83,0xf5,0x83,0xe4,0xf0,0x90,0x02,0xa3,0x75,0xf0,0x0b,0xef,0x12,0x1f,0xf4,
+0xee,0x75,0xf0,0x0b,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0x0f,0xbf,0x00,0x01,0x0e,
+0xef,0x64,0x0a,0x4e,0x60,0x03,0x02,0x74,0x8a,0xe4,0x90,0x04,0xec,0xf0,0xa3,0xf0,
+0x22,0x90,0x05,0x3b,0x74,0x05,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,0x03,0xf0,0xa3,0x74,
+0xc0,0xf0,0x90,0x05,0x37,0x74,0x0a,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,0x07,0xf0,0xa3,
+0x74,0x80,0xf0,0x90,0x05,0x3f,0x74,0x0b,0xf0,0xa3,0x74,0xb8,0xf0,0xa3,0x74,0x05,
+0xf0,0xa3,0x74,0xdc,0xf0,0xa3,0x74,0x0f,0xf0,0xa3,0x74,0xa0,0xf0,0xa3,0x74,0x0a,
+0xf0,0xa3,0x74,0xf0,0xf0,0x90,0x05,0x4a,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0xa3,0x74,
+0x01,0xf0,0xa3,0xe4,0xf0,0x90,0x05,0x48,0xf0,0xa3,0x74,0x28,0xf0,0x90,0x05,0x4e,
+0xe4,0xf0,0xa3,0x74,0x3c,0xf0,0x90,0x05,0x54,0x74,0x0f,0xf0,0xa3,0x74,0xa0,0xf0,
+0xa3,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0x90,0x05,
+0x47,0x74,0xd0,0xf0,0x90,0x04,0xf2,0x74,0x01,0xf0,0xa3,0xf0,0xa3,0x74,0xff,0xf0,
+0xa3,0x74,0x00,0xf0,0xa3,0x74,0x0e,0xf0,0xe4,0xa3,0xf0,0x12,0x92,0x7b,0xe4,0x90,
+0x04,0xf8,0xf0,0xa3,0x74,0xff,0xf0,0xa3,0x74,0x52,0xf0,0xa3,0x74,0xf5,0xf0,0xe4,
+0xa3,0xf0,0x12,0x97,0xdf,0x90,0x04,0xfd,0x74,0x01,0xf0,0xa3,0x74,0xff,0xf0,0xa3,
+0x74,0x34,0xf0,0xa3,0x74,0xe7,0xf0,0xe4,0xa3,0xf0,0x12,0x8f,0x9e,0x90,0x05,0x16,
+0x74,0x01,0xf0,0xa3,0x74,0xff,0xf0,0xa3,0x74,0x93,0xf0,0xa3,0x74,0x39,0xf0,0xe4,
+0xa3,0xf0,0x12,0x98,0x04,0xe4,0x90,0x05,0x07,0xf0,0xa3,0x74,0xff,0xf0,0xa3,0x74,
+0x7b,0xf0,0xa3,0x74,0x97,0xf0,0xe4,0xa3,0xf0,0x90,0x05,0x02,0xf0,0xa3,0x74,0xff,
+0xf0,0xa3,0x74,0x0d,0xf0,0xa3,0x74,0x40,0xf0,0xe4,0xa3,0xf0,0x90,0x05,0x0c,0xf0,
+0xa3,0x74,0xff,0xf0,0xa3,0x74,0x58,0xf0,0xa3,0x74,0xdc,0xf0,0xe4,0xa3,0xf0,0x22,
+0x90,0x05,0xff,0x12,0x1f,0xa6,0x90,0x06,0x0b,0x12,0x1f,0xb2,0xff,0xff,0xff,0xff,
+0x90,0x06,0x0b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x06,
+0x03,0xa3,0xe0,0xfb,0xc3,0x74,0x1f,0x9b,0xfb,0xf8,0x12,0x1f,0x0e,0x90,0x06,0x0b,
+0x12,0x1f,0xa6,0x90,0x06,0x0b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0x90,0x06,0x05,0xa3,0xe0,0xfa,0x2b,0xf9,0xf8,0x12,0x1e,0xfb,0x90,0x06,0x0b,
+0x12,0x1f,0xa6,0x90,0x06,0x0b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0xa8,0x02,0x12,0x1f,0x0e,0x90,0x06,0x0b,0x12,0x1f,0xa6,0x90,0x06,0x0b,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x1e,0xb9,0x90,0x06,0x0b,
+0x12,0x1f,0xa6,0x90,0x05,0xff,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0x90,0x06,0x0f,0x12,0x1f,0xa6,0x90,0x06,0x0f,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,
+0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x06,0x0b,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xfb,0xef,0x5b,0xff,0xee,0x5a,0xfe,0xed,0x59,0xfd,0xec,0x58,0xfc,0xa3,
+0x12,0x1f,0xa6,0x90,0x06,0x07,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0x90,0x06,0x05,0xa3,0xe0,0xf9,0xf8,0x12,0x1f,0x0e,0x90,0x06,0x0f,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0x4f,0xff,0xea,0x4e,0xfe,0xe9,0x4d,0xfd,
+0xe8,0x4c,0xfc,0x90,0x06,0x0f,0x12,0x1f,0xa6,0x90,0x06,0x0f,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x12,0x8d,0x77,0x7f,0x04,0x7e,0xe0,0x12,
+0x96,0x64,0xef,0x54,0x7f,0xfd,0x7f,0x04,0x7e,0xe0,0x12,0x96,0xbd,0x90,0x02,0x8c,
+0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,
+0xc0,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x8e,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,
+0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xc1,0x7e,0xe6,0x12,0x96,0xbd,0x90,
+0x02,0x84,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,
+0xfd,0x7f,0xc2,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x86,0xe0,0xfe,0xa3,0xe0,0x78,
+0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xc3,0x7e,0xe6,0x12,0x96,
+0xbd,0x90,0x02,0x91,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,
+0xd8,0xf8,0xfd,0x7f,0xd8,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x93,0xe0,0xfe,0xa3,
+0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xd9,0x7e,0xe6,
+0x12,0x96,0xbd,0x90,0x02,0x88,0xe0,0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,
+0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xda,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x02,0x8a,0xe0,
+0xfe,0xa3,0xe0,0x78,0x04,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0xdb,
+0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x07,0x7e,0xf2,0x12,0x96,0xbd,0xe4,0x90,
+0x05,0x02,0xf0,0xfd,0x7f,0x07,0x7e,0xf2,0x12,0x96,0xbd,0x90,0x02,0x90,0xe0,0xfd,
+0x7f,0x1e,0x7e,0xee,0x02,0x96,0xbd,0x90,0x03,0xe5,0xef,0xf0,0x90,0x05,0xf5,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xea,0x12,0x1f,0xa6,
+0x90,0x03,0x1c,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,0xe8,0xee,0xf0,0xa3,0xef,0xf0,
+0xd3,0x90,0x03,0xc6,0xe0,0x94,0x18,0x90,0x03,0xc5,0xe0,0x64,0x80,0x94,0x80,0x40,
+0x5b,0x90,0x03,0xee,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,0xee,0xe0,0xfe,0xa3,0xe0,
+0xff,0xc3,0x94,0x19,0xee,0x64,0x80,0x94,0x80,0x50,0x38,0x7c,0x00,0x7d,0x06,0x12,
+0x1c,0x50,0x74,0x2a,0x2f,0xf9,0x74,0x03,0x3e,0xfa,0x7b,0x01,0xc0,0x01,0x74,0x24,
+0x2f,0xf9,0x74,0x03,0x3e,0xa8,0x01,0xfc,0x7d,0x01,0xd0,0x01,0x7e,0x00,0x7f,0x06,
+0x12,0x1b,0xeb,0x90,0x03,0xef,0xe0,0x04,0xf0,0x70,0xbe,0x90,0x03,0xee,0xe0,0x04,
+0xf0,0x80,0xb6,0x90,0x03,0xc5,0xe4,0xf0,0xa3,0x74,0x18,0xf0,0x90,0x03,0xe8,0xe0,
+0xfe,0xa3,0xe0,0xff,0x90,0x03,0xc5,0xe0,0xfa,0xa3,0xe0,0xfb,0x90,0x03,0x2a,0x75,
+0xf0,0x06,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x03,0xea,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,
+0xff,0x90,0x03,0x2c,0x75,0xf0,0x06,0xeb,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,
+0x25,0x83,0xf5,0x83,0x12,0x1f,0xa6,0x90,0x03,0xc6,0xe0,0x04,0xf0,0x70,0x06,0x90,
+0x03,0xc5,0xe0,0x04,0xf0,0x22,0x90,0x04,0xc9,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,
+0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x04,0xe1,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,
+0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,0x19,0x41,0x90,0x03,0xe6,0x12,0x1f,0xa6,0x90,
+0x04,0x99,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xc0,0x04,0xc0,0x05,0xc0,
+0x06,0xc0,0x07,0x90,0x04,0x70,0xe0,0xfc,0xa3,0xe0,0xfd,0xe4,0x12,0x1a,0x61,0xa8,
+0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0x12,
+0x19,0x41,0x90,0x03,0xea,0x12,0x1f,0xa6,0x90,0x04,0x70,0xe0,0xfc,0xa3,0xe0,0xfd,
+0xe4,0x12,0x1a,0x61,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0xe4,0xff,0xfe,0xfd,
+0x7c,0x41,0x12,0x19,0x41,0xa8,0x04,0xa9,0x05,0xaa,0x06,0xab,0x07,0x90,0x03,0xea,
+0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x17,0x43,0xc0,0x04,
+0xc0,0x05,0xc0,0x06,0xc0,0x07,0x90,0x03,0xe6,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,
+0xfe,0xa3,0xe0,0xff,0x12,0x1a,0x4b,0xd0,0x03,0xd0,0x02,0xd0,0x01,0xd0,0x00,0x12,
+0x17,0x43,0xe4,0xfb,0xfa,0x79,0x20,0x78,0x41,0x12,0x18,0x38,0xe4,0xfb,0xfa,0x79,
+0xd0,0x78,0x41,0x12,0x17,0x47,0x12,0x1a,0x9a,0x22,0x90,0x03,0xe5,0xef,0xf0,0xa3,
+0xed,0xf0,0xa3,0xeb,0xf0,0xd3,0x90,0x05,0xb8,0xe0,0x94,0x13,0x90,0x05,0xb7,0xe0,
+0x64,0x80,0x94,0x80,0x40,0x5e,0x90,0x03,0xe9,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x03,
+0xe9,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x94,0x14,0xee,0x64,0x80,0x94,0x80,0x50,0x3b,
+0xef,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x24,0x62,0xf9,0x74,0x05,
+0x3e,0xfa,0x7b,0x01,0xc0,0x01,0x74,0x5e,0x2f,0xf9,0x74,0x05,0x3e,0xa8,0x01,0xfc,
+0x7d,0x01,0xd0,0x01,0x7e,0x00,0x7f,0x04,0x12,0x1b,0xeb,0x90,0x03,0xea,0xe0,0x04,
+0xf0,0x70,0xbb,0x90,0x03,0xe9,0xe0,0x04,0xf0,0x80,0xb3,0x90,0x05,0xb7,0xe4,0xf0,
+0xa3,0x74,0x13,0xf0,0x90,0x03,0xe5,0xe0,0xfd,0x90,0x05,0xb7,0xe0,0xfe,0xa3,0xe0,
+0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x24,0x62,0xf5,0x82,0x74,0x05,
+0x3e,0xf5,0x83,0xed,0xf0,0x90,0x03,0xe6,0xe0,0xfd,0x74,0x63,0x2f,0xf5,0x82,0x74,
+0x05,0x3e,0xf5,0x83,0xed,0xf0,0x90,0x03,0xe7,0xe0,0xfd,0x74,0x64,0x2f,0xf5,0x82,
+0x74,0x05,0x3e,0xf5,0x83,0xed,0xf0,0x90,0x03,0xe8,0xe0,0xfd,0x74,0x65,0x2f,0xf5,
+0x82,0x74,0x05,0x3e,0xf5,0x83,0xed,0xf0,0x90,0x05,0xb8,0xe0,0x04,0xf0,0x70,0x06,
+0x90,0x05,0xb7,0xe0,0x04,0xf0,0x22,0x90,0x05,0x52,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x03,0xdf,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x05,0x50,0xe0,0xfd,0xa3,0xe0,0x90,0x03,
+0xe1,0xcd,0xf0,0xa3,0xed,0xf0,0x7d,0x0c,0x7c,0x00,0x12,0x1c,0x62,0x90,0x03,0xe1,
+0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x1c,0x50,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x05,
+0x47,0xe0,0x64,0xd0,0x70,0x03,0x02,0x7c,0x72,0x7f,0x70,0x7e,0xe6,0x12,0x96,0x64,
+0x90,0x06,0x35,0xef,0xf0,0xfb,0x7a,0x00,0x90,0x03,0xdf,0xe0,0xfc,0xa3,0xe0,0xfd,
+0x7e,0x00,0x12,0x1c,0x50,0x90,0x06,0x38,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe1,
+0xe0,0xfe,0xa3,0xe0,0xff,0xad,0x03,0x7c,0x00,0x12,0x1c,0x62,0x90,0x06,0x36,0xee,
+0xf0,0xa3,0xef,0xf0,0xd3,0x90,0x06,0x39,0xe0,0x94,0x7f,0x90,0x06,0x38,0xe0,0x94,
+0x00,0x40,0x06,0xe4,0xf0,0xa3,0x74,0x7f,0xf0,0xc3,0x90,0x06,0x37,0xe0,0x94,0x01,
+0x90,0x06,0x36,0xe0,0x94,0x00,0x50,0x05,0xe4,0xf0,0xa3,0x04,0xf0,0x7f,0x71,0x7e,
+0xe6,0x12,0x96,0x64,0x90,0x06,0x3a,0xef,0xf0,0x90,0x06,0x36,0xe0,0xfe,0xa3,0xe0,
+0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x12,0x6e,0xf9,0x90,0x06,0x38,0xe0,0xfe,0xa3,
+0xe0,0xff,0x90,0x06,0x36,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x06,0x3a,0xe0,0xfb,0x12,
+0x41,0x65,0x22,0x90,0x04,0x23,0xee,0xf0,0xa3,0xef,0xf0,0xe4,0xff,0xfe,0xd3,0x90,
+0x04,0x24,0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x04,0x23,0xe0,0x64,0x80,0x98,0x50,
+0x03,0x02,0x7d,0x44,0x90,0x02,0x09,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,
+0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x03,0x0f,0xe0,
+0xfa,0xa3,0xe0,0xfb,0xc3,0xed,0x9b,0xea,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x50,
+0x7b,0x90,0x02,0x0d,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,
+0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xd3,0x9b,0xea,0x64,0x80,0xf8,0xec,0x64,
+0x80,0x98,0x40,0x58,0x90,0x02,0x0b,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,
+0xf0,0x0a,0xa4,0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xfd,0x90,0x03,0x11,0xe0,
+0xfa,0xa3,0xe0,0xfb,0xc3,0xed,0x9b,0xea,0x64,0x80,0xf8,0xec,0x64,0x80,0x98,0x50,
+0x2b,0x90,0x02,0x0f,0x75,0xf0,0x0a,0xef,0x12,0x1f,0xf4,0xee,0x75,0xf0,0x0a,0xa4,
+0x25,0x83,0xf5,0x83,0xe0,0xfc,0xa3,0xe0,0xd3,0x9b,0xea,0x64,0x80,0xf8,0xec,0x64,
+0x80,0x98,0x40,0x08,0x90,0x04,0x25,0xee,0xf0,0xa3,0xef,0xf0,0x0f,0xbf,0x00,0x01,
+0x0e,0x02,0x7c,0x7e,0x90,0x04,0x25,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x90,0x03,0xe8,
+0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x75,0x0c,0x32,0xe4,0xf5,0x08,0xf5,0x09,
+0x90,0x03,0xe8,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x85,0x09,0x82,0x85,0x08,
+0x83,0x74,0x03,0x12,0x1f,0xe3,0x12,0x1c,0x11,0xb4,0xff,0x2b,0xae,0x08,0xaf,0x09,
+0x7c,0x00,0x7d,0x03,0x12,0x1c,0x50,0x90,0x03,0xe8,0xa3,0xa3,0xe0,0x2f,0xf9,0xea,
+0x3e,0xfa,0x90,0x00,0x01,0x12,0x1c,0x11,0xb4,0xff,0x0c,0x90,0x00,0x02,0x12,0x1c,
+0x11,0xf4,0x70,0x03,0x02,0x7e,0x24,0xae,0x08,0xaf,0x09,0x7c,0x00,0x7d,0x03,0x12,
+0x1c,0x50,0x90,0x03,0xe8,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0x2f,0xf9,0xea,0x3e,
+0xfa,0x90,0x00,0x01,0x12,0x1c,0x11,0xfd,0x90,0x03,0xe8,0xa3,0xe0,0xfa,0xa3,0xe0,
+0xf9,0x85,0x09,0x82,0x85,0x08,0x83,0x74,0x03,0x12,0x1f,0xe3,0x12,0x1c,0x11,0xfe,
+0xe4,0x2d,0xf5,0x0b,0xec,0x3e,0xf5,0x0a,0xae,0x08,0xaf,0x09,0x7d,0x03,0x12,0x1c,
+0x50,0xe9,0x2f,0xf9,0xea,0x3e,0xfa,0x90,0x00,0x02,0x12,0x1c,0x11,0xf5,0x0c,0xe5,
+0x0b,0x45,0x0a,0x60,0x0b,0xad,0x0c,0xaf,0x0b,0xae,0x0a,0x12,0x96,0xbd,0x80,0x09,
+0xaf,0x0c,0xe4,0xfc,0xfd,0xfe,0x12,0x96,0xcb,0x05,0x09,0xe5,0x09,0x70,0x02,0x05,
+0x08,0x02,0x7d,0x60,0x22,0x7f,0x98,0x7e,0xeb,0x12,0x96,0x64,0x90,0x02,0x08,0xef,
+0xf0,0x14,0xb4,0x07,0x00,0x40,0x03,0x02,0x7e,0xef,0x90,0x7e,0x48,0x75,0xf0,0x03,
+0xa4,0xc5,0x83,0x25,0xf0,0xc5,0x83,0x73,0x02,0x7e,0x5d,0x02,0x7e,0x72,0x02,0x7e,
+0x87,0x02,0x7e,0x9c,0x02,0x7e,0xb1,0x02,0x7e,0xc6,0x02,0x7e,0xdb,0x90,0x01,0xc4,
+0x74,0x07,0xf0,0xa3,0x74,0x45,0xf0,0x90,0x01,0x59,0x74,0x04,0xf0,0xa3,0x74,0x79,
+0xf0,0x22,0x90,0x01,0xc4,0x74,0x06,0xf0,0xa3,0x74,0xc8,0xf0,0x90,0x01,0x59,0x74,
+0x05,0xf0,0xa3,0x74,0x76,0xf0,0x22,0x90,0x01,0xc4,0x74,0x05,0xf0,0xa3,0x74,0x17,
+0xf0,0x90,0x01,0x59,0x74,0x05,0xf0,0xa3,0x74,0x6f,0xf0,0x22,0x90,0x01,0xc4,0x74,
+0x05,0xf0,0xa3,0x74,0x2a,0xf0,0x90,0x01,0x59,0x74,0x06,0xf0,0xa3,0x74,0x92,0xf0,
+0x22,0x90,0x01,0xc4,0x74,0x05,0xf0,0xa3,0x74,0x22,0xf0,0x90,0x01,0x59,0x74,0x06,
+0xf0,0xa3,0x74,0xec,0xf0,0x22,0x90,0x01,0xc4,0x74,0x04,0xf0,0xa3,0x74,0x01,0xf0,
+0x90,0x01,0x59,0x74,0x09,0xf0,0xa3,0x74,0x45,0xf0,0x22,0x90,0x01,0xc4,0x74,0x03,
+0xf0,0xa3,0x74,0x80,0xf0,0x90,0x01,0x59,0x74,0x09,0xf0,0xa3,0x74,0x60,0xf0,0x22,
+0x7f,0x59,0x7e,0xe0,0x12,0x96,0x64,0xab,0x07,0x7a,0x00,0x90,0x05,0xe6,0x12,0x1f,
+0xb2,0x42,0xa4,0x00,0x00,0xeb,0x30,0xe0,0x39,0x90,0x05,0xec,0xe4,0xf0,0xa3,0x04,
+0xf0,0x90,0x05,0x47,0xe0,0x64,0xdb,0x70,0x69,0x90,0x05,0xc5,0x74,0x0c,0xf0,0xa3,
+0x74,0xb7,0xf0,0x90,0x05,0xcc,0x74,0x0a,0xf0,0xa3,0x74,0xe6,0xf0,0x90,0x05,0xd5,
+0x74,0x02,0xf0,0xa3,0xe4,0xf0,0x90,0x05,0xe0,0x12,0x1f,0xb2,0x42,0x34,0x00,0x00,
+0x80,0x37,0x90,0x05,0xec,0xe4,0xf0,0xa3,0x74,0x02,0xf0,0x90,0x05,0x47,0xe0,0xb4,
+0xdb,0x30,0x90,0x05,0xc5,0x74,0x07,0xf0,0xa3,0x74,0x80,0xf0,0x90,0x05,0xcc,0x74,
+0x07,0xf0,0xa3,0x74,0x76,0xf0,0x90,0x05,0xd5,0x74,0x02,0xf0,0xa3,0xe4,0xf0,0x90,
+0x05,0xe0,0x12,0x1f,0xb2,0x42,0x96,0x00,0x00,0x90,0x05,0xfd,0xe4,0xf0,0xa3,0x74,
+0x37,0xf0,0x90,0x05,0xe0,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,
+0x90,0x05,0xe6,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x12,0x19,
+0x41,0x90,0x05,0xda,0x12,0x1f,0xa6,0x90,0x05,0x58,0xe4,0xf0,0xa3,0x74,0x20,0xf0,
+0x90,0x05,0xde,0x74,0x02,0xf0,0xa3,0xe4,0xf0,0x22,0x7d,0xff,0x7f,0x71,0x7e,0xed,
+0x12,0x96,0xbd,0x90,0x05,0x47,0x74,0xd5,0xf0,0x7f,0x12,0x7e,0xe0,0x12,0x96,0x64,
+0x90,0x03,0xe5,0xef,0xf0,0x7d,0x02,0x7f,0x12,0x7e,0xe0,0x12,0x96,0xbd,0x7b,0xff,
+0x7a,0xa4,0x79,0x95,0x12,0x7d,0x4d,0x90,0x03,0xe5,0xe0,0xfd,0x7f,0x12,0x7e,0xe0,
+0x12,0x96,0xbd,0x12,0x39,0x2d,0xe4,0xfd,0x7f,0x71,0x7e,0xed,0x02,0x96,0xbd,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x7f,0xa8,0x7e,0xe6,0x12,0x96,0x64,0xef,0x24,0xfa,0x60,0x21,0x14,0x60,0x32,0x14,
+0x60,0x42,0x24,0x03,0x60,0x03,0x02,0x81,0xc4,0x90,0x03,0xe8,0x74,0x03,0xf0,0xa3,
+0x74,0x20,0xf0,0xa3,0x74,0x02,0xf0,0xa3,0x74,0x58,0xf0,0x80,0x37,0x90,0x03,0xe8,
+0x74,0x02,0xf0,0xa3,0x74,0x80,0xf0,0xa3,0x74,0x01,0xf0,0xa3,0x74,0xe0,0xf0,0x80,
+0x23,0x90,0x03,0xe8,0x74,0x01,0xf0,0xa3,0x74,0x40,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,
+0xf0,0xf0,0x80,0x10,0x90,0x03,0xe8,0xe4,0xf0,0xa3,0x74,0xa0,0xf0,0xa3,0xe4,0xf0,
+0xa3,0x74,0x78,0xf0,0x90,0x03,0xe8,0xe0,0xfd,0x7f,0x5c,0x7e,0xed,0x12,0x96,0xbd,
+0x90,0x03,0xe9,0xe0,0xfd,0x7f,0x5d,0x7e,0xed,0x12,0x96,0xbd,0x90,0x03,0xea,0xe0,
+0xfd,0x7f,0x5e,0x7e,0xed,0x12,0x96,0xbd,0x90,0x03,0xeb,0xe0,0xfd,0x7f,0x5f,0x7e,
+0xed,0x12,0x96,0xbd,0x90,0x03,0xe8,0xe0,0xfd,0x7f,0x10,0x7e,0xee,0x12,0x96,0xbd,
+0x90,0x03,0xe9,0xe0,0xfd,0x7f,0x11,0x7e,0xee,0x12,0x96,0xbd,0x90,0x03,0xea,0xe0,
+0xfd,0x7f,0x12,0x7e,0xee,0x12,0x96,0xbd,0x90,0x03,0xeb,0xe0,0xfd,0x7f,0x13,0x7e,
+0xee,0x12,0x96,0xbd,0x22,0x90,0x03,0xdf,0xe5,0xa8,0xf0,0x90,0x06,0x43,0xe0,0x70,
+0x02,0xa3,0xe0,0x70,0x03,0x02,0x82,0x85,0x90,0x06,0x5f,0xe0,0x70,0x03,0x02,0x82,
+0x7e,0x90,0x04,0xf3,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x04,0xfd,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x05,0x02,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x04,0xf8,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x05,0x07,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x05,0x16,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x05,0x0c,0xe0,0x60,0x0a,0xa3,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0x12,0x20,
+0x8d,0x90,0x06,0x3e,0xa3,0xa3,0xa3,0xe0,0x54,0x03,0xff,0xe4,0xfe,0xfd,0xfc,0x12,
+0x20,0x53,0x82,0x7e,0x00,0x00,0x00,0x00,0x82,0x7e,0x00,0x00,0x00,0x01,0x82,0x7e,
+0x00,0x00,0x00,0x02,0x82,0x7e,0x00,0x00,0x00,0x03,0x00,0x00,0x82,0x7e,0xe4,0x90,
+0x06,0x43,0xf0,0xa3,0xf0,0x22,0x90,0x03,0xc0,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x03,
+0xf7,0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xee,0xf0,0xa3,0xef,0xf0,0x7d,0x07,0x7f,0x3c,
+0x7e,0xe0,0x12,0x96,0xbd,0x7d,0x52,0x7f,0x31,0x7e,0xe0,0x12,0x96,0xbd,0x7d,0x01,
+0x7f,0x32,0x7e,0xe0,0x12,0x96,0xbd,0x7d,0x18,0x7f,0x30,0x7e,0xe0,0x12,0x96,0xbd,
+0x7f,0x46,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xf9,0xe0,0xfe,
+0xa3,0xe0,0x78,0x02,0xce,0xa2,0xe7,0x13,0xce,0x13,0xd8,0xf8,0xfd,0x7f,0x34,0x7e,
+0xe0,0x12,0x96,0xbd,0x90,0x03,0xf9,0xe0,0xfe,0xa3,0xe0,0x78,0x06,0xc3,0x33,0xce,
+0x33,0xce,0xd8,0xf9,0xfd,0x7f,0x36,0x7e,0xe0,0x12,0x96,0xbd,0x7f,0x46,0x7e,0x00,
+0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x7d,0x22,0x7f,0x30,0x7e,0xe0,0x12,0x96,0xbd,
+0xe4,0xfd,0x7f,0x32,0x7e,0xe0,0x12,0x96,0xbd,0x7d,0x51,0x7f,0x31,0x7e,0xe0,0x12,
+0x96,0xbd,0x7f,0x46,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xf9,
+0xa3,0xe0,0xfd,0x7f,0x65,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0xf7,0xe0,0xfe,0xa3,
+0xe0,0xff,0x22,0x7f,0x2a,0x7e,0xe6,0x12,0x96,0x64,0xef,0x24,0xf9,0x60,0x21,0x24,
+0xfc,0x60,0x38,0x24,0x0b,0x60,0x03,0x02,0x83,0xfc,0x90,0x03,0x1c,0xe0,0xff,0x33,
+0x95,0xe0,0xad,0x07,0x7f,0x28,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0x1c,0x80,0x14,
+0x90,0x03,0xdc,0xe0,0xff,0x33,0x95,0xe0,0xad,0x07,0x7f,0x28,0x7e,0xe6,0x12,0x96,
+0xbd,0x90,0x03,0xdc,0xa3,0xe0,0xfd,0x7f,0x29,0x80,0x6c,0x12,0x6a,0x41,0x90,0x03,
+0xe5,0x12,0x1f,0xa6,0x90,0x03,0xe5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,
+0xe0,0xff,0x78,0x18,0x12,0x1e,0xfb,0xad,0x07,0x7f,0x28,0x7e,0xe6,0x12,0x96,0xbd,
+0x90,0x03,0xe5,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x78,0x10,
+0x12,0x1e,0xfb,0xad,0x07,0x7f,0x29,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0xe5,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x78,0x08,0x12,0x1e,0xfb,0xad,
+0x07,0x7f,0x2a,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0xe5,0xe0,0xfc,0xa3,0xa3,0xa3,
+0xe0,0xff,0xe4,0xad,0x07,0x7f,0x2b,0x7e,0xe6,0x12,0x96,0xbd,0x22,0x90,0x06,0x27,
+0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xea,0xf0,0xa3,0xeb,
+0xf0,0x74,0xff,0x90,0x06,0x2f,0xf0,0xa3,0xf0,0x90,0x06,0x29,0xa3,0xe0,0xff,0xc3,
+0x74,0x0f,0x9f,0xfd,0x90,0x06,0x2f,0xe0,0xfe,0xa3,0xe0,0xa8,0x05,0x08,0x80,0x05,
+0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xf0,0xee,0x90,0x06,0x2f,0xf0,0x90,0x06,0x2b,
+0xa3,0xe0,0xfc,0x2d,0xff,0x90,0x06,0x2f,0xe0,0xfe,0xa3,0xe0,0xa8,0x07,0x08,0x80,
+0x05,0xce,0xc3,0x13,0xce,0x13,0xd8,0xf9,0xf0,0xee,0x90,0x06,0x2f,0xf0,0xe0,0xfe,
+0xa3,0xe0,0xa8,0x04,0x08,0x80,0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x90,
+0x06,0x2f,0xee,0xf0,0xa3,0xef,0xf0,0xf4,0xff,0xee,0xf4,0xfe,0x90,0x06,0x2f,0xf0,
+0xa3,0xef,0xf0,0x90,0x06,0x27,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x5e,0xfc,0xed,0x5f,
+0xfd,0x90,0x06,0x2b,0xa3,0xe0,0xff,0xa3,0xe0,0xfe,0xa3,0xe0,0xa8,0x07,0x08,0x80,
+0x05,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0xee,0x4c,0xfc,0xef,0x4d,0xae,0x04,
+0xff,0x22,0x7f,0xc0,0x7e,0xe6,0x12,0x96,0x64,0xef,0x75,0xf0,0x10,0xa4,0xff,0x90,
+0x02,0x8c,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x7f,0xc1,0x7e,0xe6,0x12,0x96,0x64,0xef,
+0x75,0xf0,0x10,0xa4,0xff,0x90,0x02,0x8e,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x7f,0xc2,
+0x7e,0xe6,0x12,0x96,0x64,0xef,0x75,0xf0,0x10,0xa4,0xff,0x90,0x02,0x84,0xe5,0xf0,
+0xf0,0xa3,0xef,0xf0,0x7f,0xc3,0x7e,0xe6,0x12,0x96,0x64,0xef,0x75,0xf0,0x10,0xa4,
+0xff,0x90,0x02,0x86,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x7f,0xd8,0x7e,0xe6,0x12,0x96,
+0x64,0xef,0x75,0xf0,0x10,0xa4,0xff,0x90,0x02,0x91,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,
+0x7f,0xd9,0x7e,0xe6,0x12,0x96,0x64,0xef,0x75,0xf0,0x10,0xa4,0xff,0x90,0x02,0x93,
+0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x7f,0xda,0x7e,0xe6,0x12,0x96,0x64,0xef,0x75,0xf0,
+0x10,0xa4,0xff,0x90,0x02,0x88,0xe5,0xf0,0xf0,0xa3,0xef,0xf0,0x7f,0xdb,0x7e,0xe6,
+0x12,0x96,0x64,0xef,0x75,0xf0,0x10,0xa4,0xff,0x90,0x02,0x8a,0xe5,0xf0,0xf0,0xa3,
+0xef,0xf0,0x22,0x7f,0x40,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,0xe5,0xe4,0xf0,0xa3,
+0xef,0xf0,0x7f,0x26,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,0xe7,0xe4,0xf0,0xa3,0xef,
+0xf0,0x7f,0x27,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,0x11,0xe4,0xf0,0xa3,0xef,0xf0,
+0x90,0x03,0xe6,0xe0,0xfe,0xa3,0xe0,0x4e,0xff,0xa3,0xe0,0x90,0x03,0x0f,0xcf,0xf0,
+0xa3,0xef,0xf0,0x7f,0x68,0x7e,0xed,0x12,0x96,0x64,0xef,0x90,0x03,0xe9,0xb4,0x04,
+0x09,0x12,0x1f,0xb2,0x40,0x4c,0xcc,0xcd,0x80,0x07,0x12,0x1f,0xb2,0x40,0x80,0x00,
+0x00,0x90,0x03,0x11,0xe0,0xfc,0xa3,0xe0,0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,0xe9,
+0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,
+0x9a,0x90,0x03,0x11,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0x0f,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xec,0x12,0x1a,0x61,0x90,0x03,0xe9,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,
+0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,0x1a,0x9a,0x90,0x03,0x0f,0xee,0xf0,0xa3,0xef,
+0xf0,0xd2,0x02,0x22,0x90,0x05,0x47,0xe0,0xfb,0xb4,0xd0,0x3d,0x90,0x04,0x72,0x74,
+0x09,0xf0,0xa3,0x74,0xa0,0xf0,0x90,0x04,0xde,0x74,0x03,0xf0,0xa3,0x74,0x22,0xf0,
+0x90,0x04,0xda,0x74,0x03,0xf0,0xa3,0x74,0x18,0xf0,0x90,0x04,0xe1,0x74,0x03,0xf0,
+0xa3,0x74,0x1b,0xf0,0x90,0x04,0x70,0x74,0x02,0xf0,0xa3,0xe4,0xf0,0x90,0x04,0x83,
+0x12,0x1f,0xb2,0x38,0xab,0xf7,0x6a,0x80,0x3f,0xeb,0xb4,0xdb,0x3b,0x90,0x04,0x72,
+0x74,0x08,0xf0,0xa3,0x74,0xd0,0xf0,0x90,0x04,0xde,0x74,0x07,0xf0,0xa3,0x74,0x80,
+0xf0,0x90,0x04,0xda,0x74,0x07,0xf0,0xa3,0x74,0x76,0xf0,0x90,0x04,0xe1,0x74,0x07,
+0xf0,0xa3,0x74,0x7b,0xf0,0x90,0x04,0x70,0x74,0x02,0xf0,0xa3,0xe4,0xf0,0x90,0x04,
+0x83,0x12,0x1f,0xb2,0x38,0x9d,0x49,0x52,0x90,0x04,0x6d,0xe4,0xf0,0xa3,0x74,0x20,
+0xf0,0x90,0x04,0xda,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x78,0xcf,0xf0,0xa3,0xef,0xf0,
+0x90,0x04,0xe1,0xe0,0xff,0xa3,0xe0,0x90,0x04,0x7b,0xcf,0xf0,0xa3,0xef,0xf0,0x22,
+0x90,0x05,0x50,0xe0,0xff,0xa3,0xe0,0x90,0x05,0xc8,0xcf,0xf0,0xa3,0xef,0xf0,0x90,
+0x05,0x52,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xce,0xee,0xf0,0xa3,0xef,0xf0,0x7d,
+0x28,0x7c,0x00,0xd3,0x9d,0xee,0x9c,0x40,0x37,0x90,0x04,0xdb,0xe0,0x24,0x01,0xfe,
+0x90,0x04,0xda,0xe0,0x34,0x00,0x90,0x05,0x50,0xf0,0xa3,0xce,0xf0,0xc3,0x90,0x05,
+0xcf,0xe0,0x94,0x28,0xff,0x90,0x05,0xce,0xe0,0x94,0x00,0xfe,0x90,0x04,0x6e,0xe0,
+0x2f,0xff,0x90,0x04,0x6d,0xe0,0x3e,0x90,0x05,0x52,0xf0,0xa3,0xef,0xf0,0x80,0x33,
+0x90,0x04,0x6d,0xe0,0xfc,0xa3,0xe0,0xfd,0xd3,0x90,0x05,0xcf,0xe0,0x9d,0x90,0x05,
+0xce,0xe0,0x9c,0x40,0x1e,0x90,0x05,0xc9,0xe0,0x25,0xe0,0xfe,0x90,0x05,0xc8,0xe0,
+0x33,0x90,0x05,0x50,0xf0,0xa3,0xce,0xf0,0xed,0x24,0x01,0xfe,0xe4,0x3c,0xa3,0xf0,
+0xa3,0xce,0xf0,0x90,0x05,0xc8,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xce,0xe0,0xfc,
+0xa3,0xe0,0xfd,0x02,0x6e,0xf9,0xc3,0x90,0x05,0xfa,0xe0,0x94,0x0a,0x90,0x05,0xf9,
+0xe0,0x94,0x00,0x50,0x0c,0xa3,0xe0,0x04,0xf0,0x70,0x06,0x90,0x05,0xf9,0xe0,0x04,
+0xf0,0x90,0x05,0xc5,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf9,0xe0,0xfc,0xa3,0xe0,
+0xfd,0xd3,0x9f,0xec,0x9e,0x40,0x0d,0xed,0x24,0x0a,0xfe,0xe4,0x3c,0x90,0x05,0xc5,
+0xf0,0xa3,0xce,0xf0,0x90,0x05,0x58,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xfb,0xe0,
+0xfc,0xa3,0xe0,0xfd,0xc3,0x9f,0xec,0x9e,0x50,0x02,0x80,0x0f,0x90,0x05,0xde,0xe0,
+0xfe,0xa3,0xe0,0xff,0xd3,0xed,0x9f,0xec,0x9e,0x40,0x08,0x90,0x05,0xfb,0xee,0xf0,
+0xa3,0xef,0xf0,0x90,0x05,0xc5,0xe0,0xff,0xa3,0xe0,0x90,0x04,0xde,0xcf,0xf0,0xa3,
+0xef,0xf0,0x90,0x05,0xfb,0xe0,0xfe,0xa3,0xe0,0xff,0x90,0x05,0xf9,0xe0,0xfc,0xa3,
+0xe0,0xfd,0xe4,0xfb,0x12,0x41,0x65,0x90,0x05,0xf9,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,
+0xe0,0xfc,0xa3,0xe0,0xfd,0x02,0x6e,0xf9,0x90,0x06,0x54,0xee,0xf0,0xa3,0xef,0xf0,
+0xa3,0xec,0xf0,0xa3,0xed,0xf0,0x7f,0x00,0x7e,0x24,0x7d,0x74,0x7c,0x49,0x90,0x04,
+0x83,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x18,0x38,0x12,
+0x1a,0x9a,0x90,0x06,0x58,0xef,0xf0,0x90,0x06,0x56,0xa3,0xe0,0xfd,0x7f,0x49,0x7e,
+0xe6,0x12,0x96,0xbd,0x90,0x06,0x54,0xe0,0xfd,0x7f,0x4a,0x7e,0xe6,0x12,0x96,0xbd,
+0x90,0x06,0x54,0xa3,0xe0,0xfd,0x7f,0x4b,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x06,0x58,
+0xe0,0xfd,0x7f,0x63,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x04,0x6f,0xe0,0xfd,0x7f,0x65,
+0x7e,0xe6,0x12,0x96,0xbd,0x90,0x04,0x97,0xa3,0xe0,0xfd,0x7f,0x5b,0x7e,0xe6,0x12,
+0x96,0xbd,0x90,0x04,0xc6,0xa3,0xe0,0xfd,0x7f,0x59,0x7e,0xe6,0x12,0x96,0xbd,0x90,
+0x04,0x87,0xa3,0xe0,0xfd,0x7f,0x51,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x04,0x89,0xa3,
+0xe0,0xfd,0x7f,0x52,0x7e,0xe6,0x02,0x96,0xbd,0x7d,0xff,0x7f,0x71,0x7e,0xed,0x12,
+0x96,0xbd,0xe4,0xfd,0xfc,0xff,0x7e,0x01,0x12,0x93,0xa8,0x7f,0xa8,0x7e,0xe6,0x12,
+0x96,0x64,0x90,0x03,0xe5,0xef,0xf0,0x12,0x39,0x2d,0x90,0x05,0x47,0x74,0xdb,0xf0,
+0x12,0x86,0xc0,0x90,0x05,0x47,0x74,0xd0,0xf0,0x7d,0x08,0x7f,0x06,0x7e,0xe0,0x12,
+0x96,0xbd,0x90,0x03,0xe5,0xe0,0x7b,0xff,0x70,0x06,0x7a,0x99,0x79,0x9a,0x80,0x04,
+0x7a,0xa4,0x79,0x95,0x12,0x7d,0x4d,0x12,0x81,0x00,0x12,0x39,0x2d,0x12,0x84,0xb2,
+0x7f,0x32,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x7f,0x00,0x7e,0x01,0x12,
+0x90,0xd3,0x90,0x03,0xe6,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x32,0x7e,0x00,0x7d,0x00,
+0x7c,0x00,0x12,0x96,0xcb,0x90,0x03,0xe6,0xe0,0x44,0x01,0xfc,0xa3,0xe0,0xfd,0x7f,
+0x00,0x7e,0x01,0x12,0x93,0xa8,0xe4,0xfd,0x7f,0x71,0x7e,0xed,0x12,0x96,0xbd,0x90,
+0x05,0xc7,0x74,0x01,0xf0,0x22,0x90,0x05,0xd8,0xe0,0x14,0x60,0x2d,0x14,0x60,0x4b,
+0x14,0x60,0x69,0x24,0x03,0x60,0x03,0x02,0x89,0xe0,0x90,0x05,0x47,0xe0,0xb4,0xd0,
+0x02,0x80,0x07,0x90,0x05,0x47,0xe0,0xb4,0xdb,0x0b,0x7d,0x90,0x7c,0x00,0x7f,0x02,
+0x7e,0x00,0x12,0x93,0xa8,0xe4,0xfd,0xff,0x80,0x61,0x90,0x05,0x47,0xe0,0xb4,0xd0,
+0x02,0x80,0x07,0x90,0x05,0x47,0xe0,0xb4,0xdb,0x0b,0x7d,0x92,0x7c,0x00,0x7f,0x02,
+0x7e,0x00,0x12,0x93,0xa8,0x7d,0x03,0x7f,0x00,0x80,0x40,0x90,0x05,0x47,0xe0,0xb4,
+0xd0,0x02,0x80,0x07,0x90,0x05,0x47,0xe0,0xb4,0xdb,0x0b,0x7d,0x91,0x7c,0x00,0x7f,
+0x02,0x7e,0x00,0x12,0x93,0xa8,0x7d,0x02,0x7f,0x00,0x80,0x1f,0x90,0x05,0x47,0xe0,
+0xb4,0xd0,0x02,0x80,0x07,0x90,0x05,0x47,0xe0,0xb4,0xdb,0x0b,0x7d,0x93,0x7c,0x00,
+0x7f,0x02,0x7e,0x00,0x12,0x93,0xa8,0x7d,0x01,0x7f,0x00,0x7e,0xe3,0x12,0x96,0xbd,
+0x22,0x90,0x05,0xf1,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x90,
+0x05,0xf5,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xc3,0x12,0x1e,
+0xea,0x50,0x10,0x90,0x03,0xd4,0xe0,0x04,0xf0,0x70,0x0f,0x90,0x03,0xd3,0xe0,0x04,
+0xf0,0x80,0x07,0xe4,0x90,0x03,0xd3,0xf0,0xa3,0xf0,0x90,0x03,0x22,0x12,0x70,0x74,
+0x90,0x03,0xe8,0x12,0x1f,0xa6,0xc3,0x90,0x03,0xd4,0xe0,0x94,0x02,0x90,0x03,0xd3,
+0xe0,0x64,0x80,0x94,0x80,0x40,0x3b,0xe4,0xff,0xfe,0x7d,0xa0,0x7c,0x41,0x90,0x03,
+0xe8,0xe0,0xf8,0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x60,
+0x21,0x40,0x1f,0x7f,0xa0,0x7e,0x86,0x7d,0x01,0x7c,0x00,0x90,0x05,0xf5,0xe0,0xf8,
+0xa3,0xe0,0xf9,0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0xd3,0x12,0x1e,0xea,0x40,0x03,0x7f,
+0x01,0x22,0x7f,0x00,0x22,0xff,0xe4,0x35,0xf0,0xad,0x07,0xfc,0x90,0x04,0x17,0x74,
+0x01,0xf0,0xa3,0x74,0x03,0xf0,0xa3,0x74,0xe2,0xf0,0x7b,0x01,0x7a,0x03,0x79,0xe1,
+0x7f,0x01,0x7e,0x00,0x90,0x04,0x10,0xee,0xf0,0xa3,0xef,0xf0,0xa3,0xec,0xf0,0xa3,
+0xed,0xf0,0xa3,0xeb,0xf0,0xa3,0xea,0xf0,0xa3,0xe9,0xf0,0x90,0x04,0x10,0xa3,0xe0,
+0xfd,0x7f,0x00,0x7e,0xf2,0x12,0x96,0xbd,0x90,0x04,0x12,0xa3,0xe0,0xfd,0x7f,0x01,
+0x7e,0xf2,0x12,0x96,0xbd,0x7d,0x01,0x7f,0x06,0x7e,0xf2,0x12,0x96,0xbd,0xe4,0xfd,
+0x7f,0x06,0x7e,0xf2,0x12,0x96,0xbd,0x7f,0x05,0x7e,0xf2,0x12,0x96,0x64,0x90,0x04,
+0x14,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,0x12,0x1c,0x3e,0x7f,0x04,0x7e,
+0xf2,0x12,0x96,0x64,0x90,0x04,0x17,0xe0,0xfb,0xa3,0xe0,0xfa,0xa3,0xe0,0xf9,0xef,
+0x02,0x1c,0x3e,0x78,0x7f,0xe4,0xf6,0xd8,0xfd,0x75,0x81,0x21,0x02,0x8b,0x4a,0x02,
+0x94,0xcb,0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0x40,0x03,0xf6,0x80,0x01,0xf2,0x08,
+0xdf,0xf4,0x80,0x29,0xe4,0x93,0xa3,0xf8,0x54,0x07,0x24,0x0c,0xc8,0xc3,0x33,0xc4,
+0x54,0x0f,0x44,0x20,0xc8,0x83,0x40,0x04,0xf4,0x56,0x80,0x01,0x46,0xf6,0xdf,0xe4,
+0x80,0x0b,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x4f,0xba,0xe4,0x7e,0x01,
+0x93,0x60,0xbc,0xa3,0xff,0x54,0x3f,0x30,0xe5,0x09,0x54,0x1f,0xfe,0xe4,0x93,0xa3,
+0x60,0x01,0x0e,0xcf,0x54,0xc0,0x25,0xe0,0x60,0xa8,0x40,0xb8,0xe4,0x93,0xa3,0xfa,
+0xe4,0x93,0xa3,0xf8,0xe4,0x93,0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xf0,
+0xa3,0xc8,0xc5,0x82,0xc8,0xca,0xc5,0x83,0xca,0xdf,0xe9,0xde,0xe7,0x80,0xbe,0x90,
+0x03,0x19,0x74,0x0a,0xf0,0xef,0x8e,0xf0,0x12,0x20,0x26,0x8b,0xcb,0x00,0x00,0x8b,
+0xd1,0x02,0x00,0x8b,0xd8,0x03,0x00,0x8b,0xdf,0x03,0x80,0x8b,0xe6,0x03,0xc0,0x8b,
+0xed,0x03,0xe0,0x8b,0xf4,0x03,0xf0,0x8b,0xfb,0x03,0xf8,0x8c,0x02,0x03,0xfc,0x8c,
+0x09,0x03,0xfe,0x8c,0x10,0x03,0xff,0x00,0x00,0x8c,0x16,0xe4,0x90,0x03,0x19,0xf0,
+0x22,0x90,0x03,0x19,0x74,0x01,0xf0,0x22,0x90,0x03,0x19,0x74,0x02,0xf0,0x22,0x90,
+0x03,0x19,0x74,0x03,0xf0,0x22,0x90,0x03,0x19,0x74,0x04,0xf0,0x22,0x90,0x03,0x19,
+0x74,0x05,0xf0,0x22,0x90,0x03,0x19,0x74,0x06,0xf0,0x22,0x90,0x03,0x19,0x74,0x07,
+0xf0,0x22,0x90,0x03,0x19,0x74,0x08,0xf0,0x22,0x90,0x03,0x19,0x74,0x09,0xf0,0x22,
+0x90,0x03,0x19,0x74,0x0a,0xf0,0x22,0x7f,0x04,0x7e,0xe0,0x12,0x96,0x64,0xef,0x44,
+0x80,0x44,0x40,0xfd,0x7f,0x04,0x7e,0xe0,0x12,0x96,0xbd,0x7d,0x01,0x7f,0x07,0x7e,
+0xf2,0x12,0x96,0xbd,0xe4,0xfd,0xff,0x7e,0xf2,0x12,0x96,0xbd,0x7d,0x07,0x7f,0x01,
+0x7e,0xf2,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x02,0x7e,0xf2,0x12,0x96,0xbd,0x7d,0x07,
+0x7f,0x03,0x7e,0xf2,0x12,0x96,0xbd,0x7d,0x02,0x7f,0x06,0x7e,0xf2,0x12,0x96,0xbd,
+0xe4,0xfd,0x7f,0x06,0x7e,0xf2,0x12,0x96,0xbd,0xe4,0x90,0x04,0xec,0xf0,0xa3,0xf0,
+0x12,0x74,0x87,0x90,0x05,0x02,0x74,0x01,0xf0,0xfd,0x7f,0x07,0x7e,0xf2,0x12,0x96,
+0xbd,0x7f,0x1e,0x7e,0xee,0x12,0x96,0x64,0x90,0x02,0x90,0xef,0xf0,0x7d,0x01,0x7f,
+0x1e,0x7e,0xee,0x02,0x96,0xbd,0x7f,0xa8,0x7e,0xe6,0x12,0x96,0x64,0xef,0xb4,0x09,
+0x00,0x50,0x63,0x90,0x8c,0xaa,0xf8,0x28,0x28,0x73,0x02,0x8c,0xc5,0x02,0x8c,0xc5,
+0x02,0x8c,0xcd,0x02,0x8c,0xd5,0x02,0x8c,0xdd,0x02,0x8c,0xe5,0x02,0x8c,0xed,0x02,
+0x8c,0xf5,0x02,0x8c,0xfd,0x7b,0xff,0x7a,0x9d,0x79,0x5d,0x80,0x36,0x7b,0xff,0x7a,
+0x9e,0x79,0x44,0x80,0x2e,0x7b,0xff,0x7a,0x9f,0x79,0x2b,0x80,0x26,0x7b,0xff,0x7a,
+0xa0,0x79,0x12,0x80,0x1e,0x7b,0xff,0x7a,0xa0,0x79,0xf9,0x80,0x16,0x7b,0xff,0x7a,
+0xa1,0x79,0xe0,0x80,0x0e,0x7b,0xff,0x7a,0xa2,0x79,0xc7,0x80,0x06,0x7b,0xff,0x7a,
+0xa3,0x79,0xae,0x12,0x7d,0x4d,0x22,0x7f,0x2a,0x7e,0xe6,0x12,0x96,0x64,0xef,0x24,
+0xf9,0x60,0x34,0x24,0x07,0x70,0x5f,0x7f,0x28,0x7e,0xe6,0x12,0x96,0x64,0xef,0x7f,
+0x00,0xfe,0xc0,0x07,0xc0,0x06,0x7f,0x29,0x7e,0xe6,0x12,0x96,0x64,0xef,0xfd,0xd0,
+0xe0,0xfe,0xd0,0xe0,0x4d,0xff,0x90,0x03,0xe5,0xee,0xf0,0xa3,0xef,0xf0,0x12,0x82,
+0x8e,0x90,0x03,0x1c,0xee,0x80,0x2b,0x7f,0x28,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,
+0xe5,0xe4,0xf0,0xa3,0xef,0xf0,0x7f,0x29,0x7e,0xe6,0x12,0x96,0x64,0x7e,0x00,0x90,
+0x03,0xe7,0xee,0xf0,0xa3,0xef,0xf0,0xfd,0x90,0x03,0xe6,0xe0,0xff,0xed,0x90,0x03,
+0xdc,0xcf,0xf0,0xa3,0xef,0xf0,0x22,0x90,0x04,0x16,0xe4,0xf0,0x74,0x04,0xa3,0xf0,
+0xe4,0xfb,0xfa,0xfd,0xfc,0xff,0xfe,0x90,0x04,0x10,0xee,0xf0,0xa3,0xef,0xf0,0xa3,
+0xec,0xf0,0xa3,0xed,0xf0,0xa3,0xea,0xf0,0xa3,0xeb,0xf0,0x90,0x04,0x10,0xa3,0xe0,
+0xfd,0x7f,0x00,0x7e,0xf2,0x12,0x96,0xbd,0x90,0x04,0x12,0xa3,0xe0,0xfd,0x7f,0x01,
+0x7e,0xf2,0x12,0x96,0xbd,0x90,0x04,0x14,0xa3,0xe0,0xfd,0x7f,0x02,0x7e,0xf2,0x12,
+0x96,0xbd,0x90,0x04,0x16,0xa3,0xe0,0xfd,0x7f,0x03,0x7e,0xf2,0x12,0x96,0xbd,0x7d,
+0x02,0x7f,0x06,0x7e,0xf2,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x06,0x7e,0xf2,0x02,0x96,
+0xbd,0xe4,0x90,0x03,0xfe,0xf0,0xa3,0xf0,0x7f,0x03,0x7e,0xec,0x12,0x96,0x64,0x90,
+0x04,0x00,0xef,0xf0,0x30,0x0a,0x30,0xe4,0xfd,0xfc,0xed,0x25,0xe0,0xff,0xec,0x33,
+0xfe,0x74,0xd8,0x2f,0xf5,0x82,0x74,0x01,0x3e,0xf5,0x83,0xe0,0xfe,0xa3,0xe0,0xff,
+0x90,0x03,0xff,0xe0,0x2f,0xf0,0x90,0x03,0xfe,0xe0,0x3e,0xf0,0x0d,0xbd,0x00,0x01,
+0x0c,0xed,0x64,0x0e,0x4c,0x70,0xd3,0x90,0x03,0xfe,0xe0,0x70,0x02,0xa3,0xe0,0x70,
+0x08,0x30,0x0a,0x05,0x7d,0x80,0xff,0x80,0x04,0x7d,0x82,0x7f,0x00,0x7e,0xe8,0x12,
+0x96,0xbd,0x22,0xc0,0xe0,0xc0,0xf0,0xc0,0x83,0xc0,0x82,0xc0,0xd0,0x75,0xd0,0x00,
+0xc0,0x00,0xc0,0x01,0xc0,0x02,0xc0,0x03,0xc0,0x04,0xc0,0x05,0xc0,0x06,0xc0,0x07,
+0x90,0x06,0x43,0xe4,0xf0,0xa3,0x04,0xf0,0x90,0x06,0x3e,0x12,0x1f,0x71,0x74,0xff,
+0xfb,0xfa,0xf9,0xf8,0xc3,0x12,0x1e,0xea,0x70,0x0a,0x90,0x06,0x3e,0x12,0x1f,0xb2,
+0x00,0x00,0x00,0x00,0xd0,0x07,0xd0,0x06,0xd0,0x05,0xd0,0x04,0xd0,0x03,0xd0,0x02,
+0xd0,0x01,0xd0,0x00,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xf0,0xd0,0xe0,0x32,0x90,
+0x04,0x17,0x74,0x01,0xf0,0xa3,0x74,0x04,0xf0,0xa3,0x74,0x0f,0xf0,0x7b,0x01,0x7a,
+0x04,0x79,0x0e,0x7d,0x02,0x7c,0x00,0xe4,0xff,0xfe,0x12,0x8a,0x94,0x7f,0x05,0x7e,
+0xf2,0x12,0x96,0x64,0x90,0x04,0x0e,0xef,0xf0,0xe0,0xff,0x54,0x0c,0x13,0x13,0x54,
+0x3f,0xfe,0xef,0x54,0x03,0xff,0xee,0x04,0x75,0xf0,0x03,0x84,0xae,0xf0,0xee,0x25,
+0xe0,0x25,0xe0,0x2f,0xf0,0xe0,0xff,0x90,0x04,0x16,0xe4,0xf0,0xa3,0xef,0xf0,0xe4,
+0xfb,0xfa,0x7d,0x02,0xfc,0xff,0xfe,0x02,0x8d,0x87,0x90,0x06,0x51,0xea,0xf0,0xa3,
+0xeb,0xf0,0xa9,0x07,0x7f,0xff,0xc3,0x74,0x07,0x9d,0xfe,0xef,0xa8,0x06,0x08,0x80,
+0x02,0xc3,0x33,0xd8,0xfc,0xff,0x90,0x06,0x51,0xa3,0xe0,0xfd,0x2e,0xfe,0xef,0xa8,
+0x06,0x08,0x80,0x02,0xc3,0x13,0xd8,0xfc,0xff,0xa8,0x05,0x08,0x80,0x02,0xc3,0x33,
+0xd8,0xfc,0xf4,0xae,0x01,0x5e,0xfe,0x90,0x06,0x51,0xa3,0xe0,0xff,0xa3,0xe0,0xfd,
+0xa8,0x07,0x08,0x80,0x02,0xc3,0x33,0xd8,0xfc,0x4e,0xff,0x22,0xe4,0xfd,0xfc,0xed,
+0xae,0x04,0x78,0x02,0xc3,0x33,0xce,0x33,0xce,0xd8,0xf9,0xff,0x24,0x62,0xf5,0x82,
+0x74,0x05,0x3e,0xf5,0x83,0xe4,0xf0,0x74,0x63,0x2f,0xf5,0x82,0x74,0x05,0x3e,0xf5,
+0x83,0xe4,0xf0,0x74,0x64,0x2f,0xf5,0x82,0x74,0x05,0x3e,0xf5,0x83,0xe4,0xf0,0x74,
+0x65,0x2f,0xf5,0x82,0x74,0x05,0x3e,0xf5,0x83,0xe4,0xf0,0x0d,0xbd,0x00,0x01,0x0c,
+0xed,0x64,0x14,0x4c,0x70,0xb9,0xe4,0x90,0x05,0xb7,0xf0,0xa3,0xf0,0x22,0x7d,0x82,
+0x7f,0x00,0x7e,0xe8,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x90,0x7e,0xe6,0x12,0x96,0xbd,
+0xe4,0xfd,0x7f,0x91,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x98,0x7e,0xeb,0x12,
+0x96,0xbd,0x7d,0x06,0x7f,0xb8,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0xaf,0x7f,0xb9,0x7e,
+0xe1,0x12,0x96,0xbd,0x7d,0x05,0x7f,0xbc,0x7e,0xe1,0x12,0x96,0xbd,0x7d,0x6f,0x7f,
+0xbd,0x7e,0xe1,0x12,0x96,0xbd,0xe4,0x90,0x01,0xbf,0xf0,0xa3,0xf0,0x22,0x7f,0x03,
+0x7e,0xe0,0x12,0x96,0x64,0xef,0x44,0x04,0xfd,0x7f,0x03,0x7e,0xe0,0x12,0x96,0xbd,
+0xe4,0x90,0x05,0x5c,0xf0,0x90,0x05,0xb2,0xf0,0x90,0x05,0x5d,0xf0,0x90,0x05,0xb3,
+0xf0,0x90,0x05,0xc3,0xf0,0xa3,0xf0,0x90,0x05,0xbd,0xf0,0xa3,0xf0,0x90,0x05,0xba,
+0xf0,0xa3,0xf0,0xa3,0xf0,0x12,0x8f,0x4c,0x90,0x04,0xf8,0xe0,0x70,0x09,0x12,0x6a,
+0x41,0x90,0x05,0xf5,0x12,0x1f,0xa6,0x90,0x05,0x0c,0x74,0x01,0xf0,0x22,0x7d,0x17,
+0x7f,0x62,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x05,0x47,0x74,0xd0,0xf0,0x7b,0xff,0x7a,
+0x98,0x79,0x05,0x12,0x7d,0x4d,0x7f,0xa8,0x7e,0xe6,0x12,0x96,0x64,0xef,0x7b,0xff,
+0x70,0x06,0x7a,0x99,0x79,0x9a,0x80,0x04,0x7a,0xa4,0x79,0x95,0x12,0x7d,0x4d,0x12,
+0x81,0x00,0x7b,0xff,0x7a,0xa6,0x79,0x6f,0x12,0x7d,0x4d,0x12,0x84,0xb2,0x7d,0x08,
+0x7f,0x06,0x7e,0xe0,0x12,0x96,0xbd,0x02,0x7e,0xf0,0x90,0x03,0x28,0xe0,0x14,0x60,
+0x21,0x04,0x70,0x3c,0x90,0x03,0xd1,0xe0,0xfe,0xa3,0xe0,0xff,0xc3,0x90,0x03,0x1d,
+0xe0,0x9f,0xee,0x64,0x80,0xf8,0x90,0x03,0x1c,0xe0,0x64,0x80,0x98,0x40,0x21,0x7f,
+0x01,0x22,0x90,0x03,0xcb,0xe0,0xfe,0xa3,0xe0,0xff,0xd3,0x90,0x03,0x1d,0xe0,0x9f,
+0xee,0x64,0x80,0xf8,0x90,0x03,0x1c,0xe0,0x64,0x80,0x98,0x50,0x03,0x7f,0x01,0x22,
+0x7f,0x00,0x22,0x90,0x03,0xe8,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xe8,0xe0,0xfd,
+0x7f,0x33,0x7e,0xe0,0x12,0x96,0xbd,0x90,0x03,0xe8,0x12,0x96,0xb6,0x7f,0x35,0x7e,
+0xe0,0x12,0x96,0x64,0x12,0x96,0x58,0x7c,0x00,0x7f,0x32,0x7e,0x00,0x7d,0x00,0x12,
+0x96,0xcb,0x7f,0x35,0x7e,0xe0,0x12,0x96,0x64,0x12,0x96,0x58,0x7c,0x00,0xad,0x07,
+0x90,0x03,0xeb,0xe0,0xfe,0xe4,0x2d,0xff,0xec,0x3e,0xfe,0x22,0xd3,0x90,0x04,0xca,
+0xe0,0x94,0x3c,0x90,0x04,0xc9,0xe0,0x94,0x00,0x40,0x07,0xe4,0x90,0x04,0xe3,0xf0,
+0x80,0x06,0x90,0x04,0xe3,0x74,0x01,0xf0,0x90,0x04,0xe3,0xe0,0xff,0x90,0x04,0xe0,
+0xe0,0x6f,0x60,0x17,0xef,0x7d,0xf0,0x7c,0x84,0x7f,0x6c,0x7e,0x31,0x12,0x93,0xa8,
+0x7f,0x05,0x7e,0x00,0x7d,0x00,0x7c,0x00,0x12,0x96,0xcb,0x90,0x04,0xe3,0xe0,0x90,
+0x04,0xe0,0xf0,0x22,0xe4,0xfd,0x7f,0xc0,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,
+0xc1,0x7e,0xe6,0x12,0x96,0xbd,0x7d,0x50,0x7f,0xc2,0x7e,0xe6,0x12,0x96,0xbd,0x7d,
+0x3c,0x7f,0xc3,0x7e,0xe6,0x12,0x96,0xbd,0x7d,0x0a,0x7f,0xd8,0x7e,0xe6,0x12,0x96,
+0xbd,0xe4,0xfd,0x7f,0xd9,0x7e,0xe6,0x12,0x96,0xbd,0x7d,0x46,0x7f,0xda,0x7e,0xe6,
+0x12,0x96,0xbd,0x7d,0x0a,0x7f,0xdb,0x7e,0xe6,0x02,0x96,0xbd,0xe4,0xfb,0xfa,0x90,
+0x03,0x2c,0x75,0xf0,0x06,0xeb,0x12,0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,0x25,0x83,
+0xf5,0x83,0x12,0x1f,0xb2,0x00,0x00,0x00,0x00,0x90,0x03,0x2a,0x75,0xf0,0x06,0xeb,
+0x12,0x1f,0xf4,0xea,0x75,0xf0,0x06,0xa4,0x25,0x83,0xf5,0x83,0xe4,0xf0,0xa3,0xf0,
+0x0b,0xbb,0x00,0x01,0x0a,0xeb,0x64,0x19,0x4a,0x70,0xc4,0xe4,0x90,0x03,0xc5,0xf0,
+0xa3,0xf0,0x22,0x90,0x03,0x1d,0xe0,0x2f,0xfd,0x90,0x03,0x1c,0xe0,0x3e,0xfc,0xc3,
+0x64,0x80,0x94,0x80,0x50,0x09,0xe4,0x90,0x03,0xe5,0xf0,0xa3,0xf0,0x80,0x1b,0xd3,
+0xed,0x94,0xff,0xec,0x64,0x80,0x94,0x80,0x90,0x03,0xe5,0x40,0x08,0xe4,0xf0,0xa3,
+0x74,0xff,0xf0,0x80,0x05,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xe5,0x12,0x82,0x89,
+0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0x22,0xc0,0xe0,0xc0,0x83,0xc0,0x82,0xc0,
+0xd0,0x75,0xd0,0x00,0xc0,0x07,0x75,0x8c,0xb7,0x75,0x8a,0xfd,0x90,0x06,0x3d,0xe0,
+0xff,0x90,0x06,0x42,0xe0,0xd3,0x9f,0x40,0x0a,0x20,0x0b,0x07,0x75,0xa8,0x81,0xc2,
+0x8c,0xd2,0x0b,0x90,0x06,0x42,0xe0,0xff,0x04,0xf0,0xef,0xb4,0xff,0x02,0xe4,0xf0,
+0xd0,0x07,0xd0,0xd0,0xd0,0x82,0xd0,0x83,0xd0,0xe0,0x32,0x90,0x05,0x50,0x74,0x03,
+0xf0,0xa3,0x74,0xe8,0xf0,0xa3,0xe4,0xf0,0xa3,0x74,0x20,0xf0,0x90,0x04,0x87,0xa3,
+0xe0,0xfd,0x7f,0x13,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xff,0xfe,0x90,0x04,0x87,0xa3,
+0xe0,0xfd,0x74,0x7d,0x2f,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xed,0xf0,0x0f,0xbf,
+0x00,0x01,0x0e,0xef,0x64,0x06,0x4e,0x70,0xe3,0x02,0x86,0x14,0x90,0x03,0xcb,0xee,
+0xf0,0xa3,0xef,0xf0,0xaf,0x05,0x90,0x03,0xd1,0xec,0xf0,0xa3,0xef,0xf0,0xe4,0x90,
+0x03,0xc7,0xf0,0xa3,0xf0,0x90,0x03,0xc2,0xf0,0x90,0x03,0x1e,0x74,0x02,0xf0,0x7d,
+0x23,0x7f,0x61,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x04,0xf9,0x74,0xff,0xf0,0xa3,0x74,
+0x56,0xf0,0xa3,0x74,0x0e,0xf0,0x90,0x04,0xf8,0x74,0x01,0xf0,0x22,0x7f,0x2a,0x7e,
+0xe6,0x12,0x96,0x64,0xef,0x14,0x60,0x08,0x04,0x70,0x2d,0x90,0x04,0x7a,0x80,0x1f,
+0x7f,0x2b,0x7e,0xe6,0x12,0x96,0x64,0x90,0x03,0xe5,0xe4,0xf0,0xa3,0xef,0xf0,0x90,
+0x03,0xe5,0xe0,0xfe,0xa3,0xe0,0x24,0xcd,0xf5,0x82,0x74,0x04,0x3e,0xf5,0x83,0xe0,
+0xfd,0x7f,0x28,0x7e,0xe6,0x12,0x96,0xbd,0x22,0x90,0x05,0x52,0xe0,0xff,0xa3,0xe0,
+0x90,0x03,0xe5,0xcf,0xf0,0xa3,0xef,0xf0,0x90,0x05,0x50,0xe0,0xff,0xa3,0xe0,0x90,
+0x03,0xe7,0xcf,0xf0,0xa3,0xef,0xf0,0x7f,0x71,0x7e,0xe6,0x12,0x96,0x64,0xab,0x07,
+0x90,0x03,0xe5,0xe0,0xfe,0xa3,0xe0,0xff,0xa3,0xe0,0xfc,0xa3,0xe0,0xfd,0x02,0x41,
+0x65,0xe4,0x78,0x0e,0xf6,0x08,0xf6,0xc2,0xaf,0x76,0x08,0xd2,0x92,0xd2,0x93,0x30,
+0x93,0xfd,0x12,0x97,0x6b,0x78,0x0e,0xe6,0xff,0x25,0xe0,0xf6,0x30,0x92,0x04,0xe6,
+0x44,0x01,0xf6,0xc2,0x93,0x12,0x97,0x6b,0x78,0x0f,0x16,0xe6,0xd3,0x94,0x00,0x50,
+0xda,0xd2,0xaf,0x78,0x0e,0xe6,0xff,0x22,0x90,0x03,0xfd,0xee,0xf0,0xa3,0xef,0xf0,
+0xa3,0xec,0xf0,0xa3,0xed,0xf0,0x90,0x03,0xfd,0x7f,0x33,0x12,0x96,0xb9,0x90,0x03,
+0xfd,0x12,0x96,0xb6,0x90,0x03,0xff,0xe0,0xfd,0x7f,0x35,0x7e,0xe0,0x12,0x96,0xbd,
+0x90,0x03,0xff,0xa3,0xe0,0xfd,0x7f,0x36,0x7e,0xe0,0x02,0x96,0xbd,0xd3,0x90,0x04,
+0xca,0xe0,0x94,0xfa,0x90,0x04,0xc9,0xe0,0x94,0x00,0x50,0x11,0x90,0x05,0x47,0xe0,
+0xb4,0xd0,0x0a,0x7d,0x0d,0x7c,0x00,0x7f,0x0a,0x7e,0x00,0x80,0x07,0x7d,0x0e,0x7c,
+0x00,0xe4,0xff,0xfe,0x12,0x20,0xf3,0x90,0x00,0x05,0xa3,0xe0,0x90,0x01,0xc1,0xf0,
+0x22,0xc2,0xaf,0x78,0x10,0x76,0x08,0xef,0x30,0xe7,0x04,0xd2,0x92,0x80,0x02,0xc2,
+0x92,0xd2,0x93,0xd2,0x93,0xd2,0x93,0x30,0x93,0xfd,0x12,0x97,0x6b,0xc2,0x93,0x12,
+0x97,0x6b,0xef,0x25,0xe0,0xff,0x78,0x10,0x16,0xe6,0xd3,0x94,0x00,0x50,0xd8,0xd2,
+0xaf,0x12,0x95,0x97,0x22,0x90,0x05,0xf1,0x12,0x70,0x74,0x90,0x03,0xe8,0x12,0x1f,
+0xa6,0xe4,0xff,0xfe,0x7d,0x20,0x7c,0x42,0x90,0x03,0xe8,0xe0,0xf8,0xa3,0xe0,0xf9,
+0xa3,0xe0,0xfa,0xa3,0xe0,0xfb,0x12,0x19,0xde,0x7f,0x00,0x60,0x04,0x40,0x02,0x7f,
+0x01,0x22,0x90,0x06,0x34,0x74,0x01,0xf0,0x7d,0x06,0x7f,0x58,0x7e,0xe6,0x12,0x96,
+0xbd,0x7d,0x0f,0x7f,0x5a,0x7e,0xe6,0x12,0x96,0xbd,0x7f,0x70,0x7e,0xe6,0x12,0x96,
+0x64,0x90,0x06,0x35,0xef,0xf0,0x7d,0x22,0x7f,0x04,0x7e,0xe0,0x02,0x96,0xbd,0xef,
+0x64,0x01,0x4e,0x70,0x1a,0xfd,0x7f,0x40,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,
+0x26,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x27,0x7e,0xe6,0x12,0x96,0xbd,0xe4,
+0x90,0x03,0x0f,0xf0,0xa3,0xf0,0xa3,0xf0,0xa3,0xf0,0x22,0xc2,0x0b,0x12,0x94,0xf6,
+0x12,0x75,0xc1,0xd2,0x8c,0x12,0x81,0xc5,0x7f,0x60,0x7e,0xe6,0x12,0x96,0x64,0x90,
+0x03,0xde,0xef,0xf0,0x60,0xef,0xe0,0xff,0x12,0x3d,0x70,0xe4,0xfd,0x7f,0x60,0x7e,
+0xe6,0x12,0x96,0xbd,0x80,0xdf,0x75,0xa8,0x82,0x75,0xb8,0x13,0x75,0x89,0x21,0x75,
+0x88,0x45,0xe4,0xf5,0xc8,0x75,0x98,0x50,0x75,0x87,0x80,0x75,0x8c,0x4b,0x75,0x8a,
+0xfc,0x75,0x8d,0xe7,0xf5,0x8b,0xd2,0x99,0x75,0x90,0xc4,0x75,0xa0,0xff,0xc2,0x90,
+0x22,0x90,0x06,0x59,0xef,0xf0,0xa3,0xed,0xf0,0xe4,0x90,0x06,0x5c,0xf0,0x12,0x96,
+0xa0,0x90,0x06,0x5a,0xe0,0xff,0x90,0x06,0x59,0xe0,0x4f,0xff,0x12,0x94,0x11,0xef,
+0x60,0x06,0x90,0x06,0x5c,0x74,0x02,0xf0,0x22,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,
+0xc0,0xee,0xf0,0xa3,0xef,0xf0,0x90,0x03,0xc9,0xe0,0xff,0xef,0x14,0x60,0x09,0x14,
+0x60,0x06,0x24,0x02,0x70,0x05,0x80,0x00,0xe4,0xfc,0xfd,0xaf,0x05,0xae,0x04,0x22,
+0x7d,0xff,0x7f,0x71,0x7e,0xed,0x12,0x96,0xbd,0x90,0x05,0x47,0x74,0xdb,0xf0,0x12,
+0x8c,0x96,0x7b,0xff,0x7a,0x9b,0x79,0x7a,0x12,0x7d,0x4d,0x12,0x39,0x2d,0xe4,0xfd,
+0x7f,0x71,0x7e,0xed,0x02,0x96,0xbd,0xc2,0xaf,0xd2,0x92,0xd2,0x93,0x30,0x93,0xfd,
+0x12,0x97,0x6b,0x30,0x92,0x0c,0xc2,0x93,0x90,0x06,0x5c,0xe0,0x44,0x01,0xf0,0x7f,
+0x01,0x22,0xc2,0x93,0x12,0x97,0x6b,0xd2,0xaf,0x7f,0x00,0x22,0x90,0x04,0x0b,0xef,
+0xf0,0xa3,0xed,0xf0,0xa3,0xeb,0xf0,0x90,0x04,0x0a,0xe0,0x90,0x04,0x0e,0xf0,0x90,
+0x04,0x0b,0xe0,0xfc,0xa3,0xe0,0xfd,0xa3,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0xef,0x14,
+0x60,0x0d,0x14,0x60,0x10,0x24,0x02,0x70,0x10,0x7c,0x00,0x7d,0x14,0x80,0x0a,0x7c,
+0x00,0x7d,0x04,0x80,0x04,0x7c,0x00,0x7d,0x01,0xaf,0x05,0xae,0x04,0x22,0xe4,0x90,
+0x04,0xf8,0xf0,0x90,0x03,0xca,0xe0,0x60,0x04,0x7d,0x24,0x80,0x02,0x7d,0x22,0x7f,
+0x61,0x7e,0xe6,0x12,0x96,0xbd,0x90,0x03,0xca,0x74,0x01,0xf0,0x22,0xe4,0x90,0x06,
+0x34,0xf0,0xfd,0x7f,0x58,0x7e,0xe6,0x12,0x96,0xbd,0xe4,0xfd,0x7f,0x5a,0x7e,0xe6,
+0x12,0x96,0xbd,0x7d,0x20,0x7f,0x04,0x7e,0xe0,0x02,0x96,0xbd,0x7f,0x03,0x7e,0xe0,
+0x12,0x96,0x64,0xef,0x54,0xfb,0xfd,0x7f,0x03,0x7e,0xe0,0x12,0x96,0xbd,0xe4,0x90,
+0x05,0x0c,0xf0,0x90,0x05,0xee,0xf0,0x22,0x90,0x03,0xea,0xe4,0xf0,0xa3,0xef,0xf0,
+0x7f,0x36,0x7e,0xe0,0x90,0xe0,0x39,0xe0,0x20,0xe0,0xf9,0x8f,0x82,0x8e,0x83,0xe0,
+0xff,0x22,0x7f,0x2a,0x7e,0xe6,0x12,0x96,0x64,0xef,0x70,0x0c,0x7f,0x28,0x7e,0xe6,
+0x12,0x96,0x64,0x90,0x04,0x7a,0xef,0xf0,0x22,0xef,0x24,0xfe,0x60,0x09,0x04,0x70,
+0x0a,0x7c,0x00,0x7d,0x14,0x80,0x04,0x7c,0x00,0x7d,0x08,0xaf,0x05,0xae,0x04,0x22,
+0xc2,0xaf,0xd2,0x93,0xd2,0x92,0x12,0x97,0x6b,0xc2,0x92,0x12,0x97,0x6b,0xc2,0x93,
+0x12,0x97,0x6b,0xd2,0xaf,0x22,0xa3,0x7f,0x34,0xe0,0xfd,0x7e,0xe0,0x90,0xe0,0x39,
+0xe0,0x20,0xe0,0xf9,0x8f,0x82,0x8e,0x83,0xed,0xf0,0x22,0x90,0x03,0xfd,0x12,0x1f,
+0xa6,0x90,0x03,0xfd,0x74,0xff,0x12,0x1f,0x73,0xec,0x4d,0x4e,0x4f,0x70,0xf2,0x22,
+0x12,0x93,0x71,0x90,0x06,0x60,0xef,0xf0,0x12,0x97,0x19,0x12,0x97,0x08,0x90,0x06,
+0x60,0xe0,0xff,0x22,0x12,0x93,0x71,0x90,0x06,0x61,0xef,0xf0,0x12,0x97,0x2a,0x12,
+0x97,0x08,0x90,0x06,0x61,0xe0,0xff,0x22,0xc2,0xaf,0xc2,0x92,0x12,0x97,0x6b,0xd2,
+0x93,0x12,0x97,0x6b,0xd2,0x92,0xd2,0xaf,0x22,0xc2,0xaf,0xc2,0x92,0xd2,0x93,0x30,
+0x93,0xfd,0x12,0x97,0x6b,0xc2,0x93,0xd2,0xaf,0x22,0xc2,0xaf,0xd2,0x92,0xd2,0x93,
+0x30,0x93,0xfd,0x12,0x97,0x6b,0xc2,0x93,0xd2,0xaf,0x22,0x90,0x06,0x5d,0xef,0xf0,
+0xa3,0xed,0xf0,0x90,0x06,0x5d,0xe0,0xfe,0xa3,0xe0,0xff,0x22,0x7f,0xff,0x7e,0x00,
+0x12,0x82,0x8e,0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0x22,0xe4,0xff,0xfe,0x12,
+0x82,0x8e,0x90,0x03,0x1c,0xee,0xf0,0xa3,0xef,0xf0,0x22,0xc2,0xaf,0xe4,0xf5,0x0d,
+0x05,0x0d,0xe5,0x0d,0xb4,0x14,0xf9,0xd2,0xaf,0x22,0x12,0x94,0x11,0xef,0x60,0x07,
+0x90,0x06,0x5c,0xe0,0x44,0x04,0xf0,0x22,0xef,0x14,0x60,0x06,0x04,0x70,0x05,0x7f,
+0x01,0x22,0x7f,0x00,0x22,0xee,0x30,0xe7,0x07,0xc3,0xe4,0x9f,0xff,0xe4,0x9e,0xfe,
+0x22,0x7f,0x1e,0x7e,0x00,0x7d,0xa0,0x7c,0x00,0x02,0x64,0x55,0x7f,0x64,0x7e,0x00,
+0x7d,0xff,0x7c,0x00,0x02,0x64,0x55,0x7d,0x00,0x7c,0x07,0x7f,0x46,0x7e,0x30,0x02,
+0x93,0xa8,0x7d,0x00,0x7c,0x06,0x7f,0x46,0x7e,0x30,0x02,0x93,0xa8,0xe4,0xff,0xfe,
+0x7d,0xff,0xfc,0x02,0x64,0x55,0x12,0x93,0x39,0xe4,0x90,0x05,0x16,0xf0,0x22,0xe4,
+0x90,0x03,0x1c,0xf0,0xa3,0xf0,0x22,0x90,0x04,0xb9,0x74,0x01,0xf0,0x22,0x90,0x05,
+0x16,0x74,0x01,0xf0,0x22,0xe4,0x90,0x04,0xb9,0xf0,0x22,0x90,0x06,0x5c,0xe0,0xff,
+0x22,0x22,0x22,0x22,0x22,0xed,0x17,0x01,0xed,0x1f,0x01,0xed,0x27,0x01,0xed,0x2f,
+0x01,0xee,0x53,0x01,0xe0,0x80,0xff,0xe0,0x81,0xf0,0xe0,0x82,0xff,0xe0,0x83,0xff,
+0xe0,0x84,0x00,0xe0,0x85,0x00,0xe0,0x86,0x00,0xe0,0x87,0x00,0xe0,0x89,0x00,0xe0,
+0x8a,0x0f,0xe0,0x8b,0x00,0xe0,0x8c,0x00,0xe0,0x8d,0x00,0xe0,0x91,0xff,0xe0,0x50,
+0x8a,0xe0,0x51,0x04,0xe0,0x52,0x00,0xe0,0x58,0xf0,0xe3,0x0b,0x0a,0xe3,0x0c,0xff,
+0xed,0xf3,0x00,0xeb,0x35,0x77,0xeb,0x36,0x00,0xeb,0x40,0x00,0xeb,0x41,0x13,0xeb,
+0x42,0x00,0xeb,0x43,0x00,0xe8,0x01,0x10,0xe8,0x07,0x80,0xe8,0x08,0x10,0xe8,0x09,
+0x03,0xe8,0x0a,0x1a,0xec,0x45,0x00,0xec,0x46,0x00,0xec,0x47,0x00,0xec,0x48,0x00,
+0xe3,0x00,0x00,0xeb,0x43,0x01,0xe0,0x01,0xfe,0xe0,0x02,0x56,0xe0,0x03,0x93,0xe0,
+0x05,0x81,0xe0,0x11,0x00,0xe0,0xe0,0x00,0xee,0x16,0x08,0xee,0x15,0x10,0xee,0x17,
+0x02,0xee,0x18,0x00,0xee,0x0a,0x03,0xee,0x0b,0x00,0xee,0x1a,0x01,0xee,0x1e,0x01,
+0xed,0xa3,0x09,0xed,0xa4,0x01,0xed,0xe0,0x01,0xed,0xe1,0x07,0xed,0xe2,0x04,0xe6,
+0x70,0x02,0xe6,0x71,0x00,0xe6,0x72,0x00,0xe6,0x2b,0x00,0xf2,0x0b,0xff,0xf2,0x00,
+0x00,0xf2,0x01,0x07,0xf2,0x03,0x07,0xf2,0x06,0x02,0xf2,0x06,0x00,0xe6,0x58,0x00,
+0xe6,0x5a,0x00,0xe0,0x30,0x22,0xe0,0x3c,0x07,0xe0,0x31,0x51,0xe0,0x32,0x00,0xe0,
+0x3a,0x64,0xe0,0x37,0x00,0xe0,0x34,0x03,0xe0,0x36,0x00,0xe0,0x34,0x02,0xe0,0x36,
+0x90,0xe0,0x34,0x5e,0xe0,0x36,0x40,0xe0,0x34,0x72,0xe0,0x36,0x01,0xe0,0x34,0x4a,
+0xe0,0x36,0xf2,0xe0,0x34,0x48,0xe0,0x36,0x04,0xe0,0x34,0x49,0xe0,0x36,0x00,0xe0,
+0x34,0x5a,0xe0,0x36,0xa3,0xe0,0x34,0x4b,0xe0,0x36,0x01,0xe0,0x34,0x4c,0xe0,0x36,
+0x40,0xe0,0x34,0x4e,0xe0,0x36,0x40,0xe0,0x34,0x4f,0xe0,0x36,0x00,0xe0,0x34,0x5b,
+0xe0,0x36,0x89,0xe0,0x34,0x5c,0xe0,0x36,0x84,0xe0,0x34,0x70,0xe0,0x36,0x07,0xe0,
+0x34,0x05,0xe0,0x36,0x05,0xe0,0x34,0x54,0xe0,0x36,0x06,0xe0,0x34,0x57,0xe0,0x36,
+0x78,0xe0,0x34,0x58,0xe0,0x36,0x1a,0xe0,0x34,0x59,0xe0,0x36,0x1a,0xe0,0x34,0x28,
+0xe0,0x36,0x08,0xe0,0x34,0x29,0xe0,0x36,0x19,0xe0,0x34,0x2a,0xe0,0x36,0x06,0xe0,
+0x34,0x2b,0xe0,0x36,0x19,0xe0,0x34,0x3a,0xe0,0x36,0x00,0xe0,0x34,0x4d,0xe0,0x36,
+0x02,0xe0,0x34,0x14,0xe0,0x36,0x00,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,
+0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x04,0xe1,0x25,0x00,0xe1,0x26,0x03,0xe1,
+0x27,0x00,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,
+0x04,0xed,0x35,0x00,0xed,0x36,0x03,0xed,0x37,0x00,0xed,0x38,0x04,0xed,0x39,0x00,
+0xed,0x3a,0x03,0xed,0x3b,0x00,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,
+0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,
+0x04,0xed,0x45,0x00,0xed,0x46,0x03,0xed,0x47,0x00,0xed,0x48,0x04,0xed,0x49,0x00,
+0xed,0x4a,0x03,0xed,0x4b,0x00,0xed,0x4c,0x04,0xed,0x4d,0x00,0xed,0x4e,0x03,0xed,
+0x4f,0x00,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,
+0x04,0xed,0x55,0x00,0xed,0x56,0x03,0xed,0x57,0x00,0xed,0x58,0x04,0xed,0x59,0x00,
+0xed,0x5a,0x03,0xed,0x5b,0x00,0xed,0x5c,0x04,0xed,0x5d,0x00,0xed,0x5e,0x03,0xed,
+0x5f,0x00,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,
+0x04,0xed,0x65,0x00,0xed,0x66,0x03,0xed,0x67,0x00,0xed,0x68,0x04,0xed,0x69,0x00,
+0xed,0x6a,0x03,0xed,0x6b,0x00,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,
+0x6f,0xf0,0xee,0x10,0x04,0xee,0x11,0x00,0xee,0x12,0x03,0xee,0x13,0x00,0xee,0x53,
+0x01,0xe0,0x34,0x14,0xe0,0x36,0x00,0xe0,0x34,0x25,0xe0,0x36,0x00,0xe0,0x34,0x2c,
+0xe0,0x36,0x04,0xe0,0x34,0x2d,0xe0,0x36,0x00,0xe0,0x34,0x2e,0xe0,0x36,0x03,0xe0,
+0x34,0x2f,0xe0,0x36,0x00,0xe0,0x34,0x31,0xe0,0x36,0x03,0xe0,0x34,0x33,0xe0,0x36,
+0x03,0xe0,0x34,0x20,0xe0,0x36,0x05,0xe0,0x34,0x21,0xe0,0x36,0xdf,0xe0,0x34,0x22,
+0xe0,0x36,0x08,0xe0,0x34,0x23,0xe0,0x36,0x50,0xe0,0x34,0x04,0xe0,0x36,0x01,0xe0,
+0x34,0x44,0xe0,0x36,0x20,0xe0,0x34,0x03,0xe0,0x36,0x10,0xe6,0xc0,0x00,0xe6,0xc1,
+0x00,0xe6,0xc2,0x40,0xe6,0xc3,0x30,0xe6,0xc4,0x18,0xe6,0xc5,0x08,0xe6,0xc6,0x28,
+0xe6,0xc7,0x28,0xe6,0xc8,0x28,0xe6,0xc9,0x08,0xe6,0xca,0x38,0xe6,0xcb,0x18,0xe6,
+0xcc,0x28,0xe6,0xcd,0x18,0xe6,0xce,0x38,0xe6,0xcf,0x28,0xe6,0xd0,0x08,0xe6,0xd1,
+0x18,0xe6,0xd2,0x18,0xe6,0xd3,0x28,0xe6,0xd4,0x08,0xe6,0xd5,0x08,0xe6,0xd6,0x18,
+0xe6,0xd7,0x18,0xe6,0xd8,0x08,0xe6,0xd9,0x00,0xe6,0xda,0x38,0xe6,0xdb,0x08,0xe6,
+0xdc,0x38,0xe6,0xdd,0x08,0xe6,0xde,0x40,0xe6,0xdf,0x28,0xe6,0xe0,0x08,0xe6,0xe1,
+0x28,0xe6,0xe2,0x38,0xe6,0xe3,0x30,0xe6,0xe4,0x00,0xe6,0xe5,0x08,0xe6,0xe6,0x08,
+0xe6,0xe7,0x28,0xe8,0x98,0x03,0xe8,0x99,0x03,0xe8,0x9a,0x3d,0xe8,0x9b,0x2d,0xea,
+0x20,0x06,0xea,0x21,0x04,0xea,0x22,0x39,0xea,0x23,0x2b,0xea,0x24,0x15,0xea,0x25,
+0x10,0xea,0x26,0x2a,0xea,0x27,0x20,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,
+0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x08,0xe1,0x25,0x00,0xe1,0x26,0x06,0xe1,
+0x27,0x04,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,
+0x08,0xed,0x35,0x00,0xed,0x36,0x06,0xed,0x37,0x00,0xed,0x38,0x08,0xed,0x39,0x00,
+0xed,0x3a,0x06,0xed,0x3b,0x00,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,
+0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,
+0x08,0xed,0x45,0x00,0xed,0x46,0x06,0xed,0x47,0x00,0xed,0x48,0x08,0xed,0x49,0x00,
+0xed,0x4a,0x06,0xed,0x4b,0x00,0xed,0x4c,0x02,0xed,0x4d,0x80,0xed,0x4e,0x01,0xed,
+0x4f,0xe0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,
+0x08,0xed,0x55,0x00,0xed,0x56,0x06,0xed,0x57,0x00,0xed,0x58,0x08,0xed,0x59,0x00,
+0xed,0x5a,0x06,0xed,0x5b,0x00,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,
+0x63,0x00,0xed,0x64,0x08,0xed,0x65,0x00,0xed,0x66,0x06,0xed,0x67,0x00,0xed,0x68,
+0x08,0xed,0x69,0x00,0xed,0x6a,0x06,0xed,0x6b,0x00,0xed,0x6c,0x01,0xed,0x6d,0x40,
+0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x53,0x01,0xe0,0x34,0x14,0xe0,0x36,0x00,0xe0,
+0x34,0x25,0xe0,0x36,0x00,0xe0,0x34,0x2c,0xe0,0x36,0x08,0xe0,0x34,0x2d,0xe0,0x36,
+0x20,0xe0,0x34,0x2e,0xe0,0x36,0x06,0xe0,0x34,0x2f,0xe0,0x36,0x20,0xe0,0x34,0x31,
+0xe0,0x36,0x01,0xe0,0x34,0x33,0xe0,0x36,0x01,0xe0,0x34,0x20,0xe0,0x36,0x07,0xe0,
+0x34,0x21,0xe0,0x36,0x80,0xe0,0x34,0x22,0xe0,0x36,0x08,0xe0,0x34,0x23,0xe0,0x36,
+0xd0,0xe0,0x34,0x04,0xe0,0x36,0x02,0xe0,0x34,0x44,0xe0,0x36,0x00,0xe0,0x34,0x03,
+0xe0,0x36,0x10,0xe6,0xc0,0x00,0xe6,0xc1,0x00,0xe6,0xc2,0x80,0xe6,0xc3,0x60,0xe6,
+0xc4,0x30,0xe6,0xc5,0x10,0xe6,0xc6,0x50,0xe6,0xc7,0x50,0xe6,0xc8,0x50,0xe6,0xc9,
+0x10,0xe6,0xca,0x70,0xe6,0xcb,0x30,0xe6,0xcc,0x50,0xe6,0xcd,0x30,0xe6,0xce,0x70,
+0xe6,0xcf,0x50,0xe6,0xd0,0x10,0xe6,0xd1,0x30,0xe6,0xd2,0x30,0xe6,0xd3,0x50,0xe6,
+0xd4,0x10,0xe6,0xd5,0x10,0xe6,0xd6,0x30,0xe6,0xd7,0x30,0xe6,0xd8,0x10,0xe6,0xd9,
+0x00,0xe6,0xda,0x70,0xe6,0xdb,0x10,0xe6,0xdc,0x70,0xe6,0xdd,0x10,0xe6,0xde,0x80,
+0xe6,0xdf,0x50,0xe6,0xe0,0x10,0xe6,0xe1,0x50,0xe6,0xe2,0x70,0xe6,0xe3,0x60,0xe6,
+0xe4,0x00,0xe6,0xe5,0x10,0xe6,0xe6,0x10,0xe6,0xe7,0x50,0xe8,0x98,0x06,0xe8,0x99,
+0x06,0xe8,0x9a,0x79,0xe8,0x9b,0x59,0xe8,0x01,0x10,0xe8,0x07,0x90,0xe8,0x08,0x10,
+0xe8,0x09,0x03,0xe8,0x0a,0x1a,0xec,0x45,0x00,0xec,0x46,0x00,0xec,0x47,0x00,0xec,
+0x48,0x00,0xea,0x20,0x2d,0xea,0x21,0x28,0xea,0x22,0x52,0xea,0x23,0x38,0xea,0x24,
+0x2d,0xea,0x25,0x21,0xea,0x26,0x52,0xea,0x27,0x3e,0xff,0xff,0xff,0xe1,0x20,0x00,
+0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,0x25,0x00,0xe1,
+0x26,0x07,0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,
+0x00,0xed,0x34,0x0a,0xed,0x35,0x00,0xed,0x36,0x07,0xed,0x37,0x80,0xed,0x38,0x0a,
+0xed,0x39,0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,
+0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,
+0x00,0xed,0x44,0x0a,0xed,0x45,0x00,0xed,0x46,0x07,0xed,0x47,0x80,0xed,0x48,0x0a,
+0xed,0x49,0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,0x4d,0x40,0xed,
+0x4e,0x00,0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,
+0x00,0xed,0x54,0x0a,0xed,0x55,0x00,0xed,0x56,0x07,0xed,0x57,0x80,0xed,0x58,0x0a,
+0xed,0x59,0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,0x08,0xed,0x5d,0x00,0xed,
+0x5e,0x06,0xed,0x5f,0x00,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,
+0x00,0xed,0x64,0x0a,0xed,0x65,0x00,0xed,0x66,0x07,0xed,0x67,0x80,0xed,0x68,0x0a,
+0xed,0x69,0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,
+0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x08,0xee,0x11,0x00,0xee,0x12,0x06,0xee,0x13,
+0x00,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,
+0xe1,0x24,0x0a,0xe1,0x25,0x00,0xe1,0x26,0x07,0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,
+0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,0x0a,0xed,0x35,0x00,0xed,0x36,
+0x07,0xed,0x37,0x80,0xed,0x38,0x0a,0xed,0x39,0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,
+0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,
+0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,0x0a,0xed,0x45,0x00,0xed,0x46,
+0x07,0xed,0x47,0x80,0xed,0x48,0x0a,0xed,0x49,0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,
+0xed,0x4c,0x01,0xed,0x4d,0x40,0xed,0x4e,0x00,0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,
+0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,0x0a,0xed,0x55,0x00,0xed,0x56,
+0x07,0xed,0x57,0x80,0xed,0x58,0x0a,0xed,0x59,0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,
+0xed,0x5c,0x06,0xed,0x5d,0x40,0xed,0x5e,0x04,0xed,0x5f,0xb0,0xed,0x60,0x00,0xed,
+0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,0x0a,0xed,0x65,0x00,0xed,0x66,
+0x07,0xed,0x67,0x80,0xed,0x68,0x0a,0xed,0x69,0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,
+0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x06,0xee,
+0x11,0x40,0xee,0x12,0x04,0xee,0x13,0xb0,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,
+0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,0x25,0x00,0xe1,0x26,0x07,
+0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,
+0x34,0x0a,0xed,0x35,0x00,0xed,0x36,0x07,0xed,0x37,0x80,0xed,0x38,0x0a,0xed,0x39,
+0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,
+0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,
+0x44,0x0a,0xed,0x45,0x00,0xed,0x46,0x07,0xed,0x47,0x80,0xed,0x48,0x0a,0xed,0x49,
+0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,0x4d,0x40,0xed,0x4e,0x00,
+0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,
+0x54,0x0a,0xed,0x55,0x00,0xed,0x56,0x07,0xed,0x57,0x80,0xed,0x58,0x0a,0xed,0x59,
+0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,0x05,0xed,0x5d,0x00,0xed,0x5e,0x03,
+0xed,0x5f,0xc0,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,
+0x64,0x0a,0xed,0x65,0x00,0xed,0x66,0x07,0xed,0x67,0x80,0xed,0x68,0x0a,0xed,0x69,
+0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,
+0xed,0x6f,0xf0,0xee,0x10,0x05,0xee,0x11,0x00,0xee,0x12,0x03,0xee,0x13,0xc0,0xff,
+0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,
+0x0a,0xe1,0x25,0x00,0xe1,0x26,0x07,0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,0x31,0x00,
+0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,0x0a,0xed,0x35,0x00,0xed,0x36,0x07,0xed,
+0x37,0x80,0xed,0x38,0x0a,0xed,0x39,0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,
+0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,
+0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,0x0a,0xed,0x45,0x00,0xed,0x46,0x07,0xed,
+0x47,0x80,0xed,0x48,0x0a,0xed,0x49,0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,
+0x01,0xed,0x4d,0x40,0xed,0x4e,0x00,0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,0x51,0x00,
+0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,0x0a,0xed,0x55,0x00,0xed,0x56,0x07,0xed,
+0x57,0x80,0xed,0x58,0x0a,0xed,0x59,0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,
+0x04,0xed,0x5d,0x00,0xed,0x5e,0x03,0xed,0x5f,0x00,0xed,0x60,0x00,0xed,0x61,0x00,
+0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,0x0a,0xed,0x65,0x00,0xed,0x66,0x07,0xed,
+0x67,0x80,0xed,0x68,0x0a,0xed,0x69,0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,
+0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x04,0xee,0x11,0x00,
+0xee,0x12,0x03,0xee,0x13,0x00,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,
+0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,0x25,0x00,0xe1,0x26,0x07,0xe1,0x27,
+0xbc,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,0x0a,
+0xed,0x35,0x00,0xed,0x36,0x07,0xed,0x37,0x80,0xed,0x38,0x0a,0xed,0x39,0x00,0xed,
+0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,
+0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,0x0a,
+0xed,0x45,0x00,0xed,0x46,0x07,0xed,0x47,0x80,0xed,0x48,0x0a,0xed,0x49,0x00,0xed,
+0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,0x4d,0x40,0xed,0x4e,0x00,0xed,0x4f,
+0xf0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,0x0a,
+0xed,0x55,0x00,0xed,0x56,0x07,0xed,0x57,0x80,0xed,0x58,0x0a,0xed,0x59,0x00,0xed,
+0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,0x03,0xed,0x5d,0x20,0xed,0x5e,0x02,0xed,0x5f,
+0x58,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,0x0a,
+0xed,0x65,0x00,0xed,0x66,0x07,0xed,0x67,0x80,0xed,0x68,0x0a,0xed,0x69,0x00,0xed,
+0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,
+0xf0,0xee,0x10,0x03,0xee,0x11,0x20,0xee,0x12,0x02,0xee,0x13,0x58,0xff,0xff,0xff,
+0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,
+0x25,0x00,0xe1,0x26,0x07,0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,
+0x00,0xed,0x33,0x00,0xed,0x34,0x0a,0xed,0x35,0x00,0xed,0x36,0x07,0xed,0x37,0x80,
+0xed,0x38,0x0a,0xed,0x39,0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,
+0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,
+0x00,0xed,0x43,0x00,0xed,0x44,0x0a,0xed,0x45,0x00,0xed,0x46,0x07,0xed,0x47,0x80,
+0xed,0x48,0x0a,0xed,0x49,0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,
+0x4d,0x40,0xed,0x4e,0x00,0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,
+0x00,0xed,0x53,0x00,0xed,0x54,0x0a,0xed,0x55,0x00,0xed,0x56,0x07,0xed,0x57,0x80,
+0xed,0x58,0x0a,0xed,0x59,0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,0x02,0xed,
+0x5d,0x80,0xed,0x5e,0x01,0xed,0x5f,0xe0,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,
+0x00,0xed,0x63,0x00,0xed,0x64,0x0a,0xed,0x65,0x00,0xed,0x66,0x07,0xed,0x67,0x80,
+0xed,0x68,0x0a,0xed,0x69,0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,
+0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x02,0xee,0x11,0x80,0xee,0x12,
+0x01,0xee,0x13,0xe0,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,
+0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,0x25,0x00,0xe1,0x26,0x07,0xe1,0x27,0xbc,0xed,
+0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,0x0a,0xed,0x35,
+0x00,0xed,0x36,0x07,0xed,0x37,0x80,0xed,0x38,0x0a,0xed,0x39,0x00,0xed,0x3a,0x07,
+0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,
+0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,0x0a,0xed,0x45,
+0x00,0xed,0x46,0x07,0xed,0x47,0x80,0xed,0x48,0x0a,0xed,0x49,0x00,0xed,0x4a,0x07,
+0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,0x4d,0x40,0xed,0x4e,0x00,0xed,0x4f,0xf0,0xed,
+0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,0x0a,0xed,0x55,
+0x00,0xed,0x56,0x07,0xed,0x57,0x80,0xed,0x58,0x0a,0xed,0x59,0x00,0xed,0x5a,0x07,
+0xed,0x5b,0x80,0xed,0x5c,0x01,0xed,0x5d,0x40,0xed,0x5e,0x00,0xed,0x5f,0xf0,0xed,
+0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,0x0a,0xed,0x65,
+0x00,0xed,0x66,0x07,0xed,0x67,0x80,0xed,0x68,0x0a,0xed,0x69,0x00,0xed,0x6a,0x07,
+0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,
+0x10,0x01,0xee,0x11,0x40,0xee,0x12,0x00,0xee,0x13,0xf0,0xff,0xff,0xff,0xe1,0x20,
+0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,0x00,0xe1,0x24,0x0a,0xe1,0x25,0x00,
+0xe1,0x26,0x07,0xe1,0x27,0xbc,0xed,0x30,0x00,0xed,0x31,0x00,0xed,0x32,0x00,0xed,
+0x33,0x00,0xed,0x34,0x0a,0xed,0x35,0x00,0xed,0x36,0x07,0xed,0x37,0x80,0xed,0x38,
+0x0a,0xed,0x39,0x00,0xed,0x3a,0x07,0xed,0x3b,0x80,0xed,0x3c,0x00,0xed,0x3d,0x50,
+0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,0xed,0x41,0x00,0xed,0x42,0x00,0xed,
+0x43,0x00,0xed,0x44,0x0a,0xed,0x45,0x00,0xed,0x46,0x07,0xed,0x47,0x80,0xed,0x48,
+0x0a,0xed,0x49,0x00,0xed,0x4a,0x07,0xed,0x4b,0x80,0xed,0x4c,0x01,0xed,0x4d,0x40,
+0xed,0x4e,0x00,0xed,0x4f,0xf0,0xed,0x50,0x00,0xed,0x51,0x00,0xed,0x52,0x00,0xed,
+0x53,0x00,0xed,0x54,0x0a,0xed,0x55,0x00,0xed,0x56,0x07,0xed,0x57,0x80,0xed,0x58,
+0x0a,0xed,0x59,0x00,0xed,0x5a,0x07,0xed,0x5b,0x80,0xed,0x5c,0x00,0xed,0x5d,0xa0,
+0xed,0x5e,0x00,0xed,0x5f,0x78,0xed,0x60,0x00,0xed,0x61,0x00,0xed,0x62,0x00,0xed,
+0x63,0x00,0xed,0x64,0x0a,0xed,0x65,0x00,0xed,0x66,0x07,0xed,0x67,0x80,0xed,0x68,
+0x0a,0xed,0x69,0x00,0xed,0x6a,0x07,0xed,0x6b,0x80,0xed,0x6c,0x01,0xed,0x6d,0x40,
+0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x00,0xee,0x11,0xa0,0xee,0x12,0x00,0xee,
+0x13,0x78,0xff,0xff,0xff,0xe1,0x20,0x00,0xe1,0x21,0x00,0xe1,0x22,0x00,0xe1,0x23,
+0x00,0xe1,0x24,0x02,0xe1,0x25,0x80,0xe1,0x26,0x01,0xe1,0x27,0xe0,0xed,0x30,0x00,
+0xed,0x31,0x00,0xed,0x32,0x00,0xed,0x33,0x00,0xed,0x34,0x02,0xed,0x35,0x80,0xed,
+0x36,0x01,0xed,0x37,0xe0,0xed,0x38,0x02,0xed,0x39,0x80,0xed,0x3a,0x01,0xed,0x3b,
+0xe0,0xed,0x3c,0x00,0xed,0x3d,0x50,0xed,0x3e,0x00,0xed,0x3f,0x3c,0xed,0x40,0x00,
+0xed,0x41,0x00,0xed,0x42,0x00,0xed,0x43,0x00,0xed,0x44,0x02,0xed,0x45,0x80,0xed,
+0x46,0x01,0xed,0x47,0xe0,0xed,0x48,0x02,0xed,0x49,0x80,0xed,0x4a,0x01,0xed,0x4b,
+0xe0,0xed,0x4c,0x02,0xed,0x4d,0x80,0xed,0x4e,0x01,0xed,0x4f,0xe0,0xed,0x50,0x00,
+0xed,0x51,0x00,0xed,0x52,0x00,0xed,0x53,0x00,0xed,0x54,0x02,0xed,0x55,0x80,0xed,
+0x56,0x01,0xed,0x57,0xe0,0xed,0x58,0x02,0xed,0x59,0x80,0xed,0x5a,0x01,0xed,0x5b,
+0xe0,0xed,0x5c,0x02,0xed,0x5d,0x80,0xed,0x5e,0x01,0xed,0x5f,0xe0,0xed,0x60,0x00,
+0xed,0x61,0x00,0xed,0x62,0x00,0xed,0x63,0x00,0xed,0x64,0x02,0xed,0x65,0x80,0xed,
+0x66,0x01,0xed,0x67,0xe0,0xed,0x68,0x02,0xed,0x69,0x80,0xed,0x6a,0x01,0xed,0x6b,
+0xe0,0xed,0x6c,0x01,0xed,0x6d,0x40,0xed,0x6e,0x00,0xed,0x6f,0xf0,0xee,0x10,0x02,
+0xee,0x11,0x80,0xee,0x12,0x01,0xee,0x13,0xe0,0xee,0x53,0x01,0xe0,0x34,0x25,0xe0,
+0x36,0x00,0xe0,0x34,0x2c,0xe0,0x36,0x02,0xe0,0x34,0x2d,0xe0,0x36,0xaa,0xe0,0x34,
+0x2e,0xe0,0x36,0x02,0xe0,0x34,0x2f,0xe0,0x36,0x00,0xe0,0x34,0x31,0xe0,0x36,0x05,
+0xe0,0x34,0x33,0xe0,0x36,0x05,0xe0,0x34,0x20,0xe0,0x36,0x03,0xe0,0x34,0x21,0xe0,
+0x36,0x22,0xe0,0x34,0x22,0xe0,0x36,0x08,0xe0,0x34,0x23,0xe0,0x36,0x50,0xe0,0x34,
+0x04,0xe0,0x36,0x01,0xe0,0x34,0x44,0xe0,0x36,0x20,0xe0,0x34,0x03,0xe0,0x36,0x10,
+0xe6,0xc0,0x00,0xe6,0xc1,0x00,0xe6,0xc2,0x50,0xe6,0xc3,0x3c,0xe6,0xc4,0x1e,0xe6,
+0xc5,0x0a,0xe6,0xc6,0x32,0xe6,0xc7,0x32,0xe6,0xc8,0x32,0xe6,0xc9,0x0a,0xe6,0xca,
+0x46,0xe6,0xcb,0x1e,0xe6,0xcc,0x32,0xe6,0xcd,0x1e,0xe6,0xce,0x46,0xe6,0xcf,0x32,
+0xe6,0xd0,0x0a,0xe6,0xd1,0x1e,0xe6,0xd2,0x1e,0xe6,0xd3,0x32,0xe6,0xd4,0x0a,0xe6,
+0xd5,0x0a,0xe6,0xd6,0x1e,0xe6,0xd7,0x1e,0xe6,0xd8,0x0a,0xe6,0xd9,0x00,0xe6,0xda,
+0x46,0xe6,0xdb,0x0a,0xe6,0xdc,0x46,0xe6,0xdd,0x0a,0xe6,0xde,0x50,0xe6,0xdf,0x32,
+0xe6,0xe0,0x0a,0xe6,0xe1,0x32,0xe6,0xe2,0x46,0xe6,0xe3,0x3c,0xe6,0xe4,0x00,0xe6,
+0xe5,0x0a,0xe6,0xe6,0x0a,0xe6,0xe7,0x32,0xe8,0x98,0x03,0xe8,0x99,0x03,0xe8,0x9a,
+0x4d,0xe8,0x9b,0x39,0xea,0x20,0x08,0xea,0x21,0x06,0xea,0x22,0x48,0xea,0x23,0x36,
+0xea,0x24,0x1b,0xea,0x25,0x14,0xea,0x26,0x35,0xea,0x27,0x28,0xff,0xff,0xff,0xe8,
+0x10,0x00,0xe8,0x11,0xe6,0xe8,0x12,0x13,0xe8,0x13,0xec,0xe8,0x14,0x0c,0xe8,0x15,
+0x00,0xe8,0x16,0xe6,0xe8,0x17,0x13,0xe8,0x18,0xec,0xe8,0x19,0x0c,0xe8,0x1a,0x00,
+0xe8,0x1b,0xe6,0xe8,0x1c,0x13,0xe8,0x1d,0xec,0xe8,0x1e,0x0c,0xe8,0x1f,0x00,0xe8,
+0x20,0xe6,0xe8,0x21,0x13,0xe8,0x22,0xec,0xe8,0x23,0x0c,0xe8,0x24,0x00,0xe8,0x25,
+0xe6,0xe8,0x26,0x13,0xe8,0x27,0xec,0xe8,0x28,0x0c,0xe8,0x29,0x00,0xe8,0x2a,0xe6,
+0xe8,0x2b,0x13,0xe8,0x2c,0xec,0xe8,0x2d,0x0c,0xe8,0x2e,0x00,0xe8,0x2f,0xe6,0xe8,
+0x30,0x13,0xe8,0x31,0xec,0xe8,0x32,0x0c,0xe8,0x33,0x00,0xe8,0x34,0xe6,0xe8,0x35,
+0x13,0xe8,0x36,0xec,0xe8,0x37,0x0c,0xe8,0x38,0x00,0xe8,0x39,0xe6,0xe8,0x3a,0x13,
+0xe8,0x3b,0xec,0xe8,0x3c,0x0c,0xe8,0x3d,0x00,0xe8,0x3e,0xe3,0xe8,0x3f,0x13,0xe8,
+0x40,0xec,0xe8,0x41,0x0b,0xe8,0x42,0x00,0xe8,0x43,0x4b,0xe8,0x44,0x47,0xe8,0x45,
+0x53,0xe8,0x46,0x3f,0xe8,0x47,0x00,0xe8,0x48,0x75,0xe8,0x49,0x44,0xe8,0x4a,0x7c,
+0xe8,0x4b,0x3d,0xe8,0x4c,0x00,0xe8,0x4d,0x6d,0xe8,0x4e,0x45,0xe8,0x4f,0x75,0xe8,
+0x50,0x3e,0xe8,0x51,0x00,0xe8,0x52,0x65,0xe8,0x53,0x46,0xe8,0x54,0x6d,0xe8,0x55,
+0x3f,0xe8,0x56,0x00,0xe8,0x57,0x5d,0xe8,0x58,0x48,0xe8,0x59,0x65,0xe8,0x5a,0x41,
+0xe8,0x5b,0x00,0xe8,0x5c,0x55,0xe8,0x5d,0x4d,0xe8,0x5e,0x5d,0xe8,0x5f,0x45,0xe8,
+0x60,0x00,0xe8,0x61,0x4d,0xe8,0x62,0x51,0xe8,0x63,0x55,0xe8,0x64,0x49,0xe8,0x65,
+0x00,0xe8,0x66,0x47,0xe8,0x67,0x52,0xe8,0x68,0x4e,0xe8,0x69,0x4a,0xe8,0x6a,0x00,
+0xe8,0x6b,0x3f,0xe8,0x6c,0x53,0xe8,0x6d,0x47,0xe8,0x6e,0x4c,0xe8,0x6f,0x00,0xe8,
+0x70,0x3e,0xe8,0x71,0x5a,0xe8,0x72,0x45,0xe8,0x73,0x53,0xe8,0x74,0x00,0xe8,0x75,
+0x3d,0xe8,0x76,0x61,0xe8,0x77,0x45,0xe8,0x78,0x59,0xe8,0x79,0x00,0xe8,0x7a,0x3c,
+0xe8,0x7b,0x69,0xe8,0x7c,0x44,0xe8,0x7d,0x61,0xe8,0x7e,0x00,0xe8,0x7f,0x3b,0xe8,
+0x80,0x72,0xe8,0x81,0x43,0xe8,0x82,0x6a,0xe8,0x83,0x00,0xe8,0x84,0x3a,0xe8,0x85,
+0x7b,0xe8,0x86,0x42,0xe8,0x87,0x72,0xe8,0x07,0xc0,0xe8,0x08,0x20,0xeb,0x90,0x00,
+0xeb,0x91,0x00,0xeb,0x92,0x00,0xeb,0x93,0x00,0xeb,0x94,0x00,0xeb,0x95,0x00,0xeb,
+0x96,0x00,0xeb,0x97,0x00,0xeb,0xd0,0x00,0xeb,0xd1,0x00,0xeb,0xd2,0x00,0xeb,0xd3,
+0x00,0xeb,0xd4,0x00,0xeb,0xd5,0x00,0xeb,0xd6,0x00,0xeb,0xd7,0x00,0xeb,0xb0,0x00,
+0xeb,0xb1,0x00,0xeb,0xb2,0x00,0xeb,0xb3,0x00,0xeb,0xb4,0x00,0xeb,0xb5,0x00,0xeb,
+0xb6,0x00,0xeb,0xb7,0x00,0xe3,0x31,0x04,0xe3,0x32,0xab,0xe3,0x33,0x0d,0xe3,0x34,
+0x1f,0xe3,0x35,0x00,0xe3,0x36,0x38,0xe3,0x37,0x0f,0xe3,0x38,0x61,0xe3,0x39,0x03,
+0xe3,0x3a,0x59,0xe3,0x3b,0x0f,0xe3,0x3c,0x46,0xe3,0x3d,0x0f,0xe3,0x3e,0xe6,0xe3,
+0x3f,0x0d,0xe3,0x40,0xc9,0xe3,0x41,0x04,0xe3,0x42,0x52,0xe4,0x60,0x00,0xe4,0x61,
+0x01,0xe4,0x62,0x04,0xe4,0x63,0x06,0xe4,0x64,0x08,0xe4,0x65,0x0c,0xe4,0x66,0x10,
+0xe4,0x67,0x14,0xe4,0x68,0x18,0xe4,0x69,0x1c,0xe4,0x6a,0x20,0xe4,0x6b,0x24,0xe4,
+0x6c,0x28,0xe4,0x6d,0x2c,0xe4,0x6e,0x30,0xe4,0x6f,0x38,0xe4,0x70,0x40,0xe4,0x71,
+0x48,0xe4,0x72,0x50,0xe4,0x73,0x58,0xe4,0x74,0x60,0xe4,0x75,0x68,0xe4,0x76,0x70,
+0xe4,0x77,0x78,0xe4,0x78,0x80,0xe4,0x79,0x90,0xe4,0x7a,0xa0,0xe4,0x7b,0xb0,0xe4,
+0x7c,0xc0,0xe4,0x7d,0xd0,0xe4,0x7e,0xe0,0xe4,0x7f,0xf0,0xe0,0x05,0x01,0xe4,0x00,
+0x00,0xe4,0x01,0x07,0xe4,0x02,0x15,0xe4,0x03,0x1d,0xe4,0x04,0x24,0xe4,0x05,0x31,
+0xe4,0x06,0x3d,0xe4,0x07,0x4a,0xe4,0x08,0x54,0xe4,0x09,0x5d,0xe4,0x0a,0x65,0xe4,
+0x0b,0x6b,0xe4,0x0c,0x72,0xe4,0x0d,0x79,0xe4,0x0e,0x80,0xe4,0x0f,0x8b,0xe4,0x10,
+0x95,0xe4,0x11,0xa0,0xe4,0x12,0xab,0xe4,0x13,0xb3,0xe4,0x14,0xbb,0xe4,0x15,0xc2,
+0xe4,0x16,0xc8,0xe4,0x17,0xce,0xe4,0x18,0xd4,0xe4,0x19,0xdc,0xe4,0x1a,0xe4,0xe4,
+0x1b,0xe9,0xe4,0x1c,0xee,0xe4,0x1d,0xf3,0xe4,0x1e,0xf7,0xe4,0x1f,0xfb,0xe4,0x20,
+0x00,0xe4,0x21,0x07,0xe4,0x22,0x15,0xe4,0x23,0x1d,0xe4,0x24,0x24,0xe4,0x25,0x31,
+0xe4,0x26,0x3d,0xe4,0x27,0x4a,0xe4,0x28,0x54,0xe4,0x29,0x5d,0xe4,0x2a,0x65,0xe4,
+0x2b,0x6b,0xe4,0x2c,0x72,0xe4,0x2d,0x79,0xe4,0x2e,0x80,0xe4,0x2f,0x8b,0xe4,0x30,
+0x95,0xe4,0x31,0xa0,0xe4,0x32,0xab,0xe4,0x33,0xb3,0xe4,0x34,0xbb,0xe4,0x35,0xc2,
+0xe4,0x36,0xc8,0xe4,0x37,0xce,0xe4,0x38,0xd4,0xe4,0x39,0xdc,0xe4,0x3a,0xe4,0xe4,
+0x3b,0xe9,0xe4,0x3c,0xee,0xe4,0x3d,0xf3,0xe4,0x3e,0xf7,0xe4,0x3f,0xfb,0xe4,0x40,
+0x00,0xe4,0x41,0x07,0xe4,0x42,0x15,0xe4,0x43,0x1d,0xe4,0x44,0x24,0xe4,0x45,0x31,
+0xe4,0x46,0x3d,0xe4,0x47,0x4a,0xe4,0x48,0x54,0xe4,0x49,0x5d,0xe4,0x4a,0x65,0xe4,
+0x4b,0x6b,0xe4,0x4c,0x72,0xe4,0x4d,0x79,0xe4,0x4e,0x80,0xe4,0x4f,0x8b,0xe4,0x50,
+0x95,0xe4,0x51,0xa0,0xe4,0x52,0xab,0xe4,0x53,0xb3,0xe4,0x54,0xbb,0xe4,0x55,0xc2,
+0xe4,0x56,0xc8,0xe4,0x57,0xce,0xe4,0x58,0xd4,0xe4,0x59,0xdc,0xe4,0x5a,0xe4,0xe4,
+0x5b,0xe9,0xe4,0x5c,0xee,0xe4,0x5d,0xf3,0xe4,0x5e,0xf7,0xe4,0x5f,0xfb,0xe1,0xe1,
+0x00,0xe1,0xe2,0x01,0xe1,0xe3,0x80,0xe1,0xe4,0x00,0xe1,0xe5,0x80,0xe1,0xe6,0x04,
+0xe1,0xe7,0x01,0xe1,0xe8,0x19,0xe1,0xe9,0x01,0xe1,0xea,0x26,0xe1,0xeb,0x00,0xe1,
+0xec,0xe6,0xe1,0xed,0x00,0xe1,0xee,0xe1,0xe1,0xef,0x03,0xe1,0xf0,0xff,0xe1,0xf1,
+0x00,0xe1,0xf2,0x66,0xe1,0xf3,0x88,0xe3,0x06,0x05,0xe3,0x07,0x5f,0xe3,0x08,0x0f,
+0xe3,0x09,0x0f,0xe5,0x01,0x00,0xe5,0x02,0x08,0xe5,0x03,0x08,0xe5,0x04,0x32,0xe5,
+0x05,0x31,0xe5,0x06,0x00,0xe5,0x07,0x64,0xe5,0x08,0x00,0xe5,0x09,0x00,0xe5,0x0a,
+0x13,0xe5,0x0b,0x0c,0xe5,0x0c,0x00,0xe5,0x0d,0xcc,0xe5,0x0e,0x00,0xe5,0x0f,0xcc,
+0xe5,0x10,0x00,0xe5,0x11,0x0a,0xe5,0x12,0x00,0xe5,0x13,0x02,0xe5,0x14,0x64,0xe5,
+0x15,0x01,0xe5,0x16,0x99,0xe5,0x17,0x00,0xe5,0x18,0x28,0xe5,0x19,0x00,0xe5,0x1a,
+0x00,0xe5,0x1b,0x32,0xe5,0x1c,0x00,0xe5,0x1d,0x03,0xe5,0x1e,0x64,0xe5,0x1f,0x0a,
+0xe0,0x06,0x0c,0xe5,0x21,0x00,0xe5,0x22,0x08,0xe5,0x23,0x08,0xe5,0x24,0x32,0xe5,
+0x25,0x31,0xe5,0x26,0x00,0xe5,0x27,0x64,0xe5,0x28,0x00,0xe5,0x29,0x00,0xe5,0x2a,
+0x13,0xe5,0x2b,0x0c,0xe5,0x2c,0x7f,0xe5,0x2d,0x7f,0xe5,0x2e,0x00,0xe5,0x2f,0x10,
+0xe5,0x30,0x00,0xe5,0x31,0x10,0xe5,0x32,0x64,0xe5,0x33,0xcc,0xe5,0x34,0x0a,0xe5,
+0x35,0x00,0xe5,0x36,0x00,0xe5,0x37,0xc8,0xe5,0x38,0x00,0xe5,0x39,0x28,0xe5,0x3a,
+0x64,0xe5,0x3b,0x00,0xe3,0x11,0xc0,0xe3,0x12,0x88,0xe3,0x13,0x78,0xe3,0x14,0x80,
+0xe3,0x15,0x40,0xe3,0x16,0x88,0xe3,0x17,0x78,0xe3,0x18,0x80,0xe0,0x04,0x20,0xe6,
+0x71,0x00,0xee,0x5c,0x08,0xee,0x5d,0x00,0xee,0x5e,0x06,0xee,0x5f,0x00,0xf0,0x30,
+0x00,0xf0,0x31,0x0a,0xf0,0x04,0x00,0xf0,0x05,0x40,0xf0,0x06,0x00,0xf0,0x07,0x00,
+0xf0,0x08,0x40,0xf0,0x09,0x00,0xf0,0x0a,0x00,0xf0,0x0b,0x05,0xf0,0x0c,0x00,0xf0,
+0x0d,0x05,0xf0,0x10,0x00,0xf0,0x11,0x00,0xf0,0x12,0x64,0xf0,0x13,0x40,0xf0,0x14,
+0x78,0xf0,0x15,0x88,0xf0,0x16,0xc0,0xf0,0x17,0x78,0xf0,0x18,0x88,0xf0,0x19,0xff,
+0xf0,0x20,0x00,0xf0,0x21,0x64,0xf0,0x22,0x01,0xf0,0x23,0x01,0xf0,0x24,0x01,0xf0,
+0x25,0x01,0xf0,0x26,0x10,0xf0,0x27,0x01,0xf0,0x28,0x80,0xf0,0x29,0x80,0xf0,0x2a,
+0x80,0xf0,0x2b,0x80,0xf0,0x2c,0x00,0xe2,0x50,0x1e,0xe2,0x51,0x64,0xe2,0x52,0x3c,
+0xe2,0x55,0x64,0xe2,0x5c,0x30,0xe2,0x5e,0x32,0xe2,0x60,0x0c,0xe2,0x61,0x00,0xe2,
+0x62,0xff,0xff,0xff,0xff,0x3e,0x4c,0xcc,0xcd,0x3e,0x42,0x8f,0x5c,0x3e,0x38,0x51,
+0xec,0x3e,0x2e,0x14,0x7b,0x3e,0x23,0xd7,0x0a,0x3e,0x19,0x99,0x9a,0x3e,0x0f,0x5c,
+0x29,0x3e,0x05,0x1e,0xb8,0x3d,0xf5,0xc2,0x8f,0x3d,0xe1,0x47,0xae,0x3d,0xcc,0xcc,
+0xcd,0x3d,0xb8,0x51,0xec,0x3d,0xa3,0xd7,0x0a,0x3d,0x8f,0x5c,0x29,0x3d,0x75,0xc2,
+0x8f,0x3d,0x4c,0xcc,0xcd,0x3d,0x23,0xd7,0x0a,0x3c,0xf5,0xc2,0x8f,0x3c,0xa3,0xd7,
+0x0a,0x3c,0x23,0xd7,0x0a,0x3e,0x08,0x88,0x89,0x3e,0x00,0x00,0x00,0x3d,0xee,0xee,
+0xef,0x3d,0xdd,0xdd,0xde,0x3d,0xcc,0xcc,0xcd,0x3d,0xbb,0xbb,0xbc,0x3d,0xaa,0xaa,
+0xab,0x3d,0x99,0x99,0x9a,0x3d,0x88,0x88,0x89,0x3d,0x6e,0xee,0xef,0x3d,0x4c,0xcc,
+0xcd,0x3d,0x2a,0xaa,0xab,0x3d,0x08,0x88,0x89,0x3c,0xcc,0xcc,0xcd,0x3c,0x88,0x88,
+0x89,0x3c,0x08,0x88,0x89,0x00,0x13,0x00,0x0f,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,
+0x09,0x09,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x05,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x05,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x05,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x01,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x01,0x05,0x05,0x01,0x00,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x05,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x05,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x01,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x01,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x01,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x01,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x09,0x05,
+0x01,0x01,0x00,0x05,0x01,0x01,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x06,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x06,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x00,0x06,0x06,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x01,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x09,0x09,0x09,0x09,0x09,0x09,0x09,
+0x09,0x09,0x09,0x09,0x09,0x09,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x09,0x05,0x05,
+0x00,0x00,0x00,0x05,0x00,0x01,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x09,0x05,0x05,0x05,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x00,0x09,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x00,0x09,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x00,0x09,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x07,0x07,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x00,0x09,0x00,0x00,0x05,0x06,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x09,0x09,0x00,0x00,0x05,0x06,0x00,0x00,0x07,0x07,0x07,0x07,0x07,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x09,0x09,0x00,0x00,0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x09,0x09,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x00,0x09,0x09,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x09,0x09,0x09,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x09,0x09,0x09,0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x09,0x09,0x09,0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x09,0x09,0x05,0x05,0x05,0x05,
+0x09,0x09,0x09,0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#define ISP3BinarySize (sizeof(ISP3BinaryDataMcu)/sizeof(char))
diff --git a/drivers/misc/jz_cim/camera_source/isp/isp.c b/drivers/misc/jz_cim/camera_source/isp/isp.c
new file mode 100644
index 00000000000..cd37eb8c59c
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/isp.c
@@ -0,0 +1,5046 @@
+
+#define LOGE printk
+#define LOGD printk
+
+#include <linux/delay.h>
+
+#include "data.h"
+#include "isp.h"
+
+#define SIMULATE_I2C
+
+//we have 2 suite simulate i2c interface if burn new fw ,define i2c-1
+//#define i2c-1
+
+extern unsigned int i2c_addr;
+extern unsigned int i2c_clk;
+
+/* I2C APP */
+extern int i2c_write_16(unsigned char device, unsigned char *buf, unsigned short address, int count);
+extern int i2c_read_16(unsigned char device, unsigned char *buf, unsigned short address, int count);
+
+
+extern void sensor_write_reg(unsigned char reg, unsigned char val);
+extern int sensor_write_reg16(unsigned short reg, unsigned char val);
+extern unsigned char sensor_read_reg(unsigned char reg);
+extern unsigned char sensor_read_reg16(unsigned short reg);
+
+extern void I2CSim_Write8(unsigned char ucSlaveID, char address ,char value);
+extern unsigned char I2CSim_Read8(unsigned char ucSlaveID, char address);
+
+extern unsigned short I2C_ReadControl(unsigned char IICID, unsigned short regaddr);
+extern unsigned short I2C_WriteControl(unsigned char IICID, unsigned short regaddr, unsigned short data);
+
+
+//#define INIT_IIC_BURST_MODE // Jacky for all reg burst mode
+
+faceInfo _faceInfo[10];
+
+#ifdef HISENSE_ZOOM_TEST
+CAM_ZOOM_T g_curDigitalZoom = CAM_ZOOM_480_360;
+#else
+unsigned char g_curDigitalZoom = 0;
+#endif
+
+void sensor_set_addr(int addr)
+{
+#ifndef SIMULATE_I2C
+ i2c_addr = addr;
+#endif
+}
+
+// Following System IIC you need chang to you system IIC
+/*********************************************************************
+*Name : System_IICWrite
+*Description :
+*Param : IIC ID Address and data
+*return : none
+*Author :
+*Remark : You have to use instead of System's function
+*Log :
+**********************************************************************/
+void System_IICWrite( ClUint_8 id, ClUint_8 addr, ClUint_8 data)
+{
+/*#if defined(ISP3_EVB_ENABLE)||defined(ISP2_EVB_ENABLE)
+
+ SI2CID = id;
+ printk("%s : 0x%x\n",__func__, ((SI2CID & 0x7f) << 1));
+ IIC_WRITE(addr, data);
+#else
+#endif */
+#ifdef SIMULATE_I2C
+ I2CSim_Write8(id, addr, data);
+#else
+ sensor_set_addr(id);
+ sensor_write_reg(addr,data);
+
+#endif
+}
+
+/*********************************************************************
+*Name : System_IICRead
+*Description :
+*Param : IIC addr
+*return : iic data
+*Author :
+*Remark : You have to use instead of System's function
+*Log :
+**********************************************************************/
+ClUint_16 System_IICRead(ClUint_16 addr)
+{
+ ClUint_16 data = 0;
+ ClUint_32 delay_cnt = 0;
+
+/*#if defined(ISP3_EVB_ENABLE)||defined(ISP2_EVB_ENABLE)
+ System_IICWrite(ISP_IICID_A, 0x01, addr>>8); //3 2. IIC Addr = 0x01
+
+ SI2CID = ISP_IICID_B;
+ data = IIC_READ((ClUint_16)(addr&0xff)); //3 5. IIC Addr = low 8 bit of addr value. & Read Data with IIC ID = 0x80
+ printk("%s :: 0x%x : 0x%x\n",__func__, addr, data);
+#endif*/
+#ifdef SIMULATE_I2C
+#ifdef i2c-1
+ System_IICWrite(ISP_IICID_A, 0x01, addr>>8);
+ data = I2CSim_Read8(ISP_IICID_B, (addr&0xff));
+#else
+ I2C_WriteControl(ISP_IICID_A, 0x01, addr>>8);
+ data = I2C_ReadControl(ISP_IICID_B, (addr&0xff));
+#endif
+#else
+ //3 Please porting your system IIC read function here
+ System_IICWrite(ISP_IICID_A, 0x01, addr>>8); //3 2. IIC Addr = 0x01
+ sensor_set_addr(ISP_IICID_B);
+ data = sensor_read_reg((unsigned char)(addr&0xff));
+
+#endif
+
+ return data;
+}
+
+/*********************************************************************
+*Name : CoreISP3_I2C_Read
+*Description : Read Data from register of addr
+*Param : addr = read register
+*return : Register value
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+ClUint_16 CoreISP3_I2C_Read( ClUint_16 addr )
+{
+ ClUint_16 data = 0;
+
+ data = System_IICRead(addr);
+
+ return data;
+}
+
+#ifdef INIT_IIC_BURST_MODE
+
+void CoreISP3_I2C_Read_Bulk( ClUint_16 addr, ClUint_8 data )
+{
+ ClUint_16 data = 0;
+
+#if defined(ISP3_EVB_ENABLE)||defined(ISP2_EVB_ENABLE)
+ SI2CID = ISP_IICID_B;
+ data = IIC_READ((ClUint_16)(addr&0xff)); //3 5. IIC Addr = low 8 bit of addr value. & Read Data with IIC ID = 0x80
+#else // Please porting your iic read function
+#endif
+
+ return data;
+}
+#endif
+
+/*********************************************************************
+*Name : CoreISP3_I2C_Write
+*Description : Write Data
+*Param : addr = Addr of Register
+ data = Setting value
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+int CoreISP3_I2C_Write( ClUint_16 addr, ClUint_8 data )
+{
+#ifdef SIMULATE_I2C
+#ifdef i2c-1
+ System_IICWrite(ISP_IICID_A, 0x01, addr>>8);
+ System_IICWrite(ISP_IICID_B, addr&0xff, data);
+ mdelay(5);
+#else
+
+ I2C_WriteControl(ISP_IICID_A, 0x01, addr>>8);
+ I2C_WriteControl(ISP_IICID_B, addr&0xff, data);
+#endif
+#else
+ I2C_WriteControl(ISP_IICID_A, 0x01, addr>>8);
+ I2C_WriteControl(ISP_IICID_B, addr&0xff, data);
+
+
+#endif
+
+// if(addr!=0xe660)
+// printk("System_IIC_Write_check:write(0x%x)=0x%x,read=0x%x\n",addr,data,System_IICRead(addr));
+ return 0;
+}
+
+void CoreISP3_I2C_Write_Bulk( ClUint_16 addr, ClUint_8 data )
+{
+ //System_IICWrite(ISP_IICID_B, addr&0xff, data);
+ I2C_WriteControl(ISP_IICID_B, addr&0xff, data);;
+}
+
+
+void CoreISP3_I2C_Partial_Write( ClUint_16 Addr, ClUint_16 HighBit, ClUint_16 LowBit, ClUint_8 Data )
+{
+ ClUint_8 BitMask = 0xff;
+ ClUint_8 ReadData;
+
+ BitMask = BitMask<<(7-HighBit);
+ BitMask = BitMask>>(7-HighBit+LowBit);
+ BitMask = BitMask<<LowBit;
+ BitMask = ~BitMask;
+
+ ReadData = CoreISP3_I2C_Read(Addr);
+ if(ReadData < 0)
+ return;
+
+ ReadData = ReadData&BitMask;
+ ReadData = ReadData |Data<<LowBit;
+
+ CoreISP3_I2C_Write(Addr, ReadData);
+ printk( ">>CoreISP3_I2C_Partial_Write>>Addr 0x%x = 0x%x \n ", Addr, CoreISP3_I2C_Read(Addr));
+}
+
+
+
+/*********************************************************************
+*Name : CoreISP3_Send_Command
+*Description : Send "ISP3_COMMAND" to ISP3
+*Param : Cmd_Type ISP COMMAND
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_Send_Command(unsigned char Cmd_Type)// enISP3_CMD_TYPE Cmd_Type )
+{
+ ClUint_16 retval = 1, i = 0;
+ printk("Send Command to ISP MCU [Command Type : 0x%x]\n", Cmd_Type);
+
+ CoreISP3_I2C_Write(ISP3_COMMAND, Cmd_Type);
+ WaitTime_us(2*100); // 100ms // Jacky add this
+ while(retval)
+ {
+ retval = CoreISP3_I2C_Read(ISP3_COMMAND);
+ //for(i=0;i<0xffff;i++); // must add this delay tiem... or 100ms delay
+ WaitTime_us(2*100); // 100ms // Jacky for test
+ #if 1
+ i++;
+ if(i>50)
+ {
+ printk( "send isp cmd[0x%x] fail value 0x%x \n", Cmd_Type, retval);
+ break;
+ }
+ #endif
+ printk( "@@0x%x\n",retval);
+ }
+}
+/*********************************************************************
+*Name : CoreISP3_SetClock
+*Description : ISP3 Configuration(Set PLL of ISP3 & Initialize)
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetClock( void )
+{
+ //3 PLL OFF
+
+
+ //3 FOUT = {M x FIN} / {P x 2^S} : FOUT is the MCLK
+ //3 (24MHz x 54) / (6 x 2^2) = 54MHz 24M x 24 /(5x2^2) =
+ // 24MHz => 60MHz (26MHz for YuHua)
+ CoreISP3_I2C_Write(0xe062, 0x06); //P Div
+ CoreISP3_I2C_Write(0xe061, 0x18); //M Div
+ CoreISP3_I2C_Write(0xe063, 0x02); //S Div
+
+ CoreISP3_I2C_Write(0xe060, 0x03); //4 PLL Register
+ printk( "0xe062[0x%x], 0xe061[0x%x], 0xe063[0x%x]\n", CoreISP3_I2C_Read(0xe062) , CoreISP3_I2C_Read(0xe061), CoreISP3_I2C_Read(0xe063));
+
+/*
+[6:6] rw 0x00 CIS1SRSTMODE When this bit is set to ¡°1¡±, S1_RST and S1_PWDN will be
+controlled by CIS1RESET and CIS1PWDN.
+[5:5] rw 0x00 CIS1SRSTBIT This bit controls S1_RST pin state when CIS1REGCTL bit 0xc0 1100 0000 e0 1110
+is set to ¡°1¡±
+[4:4] rw 0x00 CIS1SPWDNBIT This bit controls S1_PWDN pin state when CIS1REGCTL bit
+is set to ¡°1¡±
+*/
+ //3 Enable parallel sensor port 1 interface
+ //3 Sensor Reset
+ CoreISP3_I2C_Write(0xe010, 0xf0); //4 [7] : Sensor Port 1 I/F Enable
+ //4 [6] : S1_RST & S1_PWDN control by CIS1RESET & CIS1PWDN
+ //4 [5] : S1_RST = 1
+
+ //3 Delay
+ WaitTime_us(2*10); //4 10ms
+
+ CoreISP3_I2C_Write(0xe010, 0xd0); //4 [7] : Sensor Port 1 I/F Enable // d 1101
+ //4 [6] : S1_RST & S1_PWDN control by CIS1RESET & CIS1PWDN
+ //4 [5] : S1_RST = 0
+
+ WaitTime_us(2*100); //4 50ms
+
+ CoreISP3_I2C_Write(0xe010, 0xf0); //4 [7] : Sensor Port 1 I/F Enable
+ //4 [6] : S1_RST & S1_PWDN control by CIS1RESET & CIS1PWDN
+ //4 [5] : S1_RST = 1
+
+
+// CoreISP3_I2C_Write(0xe0a2, 0x19); //Flash mode Jacky for test
+
+ // Read default value 0xe013[0x21], 0xe015[0x11], 0xe011[0x1] 0xe012[0x1], 0xe014[0x12]
+ printk( "0xe013[0x%x], 0xe015[0x%x], 0xe011[0x%x]\n", CoreISP3_I2C_Read(0xe013) , CoreISP3_I2C_Read(0xe015), CoreISP3_I2C_Read(0xe011));
+ printk( "0xe012[0x%x], 0xe014[0x%x] \n", CoreISP3_I2C_Read(0xe012) , CoreISP3_I2C_Read(0xe014));
+ //3 Div from GCLK : MCLK, FCLK, JMCLK
+ //CoreISP3_I2C_Write(0xe013, 0x21); //4 [7:4] Cis1IntD(SCLK Divider Value)
+ //4 ISP System Clock : FOUT x 1/2 = 27MHz
+ //4 [3:0] Cis1IntD(MCLK Divider Value)
+ //4 ISP ISP Memory Clock : FOUT x 1 = 54MHz
+
+ //CoreISP3_I2C_Write(0xe015, 0x11); //4[7:4] FClkDiv(FCLK) => 54MHz, [2:0] JMClkDiv(JMCLK) => 54MHz
+
+ //0xe012 [2:0] rw 0x01 Cis1IntC SMCLK divider value
+ // (1: x1, 2:x1/2, 4:x1/4, 8:x1/8, 4:x1/16)
+ //3 Div from MCLK : SMCLK, 8051CLK, SCLK, JCLK
+
+ CoreISP3_I2C_Write(0xe012, 0x01); //4[2:0] Cis1ClkDiv(S1_MCLK) => 27MHz
+ mdelay(100);
+
+ CoreISP3_I2C_Write(0xe014, 0x12); //4[7:4] i8051_ClkDiv => 27MHz, [3:0] JClkDiv(JCLK) => 27MHz
+
+
+ /* CCLK Setting */
+ //CoreISP3_I2C_Write(0xe011, 0x00); //4[5:4] '0' =>S1_PCLK, '1' => S1_MCLK, '2' => SCLK
+ WaitTime_us(2*10); // 10ms
+
+ /* PLL ON */
+ CoreISP3_I2C_Write(0xe060, 0x00);
+ //WaitTime_us(2*500); // 500ms Jacky delete this for test ok
+
+}
+
+
+/*********************************************************************
+*Name : CoreISP3_LSC_TableDownLoad
+*Description : Downloading Lens Shading Data
+*Param : none
+*return : Cl_True : Scuuess, Cl_False : Fail
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+#ifndef ISP3_MCU_LSC
+Cl_Bool CoreISP3_LSC_TableDownLoad( void )
+{
+ ClUint_32 data_cnt;
+ ClUint_16 reg_data;
+ ClUint_32 i;
+
+ printk("[CoreISP3_LSC_TableDownLoad]LSC Binary Size : :%d\n", LSC_SIZE);
+
+#ifdef INIT_IIC_BURST_MODE
+ System_IICWrite(ISP_IICID_A, 0x01, 0xe0);
+ CoreISP3_I2C_Write_Bulk(IspFenA, 0x00);
+
+ System_IICWrite(ISP_IICID_A, 0x01, 0xe2);
+ CoreISP3_I2C_Write(ShdLMDsizeH, LSC_SIZE/256);
+ CoreISP3_I2C_Write(ShdLMDsizeL, LSC_SIZE%256);
+#else
+ /* -LSC(Lens Shading Compension) Function disable.*/
+ CoreISP3_I2C_Write(IspFenA, 0x00);
+
+ // -LSC Size Setting
+ CoreISP3_I2C_Write(ShdLMDsizeH, LSC_SIZE/256);
+ CoreISP3_I2C_Write(ShdLMDsizeL, LSC_SIZE%256);
+
+ printk(">>ISP2_REG>>0xe2e2==0x%x[0x%x]\n",CoreISP3_I2C_Read(ShdLMDsizeH), LSC_SIZE/256);
+ printk(">>ISP2_REG>>0xe2e3==0x%x[0x%x]\n",CoreISP3_I2C_Read(ShdLMDsizeL), LSC_SIZE%256);
+ if(CoreISP3_I2C_Read(ShdLMDsizeH)!= LSC_SIZE/256)
+ {
+ printk("IIC_Write Read error...\n");
+ return ClFalse;
+ }
+ // -Download LSC file
+ printk("LSC Binary Downloading.....>>>>>>>>>>.\n");
+ printk("%s<CoreISP3_I2C_Write_Bulk> : 0x%x\n",__func__, ((SI2CID & 0x7f) << 1));
+#endif
+
+ for(data_cnt=0; data_cnt<LSC_SIZE; data_cnt++)
+ {
+ //4 0x80
+ CoreISP3_I2C_Write_Bulk(ShdLMData, LSC_INIT_TABLE[data_cnt]);
+ }
+
+ printk("LSC Binary Download End!!\n");
+
+ CoreISP3_I2C_Write(IspFenA, 0x01); // -LSC Function enable.
+
+#if 0 //3 Verify LSC Data
+ printk("LSC Verify START @@@@@@@@@@@@@@@@@@@@@\n");
+ for( i=0; i<LSC_SIZE; i++ )
+ {
+ //3 Set Address
+ CoreISP3_I2C_Write(0xe2e0, i>>8); //4 Set Upper Address
+ CoreISP3_I2C_Write(0xe2e1, i & 0xFF); //4 Set Lower Addreaa
+ reg_data = CoreISP3_I2C_Read(0xe2e4); //4 Read Data of Address
+ reg_data = CoreISP3_I2C_Read(0xe2e4); //4 Read Data of Address
+
+ if (reg_data != LSC_INIT_TABLE[i])
+ {
+ printk("LSC Verify ERROR LSC_INIT_TABLE[%d] = 0x%x : 0x%x !!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", i, reg_data, LSC_INIT_TABLE[i]);
+ return Cl_False;
+ }
+
+ }
+ printk( "LSC Verify END @@@@@@@@@@@@@@@@@@@@@\n");
+#endif
+
+ return Cl_True;
+}
+#endif
+/*********************************************************************
+*Name : ISP3_FlashromFormat
+*Description : Format Flash of ISP3
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void ISP3_FlashromFormat(void)
+{
+#ifdef INIT_IIC_BURST_MODE
+ System_IICWrite(ISP_IICID_A, 0x01, 0xe0);
+ CoreISP3_I2C_Write_Bulk(0xE070, 0xFD); // MCU hold
+ CoreISP3_I2C_Write_Bulk(0xE0C4, 0x10);
+ CoreISP3_I2C_Write_Bulk(0xE0A2, 0x19); // Flashrom mode
+ CoreISP3_I2C_Write_Bulk(0xE0A1, 0x01); // Format
+#else // Flashrom Format
+ CoreISP3_I2C_Write(0xE070, 0xFD); // MCU hold
+ CoreISP3_I2C_Write(0xE0C4, 0x10);
+ CoreISP3_I2C_Write(0xE0A2, 0x19); // Flashrom mode
+ CoreISP3_I2C_Write(0xE0A1, 0x01); // Format
+#endif
+}
+/*********************************************************************
+*Name : ISP3_FlashromBlockErase
+*Description : Erase Flash of ISP3 Block
+*Param : eraseStartAddress Start Address of Flash
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void ISP3_FlashromBlockErase(int eraseStartAddress)
+{
+ // Flash Block Erase
+ CoreISP3_I2C_Write(0xE070, 0xFD); // MCU Hold
+ CoreISP3_I2C_Write(0xE0BA, eraseStartAddress>>8);
+ CoreISP3_I2C_Write(0xE0BB, eraseStartAddress&0xFF);
+ CoreISP3_I2C_Write(0xE0C4, 0x30);
+ CoreISP3_I2C_Write(0xE0A1, 0x01);
+}
+
+#ifdef IIC_BURST_MODE
+void ISP3_FlashromBurstWrite(int writeStartAddress, ClUint_8* data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount))
+{
+ int i;
+ int writeEndAddress = writeStartAddress+length-1;
+ ClUint_16 val;
+
+ val = CoreISP3_I2C_Read(0xE037);
+ printk("write burst\n");
+
+#ifdef INIT_IIC_BURST_MODE
+ System_IICWrite(ISP_IICID_A, 0x01, 0xe0);
+ CoreISP3_I2C_Write_Bulk(0xE037, val&~0x80); // Address Auto Inc Off
+
+ // Flash Write
+ CoreISP3_I2C_Write_Bulk(0xE070, 0xFD);
+ CoreISP3_I2C_Write_Bulk(0xE0A3, writeStartAddress>>8);
+ CoreISP3_I2C_Write_Bulk(0xE0A4, writeStartAddress&0xFF);
+ CoreISP3_I2C_Write_Bulk(0xE0A6, writeEndAddress>>8);
+ CoreISP3_I2C_Write_Bulk(0xE0A7, writeEndAddress&0xFF);
+ CoreISP3_I2C_Write_Bulk(0xE0A2, 0x29);
+ CoreISP3_I2C_Write_Bulk(0xE0A2, 0x19);
+ WaitTime_us(2*50);
+ for(i=0; i<length; i++)
+ {
+ CoreISP3_I2C_Write_Bulk(0xE0A5, data[i]);
+ if(callbackFunc != Cl_Null)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ //Sleep(2);
+ }
+ }
+
+ CoreISP3_I2C_Write(0xE037, val);
+#else
+ CoreISP3_I2C_Write(0xE037, val&~0x80); // Address Auto Inc Off
+
+ // Flash Write
+ CoreISP3_I2C_Write(0xE070, 0xFD);
+ CoreISP3_I2C_Write(0xE0A3, writeStartAddress>>8);
+ CoreISP3_I2C_Write(0xE0A4, writeStartAddress&0xFF);
+ CoreISP3_I2C_Write(0xE0A6, writeEndAddress>>8);
+ CoreISP3_I2C_Write(0xE0A7, writeEndAddress&0xFF);
+ CoreISP3_I2C_Write(0xE0A2, 0x29);
+ CoreISP3_I2C_Write(0xE0A2, 0x19);
+ WaitTime_us(2*50);
+ for(i=0; i<length; i++)
+ {
+ CoreISP3_I2C_Write_Bulk(0xE0A5, data[i]);
+ if(callbackFunc != Cl_Null)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ //Sleep(2);
+ //printk("%d,0x%x\n",i,data[i]);
+ //WaitTime_us(10);
+ }
+ }
+
+ CoreISP3_I2C_Write(0xE037, val);
+#endif
+}
+
+#else
+
+/*********************************************************************
+*Name : ISP3_FlashromWrite
+*Description : Write to Flash of ISP3
+*Param : writeStartAddress Start address of Flash
+ data Point of Data
+ length Data Size
+ callbackFunc Call back function
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void ISP3_FlashromWrite(int writeStartAddress, ClUint_8* data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount))
+{
+ int i;
+ int writeEndAddress = writeStartAddress+length-1;
+ // Flash Write
+ printk("ISP3_FLASH-WRITE\n");
+ CoreISP3_I2C_Write(0xE070, 0xFD);
+ CoreISP3_I2C_Write(0xE0A3, writeStartAddress>>8);
+ CoreISP3_I2C_Write(0xE0A4, writeStartAddress&0xFF);
+ CoreISP3_I2C_Write(0xE0A6, writeEndAddress>>8);
+ CoreISP3_I2C_Write(0xE0A7, writeEndAddress&0xFF);
+ CoreISP3_I2C_Write(0xE0A2, 0x29);
+ CoreISP3_I2C_Write(0xE0A2, 0x19);
+ WaitTime_us(2*50); //4 50 ms
+
+ for(i=0; i<length; i++)
+ { printk("%d,0x%x\n",i,data[i]);
+ CoreISP3_I2C_Write(0xE0A5, data[i]);
+ if(callbackFunc != Cl_Null)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ // Sleep(2);
+ }
+ }
+}
+#endif //4 IIC_BURST_MODE
+
+/*********************************************************************
+*Name : ISP3_FlashromRead
+*Description : Read from Flash of ISP3
+*Param : readStartAddress Start address of Flash
+ data Save Reading data
+ length Read size
+ callbackFunc Call back function
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void ISP3_FlashromRead(int readStartAddress, ClUint_8 *data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount))
+{
+ int i;
+ // Dump
+ CoreISP3_I2C_Write(0xE070, 0xFD);
+ CoreISP3_I2C_Write(0xE0A2, 0x31);
+
+ for(i=0; i<length; i++)
+ {
+ int addr = readStartAddress+i;
+ CoreISP3_I2C_Write(0xE0A3, addr>>8); // Address High
+ CoreISP3_I2C_Write(0xE0A4, addr&0xFF); // Address Low
+ data[i] = CoreISP3_I2C_Read(0xE0A5);
+ // data[i] = clIIC_Read(0xE0A5);
+ if(callbackFunc != Cl_Null)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ // Sleep(2);
+ }
+ }
+}
+
+
+ClUint_8 CoreISP3_Code_Verification( ClUint_8 * pVerifyData, ClUint_32 VerifyDataSize, enIsp3DownloadMode ModeParam )
+{
+ ClUint_8 RetVal = 0;
+ ClUint_32 data_cnt, reg_cnt, RegData;
+
+ /* MCU Reset */
+ CoreISP3_I2C_Write(MCURST, 0x05);
+ WaitTime_us(2*100); // 100ms
+ CoreISP3_I2C_Write(MCURST, 0x04);
+ WaitTime_us(2*100); // 100ms
+
+ if(ModeParam == enDownloadMode_StackedMem)
+ {
+ CoreISP3_I2C_Write(ShdCenY, 0x31);
+ }
+ else
+ {
+ CoreISP3_I2C_Write(ShdCenY, 0xa0);
+ }
+ reg_cnt = 0;
+ for(data_cnt=0; data_cnt<VerifyDataSize+1; data_cnt++)
+ {
+ CoreISP3_I2C_Write(ShdCnvRtoH, data_cnt/256);
+ CoreISP3_I2C_Write(ShdCnvRtoL, data_cnt%256);
+ RegData = CoreISP3_I2C_Read(FlashData);
+ if(data_cnt>0)
+ {
+ if(RegData != pVerifyData[reg_cnt])
+ {
+ reg_cnt++;
+ printk( "MCU Bin Verify ERROR pInitialData[%d] = 0x%x : 0x%x @@@@@@@@@@@@@@@@@@@@@\n", data_cnt, RegData, pVerifyData[reg_cnt]);
+ return 1;
+ }
+ }
+ }
+ return RetVal;
+}
+
+/*********************************************************************
+*Name : CoreISP3_MCU_CodeDownload
+*Description : Downloading ISP3 LSC & Main Bin Data
+*Param : pInitialData Pointer of MCU Data
+ InitialDataSize Length of MCU Data
+ ModeParam enDownloadMode_StackedMem Write to Flash
+ enDownloadMode_SkipedMCUBin Read from Flash
+ enDownloadMode_CodeRAM Write to RAM
+*return : Cl_True : Scuuess, Cl_False : Fail
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+ClUint_8 CoreISP3_MCU_CodeDownload( ClUint_8 * pInitialData, ClUint_32 InitialDataSize, enIsp3DownloadMode ModeParam )
+{
+ ClUint_8 RetVal = 0;
+ ClUint_16 reg_data;
+ ClUint_32 i;
+ int earseAddr=0;
+
+ printk( "[CoreISP3_MCU_CodeDownload]MCU Binary Size : :%d, ModeParam : %d\n", InitialDataSize, ModeParam);
+
+ // Format
+ for(earseAddr=0;earseAddr<0xf000;earseAddr+=0x1000)
+ ISP3_FlashromBlockErase(earseAddr);
+ //ISP3_FlashromFormat();
+
+ WaitTime_us(2*200); //4 200 ms
+ #ifdef IIC_BURST_MODE
+ ISP3_FlashromBurstWrite(0x0000, pInitialData, InitialDataSize, Cl_Null);
+ #else
+ ISP3_FlashromWrite(0x0000, pInitialData, InitialDataSize, Cl_Null);
+ #endif
+ WaitTime_us(2*100); //4 100 ms
+ WaitTime_us(2*100); //4 100 ms
+
+ #ifndef ISP3_MCU_LSC
+ // Code copy
+ #ifdef INIT_IIC_BURST_MODE
+ System_IICWrite(ISP_IICID_A, 0x01, 0xe0);
+ CoreISP3_I2C_Write_Bulk(FlashDEV, 0x29); // # flash code mode
+ CoreISP3_I2C_Write_Bulk(FlashDEV, 0x19); // # flash code mode
+ WaitTime_us(2*10); //4 10 ms
+ CoreISP3_I2C_Write_Bulk(FlashDEV, 0x30); // # flash code copy address reset
+ CoreISP3_I2C_Write_Bulk(FlashDEV, 0x10); //# flash code copy address release
+ CoreISP3_I2C_Write_Bulk(FlashDSizeH, 0xc0); // # code ram size: 48KB
+ CoreISP3_I2C_Write_Bulk(FlashDSizeL, 0x00);
+ CoreISP3_I2C_Write_Bulk(FlashDown, 0x01); // # flash code copy to code ram start
+ WaitTime_us(2*50); //4 50 ms
+ CoreISP3_I2C_Write_Bulk(FlashDown, 0x00); // # flash code copy to code ram end
+ CoreISP3_I2C_Write_Bulk(FlashDEV, 0x00); // # code ram mode
+ #else
+ CoreISP3_I2C_Write(FlashDEV, 0x29); // # flash code mode
+ CoreISP3_I2C_Write(FlashDEV, 0x19); // # flash code mode
+ WaitTime_us(2*10); //4 10 ms
+ CoreISP3_I2C_Write(FlashDEV, 0x30); // # flash code copy address reset
+ CoreISP3_I2C_Write(FlashDEV, 0x10); //# flash code copy address release
+ CoreISP3_I2C_Write(FlashDSizeH, 0xc0); // # code ram size: 48KB
+ CoreISP3_I2C_Write(FlashDSizeL, 0x00);
+ CoreISP3_I2C_Write(FlashDown, 0x01); // # flash code copy to code ram start
+ WaitTime_us(2*50); //4 50 ms
+ CoreISP3_I2C_Write(FlashDown, 0x00); // # flash code copy to code ram end
+ CoreISP3_I2C_Write(FlashDEV, 0x00); // # code ram mode
+ #endif
+ #endif
+
+#if 1 //3 Verify MCU Bin Data // need long time
+ printk("MCU Bin Verify START @@@@@@@@@@@@@@@@@@@@@\n");
+
+ #ifdef INIT_IIC_BURST_MODE
+
+ CoreISP3_I2C_Write_Bulk(0xE070, 0x05); //4 Reset 8051
+ WaitTime_us(2*100); //4 100 ms
+
+ if(ModeParam == enDownloadMode_CodeRAM)
+ CoreISP3_I2C_Write_Bulk(0xE0A2, 0xa0); //4 0x31 : Select Flash memory , 0xA0 : Select SDRAM
+ else
+ CoreISP3_I2C_Write_Bulk(0xE0A2, 0x31);
+
+ WaitTime_us(2*100); //4 100 ms
+
+ for( i=0; i<InitialDataSize; i++ )
+ {
+ CoreISP3_I2C_Write_Bulk(0xE0A3, i>>8); //4 Set Upper Address
+ CoreISP3_I2C_Write_Bulk(0xE0A4, i & 0xFF); //4 Set Lower Addreaa
+ reg_data = CoreISP3_I2C_Read_Bulk(0xE0A5); //4 Read Data of Address
+
+ if (reg_data != pInitialData[i])
+ {
+ printk( "MCU Bin Verify ERROR pInitialData[%d] = 0x%x : 0x%x @@@@@@@@@@@@@@@@@@@@@\n", i, reg_data, pInitialData[i]);
+ return Cl_False;
+ }
+
+ }
+ #else
+ CoreISP3_I2C_Write(0xE070, 0x05); //4 Reset 8051
+ WaitTime_us(2*100); //4 100 ms
+
+ if(ModeParam == enDownloadMode_CodeRAM)
+ CoreISP3_I2C_Write(0xE0A2, 0xa0); //4 0x31 : Select Flash memory , 0xA0 : Select SDRAM
+ else
+ CoreISP3_I2C_Write(0xE0A2, 0x31);
+
+ WaitTime_us(2*100); //4 100 ms
+ printk("!!!!!!!!!!!!!!!!!!!!!!datasize=%d\n",InitialDataSize);
+ for( i=0; i<InitialDataSize; i++ )
+ { printk("%d\n",i);
+ CoreISP3_I2C_Write(0xE0A3, i>>8); //4 Set Upper Address
+ CoreISP3_I2C_Write(0xE0A4, i & 0xFF); //4 Set Lower Addreaa
+ reg_data = CoreISP3_I2C_Read(0xE0A5); //4 Read Data of Address
+
+ if (reg_data != pInitialData[i])
+ { while(1)
+ printk( "MCU Bin Verify ERROR pInitialData[%d] = 0x%x : 0x%x @@@@@@@@@@@@@@@@@@@@@\n", i, reg_data, pInitialData[i]);
+ return Cl_False;
+ }
+
+ }
+ #endif
+ printk( "MCU Bin Verify END @@@@@@@@@@@@@@@@@@@@@\n");
+#else // must add this
+ CoreISP3_I2C_Write(0xE070, 0x05); //4 Reset 8051
+ WaitTime_us(2*10); //4 100 ms
+
+ if(ModeParam == enDownloadMode_CodeRAM)
+ CoreISP3_I2C_Write(0xE0A2, 0xa0); //4 0x31 : Select Flash memory , 0xA0 : Select SDRAM
+ else
+ CoreISP3_I2C_Write(0xE0A2, 0x31);
+
+ WaitTime_us(2*10); //4 100 ms
+#endif
+ printk("ok\n");
+ return 1;
+}
+
+
+Cl_Bool CoreISP3_PowerOn()
+{
+ return 0;
+}
+
+Cl_Bool CoreISP3_Reset()
+{
+ return 0;
+}
+
+// Following part is our stardard function api
+/*********************************************************************
+*Name : CoreISP3_Initialize
+*Description : Main ISP3 Initialize Routine
+*Param : param enDownloadMode_StackedMem Write to Flash
+ enDownloadMode_SkipedMCUBin Read from Flash
+ enDownloadMode_CodeRAM Write to RAM
+*return : Cl_True : Scuuess, Cl_False : Fail
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+Cl_Bool CoreISP3_Initialize( enIsp3DownloadMode param )
+{
+ Cl_Bool RetVal = Cl_True;
+ ClUint_32 temp;
+
+
+ printk("=========================== CoreISP3_Initialize : START ===========================\n");
+ printk("enIsp3DownloadMode : %d\n", param);
+
+ /* ISP Clock Setting */
+ CoreISP3_SetClock();
+
+ // LSC Table Download.
+ /**/
+
+
+ /* MCU Binary Download */
+ if(param != enDownloadMode_SkipedMCUBin)
+ {
+
+ RetVal = CoreISP3_MCU_CodeDownload((ClUint_8*)&ISP3BinaryDataMcu, ISP3BinarySize, param);
+
+ if (RetVal == Cl_False)
+ {
+ printk( "CoreISP3_MCU_CodeDownload Fail Error : %d \n", RetVal);
+ return Cl_False;
+ }
+
+
+ }
+
+ /* MCU Reset */
+ CoreISP3_I2C_Write(MCURST, 0x05);
+ WaitTime_us(2*10); // 100ms // Jacky change this time for init time
+ CoreISP3_I2C_Write(MCURST, 0x04);
+ WaitTime_us(2*500); // 100ms // Jacky change this time for init time
+
+ /* Send Command(ISP & Sensor Initialize) to ISP */
+ printk( "ISP3_CMD_SENSOR_INIT \n");
+ CoreISP3_Send_Command(ISP3_CMD_SENSOR_INIT);
+
+ WaitTime_us(2*100); // 100ms
+ printk("after cmd init 0xe062[0x%x], 0xe061[0x%x], 0xe063[0x%x]\n", CoreISP3_I2C_Read(0xe062) , CoreISP3_I2C_Read(0xe061), CoreISP3_I2C_Read(0xe063));
+ printk("ISP3_CMD_SENSOR_INIT end\n");
+
+ /*Sensor Interface*/
+ CoreISP3_I2C_Write(SMIABypass, 0x00); //[7:7] LMBYPASS '0' = Async, '1' = Sync
+ printk("after cmd SMIABypass 0xe062[0x%x], 0xe061[0x%x], 0xe063[0x%x]\n", CoreISP3_I2C_Read(0xe062) , CoreISP3_I2C_Read(0xe061), CoreISP3_I2C_Read(0xe063));
+
+ /* OUT FORMAT */
+ //CoreISP3_I2C_Write(OutFmt_JPG, 0x82); //[0:0] OutFmt ' 0' = YCbCr, '1' = JPEG
+ CoreISP3_I2C_Write(OutFmt_JPG, 0x0); //[0:0] OutFmt ' 0' = YCbCr, '1' = JPEG for yuv
+ WaitTime_us(2*10); // 100ms // Jacky change this time for init time
+
+ printk( "=========================== CoreISP3_Initialize : END ===========================\n");
+
+ //CoreISP3_Get_Version();
+ //CoreISP3_TestPatten(); // Jacky for test
+
+ //CoreISP3_YUV_Swap(enISP_CbYCr); // Jacky for Meizu test binary already add
+ //CoreISP3_Mirror_Flip(ISP3_ROTATION_NONE);
+ //CoreISP3_PCLK_Inv(); // Jacky for Meizu test binary already add
+
+ return 1;
+}
+
+
+void CoreISP3_SetResolution( enIsp3OutResolution OutResolution , CMD_Mode Mode )
+{
+ printk("SetResolution :%d ,%d \n",OutResolution, Mode);
+#if 1
+ if(CMD_Preview == Mode) //Fix resolution
+ {
+ switch(OutResolution)
+ {
+
+ case enISP_RES_1_3MP: // 1280 x 960
+ CoreISP3_I2C_Write(0xE6A8, SXGA);
+ break;
+
+ case enISP_RES_XGA: // 1024 x 768
+ CoreISP3_I2C_Write(0xE6A8, XGA);
+ break;
+
+ case enISP_RES_SVGA: // 800 x 600
+ CoreISP3_I2C_Write(0xE6A8, SVGA);
+ break;
+
+ #ifdef MEIZU_FEATURES
+ case enISP_RES_QSVGA: // 400x300
+ CoreISP3_I2C_Write(0xE6A8, QSVGA);
+ break;
+ #endif
+
+ case enISP_RES_VGA: // 640 x 480
+ CoreISP3_I2C_Write(0xE6A8, VGA);
+ break;
+
+ case enISP_RES_QVGA: // 320 x 240
+ CoreISP3_I2C_Write(0xE6A8, QVGA);
+ break;
+
+ default:
+ break;
+ }
+
+ CoreISP3_Send_Command(ISP3_CMD_PREVIEW);
+ CoreISP3_SetSensorInfo(OutResolution);
+ return;
+ }
+#endif
+
+ switch(OutResolution)
+ {
+ case enISP_RES_5MP_FULL: // 2560 x 1920
+ {
+ CoreISP3_I2C_Write(0xE6A8, QSXGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_QXGA: // 2048 x 1536
+ {
+ CoreISP3_I2C_Write(0xE6A8, QXGA);
+ WaitTime_us(2*100); // 100ms // Jacky for test
+ CoreISP3_Send_Command(0xdf);
+
+ CoreISP3_I2C_Write(0xE6A8, QXGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ WaitTime_us(2*100); // 100ms // Jacky for test
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_UXGA: // 1600 x 1200
+ {
+ CoreISP3_I2C_Write(0xE6A8, UXGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_SXGA: // 1280 x 1024
+ {
+ CoreISP3_I2C_Write(0xE6A8, SXGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_1_3MP: // 1280 x 960
+ {
+ CoreISP3_I2C_Write(0xE6A8, 4);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_XGA: // 1024 x 768
+ {
+ CoreISP3_I2C_Write(0xE6A8, XGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_SVGA: // 800 x 600
+ {
+ CoreISP3_I2C_Write(0xE6A8, SVGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_VGA: // 640 x 480
+ {
+ CoreISP3_I2C_Write(0xE6A8, VGA);
+ CoreISP3_I2C_Write(0xE62b, 0x00);//zoom
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ case enISP_RES_QVGA: // 320 x 240
+ {
+ CoreISP3_I2C_Write(0xE6A8, QVGA);
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* Store current resolution */
+ CoreISP3_SetSensorInfo(OutResolution);
+
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetAutoWhiteBalance
+*Description : Set AWB
+*Param : AWB_Param ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetAutoWhiteBalance( enIsp3FunctionsAWB AWB_Param )
+{
+ printk( "====> %s::%d\n", __func__, AWB_Param);
+
+ if(AWB_Param == enISP_FUNC_AWB_ON)
+ {
+ /* Send command to CoreISP3_Send_CommandISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AWB_ON);
+ }
+ else //AWB_Param == enISP_FUNC_AWB_OFF
+ {
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AWB_OFF);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetAutoExposure
+*Description : Set AE
+*Param : AE_Param ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetAutoExposure( enIsp3FunctionsAE AE_Param )
+{
+ printk("====> %s::%d\n", __func__, AE_Param);
+
+ if(AE_Param == enISP_FUNC_AE_ON)
+ {
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON);
+ }
+ else //AE_Param == enISP_FUNC_AE_OFF
+ {
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+/*********************************************************************
+*Name : CoreISP3_SetAutoFocus
+*Description : Set AF
+*Param : AF_Param ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetAutoFocus( enIsp3FunctionsAF AF_Param )
+{
+ ClUint_16 af_value;
+
+#ifdef MEIZU_FEATURES
+ printk("0xE072: 0x%x \n", CoreISP3_I2C_Read(0xE072));
+ //CoreISP3_I2C_Write(0xE072, 0xff);
+ printk( "...0xE072: 0x%x \n", CoreISP3_I2C_Read(0xE072));
+#endif
+
+ printk( "====> %s::%d\n", __func__, AF_Param);
+ //CoreISP3_I2C_Write(0xE072, 0xff);
+
+ if(AF_Param == enISP_FUNC_AF_ON)
+ {
+ /* Send command to ISP MCU */
+ //CoreISP3_Send_Command(ISP3_CMD_FULLAF);
+ CoreISP3_Send_Command(ISP3_CMD_AF_ON);
+ }
+ else //AF_Param == enISP_FUNC_AF_OFF
+ {
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AF_OFF);
+ }
+ /* Delay Time : 100ms */
+ //WaitTime_us(2*100);
+
+/*
+1. AF Complete Register [0xE661]
+ -> Yulong updated AF value before read AF done.
+ calculate--> Only use this register for AF Complete. (Yulong no need to change SW)
+*/
+ //af_value = CoreISP3_I2C_Read(0xE661);
+ //printk( " af value 0xE661 = 0x%x\n", af_value);
+
+ //WaitTime_us(2*500); // 1S wait
+ //WaitTime_us(2*500);
+ //CoreISP3_GetAutoFocusState();
+
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetAutoFocus_FullScan
+*Description : Set AF
+*Param : void
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetAutoFocus_FullScan(void)
+{
+ printk("====> %s::\n", __func__);
+
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_AF_FULL_SCAN);
+
+ //WaitTime_us(2*100);
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetAutoFocus_Micro
+*Description : Set AF
+*Param : void
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetAutoFocus_Micro(void)//΢¾àÀë
+{
+ printk( "====> %s::\n", __func__);
+
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_MICROAF);
+
+ //WaitTime_us(2*100);
+}
+
+/*
+2. JPEG EXIF Information.
+ -> ISO Value :
+ 0xE649[7:0] = ISO Gain
+ calculate => ( ISO Gain / 8 ) x 100 = ISO Value
+
+*/
+/*********************************************************************
+*Name : CoreISP3_SetAutoFocus_FullScan
+*Description : Set AF
+*Param : void
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+ClUint_32 CoreISP3_GetISOGain(void)
+{
+ ClUint_32 gain;
+ ClUint_16 val;
+
+ val = CoreISP3_I2C_Read(0xE649);
+
+ gain = val/8 *100;
+ printk( "\n====> vol: [%x]:: Gain: [%x] \n", val, gain);
+
+ WaitTime_us(2*100);
+
+ return gain;
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetAutoFocus_FullScan
+*Description : Set AF
+*Param : void
+*return : none
+*Author :
+*Remark :
+*Log :
+ -> Shutter Speed :
+ 0xE64A [7:0] = Shutter Speed high byte, 0xE64b [7:0] = Shutter Speed low byte, 0xE663[7:0] = Hsync Time.
+ calculate= > Shutter Speed ( high byte, low byte) x Hsync Time = Shutter Speed [ uS ]
+
+**********************************************************************/
+ClUint_32 CoreISP3_GetShutterSpeed(void)
+{
+ ClUint_32 speed;
+ ClUint_16 high;
+ ClUint_16 low;
+ ClUint_16 Hsync_time;
+
+ printk( "====> %s::\n", __func__);
+
+ high = CoreISP3_I2C_Read(0xE64A);
+ low = CoreISP3_I2C_Read(0xE64B);
+ Hsync_time = CoreISP3_I2C_Read(0xE663);
+
+ printk( "====> %x %x %x::\n", high, low, Hsync_time);
+
+ speed = (((high&0xff)<<8)|(low&0xff))*Hsync_time;
+
+ WaitTime_us(2*100);
+
+ return speed;
+}
+
+ClUint_32 CoreISP3_GetAutoFocusState(void)
+{
+ ClUint_32 af_state;
+ // When af this value is 0x23, when af finish this value is not 0x23 0x24 finished, 0x23 not focused
+ af_state = CoreISP3_I2C_Read(0xE661);
+
+ printk( "====> af status %d::\n", af_state);
+ return af_state;
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetANR
+*Description : Set ANR
+*Param : ANR_Param enISP_FUNC_ANR_LEVEL_0
+ enISP_FUNC_ANR_LEVEL_1
+ enISP_FUNC_ANR_LEVEL_2
+ enISP_FUNC_ANR_LEVEL_3
+ enISP_FUNC_ANR_LEVEL_4
+*return : none
+*Author :
+*Remark : enISP_FUNC_ANR_LEVEL_0 is ANR OFF.
+*Log :
+**********************************************************************/
+void CoreISP3_SetANR( enISP3FunctionsANRLevel ANR_Param )
+{
+ printk( "====> %s::%d\n", __func__, ANR_Param);
+
+ /* Set Adative Noise Reduction Level */
+ switch(ANR_Param)
+ {
+ case enISP_FUNC_ANR_LEVEL_0: /*Auto*/
+ CoreISP3_I2C_Write(0xe671, 0x4);
+ break;
+ case enISP_FUNC_ANR_LEVEL_1:
+ case enISP_FUNC_ANR_LEVEL_2:
+ case enISP_FUNC_ANR_LEVEL_3:
+ case enISP_FUNC_ANR_LEVEL_4:
+ CoreISP3_I2C_Write(0xe671, ANR_Param);
+ break;
+ }
+ /* Send command to ISP MCU */
+ CoreISP3_Send_Command(ISP3_CMD_ANR_ON);
+
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+/*********************************************************************
+*Name : CoreISP3_SetWDR//¿íͨ´ø
+*Description : Set WDR
+*Param : stIspWdrCtrl bWDREnable WDR ON/OFF
+ enISP_FUNC_WDR_LEVEL_0
+ enISP_FUNC_WDR_LEVEL_1
+ enISP_FUNC_WDR_LEVEL_2
+ enISP_FUNC_WDR_LEVEL_3
+ enISP_FUNC_WDR_LEVEL_4
+ enISP_FUNC_WDR_LEVEL_5
+ enISP_FUNC_WDR_LEVEL_6
+ enISP_FUNC_WDR_LEVEL_7
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetWDR( _tISP_WDR_CTRL *stIspWdrCtrl )
+{
+ printk( "====> %s::%d,%d\n", __func__, stIspWdrCtrl->bWDREnable, stIspWdrCtrl->WDRlevel);
+
+ if(stIspWdrCtrl->bWDREnable)
+ {
+ /* Set WDR Level */
+ CoreISP3_I2C_Partial_Write(0xe006, 7, 5, stIspWdrCtrl->WDRlevel);
+
+ /* WDR Enable */
+ CoreISP3_I2C_Partial_Write(0xe006, 4, 4, stIspWdrCtrl->bWDREnable);
+ }
+ else
+ {
+ /* WDR Disable */
+ CoreISP3_I2C_Partial_Write(0xe006, 4, 4, stIspWdrCtrl->bWDREnable);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+
+/*********************************************************************
+*Name : CoreISP3_StillStabilizerLevelSetup
+*Description : Set Stabilizer's Level
+*Param : enISP_FUNC_SS_LEVEL_1
+ enISP_FUNC_SS_LEVEL_1_2
+ enISP_FUNC_SS_LEVEL_1_3
+ enISP_FUNC_SS_LEVEL_1_4
+ enISP_FUNC_SS_LEVEL_1_5
+ enISP_FUNC_SS_LEVEL_1_6
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_StillStabilizerLevelSetup( ClUint_16 LevelParam )
+{
+ printk( "====> %s::%d\n", __func__, LevelParam);
+
+ switch(LevelParam)
+ {
+ case enISP_FUNC_SS_LEVEL_NONE:
+ case enISP_FUNC_SS_LEVEL_1:
+ break;
+ case enISP_FUNC_SS_LEVEL_1_2:
+ case enISP_FUNC_SS_LEVEL_1_3:
+ case enISP_FUNC_SS_LEVEL_1_4:
+ case enISP_FUNC_SS_LEVEL_1_5:
+ case enISP_FUNC_SS_LEVEL_1_6:
+ CoreISP3_I2C_Write(0xe670, LevelParam);
+ CoreISP3_I2C_Write(0xe671, 0x00);
+ break;
+ }
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetStillStabilizer
+*Description : Set Stabilizer
+*Param : stIspStillStabilizerCtrlParam bStillStabilizerEnable Stabilizer ON/OFF
+ enISP_FUNC_SS_LEVEL_1
+ enISP_FUNC_SS_LEVEL_1_2
+ enISP_FUNC_SS_LEVEL_1_3
+ enISP_FUNC_SS_LEVEL_1_4
+ enISP_FUNC_SS_LEVEL_1_5
+ enISP_FUNC_SS_LEVEL_1_6
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetStillStabilizer( _tIspStillStabilizerCtrl *stIspStillStabilizerCtrlParam )
+{
+ printk("====> %s::%d,%d\n", __func__, stIspStillStabilizerCtrlParam->bStillStabilizerEnable, stIspStillStabilizerCtrlParam->StillStabilzerLevel);
+
+ if(stIspStillStabilizerCtrlParam->bStillStabilizerEnable)
+ {
+ /* Still stabilizer enable */
+ CoreISP3_I2C_Write(0xe004, 0x2b);
+
+ /* Set the SS level */
+ CoreISP3_StillStabilizerLevelSetup(stIspStillStabilizerCtrlParam->StillStabilzerLevel);
+
+ /* Send command to ISP MCU : Still Stabilizer Enable */
+ CoreISP3_Send_Command(ISP3_CMD_STILL_ON);
+ }
+ else
+ {
+ /* Still stabilizer disable */
+ CoreISP3_I2C_Write(0xe004, 0x22);
+
+ /* Send command to ISP MCU : Still Stabilizer Disable */
+ CoreISP3_Send_Command(ISP3_CMD_STILL_OFF);
+ }
+}
+/*********************************************************************
+*Name : CoreISP3_SetStillStabilizer
+*Description : Set Stabilizer
+*Param : enISP_FUNC_IMAGE_NORMAL
+ enISP_FUNC_IMAGE_EMBOSS
+ enISP_FUNC_IMAGE_SKETCH1
+ enISP_FUNC_IMAGE_SKETCH2
+ enISP_FUNC_IMAGE_BLACK_WHITE
+ enISP_FUNC_IMAGE_NORMAL_MOVIE
+ enISP_FUNC_IMAGE_OLD_MOVIE
+ enISP_FUNC_IMAGE_GRAY
+ enISP_FUNC_IMAGE_ACCENT
+ enISP_FUNC_IMAGE_SWAPING
+ enISP_FUNC_IMAGE_ACCENT_SWAPING
+ enISP_FUNC_IMAGE_WARM
+ enISP_FUNC_IMAGE_COOL
+ enISP_FUNC_IMAGE_FOG
+ enISP_FUNC_IMAGE_OPPOSITE_NEGATIVE
+ enISP_FUNC_IMAGE_OPPOSITE_AVERAGE
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetImageEffect( enISPFunctionsImageEffect IspImageEffectParam )
+{
+ printk( "====> %s::%d\n", __func__, IspImageEffectParam);
+
+ switch(IspImageEffectParam)
+ {
+ case enISP_FUNC_IMAGE_NORMAL:
+ CoreISP3_I2C_Write(ImgEffectA, 0x02);
+ CoreISP3_I2C_Write(ImgEffectB, 0x00);
+ CoreISP3_I2C_Write(ImgEffectC, 0x00);
+ break;
+ case enISP_FUNC_IMAGE_EMBOSS:
+ CoreISP3_I2C_Write(ImgEffectC, 0x01);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_SKETCH1:
+ CoreISP3_I2C_Write(ImgEffectC, 0x02);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect Ons
+ break;
+ case enISP_FUNC_IMAGE_SKETCH2:
+ CoreISP3_I2C_Write(ImgEffectC, 0x03);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_BLACK_WHITE:
+ CoreISP3_I2C_Write(ImgEffectC, 0x04);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_NORMAL_MOVIE:
+ CoreISP3_I2C_Write(ImgEffectC, 0x05);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_OLD_MOVIE:
+ CoreISP3_I2C_Write(ImgEffectC, 0x06);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_GRAY:
+ CoreISP3_I2C_Write(ImgEffectC, 0x07);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_ACCENT:
+ CoreISP3_I2C_Write(Acc_Cb_Min, 0x00);
+ CoreISP3_I2C_Write(Acc_Cb_Max, 0xff);
+ CoreISP3_I2C_Write(Acc_Cr_Min, 0x00);
+ CoreISP3_I2C_Write(Acc_Cr_Max, 0x60);
+ CoreISP3_I2C_Write(ImgEffectC, 0x08);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_SWAPING:
+ CoreISP3_I2C_Write(Swp_Cb_Min1, 0x80);
+ CoreISP3_I2C_Write(Swp_Cb_Max1, 0xff);
+ CoreISP3_I2C_Write(Swp_Cr_Min1, 0x20);
+ CoreISP3_I2C_Write(Swp_Cr_Max1, 0x60);
+ CoreISP3_I2C_Write(Swp_Cb1, 0x00);
+ CoreISP3_I2C_Write(Swp_Cr1, 0xff);
+ CoreISP3_I2C_Write(Swp_Cb_Min2, 0x20);
+ CoreISP3_I2C_Write(Swp_Cb_Max2, 0x60);
+ CoreISP3_I2C_Write(Swp_Cr_Min2, 0x80);
+ CoreISP3_I2C_Write(Swp_Cr_Max2, 0xff);
+ CoreISP3_I2C_Write(Swp_Cb2, 0xff);
+ CoreISP3_I2C_Write(Swp_Cr2, 0x00);
+ CoreISP3_I2C_Write(ImgEffectC, 0x09);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_ACCENT_SWAPING:
+ CoreISP3_I2C_Write(ASwp_Cb_Min1, 0x80);
+ CoreISP3_I2C_Write(ASwp_Cb_Max1, 0xff);
+ CoreISP3_I2C_Write(ASwp_Cr_Min1, 0x20);
+ CoreISP3_I2C_Write(ASwp_Cr_Max1, 0x60);
+ CoreISP3_I2C_Write(ASwp_Cb1, 0x00);
+ CoreISP3_I2C_Write(ASwp_Cr1, 0xff);
+ CoreISP3_I2C_Write(ASwp_Cb_Min2, 0x20);
+ CoreISP3_I2C_Write(ASwp_Cb_Max2, 0x60);
+ CoreISP3_I2C_Write(ASwp_Cr_Min2, 0x80);
+ CoreISP3_I2C_Write(ASwp_Cr_Max2, 0xff);
+ CoreISP3_I2C_Write(ASwp_Cb2, 0xff);
+ CoreISP3_I2C_Write(ASwp_Cr2, 0x00);
+ CoreISP3_I2C_Write(ImgEffectC, 0x0a);
+ CoreISP3_I2C_Write(ImgEffectA, 0x04); //YCbCr Effect On
+ break;
+ case enISP_FUNC_IMAGE_WARM:
+ CoreISP3_I2C_Write(ImgEffectB, 0x01);
+ CoreISP3_I2C_Write(ImgEffectA, 0x00); //RGB Effect On
+ break;
+ case enISP_FUNC_IMAGE_COOL:
+ CoreISP3_I2C_Write(ImgEffectB, 0x02);
+ CoreISP3_I2C_Write(ImgEffectA, 0x00); //RGB Effect On
+ break;
+ case enISP_FUNC_IMAGE_FOG:
+ CoreISP3_I2C_Write(ImgEffectB, 0x03);
+ CoreISP3_I2C_Write(ImgEffectD, 0x80);
+ CoreISP3_I2C_Write(ImgEffectA, 0x00); //RGB Effect On
+ break;
+ case enISP_FUNC_IMAGE_OPPOSITE_NEGATIVE: //·´É«
+ CoreISP3_I2C_Write(ImgEffectB, 0x04);
+ CoreISP3_I2C_Write(ImgEffectA, 0x00); //RGB Effect On
+ break;
+ case enISP_FUNC_IMAGE_OPPOSITE_AVERAGE:
+ CoreISP3_I2C_Write(ImgEffectB, 0x05);
+ CoreISP3_I2C_Write(ImgEffectA, 0x00); //RGB Effect On
+ break;
+ default:
+ case 'x': case 'X':
+ break;
+ }
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetFaceTracking
+*Description : Set Face Tracking
+*Param : FaceTrackingParam ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceTracking( Cl_Bool FaceTrackingParam )
+{
+ printk( "====> %s::%d\n", __func__, FaceTrackingParam);
+
+ if(FaceTrackingParam)
+ {
+ /* Send command to ISP MCU : Face Tracking Enable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_TRACKING_START);
+ }
+ else
+ {
+ /* Send command to ISP MCU : Face Tracking Disable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_TRACKING_STOP);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceAE
+*Description : Set AE with Face Tracking
+*Param : FaceAEParam ON
+ OFF
+ FaceAEGlobalParam ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceAE( Cl_Bool FaceAEParam)
+{
+ printk( "====> %s::%d, %d\n", __func__, FaceAEParam);
+#if 0
+ if(FaceAEParam)
+ {
+ /* Send command to ISP MCU : Face AE Enable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AE_START);
+ }
+ else
+ {
+ /* Send command to ISP MCU : Face AE Disable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AE_STOP);
+ }
+#else
+ switch(FaceAEParam)
+ {
+ case enISP_FUNC_AEwithFACE_1:
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AE_STOP);
+ break;
+ case enISP_FUNC_AEwithFACE_2:
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AE_START);
+ CoreISP3_Send_Command(ISP3_CMD_AE_GLOBAL);
+ break;
+ case enISP_FUNC_AEwithFACE_3:
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AE_START);
+ CoreISP3_Send_Command(ISP3_CMD_AE_MULTI);
+ break;
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+#endif
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceAF
+*Description : Set AF with Face Tracking
+*Param : FaceAFParam ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceAF( Cl_Bool FaceAFParam )
+{
+ printk( "====> %s::%d\n", __func__, FaceAFParam);
+
+ if(FaceAFParam)
+ {
+ /* Send command to ISP MCU : Face AF Enable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AF_START);
+
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+
+ /* Send command to ISP MCU : Face Full AF Enable */
+ CoreISP3_Send_Command(ISP3_CMD_FULLAF);
+ }
+ else
+ {
+ /* Send command to ISP MCU : Face AF Disable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_AF_STOP);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceAWB
+*Description : Set AWB with Face Tracking
+*Param : enISP_FUNC_AWBwithFD_Level_1
+ enISP_FUNC_AWBwithFD_Level_2
+ enISP_FUNC_AWBwithFD_Level_3
+ enISP_FUNC_AWBwithFD_Level_4
+ enISP_FUNC_AWBwithFD_Level_5
+ enISP_FUNC_AWBwithFD_Level_6
+ enISP_FUNC_AWBwithFD_Level_7
+ enISP_FUNC_AWBwithFD_Level_8
+ enISP_FUNC_AWBwithFD_Level_9
+ enISP_FUNC_AWBwithFD_Level_10
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceAWB( Cl_Bool FaceAWBParam )
+{
+#if 0
+ if(FaceAWBParam)
+ {
+ }
+ else
+ {
+ }
+#else
+ ClUint_16 retval = 0;
+ printk("====> %s::%d\n", __func__, FaceAWBParam);
+ switch(FaceAWBParam)
+ {
+ case enISP_FUNC_AWBwithFD_Level_1:
+ retval = CoreISP3_I2C_Read(EnAWBFaceH);
+ CoreISP3_I2C_Write(EnAWBFaceH, (retval | 0x02));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_2:
+ retval = CoreISP3_I2C_Read(EnAWBFaceH);
+ CoreISP3_I2C_Write(EnAWBFaceH, (retval | 0x01));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_3:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x80));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_4:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x40));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_5:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x20));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_6:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x10));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_7:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x08));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_8:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x04));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_9:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x02));
+ break;
+ case enISP_FUNC_AWBwithFD_Level_10:
+ retval = CoreISP3_I2C_Read(EnAWBFaceL);
+ CoreISP3_I2C_Write(EnAWBFaceL, (retval | 0x01));
+ break;
+ default:
+ break;
+ }
+#endif
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceRotation
+*Description : Set Rotation of Face Tracking
+*Param : FaceRotation ON
+ OFF
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceRotation( Cl_Bool FaceRotation )
+{
+ printk( "====> %s::%d\n", __func__, FaceRotation);
+
+ if(FaceRotation)
+ {
+ /* Send command to ISP MCU : Face Rotation Enable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_ROTATE_START);
+ }
+ else
+ {
+ /* Send command to ISP MCU : Face Rotation Disable */
+ CoreISP3_Send_Command(ISP3_CMD_FACE_ROTATE_STOP);
+ }
+ /* Delay Time : 100ms */
+ WaitTime_us(2*100);
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceROIThick
+*Description : Set ROI of Face Tracking
+*Param : FaceRoiThickParam enISP_FUNC_FD_ROI_THICK_0
+ enISP_FUNC_FD_ROI_THICK_1
+ enISP_FUNC_FD_ROI_THICK_2
+ enISP_FUNC_FD_ROI_THICK_3
+ enISP_FUNC_FD_ROI_THICK_4
+ enISP_FUNC_FD_ROI_THICK_5
+ enISP_FUNC_FD_ROI_THICK_6
+ enISP_FUNC_FD_ROI_THICK_7
+ enISP_FUNC_FD_ROI_THICK_8
+ enISP_FUNC_FD_ROI_THICK_9
+ enISP_FUNC_FD_ROI_THICK_10
+ enISP_FUNC_FD_ROI_THICK_11
+ enISP_FUNC_FD_ROI_THICK_12
+ enISP_FUNC_FD_ROI_THICK_13
+ enISP_FUNC_FD_ROI_THICK_14
+ enISP_FUNC_FD_ROI_THICK_15
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceROIThick( enIsp3FaceROIThick FaceRoiThickParam )
+{
+ printk("====> %s::%d\n", __func__, FaceRoiThickParam);
+
+ CoreISP3_I2C_Write(0xf20c, FaceRoiThickParam);
+ printk(">>ISP2_REG>>0xf20c==0x%x\n",CoreISP3_I2C_Read(0xf20c));
+}
+/*********************************************************************
+*Name : CoreISP3_SetFaceMaxDetectionCount
+*Description : Set Max Detecting count of Face Tracking
+*Param : FaceMaxDetectionParam enISP_FUNC_FD_MAXCOUNT_1
+ enISP_FUNC_FD_MAXCOUNT_2
+ enISP_FUNC_FD_MAXCOUNT_3
+ enISP_FUNC_FD_MAXCOUNT_4
+ enISP_FUNC_FD_MAXCOUNT_5
+ enISP_FUNC_FD_MAXCOUNT_6
+ enISP_FUNC_FD_MAXCOUNT_7
+ enISP_FUNC_FD_MAXCOUNT_8
+ enISP_FUNC_FD_MAXCOUNT_9
+ enISP_FUNC_FD_MAXCOUNT_10
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceMaxDetectionCount( enIsp3FaceMaxDetectionCount FaceMaxDetectionParam )
+{
+ printk( "====> %s::%d\n", __func__, FaceMaxDetectionParam);
+
+ switch(FaceMaxDetectionParam)
+ {
+ case enISP_FUNC_FD_MAXCOUNT_1:
+ CoreISP3_I2C_Write(0xf20a, 0x02);
+ CoreISP3_I2C_Write(0xf20b, 0x00);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_2:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0x00);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_3:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0x80);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_4:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xc0);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_5:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xe0);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_6:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xf0);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_7:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xf8);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_8:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xfc);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_9:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xfe);
+ break;
+ case enISP_FUNC_FD_MAXCOUNT_10:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xff);
+ break;
+ default:
+ CoreISP3_I2C_Write(0xf20a, 0x03);
+ CoreISP3_I2C_Write(0xf20b, 0xc0);
+ break;
+ }
+
+}
+
+stFaceInfo CoreISP3_GetFacePosition(unsigned char index )
+{
+
+ stFaceInfo faceInfo;
+ ClUint_16 high;
+ ClUint_16 low;
+ ClUint_16 regAdd = 0xf3f1 + (index*8); //start from 0xf3f1, every 8 register
+
+ printk( "\n\n====> %s:%d:\n", __func__,CoreISP3_I2C_Read(0xf212));
+
+ high = CoreISP3_I2C_Read(regAdd++);
+ low = CoreISP3_I2C_Read(regAdd++);
+ faceInfo.sx = (((high&0xff)<<8)|(low&0xff));
+ faceInfo.sx/=4;
+ printk( "Start X-Coordinate of face::[%d]::\n", faceInfo.sx);
+
+ high = CoreISP3_I2C_Read(regAdd++);
+ low = CoreISP3_I2C_Read(regAdd++);
+ faceInfo.sy = (((high&0xff)<<8)|(low&0xff));
+ faceInfo.sy/=4;
+ printk( "Start Y-Coordinate of face::[%d]::\n", faceInfo.sy);
+
+ high = CoreISP3_I2C_Read(regAdd++);
+ low = CoreISP3_I2C_Read(regAdd++);
+ faceInfo.ex = (((high&0xff)<<8)|(low&0xff));
+ faceInfo.ex/=4;
+ printk( "END X-Coordinate of face::[%d]::\n", faceInfo.ex);
+
+ high = CoreISP3_I2C_Read(regAdd++);
+ low = CoreISP3_I2C_Read(regAdd++);
+ faceInfo.ey = (((high&0xff)<<8)|(low&0xf8));
+ faceInfo.ey/=4;
+ printk( "END Y-Coordinate of face::[%d]::\n", faceInfo.ey);
+
+ return faceInfo;
+
+
+}
+
+
+void CoreISP3_Select_ROI(ClUint_8 area, ClUint_8 count)//ROI µÚ¼¸¸öÈËÁ³ÓÃÓÚ¶Ô½¹
+{
+ ClUint_8 data = (count <<4) | (area & 0x0F);
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, data);
+ CoreISP3_Send_Command(0xa9);
+ printk( "FaceUserModeParam count:%x area:%x ==>:%x\n", count, area,data );
+ printk( "Check:%x\n",CoreISP3_I2C_Read(0xE640) );
+}
+
+/*********************************************************************
+*Name : CoreISP3_SetFaceUserMode
+*Description : Set Face Area to select Face by user
+*Param : enIspFaceUserMode enISP_FUNC_FDUser_Level_0 : Disable User Mode
+ enISP_FUNC_FDUser_Level_1
+ enISP_FUNC_FDUser_Level_2
+ enISP_FUNC_FDUser_Level_3
+ enISP_FUNC_FDUser_Level_4
+ enISP_FUNC_FDUser_Level_5
+ enISP_FUNC_FDUser_Level_6
+ enISP_FUNC_FDUser_Level_7
+ enISP_FUNC_FDUser_Level_8
+ enISP_FUNC_FDUser_Level_9
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SetFaceUserMode( enIspFaceUserMode FaceUserModeParam )
+{
+ ClUint_8 area = 0;
+ ClUint_8 count1 = 1, count2 = 1, count3 = 1, count4 = 1, count5 = 1, count6 = 1, count7 = 1, count8 = 1, count9 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "====> %s::%d\n", __func__, FaceUserModeParam);
+ #endif
+ #if 1
+ CoreISP3_Select_ROI((FaceUserModeParam&0xF),(FaceUserModeParam>>4));
+ return;
+ #endif
+
+ switch(FaceUserModeParam)
+ {
+ case enISP_FUNC_FDUser_Level_1:
+ area = enISP_FUNC_FDUser_Level_1;
+
+ count1++;
+ if(count1 > 5) count1 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count1 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count9 & 0xF0) | (area & 0x0F));
+ break;
+
+ case enISP_FUNC_FDUser_Level_2:
+ area = enISP_FUNC_FDUser_Level_2;
+ count2++;
+ if(count2 > 5) count2 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count2 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count2 & 0xF0) | (area & 0x0F));
+ break;
+
+ case enISP_FUNC_FDUser_Level_3:
+ area = enISP_FUNC_FDUser_Level_3;
+ count3++;
+ if(count3 > 5) count3 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count3 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count3 & 0xF0) | (area & 0x0F));
+ break;
+
+ case enISP_FUNC_FDUser_Level_4:
+ area = enISP_FUNC_FDUser_Level_4;
+ count4++;
+ if(count4 > 5) count4 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count4 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count4 & 0xF0) | (area & 0x0F));
+ break;
+
+ case enISP_FUNC_FDUser_Level_5:
+ area = enISP_FUNC_FDUser_Level_5;
+ count5++;
+ if(count5> 5) count5 = 1;
+
+ count5<<=4; // Jacky for test
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count5 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count5 & 0xF0) | (area & 0x0F));
+ break;
+
+ case enISP_FUNC_FDUser_Level_6:
+ area = enISP_FUNC_FDUser_Level_6;
+ count6++;
+ if(count6 > 5) count6 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count6 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count6 & 0xF0) | (area & 0x0F));
+ break;
+ case enISP_FUNC_FDUser_Level_7:
+ area = enISP_FUNC_FDUser_Level_7;
+ count7++;
+ if(count7 > 5) count7 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count7 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count7 & 0xF0) | (area & 0x0F));
+ break;
+ case enISP_FUNC_FDUser_Level_8:
+ area = enISP_FUNC_FDUser_Level_8;
+ count8++;
+ if(count8 > 5) count8 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count8 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count8 & 0xF0) | (area & 0x0F));
+ break;
+ case enISP_FUNC_FDUser_Level_9:
+ area = enISP_FUNC_FDUser_Level_9;
+ count9++;
+ if(count9 > 5) count9 = 1;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "FaceUserModeParam 0x%x\n", (count9 & 0xF0) | (area & 0x0F));
+ #endif
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_START);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ CoreISP3_I2C_Write(0xE640, (count9 & 0xF0) | (area & 0x0F));
+ break;
+ case enISP_FUNC_FDUser_Level_0:
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_STOP);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ break;
+
+ default:
+ CoreISP3_Send_Command(ISP3_CMD_FACE_USERMODE_STOP);
+ CoreISP3_I2C_Write(0xE640, 0x00);
+ break;
+ }
+
+}
+
+void CoreISP3_FaceSelect(int x, int y)
+{
+#if 0
+ ISP3_RegWrite(0xE628, x>>8);
+ ISP3_RegWrite(0xE629, x&0xFF);
+ ISP3_RegWrite(0xE62A, y>>8);
+ ISP3_RegWrite(0xE62B, y&0xFF);
+ ISP3_WriteCmd(FACE_SELECT); // 0xea
+#else
+
+#define ButtonReg 0xE640
+#define ClickPosX 0xE626
+#define ClickPosY 0xE627
+//#define FACE_USERMODE_DYNAMIC_AREA 0xa8
+
+ CoreISP3_I2C_Write(ButtonReg, x>>8); // x pos high bit
+ CoreISP3_I2C_Write(ClickPosX, x&0xFF); // y pos low bit
+ CoreISP3_I2C_Write(ClickPosY, y);
+ CoreISP3_Send_Command(0xa8);
+#endif
+}
+
+void CoreISP3_SetFocusPos(signed short focusPos)//É趨²½½øÂí´ïλÖÃ
+{
+ CoreISP3_I2C_Write(0xE628, (focusPos>>8)&0xFF);
+ CoreISP3_I2C_Write(0xE629, focusPos&0xFF);
+
+ CoreISP3_I2C_Write(0xE62A, 0);
+ CoreISP3_Send_Command(0xb7);
+}
+
+signed short CoreISP3_GetFocusPos(void)
+{
+ signed short focusPos;
+
+ CoreISP3_I2C_Write(0xE62A, 0);
+ CoreISP3_Send_Command(0x4f);
+
+ focusPos = (CoreISP3_I2C_Read(0xE628)<<8 | CoreISP3_I2C_Read(0xE629));
+ return focusPos;
+}
+
+void CoreISP3_UserArea_AFOn(int centerX, int centerY, int afWindowWidth, int afWindowHeight)
+{
+// int afWindowWidth = g_sensorOutputWidth/4;
+// int afWindowHeight = g_sensorOutputHeight/4;
+ int sx, sy;
+ int ex, ey;
+
+ if(centerX - afWindowWidth/2 < 0)
+ centerX = afWindowWidth/2;
+ else if(centerX + afWindowWidth/2 > 640)
+ centerX = 480 - afWindowWidth/2;
+
+ if(centerY - afWindowHeight/2 < 0)
+ centerY = afWindowHeight/2;
+ else if(centerY + afWindowHeight/2 > 640)
+ centerY = 480 - afWindowHeight/2;
+
+ sx = centerX - afWindowWidth/2;
+ sy = centerY - afWindowHeight/2;
+ ex = centerX + afWindowWidth/2;
+ ey = centerY + afWindowHeight/2;
+
+ CoreISP3_I2C_Write(AFWinEStrX, sx>>4);
+ CoreISP3_I2C_Write(AFWinEStrY, sy>>4);
+ CoreISP3_I2C_Write(AFWinEEndX, ex>>4);
+ CoreISP3_I2C_Write(AFWinEEndY, ey>>4);
+
+ CoreISP3_I2C_Write(0xE628, 0x01); // User Area AF
+ CoreISP3_Send_Command(ISP3_CMD_FULLAF);
+}
+
+
+static ClSint_16 System_I2C_ReadA1D1(ClUint_8 devID/**< DeviceID */, ClUint_8 addr/**< Address */)
+{
+ //Set_Sensor_Addr(devID>>1);
+#if defined(ISP3_EVB_ENABLE)||defined(ISP2_EVB_ENABLE)
+ SetReg_I2CID(devID>>1);
+
+ return IIC_READ(addr);
+
+#else
+ return 0;
+#endif
+}
+/*
+Please add below part before another access IIC.
+1. I2C write: deviceID address wrdata: 0x82 0x00 0xFF
+: I2C_WriteA1D1(0x82, 0x00, 0xFF)
+ System_IICWrite(0x82, 0x00, 0xFF);
+
+2. I2C read : deviceID address rddata: 0x83 0x00 rddata
+: rddata = I2C_ReadA1D1(0x83, 0x00)
+
+3. ISP3 write: 0xF100 <- 0xFF
+: CoreISP3_I2C_Write(0xF100, 0xFF)
+
+4. ISP3 read : 0xF100
+: a = CoreISP3_I2C_Read(0xF100)
+ if(a != 0xFF)
+ return error.
+
+5. 0xE037[7] = 0;
+: a = CoreISP3_I2C_Read(0xF100)
+ CoreISP3_I2C_Write(0xE037, a & 0x7F)
+*/
+ClUint_8 CoreISP3_IIC_Patch(void)
+{
+ ClUint_16 a;
+
+ System_IICWrite(0x82, 0x00, 0xFF); // slave id 0x82 write reg 0x00 0xff
+
+ a = System_I2C_ReadA1D1(0x83, 0x00); // slave id 0x83 read 0x00 reg
+ if(a != 0xFF)
+ {
+ printk( "0x00 Write fail \n");
+ return 0; //fail
+ }
+
+ CoreISP3_I2C_Write(0xF100, 0xFF);
+
+ a = CoreISP3_I2C_Read(0xF100);
+ if(a != 0xFF)
+ {
+ printk( "0xF100 Write fail \n");
+ return 0; //fail
+ }
+ a = CoreISP3_I2C_Read(0xF100);
+ CoreISP3_I2C_Write(0xE037, a & 0x7F);
+}
+
+/*
+1. for Touch pad
+ 1. 0xE037[7] = 0;
+ 2. ISP3 write: 0xF180 <- 0xFF
+ 3. ISP3 read : 0xF180
+
+2. for PMU
+1. BB want to access 0x81 register
+ 1. 0xE037[7] = 0;
+ 2. ISP3 write: 0xF180 <- 0xFF
+ 3. ISP3 read : 0xF180
+
+2. BB want to access 0x83 register
+ 1. 0xE037[7] = 0;
+ 2. ISP3 I2C byte write:
+ 3. ISP3 I2C byte read :
+*/
+ClUint_8 CoreISP3_IIC_ForTouchPad_81Reg(void)
+{
+ ClUint_16 a;
+
+ a= CoreISP3_I2C_Read(0xE037);
+ CoreISP3_I2C_Write(0xE037, a&0x7f);
+
+ CoreISP3_I2C_Write(0xf180, 0xff);
+
+ a = CoreISP3_I2C_Read(0xf180);
+ if(a != 0xFF)
+ {
+ printk( "0xf180 Write fail \n");
+ return 0; //fail
+ }
+}
+
+ClUint_8 CoreISP3_IIC_For83Reg(void)
+{
+ ClUint_16 a;
+
+ a= CoreISP3_I2C_Read(0xE037);
+ CoreISP3_I2C_Write(0xE037, a&0x7f);
+
+ System_IICWrite(0x82, 0x00, 0xFF); // slave id 0x82 write reg 0x00 0xff
+
+ a = System_I2C_ReadA1D1(0x83, 0x00); // slave id 0x83 read 0x00 reg
+ if(a != 0xFF)
+ {
+ printk( "0x00 Write fail \n");
+ return 0; //fail
+ }
+}
+
+
+
+/*********************************************************************
+*Name : CoreISP3_ControlFaceApplication
+*Description : Set All param of Face Tracking
+*Param : stIspFaceDetectionCtrlParam bFaceDetectionEnable
+ bFaceTrackingEnable
+ bFaceAE
+ bFaceAF
+ bFaceAWB
+ bFaceRotation
+ Isp3FaceROIThick
+ Isp3FaceMaxDetectionCount
+ enIsp3OutResolution OutputResolution
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_ControlFaceApplication( _tIspFaceDetectionCtrl *stIspFaceDetectionCtrlParam )
+{
+ printk( "====> %s::%d,%d,%d,%d,%d,%d,%d,%d,%d\n", __func__,
+ stIspFaceDetectionCtrlParam->bFaceAE, stIspFaceDetectionCtrlParam->bFaceAF,
+ stIspFaceDetectionCtrlParam->bFaceAWB, stIspFaceDetectionCtrlParam->bFaceDetectionEnable,
+ stIspFaceDetectionCtrlParam->bFaceRotation, stIspFaceDetectionCtrlParam->bFaceTrackingEnable,
+ stIspFaceDetectionCtrlParam->Isp3FaceMaxDetectionCount, stIspFaceDetectionCtrlParam->Isp3FaceROIThick,
+ stIspFaceDetectionCtrlParam->OutputResolution);
+
+ /*if((CoreISP3_I2C_Read(0xed6c)!=0x01)||(CoreISP3_I2C_Read(0xed6d)!=0x40)||(CoreISP3_I2C_Read(0xed6e)!=0x00)||(CoreISP3_I2C_Read(0xed6f)!=0x40))
+ {
+ printk( "Thumbnail size not 320x240\n");
+ CoreISP3_I2C_Write(0xed6c, 0x01);
+ CoreISP3_I2C_Write(0xed6d, 0x40);
+ CoreISP3_I2C_Write(0xed6e, 0x00);
+ CoreISP3_I2C_Write(0xed6f, 0x40);
+ }
+ */
+
+ if(stIspFaceDetectionCtrlParam->bFaceDetectionEnable == Cl_True)
+ {
+ CoreISP3_Send_Command(ISP3_CMD_FACE_DETECTION_START);
+
+ /* Check each functions */
+ if(stIspFaceDetectionCtrlParam->bFaceTrackingEnable)
+ {
+ CoreISP3_SetFaceTracking(stIspFaceDetectionCtrlParam->bFaceTrackingEnable);
+ }
+ if(stIspFaceDetectionCtrlParam->bFaceAE)
+ {
+ CoreISP3_SetFaceAE(stIspFaceDetectionCtrlParam->bFaceAE);
+ }
+ if(stIspFaceDetectionCtrlParam->bFaceAF)
+ {
+ CoreISP3_SetFaceAF(stIspFaceDetectionCtrlParam->bFaceAF);
+ }
+ if(stIspFaceDetectionCtrlParam->bFaceAWB)
+ {
+ CoreISP3_SetFaceAWB(stIspFaceDetectionCtrlParam->bFaceAWB);
+ }
+ if(stIspFaceDetectionCtrlParam->bFaceRotation)
+ {
+ CoreISP3_SetFaceRotation(stIspFaceDetectionCtrlParam->bFaceRotation);
+ }
+ if(stIspFaceDetectionCtrlParam->Isp3FaceROIThick>enISP_FUNC_FD_ROI_THICK_0)
+ {
+ CoreISP3_SetFaceROIThick(stIspFaceDetectionCtrlParam->Isp3FaceROIThick);
+ }
+ if(stIspFaceDetectionCtrlParam->Isp3FaceMaxDetectionCount>enISP_FUNC_FD_MAXCOUNT_1)
+ {
+ CoreISP3_SetFaceMaxDetectionCount(stIspFaceDetectionCtrlParam->Isp3FaceMaxDetectionCount);
+ }
+ if(stIspFaceDetectionCtrlParam->bFaceUserMode>enISP_FUNC_FDUser_Level_0)
+ {
+ CoreISP3_SetFaceUserMode(stIspFaceDetectionCtrlParam->bFaceUserMode);
+ }
+ }
+ else
+ {
+ CoreISP3_Send_Command(ISP3_CMD_FACE_DETECTION_STOP);
+
+ CoreISP3_SetFaceTracking(Cl_False);
+ }
+}
+//Added by Jacky for Face Tracking
+
+void CoreISP3_FaceTracking_On(void)
+{
+ _tIspFaceDetectionCtrl g_tIspFaceDetectCtrl;
+
+ g_tIspFaceDetectCtrl.bFaceDetectionEnable = Cl_True;
+ g_tIspFaceDetectCtrl.bFaceTrackingEnable = Cl_True;
+ g_tIspFaceDetectCtrl.bFaceAE = Cl_False; // enISP_FUNC_AEwithFACE_1; // Jacky change this
+ g_tIspFaceDetectCtrl.bFaceAF = Cl_False;
+ g_tIspFaceDetectCtrl.bFaceAWB = Cl_False;
+ g_tIspFaceDetectCtrl.bFaceRotation = Cl_True;
+ g_tIspFaceDetectCtrl.Isp3FaceROIThick = enISP_FUNC_FD_ROI_THICK_4;
+ g_tIspFaceDetectCtrl.Isp3FaceMaxDetectionCount = enISP_FUNC_FD_MAXCOUNT_10; // enISP_FUNC_FD_MAXCOUNT_10; Jacky change this for test
+ g_tIspFaceDetectCtrl.bFaceUserMode = enISP_FUNC_FDUser_Level_5; // Jacky change user mode
+
+ CoreISP3_ControlFaceApplication(&g_tIspFaceDetectCtrl);
+}
+
+void CoreISP3_FaceTracking_Off(void)
+{
+ _tIspFaceDetectionCtrl g_tIspFaceDetectCtrl;
+
+ g_tIspFaceDetectCtrl.bFaceDetectionEnable = Cl_False;
+
+ CoreISP3_ControlFaceApplication(&g_tIspFaceDetectCtrl);
+}
+
+/*
+0x001 [5:0] ro 0x000 DNUM Face Detection Result Count Register
+Permitted values 0x0 ~ 0x23(Max 35)
+*/
+void face_Reg_Read_Set(short faceAddrH, short faceAddrL, ClUint_8 *read_dataL, ClUint_8 *read_dataH)
+{
+ printk( " ====> %s:: 0x%x\n", __func__, faceAddrH<<8|faceAddrL);
+ CoreISP3_I2C_Write(FaceAddrH,(short)faceAddrH);
+ CoreISP3_I2C_Write(FaceAddrL,(short)faceAddrL);
+ CoreISP3_I2C_Write(FaceRW,(short)0x01);
+ CoreISP3_I2C_Write(FaceRW,(short)0x00);
+ *read_dataL = (int)CoreISP3_I2C_Read(FaceRDataL);
+ *read_dataH = (int)CoreISP3_I2C_Read(FaceRDataH);
+}
+
+
+ClUint_32 CoreISP3_ReadFace_Cnt(void)
+{
+ ClUint_8 read_value, read_dataL, read_dataH;
+ ClUint_16 face_cnt;
+/*
+ face_Reg_Read_Set((short)0x00, (short)0x01, &read_dataL, &read_dataH);
+ face_cnt = CoreISP3_I2C_Read(FaceRDataL);
+ printk( " ====> %s:: FaceRDataL: %d\n", __func__, face_cnt);
+*/
+
+ face_cnt = CoreISP3_I2C_Read(FaceResultCnt);
+ printk( " ====> %s:: FaceResultCnt: %d\n", __func__, face_cnt);
+
+ return face_cnt;
+}
+
+void CoreISP3_ReadFace_AFPosition(void)
+{
+ ClUint_16 face_af;
+
+ face_af = CoreISP3_I2C_Read(FaceAFPosH)<<8|CoreISP3_I2C_Read(FaceAFPosL);
+
+ printk( " ====> %s::F : %d\n", __func__, face_af);
+
+}
+
+void CoreISP3_ReadFaceA_Position(void)
+{
+ ClUint_16 face_a_strx;
+ ClUint_16 face_a_stry;
+ ClUint_16 face_a_endx;
+ ClUint_16 face_a_endy;
+
+ face_a_strx = CoreISP3_I2C_Read(FaceAStrX_8051H)<<8|CoreISP3_I2C_Read(FaceAStrX_8051L);
+ face_a_stry = CoreISP3_I2C_Read(FaceAStrY_8051H)<<8|CoreISP3_I2C_Read(FaceAStrY_8051L);
+ face_a_endx = CoreISP3_I2C_Read(FaceAEndX_8051H)<<8|CoreISP3_I2C_Read(FaceAEndX_8051L);
+ face_a_endy = CoreISP3_I2C_Read(FaceAEndY_8051H)<<8|CoreISP3_I2C_Read(FaceAEndY_8051L);
+ #if 1
+ // (1280x960)/4 = (320x240)
+ _faceInfo[0].sx = face_a_strx/4;
+ _faceInfo[0].sy = face_a_stry/4;
+ _faceInfo[0].ex = face_a_endx/4;
+ _faceInfo[0].ey = face_a_endy/4;
+ #else
+ // (1280x960) -> (240x180)
+ _faceInfo[0].sx = face_a_strx*(1280/240);
+ _faceInfo[0].sy = face_a_stry*(1280/240);
+ _faceInfo[0].ex = face_a_endx*(1280/240);
+ _faceInfo[0].ey = face_a_endy*(1280/240);
+ #endif
+ printk( " ====> %s:: [%d %d %d %d]\n", __func__, _faceInfo[0].sx, _faceInfo[0].sy, _faceInfo[0].ex, _faceInfo[0].ey);
+
+}
+
+/*********************************************************************
+*Name : CoreISP3_ReadJPEGRowCnt
+*Description :
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+ClUint_16 CoreISP3_ReadJPEGRowCnt( void )
+{
+ ClUint_16 RowCnt;
+
+ RowCnt = CoreISP3_I2C_Read(RowCntH)<<8|CoreISP3_I2C_Read(RowCntL);
+
+ if((RowCnt<480)||(RowCnt>1200))
+ {
+ printk( "Row cnt over flow %d\n", RowCnt);
+ RowCnt = 1200; // Jacky for protect
+ }
+ printk( "\n read fixed jpeg stream size 2048 x %d \n", RowCnt);
+
+ return RowCnt;
+}
+
+
+ClUint_32 CoreISP3_ReadJPEG_Size(void)
+{
+ClUint_8 overflow_flag;
+ClUint_16 size_h;
+ClUint_16 size_m;
+ClUint_16 size_l;
+/*
+0xee01 [7:7] r 0x00 Overflow JPEG Fifo Overflow Check Flag 0xee01
+ [6:0] r 0x00 JSizeH JPEG Size High
+0xee02 [7:0] r 0x00 JSizeM JPEG Size Medium
+0xee03 [7:0] r 0x00 JSizeL JPEG Size Low
+*/
+
+size_h = CoreISP3_I2C_Read(0xee01);
+size_m = CoreISP3_I2C_Read(0xee02);
+size_l = CoreISP3_I2C_Read(0xee03);
+
+overflow_flag= (size_h&0x80)>>7;
+
+printk( "\n Read jpeg size [%d] [%d] [%d] [%d] \n", size_h, size_m, size_l, ((size_h&0x7f)<<16)|(size_m<<8)|(size_l));
+
+return ((size_h&0x7f)<<16)|(size_m<<8)|(size_l);
+}
+
+//0xee15 [7:0] rw 0x18 RSF JPEG Quality Factor(18:Good <-> 28:Poor)
+void CoreISP3_SetJPEG_Quality_Factor(enIsp3JPEGQF value)
+{
+ printk( "====> %s::%d\n", __func__, value);
+
+ CoreISP3_I2C_Write(0xee15, value);
+}
+
+/*********************************************************************
+*Name : CoreISP3_OutpJPEG_Resolution
+*Description : Set ISP Mode
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_OutpJPEG_Resolution( Cl_Bool bThumbnail , enIsp3OutResolution OutResolution)
+{
+ printk( "====> %s::%d\n", __func__, bThumbnail);
+
+ /* Global Variable Set */
+#ifdef ISP3_EVB_ENABLE
+ g_bJpegMode = ClTrue;
+#endif
+/*
+default is 0x200=512 0x800=2048
+0xee17 [7:0] rw 0x02 JPGFifoSizeH JPEG FIFO Limit control High
+0xee18 [7:0] rw 0x00 JPGFifoSizeL JPEG FIFO Limit control Low
+
+JPEG Output row count 0x2cc is original value
+
+2. FIFO size x Hync count.
+ FIFO size is 2048. This is fixed.
+
+3. If we want to use 1280 x 960, our ISP3 will make a 2048 x 960 because FIFO size is 2048 fix.
+ Thus, 2048 x 960 = around 1.9M. BB need to allocation around 1.9MByte.
+
+4. Ex) 2048 x 960 resolution
+ 0xEe, 0x0a, 0x03, // #RowCntH
+ 0xEe, 0x0b, 0xc0, // #RowCntL
+ Ex) 2048 x 480 resolution
+ 0xEe, 0x0a, 0x01, // #RowCntH
+ 0xEe, 0x0b, 0xE0, // #RowCntL
+
+*/
+
+
+#ifdef __ISP3_R__
+ CoreISP3_I2C_Write(JpgOutMode, 0x18); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+ //CoreISP3_I2C_Write(JpgOutMode, 0x16); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+ //CoreISP3_I2C_Write(JpgOutMode, 0x12); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+
+#else //__ISP3_R__
+ CoreISP3_I2C_Write(JpgOutMode, 0x08); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+ CoreISP3_I2C_Write(Jpg_FifoLimit_H, 0x01); //#0: 288, 1: 192, 2: 96, 3: JPEG fifo size high 5bit, low 8bit, else: 192
+ CoreISP3_I2C_Write(Jpg_FifoLimit_L, 0xc0); //#JPEG fifo size low byte
+#endif //__ISP3_R__
+
+/* Jpeg data + padding data size */
+#ifdef __ISP3_R__ // Jacky add this for test
+ printk("====> jpeg output OutResolution \n", OutResolution);
+ printk("jpg fifoH: 0x%x L:0x%x \n", CoreISP3_I2C_Read(Jpg_FifoLimit_H), CoreISP3_I2C_Read(Jpg_FifoLimit_L));
+ if(OutResolution == enISP_RES_5MP_FULL) // 2560x1920
+ { // data size: 2048x1920
+ CoreISP3_I2C_Write(RowCntH, 0x07); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0x80); //JPEG Output row count Low
+ }
+ else if(OutResolution == enISP_RES_QXGA) // 2048x1536
+ { // data size: 2048x1536
+ CoreISP3_I2C_Write(RowCntH, 0x06); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0x00); //JPEG Output row count Low
+ }
+ else if(OutResolution == enISP_RES_UXGA) // 1600x1200
+ { // data size: 2048x1200
+ CoreISP3_I2C_Write(RowCntH, 0x04); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xb0); //JPEG Output row count Low
+ }
+ else if(OutResolution == enISP_RES_1_3MP) // 1280x960
+ { // data size: 2048x960
+ CoreISP3_I2C_Write(RowCntH, 0x03); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xc0); //JPEG Output row count Low
+ }
+ else if(OutResolution == enISP_RES_SVGA) // 800x600
+ { // data size: 2048x600
+ CoreISP3_I2C_Write(RowCntH, 0x02); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0x58); //JPEG Output row count Low
+ }
+ else if(OutResolution == enISP_RES_VGA) // 640x480
+ {// data size: 2048x480 = 983040bytes // jade read size: 2048*(480+6) = 995733 1018333(JHBlank=0) Jade get size is fixed 1136703
+ CoreISP3_I2C_Write(RowCntH, 0x01); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xe0); //JPEG Output row count Low
+ }
+ else // 716
+ {
+ CoreISP3_I2C_Write(RowCntH, 0x02); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xcc); //JPEG Output row count Low
+ }
+#else //__ISP3_R__
+ CoreISP3_I2C_Write(RowCntH, 0x03); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xcc); //JPEG Output row count Low
+#endif //__ISP3_R__
+
+ CoreISP3_I2C_Write(FlipHold, 0xff); //JPEG Rotation (8x8) Parameter
+
+ CoreISP3_I2C_Write(JHBlank, 0x06); //JPEG Output Horizontal Blank Size
+ //CoreISP3_I2C_Write(Still_UpHBlankL, 0x10); //Up scaling line blank
+
+ //CoreISP3_I2C_Write(JHBlank, 0x00); //JPEG Output Horizontal Blank Size Jacky change for test
+ CoreISP3_I2C_Write(Still_UpHBlankL, 0x10); //Up scaling line blank
+
+ CoreISP3_I2C_Write(Still_VRdRate_SclMode, 0x0f); //JPEG Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+ CoreISP3_I2C_Write(Thu_VRdRate_SclMode, 0x02); //Thumbnail Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+ CoreISP3_I2C_Write(Pre_VRdRate_SclMode, 0x0f); //Preview Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+
+ if(bThumbnail)
+ {
+#ifdef __ISP3_R__
+ /*JPCLKDiv = JpgClkDiv[3:0] PrvCLKDiv = JpgClkDiv[3:0] */
+ CoreISP3_I2C_Write(JpgClkDiv, 0x02); //PrvCLKDiv (2 = JClck * 1/2)
+ /* Face Detection OFF */
+ CoreISP3_I2C_Write(FaceModeReg, 0x00); //Face off
+#else //__ISP3_R__
+ /*JPCLKDiv = JpgClkDiv[3:0] PrvCLKDiv = JpgClkDiv[3:0] */
+ CoreISP3_I2C_Write(JpgClkDiv, 0x01); //PrvCLKDiv
+#endif //__ISP3_R__
+
+ CoreISP3_I2C_Write(PrvMode, 0x01); //Preview Mode On
+ WaitTime_us(2*100); // 100ms
+ }
+
+ /* OUT FORMAT */
+ CoreISP3_I2C_Write(OutFmt_JPG, 0x83); //[0:0] OutFmt ' 0' = YCbCr, '1' = JPEG [1:1] rw 0x00 JPGENCODE JPEG encoder enable [0:0] rw 0x00 JPGOUTEN JPEG mode output enable
+ WaitTime_us(2*100); // 100ms
+
+ /* Send Command(Output Jpeg Mode) to ISP */
+ CoreISP3_Send_Command(ISP3_CMD_CAPTURE);
+ WaitTime_us(2*500); // 500ms
+#ifdef DOWN_TIME_CHECK
+ printk( "Isp3 200ms time check start: %d\n", TIMER_curTime_ms(1));
+ //WaitTime_us(2*200); // 500ms
+ printk( "Isp3 200ms time check end: %d\n", TIMER_curTime_ms(1));
+#endif
+ //general_ctrl.output_mode = 1;
+ //printk("====> %s, %d\n", __func__, general_ctrl.output_mode);
+}
+
+/*********************************************************************
+*Name : CoreISP3_OutpJPEG
+*Description : Set ISP Mode
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_OutpJPEG( Cl_Bool bThumbnail )
+{
+ printk( "====> %s::%d\n", __func__, bThumbnail);
+/*
+ On Off
+Thumbnail PrvMode (0xEE1A) 0x01 0x00
+Dummy JpgOutMode (0xEE16) 0x28 0x26
+*/
+ /* Global Variable Set */
+#ifdef ISP3_EVB_ENABLE
+ g_bJpegMode = ClTrue;
+#endif
+
+#ifdef __ISP3_R__
+ CoreISP3_I2C_Write(JpgOutMode, 0x18); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+
+#else //__ISP3_R__
+ CoreISP3_I2C_Write(JpgOutMode, 0x08); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+ CoreISP3_I2C_Write(Jpg_FifoLimit_H, 0x01); //#0: 288, 1: 192, 2: 96, 3: JPEG fifo size high 5bit, low 8bit, else: 192
+ CoreISP3_I2C_Write(Jpg_FifoLimit_L, 0xc0); //#JPEG fifo size low byte
+#endif //__ISP3_R__
+
+/* Jpeg data + padding data size */
+#ifdef __ISP3_R__
+ //240
+ //CoreISP3_I2C_Write(RowCntH, 0x00); //JPEG Output row count High
+ //CoreISP3_I2C_Write(RowCntL, 0xf0); //JPEG Output row count Low
+ //480
+ // printk( "\n jpeg stream size 2048x480 \n");
+ CoreISP3_I2C_Write(RowCntH, 0x01); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xe0); //JPEG Output row count Low
+ printk( "\n fixed jpeg stream size 2048 x %d \n", CoreISP3_I2C_Read(RowCntH)<<8|CoreISP3_I2C_Read(RowCntL) );
+ //716
+ //CoreISP3_I2C_Write(RowCntH, 0x02); //JPEG Output row count High
+ //CoreISP3_I2C_Write(RowCntL, 0xcc); //JPEG Output row count Low
+#else //__ISP3_R__
+ CoreISP3_I2C_Write(RowCntH, 0x03); //JPEG Output row count High
+ CoreISP3_I2C_Write(RowCntL, 0xcc); //JPEG Output row count Low
+#endif //__ISP3_R__
+
+ CoreISP3_I2C_Write(FlipHold, 0xff); //JPEG Rotation (8x8) Parameter
+
+ CoreISP3_I2C_Write(JHBlank, 0x06); //JPEG Output Horizontal Blank Size
+ CoreISP3_I2C_Write(Still_UpHBlankL, 0x10); //Up scaling line blank
+
+ CoreISP3_I2C_Write(Still_VRdRate_SclMode, 0x0f); //JPEG Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+ CoreISP3_I2C_Write(Thu_VRdRate_SclMode, 0x02); //Thumbnail Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+ CoreISP3_I2C_Write(Pre_VRdRate_SclMode, 0x0f); //Preview Scaling mode[auto mode : 0x0F, average : 0x0A, linear : 0x05, subsample : 0x00]
+
+ if(bThumbnail)
+ {
+#ifdef ISP3_EVB_ENABLE
+ g_bJpegThumbnail = Cl_True;
+#endif //
+
+#ifdef __ISP3_R__
+ /*JPCLKDiv = JpgClkDiv[3:0] PrvCLKDiv = JpgClkDiv[3:0] */
+ CoreISP3_I2C_Write(JpgClkDiv, 0x02); //PrvCLKDiv (2 = JClck * 1/2)
+ /* Face Detection OFF */
+ CoreISP3_I2C_Write(FaceModeReg, 0x00); //Face off
+#else //__ISP3_R__
+ /*JPCLKDiv = JpgClkDiv[3:0] PrvCLKDiv = JpgClkDiv[3:0] */
+ CoreISP3_I2C_Write(JpgClkDiv, 0x01); //PrvCLKDiv
+#endif //__ISP3_R__
+
+ CoreISP3_I2C_Write(PrvMode, 0x01); //Thumbnail On
+ WaitTime_us(2*100); // 100ms
+ }
+ else
+ {
+#ifdef ISP3_EVB_ENABLE
+ g_bJpegThumbnail = Cl_False;
+#endif //
+ // no dummy, no thumbnail.. already test ok, after ff d9 still have some data
+ CoreISP3_I2C_Write(JpgOutMode, 0x16); //JpgClk Div [5:4] 0:x1 1:x1/2 2:x1/4 [3:0] 6: No Padding data 8:Padding data
+
+ CoreISP3_I2C_Write(PrvMode, 0x00); //Thumbnail Off
+ WaitTime_us(2*100); // 100ms
+ }
+ /* OUT FORMAT */
+ CoreISP3_I2C_Write(OutFmt_JPG, 0x83); //[0:0] OutFmt ' 0' = YCbCr, '1' = JPEG
+ WaitTime_us(2*100); // 100ms
+
+ /* Send Command(Output Jpeg Mode) to ISP */
+ //CoreISP3_Send_Command(ISP3_CMD_CAPTURE); // saving time
+ //WaitTime_us(2*500); // 500ms
+
+
+ printk("jpg fifoH: 0x%x L:0x%x \n", CoreISP3_I2C_Read(Jpg_FifoLimit_H), CoreISP3_I2C_Read(Jpg_FifoLimit_L));
+ CoreISP3_ReadJPEG_Size();
+
+}
+/*********************************************************************
+*Name : CoreISP3_OutpYCbCr
+*Description : Set ISP Mode
+*Param : none
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_OutpYCbCr( void )
+{
+ printk( "====> %s\n", __func__);
+ /* Global Variable Set */
+#ifdef ISP3_EVB_ENABLE
+ g_bJpegMode = Cl_False;
+#endif
+ /* OUT FORMAT */
+ CoreISP3_I2C_Write(OutFmt_JPG, 0x82); //[0:0] OutFmt ' 0' = YCbCr, '1' = JPEG
+ WaitTime_us(2*100); // 100ms
+
+ CoreISP3_Send_Command(ISP3_CMD_PREVIEW);
+ WaitTime_us(2*500); // 500ms
+}
+
+void CoreISP3_RGB565_Out(void)
+{
+ ClUint_8 reg_data = 0;
+ //reg_data = CoreISP3_I2C_Read(OutFmt);
+ //CoreISP3_I2C_Write(OutFmt, (reg_data | 0x10));
+ //DebugMessage(DM_JPEG, "reg_data 0x%x\n", reg_data);
+ CoreISP3_I2C_Write(OutFmt, 0x1a);
+}
+/*********************************************************************
+*Name : CoreISP3_SystemControl
+*Description : Set ISP Sleep & Wake Up mode
+*Param : param ON : Sleep Mode
+ OFF : Wake Up Mode
+*return : none
+*Author :
+*Remark :
+*Log :
+**********************************************************************/
+void CoreISP3_SystemControl( ClUint_16 param )
+{
+ ClUint_32 temp;
+
+ printk( "====> %s::%d\n", __func__, param);
+ printk( "System contron on \n");
+
+
+ CoreISP3_I2C_Write(0xe010, 0xe0); //4 [7] : Sensor reset low, vcm disable Reset pin low for sensor sleep .. useless
+
+ //CoreISP3_I2C_Write(0xEDE0, 0x00); //useless
+
+ CoreISP3_I2C_Write(0xE058, /*0x3f*/0x30);
+ WaitTime_us(2*100); //4 100 ms
+
+ CoreISP3_I2C_Write(0xE052, /*0xff*/0x00);
+ WaitTime_us(2*100); //4 100 ms
+
+ temp = CoreISP3_I2C_Read(0xE0A2);
+ CoreISP3_I2C_Write(0xE0A2, temp & 0xEF);
+ printk( "\nCoreISP3_I2C_Read(0xE0A2)::0x%x\n", CoreISP3_I2C_Read(0xE0A2));
+ WaitTime_us(2*100); //4 100 ms
+
+ CoreISP3_I2C_Write(0xe060, /*0x03*/0x02); //4 PLL Register
+ WaitTime_us(2*100); //4 100 ms
+
+ //temp = CLKEN; //bit17 0010 0000 0000 0000 0000
+ //CLKEN = (temp&0xfffdffff); // Add this line 0.8mA
+
+ //ExtGPIO_WriteData(1, 1); //Vddc 1.2V off only this line 1.3 mA sleep current
+
+ // Sensor Reset Pin
+ //SI2CCNTL = 1;
+ //SPSC = 1 ;
+ //DUALSCNTL=0;
+}
+
+void CoreISP3_SetSensorInfo( enIsp3OutResolution Isp3OutResolution )
+{
+#ifdef ISP3_EVB_ENABLE
+ // tSensorInfo g_Isp3SensorInfo;
+
+ ////DebugMessage(DM_ISP, "CoreISP3_SetSensorInfo %d\n", Isp3OutResolution);
+
+ switch(Isp3OutResolution)
+ {
+ case enISP_RES_5MP_FULL: // 2560 x 1920
+ g_Isp3SensorInfo.width=2560;
+ g_Isp3SensorInfo.height=1920;
+ break;
+ case enISP_RES_QXGA: // 2048 x 1536
+ g_Isp3SensorInfo.width=2048;
+ g_Isp3SensorInfo.height=1536;
+ break;
+ case enISP_RES_UXGA: // 1600 x 1200
+ g_Isp3SensorInfo.width=1600;
+ g_Isp3SensorInfo.height=1200;
+ break;
+ case enISP_RES_SXGA: // 1280 x 1024
+ g_Isp3SensorInfo.width=1280;
+ g_Isp3SensorInfo.height=1024;
+ break;
+ case enISP_RES_1_3MP: // 1280 x 960
+ g_Isp3SensorInfo.width=1280;
+ g_Isp3SensorInfo.height=960;
+ break;
+ case enISP_RES_XGA: // 1024 x 768
+ g_Isp3SensorInfo.width=1024;
+ g_Isp3SensorInfo.height=768;
+ break;
+ case enISP_RES_SVGA: // 800 x 600
+ g_Isp3SensorInfo.width=800;
+ g_Isp3SensorInfo.height=600;
+ break;
+ case enISP_RES_VGA: // 640 x 480
+ g_Isp3SensorInfo.width=640;
+ g_Isp3SensorInfo.height=480;
+ break;
+ case enISP_RES_QVGA: // 320 x 240
+ g_Isp3SensorInfo.width=320;
+ g_Isp3SensorInfo.height=240;
+ break;
+ case enISP_RES_HVGA: // 320 x 240
+ g_Isp3SensorInfo.width=480;
+ g_Isp3SensorInfo.height=320;
+ break;
+ case enISP_RES_480_360: // Added by Jacky
+ g_Isp3SensorInfo.width=480;
+ g_Isp3SensorInfo.height=360;
+ break;
+ case enISP_RES_480_320: // Added by Jacky
+ g_Isp3SensorInfo.width=480;
+ g_Isp3SensorInfo.height=320;
+ break;
+ case enISP_RES_800_480: //
+ g_Isp3SensorInfo.width=800;
+ g_Isp3SensorInfo.height=480;
+ break;
+ case enISP_RES_1600_960: //
+ g_Isp3SensorInfo.width=1600;
+ g_Isp3SensorInfo.height=960;
+ break;
+ case enISP_RES_2048_1228: //
+ g_Isp3SensorInfo.width=2048;
+ g_Isp3SensorInfo.height=1228;
+ break;
+ case enISP_RES_2560_1536: //
+ g_Isp3SensorInfo.width=2560;
+ g_Isp3SensorInfo.height=1536;
+ break;
+ default:
+ break;
+ }
+ g_Isp3SensorInfo.fullwidth=2560; // 500M
+ g_Isp3SensorInfo.fullheight=1920;
+
+ printk( "Resolution setting change, sensor: [%d x %d] \n", g_Isp3SensorInfo.width, g_Isp3SensorInfo.height);
+ OSAL_MemCopy(&g_stSensorInfo, &g_Isp3SensorInfo, sizeof(g_Isp3SensorInfo));
+#else
+ printk( "Resolution setting change \n");
+#endif
+}
+
+void CoreISP3_PLLOn(Cl_Bool bOn)
+{
+ //bPLL = bOn;
+ if(bOn)
+ {
+ CoreISP3_I2C_Write(0xE060, 0x00);
+ }
+ else
+ {
+ CoreISP3_I2C_Write(0xE060, 0x03);
+ }
+}
+
+void CoreISP3_FlickerSuppression(FLICKER_TYPE type)
+{
+ printk( "\n %s %d \n",__func__, type);
+
+#if 0 // old
+ switch(type)
+ {
+ case FLICKER_OFF:
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_OFF);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_OFF);
+ break;
+
+ case FLICKER_AUTO:
+ CoreISP3_I2C_Write(0xE628, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_ON);
+ break;
+
+ case FLICKER_50HZ:
+ CoreISP3_I2C_Write(0xE628, 0x32);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_OFF);
+ break;
+
+ case FLICKER_60HZ:
+ CoreISP3_I2C_Write(0xE628, 0x3c);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_OFF);
+ break;
+ }
+#else // update latest
+ switch(type)
+ {
+ case FLICKER_50HZ_OFF: // 0
+ CoreISP3_I2C_Write(0xE628, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_OFF);
+ break;
+
+ case FLICKER_50HZ_ON:
+ CoreISP3_I2C_Write(0xE628, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ break;
+
+ case FLICKER_60HZ_OFF:
+ CoreISP3_I2C_Write(0xE628, 0x3C);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_OFF);
+ break;
+
+ case FLICKER_60HZ_ON:
+ CoreISP3_I2C_Write(0xE628, 0x3C);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ break;
+
+ case FLICKER_AUTO_OFF:
+ CoreISP3_I2C_Write(0xE628, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_OFF);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_OFF);
+ break;
+
+ case FLICKER_AUTO_ON:
+ CoreISP3_I2C_Write(0xE628, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_SUPPRESSION_ON);
+ CoreISP3_Send_Command(ISP3_CMD_FLICKER_DETECTION_ON);
+ break;
+ }
+
+#endif
+}
+
+void CoreISP3_AE_SetEV(int ev_Y/**< EV : -5~+5, 0:Default, -5: Dark, +5:Bright */)
+{
+ CoreISP3_I2C_Write(0xE62A, ev_Y);
+ CoreISP3_Send_Command(ISP3_CMD_SET_AE_CONFIG);
+}
+
+void CoreISP3_AE_SetISO(enIsp3AEISO isoLevel/**< ISO Level : 1~8, 0: Auto 1: Low ISO, 8: High ISO*/)
+{
+ printk( "\n %s %d \n",__func__, isoLevel);
+
+ switch(isoLevel)
+ {
+ case enISP_AE_ISO_AUTO: // AUTO
+ CoreISP3_I2C_Write(0xE65A, 0x00);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_100: // ISO 100
+ CoreISP3_I2C_Write(0xE65A, 0x01);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_200:// ISO 200
+ CoreISP3_I2C_Write(0xE65A, 0x02);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_300:// ISO 300
+ CoreISP3_I2C_Write(0xE65A, 0x03);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_400:// ISO 400
+ CoreISP3_I2C_Write(0xE65A, 0x04);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_500:// ISO 500
+ CoreISP3_I2C_Write(0xE65A, 0x05);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_600:// ISO 600
+ CoreISP3_I2C_Write(0xE65A, 0x06);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_700:// ISO 700
+ CoreISP3_I2C_Write(0xE65A, 0x07);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ case enISP_AE_ISO_800:// ISO 800
+ CoreISP3_I2C_Write(0xE65A, 0x08);
+ CoreISP3_Send_Command(ISP3_CMD_AE_SET_ISO);
+ break;
+
+ default:
+ break;
+ }
+
+ CoreISP3_GetISOGain(); // Jacky for test
+}
+//float
+ClUint_32 CoreISP3_Get_Version(void)
+{
+ ClUint_32 SW_Ver;
+ ClUint_16 majorVer;
+ ClUint_16 minorVer;
+ ClUint_16 data1;
+ ClUint_16 data0;
+
+ CoreISP3_Send_Command(ISP3_CMD_GET_VERSION); // Jacky change this
+
+ data1 = CoreISP3_I2C_Read(0xE628);
+ data0 = CoreISP3_I2C_Read(0xE629);
+ majorVer = data1<<8 | data0;
+
+ data1 = CoreISP3_I2C_Read(0xE62A);
+ data0 = CoreISP3_I2C_Read(0xE62B);
+ minorVer = data1<<8 | data0;
+
+ SW_Ver = majorVer <<16 | minorVer;
+
+ printk( " ====Get ISP vision %d [0x%x]====\n", SW_Ver, SW_Ver);
+ printk(" ====Get ISP vision %d [0x%x]====\n", SW_Ver, SW_Ver);
+ return SW_Ver;
+
+}
+
+void CoreISP3_SetAWBMode(enWB_MANUAL_TYPE type)
+{
+ printk( " %s %d \n",__func__, type);
+ CoreISP3_I2C_Write(0xEb98, (ClUint_8)type);
+}
+
+
+// Added by Jacky according ISP3R function flow
+void CoreISP3_SetSceneMode(enIsp3SceneMode mode)
+{
+ printk( " %s %d \n",__func__, mode);
+
+ CoreISP3_I2C_Write(0xE628, mode);
+ CoreISP3_Send_Command(ISP3_CMD_MODE_AUTOMODE); // Jacky change this 0x20
+}
+
+/* =============================================================================================================
+Description : UnSet WDR Mode
+============================================================================================================= */
+void CoreISP3_Set_WDR_Off(void)
+{
+ _tISP_WDR_CTRL IspWdrCtrl;
+
+ IspWdrCtrl.bWDREnable = Cl_False;
+ CoreISP3_SetWDR(&IspWdrCtrl);
+}
+
+
+void CoreISP3_Set_StillStabilizer_On(void)
+{
+ _tIspStillStabilizerCtrl StillStabilizerParam;
+ StillStabilizerParam.bStillStabilizerEnable = Cl_True;
+ StillStabilizerParam.StillStabilzerLevel = enISP_FUNC_SS_LEVEL_1_2;
+ CoreISP3_SetStillStabilizer(&StillStabilizerParam);
+}
+
+
+void CoreISP3_Set_StillStabilizer_Off(void)
+{
+ _tIspStillStabilizerCtrl StillStabilizerParam;
+ StillStabilizerParam.bStillStabilizerEnable = Cl_False;
+ StillStabilizerParam.StillStabilzerLevel = enISP_FUNC_SS_LEVEL_1_2;
+ CoreISP3_SetStillStabilizer(&StillStabilizerParam);
+}
+
+#define STEP_GAP 12 // 5
+
+/*
+0xE002
+
+[7:0] rw 0x00 ISPFENB ISP function enable set B 0xe002
+[7:7] rw 0x00 ENHUE Hue Control
+[6:6] rw 0x00 ENSAT Saturation Control
+[5:5] rw 0x00 ENGRY Enable gray effect
+[4:4] rw 0x00 ENBPC Enable black offset adjustment
+[3:3] rw 0x00 ENBCC Enable brightness & contrast control
+[2:2] rw 0x00 ENATC Enable adaptive tone curve selection with fuzzy algori
+8051 code
+[1:1] rw 0x00 ENRTNX Enable retinex effect for boosting low light area
+preserving high light area tone gradation
+[0:0] rw 0x00 ENFCSHL Enable false color suppression in high & low light area
+
+*/
+void CoreISP3_SetBrightness(enIsp3Level_Value val)
+{
+ printk( " %s %d ->[0x%x] \n", __func__, val, (0x40+((int)val-5)*STEP_GAP));
+
+ CoreISP3_I2C_Write(0xE5E1, (ClUint_8)(0x40+((int)val-(enISP_Level_Max-1)/2)*STEP_GAP));
+ CoreISP3_I2C_Partial_Write(0xE002, 2, 2, 1); // brightness enable
+}
+
+void CoreISP3_SetContrast(enIsp3Level_Value val)
+{
+ printk( " %s %d ->[0x%x] \n", __func__, val, ((0x00+((int)val)*STEP_GAP)&0xFF));
+
+ CoreISP3_I2C_Write(0xE5E0, (ClUint_8)((0x00+((int)val)*STEP_GAP)&0xFF));
+ CoreISP3_I2C_Partial_Write(0xE002, 2, 2, 1); // contrast enable
+}
+
+void CoreISP3_SetSaturation(enIsp3Level_Value val) // default 0x40
+{
+ printk( " %s %d ->[0x%x] \n", __func__, val, (0x80+((int)val-5)*STEP_GAP));
+
+ CoreISP3_I2C_Write(0xE5B0, (ClUint_8)(0x80+((int)val-(enISP_Level_Max-1)/2)*STEP_GAP));
+ CoreISP3_I2C_Partial_Write(0xE002, 6, 6, 1); // satuation enable
+}
+
+void CoreISP3_SetHue(enIsp3Level_Value val)
+{
+ printk( " %s %d ->[0x%x] \n", __func__, val, ((0x00+((int)val)*STEP_GAP)&0xFF));
+
+ CoreISP3_I2C_Write(0xE5B1, (ClUint_8)((0x00+((int)val)*STEP_GAP)&0xFF));
+ CoreISP3_I2C_Partial_Write(0xE002, 7, 7, 1); // hue enable
+}
+
+void CoreISP3_Brightness_OnOff(Cl_Bool Brightness)
+{
+#ifdef ISP3_EVB_ENABLE
+ printk( "====> %s::%d\n", __func__, Brightness);
+#endif
+
+ if(Brightness)
+ {
+ //# Level (Default =0x40) 0xE5E1[7:0] = 10step(gap = 0x05)
+ CoreISP3_I2C_Write(0xE5E1, 0x40);
+ //# Enable = 0xE002[2:2] = On(1)
+ CoreISP3_I2C_Write(0xE002, 1<<2);
+ }
+ else
+ {
+ //# Disable = 0xE002[2:2] = Off (0)
+ CoreISP3_I2C_Write(0xE002, 0<<2);
+ }
+}
+
+void CoreISP3_Contrast_OnOff(Cl_Bool Contrast)
+{
+#ifdef ISP3_EVB_ENABLE
+ printk( "====> %s::%d\n", __func__, Contrast);
+#endif
+ if(Contrast)
+ {
+ //# Level (Default =0x00) 0xE5E0[7:0] = 10step(gap = 0x05)
+ CoreISP3_I2C_Write(0xE5E0, 0x00);
+ //# Enable = 0xE002[2:2] = On(1)
+ CoreISP3_I2C_Write(0xE002, 1<<2);
+ }
+ else
+ {
+ //# Disable = 0xE002[2:2] = On(1)
+ CoreISP3_I2C_Write(0xE002, 0<<2);
+ }
+}
+
+void CoreISP3_Saturation_OnOff(Cl_Bool Saturation)
+{
+#ifdef ISP3_EVB_ENABLE
+ printk( "====> %s::%d\n", __func__, Saturation);
+#endif
+ if(Saturation)
+ {
+ //# Level (Default =0x80) 0xE5B0 [7:0] = 10step(gap = 0x05)
+ CoreISP3_I2C_Write(0xE5B0, 0x80);
+ //# Enable = 0xE002[6:6] = On(1)
+ CoreISP3_I2C_Write(0xE002, 1<<6);
+ }
+ else
+ {
+ //# Enable = 0xE002[6:6] = Off (0)
+ CoreISP3_I2C_Write(0xE002, 0<<6);
+ }
+}
+
+void CoreISP3_Hue_OnOff(Cl_Bool Hue)
+{
+#ifdef ISP3_EVB_ENABLE
+ printk( "====> %s::%d\n", __func__, Hue);
+#endif
+ if(Hue)
+ {
+ //# Level (Default =0x00) 0xE5B1[7:0] = 10step(gap = 0x05)
+ CoreISP3_I2C_Write(0xE5B1, 0x00);
+ //# Enable = 0xE002[7:7] = On(1)
+ CoreISP3_I2C_Write(0xE002, 1<<7);
+ }
+ else
+ {
+ //# Disable = 0xE002[7:7] = Off (0)
+ CoreISP3_I2C_Write(0xE002, 0<<7);
+ }
+}
+
+// // Jacky update
+// We can change YUV swap as below.
+void CoreISP3_YUV_Swap(enIsp3YUV_Swap mode)
+{
+/*===========================================================
+ enISP_CrYCb = 0x08,
+ enISP_YCrCb = 0x09,
+ enISP_CbYCr = 0x0a,
+ enISP_YCbCr = 0x0b,
+
+YuV Format
+1. Register : 0xE050
+ [1]= 1 or 0 1: Cb pixel first , 0 : Cr pixel first
+ [0]= 1 or 0 1: Y pixel first , 0 : Cb or Cr first
+
+2. setting
+ 2-1) 0xE050 <== 0x0A Cb first : CbY CrY CbY CrY 10
+ 2-2) 0xE050 <== 0x08 Cr first : CrY CbY CrY CbY 00
+ 2-3) 0xE050 <== 0x0B Y first Cb: YCb YCr YCb YCr 11
+ 2-4) 0xE050 <== 0x09 Y first Cr: YCr YCb YCr Ycb 01
+==========================================================*/
+ printk( "\n %s 0x%x \n", __func__, mode);
+ //CoreISP3_I2C_Read(0xE050); // [7:7] rw 0x00 INVVSC Invert CVS (VSYNC) output
+ CoreISP3_I2C_Write(0xE050, mode);
+
+}
+
+void CoreISP3_PCLK_Inv(void)
+{
+ ClSint_16 reg_data = 0;
+
+ reg_data = CoreISP3_I2C_Read(OutFmt); // PCLK invert
+ CoreISP3_I2C_Write(OutFmt, (reg_data | 0x20));
+ printk( "reg_data 0x%x\n", reg_data);
+
+}
+
+void CoreISP3_TestPatten(void)
+{
+ printk( "\n %s \n", __func__);
+/*
+ISP3 Test Pattern
+ Address Value
+1. 0xE0C8 0x84 ( RGB value )
+2. 0xE0C8 0x85 ( Red value )
+3. 0xE0C8 0x87 ( Gray value )
+
+*///
+ //CoreISP3_I2C_Write(0xE0C8, 0x84);
+ //CoreISP3_I2C_Write(0xE0C8, 0x85);
+ //CoreISP3_I2C_Write(0xE0C8, 0x87);
+
+}
+
+void CoreISP3_Mirror_Flip(enIsp3MIRROR_MODE mode) // added by Jacky
+{
+#if 1 // add cmd in binary
+ CoreISP3_I2C_Write(0xE628, mode);
+ CoreISP3_Send_Command(ISP3_CMD_SET_FLIP_MIRROR);
+#else
+ // For Samsung 4C1
+ CoreISP3_I2C_Write(0xE034, 0x02); //02h bit0
+ if(flag==0) // Normal
+ CoreISP3_I2C_Write(0xE036, 0x10);
+ else if(flag==1) // mirror
+ CoreISP3_I2C_Write(0xE036, 0x11);
+ else if(flag==2) // flip
+ CoreISP3_I2C_Write(0xE036, 0x12);
+ else if(flag==3) // mirror&flip
+ CoreISP3_I2C_Write(0xE036, 0x13);
+
+
+ // 0: Gr 1: Gb 2: Rg 3: Bg
+ //CoreISP3_I2C_Write(0xe300, 0x02);
+#endif
+}
+
+#ifdef EEPROM_ACCESS_ENABLE
+
+/**
+ * \brief EEPROM? ??Address?? data[]? write ?? ??
+ * \remarks
+ * MCU? ???? ?? ???? ???? ?? ??. MCU? ??? I2C? ?? ?? ??? ??? ?? ??? ??.
+ * \return
+ * void
+ * \author Lee Suk-Joo
+ * \date 2008-06-01
+ */
+int ISP3_LiteOnEEPROM_Write(int startAddress, BYTE *data, int length, void (*callbackFunc)(BYTE *data, int n, int nCount))
+{
+ BYTE devID, addrLenType, dataLenType;
+ int i=-1; // write ? ???? ?
+
+ devID = CoreISP3_I2C_Read(0xE030);
+ addrLenType = CoreISP3_I2C_Read(0xE03C);
+ dataLenType = CoreISP3_I2C_Read(0xE031);
+
+ CoreISP3_I2C_Write(0xE03C, 0x07); //# For 2Byte Length Address (it's Upper Address) - 0x05: 2Byte address, 0x07: 1Byte address
+ CoreISP3_I2C_Write(0xE031, 0x51); //# IicMode1 - 0x51 : 1Byte data, 0x52 : 2Byte data
+
+ // for(i=0; i<length; i+=2)
+ for(i=0; i<length; i++)
+ {
+ U16 addr = startAddress+i;
+
+ CoreISP3_I2C_Write(0xE030, DEV_ID | (addr>>8)&1);
+ CoreISP3_I2C_Write(0xE034, (addr)&0xFF);
+ CoreISP3_I2C_Write(0xE036, data[i]);
+
+ if(callbackFunc != NULL)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ //WaitTime_us(2*10);
+ WaitTime_us(2*300);
+ }
+ }
+ CoreISP3_I2C_Write(0xE030, devID);
+ CoreISP3_I2C_Write(0xE03C, addrLenType);
+ CoreISP3_I2C_Write(0xE031, dataLenType);
+
+ return i;
+}
+
+
+
+/**
+ * \brief EEPROM? ??Address?? data[]? read ?? ??
+ * \remarks
+ * MCU? ???? ?? ???? ???? ?? ??.
+ * \return
+ * void
+ * \author Lee Suk-Joo
+ * \date 2008-06-01
+ */
+int ISP3_LiteOnEEPROM_Read(int startAddress, BYTE *data, int length, void (*callbackFunc)(BYTE *data, int n, int nCount))
+{
+ BYTE devID, addrLenType, dataLenType;
+ int i=-1; // read ? ???? ?
+
+ devID = CoreISP3_I2C_Read(0xE030);
+ addrLenType = CoreISP3_I2C_Read(0xE03C);
+ dataLenType = CoreISP3_I2C_Read(0xE031);
+
+ CoreISP3_I2C_Write(0xE03C, 0x07); //# For 2Byte Length Address (it's Upper Address) - 0x05: 2Byte address, 0x07: 1Byte address
+ CoreISP3_I2C_Write(0xE031, 0x51); //# IicMode1 - 0x51 : 1Byte data, 0x52 : 2Byte data
+
+ // for(i=0; i<length; i+=2)
+ for(i=0; i<length; i++)
+ {
+ U16 addr = startAddress+i;
+ CoreISP3_I2C_Write(0xE030, DEV_ID | (((addr>>8)&0x1)<<1));
+
+ CoreISP3_I2C_Write(0xE034, addr&0xFF);
+ // data[i] = ISP3_RegRead(0xE035);
+ // data[i+1] = ISP3_RegRead(0xE036);
+ // data[i] = ISP3_RegRead(0xE035);
+ // data[i+1] = ISP3_RegRead(0xE036);
+ data[i] = CoreISP3_I2C_Read(0xE036);
+ data[i] = CoreISP3_I2C_Read(0xE036);
+ /*
+ ISP3_RegWrite(0xE034, addr&0xFF);
+ // data[i] = ISP3_RegRead(0xE035);
+ // data[i+1] = ISP3_RegRead(0xE036);
+ // data[i] = ISP3_RegRead(0xE035);
+ // data[i+1] = ISP3_RegRead(0xE036);
+ data[i] = ISP3_RegRead(0xE036);
+ data[i] = ISP3_RegRead(0xE036);
+ */
+ if(callbackFunc != NULL)
+ {
+ callbackFunc(data, i, length);
+ }
+ else
+ {
+ WaitTime_us(2*10);
+ WaitTime_us(2*300);
+ }
+ }
+ CoreISP3_I2C_Write(0xE030, devID);
+ CoreISP3_I2C_Write(0xE03C, addrLenType);
+ CoreISP3_I2C_Write(0xE031, dataLenType);
+
+ return i;
+}
+
+
+void EEPROM_Tes_Func(void)
+{
+ BYTE tempdata[3300];
+ int i;
+
+ for(i=0;i<3300;i++)
+ tempdata[i] = 0xFF;
+
+ #if 1
+ ISP3_LiteOnEEPROM_Write(0, LSC_INIT_TABLE, 0x200, NULL);
+ WaitTime_us(2*2000);
+ #endif
+
+ #if 1
+ ISP3_LiteOnEEPROM_Read(0, tempdata, 0x200, Cl_Null);
+ WaitTime_us(2*2000);
+ for(i=0;i<0x200;i++)
+ {
+ if(LSC_INIT_TABLE[i] != tempdata[i])
+ {
+ printk( "1. ERROR data[%x] : %x :: %x\n", i, tempdata[i], LSC_INIT_TABLE[i]);
+ return;
+ }
+ //else
+ //printk( "1. OK data[%x] =%x :: LSC_INIT_TABLE[%d]=%x\n", i, data[i+1], i, LSC_INIT_TABLE[i]);
+ }
+ printk( ">>>>>>>>>>>>>>>>>> 1. OK\n");
+ #endif
+
+ #if 0
+ ISP3_LiteOnEEPROM_Write(0x100, LSC_INIT_TABLE, 0x100, NULL);
+ WaitTime_us(2*2000);
+ ISP3_LiteOnEEPROM_Read(0x100, data, 0x100, Cl_Null);
+ WaitTime_us(2*2000);
+ for(i=0x100;i<0xfd;i++)
+ {
+ if(LSC_INIT_TABLE[i] != data[i+1])
+ {
+ printk( "2. ERROR data[%x] : %x :: %x\n", i, data[i+1], LSC_INIT_TABLE[i]);
+ return;
+ }
+ //else
+ //printk( "2. OK data[%x] =%x :: LSC_INIT_TABLE[%d]=%x\n", i, data[i+1], i, LSC_INIT_TABLE[i]);
+ }
+ printk( ">>>>>>>>>>>>>>>>>> 2. OK\n");
+ #endif
+
+}
+#endif
+
+
+
+#ifdef ISP3_ZOOM_ENABLE
+ClUint_16 ispOutputWidth;
+ClUint_16 ispOutputHeight;
+ClUint_16 sensorOutputWidth;
+ClUint_16 sensorOutputHeight;
+// Jacky add this for zoom capture
+ClUint_16 ispCaptureOutputWidth; // this is capture resolution
+ClUint_16 ispCaptureOutputHeight;
+ClUint_16 sensorCaptureOutputWidth = 2560; // 5M is 2560x1920
+ClUint_16 sensorCaptureOutputHeight = 1920; // 2M is 1600x1200
+//end
+
+#ifdef DEFINE_FLOAT
+float zoomStepSize = 0.1f;
+float g_curDigitalZoomRate = 1.0f;
+#endif
+
+
+#ifndef ISP3_EVB_ENABLE
+#define ROUND(d) ((d) > 0.0 ? (int) ((d) + 0.5) : -(int) ((-(d)) + 0.5))
+#endif
+
+void ISP3_RegWrite_Partial( ClUint_16 addr, ClUint_16 data2, ClUint_16 data1, ClUint_16 data0)
+{
+ CoreISP3_I2C_Partial_Write(addr, data2, data1, data0);
+
+}
+
+int ISP3_RegRead(ClUint_16 addr)
+{
+ return (int)CoreISP3_I2C_Read(addr);
+}
+
+
+
+void ISP3_Set_StillWindowsStartX(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinXStrH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinXStrH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinXStrL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinXStrL, nLow);
+}
+
+void ISP3_Set_StillWindowsStartY(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinYStrH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinYStrH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinYStrL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinYStrL, nLow);
+}
+
+void ISP3_Set_StillWindowsWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinWidthH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinWidthH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinWidthL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinWidthL, nLow);
+}
+
+void ISP3_Set_StillWindowsHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinHeightH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinHeightH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_WinHeightL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_WinHeightL, nLow);
+}
+
+void ISP3_Set_ScaleInputWindowsWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclWidthIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclWidthIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclWidthIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclWidthIL, nLow);
+}
+
+void ISP3_Set_ScaleInputWindowsHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclHeightIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclHeightIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclHeightIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclHeightIL, nLow);
+}
+
+void ISP3_Set_ScaleOutputWindowsWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclWidthOH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclWidthOH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclWidthOL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclWidthOL, nLow);
+}
+
+void ISP3_Set_ScaleOutputWindowsHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclHeightOH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclHeightOH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Still_SclHeightOL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Still_SclHeightOL, nLow);
+}
+
+void ISP3_Set_JpegWindowsWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(JpgWidthH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(JpgWidthH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(JpgWidthL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(JpgWidthL, nLow);
+}
+
+void ISP3_Set_JpegWindowsHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(JpgHeightH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(JpgHeightH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(JpgHeightL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(JpgHeightL, nLow);
+}
+
+void ISP3_Set_ThumbnailScaleInputWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Thu_SclWidthIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Thu_SclWidthIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Thu_SclWidthIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Thu_SclWidthIL, nLow);
+}
+
+void ISP3_Set_ThumbnailScaleInputHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Thu_SclHeightIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Thu_SclHeightIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Thu_SclHeightIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Thu_SclHeightIL, nLow);
+}
+
+void ISP3_Set_ScalePreviewWindowsInputWidth(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Pre_SclWidthIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Pre_SclWidthIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Pre_SclWidthIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Pre_SclWidthIL, nLow);
+}
+
+void ISP3_Set_ScalePreviewWindowsInputHeight(ClUint_16 nData)
+{
+ ClUint_8 nHigh, nLow, nTemp;
+ nHigh = nData>>8;
+ nLow = nData&0xFF;
+ printk( "====> %s, nData: %d \n", __func__, nData);
+
+ nTemp = CoreISP3_I2C_Write(Pre_SclHeightIH, nHigh);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Pre_SclHeightIH, nHigh);
+
+ nTemp = CoreISP3_I2C_Write(Pre_SclHeightIL, nLow);
+ //if (nTemp < 0) CoreISP3_I2C_Write(Pre_SclHeightIL, nLow);
+}
+
+/**
+ * \brief Set Zoom for ISP3
+ * \remarks
+ * Change Digital Zoom rate
+ * \return
+ * Changed Digital Zoom rate
+ * \author Lee Suk-Joo
+ * \date 2008-06-01
+ */
+ #if 0
+//float ISP3_ZoomScaleSet(int sensorOutputWidth, int sensorOutputHeight, float zoomRate, int *outputWidth, int *outputHeight)
+float ISP3_ZoomScaleSet(UINT sensorOutputWidth, UINT sensorOutputHeight, float zoomRate)
+{
+ RETAILMSG(DBMSG, (TEXT(" CAM!++ ISP3_ZoomScaleSet.\r\n")));
+ ISP3_WriteCmd(ISP3_CMD_AE_OFF); // AE OFF
+
+ clIIC_WriteReg_Partial_ISP3(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+// Sleep(500);
+
+ if(zoomRate <= ZOOMRATE_1X)
+ {
+ //// Downscaling ////
+ //UINT width = ROUND(sensorOutputWidth * zoomRate);
+ //UINT height = ROUND(sensorOutputHeight * zoomRate);
+ UINT width = (UINT)((float)sensorOutputWidth * zoomRate);
+ UINT height = (UINT)((float)sensorOutputHeight * zoomRate);
+ RETAILMSG(DBMSG, (TEXT(" CAM!Downscaling,sensorOutputWidth = %d,sensorOutputHeight = %d.preview output width =%d,height = %d\r\n"),sensorOutputWidth,sensorOutputHeight,width,height));
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ clIIC_WriteReg_Partial_ISP3(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+/*
+ ///// SensorÀÇ Frame Length¸¦ ³ÐÈù´Ù.
+*/
+
+ ISP3_Set_StillWindowsStartX(0);
+ ISP3_Set_StillWindowsStartY(0);
+ ISP3_Set_StillWindowsWidth((int)sensorOutputWidth);
+ ISP3_Set_StillWindowsHeight((int)sensorOutputHeight);
+ ISP3_Set_ScaleInputWindowsWidth((int)sensorOutputWidth);
+ ISP3_Set_ScaleInputWindowsHeight((int)sensorOutputHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(width);
+ ISP3_Set_ScaleOutputWindowsHeight(height);
+ ISP3_Set_JpegWindowsWidth(width);
+ ISP3_Set_JpegWindowsHeight(height);
+ ISP3_Set_ThumbnailScaleInputWidth(width);
+ ISP3_Set_ThumbnailScaleInputHeight(height);
+ ISP3_Set_ScalePreviewWindowsInputWidth(width);
+ ISP3_Set_ScalePreviewWindowsInputHeight(height);
+
+ //*outputWidth = width;
+ //*outputHeight = height;
+ }
+ else
+ {
+ // Upscaling
+ UINT startPosDiffx, startPosDiffy;
+
+ //UINT width = ROUND(sensorOutputWidth / zoomRate);
+ //UINT height = ROUND(sensorOutputHeight / zoomRate);
+ UINT width = (UINT)((float)sensorOutputWidth / zoomRate);
+ UINT height = (UINT)((float)sensorOutputHeight / zoomRate);
+
+ RETAILMSG(DBMSG, (TEXT(" CAM!Downscaling,sensorOutputWidth = %d,sensorOutputHeight = %d.preview output width =%d,height = %d\r\n"),width,height,sensorOutputWidth, sensorOutputHeight));
+
+ int valueOfE059 = CoreISP3_I2C_Read(0xE059);
+ if(valueOfE059 & 0x01)
+ {
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+
+ clIIC_WriteReg_Partial_ISP3(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+/*
+ clIIC_Write(0xE033, 0x03);
+ clIIC_Write(0xE034, 0x42);
+ clIIC_Write(0xE035, 0x20);
+ clIIC_Write(0xE036, 0x00);
+*/
+
+ if(zoomRate > 2.0f)
+ {
+ CoreISP3_I2C_Write(0xEDE2, 0x0004);
+ }
+/*
+ if(g_curDigitalZoomRate == 1.0f)
+ {
+ clIIC_Write(0xE013, 0x0021);
+ clIIC_WriteReg_Partial_ISP3(0xE014, 3, 0, 0x02);
+ clIIC_Write(0xED27, 0x0001);
+ clIIC_Write(0xEDE2, 0x0003);
+// clIIC_Write(0xE012, 0x0001);
+
+ ///// SensorÀÇ Frame Length¸¦ ³ÐÈù´Ù.
+ }
+*/
+ startPosDiffx = ((int)sensorOutputWidth - width)/2;
+ startPosDiffy = ((int)sensorOutputHeight - height)/2;
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(width);
+ ISP3_Set_StillWindowsHeight(height);
+ ISP3_Set_ScaleInputWindowsWidth(width);
+ ISP3_Set_ScaleInputWindowsHeight(height);
+ ISP3_Set_ScaleOutputWindowsWidth((int)sensorOutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight((int)sensorOutputHeight);
+ ISP3_Set_JpegWindowsWidth((int)sensorOutputWidth);
+ ISP3_Set_JpegWindowsHeight((int)sensorOutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth((int)sensorOutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight((int)sensorOutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth((int)sensorOutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight((int)sensorOutputHeight);
+
+ //*outputWidth = width;
+ //*outputHeight = height;
+ }
+
+ clIIC_WriteReg_Partial_ISP3(0xE010, 7, 7, 1); // Sensor 1 Input off
+
+ ISP3_WriteCmd(ISP3_CMD_AE_ON); // AE ON
+
+ return zoomRate;
+ RETAILMSG(DBMSG, (TEXT(" CAM!-- ISP3_ZoomScaleSet.\r\n")));
+}
+
+// 1280*960 (640*480) -> 1280*960
+void Zoom1M_2X()
+{
+ ISP3_ZoomScaleSet(1280, 960, 2.0f);
+}
+#endif
+
+//crop and downscale image for preview
+// for 480x320 hisense
+void ISP3_HVGA_PreviewZoomScaleSet(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom)
+{
+ unsigned int startPosDiffx, startPosDiffy,nWidth,nHeight;
+ int width;
+ int height;
+ int valueOfE059;
+
+ sensorOutputWidth = 1280; // Jacky for test
+ sensorOutputHeight = 960;
+ ispOutputWidth = 480; // 240 //
+ ispOutputHeight = 320; // 160 //
+
+ printk( "Scl Window[%d %d %d %d] \n", CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL)
+ , CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL)
+ , CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL)
+ , CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL)
+ );
+
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+
+ switch(dwZoom)
+ {
+ case CAM_ZOOM_125X:
+ {
+ width = 1272; //²Ã¼ôºóµÄ´óС
+ height = 848;
+ break;
+ }
+ case CAM_ZOOM_150X: // 1.6
+ {
+ width = 751; //²Ã¼ôºóµÄ´óС,640/1.6 = 400
+ height = 530;
+ break;
+ }
+ case CAM_ZOOM_200X: // only this scale ok
+ {
+ width = 1272/2; // 636 //²Ã¼ôºóµÄ´óС
+ height = 848/2; // 424
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ width = 1272; //²Ã¼ôºóµÄ´óС
+ height = 848;
+ break;
+ }
+ case CAM_ZOOM_VP:
+ {
+ //width = 1056; //²Ã¼ôºóµÄ´óС,CIF*3 for 5M camera VP
+ //height = 864;
+ break;
+ }
+ case CAM_ZOOM_100X:
+ default: //%100
+ {
+ width = 1272; //
+ height = 848; //
+ break;
+ }
+ }
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+ startPosDiffx = (sensorOutputWidth - width)/2;
+ startPosDiffy = (sensorOutputHeight - height)/2;
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(width);
+ ISP3_Set_StillWindowsHeight(height);
+ ISP3_Set_ScaleInputWindowsWidth(width);
+ ISP3_Set_ScaleInputWindowsHeight(height);
+
+ ISP3_Set_ScaleOutputWindowsWidth(ispOutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(ispOutputHeight);
+ ISP3_Set_JpegWindowsWidth(ispOutputWidth);
+ ISP3_Set_JpegWindowsHeight(ispOutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(ispOutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(ispOutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(ispOutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(ispOutputHeight);
+
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 1); // Sensor 1 Input off
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+ printk( " %s %dx%d, zoom: %d \n",__func__, OutputWidth, OutputHeight, dwZoom);
+
+
+}
+
+void ISP3_VGA_PreviewZoomScaleSet(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom)
+{
+ unsigned int startPosDiffx, startPosDiffy,nWidth,nHeight;
+
+ printk( " %s %dx%d, zoom: %d \n",__func__, OutputWidth, OutputHeight, dwZoom);
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+ //Sleep(500);
+ switch(dwZoom)
+ {
+ case CAM_ZOOM_100X:
+ {
+ nWidth = 640;
+ nHeight = 480;
+ break;
+ }
+ case CAM_ZOOM_125X:
+ {
+ nWidth = 512; //²Ã¼ôºóµÄ´óС
+ nHeight = 384;
+ break;
+ }
+ case CAM_ZOOM_150X: // 1.6
+ {
+ nWidth = 400; //²Ã¼ôºóµÄ´óС,640/1.6 = 400
+ nHeight = 300;
+ break;
+ }
+ case CAM_ZOOM_200X: // only this scale ok
+ {
+ nWidth = 320; //²Ã¼ôºóµÄ´óС
+ nHeight = 240;
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ nWidth = 256; //²Ã¼ôºóµÄ´óС
+ nHeight = 192;
+ break;
+ }
+ case CAM_ZOOM_VP:
+ {
+ //nWidth = 1056; //²Ã¼ôºóµÄ´óС,CIF*3 for 5M camera VP
+ //nHeight = 864;
+ break;
+ }
+ default: //%100
+ {
+ nWidth = 640;
+ nHeight = 480;
+ break;
+ }
+ }
+
+ startPosDiffx = (640 - nWidth)/2;
+ startPosDiffy = (480 - nHeight)/2;
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(nWidth); // width
+ ISP3_Set_StillWindowsHeight(nHeight);
+ ISP3_Set_ScaleInputWindowsWidth(nWidth);
+ ISP3_Set_ScaleInputWindowsHeight(nHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(OutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(OutputHeight);
+
+ ISP3_Set_JpegWindowsWidth(OutputWidth);
+ ISP3_Set_JpegWindowsHeight(OutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(OutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(OutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(OutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(OutputHeight);
+
+ //Sleep(500);
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 1); // Sensor 1 Input on
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+
+}
+
+
+//crop and downscale image for preview
+void ISP3_PreviewZoomScaleSet(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom)
+{
+ unsigned int startPosDiffx, startPosDiffy,nWidth,nHeight;
+
+ printk( " %s %dx%d, zoom: %d \n",__func__, OutputWidth, OutputHeight, dwZoom);
+
+ //CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+ //Sleep(500);
+ switch(dwZoom)
+ {
+ case CAM_ZOOM_100X:
+ {
+ nWidth = 1280;
+ nHeight = 960;
+ break;
+ }
+ case CAM_ZOOM_125X:
+ {
+ nWidth = 1024; //²Ã¼ôºóµÄ´óС
+ nHeight = 768;
+ break;
+ }
+ case CAM_ZOOM_150X:
+ {
+ nWidth = 864; //²Ã¼ôºóµÄ´óС,1280/864 = 1.48
+ nHeight = 648; //960/648 = 1.48
+ break;
+ }
+ case CAM_ZOOM_200X: // 2X
+ {
+ nWidth = 640; //²Ã¼ôºóµÄ´óС
+ nHeight = 480;
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ nWidth = 512; //²Ã¼ôºóµÄ´óС
+ nHeight = 384;
+ break;
+ }
+ case CAM_ZOOM_VP:
+ {
+ nWidth = 1056; //²Ã¼ôºóµÄ´óС,CIF*3 for 5M camera VP
+ nHeight = 864;
+ break;
+ }
+ default: //%100
+ {
+ nWidth = 1280;
+ nHeight = 960;
+ break;
+ }
+ }
+
+ startPosDiffx = (1280 - nWidth)/2;
+ startPosDiffy = (960 - nHeight)/2;
+
+ /* can not disable tollowing code */
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(nWidth);
+ ISP3_Set_StillWindowsHeight(nHeight);
+ ISP3_Set_ScaleInputWindowsWidth(nWidth);
+ ISP3_Set_ScaleInputWindowsHeight(nHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(OutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(OutputHeight);
+/*
+ ISP3_Set_JpegWindowsWidth(OutputWidth);
+ ISP3_Set_JpegWindowsHeight(OutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(OutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(OutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(OutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(OutputHeight);
+*/
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 1); // Sensor 1 Input on
+
+ //CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+
+}
+
+//crop and downscale image for preview
+void ISP3_CaptureZoomScaleSet(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom)
+{
+ unsigned int startPosDiffx, startPosDiffy,nWidth,nHeight;
+
+ sensorOutputWidth = 2560; //
+ sensorOutputHeight = 1920;
+
+ ispCaptureOutputWidth = 2560;
+ ispCaptureOutputWidth = 1920;
+
+ ispOutputWidth = 2560; // 240 //
+ ispOutputHeight = 1920; // 160 //
+
+ printk( " %s %dx%d, zoom: %d \n",__func__, OutputWidth, OutputHeight, dwZoom);
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+ //Sleep(500);
+ switch(dwZoom)
+ {
+ case CAM_ZOOM_100X:
+ {
+ nWidth = sensorOutputWidth;
+ nHeight = sensorOutputHeight;
+ break;
+ }
+ case CAM_ZOOM_125X:
+ {
+ nWidth = sensorOutputWidth*4/5; //²Ã¼ôºóµÄ´óС
+ nHeight = sensorOutputHeight*4/5;
+ break;
+ }
+ case CAM_ZOOM_150X: // 1.6
+ {
+ nWidth = sensorOutputWidth*4/5; //²Ã¼ôºóµÄ´óС
+ nHeight = sensorOutputHeight*4/5;
+ break;
+ }
+ case CAM_ZOOM_200X:
+ {
+ nWidth = sensorOutputWidth/2; //²Ã¼ôºóµÄ´óС
+ nHeight = sensorOutputHeight/2;
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ nWidth = sensorOutputWidth*2/5; //²Ã¼ôºóµÄ´óС
+ nHeight = sensorOutputWidth*2/5;
+ break;
+ }
+ case CAM_ZOOM_VP:
+ {
+ nWidth = 1056; //²Ã¼ôºóµÄ´óС,CIF*3 for 5M camera VP
+ nHeight = 864;
+ break;
+ }
+ default: //%100
+ {
+ nWidth = 1280;
+ nHeight = 960;
+ break;
+ }
+ }
+
+ startPosDiffx = (2560 - nWidth)/2;
+ startPosDiffy = (1920 - nHeight)/2;
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(nWidth);
+ ISP3_Set_StillWindowsHeight(nHeight);
+ ISP3_Set_ScaleInputWindowsWidth(nWidth);
+ ISP3_Set_ScaleInputWindowsHeight(nHeight);
+
+ ISP3_Set_ScaleOutputWindowsWidth(OutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(OutputHeight);
+ ISP3_Set_JpegWindowsWidth(OutputWidth);
+ ISP3_Set_JpegWindowsHeight(OutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(OutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(OutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(OutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(OutputHeight);
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 1); // Sensor 1 Input on
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+}
+
+void ISP3_PreviewZoomScaleSet_YuLong(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom)
+{
+ unsigned int startPosDiffx, startPosDiffy,nWidth,nHeight;
+
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+ //Sleep(500);
+ switch(dwZoom)
+ {
+ case CAM_ZOOM_100X:
+ {
+ nWidth = 1280;
+ nHeight = 960;
+ break;
+ }
+ case CAM_ZOOM_125X:
+ {
+ nWidth = 1024; //²Ã¼ôºóµÄ´óС
+ nHeight = 768;
+ break;
+ }
+ case CAM_ZOOM_150X:
+ {
+ nWidth = 864; //²Ã¼ôºóµÄ´óС,1280/864 = 1.48
+ nHeight = 648; //960/648 = 1.48
+ break;
+ }
+ case CAM_ZOOM_200X:
+ {
+ nWidth = 640; //²Ã¼ôºóµÄ´óС
+ nHeight = 480;
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ nWidth = 512; //²Ã¼ôºóµÄ´óС
+ nHeight = 384;
+ break;
+ }
+ case CAM_ZOOM_VP:
+ {
+ nWidth = 1056; //²Ã¼ôºóµÄ´óС,CIF*3 for 5M camera VP
+ nHeight = 864;
+ break;
+ }
+ default: //%100
+ {
+ nWidth = 1280;
+ nHeight = 960;
+ break;
+ }
+ }
+
+ startPosDiffx = (1280 - nWidth)/2;
+ startPosDiffy = (960 - nHeight)/2;
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+/* if(nWidth >= OutputWidth) //downscale
+ {
+ RETAILMSG(DEBUG_INFOR, (TEXT(" CAM!downscale.\r\n")));
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+ }
+ else //upscale
+ {
+ RETAILMSG(DEBUG_INFOR, (TEXT(" CAM!upscale.\r\n")));
+ int valueOfE059 = CoreISP3_I2C_Read(0xE059);
+ if(valueOfE059 & 0x01)
+ {
+ RETAILMSG(DEBUG_INFOR, (TEXT(" CAM!CoreISP3_I2C_Write(0xE013, 0x0021);.\r\n")));
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ RETAILMSG(DEBUG_INFOR, (TEXT(" CAM!CoreISP3_I2C_Write(0xE013, 0x0022);.\r\n")));
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+ }
+*/
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(nWidth);
+ ISP3_Set_StillWindowsHeight(nHeight);
+ ISP3_Set_ScaleInputWindowsWidth(nWidth);
+ ISP3_Set_ScaleInputWindowsHeight(nHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(OutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(OutputHeight);
+ ISP3_Set_JpegWindowsWidth(OutputWidth);
+ ISP3_Set_JpegWindowsHeight(OutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(OutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(OutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(OutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(OutputHeight);
+
+ //Sleep(500);
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 1); // Sensor 1 Input on
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+
+}
+//crop and downscale image for capture
+void ISP3_ImageCrop(unsigned int sensorOutputWidth, unsigned int sensorOutputHeight,unsigned int CropedWidth,unsigned int CropedHeight, unsigned int OutputWidth,unsigned int OutputHeight)
+{
+ unsigned int startPosDiffx, startPosDiffy;
+ int valueOfE059;
+
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 0); // Sensor 1 Input off
+ WaitTime_us(2*50*1000);
+
+ startPosDiffx = (sensorOutputWidth - CropedWidth)/2;
+ startPosDiffy = (sensorOutputHeight - CropedHeight)/2;
+
+ printk( " %s %dx%d \n",__func__, startPosDiffx, startPosDiffy);
+
+ #if 1 // for JPEG zoom capture must use following code...test ok
+ valueOfE059 = ISP3_RegRead(0xE059);
+
+ printk( " 0xe059: 0x%x \n", valueOfE059);
+ if(valueOfE059 & 0x01)
+ {
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+
+ //if(zoomRate > 2.0f)
+ {
+ //CoreISP3_I2C_Write(0xEDE2, 0x0004);
+ }
+ #else// jacky open this for test ok
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+ #endif
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(CropedWidth);
+ ISP3_Set_StillWindowsHeight(CropedHeight);
+ ISP3_Set_ScaleInputWindowsWidth(CropedWidth);
+ ISP3_Set_ScaleInputWindowsHeight(CropedHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(OutputWidth);
+ ISP3_Set_ScaleOutputWindowsHeight(OutputHeight);
+ // following code need for jpeg
+ ISP3_Set_JpegWindowsWidth(OutputWidth);
+ ISP3_Set_JpegWindowsHeight(OutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(OutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(OutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(OutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(OutputHeight);
+/**/
+ WaitTime_us(2*50);
+ CoreISP3_I2C_Partial_Write(0xE010, 7, 7, 1); // Sensor 1 Input on
+
+}
+
+void ISP3_ZoomInit(void)
+{
+ int upscaleStepCount;
+ int downscaleStepCount;
+
+ #ifdef ISP3_EVB_ENABLE
+ printk( "====> %s, [%dx%d]\n", __func__, g_Isp3SensorInfo.width, g_Isp3SensorInfo.height);
+
+ sensorOutputWidth = CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL);
+ sensorOutputHeight = CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL);
+ ispOutputWidth = CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL);
+ ispOutputHeight= CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL);
+ #else
+ sensorOutputWidth = CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL);
+ sensorOutputHeight = CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL);
+ ispOutputWidth = CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL);
+ ispOutputHeight= CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL);
+ #endif
+ printk( "====> %s, I[%d %d]->O[%d %d]\n", __func__, sensorOutputWidth, sensorOutputHeight, ispOutputWidth, ispOutputHeight);
+
+ #ifdef DEFINE_FLOAT
+ zoomStepSize = 0.1f;
+ // SlideBar ÀÇ Range´Â 0 ~ upscaleStepCount + downscaleStepCount ÀÌ µÈ´Ù.
+ g_curDigitalZoomRate = 1.0f;
+ #endif
+
+}
+
+void Yulong_TestZoom(void)
+{
+#ifdef DEFINE_FLOAT
+ printk( "====> %s \n", __func__);
+ /////////////////////////////////////
+ // Zoom In Full mode
+ /////////////////////////////////////
+ CoreISP3_SetResolution(enISP_RES_5MP_FULL , CMD_Preview);
+
+ sensorOutputWidth = 2560;
+ sensorOutputHeight = 1920;
+ ispOutputWidth = 2560;
+ ispOutputHeight = 1920;
+/////// up scaleing /////////
+ ISP3_SetDigitalZoomRate((float)2560/(float)1280); // 2.0
+ ISP3_SetDigitalZoomRate((float)2560/(float)1600); // 1.6
+ ISP3_SetDigitalZoomRate((float)2560/(float)2048); // 1.25
+ ISP3_SetDigitalZoomRate((float)2560/(float)2560); // 1.0
+
+/////// down scaleing /////////
+ ISP3_SetDigitalZoomRate((float)2048/(float)2560);
+ ISP3_SetDigitalZoomRate((float)1600/(float)2560);
+ ISP3_SetDigitalZoomRate((float)1280/(float)2560);
+ ISP3_SetDigitalZoomRate((float)1024/(float)2560);
+ ISP3_SetDigitalZoomRate((float)800/(float)2560);
+ ISP3_SetDigitalZoomRate((float)640/(float)2560);
+ ISP3_SetDigitalZoomRate((float)320/(float)2560);
+ ISP3_SetDigitalZoomRate((float)160/(float)2560);
+
+ /////////////////////////////////////
+ // Zoom In Preview mode
+ /////////////////////////////////////
+ //CoreISP3_SetResolution(ISP3_CMD_PREVIEW, CMD_Preview);
+ CoreISP3_SetResolution(enISP_RES_5MP_FULL, CMD_Preview); // Jacky change this
+
+ sensorOutputWidth = 1280;
+ sensorOutputHeight = 960;
+ ispOutputWidth = 1280;
+ ispOutputHeight = 960;
+
+/////// up scaleing /////////
+ ISP3_SetDigitalZoomRate((float)1280/(float)640); // 2.0
+ ISP3_SetDigitalZoomRate((float)1280/(float)800);
+ ISP3_SetDigitalZoomRate((float)1280/(float)1024);
+ ISP3_SetDigitalZoomRate((float)1280/(float)1280); // 1.0
+
+/////// down scaleing /////////
+ ISP3_SetDigitalZoomRate((float)1024/(float)1280);
+ ISP3_SetDigitalZoomRate((float)800/(float)1280);
+ ISP3_SetDigitalZoomRate((float)640/(float)1280);
+ ISP3_SetDigitalZoomRate((float)320/(float)1280);
+ ISP3_SetDigitalZoomRate((float)160/(float)1280);
+
+ /////////////////////////////////////
+ // Zoom In VGA mode
+ /////////////////////////////////////
+ CoreISP3_SetResolution(enISP_RES_VGA, CMD_Preview); // Jacky change this
+
+ sensorOutputWidth = 640;
+ sensorOutputHeight = 480;
+ ispOutputWidth = 640;
+ ispOutputHeight = 480;
+
+/////// up scaleing /////////
+ ISP3_SetDigitalZoomRate((float)640/(float)320); // 2.0
+ ISP3_SetDigitalZoomRate((float)640/(float)640); // 1.0
+
+/////// down scaleing /////////
+ ISP3_SetDigitalZoomRate((float)320/(float)640); // 0.5
+ ISP3_SetDigitalZoomRate((float)160/(float)640); // 0.25
+#endif
+}
+
+/*
+
+1280x960 (1272*848) -> 480x320
+//(1280-1272)/2 = 4
+//(960-848)/2 = 56
+
+OPPO request
+ ¸ß¿í±ÈÀýΪ5£º3 //¿ÉÒÔʵÏÖ£¬Corelogic·½ÕùÈ¡¾¡ÔçÍê³É
+ 800*480
+ 1600*960
+ 2048*1228
+ 2560*1536
+
+*/
+
+void ISP3_SetDigitalZoom(CAM_ZOOM_T rate) // for 480x320 resolution
+{
+ int width;
+ int height;
+ int startPosDiffx, startPosDiffy;
+ int valueOfE059;
+
+ //Image scaling: 1/32 ~ 2x linear (area 4x)
+
+ sensorOutputWidth = 1280; // Jacky for test
+ sensorOutputHeight = 960;
+ ispOutputWidth = 480; // 240 //
+ ispOutputHeight = 320; // 160 //
+
+ printk( "ISP3_SetDigitalZoom Scl Window[%d %d %d %d] \n", CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL)
+ , CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL)
+ , CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL)
+ , CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL)
+ );
+
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+
+ {
+ // Upscaling
+ switch(rate)
+ {
+ case CAM_ZOOM_125X:
+ {
+ width = 1272-120; // 1152 //²Ã¼ôºóµÄ´óС
+ height = 848-80; // 768
+ break;
+ }
+ case CAM_ZOOM_150X: // 1.6
+ {
+ width = 751; //²Ã¼ôºóµÄ´óС,640/1.6 = 400
+ height = 530;
+ break;
+ }
+ case CAM_ZOOM_200X: // only this scale ok
+ {
+ width = 1272/2; // 636 //²Ã¼ôºóµÄ´óС
+ height = 848/2; // 424
+ break;
+ }
+ case CAM_ZOOM_250X:
+ {
+ width = 636-30; // 606 //²Ã¼ôºóµÄ´óС
+ height = 424-20; // 404
+ break;
+ }
+ case CAM_ZOOM_400X:
+ {
+ width = 480;
+ height = 320;
+ break;
+ }
+ // Image scaling: 1/32 ~ 2x linear (area 4x)
+ case CAM_ZOOM_CIF:
+ {
+ ispOutputWidth = 352; // 240 // 176x144 ->88x72 ->44x36->22x18->11x9 ->110x90
+ ispOutputHeight = 288; // 160 //
+ width = 1166; // 1408x1152 - 176x144 = 1232x1008 -176x144 = 1056x864
+ height = 954; // 960
+ break;
+ }
+
+ case CAM_ZOOM_QCIF:
+ {
+ ispOutputWidth = 176; // 240 // 176x144 ->88x72 ->44x36->22x18->11x9 ->110x90
+ ispOutputHeight = 144; // 160 //
+ width = 1166; // 1408x1152 - 176x144 = 1232x1008 -176x144 = 1056x864
+ height = 954; // 960
+ break;
+ }
+ case CAM_ZOOM_480_360: // isp scale to 480x360
+ {
+ ispOutputWidth = 480;
+ ispOutputHeight = 360;
+ width = 1280;
+ height = 960;
+ break;
+ }
+ case CAM_ZOOM_480_360X1: // isp scale to 480x360
+ {
+ ispOutputWidth = 480;
+ ispOutputHeight = 360;
+ width = 1120;
+ height = 840;
+ break;
+ }
+ case CAM_ZOOM_480_360X2: // isp scale to 480x360
+ {
+ ispOutputWidth = 480;
+ ispOutputHeight = 360;
+ width = 960; //640;
+ height = 720; //480;
+ break;
+ }
+ case CAM_ZOOM_480_360X3: // isp scale to 480x360
+ {
+ ispOutputWidth = 480;
+ ispOutputHeight = 360;
+ width = 800; //520;
+ height = 600; //390;
+ break;
+ }
+ case CAM_ZOOM_480_360X4: // isp scale to 480x360
+ {
+ ispOutputWidth = 480;
+ ispOutputHeight = 360;
+ width = 640; //480;
+ height = 480; //360;
+ break;
+ }
+ case CAM_ZOOM_VGA: // isp scale to
+ {
+ ispOutputWidth = 640;
+ ispOutputHeight = 480;
+ width = 1280;
+ height = 960;
+ break;
+ }
+ case CAM_ZOOM_SVGA: // isp scale to
+ {
+ ispOutputWidth = 800;
+ ispOutputHeight = 600;
+ width = 1280;
+ height = 960;
+ break;
+ }
+ case CAM_ZOOM_1_3M: // isp scale to
+ {
+ ispOutputWidth = 1280;
+ ispOutputHeight = 960;
+ width = 1280;
+ height = 960;
+ break;
+ }
+
+ // For OPPO 5:3 resolutions
+ case CAM_ZOOM_800_480: // isp scale to
+ { // 1280x960 crop and scale down
+ ispOutputWidth = 800;
+ ispOutputHeight = 480;
+ width = 1280;
+ height = 768; // 960-768=192
+ break;
+ }
+ case CAM_ZOOM_1600_960: // isp scale to
+ { // 2560x1920 crop and scale down
+ sensorOutputWidth = 2560; // Jacky for test
+ sensorOutputHeight = 1920;
+ ispOutputWidth = 1600;
+ ispOutputHeight = 960;
+ width = 2560;
+ height = 1536; //1920-1536 = 384
+ break;
+ }
+ case CAM_ZOOM_2048_1228: // isp scale to
+ { // 2560x1920 crop and scale down
+ sensorOutputWidth = 2560; // Jacky for test
+ sensorOutputHeight = 1920;
+ ispOutputWidth = 2048;
+ ispOutputHeight = 1228; //2048*0.6 = 1228.8
+ width = 2560;
+ height = 1535; // 2560x1535->2048x1228 1920-1535=385
+ break;
+ }
+ case CAM_ZOOM_2560_1536: // isp scale to
+ { // 2560x1920 crop and scale down
+ sensorOutputWidth = 2560; // Jacky for test
+ sensorOutputHeight = 1920;
+ ispOutputWidth = 2560;
+ ispOutputHeight = 1536;
+ width = 2560;
+ height = 1536; //1920-1536 = 384
+ break;
+ }
+
+ case CAM_ZOOM_100X:
+ default: //%100
+ {
+ width = 1272; //
+ height = 848; //
+ break;
+ }
+ }
+
+ #if 1
+ valueOfE059 = ISP3_RegRead(0xE059);
+ //printk( "Upscaling [%d %d], 0xe059: 0x%x \n", width, height, valueOfE059);
+ if(valueOfE059 & 0x01)
+ {
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+ #else
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+ #endif
+
+ startPosDiffx = (sensorOutputWidth - width)/2;
+ startPosDiffy = (sensorOutputHeight - height)/2;
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(width);
+ ISP3_Set_StillWindowsHeight(height);
+ ISP3_Set_ScaleInputWindowsWidth(width);
+ ISP3_Set_ScaleInputWindowsHeight(height);
+ ISP3_Set_ScaleOutputWindowsWidth(ispOutputWidth); // Jacky change and test ok
+ ISP3_Set_ScaleOutputWindowsHeight(ispOutputHeight);
+
+ /*// following .. do not set following register, it will effect face tracking
+ ISP3_Set_JpegWindowsWidth(ispOutputWidth);
+ ISP3_Set_JpegWindowsHeight(ispOutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(ispOutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(ispOutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(ispOutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(ispOutputHeight);
+ */
+ }
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 1); // Sensor 1 Input off
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON Jacky disable this for test
+
+}
+
+
+#ifdef DEFINE_FLOAT
+float ISP3_SetDigitalZoomRate(float zoomRate)
+{
+ int width;
+ int height;
+
+ #if 0
+ sensorOutputWidth = CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL);
+ sensorOutputHeight = CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL);
+ ispOutputWidth = CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL);
+ ispOutputHeight= CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL);
+ //#else
+ sensorOutputWidth = 1280; // Jacky for test
+ sensorOutputHeight = 960;
+ ispOutputWidth = 640;
+ ispOutputHeight = 480;
+ #endif
+ printk( "Scl Window[%d %d %d %d] \n", CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL)
+ , CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL)
+ , CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL)
+ , CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL)
+ );
+
+ printk( "====> %s, rate: %d I[%d %d]->O[%d %d]\n", __func__, zoomRate, sensorOutputWidth, sensorOutputHeight, ispOutputWidth, ispOutputHeight);
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+
+ if(zoomRate <= ZOOMRATE_1X)
+ {
+ //// Downscaling ////
+
+ width = ROUND((float)sensorOutputWidth * zoomRate);
+ height = ROUND((float)sensorOutputHeight * zoomRate);
+
+ printk( "Downscaling [%d %d] \n", width, height);
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+ ISP3_Set_StillWindowsStartX(0);
+ ISP3_Set_StillWindowsStartY(0);
+ ISP3_Set_StillWindowsWidth(sensorOutputWidth);
+ ISP3_Set_StillWindowsHeight(sensorOutputHeight);
+ ISP3_Set_ScaleInputWindowsWidth(sensorOutputWidth);
+ ISP3_Set_ScaleInputWindowsHeight(sensorOutputHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(width);
+ ISP3_Set_ScaleOutputWindowsHeight(height);
+ /*
+ ISP3_Set_JpegWindowsWidth(width);
+ ISP3_Set_JpegWindowsHeight(height);
+ ISP3_Set_ThumbnailScaleInputWidth(width);
+ ISP3_Set_ThumbnailScaleInputHeight(height);
+ ISP3_Set_ScalePreviewWindowsInputWidth(width);
+ ISP3_Set_ScalePreviewWindowsInputHeight(height);
+ */
+
+ }
+ else
+ {
+ // Upscaling
+ int startPosDiffx, startPosDiffy;
+ int valueOfE059;
+
+ //width = ROUND((float)sensorOutputWidth * zoomRate); // Jacky for test
+ //height = ROUND((float)sensorOutputHeight * zoomRate);
+ width = ((float)sensorOutputWidth / zoomRate); // ROUND
+ height = ((float)sensorOutputHeight / zoomRate); //ROUND
+
+ valueOfE059 = ISP3_RegRead(0xE059);
+
+ printk( "Upscaling [%d %d], 0xe059: 0x%x \n", width, height, valueOfE059);
+ #if 1 // test ok
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+ #else// jacky open this for test ok
+ if(valueOfE059 & 0x01)
+ {
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+
+ if(zoomRate > 2.0f)
+ {
+ CoreISP3_I2C_Write(0xEDE2, 0x0004);
+ }
+ #endif
+
+ startPosDiffx = (sensorOutputWidth - width)/2;
+ startPosDiffy = (sensorOutputHeight - height)/2;
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(width);
+ ISP3_Set_StillWindowsHeight(height);
+ ISP3_Set_ScaleInputWindowsWidth(width);
+ ISP3_Set_ScaleInputWindowsHeight(height);
+ ISP3_Set_ScaleOutputWindowsWidth(ispOutputWidth); // Jacky change and test ok
+ ISP3_Set_ScaleOutputWindowsHeight(ispOutputHeight);
+ /*
+ ISP3_Set_JpegWindowsWidth(ispOutputWidth);
+ ISP3_Set_JpegWindowsHeight(ispOutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(ispOutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(ispOutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(ispOutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(ispOutputHeight);
+ */
+ }
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 1); // Sensor 1 Input off
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+ return zoomRate;
+}
+
+
+float ISP3_SetDigitalZoomRate_Face(float zoomRate, int startPosDiffx, int startPosDiffy)
+{
+ int width;
+ int height;
+
+ #if 0
+ sensorOutputWidth = 1280; // Jacky for test
+ sensorOutputHeight = 960;
+ ispOutputWidth = 640;
+ ispOutputHeight = 480;
+ #endif
+ printk( "Scl Window[%d %d %d %d] \n", CoreISP3_I2C_Read(Still_SclWidthIH)<<8|CoreISP3_I2C_Read(Still_SclWidthIL)
+ , CoreISP3_I2C_Read(Still_SclHeightIH)<<8|CoreISP3_I2C_Read(Still_SclHeightIL)
+ , CoreISP3_I2C_Read(Still_SclWidthOH)<<8|CoreISP3_I2C_Read(Still_SclWidthOL)
+ , CoreISP3_I2C_Read(Still_SclHeightOH)<<8|CoreISP3_I2C_Read(Still_SclHeightOL)
+ );
+
+ printk( "====> %s, rate%d: I[%d %d]->O[%d %d]\n", __func__, sensorOutputWidth, sensorOutputHeight, ispOutputWidth, ispOutputHeight);
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_OFF); // AE OFF
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 0); // Sensor 1 Input off - IPC ó¸® µµÁß Scale ¼ÂÆÃÀÌ º¯°æµÇ¸é ¹®Á¦°¡ ¹ß»ýµÇ¹Ç·Î
+// Sleep(500);
+
+ if(zoomRate <= ZOOMRATE_1X)
+ {
+ //// Downscaling ////
+
+ width = ROUND((float)sensorOutputWidth * zoomRate);
+ height = ROUND((float)sensorOutputHeight * zoomRate);
+
+ printk( "Downscaling [%d %d] \n", width, height);
+
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+
+ ISP3_Set_StillWindowsStartX(0);
+ ISP3_Set_StillWindowsStartY(0);
+ ISP3_Set_StillWindowsWidth(sensorOutputWidth);
+ ISP3_Set_StillWindowsHeight(sensorOutputHeight);
+ ISP3_Set_ScaleInputWindowsWidth(sensorOutputWidth);
+ ISP3_Set_ScaleInputWindowsHeight(sensorOutputHeight);
+ ISP3_Set_ScaleOutputWindowsWidth(width);
+ ISP3_Set_ScaleOutputWindowsHeight(height);
+ /*
+ ISP3_Set_JpegWindowsWidth(width);
+ ISP3_Set_JpegWindowsHeight(height);
+ ISP3_Set_ThumbnailScaleInputWidth(width);
+ ISP3_Set_ThumbnailScaleInputHeight(height);
+ ISP3_Set_ScalePreviewWindowsInputWidth(width);
+ ISP3_Set_ScalePreviewWindowsInputHeight(height);
+ */
+
+ }
+ else
+ {
+ // Upscaling
+ //int startPosDiffx, startPosDiffy;
+ int valueOfE059;
+
+ //width = ROUND((float)sensorOutputWidth * zoomRate); // Jacky for test
+ //height = ROUND((float)sensorOutputHeight * zoomRate);
+ width = ((float)sensorOutputWidth / zoomRate); // ROUND
+ height = ((float)sensorOutputHeight / zoomRate); //ROUND
+
+ #if 1 // test ok
+ CoreISP3_I2C_Write(0xE013, 0x0021); // Cis1IntD
+ CoreISP3_I2C_Partial_Write(0xE014, 3, 0, 0x02); // Cis1IntE
+ CoreISP3_I2C_Write(0xED27, 0x0001); // Still_ClkMode_Bypss
+ CoreISP3_I2C_Write(0xEDE2, 0x0003); // Mem_Type
+ CoreISP3_I2C_Write(0xE012, 0x0001);
+ #else// jacky open this for test
+ valueOfE059 = ISP3_RegRead(0xE059);
+ printk( "Upscaling [%d %d], 0xe059: 0x%x \n", width, height, valueOfE059);
+
+ if(valueOfE059 & 0x01)
+ {
+ // JPEG À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0021);
+ }
+ else
+ {
+ // YCbCr À̸é
+ CoreISP3_I2C_Write(0xE013, 0x0022);
+ }
+ ISP3_RegWrite_Partial(0xE014, 3, 0, 0x01);
+ CoreISP3_I2C_Write(0xED27, 0x0011);
+ CoreISP3_I2C_Write(0xEDE2, 0x0003);
+ CoreISP3_I2C_Write(0xE012, 0x0002);
+
+ if(zoomRate > 2.0f)
+ {
+ CoreISP3_I2C_Write(0xEDE2, 0x0004);
+ }
+ #endif
+
+ //startPosDiffx = (sensorOutputWidth - width)/2;
+ //startPosDiffy = (sensorOutputHeight - height)/2;
+
+ ISP3_Set_StillWindowsStartX(startPosDiffx);
+ ISP3_Set_StillWindowsStartY(startPosDiffy);
+ ISP3_Set_StillWindowsWidth(width);
+ ISP3_Set_StillWindowsHeight(height);
+ ISP3_Set_ScaleInputWindowsWidth(width);
+ ISP3_Set_ScaleInputWindowsHeight(height);
+ ISP3_Set_ScaleOutputWindowsWidth(ispOutputWidth); // Jacky change and test ok
+ ISP3_Set_ScaleOutputWindowsHeight(ispOutputHeight);
+ /*
+ ISP3_Set_JpegWindowsWidth(ispOutputWidth);
+ ISP3_Set_JpegWindowsHeight(ispOutputHeight);
+ ISP3_Set_ThumbnailScaleInputWidth(ispOutputWidth);
+ ISP3_Set_ThumbnailScaleInputHeight(ispOutputHeight);
+ ISP3_Set_ScalePreviewWindowsInputWidth(ispOutputWidth);
+ ISP3_Set_ScalePreviewWindowsInputHeight(ispOutputHeight);
+ */
+
+ }
+
+ ISP3_RegWrite_Partial(0xE010, 7, 7, 1); // Sensor 1 Input off
+
+ CoreISP3_Send_Command(ISP3_CMD_AE_ON); // AE ON
+
+ return zoomRate;
+}
+#endif
+
+void ISP3_SetZoomRate(enIsp3ZoomRate rate)
+{
+ //Yulong_TestZoom();
+ //ISP3_PreviewZoomScaleSet(240, 320, CAM_ZOOM_200X); // Jacky for test
+ //ISP3_PreviewZoomScaleSet(1280, 960, CAM_ZOOM_250X); // Jacky for test
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_200X); // Jacky for test
+ //ISP3_SetDigitalZoom(g_curDigitalZoom); // for HVGA 3:2 mode
+ //return;
+
+ printk( "====> %s, rate: %d \n", __func__, rate);
+ g_curDigitalZoom = rate;
+
+ switch(rate)
+ {
+ case enISP_ZOOM_RATE_1:
+ //ISP3_SetDigitalZoomRate(1.0f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_100X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_100X); // Jacky for test
+ break;
+ case enISP_ZOOM_RATE_1_25:
+ //ISP3_SetDigitalZoomRate(1.25f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_125X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_125X); // Jacky for test
+ break;
+ case enISP_ZOOM_RATE_1_5:
+ //ISP3_SetDigitalZoomRate(1.5f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_150X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_150X); // Jacky for test
+ break;
+ case enISP_ZOOM_RATE_1_75:
+ //ISP3_SetDigitalZoomRate(1.75f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_200X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_200X); // Jacky for test
+ break;
+ case enISP_ZOOM_RATE_2:
+ //ISP3_SetDigitalZoomRate(2.0f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_250X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_250X); // Jacky for test
+ break;
+ case enISP_ZOOM_RATE_2_5:
+ //ISP3_SetDigitalZoomRate(2.5f);
+ //ISP3_VGA_PreviewZoomScaleSet(640, 480, CAM_ZOOM_100X); // Jacky for test
+ ISP3_PreviewZoomScaleSet(ispOutputWidth, ispOutputHeight, CAM_ZOOM_100X); // Jacky for test
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/isp/isp.h b/drivers/misc/jz_cim/camera_source/isp/isp.h
new file mode 100644
index 00000000000..0df9306297b
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/isp.h
@@ -0,0 +1,3373 @@
+#ifndef _COREISP3_H_
+#define _COREISP3_H_
+
+#ifdef __cplusplus
+//extern "C" {
+#endif
+
+typedef unsigned long long ClUint_64;
+typedef unsigned int ClUint_32;
+typedef unsigned short ClUint_16;
+typedef unsigned char ClUint_8;
+typedef long ClSint_64;
+typedef int ClSint_32;
+typedef short ClSint_16;
+typedef char ClSint_8;
+typedef char Cl_Char;
+typedef ClUint_32 Cl_Handle;
+typedef ClUint_8 Cl_Bool;
+
+#define Cl_Null (0)
+#define Cl_True (1)
+#define Cl_False (0)
+
+//#define ISP2_EVB_ENABLE
+//#define ISP3_EVB_ENABLE
+
+//#define ISP3_MCU_ARRAY // Added by Jacky
+//
+#define ISP3_MCU_LSC // Jacky for LSC table in MCU
+//#define YUVDATA_DUMMY // Jacky for test
+
+//#define API_SCALE_PREVIEW // Jacky for under 1.3M preview
+
+// Please select one sensor
+#define MICRON_MI5130_SUNNY // Sensor define 5M sensor
+//#define MICRON_MI5130_MCNEX // Sensor define 5M sensor
+//#define SAMSUNG_3E2_MCNEX // Sensor define 5M sensor
+//#define OV5630_TRULY // Sensor define 5M sensor
+//#define OV2M_TRULY // Sensor define
+//#define TRULY_2M_MODULE // Sensor define
+//#define HNT_5M_MODULE // Sensor define for SAMSUNG_3E2 HNT module
+//#define SAMSUNG_3E2_LITE_ON // Sensor define 5M sensor
+//#define HNT_2M_MODULE // Sensor SAMSUNG HNT module
+
+#ifdef SAMSUNG_3E2_LITE_ON
+//#define EEPROM_ACCESS_ENABLE
+#endif
+
+#ifdef MICRON_MI5130_MCNEX
+//#define ISP3_MCU_LSC // Added by Jacky for test
+//#define SENSOR_180_ROTATE // Added by Jacky for test
+//#define HISENSE_ZOOM_TEST
+#define OPPO_FEATURES
+#else
+//#define MEIZU_FEATURES
+#endif
+
+#define ISP3_COMMAND 0xe660
+
+#define __ISP3_R__
+
+#ifndef ISP3_EVB_ENABLE
+#define DM_JPEG 1
+#define DebugMessage // to your system print function
+#define WaitTime_us mdelay
+#endif
+
+#define IIC_BURST_MODE // Jacky add this
+
+#define ISP3_ZOOM_ENABLE
+//#define DEFINE_FLOAT
+
+#define IICID_A 0x82
+#define IICID_B 0x80
+
+#define ISP_IICID_A 0x41<<1
+#define ISP_IICID_B 0x40<<1
+
+#ifdef ISP3_ZOOM_ENABLE
+#define ZOOMRATE_1X 1.0f
+#define ZOOMRATE_2X 2.0f
+#define ZOOMRATE_4X 4.0f
+#define ZOOM_STEP_WIDTH 32 // Minimum step size of Zoom Setting is width 32, height 24
+
+typedef enum
+{
+// enISP_ZOOM_RATE_0 = 0x00, // 0
+// enISP_ZOOM_RATE_0_1, // 0.1
+// enISP_ZOOM_RATE_0_5, // 0.5
+ enISP_ZOOM_RATE_1, // 1
+ enISP_ZOOM_RATE_1_25, // 1.25
+ enISP_ZOOM_RATE_1_5, // 1.5
+ enISP_ZOOM_RATE_1_75, // 1.75
+ enISP_ZOOM_RATE_2, // 2
+ enISP_ZOOM_RATE_2_5 // 2.5
+}enIsp3ZoomRate;
+
+typedef enum // YuLong used code now
+{
+ CAM_ZOOM_100X=0,
+ CAM_ZOOM_125X,
+ CAM_ZOOM_150X,
+ CAM_ZOOM_200X,
+ CAM_ZOOM_250X,
+ CAM_ZOOM_400X,
+ CAM_ZOOM_CIF, // 352x288 1.222
+ CAM_ZOOM_QCIF, // 176x144
+ CAM_ZOOM_480_360, // 480_360
+ CAM_ZOOM_480_360X1, //
+ CAM_ZOOM_480_360X2, //
+ CAM_ZOOM_480_360X3, //
+ CAM_ZOOM_480_360X4, //
+ CAM_ZOOM_VGA, // 640x480
+ CAM_ZOOM_SVGA, // 800x600
+ CAM_ZOOM_1_3M, // 1280x960
+
+//Following for OPPO 5:3 resolution
+ CAM_ZOOM_800_480,
+ CAM_ZOOM_1600_960,
+ CAM_ZOOM_2048_1228,
+ CAM_ZOOM_2560_1536,
+//end
+ CAM_ZOOM_VP
+}CAM_ZOOM_T;
+#endif
+
+// added by Jacky
+typedef enum
+{
+ QSXGA = 0x00, // 2560x1920
+ QXGA = 0x01, // 2048x1536
+ UXGA = 0x02, // 1600x1200
+ SXGA , // 1280x960
+ XGA , // 1024x768
+ SVGA , // 800x600
+ VGA , // 640x480
+ QVGA , // 320x240
+ QQVGA , // 160x120
+ QSVGA // 400x300
+ // Jacky add following code for test
+ ,HVGA_100
+ ,HVGA_125
+ ,HVGA_150
+ ,HVGA_175
+ ,HVGA_200
+ //WSXGA , // 1280x1024
+ ,WQXGA = 0x0A // 2560x1536 // 5:3 ¨¤ 1280 * 960 ->800 * 480 ; 4:3 ¨¤ 1280*768->640 * 480 ;
+} Resol_MODE;
+typedef enum
+{
+ enISP_JPEG_QF_Fine = 18, // 18
+ enISP_JPEG_QF_High = 20, // 20
+ enISP_JPEG_QF_Middle = 25,// 25
+ enISP_JPEG_QF_Low=28, // 28
+}enIsp3JPEGQF;
+
+ // Added by Jacky for resolution, delete useless value
+typedef enum
+{
+ enISP_RES_5MP_FULL = 0x00, // 2560 x 1920
+ enISP_RES_QXGA, // 2048 x 1536
+ enISP_RES_UXGA, // 1600 x 1200
+ enISP_RES_1_3MP, // 1280 x 960
+ enISP_RES_XGA, // 1024 x 768
+ enISP_RES_SVGA, // 800 x 600
+ enISP_RES_VGA, // 640 x 480
+ enISP_RES_QVGA, // 320 x 240
+
+ enISP_RES_SXGA, // 1280 x 1024
+ enISP_RES_QQVGA, // 160 x 120
+ enISP_RES_HQVGA, // 240x160
+ enISP_RES_HVGA, // 480x320
+ enISP_RES_480_360, // 480x360
+ enISP_RES_QSVGA, // 400x300
+ // For OPPO 5:3 resolution
+ enISP_RES_800_480,
+ enISP_RES_1600_960,
+ enISP_RES_2048_1228,
+ enISP_RES_2560_1536,
+ enISP_RES_480_320, // 480x360
+ enISP_RES_None
+}enIsp3OutResolution;
+
+
+typedef enum
+{
+ enISP_FUNC_AWB_OFF = 0x00,
+ enISP_FUNC_AWB_ON
+}enIsp3FunctionsAWB;
+typedef enum
+{
+ enISP_FUNC_AE_OFF = 0x00,
+ enISP_FUNC_AE_ON
+}enIsp3FunctionsAE;
+
+
+typedef enum
+{
+ enISP_FUNC_AF_OFF = 0x00,
+ enISP_FUNC_AF_ON
+}enIsp3FunctionsAF;
+
+typedef enum
+{
+ enISP_FUNC_ANR_LEVEL_0 = 0x00,
+ enISP_FUNC_ANR_LEVEL_1,
+ enISP_FUNC_ANR_LEVEL_2,
+ enISP_FUNC_ANR_LEVEL_3,
+ enISP_FUNC_ANR_LEVEL_4
+}enISP3FunctionsANRLevel;
+
+typedef enum
+
+{
+ enISP_FUNC_WDR_LEVEL_0 = 0x00,
+ enISP_FUNC_WDR_LEVEL_1,
+ enISP_FUNC_WDR_LEVEL_2,
+ enISP_FUNC_WDR_LEVEL_3,
+ enISP_FUNC_WDR_LEVEL_4,
+ enISP_FUNC_WDR_LEVEL_5,
+ enISP_FUNC_WDR_LEVEL_6,
+ enISP_FUNC_WDR_LEVEL_7
+}enISP3FucntionsWDRLevel;
+
+typedef struct
+{
+ ClUint_8 bWDREnable;
+ enISP3FucntionsWDRLevel WDRlevel;
+}_tISP_WDR_CTRL;
+
+typedef struct
+{
+ ClUint_16 addr;
+ ClUint_16 val;
+}_tISP_IIC_CTRL;
+
+typedef enum
+{
+ enISP_FUNC_FD_ROI_THICK_0 = 0x00,
+ enISP_FUNC_FD_ROI_THICK_1,
+ enISP_FUNC_FD_ROI_THICK_2,
+ enISP_FUNC_FD_ROI_THICK_3,
+ enISP_FUNC_FD_ROI_THICK_4,
+ enISP_FUNC_FD_ROI_THICK_5,
+ enISP_FUNC_FD_ROI_THICK_6,
+ enISP_FUNC_FD_ROI_THICK_7,
+ enISP_FUNC_FD_ROI_THICK_8,
+ enISP_FUNC_FD_ROI_THICK_9,
+ enISP_FUNC_FD_ROI_THICK_10,
+ enISP_FUNC_FD_ROI_THICK_11,
+ enISP_FUNC_FD_ROI_THICK_12,
+ enISP_FUNC_FD_ROI_THICK_13,
+ enISP_FUNC_FD_ROI_THICK_14,
+ enISP_FUNC_FD_ROI_THICK_15
+}enIsp3FaceROIThick;
+
+typedef enum
+{
+ enISP_FUNC_FD_MAXCOUNT_1 = 0x00,
+ enISP_FUNC_FD_MAXCOUNT_2,
+ enISP_FUNC_FD_MAXCOUNT_3,
+ enISP_FUNC_FD_MAXCOUNT_4,
+ enISP_FUNC_FD_MAXCOUNT_5,
+ enISP_FUNC_FD_MAXCOUNT_6,
+ enISP_FUNC_FD_MAXCOUNT_7,
+ enISP_FUNC_FD_MAXCOUNT_8,
+ enISP_FUNC_FD_MAXCOUNT_9,
+ enISP_FUNC_FD_MAXCOUNT_10
+}enIsp3FaceMaxDetectionCount;
+
+typedef struct
+{
+ ClUint_8 bFaceDetectionEnable;
+ ClUint_8 bFaceTrackingEnable;
+ ClUint_8 bFaceAE;
+ ClUint_8 bFaceAF;
+ ClUint_8 bFaceAWB;
+ ClUint_8 bFaceRotation;
+ ClUint_8 bFaceUserMode;
+ enIsp3FaceROIThick Isp3FaceROIThick;
+ enIsp3FaceMaxDetectionCount Isp3FaceMaxDetectionCount;
+ enIsp3OutResolution OutputResolution;
+}_tIspFaceDetectionCtrl;
+
+typedef struct
+{
+ int sx;
+ int sy;
+ int ex;
+ int ey;
+ ClUint_8 first_pos_index;
+ ClUint_8 second_pos_index;
+}faceInfo;
+extern faceInfo _faceInfo[10];
+
+typedef enum
+{
+ enDownloadMode_StackedMem,
+ enDownloadMode_SkipedMCUBin,
+ enDownloadMode_CodeRAM,
+ enDownloadMode_None
+}enIsp3DownloadMode;
+
+typedef enum
+{
+ CMD_Capture,
+ CMD_Preview,
+} CMD_Mode; // update
+
+typedef enum
+{
+ FLICKER_50HZ_OFF = 0,
+ FLICKER_50HZ_ON,
+ FLICKER_60HZ_OFF,
+ FLICKER_60HZ_ON,
+ FLICKER_AUTO_OFF,
+ FLICKER_AUTO_ON,
+
+} FLICKER_TYPE; // update
+
+//auto
+//sunny
+//cloudy
+//night
+//flocsnet
+//incandscent
+
+typedef enum
+{
+ WB_AUTO = 0x00, //Auto White Balance mode
+ WB_CLOUDY = 0x01, //6000K
+ WB_SUNNY = 0x02, //5200K
+ WB_FLOCSNET = 0x03, //4600K flocesnet
+ WB_TUNGSTEN = 0x04, //3500K
+ WB_SUNSET = 0x05, //2000K~3000K
+ WB_INCANDESCENT = 0x06, //2300K
+ WB_CANDLE = 0x07 //1500K~2000K
+} enWB_MANUAL_TYPE; // update
+
+typedef enum
+{
+ enISP_Level_0 = 0x00, // -5
+ enISP_Level_1, // -4
+ enISP_Level_2, // -3
+ enISP_Level_3, // -2
+ enISP_Level_4, // -1
+ enISP_Level_5, // 0
+ enISP_Level_6, // +1
+ enISP_Level_7, // +2
+ enISP_Level_8, // +3
+ enISP_Level_9, // +4
+ enISP_Level_10, // +5
+ enISP_Level_Max,
+ enISP_Level_Default,
+ enISP_Level_Off
+}enIsp3Level_Value; // update by Jacky
+
+typedef enum
+{
+ enISP_CrYCb = 0x08,
+ enISP_YCrCb = 0x09,
+ enISP_CbYCr = 0x0a,
+ enISP_YCbCr = 0x0b,
+}enIsp3YUV_Swap; // update by Jacky
+
+typedef enum
+{
+ ISP3_ROTATION_NONE = 0x00,
+ ISP3_ROTATION_FLIP = 0x01,
+ ISP3_ROTATION_MIRROR = 0x02,
+ ISP3_ROTATION_MIRRORFLIP = 0x03,
+} enIsp3MIRROR_MODE; // update by Jacky
+
+typedef enum
+{
+ enISP_FUNC_SS_LEVEL_NONE = 0x00,
+ enISP_FUNC_SS_LEVEL_1,
+ enISP_FUNC_SS_LEVEL_1_2,
+ enISP_FUNC_SS_LEVEL_1_3,
+ enISP_FUNC_SS_LEVEL_1_4,
+ enISP_FUNC_SS_LEVEL_1_5,
+ enISP_FUNC_SS_LEVEL_1_6
+}enISP3FunctionsSSLevel;
+
+typedef struct
+{
+ ClUint_8 bStillStabilizerEnable;
+ enISP3FunctionsSSLevel StillStabilzerLevel;
+}_tIspStillStabilizerCtrl;
+
+typedef enum
+{
+ enISP_FUNC_IMAGE_NORMAL = 0x00,
+ enISP_FUNC_IMAGE_EMBOSS,
+ enISP_FUNC_IMAGE_SKETCH1,
+ enISP_FUNC_IMAGE_SKETCH2,
+ enISP_FUNC_IMAGE_BLACK_WHITE,
+ enISP_FUNC_IMAGE_NORMAL_MOVIE,
+ enISP_FUNC_IMAGE_OLD_MOVIE,
+ enISP_FUNC_IMAGE_GRAY,
+ enISP_FUNC_IMAGE_ACCENT,
+ enISP_FUNC_IMAGE_SWAPING,
+ enISP_FUNC_IMAGE_ACCENT_SWAPING,
+ enISP_FUNC_IMAGE_WARM,
+ enISP_FUNC_IMAGE_COOL,
+ enISP_FUNC_IMAGE_FOG,
+ enISP_FUNC_IMAGE_OPPOSITE_NEGATIVE,
+ enISP_FUNC_IMAGE_OPPOSITE_AVERAGE
+}enISPFunctionsImageEffect;
+
+typedef enum
+{
+ enISP_FUNC_AEwithFACE_1 = 0, //3 AE OFF
+ enISP_FUNC_AEwithFACE_2, //3 AE ON & Global
+ enISP_FUNC_AEwithFACE_3 //3 AE ON & MULTI
+}enISPFunctionsAEwithFaceApp;
+
+typedef enum
+{
+ enISP_FUNC_AWBwithFD_Level_0 = 0x00,
+ enISP_FUNC_AWBwithFD_Level_1,
+ enISP_FUNC_AWBwithFD_Level_2,
+ enISP_FUNC_AWBwithFD_Level_3,
+ enISP_FUNC_AWBwithFD_Level_4,
+ enISP_FUNC_AWBwithFD_Level_5,
+ enISP_FUNC_AWBwithFD_Level_6,
+ enISP_FUNC_AWBwithFD_Level_7,
+ enISP_FUNC_AWBwithFD_Level_8,
+ enISP_FUNC_AWBwithFD_Level_9,
+ enISP_FUNC_AWBwithFD_Level_10
+}enIsp3AWBwithFaceLevel;
+
+typedef struct
+{
+ ClUint_32 sx;
+ ClUint_32 sy;
+ ClUint_32 ex;
+ ClUint_32 ey;
+ ClUint_8 first_pos_index;
+ ClUint_8 second_pos_index;
+
+}stFaceInfo;
+
+typedef enum
+{
+ enISP_FUNC_FDUser_Level_0 = 0x00,
+ enISP_FUNC_FDUser_Level_1,
+ enISP_FUNC_FDUser_Level_2,
+ enISP_FUNC_FDUser_Level_3,
+ enISP_FUNC_FDUser_Level_4,
+ enISP_FUNC_FDUser_Level_5,
+ enISP_FUNC_FDUser_Level_6,
+ enISP_FUNC_FDUser_Level_7,
+ enISP_FUNC_FDUser_Level_8,
+ enISP_FUNC_FDUser_Level_9
+}enIspFaceUserMode;
+
+typedef enum
+{
+ ISP3_CMD_DEBUG_DEFAULT = 0x01,
+ ISP3_CMD_DEBUG_AE = 0x02,
+ ISP3_CMD_DEBUG_AF = 0x03,
+ ISP3_CMD_DEBUG_AWB = 0x04,
+ ISP3_CMD_DEBUG_FACE = 0x05,
+ ISP3_CMD_DEBUG_STILL = 0x06,
+ ISP3_CMD_DEBUG_FLICKER = 0x07,
+ ISP3_CMD_DEBUG_ATC = 0x08,
+ ISP3_CMD_DEBUG_ANR = 0x09,
+ ISP3_CMD_DEBUG_EFFECT = 0x0A,
+ ISP3_CMD_DEBUG_BESTEXIF = 0x0C,
+ ISP3_CMD_DEBUG_FRMSG = 0x0D,
+ ISP3_CMD_BAUDRATE = 0x0E,
+
+ // MCU function
+ ISP3_CMD_ISR_ON = 0x11,
+ ISP3_CMD_ISR_OFF = 0x12,
+ ISP3_CMD_FRAME_COUNT_CLEAR = 0x13,
+
+ ISP3_CMD_GET_VERSION = 0x14,
+ // Camera secene mode
+ ISP3_CMD_MODE_AUTOMODE = 0x20,
+ ISP3_CMD_MODE_PORTRAIT = 0x21,
+ ISP3_CMD_MODE_LANDSCAPE = 0x22,
+ ISP3_CMD_MODE_INDOOR = 0x23,
+ ISP3_CMD_MODE_SPORTS = 0x24,
+ ISP3_CMD_MODE_NIGHT = 0x25,
+ ISP3_CMD_MODE_CANDLE = 0x26,
+ ISP3_CMD_MODE_FIREWORKS = 0x27,
+ ISP3_CMD_MODE_SNOW = 0x28,
+ ISP3_CMD_MODE_QUATREFOIL = 0x29,
+
+ // LSC
+ ISP3_CMD_LSC_DOWN = 0x31,
+ ISP3_CMD_LSC_DEBUG = 0x32,
+
+ // JPEG ZOOM
+ ISP3_CMD_JPEGZOOM_ON = 0x41,
+ ISP3_CMD_JPEGZOOM_OFF = 0x42,
+
+ //BEST EXIF
+ ISP3_CMD_BESTONE = 0x59,
+ ISP3_CMD_BESTTHR = 0x5a,
+ ISP3_CMD_BESTFIV = 0x5b,
+ ISP3_CMD_BESTSEV = 0x5c,
+ ISP3_CMD_BESTNIN = 0x5d,
+ ISP3_CMD_BESTOFF = 0x5e,
+
+ //Senser Reg R/W
+ ISP3_CMD_SenRegRead = 0x62,
+ ISP3_CMD_SenRegWrit = 0x63,
+
+ ISP3_CMD_MCUExifON = 0x60,
+ ISP3_CMD_MCUExifOFF = 0x61,
+
+ // IMAGE EFFECT
+ ISP3_CMD_EFFECT_DEFAULT = 0x70,
+ ISP3_CMD_EFFECT_SPLENDID = 0x71,
+ ISP3_CMD_EFFECT_CHARISMA = 0x72,
+ ISP3_CMD_EFFECT_DIGNITY = 0x73,
+ ISP3_CMD_EFFECT_HORROR = 0x74,
+
+ // ISO FLAG NUMBERING
+ ISP3_CMD_ASA100 = 0x80,
+ ISP3_CMD_ASA200 = 0x81,
+ ISP3_CMD_ASA400 = 0x82,
+ ISP3_CMD_ASA800 = 0x83,
+ ISP3_CMD_ASA1600 = 0x84,
+
+ ISP3_CMD_OPTICAL_ZOOM_COMPENSATION = 0x90,
+ ISP3_CMD_OPTICAL_ZOOMAF_COMPENSATION = 0x91,
+ ISP3_CMD_DIGITAL_ZOOM_ON = 0x93, // DIGITAL ZOOM CONTROL FUNCTION
+ ISP3_CMD_DIGITAL_ZOOM_OFF = 0x94,
+ ISP3_CMD_DIGITAL_ZOOM_CAPTURE = 0x95,
+ ISP3_CMD_OPTICAL_ZOOM_MOVE = 0x96,
+ ISP3_CMD_OPTICAL_ZOOMAF_MOVE = 0x97,
+ ISP3_CMD_ATC_ON = 0x98, // Adaptive Tone Curve
+ ISP3_CMD_ATC_OFF = 0x99,
+ ISP3_CMD_ANR_ON = 0x9c, // Adaptive Noise Reduction
+ ISP3_CMD_ANR_OFF = 0x9d,
+
+ // FLICKER DETECTION & SUPPRESSION
+ ISP3_CMD_FLICKER_DETECTION_ON = 0xa0,
+ ISP3_CMD_FLICKER_DETECTION_OFF = 0xa1,
+ ISP3_CMD_FLICKER_SUPPRESSION_ON = 0xa2,
+ ISP3_CMD_FLICKER_SUPPRESSION_OFF = 0xa3,
+ // Sensor control
+ ISP3_CMD_SENSOR_INIT = 0xb0,
+ ISP3_CMD_SENSOR_READ = 0xb1,
+ ISP3_CMD_SENSOR_WRITE = 0xb2,
+ // Jacky add this for hisense
+ISP3_CMD_FLASHLIGHT_ON = 0xb4,
+ISP3_CMD_FLASHLIGHT_OFF = 0xb5,
+
+ // AE FLAG NUMBERING
+ ISP3_CMD_AE_OFF = 0xc0,
+ ISP3_CMD_AE_ON = 0xc1,
+ ISP3_CMD_AE_MULTI = 0xc2,
+ ISP3_CMD_AE_GLOBAL = 0xc3,
+ ISP3_CMD_AE_SPOT = 0xc4,
+ ISP3_CMD_SET_SHUTTER_AGC = 0xc5, // cltuner sync need
+
+ ISP3_CMD_AE_SET_ISO = 0xc7, // Jacky update
+ //SET_AGC
+ ISP3_CMD_AE_HALF_RELEASE = 0xce,
+ ISP3_CMD_AE_HALF_SHUTTER = 0xcf,
+
+ ISP3_CMD_STILL_OFF = 0xc8, // Still stabilizer
+ ISP3_CMD_STILL_ON = 0xc9,
+ ISP3_CMD_SET_AE_CONFIG = 0xcb, // Jacky for EV
+ // Image size flag
+ ISP3_CMD_PREVIEW = 0xd0, // Preview Size : Frame rate is High, but Image quality is low.
+ ISP3_CMD_CAPTURE = 0xdb, // Capture Size : Frame rate is Low, but Image quality is High.
+ ISP3_CMD_THUMBNAIL_ON = 0xdc, // Thumbnail Preview On
+ ISP3_CMD_THUMBNAIL_OFF = 0xdd, // Thunbnail Preview Off
+
+#ifdef TRULY_2M_MODULE // Jacky add this for Truly 2M
+ ISP3_CMD_PREVIEW_SVGA = 0xd1, //SF SVGA sub-sampling preview
+ ISP3_CMD_CAPTURE_5M = 0xd2, //5M capture
+ ISP3_CMD_CAPTURE_3M = 0xd3, // 3M capture add by Jacky
+#else
+ ISP3_CMD_CAPTURE_5M = 0xd2, //5M capture
+#endif
+ //MYShin_081002 MCU Fucntion Added..
+/* ISP3_CMD_SET_13MP_SIZE = 0xd1, //Preview Size : 1.3MP(1280 x 960)
+ ISP3_CMD_SET_3MP_SIZE = 0xd2, //Preview Size : 3MP(2048 x 1536)
+ ISP3_CMD_SET_5MP_FULL_SIZE = 0xd3, //Preview Size : 5MP(2560 x 1920)
+ ISP3_CMD_SET_SVGA_SIZE = 0xd4, //Preview Size : 800 x 600
+*/
+ ISP3_CMD_SET_VGA_SIZE = 0xd5, //Preview Size : 640 x 480
+ ISP3_CMD_SET_HVGA_SIZE = 0xb8, //Preview Size : 480x320
+ ISP3_CMD_DZOOM_SENSOR_VALUE_ON = 0xd6, // update
+ ISP3_CMD_DZOOM_SENSOR_VALUE_OFF = 0xd7,
+
+ // AWB FLAG NUMBERING
+ ISP3_CMD_AWB_SET_MAP1_DATA_TO_REG = 0xe0,
+ ISP3_CMD_AWB_SET_MAP2_DATA_TO_REG = 0xe1,
+ ISP3_CMD_AWB_SET_MAP1_REG_TO_DATA = 0xe2,
+ ISP3_CMD_AWB_SET_MAP2_REG_TO_DATA = 0xe5,
+ ISP3_CMD_AWB_ON = 0xe3,
+ ISP3_CMD_AWB_OFF = 0xe4,
+ ISP3_CMD_AWB_DEFENCE_ONOFF = 0xdf,
+ ISP3_CMD_CUSTOM_WB = 0xe6,
+ ISP3_CMD_CUSTOM_WB_SET = 0xe7,
+ ISP3_CMD_WB_AUTO = 0xe8,
+ ISP3_CMD_WB_DAYLIGHT = 0xeb,
+ ISP3_CMD_WB_CLOUDY = 0xec,
+ ISP3_CMD_WB_SUNSET = 0xed,
+ ISP3_CMD_WB_FLOURESCENT = 0xee,
+ ISP3_CMD_WB_INCANDESCENT = 0xef,
+
+ // FACE DETECTION
+ ISP3_CMD_FACE_ROTATE_START = 0x34,
+ ISP3_CMD_FACE_ROTATE_STOP = 0x35,
+ ISP3_CMD_FACE_USERMODE_START = 0x36,
+ ISP3_CMD_FACE_USERMODE_STOP = 0x37,
+
+ ISP3_CMD_FACE_TRACKING_START = 0x38,
+ ISP3_CMD_FACE_TRACKING_STOP = 0x39,
+ ISP3_CMD_FACE_DETECTION_START = 0xe6,
+ ISP3_CMD_FACE_DETECTION_STOP = 0xe7,
+ ISP3_CMD_FLICKER_DETECTION_START = 0xe8,
+ ISP3_CMD_FLICKER_DETECTION_STOP = 0xe9,
+ ISP3_CMD_FLICKER_DETECTION_120_ENABLE = 0xa0,
+ ISP3_CMD_FLICKER_DETECTION_120_DISABLE = 0xa1,
+ ISP3_CMD_FACE_DETECTION_DEBUG = 0xa2,
+ ISP3_CMD_SET_FLIP_MIRROR =0xbe,
+ ISP3_CMD_AE_50HZ = 0xea,
+ ISP3_CMD_AE_60HZ = 0xeb,
+ ISP3_CMD_FACE_AF_START = 0xec,
+ ISP3_CMD_FACE_AF_STOP = 0xed,
+ ISP3_CMD_FACE_AE_START = 0xee,
+ ISP3_CMD_FACE_AE_STOP = 0xef,
+
+ // AF FLAG NUMBERING
+ ISP3_CMD_AF_ON = 0xf0,
+ ISP3_CMD_AF_OFF = 0xf1,
+ ISP3_CMD_MICROAF = 0xf2, // ISP3_CMD_CLOSEAF
+ ISP3_CMD_FULLAF = 0xf3,
+ ISP3_CMD_INTELAF = 0xf4,
+ ISP3_CMD_FORWARD = 0xf5,
+ ISP3_CMD_BACKWARD = 0xf6,
+ ISP3_CMD_ENDNEAR = 0xf7,
+ ISP3_CMD_ENDFAR = 0xf8,
+ ISP3_CMD_AF_INITFAR = 0xf9,
+ ISP3_CMD_AF_MOVE_MOTOR = 0xfa,
+ ISP3_CMD_AF_FULL_SCAN = 0xfb, // Added by Jacky
+ ISP3_CMD_AF_MICRO_SCAN = 0xfc, // Added by Jacky
+ ISP3_CMD_NONE
+} enISP3_CMD_TYPE;
+
+
+
+
+/*------------------------------------------------------------------------------
+ Image Processings
+------------------------------------------------------------------------------*/
+#define DevID 0xE000
+#define IspFenA 0xE001
+#define IspFenB 0xE002
+#define IspFenC 0xE003
+#define IspFenD 0xE004
+#define IspFenE 0xE005
+#define IspFenF 0xE006
+#define IspFenG 0xE007
+
+/*------------------------------------------------------------------------------
+ Sensor Data Interface
+------------------------------------------------------------------------------*/
+#define Cis1IntA 0xE010
+#define Cis1IntB 0xE011
+#define Cis1IntC 0xE012
+#define Cis1IntD 0xE013
+#define Cis1IntE 0xE014
+#define Cis1IntF 0xE015
+
+#define Cis2IntA 0xE020
+#define Cis2IntB 0xE021
+#define Cis2IntC 0xE022
+#define Cis2IntD 0xE023
+
+/*------------------------------------------------------------------------------
+ Sensor Control Interface
+------------------------------------------------------------------------------*/
+#define IicDev 0xE030
+#define IicMode1 0xE031
+#define IicMode2 0xE032
+#define IicAddrH 0xE033
+#define IicAddrL 0xE034
+#define IicWrDtH 0xE035
+#define IicWrDtL 0xE036
+#define S3Mode 0xE037
+#define S3SCKPrd 0xE038
+#define SIicFSM 0xE039
+#define IicSPrd 0xE03a
+#define SCtlMode 0xE03b
+#define CISSel 0xE03C // Temporary hEF97, VISTA : hED97
+
+/*------------------------------------------------------------------------------
+ Host access flag
+------------------------------------------------------------------------------*/
+#define HostAccess 0xE040
+
+/*------------------------------------------------------------------------------
+ Chip Test Gadget
+------------------------------------------------------------------------------*/
+#define TstRamSel 0xE048
+
+/*------------------------------------------------------------------------------
+ Applocation Processor Interface
+------------------------------------------------------------------------------*/
+#define OutFmt 0xE050
+#define OutFmt_EXT 0xE051
+#define CdEn 0xE052
+#define OutEnb 0xE058
+#define OutFmt_JPG 0xE059
+#define PrvMarker1 0xE05a
+#define PrvMarker2 0xE05b
+#define S4Mode 0xE05c
+#define S4SmplMode 0xE05d
+
+/*------------------------------------------------------------------------------
+ PLL Management
+------------------------------------------------------------------------------*/
+#define PLLMODE 0xE060
+#define PLLMul 0xE061
+#define PLLPre 0xE062
+#define PLLPost 0xE063
+
+/*------------------------------------------------------------------------------
+ PAD Control
+------------------------------------------------------------------------------*/
+#define PADCTRL0 0xE067
+#define PADCTRL1 0xE068
+#define PADCTRL2 0xE069
+#define PADCTRL3 0xE06a
+#define PADCTRL4 0xE06b
+
+/*------------------------------------------------------------------------------
+ MCU Control
+------------------------------------------------------------------------------*/
+#define MCURST 0xE070
+#define MCUP0 0xE071
+#define MCUP1 0xE072
+#define MCUP2 0xE073
+#define MCUP3 0xE074
+#define MCUIntSel 0xE075
+
+#define GPIO0En 0xE080
+#define GPIO1En 0xE081
+#define GPIO2En 0xE082
+#define GPIO3En 0xE083
+#define GPIO0SMCEn 0xE084
+#define GPIO1SMCEn 0xE085
+#define GPIO2SMCEn 0xE086
+#define GPIO3SMCEn 0xE087
+#define GPIO0DirCon 0xE089
+#define GPIO1DirCon 0xE08a
+#define GPIO2DirCon 0xE08b
+#define GPIO3DirCon 0xE08c
+#define GPIO0CPU 0xE08d
+#define GPIO1CPU 0xE08e
+#define GPIO2CPU 0xE08f
+#define GPIO3CPU 0xE090
+#define GPIO0CPD 0xE091
+#define GPIO1CPD 0xE092
+#define GPIO2CPD 0xE093
+#define GPIO3CPD 0xE094
+
+
+/*------------------------------------------------------------------------------
+ Flash Memory Control
+------------------------------------------------------------------------------*/
+//efine CdWrapper 0xE0a0
+#define FlashErase 0xE0a1
+#define FlashDEV 0xE0a2
+#define FlashAddrH 0xE0a3
+#define FlashAddrL 0xE0a4
+#define FlashData 0xE0a5
+#define FlashDSizeH 0xE0a6
+#define FlashDSizeL 0xE0a7
+#define UsrRomRdCfg 0xE0a8
+#define UsrRomWrCfg 0xE0a9
+#define SerialAddr1 0xE0aa
+#define SerialAddr2 0xE0ab
+#define SerialAddr3 0xE0ac
+
+#define FlashCMDAH 0xE0b0
+#define FlashCMDAL 0xE0b1
+#define FlashCMDBH 0xE0b2
+#define FlashCMDBL 0xE0b3
+#define FlashCMDCH 0xE0b4
+#define FlashCMDCL 0xE0b5
+#define FlashCMDDH 0xE0b6
+#define FlashCMDDL 0xE0b7
+#define FlashCMDEH 0xE0b8
+#define FlashCMDEL 0xE0b9
+#define FlashCMDFH 0xE0ba
+#define FlashCMDFL 0xE0bb
+
+#define FlashCMDDA 0xE0be
+#define FlashCMDDB 0xE0bf
+#define FlashPGMDC 0xE0c0
+#define FlashCMDDC 0xE0c1
+#define FlashCMDDD 0xE0c2
+#define FlashCMDDE 0xE0c3
+#define FlashCMDDF 0xE0c4
+
+#define FlashDown 0xE0c6
+
+/*------------------------------------------------------------------------------
+ Test Pattern
+------------------------------------------------------------------------------*/
+#define PttrnSel 0xE0c8
+#define Pattern0 0xE0c9
+#define Pattern1 0xE0ca
+#define Pattern2 0xE0cb
+#define Pattern3 0xE0cc
+
+/*------------------------------------------------------------------------------
+ Sync Driving
+------------------------------------------------------------------------------*/
+#define CDrvMode 0xE0d0
+#define CDrvXWidH 0xE0d1
+#define CDrvXWidL 0xE0d2
+#define CDrvYWidH 0xE0d3
+#define CDrvYWidL 0xE0d4
+#define CDrvHsWid 0xE0d5
+#define CDrvVsWid 0xE0d6
+
+/*------------------------------------------------------------------------------
+ Video Sync Repositioning
+------------------------------------------------------------------------------*/
+#define VsyncStr 0xE0e0
+#define VsyncVldPrdH 0xE0e1
+#define VsyncVldPrdL 0xE0e2
+#define VSCntStrH 0xE0e3
+#define VSCntStrL 0xE0e4
+#define VSCntEndH 0xE0e5
+#define VSCntEndL 0xE0e6
+#define VsyncVldPrd_StrH 0xE0e7
+#define VsyncVldPrd_StrL 0xE0e8
+
+/*------------------------------------------------------------------------------
+ SPI
+------------------------------------------------------------------------------*/
+#define SPICtrl 0xE0f0
+#define SPIClkCtrl 0xE0f1
+#define PADDRH 0xE0f2
+#define PADDRL 0xE0f3
+#define PWDATA_Reg_H 0xE0f4
+#define PWDATA_Reg_L 0xE0f5
+
+/*------------------------------------------------------------------------------
+ Optical Black Pixel Window Selection
+------------------------------------------------------------------------------*/
+#define BlkWinAStrXH 0xE100
+#define BlkWinAStrXL 0xE101
+#define BlkWinAStrYH 0xE102
+#define BlkWinAStrYL 0xE103
+#define BlkWinAEndXH 0xE104
+#define BlkWinAEndXL 0xE105
+#define BlkWinAEndYH 0xE106
+#define BlkWinAEndYL 0xE107
+#define BlkWinBStrXH 0xE108
+#define BlkWinBStrXL 0xE109
+#define BlkWinBStrYH 0xE10a
+#define BlkWinBStrYL 0xE10b
+#define BlkWinBEndXH 0xE10c
+#define BlkWinBEndXL 0xE10d
+#define BlkWinBEndYH 0xE10e
+#define BlkWinBEndYL 0xE10f
+#define BlkWinCStrXH 0xE110
+#define BlkWinCStrXL 0xE111
+#define BlkWinCStrYH 0xE112
+#define BlkWinCStrYL 0xE113
+#define BlkWinCEndXH 0xE114
+#define BlkWinCEndXL 0xE115
+#define BlkWinCEndYH 0xE116
+#define BlkWinCEndYL 0xE117
+#define BlkWinDStrXH 0xE118
+#define BlkWinDStrXL 0xE119
+#define BlkWinDStrYH 0xE11a
+#define BlkWinDStrYL 0xE11b
+#define BlkWinDEndXH 0xE11c
+#define BlkWinDEndXL 0xE11d
+#define BlkWinDEndYH 0xE11e
+#define BlkWinDEndYL 0xE11f
+
+/*------------------------------------------------------------------------------
+ Active Pixel Window Selection (Start)
+------------------------------------------------------------------------------*/
+#define ActWinStrXH 0xE120
+#define ActWinStrXL 0xE121
+#define ActWinStrYH 0xE122
+#define ActWinStrYL 0xE123
+#define ActWinEndXH 0xE124
+#define ActWinEndXL 0xE125
+#define ActWinEndYH 0xE126
+#define ActWinEndYL 0xE127
+#define ActWinWidthH 0xE128
+#define ActWinWidthL 0xE129
+
+/*------------------------------------------------------------------------------
+ Optical Black Mode & Average Value
+------------------------------------------------------------------------------*/
+#define BlkMode 0xE1a0
+#define RgBlack 0xE1a1
+#define GrBlack 0xE1a2
+#define GbBlack 0xE1a3
+#define BgBlack 0xE1a4
+#define BlkScale 0xE1a5
+
+/*------------------------------------------------------------------------------
+ Black Offset Adjustment
+------------------------------------------------------------------------------*/
+#define BlkLvlRg 0xE1a6
+#define BlkLvlGr 0xE1a7
+#define BlkLvlGb 0xE1a8
+#define BlkLvlBg 0xE1a9
+
+/*------------------------------------------------------------------------------
+ Offset adjustment control in Bayer digital gain stage
+------------------------------------------------------------------------------*/
+#define RgOfsBgn 0xE1aa
+#define GrOfsBgn 0xE1ab
+#define GbOfsBgn 0xE1ac
+#define BgOfsBgn 0xE1ad
+
+/*------------------------------------------------------------------------------
+ R/G/B Channel Gain Control
+------------------------------------------------------------------------------*/
+#define PRgGain 0xE1b0 // Bayer Prefix Gain
+#define PGrGain 0xE1b1
+#define PGbGain 0xE1b2
+#define PBgGain 0xE1b3
+
+#define RGainH 0xE1b8 // Bayer Awb Gain Control
+#define RGainL 0xE1b9
+#define GGainH 0xE1ba
+#define GGainL 0xE1bb
+#define BGainH 0xE1bc
+#define BGainL 0xE1bd
+
+#define RGainMin 0xE1c8 // R/G/B Gain Mix/Max Limit
+#define RGainMax 0xE1c9
+#define GGainMin 0xE1ca
+#define GGainMax 0xE1cb
+#define BGainMin 0xE1cc
+#define BGainMax 0xE1cd
+
+#define WhiteClip 0xE1d0
+
+/*------------------------------------------------------------------------------
+ DPC Internal Function Register
+------------------------------------------------------------------------------*/
+#define HotRatioThrH_H 0xE1e2
+#define HotRatioThrH_L 0xE1e3
+#define HotRatioThrL_H 0xE1e4
+#define HotRatioThrL_L 0xE1e5
+
+#define CenterWeight 0xE1e6
+
+#define ClipRatioH_Max_H 0xE1e7
+#define ClipRatioH_Max_L 0xE1e8
+#define ClipRatioH_Min_H 0xE1e9
+#define ClipRatioH_Min_L 0xE1ea
+#define ClipRatioL_Max_H 0xE1eb
+#define ClipRatioL_Max_L 0xE1ec
+#define ClipRatioL_Min_H 0xE1ed
+#define ClipRatioL_Min_L 0xE1ee
+
+#define LevelRange_Max_H 0xE1ef
+#define LevelRange_Max_L 0xE1f0
+#define LevelRange_Min_H 0xE1f1
+#define LevelRange_Min_L 0xE1f2
+
+#define HotThrNo 0xE1f3
+#define LevelThr 0xE1f4 // HotGNoTh, HotCNoTh
+
+/*------------------------------------------------------------------------------
+ DPC Pixel Location Address
+------------------------------------------------------------------------------*/
+#define DPCPxlPntX0H 0xE200
+#define DPCPxlPntX0L 0xE201
+#define DPCPxlPntY0H 0xE202
+#define DPCPxlPntY0L 0xE203
+#define DPCPxlPntX1H 0xE204
+#define DPCPxlPntX1L 0xE205
+#define DPCPxlPntY1H 0xE206
+#define DPCPxlPntY1L 0xE207
+#define DPCPxlPntX2H 0xE208
+#define DPCPxlPntX2L 0xE209
+#define DPCPxlPntY2H 0xE20a
+#define DPCPxlPntY2L 0xE20b
+#define DPCPxlPntX3H 0xE20c
+#define DPCPxlPntX3L 0xE20d
+#define DPCPxlPntY3H 0xE20e
+#define DPCPxlPntY3L 0xE20f
+#define DPCPxlPntX4H 0xE210
+#define DPCPxlPntX4L 0xE211
+#define DPCPxlPntY4H 0xE212
+#define DPCPxlPntY4L 0xE213
+#define DPCPxlPntX5H 0xE214
+#define DPCPxlPntX5L 0xE215
+#define DPCPxlPntY5H 0xE216
+#define DPCPxlPntY5L 0xE217
+#define DPCPxlPntX6H 0xE218
+#define DPCPxlPntX6L 0xE219
+#define DPCPxlPntY6H 0xE21a
+#define DPCPxlPntY6L 0xE21b
+#define DPCPxlPntX7H 0xE21c
+#define DPCPxlPntX7L 0xE21d
+#define DPCPxlPntY7H 0xE21e
+#define DPCPxlPntY7L 0xE21f
+#define DPCPxlPntX8H 0xE220
+#define DPCPxlPntX8L 0xE221
+#define DPCPxlPntY8H 0xE222
+#define DPCPxlPntY8L 0xE223
+#define DPCPxlPntX9H 0xE224
+#define DPCPxlPntX9L 0xE225
+#define DPCPxlPntY9H 0xE226
+#define DPCPxlPntY9L 0xE227
+
+#define DPCPxlPntX10H 0xE228
+#define DPCPxlPntX10L 0xE229
+#define DPCPxlPntY10H 0xE22a
+#define DPCPxlPntY10L 0xE22b
+#define DPCPxlPntX11H 0xE22c
+#define DPCPxlPntX11L 0xE22d
+#define DPCPxlPntY11H 0xE22e
+#define DPCPxlPntY11L 0xE22f
+#define DPCPxlPntX12H 0xE230
+#define DPCPxlPntX12L 0xE231
+#define DPCPxlPntY12H 0xE232
+#define DPCPxlPntY12L 0xE233
+#define DPCPxlPntX13H 0xE234
+#define DPCPxlPntX13L 0xE235
+#define DPCPxlPntY13H 0xE236
+#define DPCPxlPntY13L 0xE237
+#define DPCPxlPntX14H 0xE238
+#define DPCPxlPntX14L 0xE239
+#define DPCPxlPntY14H 0xE23a
+#define DPCPxlPntY14L 0xE23b
+#define DPCPxlPntX15H 0xE23c
+#define DPCPxlPntX15L 0xE23d
+#define DPCPxlPntY15H 0xE23e
+#define DPCPxlPntY15L 0xE23f
+#define DPCPxlPntX16H 0xE240
+#define DPCPxlPntX16L 0xE241
+#define DPCPxlPntY16H 0xE242
+#define DPCPxlPntY16L 0xE243
+#define DPCPxlPntX17H 0xE244
+#define DPCPxlPntX17L 0xE245
+#define DPCPxlPntY17H 0xE246
+#define DPCPxlPntY17L 0xE247
+#define DPCPxlPntX18H 0xE248
+#define DPCPxlPntX18L 0xE249
+#define DPCPxlPntY18H 0xE24a
+#define DPCPxlPntY18L 0xE24b
+#define DPCPxlPntX19H 0xE24c
+#define DPCPxlPntX19L 0xE24d
+#define DPCPxlPntY19H 0xE24e
+#define DPCPxlPntY19L 0xE24f
+
+//Flicker Detection
+#define Gap_Thr 0xE250
+#define Percentage_all 0xE251
+#define Percentage_fk 0xE252
+#define Debug_line_Cnt_End1 0xE253
+#define Debug_line_Cnt_End2 0xE254
+#define Width_ratio 0xE255
+
+#define Flck_img 0xE256
+#define All_line 0xE257
+#define Dtd_All_line 0xE258
+#define All_fk_line 0xE259
+#define Dtd_All_fk_line 0xE25a
+#define Dtd_All_line_Thr 0xE25b
+#define M_LineCnt 0xE25c
+#define FkGap_Avg 0xE25d
+#define Inflection_Gap_Thr 0xE25e
+#define Row_Skip 0xE25f
+#define min_line 0xE260
+#define min_y 0xE261
+#define max_y 0xE262
+
+#define PxlDelay 0xE263
+
+#define RadiusY 0xE270
+#define RadiusCb 0xE271
+#define RadiusCr 0xE272
+
+/*------------------------------------------------------------------------------
+ Shading Correction - ISP1 legacy dead address
+------------------------------------------------------------------------------*/
+#define ShdMode 0xE2a0
+#define ShdCenX 0xE2a1
+#define ShdCenY 0xE2a2
+#define ShdCnvRtoH 0xE2a3
+#define ShdCnvRtoL 0xE2a4
+#define ShdSclRg 0xE2a5
+#define ShdSclGr 0xE2a6
+#define ShdSclGb 0xE2a7
+#define ShdSclBg 0xE2a8
+
+#define ShdXpt1 0xE2b0
+#define ShdXpt2 0xE2b1
+#define ShdXpt3 0xE2b2
+#define ShdXpt4 0xE2b3
+#define ShdXpt5 0xE2b4
+#define ShdXpt6 0xE2b5
+#define ShdXpt7 0xE2b6
+#define ShdXpt8 0xE2b7
+#define ShdXpt9 0xE2b8
+
+#define ShdPtr0 0xE2c0
+#define ShdPtr1 0xE2c1
+#define ShdPtr2 0xE2c2
+#define ShdPtr3 0xE2c3
+#define ShdPtr4 0xE2c4
+#define ShdPtr5 0xE2c5
+#define ShdPtr6 0xE2c6
+#define ShdPtr7 0xE2c7
+#define ShdPtr8 0xE2c8
+#define ShdPtr9 0xE2c9
+
+#define ShdSlp0 0xE2d0
+#define ShdSlp1 0xE2d1
+#define ShdSlp2 0xE2d2
+#define ShdSlp3 0xE2d3
+#define ShdSlp4 0xE2d4
+#define ShdSlp5 0xE2d5
+#define ShdSlp6 0xE2d6
+#define ShdSlp7 0xE2d7
+#define ShdSlp8 0xE2d8
+#define ShdSlp9 0xE2d9
+#define ShdPtrGVal 0xE2b0
+
+#define ShdLMAddrH 0xE2e0
+#define ShdLMAddrL 0xE2e1
+#define ShdLMDsizeH 0xE2e2
+#define ShdLMDsizeL 0xE2e3
+#define ShdLMData 0xE2e4
+
+#define Shade_X_Ea 0xE2e5
+#define Shade_Y_Ea 0xE2e6
+
+/*------------------------------------------------------------------------------
+ EXIF data ram access port
+------------------------------------------------------------------------------*/
+#define ExifData 0xE2f0
+#define ExifLMAddrH 0xE2f1
+#define ExifLMAddrL 0xE2f2
+#define DataCnt_Dbg_H 0xE2f3
+#define DataCnt_Dbg_L 0xE2f4
+#define ExifState 0xE2f5
+#define FrameCnt_BestShot 0xE2f6
+
+/*------------------------------------------------------------------------------
+ Color Interpolation Block
+------------------------------------------------------------------------------*/
+#define IntStrPxl 0xE300
+#define IntRTh 0xE301
+#define IntBTh 0xE302
+#define IntGTh 0xE303
+
+#define DeBugMode 0xE305
+#define DirectionThrL 0xE306
+#define DirectionThrH 0xE307
+
+#define DetailDirMul 0xE308
+#define DetailDirDiffMul 0xE309
+
+#define SyncGenStrH 0xE30a
+#define SyncGenStrL 0xE30b
+
+#define SyncGenPrd 0xE30c
+
+/*------------------------------------------------------------------------------
+ False Color Suppression
+------------------------------------------------------------------------------*/
+#define FalseTh 0xE310
+
+#define FcsHiYHTh 0xE311
+#define FcsHiCHTh 0xE312
+#define FcsHiCLTh 0xE313
+#define FcsHiSlp 0xE314
+
+#define FcsLoYLTh 0xE315
+#define FcsLoCHTh 0xE316
+#define FcsLoCLTh 0xE317
+#define FcsLoSlp 0xE318
+
+/*------------------------------------------------------------------------------
+ Color Matrix
+------------------------------------------------------------------------------*/
+#define CMAPO 0xE330
+#define CMA11H 0xE331
+#define CMA11L 0xE332
+#define CMA12H 0xE333
+#define CMA12L 0xE334
+#define CMA13H 0xE335
+#define CMA13L 0xE336
+#define CMA21H 0xE337
+#define CMA21L 0xE338
+#define CMA22H 0xE339
+#define CMA22L 0xE33a
+#define CMA23H 0xE33b
+#define CMA23L 0xE33c
+#define CMA31H 0xE33d
+#define CMA31L 0xE33e
+#define CMA32H 0xE33f
+#define CMA32L 0xE340
+#define CMA33H 0xE341
+#define CMA33L 0xE342
+#define RxOffH 0xE343
+#define RxOffL 0xE344
+#define GxOffH 0xE345
+#define GxOffL 0xE346
+#define BxOffH 0xE347
+#define BxOffL 0xE348
+
+/*------------------------------------------------------------------------------
+ Black Point Correction before Gamma
+------------------------------------------------------------------------------*/
+#define R_Bpc 0xE350
+#define G_Bpc 0xE351
+#define B_Bpc 0xE352
+
+/*------------------------------------------------------------------------------
+ Separate Gamma for R, G, and B
+------------------------------------------------------------------------------*/
+#define GmaYPtr00R 0xE400
+#define GmaYPtr01R 0xE401
+#define GmaYPtr02R 0xE402
+#define GmaYPtr03R 0xE403
+#define GmaYPtr04R 0xE404
+#define GmaYPtr05R 0xE405
+#define GmaYPtr06R 0xE406
+#define GmaYPtr07R 0xE407
+#define GmaYPtr08R 0xE408
+#define GmaYPtr09R 0xE409
+#define GmaYPtr0aR 0xE40a
+#define GmaYPtr0bR 0xE40b
+#define GmaYPtr0cR 0xE40c
+#define GmaYPtr0dR 0xE40d
+#define GmaYPtr0eR 0xE40e
+#define GmaYPtr0fR 0xE40f
+#define GmaYPtr10R 0xE410
+#define GmaYPtr11R 0xE411
+#define GmaYPtr12R 0xE412
+#define GmaYPtr13R 0xE413
+#define GmaYPtr14R 0xE414
+#define GmaYPtr15R 0xE415
+#define GmaYPtr16R 0xE416
+#define GmaYPtr17R 0xE417
+#define GmaYPtr18R 0xE418
+#define GmaYPtr19R 0xE419
+#define GmaYPtr1aR 0xE41a
+#define GmaYPtr1bR 0xE41b
+#define GmaYPtr1cR 0xE41c
+#define GmaYPtr1dR 0xE41d
+#define GmaYPtr1eR 0xE41e
+#define GmaYPtr1fR 0xE41f
+
+#define GmaYPtr00G 0xE420
+#define GmaYPtr01G 0xE421
+#define GmaYPtr02G 0xE422
+#define GmaYPtr03G 0xE423
+#define GmaYPtr04G 0xE424
+#define GmaYPtr05G 0xE425
+#define GmaYPtr06G 0xE426
+#define GmaYPtr07G 0xE427
+#define GmaYPtr08G 0xE428
+#define GmaYPtr09G 0xE429
+#define GmaYPtr0aG 0xE42a
+#define GmaYPtr0bG 0xE42b
+#define GmaYPtr0cG 0xE42c
+#define GmaYPtr0dG 0xE42d
+#define GmaYPtr0eG 0xE42e
+#define GmaYPtr0fG 0xE42f
+#define GmaYPtr10G 0xE430
+#define GmaYPtr11G 0xE431
+#define GmaYPtr12G 0xE432
+#define GmaYPtr13G 0xE433
+#define GmaYPtr14G 0xE434
+#define GmaYPtr15G 0xE435
+#define GmaYPtr16G 0xE436
+#define GmaYPtr17G 0xE437
+#define GmaYPtr18G 0xE438
+#define GmaYPtr19G 0xE439
+#define GmaYPtr1aG 0xE43a
+#define GmaYPtr1bG 0xE43b
+#define GmaYPtr1cG 0xE43c
+#define GmaYPtr1dG 0xE43d
+#define GmaYPtr1eG 0xE43e
+#define GmaYPtr1fG 0xE43f
+
+#define GmaYPtr00B 0xE440
+#define GmaYPtr01B 0xE441
+#define GmaYPtr02B 0xE442
+#define GmaYPtr03B 0xE443
+#define GmaYPtr04B 0xE444
+#define GmaYPtr05B 0xE445
+#define GmaYPtr06B 0xE446
+#define GmaYPtr07B 0xE447
+#define GmaYPtr08B 0xE448
+#define GmaYPtr09B 0xE449
+#define GmaYPtr0aB 0xE44a
+#define GmaYPtr0bB 0xE44b
+#define GmaYPtr0cB 0xE44c
+#define GmaYPtr0dB 0xE44d
+#define GmaYPtr0eB 0xE44e
+#define GmaYPtr0fB 0xE44f
+#define GmaYPtr10B 0xE450
+#define GmaYPtr11B 0xE451
+#define GmaYPtr12B 0xE452
+#define GmaYPtr13B 0xE453
+#define GmaYPtr14B 0xE454
+#define GmaYPtr15B 0xE455
+#define GmaYPtr16B 0xE456
+#define GmaYPtr17B 0xE457
+#define GmaYPtr18B 0xE458
+#define GmaYPtr19B 0xE459
+#define GmaYPtr1aB 0xE45a
+#define GmaYPtr1bB 0xE45b
+#define GmaYPtr1cB 0xE45c
+#define GmaYPtr1dB 0xE45d
+#define GmaYPtr1eB 0xE45e
+#define GmaYPtr1fB 0xE45f
+
+#define GmaXPtr00 0xE460
+#define GmaXPtr01 0xE461
+#define GmaXPtr02 0xE462
+#define GmaXPtr03 0xE463
+#define GmaXPtr04 0xE464
+#define GmaXPtr05 0xE465
+#define GmaXPtr06 0xE466
+#define GmaXPtr07 0xE467
+#define GmaXPtr08 0xE468
+#define GmaXPtr09 0xE469
+#define GmaXPtr0a 0xE46a
+#define GmaXPtr0b 0xE46b
+#define GmaXPtr0c 0xE46c
+#define GmaXPtr0d 0xE46d
+#define GmaXPtr0e 0xE46e
+#define GmaXPtr0f 0xE46f
+#define GmaXPtr10 0xE470
+#define GmaXPtr11 0xE471
+#define GmaXPtr12 0xE472
+#define GmaXPtr13 0xE473
+#define GmaXPtr14 0xE474
+#define GmaXPtr15 0xE475
+#define GmaXPtr16 0xE476
+#define GmaXPtr17 0xE477
+#define GmaXPtr18 0xE478
+#define GmaXPtr19 0xE479
+#define GmaXPtr1a 0xE47a
+#define GmaXPtr1b 0xE47b
+#define GmaXPtr1c 0xE47c
+#define GmaXPtr1d 0xE47d
+#define GmaXPtr1e 0xE47e
+#define GmaXPtr1f 0xE47f
+
+/*------------------------------------------------------------------------------
+ EFC1 Block Register
+------------------------------------------------------------------------------*/
+#define ThrLO 0xE501
+#define ThrLM 0xE502
+#define ThrMH 0xE503
+#define ThrHI 0xE504
+#define Boost 0xE505
+#define boost_EMVSlp0H 0xE506
+#define boost_EMVSlp0M 0xE507
+#define boost_EMVSlp0L 0xE508
+#define boost_EMVSlp1H 0xE509
+#define boost_EMVSlp1M 0xE50a
+#define boost_EMVSlp1L 0xE50b
+#define boost_RangeMaxH 0xE50c
+#define boost_RangeMaxL 0xE50d
+#define boost_RangeMinH 0xE50e
+#define boost_RangeMinL 0xE50f
+#define boost_WeightSlp0H 0xE510
+#define boost_WeightSlp0L 0xE511
+#define boost_WeightSlp1H 0xE512
+#define boost_WeightSlp1L 0xE513
+#define NonZeroThr 0xE514
+
+#define DropLevelMaxH 0xE515
+#define DropLevelMaxL 0xE516
+#define DropLevelMinH 0xE517
+#define DropLevelMinL 0xE518
+#define DropValue 0xE519
+#define DropLUTSlp0H 0xE51a
+#define DropLUTSlp0L 0xE51b
+#define DropLUTSlp1H 0xE51c
+#define DropLUTSlp1L 0xE51d
+#define EMDThr 0xE51e
+#define GrayRatioThr 0xE51f
+
+/*------------------------------------------------------------------------------
+ EFC2 Block Register
+------------------------------------------------------------------------------*/
+#define ThrLO2 0xE521
+#define ThrLM2 0xE522
+#define ThrMH2 0xE523
+#define ThrHI2 0xE524
+#define Boost2 0xE525
+#define boost_EMVSlpH02 0xE526
+#define boost_EMVSlpM02 0xE527
+#define boost_EMVSlpL02 0xE528
+#define boost_EMVSlpH12 0xE529
+#define boost_EMVSlpM12 0xE52a
+#define boost_EMVSlpL12 0xE52b
+#define boost_RangeMax2 0xE52c
+#define boost_RangeMin2 0xE52d
+#define boost_WeightSlp0H2 0xE52e
+#define boost_WeightSlp0L2 0xE52f
+#define boost_WeightSlp1H2 0xE530
+#define boost_WeightSlp1L2 0xE531
+#define NonZeroThr2 0xE532
+
+#define DropLevelMax2 0xE533
+#define DropLevelMin2 0xE534
+#define DropValue2 0xE535
+#define DropLUTSlp0H2 0xE536
+#define DropLUTSlp0L2 0xE537
+#define DropLUTSlp1H2 0xE538
+#define DropLUTSlp1L2 0xE539
+#define EMDThr2 0xE53a
+#define GrayRatioThr2 0xE53b
+
+#define yy_sum_fr3 0xE53c
+#define yy_sum_fr2 0xE53d
+#define yy_sum_fr1 0xE53e
+#define yy_sum_fr0 0xE53f
+
+#define BestWinStrXH 0xE540
+#define BestWinStrXL 0xE541
+#define BestWinStrYH 0xE542
+#define BestWinStrYL 0xE543
+#define BestWinEndXH 0xE544
+#define BestWinEndXL 0xE545
+#define BestWinEndYH 0xE546
+#define BestWinEndYL 0xE547
+
+/*------------------------------------------------------------------------------
+ Histogram Stretching & Equalization
+------------------------------------------------------------------------------*/
+#define Hst_PixelCntH 0xE550
+#define Hst_PixelCntM 0xE551
+#define Hst_PixelCntL 0xE552
+#define Hst_Mean 0xE553
+
+#define Region00 0xE554
+#define Region01 0xE555
+#define Region02 0xE556
+#define Region03 0xE557
+#define Region04 0xE558
+#define Region05 0xE559
+#define Region06 0xE55a
+#define Region07 0xE55b
+#define Region08 0xE55c
+#define Region09 0xE55d
+#define Region0A 0xE55e
+#define Region0B 0xE55f
+#define Region0C 0xE560
+#define Region0D 0xE561
+#define Region0E 0xE562
+#define Region0F 0xE563
+#define Region10 0xE564
+#define Region11 0xE565
+#define Region12 0xE566
+#define Region13 0xE567
+#define Region14 0xE568
+#define Region15 0xE569
+#define Region16 0xE56a
+#define Region17 0xE56b
+#define Region18 0xE56c
+#define Region19 0xE56d
+#define Region1A 0xE56e
+#define Region1B 0xE56f
+#define Region1C 0xE570
+#define Region1D 0xE571
+#define Region1E 0xE572
+#define Region1F 0xE573
+
+#define Thr00 0xE574
+#define Thr01 0xE575
+#define Thr02 0xE576
+#define Thr03 0xE577
+#define Thr04 0xE578
+#define Thr05 0xE579
+#define Thr06 0xE57A
+#define Thr07 0xE57B
+#define Thr08 0xE57C
+#define Thr09 0xE57D
+#define Thr0A 0xE57E
+#define Thr0B 0xE57F
+#define Thr0C 0xE580
+#define Thr0D 0xE581
+#define Thr0E 0xE582
+#define Thr0F 0xE583
+#define Thr10 0xE584
+#define Thr11 0xE585
+#define Thr12 0xE586
+#define Thr13 0xE587
+#define Thr14 0xE588
+#define Thr15 0xE589
+#define Thr16 0xE58A
+#define Thr17 0xE58B
+#define Thr18 0xE58C
+#define Thr19 0xE58D
+#define Thr1A 0xE58E
+#define Thr1B 0xE58F
+#define Thr1C 0xE590
+#define Thr1D 0xE591
+#define Thr1E 0xE592
+
+#define Line_Minus 0xE593
+
+/*------------------------------------------------------------------------------
+ Hue/saturation control
+ Point color approximation control
+------------------------------------------------------------------------------*/
+#define SatCtl 0xE5b0
+#define HueCtl 0xE5b1
+#define HueInpSel 0xE5b2
+#define HuePnt0Quad 0xE5b3
+#define HuePnt0TgtX 0xE5b4
+#define HuePnt0TgtY 0xE5b5
+#define HuePnt0SlpX 0xE5b6
+#define HuePnt0SlpY 0xE5b7
+#define HuePnt1Quad 0xE5b8
+#define HuePnt1TgtX 0xE5b9
+#define HuePnt1TgtY 0xE5ba
+#define HuePnt1SlpX 0xE5bb
+#define HuePnt1SlpY 0xE5bc
+#define HuePnt2Quad 0xE5bd
+#define HuePnt2TgtX 0xE5be
+#define HuePnt2TgtY 0xE5bf
+#define HuePnt2SlpX 0xE5c0
+#define HuePnt2SlpY 0xE5c1
+#define HuePnt3Quad 0xE5c2
+#define HuePnt3TgtX 0xE5c3
+#define HuePnt3TgtY 0xE5c4
+#define HuePnt3SlpX 0xE5c5
+#define HuePnt3SlpY 0xE5c6
+#define HuePnt4Quad 0xE5c7
+#define HuePnt4TgtX 0xE5c8
+#define HuePnt4TgtY 0xE5c9
+#define HuePnt4SlpX 0xE5ca
+#define HuePnt4SlpY 0xE5cb
+#define HuePnt5Quad 0xE5cc
+#define HuePnt5TgtX 0xE5cd
+#define HuePnt5TgtY 0xE5ce
+#define HuePnt5SlpX 0xE5cf
+#define HuePnt5SlpY 0xE5d0
+#define HuePnt6Quad 0xE5d1
+#define HuePnt6TgtX 0xE5d2
+#define HuePnt6TgtY 0xE5d3
+#define HuePnt6SlpX 0xE5d4
+#define HuePnt6SlpY 0xE5d5
+#define HuePnt7Quad 0xE5d6
+#define HuePnt7TgtX 0xE5d7
+#define HuePnt7TgtY 0xE5d8
+#define HuePnt7SlpX 0xE5d9
+#define HuePnt7SlpY 0xE5da
+
+/*------------------------------------------------------------------------------
+ Brightness/Contrast Control
+------------------------------------------------------------------------------*/
+#define YCntrst 0xE5e0
+#define YBLvl 0xE5e1
+#define YCntrstRef 0xE5e2
+
+/*------------------------------------------------------------------------------
+ Auto Function Common Control
+------------------------------------------------------------------------------*/
+#define AtoFrWait 0xE600
+#define AtoFrSkip 0xE601
+#define AtoChlSel 0xE603
+
+/*------------------------------------------------------------------------------
+ AE Window Register
+------------------------------------------------------------------------------*/
+#define AeMode1 0xE610
+#define AeMode2 0xE611
+#define AeMode3 0xE612
+#define Y_Target 0xE613
+#define AeLockFineBnd 0xE614
+#define AeUnlockBnd 0xE615
+#define AeFrSkip 0xE616
+
+#define IntTimeH 0xE620
+#define IntTimeM 0xE621
+#define IntTimeL 0xE622
+#define AeIntMinLmtH 0xE623
+#define AeIntMinLmtL 0xE624
+#define AeIntStepH 0xE625
+#define AeIntStepM 0xE626
+#define AeIntStepL 0xE627
+#define AeBndOffLmtH 0xE628
+#define AeBndOffLmtM 0xE629
+#define AeBndOffLmtL 0xE62a
+#define AeIntMaxLmtH 0xE62b
+#define AeIntMaxLmtM 0xE62c
+#define AeIntMaxLmtL 0xE62d
+
+#define PgaNow 0xE640
+#define PgaMin 0xE641
+#define PgaNom 0xE642
+#define PgaMax 0xE643
+
+#define KlGain 0xE648
+#define KlBndMin 0xE649
+#define KlBndNom 0xE64a
+#define KlBndMax 0xE64b
+
+#define AeSclLmt 0xE650
+#define AeFrgBck 0xE651
+#define AeVblVal 0xE652
+
+#define AeFrXWidH 0xE658
+#define AeFrXWidL 0xE659
+#define AeFrYWidH 0xE65a
+#define AeFrYWidL 0xE65b
+
+#define AeHblAddr 0xE660 // MCU CamMode
+#define AeHblMode 0xE661 // MCU CamStatus
+#define AeHblUnit 0xE662 // MCU CamFlag
+#define AeHblMin 0xE663
+#define AeHblMaxH 0xE664
+#define AeHblMaxL 0xE665
+
+#define AeCrseAddr1 0xE670 // shutter divide
+#define AeCrseAddr2 0xE671 // ANR
+#define AeCrseMode 0xE672
+
+#define AeFineAddr 0xE680 // MCU baud rate control
+#define AeFineMode 0xE681 // AWB even/odd map control
+#define AeFineUnit 0xE682 // AWB 1st rank user define
+#define AeFineMaxH 0xE683
+#define AeFineMaxL 0xE684
+
+#define AePgaAddr 0xE690
+#define AePgaMode 0xE691
+#define AePgaAdrStp 0xE692
+
+#define AeUpdAddr 0xE6a0
+#define AeUpdMode 0xE6a1
+
+#define AeDevSel 0xE6a8
+
+#define AeISO 0xE6a9
+#define AeShutter 0xE6aa
+
+/*------------------------------------------------------------------------------
+ AE Window Register
+------------------------------------------------------------------------------*/
+#define WinAStrX 0xE6c0
+#define WinAStrY 0xE6c1
+#define WinAEndX 0xE6c2
+#define WinAEndY 0xE6c3
+#define WinBStrX 0xE6c4
+#define WinBStrY 0xE6c5
+#define WinBEndX 0xE6c6
+#define WinBEndY 0xE6c7
+#define WinCStrX 0xE6c8
+#define WinCStrY 0xE6c9
+#define WinCEndX 0xE6ca
+#define WinCEndY 0xE6cb
+#define WinDStrX 0xE6cc
+#define WinDStrY 0xE6cd
+#define WinDEndX 0xE6ce
+#define WinDEndY 0xE6cf
+#define WinEStrX 0xE6d0
+#define WinEStrY 0xE6d1
+#define WinEEndX 0xE6d2
+#define WinEEndY 0xE6d3
+#define WinFStrX 0xE6d4
+#define WinFStrY 0xE6d5
+#define WinFEndX 0xE6d6
+#define WinFEndY 0xE6d7
+#define WinGStrX 0xE6d8
+#define WinGStrY 0xE6d9
+#define WinGEndX 0xE6da
+#define WinGEndY 0xE6db
+#define WinHStrX 0xE6dc
+#define WinHStrY 0xE6dd
+#define WinHEndX 0xE6de
+#define WinHEndY 0xE6df
+#define WinIStrX 0xE6e0
+#define WinIStrY 0xE6e1
+#define WinIEndX 0xE6e2
+#define WinIEndY 0xE6e3
+#define WinJStrX 0xE6e4
+#define WinJStrY 0xE6e5
+#define WinJEndX 0xE6e6
+#define WinJEndY 0xE6e7
+#define WinKStrX 0xE6e8
+#define WinKStrY 0xE6e9
+#define WinKEndX 0xE6ea
+#define WinKEndY 0xE6eb
+#define WinLStrX 0xE6ec
+#define WinLStrY 0xE6ed
+#define WinLEndX 0xE6ee
+#define WinLEndY 0xE6ef
+
+/*------------------------------------------------------------------------------
+ AE Window Weighting
+------------------------------------------------------------------------------*/
+#define WinABExpWght_f 0xE6f0
+#define WinCDExpWght_f 0xE6f1
+#define WinEFExpWght_f 0xE6f2
+#define WinGHExpWght_f 0xE6f3
+#define WinIJExpWght_f 0xE6f4
+#define WinKLExpWght_f 0xE6f5
+
+#define WinABExpWght_b 0xE6f6
+#define WinCDExpWght_b 0xE6f7
+#define WinEFExpWght_b 0xE6f8
+#define WinGHExpWght_b 0xE6f9
+#define WinIJExpWght_b 0xE6fa
+#define WinKLExpWght_b 0xE6fb
+
+/*------------------------------------------------------------------------------
+ AWB Mode Control
+------------------------------------------------------------------------------*/
+#define AwbMode1 0xE800
+#define AwbMode2 0xE801
+#define CbTarget 0xE802
+#define CrTarget 0xE803
+#define AwbLockBnd 0xE804
+#define AwbUnlockBnd 0xE805
+#define AwbWhiteBnd 0xE806
+
+#define AwbWhite 0xE807
+#define AwbBlack 0xE808
+#define AwbNumbr 0xE809
+#define AwbExpLvl 0xE80a
+#define AwbBlkBnd 0xE80b
+#define AwbTuneRange 0xE80c
+#define AwbFrSkip 0xE80d
+#define AwbWpd 0xE80e
+
+/*------------------------------------------------------------------------------
+ Awb Light Source Polygon Map
+--------------------------------------------------------------------------------
+#define WpdLn0Mode 0xE810
+#define WpdLn0CnstAH 0xE811
+#define WpdLn0CnstAL 0xE812
+#define WpdLn0CnstBH 0xE813
+#define WpdLn0CnstBL 0xE814
+
+#define WpdLn1Mode 0xE815
+#define WpdLn1CnstAH 0xE816
+#define WpdLn1CnstAL 0xE817
+#define WpdLn1CnstBH 0xE818
+#define WpdLn1CnstBL 0xE819
+
+#define WpdLn2Mode 0xE81a
+#define WpdLn2CnstAH 0xE81b
+#define WpdLn2CnstAL 0xE81c
+#define WpdLn2CnstBH 0xE81d
+#define WpdLn2CnstBL 0xE81e
+
+#define WpdLn3Mode 0xE820
+#define WpdLn3CnstAH 0xE821
+#define WpdLn3CnstAL 0xE822
+#define WpdLn3CnstBH 0xE823
+#define WpdLn3CnstBL 0xE824
+
+#define WpdLn4Mode 0xE825
+#define WpdLn4CnstAH 0xE826
+#define WpdLn4CnstAL 0xE827
+#define WpdLn4CnstBH 0xE828
+#define WpdLn4CnstBL 0xE829
+
+#define WpdLn5Mode 0xE82a
+#define WpdLn5CnstAH 0xE82b
+#define WpdLn5CnstAL 0xE82c
+#define WpdLn5CnstBH 0xE82d
+#define WpdLn5CnstBL 0xE82e
+
+#define WpdLn6Mode 0xE830
+#define WpdLn6CnstAH 0xE831
+#define WpdLn6CnstAL 0xE832
+#define WpdLn6CnstBH 0xE833
+#define WpdLn6CnstBL 0xE834
+
+#define WpdLn7Mode 0xE835
+#define WpdLn7CnstAH 0xE836
+#define WpdLn7CnstAL 0xE837
+#define WpdLn7CnstBH 0xE838
+#define WpdLn7CnstBL 0xE839
+
+#define WpdLn8Mode 0xE83a
+#define WpdLn8CnstAH 0xE83b
+#define WpdLn8CnstAL 0xE83c
+#define WpdLn8CnstBH 0xE83d
+#define WpdLn8CnstBL 0xE83e
+
+#define WpdLn9Mode 0xE840
+#define WpdLn9CnstAH 0xE841
+#define WpdLn9CnstAL 0xE842
+#define WpdLn9CnstBH 0xE843
+#define WpdLn9CnstBL 0xE844
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ Awb Light Source Box Map 3
+------------------------------------------------------------------------------*/
+#define WpdBox23ubts 0xe810
+#define WpdBox23ulxl 0xe811
+#define WpdBox23ulyl 0xe812
+#define WpdBox23lrxl 0xe813
+#define WpdBox23lryl 0xe814
+
+#define WpdBox22ubts 0xe815
+#define WpdBox22ulxl 0xe816
+#define WpdBox22ulyl 0xe817
+#define WpdBox22lrxl 0xe818
+#define WpdBox22lryl 0xe819
+
+#define WpdBox21ubts 0xe81a
+#define WpdBox21ulxl 0xe81b
+#define WpdBox21ulyl 0xe81c
+#define WpdBox21lrxl 0xe81d
+#define WpdBox21lryl 0xe81e
+
+#define WpdBox20ubts 0xe81f
+#define WpdBox20ulxl 0xe820
+#define WpdBox20ulyl 0xe821
+#define WpdBox20lrxl 0xe822
+#define WpdBox20lryl 0xe823
+
+#define WpdBox19ubts 0xe824
+#define WpdBox19ulxl 0xe825
+#define WpdBox19ulyl 0xe826
+#define WpdBox19lrxl 0xe827
+#define WpdBox19lryl 0xe828
+
+#define WpdBox18ubts 0xe829
+#define WpdBox18ulxl 0xe82a
+#define WpdBox18ulyl 0xe82b
+#define WpdBox18lrxl 0xe82c
+#define WpdBox18lryl 0xe82d
+
+#define WpdBox17ubts 0xe82e
+#define WpdBox17ulxl 0xe82f
+#define WpdBox17ulyl 0xe830
+#define WpdBox17lrxl 0xe831
+#define WpdBox17lryl 0xe832
+
+#define WpdBox16ubts 0xe833
+#define WpdBox16ulxl 0xe834
+#define WpdBox16ulyl 0xe835
+#define WpdBox16lrxl 0xe836
+#define WpdBox16lryl 0xe837
+
+/*------------------------------------------------------------------------------
+ Awb Light Source Box Map 2
+------------------------------------------------------------------------------*/
+#define WpdBox15ubts 0xe838
+#define WpdBox15ulxl 0xe839
+#define WpdBox15ulyl 0xe83a
+#define WpdBox15lrxl 0xe83b
+#define WpdBox15lryl 0xe83c
+
+#define WpdBox14ubts 0xe83d
+#define WpdBox14ulxl 0xe83e
+#define WpdBox14ulyl 0xe83f
+#define WpdBox14lrxl 0xe840
+#define WpdBox14lryl 0xe841
+
+#define WpdBox13ubts 0xe842
+#define WpdBox13ulxl 0xe843
+#define WpdBox13ulyl 0xe844
+#define WpdBox13lrxl 0xe845
+#define WpdBox13lryl 0xe846
+
+#define WpdBox12ubts 0xe847
+#define WpdBox12ulxl 0xe848
+#define WpdBox12ulyl 0xe849
+#define WpdBox12lrxl 0xe84a
+#define WpdBox12lryl 0xe84b
+
+#define WpdBox11ubts 0xe84c
+#define WpdBox11ulxl 0xe84d
+#define WpdBox11ulyl 0xe84e
+#define WpdBox11lrxl 0xe84f
+#define WpdBox11lryl 0xe850
+
+#define WpdBox10ubts 0xe851
+#define WpdBox10ulxl 0xe852
+#define WpdBox10ulyl 0xe853
+#define WpdBox10lrxl 0xe854
+#define WpdBox10lryl 0xe855
+
+#define WpdBox9ubts 0xe856
+#define WpdBox9ulxl 0xe857
+#define WpdBox9ulyl 0xe858
+#define WpdBox9lrxl 0xe859
+#define WpdBox9lryl 0xe85a
+
+#define WpdBox8ubts 0xe85b
+#define WpdBox8ulxl 0xe85c
+#define WpdBox8ulyl 0xe85d
+#define WpdBox8lrxl 0xe85e
+#define WpdBox8lryl 0xe85f
+
+/*------------------------------------------------------------------------------
+ Awb Light Source Box Map 1
+------------------------------------------------------------------------------*/
+#define WpdBox7ubts 0xE860
+#define WpdBox7ulxl 0xE861
+#define WpdBox7ulyl 0xE862
+#define WpdBox7lrxl 0xE863
+#define WpdBox7lryl 0xE864
+
+#define WpdBox6ubts 0xE865
+#define WpdBox6ulxl 0xE866
+#define WpdBox6ulyl 0xE867
+#define WpdBox6lrxl 0xE868
+#define WpdBox6lryl 0xE869
+
+#define WpdBox5ubts 0xE86a
+#define WpdBox5ulxl 0xE86b
+#define WpdBox5ulyl 0xE86c
+#define WpdBox5lrxl 0xE86d
+#define WpdBox5lryl 0xE86e
+
+#define WpdBox4ubts 0xE86f
+#define WpdBox4ulxl 0xE870
+#define WpdBox4ulyl 0xE871
+#define WpdBox4lrxl 0xE872
+#define WpdBox4lryl 0xE873
+
+#define WpdBox3ubts 0xE874
+#define WpdBox3ulxl 0xE875
+#define WpdBox3ulyl 0xE876
+#define WpdBox3lrxl 0xE877
+#define WpdBox3lryl 0xE878
+
+#define WpdBox2ubts 0xE879
+#define WpdBox2ulxl 0xE87a
+#define WpdBox2ulyl 0xE87b
+#define WpdBox2lrxl 0xE87c
+#define WpdBox2lryl 0xE87d
+
+#define WpdBox1ubts 0xE87e
+#define WpdBox1ulxl 0xE87f
+#define WpdBox1ulyl 0xE880
+#define WpdBox1lrxl 0xE881
+#define WpdBox1lryl 0xE882
+
+#define WpdBox0ubts 0xE883
+#define WpdBox0ulxl 0xE884
+#define WpdBox0ulyl 0xE885
+#define WpdBox0lrxl 0xE886
+#define WpdBox0lryl 0xE887
+
+/*------------------------------------------------------------------------------
+ AWB Window Weighting Register
+------------------------------------------------------------------------------*/
+#define WinABAwbWght_f 0xE890
+#define WinCDAwbWght_f 0xE891
+#define WinEFAwbWght_f 0xE892
+#define WinABAwbWght_b 0xE893
+#define WinCDAwbWght_b 0xE894
+#define WinEFAwbWght_b 0xE895
+
+/*------------------------------------------------------------------------------
+ AWB window selection, 2005/12/03/Sat/11/00/11/14/junsc
+------------------------------------------------------------------------------*/
+#define AWBWinStrX 0xE898
+#define AWBWinStrY 0xE899
+#define AWBWinEndX 0xE89a
+#define AWBWinEndY 0xE89b
+
+/*------------------------------------------------------------------------------
+ Awb Light Source Selection
+------------------------------------------------------------------------------*/
+#define B_Y_BlkSel1 0xE8a0
+#define B_Y_BlkSel2 0xE8a1
+#define B_Y_Sel 0xE8a2
+#define Max1Blk 0xE8a3
+#define Max2Blk 0xE8a4
+#define Max3Blk 0xE8a5
+
+/*------------------------------------------------------------------------------
+ R/G, B/G ratio
+------------------------------------------------------------------------------*/
+#define RGRatioH 0xE8b0
+#define RGRatioL 0xE8b1
+#define BGRatioH 0xE8b2
+#define BGRatioL 0xE8b3
+#define RGSft 0xE8b4
+#define BGSft 0xE8b5
+
+/*------------------------------------------------------------------------------
+ AF Mode Control
+------------------------------------------------------------------------------*/
+#define AFMode1 0xEA00
+#define AFMode2 0xEA01
+#define AFWinFEVSel 0xEA02
+#define AFFEVTh 0xEA03
+
+#define af_clp 0xEA10
+#define af_pcpf1 0xEA11
+#define af_pcpf2 0xEA12
+#define af_pcpf3 0xEA13
+#define af_pcpf4 0xEA14
+
+#define af_scpf1 0xEA18
+#define af_scpf2 0xEA19
+#define af_scpf3 0xEA1a
+#define af_scpf4 0xEA1b
+
+/*------------------------------------------------------------------------------
+ AF Window Selection
+------------------------------------------------------------------------------*/
+#define AFWinAStrX 0xEA20
+#define AFWinAStrY 0xEA21
+#define AFWinAEndX 0xEA22
+#define AFWinAEndY 0xEA23
+
+#define AFWinBStrX 0xEA24
+#define AFWinBStrY 0xEA25
+#define AFWinBEndX 0xEA26
+#define AFWinBEndY 0xEA27
+
+#define AFWinCStrX 0xEA28
+#define AFWinCStrY 0xEA29
+#define AFWinCEndX 0xEA2a
+#define AFWinCEndY 0xEA2b
+
+#define AFWinDStrX 0xEA2c
+#define AFWinDStrY 0xEA2d
+#define AFWinDEndX 0xEA2e
+#define AFWinDEndY 0xEA2f
+
+#define AFWinEStrX 0xEA30
+#define AFWinEStrY 0xEA31
+#define AFWinEEndX 0xEA32
+#define AFWinEEndY 0xEA33
+
+#define AFWinFStrX 0xEA34
+#define AFWinFStrY 0xEA35
+#define AFWinFEndX 0xEA36
+#define AFWinFEndY 0xEA37
+
+/*------------------------------------------------------------------------------
+ Actuator Control
+------------------------------------------------------------------------------*/
+#define AFManTrgDir 0xEB30
+#define AFFtlDrv 0xEB31
+#define AFManDrv 0xEB32
+#define AFManDrvSum 0xEB33
+#define AFManDrvSumCCW 0xEB34
+
+#define SMCIOSel 0xEB35
+#define SMCLoop 0xEB36
+
+/*------------------------------------------------------------------------------
+ Actuator Drive PWM 1
+------------------------------------------------------------------------------*/
+#define AFManIncH_A 0xEB40
+#define AFManIncL_A 0xEB41
+#define SMCCkPrdH_A 0xEB42
+#define SMCCkPrdL_A 0xEB43
+#define SMCTrPrd_A 0xEB44
+#define VCMDuty_A 0xEB45
+
+#define SMCTrPnt0_A 0xEB50
+#define SMCTrPnt1_A 0xEB51
+#define SMCTrPnt2_A 0xEB52
+#define SMCTrPnt3_A 0xEB53
+#define SMCTrPnt4_A 0xEB54
+#define SMCTrPnt5_A 0xEB55
+#define SMCTrPnt6_A 0xEB56
+#define SMCTrPnt7_A 0xEB57
+#define SMCTrPnt8_A 0xEB58
+#define SMCTrPnt9_A 0xEB59
+
+#define SMCPttA0_A 0xEB60
+#define SMCPttA1_A 0xEB61
+#define SMCPttA2_A 0xEB62
+#define SMCPttA3_A 0xEB63
+#define SMCPttA4_A 0xEB64
+#define SMCPttA5_A 0xEB65
+#define SMCPttA6_A 0xEB66
+#define SMCPttA7_A 0xEB67
+#define SMCPttA8_A 0xEB68
+#define SMCPttA9_A 0xEB69
+
+#define SMCPttB0_A 0xEB70
+#define SMCPttB1_A 0xEB71
+#define SMCPttB2_A 0xEB72
+#define SMCPttB3_A 0xEB73
+#define SMCPttB4_A 0xEB74
+#define SMCPttB5_A 0xEB75
+#define SMCPttB6_A 0xEB76
+#define SMCPttB7_A 0xEB77
+#define SMCPttB8_A 0xEB78
+#define SMCPttB9_A 0xEB79
+
+/*------------------------------------------------------------------------------
+ Actuator Drive PWM 2
+------------------------------------------------------------------------------*/
+#define AFManIncH_B 0xEB80
+#define AFManIncL_B 0xEB81
+#define SMCCkPrdH_B 0xEB82
+#define SMCCkPrdL_B 0xEB83
+#define SMCTrPrd_B 0xEB84
+#define VCMDuty_B 0xEB85
+
+#define SMCTrPnt0_B 0xEB90
+#define SMCTrPnt1_B 0xEB91
+#define SMCTrPnt2_B 0xEB92
+#define SMCTrPnt3_B 0xEB93
+#define SMCTrPnt4_B 0xEB94
+#define SMCTrPnt5_B 0xEB95
+#define SMCTrPnt6_B 0xEB96
+#define SMCTrPnt7_B 0xEB97
+#define SMCTrPnt8_B 0xEB98
+#define SMCTrPnt9_B 0xEB99
+
+#define SMCPttA0_B 0xEBa0
+#define SMCPttA1_B 0xEBa1
+#define SMCPttA2_B 0xEBa2
+#define SMCPttA3_B 0xEBa3
+#define SMCPttA4_B 0xEBa4
+#define SMCPttA5_B 0xEBa5
+#define SMCPttA6_B 0xEBa6
+#define SMCPttA7_B 0xEBa7
+#define SMCPttA8_B 0xEBa8
+#define SMCPttA9_B 0xEBa9
+
+#define SMCPttB0_B 0xEBb0
+#define SMCPttB1_B 0xEBb1
+#define SMCPttB2_B 0xEBb2
+#define SMCPttB3_B 0xEBb3
+#define SMCPttB4_B 0xEBb4
+#define SMCPttB5_B 0xEBb5
+#define SMCPttB6_B 0xEBb6
+#define SMCPttB7_B 0xEBb7
+#define SMCPttB8_B 0xEBb8
+#define SMCPttB9_B 0xEBb9
+
+/*------------------------------------------------------------------------------
+ Actuator Drive PWM 3
+------------------------------------------------------------------------------*/
+#define AFManIncH_C 0xEBc0
+#define AFManIncL_C 0xEBc1
+#define SMCCkPrdH_C 0xEBc2
+#define SMCCkPrdL_C 0xEBc3
+#define SMCTrPrd_C 0xEBc4
+#define VCMDuty_C 0xEBc5
+
+#define SMCTrPnt0_C 0xEBd0
+#define SMCTrPnt1_C 0xEBd1
+#define SMCTrPnt2_C 0xEBd2
+#define SMCTrPnt3_C 0xEBd3
+#define SMCTrPnt4_C 0xEBd4
+#define SMCTrPnt5_C 0xEBd5
+#define SMCTrPnt6_C 0xEBd6
+#define SMCTrPnt7_C 0xEBd7
+#define SMCTrPnt8_C 0xEBd8
+#define SMCTrPnt9_C 0xEBd9
+
+#define SMCPttA0_C 0xEBe0
+#define SMCPttA1_C 0xEBe1
+#define SMCPttA2_C 0xEBe2
+#define SMCPttA3_C 0xEBe3
+#define SMCPttA4_C 0xEBe4
+#define SMCPttA5_C 0xEBe5
+#define SMCPttA6_C 0xEBe6
+#define SMCPttA7_C 0xEBe7
+#define SMCPttA8_C 0xEBe8
+#define SMCPttA9_C 0xEBe9
+
+#define SMCPttB0_C 0xEBf0
+#define SMCPttB1_C 0xEBf1
+#define SMCPttB2_C 0xEBf2
+#define SMCPttB3_C 0xEBf3
+#define SMCPttB4_C 0xEBf4
+#define SMCPttB5_C 0xEBf5
+#define SMCPttB6_C 0xEBf6
+#define SMCPttB7_C 0xEBf7
+#define SMCPttB8_C 0xEBf8
+#define SMCPttB9_C 0xEBf9
+
+/*------------------------------------------------------------------------------
+ AE Statistics
+------------------------------------------------------------------------------*/
+#define AeFSM 0xEC00
+#define Y_Avg4F 0xEC01
+#define Y_AvgAll 0xEC02
+#define WinAYAvg 0xEC03
+#define WinBYAvg 0xEC04
+#define WinCYAvg 0xEC05
+#define WinDYAvg 0xEC06
+#define WinEYAvg 0xEC07
+#define WinFYAvg 0xEC08
+#define WinGYAvg 0xEC09
+#define WinHYAvg 0xEC0a
+#define WinIYAvg 0xEC0b
+#define WinJYAvg 0xEC0c
+#define WinKYAvg 0xEC0d
+#define WinLYAvg 0xEC0e
+
+/*------------------------------------------------------------------------------
+ AWB Statistics
+------------------------------------------------------------------------------*/
+#define AwbFSM 0xEC40
+#define CbAvg4F 0xEC41
+#define CrAvg4F 0xEC42
+
+#define CCntSumSel 0xEC45
+#define AwbRSumSel 0xEC46
+#define AwbGSumSel 0xEC47
+#define AwbBSumSel 0xEC48
+
+#define AwbRSum3 0xEC50
+#define AwbRSum2 0xEC51
+#define AwbRSum1 0xEC52
+#define AwbRSum0 0xEC53
+#define AwbGSum3 0xEC54
+#define AwbGSum2 0xEC55
+#define AwbGSum1 0xEC56
+#define AwbGSum0 0xEC57
+#define AwbBSum3 0xEC58
+#define AwbBSum2 0xEC59
+#define AwbBSum1 0xEC5a
+#define AwbBSum0 0xEC5b
+#define CCntSum2 0xEC5c
+#define CCntSum1 0xEC5d
+#define CCntSum0 0xEC5e
+
+#define RGainGuessH 0xEC60
+#define RGainGuessL 0xEC61
+#define BGainGuessH 0xEC62
+#define BGainGuessL 0xEC63
+#define BiasedGRH 0xEC64
+#define BiasedGRL 0xEC65
+#define BiasedGBH 0xEC66
+#define BiasedGBL 0xEC67
+
+/*------------------------------------------------------------------------------
+ AF Statistics
+------------------------------------------------------------------------------*/
+#define af_hcp_rx_byte2 0xEC80
+#define af_hcp_rx_byte1 0xEC81
+#define af_hcp_rx_byte0 0xEC82
+
+#define af_pct1_r1_byte2 0xEC83
+#define af_pct1_r1_byte1 0xEC84
+#define af_pct1_r1_byte0 0xEC85
+#define af_pct2_r1_byte2 0xEC86
+#define af_pct2_r1_byte1 0xEC87
+#define af_pct2_r1_byte0 0xEC88
+#define af_pct3_r1_byte2 0xEC89
+#define af_pct3_r1_byte1 0xEC8a
+#define af_pct3_r1_byte0 0xEC8b
+#define af_pct4_r1_byte2 0xEC8c
+#define af_pct4_r1_byte1 0xEC8d
+#define af_pct4_r1_byte0 0xEC8e
+
+#define af_pct1_r2_byte2 0xEC8f
+#define af_pct1_r2_byte1 0xEC90
+#define af_pct1_r2_byte0 0xEC91
+#define af_pct2_r2_byte2 0xEC92
+#define af_pct2_r2_byte1 0xEC93
+#define af_pct2_r2_byte0 0xEC94
+#define af_pct3_r2_byte2 0xEC95
+#define af_pct3_r2_byte1 0xEC96
+#define af_pct3_r2_byte0 0xEC97
+#define af_pct4_r2_byte2 0xEC98
+#define af_pct4_r2_byte1 0xEC99
+#define af_pct4_r2_byte0 0xEC9a
+
+#define af_sum1_r1_byte3 0xEC9b
+#define af_sum1_r1_byte2 0xEC9c
+#define af_sum1_r1_byte1 0xEC9d
+#define af_sum1_r1_byte0 0xEC9e
+#define af_sum2_r1_byte3 0xEC9f
+#define af_sum2_r1_byte2 0xECa0
+#define af_sum2_r1_byte1 0xECa1
+#define af_sum2_r1_byte0 0xECa2
+#define af_sum3_r1_byte3 0xECa3
+#define af_sum3_r1_byte2 0xECa4
+#define af_sum3_r1_byte1 0xECa5
+#define af_sum3_r1_byte0 0xECa6
+#define af_sum4_r1_byte3 0xECa7
+#define af_sum4_r1_byte2 0xECa8
+#define af_sum4_r1_byte1 0xECa9
+#define af_sum4_r1_byte0 0xECaa
+
+#define af_sum1_r2_byte3 0xECab
+#define af_sum1_r2_byte2 0xECac
+#define af_sum1_r2_byte1 0xECad
+#define af_sum1_r2_byte0 0xECae
+#define af_sum2_r2_byte3 0xECaf
+#define af_sum2_r2_byte2 0xECb0
+#define af_sum2_r2_byte1 0xECb1
+#define af_sum2_r2_byte0 0xECb2
+#define af_sum3_r2_byte3 0xECb3
+#define af_sum3_r2_byte2 0xECb4
+#define af_sum3_r2_byte1 0xECb5
+#define af_sum3_r2_byte0 0xECb6
+#define af_sum4_r2_byte3 0xECb7
+#define af_sum4_r2_byte2 0xECb8
+#define af_sum4_r2_byte1 0xECb9
+#define af_sum4_r2_byte0 0xECba
+
+#define WinAFEV 0xECbb
+
+#define AFWinASumB3 0xECbc
+#define AFWinASumB2 0xECbd
+#define AFWinASumB1 0xECbe
+#define AFWinASumB0 0xECbf
+
+#define AFWinBSumB3 0xECc0
+#define AFWinBSumB2 0xECc1
+#define AFWinBSumB1 0xECc2
+#define AFWinBSumB0 0xECc3
+
+#define AFWinCSumB3 0xECc4
+#define AFWinCSumB2 0xECc5
+#define AFWinCSumB1 0xECc6
+#define AFWinCSumB0 0xECc7
+
+#define AFWinDSumB3 0xECc8
+#define AFWinDSumB2 0xECc9
+#define AFWinDSumB1 0xECca
+#define AFWinDSumB0 0xECcb
+
+#define AFWinESumB3 0xECcc
+#define AFWinESumB2 0xECcd
+#define AFWinESumB1 0xECce
+#define AFWinESumB0 0xECcf
+
+#define AFWinFSumB3 0xECd0
+#define AFWinFSumB2 0xECd1
+#define AFWinFSumB1 0xECd2
+#define AFWinFSumB0 0xECd3
+
+/*------------------------------------------------------------------------------
+ MIPI Control register
+------------------------------------------------------------------------------*/
+#define MIPIMode 0xED00
+#define PLLCtlH 0xED01 //PLLCtl[19:0]
+#define PLLCtlM 0xED02
+#define PLLCtlL 0xED03
+#define M_Ctl 0xED04 //BandCtl[7:4],HSZeroCtl[3:0]
+#define LaneCtl 0xED05 //Enable : M0_Clk,M0_Data,S0_Clk,S0_Data,S1_Clk,S1_Data
+#define HSSettleCtl0 0xED06
+#define HSSettleCtl1 0xED07
+#define M_DPHYTestH 0xED08
+#define M_DPHYTestL 0xED09
+#define S0_DPHYTestH 0xED0a
+#define S0_DPHYTestL 0xED0b
+#define S1_DPHYTestH 0xED0c
+#define S1_DPHYTestL 0xED0d
+#define MIPI_ErrCode 0xED0e
+
+/*------------------------------------------------------------------------------
+ Image Size Register (Start)
+------------------------------------------------------------------------------*/
+// Scaler Control Selection (Start)
+#define CR_RatioXH 0xED10
+#define CR_RatioXL 0xED11
+#define CR_RatioYH 0xED12
+#define CR_RatioYL 0xED13
+#define CR_UpHBlankH 0xED14
+#define CR_UpHBlankL 0xED15
+#define CR_VRdRate_SclMode 0xED16
+#define CR_ClkMode_Bypss 0xED17
+
+#define Pre_RatioXH 0xED18
+#define Pre_RatioXL 0xED19
+#define Pre_RatioYH 0xED1A
+#define Pre_RatioYL 0xED1B
+#define Pre_UpHBlankH 0xED1C
+#define Pre_UpHBlankL 0xED1D
+#define Pre_VRdRate_SclMode 0xED1E
+#define Pre_ClkMode_Bypss 0xED1F
+
+#define Still_RatioX_SclH 0xED20
+#define Still_RatioX_SclL 0xED21
+#define Still_RatioY_SclH 0xED22
+#define Still_RatioY_SclL 0xED23
+#define Still_UpHBlankH 0xED24
+#define Still_UpHBlankL 0xED25
+#define Still_VRdRate_SclMode 0xED26
+#define Still_ClkMode_Bypss 0xED27
+
+#define Thu_RatioXH 0xED28
+#define Thu_RatioXL 0xED29
+#define Thu_RatioYH 0xED2A
+#define Thu_RatioYL 0xED2B
+#define Thu_UpHBlankH 0xED2C
+#define Thu_UpHBlankL 0xED2D
+#define Thu_VRdRate_SclMode 0xED2E
+#define Thu_ClkMode_Bypss 0xED2F
+// Scaler Control Selection (End)
+
+// Color Restoration Windows & Scaler Selection (Start)
+#define CR_WinXStrH 0xED30
+#define CR_WinXStrL 0xED31
+#define CR_WinYStrH 0xED32
+#define CR_WinYStrL 0xED33
+#define CR_WinWidthH 0xED34
+#define CR_WinWidthL 0xED35
+#define CR_WinHeightH 0xED36
+#define CR_WinHeightL 0xED37
+
+#define CR_SclWidthIH 0xED38
+#define CR_SclWidthIL 0xED39
+#define CR_SclHeightIH 0xED3A
+#define CR_SclHeightIL 0xED3B
+#define CR_SclWidthOH 0xED3C
+#define CR_SclWidthOL 0xED3D
+#define CR_SclHeightOH 0xED3E
+#define CR_SclHeightOL 0xED3F
+// Color Restoration Windows & Scaler Selection (End)
+
+// Preview Windows & Scaler Selection (Start)
+#define Pre_WinXStrH 0xED40
+#define Pre_WinXStrL 0xED41
+#define Pre_WinYStrH 0xED42
+#define Pre_WinYStrL 0xED43
+#define Pre_WinWidthH 0xED44
+#define Pre_WinWidthL 0xED45
+#define Pre_WinHeightH 0xED46
+#define Pre_WinHeightL 0xED47
+
+#define Pre_SclWidthIH 0xED48
+#define Pre_SclWidthIL 0xED49
+#define Pre_SclHeightIH 0xED4A
+#define Pre_SclHeightIL 0xED4B
+#define Pre_SclWidthOH 0xED4C
+#define Pre_SclWidthOL 0xED4D
+#define Pre_SclHeightOH 0xED4E
+#define Pre_SclHeightOL 0xED4F
+// Preview Windows & Scaler Selection (End)
+
+// Still Windows & Scaler Selection (Start)
+#define Still_WinXStrH 0xED50
+#define Still_WinXStrL 0xED51
+#define Still_WinYStrH 0xED52
+#define Still_WinYStrL 0xED53
+#define Still_WinWidthH 0xED54
+#define Still_WinWidthL 0xED55
+#define Still_WinHeightH 0xED56
+#define Still_WinHeightL 0xED57
+
+#define Still_SclWidthIH 0xED58
+#define Still_SclWidthIL 0xED59
+#define Still_SclHeightIH 0xED5A
+#define Still_SclHeightIL 0xED5B
+#define Still_SclWidthOH 0xED5C
+#define Still_SclWidthOL 0xED5D
+#define Still_SclHeightOH 0xED5E
+#define Still_SclHeightOL 0xED5F
+// Still Windows & Scaler Selection (End)
+
+// Thumbnail Windows & Scaler Selection (Start)
+#define Thu_WinXStrH 0xED60
+#define Thu_WinXStrL 0xED61
+#define Thu_WinYStrH 0xED62
+#define Thu_WinYStrL 0xED63
+#define Thu_WinWidthH 0xED64
+#define Thu_WinWidthL 0xED65
+#define Thu_WinHeightH 0xED66
+#define Thu_WinHeightL 0xED67
+
+#define Thu_SclWidthIH 0xED68
+#define Thu_SclWidthIL 0xED69
+#define Thu_SclHeightIH 0xED6A
+#define Thu_SclHeightIL 0xED6B
+#define Thu_SclWidthOH 0xED6C
+#define Thu_SclWidthOL 0xED6D
+#define Thu_SclHeightOH 0xED6E
+#define Thu_SclHeightOL 0xED6F
+// Thumbnail Windows & Scaler Selection (End)
+
+// Image Rotation Mode (Start)
+#define RotMode 0xED70
+// Image Rotation Mode (End)
+
+// Frame Skip Control (Start)
+#define FrmSkipNum 0xED71
+// Frame Skip Control (End)
+
+/*------------------------------------------------------------------------------
+ Best shot register
+------------------------------------------------------------------------------*/
+#define FrameSel1 0xEda0
+#define FrameSel2 0xEda1
+#define FrameSel3 0xEda2
+#define FrameLimitWr 0xEda3
+#define FrameLimitRd 0xEda4
+#define BestNumber 0xEda5
+#define FrameCntWr 0xEda6
+#define FrameSkip 0xEda7
+#define LastCnt 0xEda8
+
+#define ThumbSize0_H 0xEdc0
+#define ThumbSize0_L 0xEdc1
+#define ThumbSize1_H 0xEdc2
+#define ThumbSize1_L 0xEdc3
+#define ThumbSize2_H 0xEdc4
+#define ThumbSize2_L 0xEdc5
+#define ThumbSize3_H 0xEdc6
+#define ThumbSize3_L 0xEdc7
+#define ThumbSize4_H 0xEdc8
+#define ThumbSize4_L 0xEdc9
+#define ThumbSize5_H 0xEdca
+#define ThumbSize5_L 0xEdcb
+#define ThumbSize6_H 0xEdcc
+#define ThumbSize6_L 0xEdcd
+#define ThumbSize7_H 0xEdce
+#define ThumbSize7_L 0xEdcf
+#define ThumbSize8_H 0xEdd0
+#define ThumbSize8_L 0xEdd1
+
+#define SdramOffset0 0xEdd2
+#define SdramOffset1 0xEdd3
+#define SdramOffset2 0xEdd4
+
+
+/*------------------------------------------------------------------------------
+ SDRAM Control register
+------------------------------------------------------------------------------*/
+#define SdramMode1 0xEde0
+#define SdramMode2 0xEde1
+#define Mem_Type 0xEde2
+#define Freq 0xEde3
+#define MRSH 0xEde4
+#define MRSL 0xEde5
+#define TRC 0xEde6
+#define TRP 0xEde7
+#define TRCD 0xEde8
+#define TRFC 0xEde9
+
+#define BISTMode1 0xEdea
+#define BISTMode2 0xEdeb
+#define RefTime 0xEdec
+#define SD_Arbi_FifoLimit_H 0xEded
+#define SD_Arbi_FifoLimit_L 0xEdee
+#define BlankCnt 0xEdef
+
+
+/*------------------------------------------------------------------------------
+ SMIA Control register
+------------------------------------------------------------------------------*/
+#define SMIAMODE 0xEDF0
+#define SMIAOUTMODEH 0xEDF1
+#define SMIAOUTMODEL 0xEDF2
+#define SMIABypass 0xEDF3
+
+/*------------------------------------------------------------------------------
+ TV_ENB register & read address
+------------------------------------------------------------------------------*/
+#define ETC_EN 0xEDFE
+#define ETC_EN_RD 0xEDFF
+
+/*------------------------------------------------------------------------------
+ JPEG Encoder
+------------------------------------------------------------------------------*/
+#define JSizeH 0xEE01
+#define JSizeM 0xEE02
+#define JSizeL 0xEE03
+#define VBlank 0xEE04
+#define YHblank 0xEE05
+#define JWinIWidH 0xEE06 //(Wr10)
+#define JWinIWidL 0xEE07 //(Wr11)
+#define JWinOWidH 0xEE08 //(Wr14)
+#define JWinOWidL 0xEE09 //(Wr15)
+#define RowCntH 0xEE0a
+#define RowCntL 0xEE0b
+#define FlipHold 0xEE0c
+#define RstVal 0xEE0d
+#define JpgRowCntH 0xEE0e
+#define JpgRowCntL 0xEE0f
+
+#define JpgWidthH 0xEE10
+#define JpgWidthL 0xEE11
+#define JpgHeightH 0xEE12
+#define JpgHeightL 0xEE13
+#define RSF 0xEE15
+#define JpgOutMode 0xEE16
+#define Jpg_FifoLimit_H 0xEE17
+#define Jpg_FifoLimit_L 0xEE18
+#define JHBlank 0xEE19
+#define PrvMode 0xEE1a
+#define JVsyncWidth 0xEE1b
+#define JVsyncDlyH 0xEE1c
+#define JVsyncDlyL 0xEE1d
+#define JpgClkDiv 0xEE1e
+#define ReqWidth 0xEE1f
+
+/*------------------------------------------------------------------------------
+//ImgEffect
+------------------------------------------------------------------------------*/
+#define ImgEffectA 0xEE20
+#define ImgEffectB 0xEE21
+#define ImgEffectC 0xEE22
+#define ImgEffectD 0xEE23
+#define RChr 0xEE24 //(Wr6d)
+#define GChr 0xEE25 //(Wr6e)
+#define BChr 0xEE26 //(Wr6f)
+#define ImgEffectE 0xEE27
+#define SKETCH 0xEE28 // Color & Gray Sketch
+
+#define ReadEn_Blnk 0xEE2D
+#define Addr_Cnst_H 0xEE2E //jpeg WrAddr_H
+#define Addr_Cnst_L 0xEE2F //jpeg WrAddr_L
+
+#define Acc_Cb_Min 0xEE30
+#define Acc_Cb_Max 0xEE31
+#define Acc_Cr_Min 0xEE32
+#define Acc_Cr_Max 0xEE33
+
+#define Swp_Cb_Min1 0xEE34
+#define Swp_Cb_Max1 0xEE35
+#define Swp_Cb_Min2 0xEE36
+#define Swp_Cb_Max2 0xEE37
+#define Swp_Cr_Min1 0xEE38
+#define Swp_Cr_Max1 0xEE39
+#define Swp_Cr_Min2 0xEE3a
+#define Swp_Cr_Max2 0xEE3b
+
+#define Swp_Cb1 0xEE3c
+#define Swp_Cb2 0xEE3d
+#define Swp_Cr1 0xEE3e
+#define Swp_Cr2 0xEE3f
+
+#define ASwp_Cb_Min1 0xEE40
+#define ASwp_Cb_Max1 0xEE41
+#define ASwp_Cb_Min2 0xEE42
+#define ASwp_Cb_Max2 0xEE43
+#define ASwp_Cr_Min1 0xEE44
+#define ASwp_Cr_Max1 0xEE45
+#define ASwp_Cr_Min2 0xEE46
+#define ASwp_Cr_Max2 0xEE47
+
+#define ASwp_Cb1 0xEE48
+#define ASwp_Cb2 0xEE49
+#define ASwp_Cr1 0xEE4a
+#define ASwp_Cr2 0xEE4b
+
+/*------------------------------------------------------------------------------
+// AdToneCu
+------------------------------------------------------------------------------*/
+#define Mean_H 0xEE50
+#define Mean_L 0xEE60
+
+#define Thr0_H 0xEE51
+#define Thr1_H 0xEE52
+#define Thr2_H 0xEE53
+#define Thr3_H 0xEE54
+#define Thr4_H 0xEE55
+#define Thr5_H 0xEE56
+#define Thr6_H 0xEE57
+#define Thr7_H 0xEE58
+#define Thr8_H 0xEE59
+#define Thr9_H 0xEE5A
+#define ThrA_H 0xEE5B
+#define ThrB_H 0xEE5C
+#define ThrC_H 0xEE5D
+#define ThrD_H 0xEE5E
+#define ThrE_H 0xEE5F
+
+#define Thr0_L 0xEE61
+#define Thr1_L 0xEE62
+#define Thr2_L 0xEE63
+#define Thr3_L 0xEE64
+#define Thr4_L 0xEE65
+#define Thr5_L 0xEE66
+#define Thr6_L 0xEE67
+#define Thr7_L 0xEE68
+#define Thr8_L 0xEE69
+#define Thr9_L 0xEE6A
+#define ThrA_L 0xEE6B
+#define ThrB_L 0xEE6C
+#define ThrC_L 0xEE6D
+#define ThrD_L 0xEE6E
+#define ThrE_L 0xEE6F
+
+#define Region0 0xEE70
+#define Region1 0xEE71
+#define Region2 0xEE72
+#define Region3 0xEE73
+#define Region4 0xEE74
+#define Region5 0xEE75
+#define Region6 0xEE76
+#define Region7 0xEE77
+#define Region8 0xEE78
+#define Region9 0xEE79
+#define RegionA 0xEE7A
+#define RegionB 0xEE7B
+#define RegionC 0xEE7C
+#define RegionD 0xEE7D
+#define RegionE 0xEE7E
+#define RegionF 0xEE7F
+
+#define PixelCntH 0xEE80
+#define PixelCntM 0xEE81
+#define PixelCntL 0xEE82
+
+/*------------------------------------------------------------------------------
+ Legacy, not used for real
+------------------------------------------------------------------------------*/
+#define VscStr 0xEE90
+#define VscEnd 0xEE91
+#define BlkStr 0xEE92
+#define BlkEnd 0xEE93
+#define HscStr 0xEE94
+#define HscEndH 0xEE95
+#define HscEndL 0xEE96
+#define AeVblMaxH 0xEE98
+#define AeVblMaxL 0xEE99
+#define AFFrFEVH 0xEE9a
+#define AFFrFEVL 0xEE9b
+#define VscVldPrd 0xEE9c
+
+/*------------------------------------------------------------------------------
+ YCAvg TEST
+------------------------------------------------------------------------------*/
+#define YCAvgTest0 0xEEa0
+#define YCAvgTest1 0xEEa1
+#define YCAvgTest2 0xEEa2
+#define YCAvgTest3 0xEEa3
+
+/*------------------------------------------------------------------------------
+ Still Stabilizer
+------------------------------------------------------------------------------*/
+#define Still_Control_Skip 0xF000
+#define Still_Margin 0xF001
+#define Still_In_FrameCnt 0xF002
+#define Still_Mean 0xF003
+
+// CR Parameter (Start)
+#define Still_RatioX_H 0xF004
+#define Still_RatioX_M 0xF005
+#define Still_RatioX_L 0xF006
+#define Still_RatioY_H 0xF007
+#define Still_RatioY_M 0xF008
+#define Still_RatioY_L 0xF009
+
+#define Still_MaxThr_H 0xF00a
+#define Still_MaxThr_L 0xF00b
+#define Still_MinThr_H 0xF00c
+#define Still_MinThr_L 0xF00d
+
+#define Still_CR_Weight_1 0xF010
+#define Still_CR_Weight_2 0xF011
+#define Still_CR_Weight_3 0xF012
+
+#define Still_Y_Thr_L 0xF013
+#define Still_Thr_Min_Y_L 0xF014
+#define Still_Thr_Max_Y_L 0xF015
+
+#define Still_Y_Thr_H 0xF016
+#define Still_Thr_Min_Y_H 0xF017
+#define Still_Thr_Max_Y_H 0xF018
+
+#define Stretching_Max 0xF019
+// CR Parameter (End)
+
+// NR Parameter (Start)
+#define Still_Level_L 0xF020
+#define Still_Level_H 0xF021
+
+#define Still_Edge_Thr_Min 0xF022
+#define Still_Edge_Thr_Max 0xF023
+#define Still_Edge_Thr_Gain 0xF024
+
+#define Still_Flat_C_Weight 0xF025
+#define Still_Edge_C_Weight 0xF026
+#define Still_Edge_B_Gain 0xF027
+
+#define Still_Y_Thr1 0xF028
+#define Still_Y_Thr2 0xF029
+#define Still_C_Thr_Min 0xF02a
+#define Still_C_Thr_Max 0xF02b
+
+#define Still_C_Thr_Ext 0xF02c
+// NR Parameter (End)
+
+#define Still_SyncGenStrH 0xF030
+#define Still_SyncGenStrL 0xF031
+
+// LUT Parameter (Start)
+#define Y_000 0xF100
+#define Y_001 0xF101
+#define Y_002 0xF102
+#define Y_003 0xF103
+#define Y_004 0xF104
+#define Y_005 0xF105
+#define Y_006 0xF106
+#define Y_007 0xF107
+#define Y_008 0xF108
+#define Y_009 0xF109
+#define Y_010 0xF10a
+#define Y_011 0xF10b
+#define Y_012 0xF10c
+#define Y_013 0xF10d
+#define Y_014 0xF10e
+#define Y_015 0xF10f
+#define Y_016 0xF110
+#define Y_017 0xF111
+#define Y_018 0xF112
+#define Y_019 0xF113
+#define Y_020 0xF114
+#define Y_021 0xF115
+#define Y_022 0xF116
+#define Y_023 0xF117
+#define Y_024 0xF118
+#define Y_025 0xF119
+#define Y_026 0xF11a
+#define Y_027 0xF11b
+#define Y_028 0xF11c
+#define Y_029 0xF11d
+#define Y_030 0xF11e
+#define Y_031 0xF11f
+#define Y_032 0xF120
+#define Y_033 0xF121
+#define Y_034 0xF122
+#define Y_035 0xF123
+#define Y_036 0xF124
+#define Y_037 0xF125
+#define Y_038 0xF126
+#define Y_039 0xF127
+#define Y_040 0xF128
+#define Y_041 0xF129
+#define Y_042 0xF12a
+#define Y_043 0xF12b
+#define Y_044 0xF12c
+#define Y_045 0xF12d
+#define Y_046 0xF12e
+#define Y_047 0xF12f
+#define Y_048 0xF130
+#define Y_049 0xF131
+#define Y_050 0xF132
+#define Y_051 0xF133
+#define Y_052 0xF134
+#define Y_053 0xF135
+#define Y_054 0xF136
+#define Y_055 0xF137
+#define Y_056 0xF138
+#define Y_057 0xF139
+#define Y_058 0xF13a
+#define Y_059 0xF13b
+#define Y_060 0xF13c
+#define Y_061 0xF13d
+#define Y_062 0xF13e
+#define Y_063 0xF13f
+#define Y_064 0xF140
+#define Y_065 0xF141
+#define Y_066 0xF142
+#define Y_067 0xF143
+#define Y_068 0xF144
+#define Y_069 0xF145
+#define Y_070 0xF146
+#define Y_071 0xF147
+#define Y_072 0xF148
+#define Y_073 0xF149
+#define Y_074 0xF14a
+#define Y_075 0xF14b
+#define Y_076 0xF14c
+#define Y_077 0xF14d
+#define Y_078 0xF14e
+#define Y_079 0xF14f
+#define Y_080 0xF150
+#define Y_081 0xF151
+#define Y_082 0xF152
+#define Y_083 0xF153
+#define Y_084 0xF154
+#define Y_085 0xF155
+#define Y_086 0xF156
+#define Y_087 0xF157
+#define Y_088 0xF158
+#define Y_089 0xF159
+#define Y_090 0xF15a
+#define Y_091 0xF15b
+#define Y_092 0xF15c
+#define Y_093 0xF15d
+#define Y_094 0xF15e
+#define Y_095 0xF15f
+#define Y_096 0xF160
+#define Y_097 0xF161
+#define Y_098 0xF162
+#define Y_099 0xF163
+#define Y_100 0xF164
+#define Y_101 0xF165
+#define Y_102 0xF166
+#define Y_103 0xF167
+#define Y_104 0xF168
+#define Y_105 0xF169
+#define Y_106 0xF16a
+#define Y_107 0xF16b
+#define Y_108 0xF16c
+#define Y_109 0xF16d
+#define Y_110 0xF16e
+#define Y_111 0xF16f
+#define Y_112 0xF170
+#define Y_113 0xF171
+#define Y_114 0xF172
+#define Y_115 0xF173
+#define Y_116 0xF174
+#define Y_117 0xF175
+#define Y_118 0xF176
+#define Y_119 0xF177
+#define Y_120 0xF178
+#define Y_121 0xF179
+#define Y_122 0xF17a
+#define Y_123 0xF17b
+#define Y_124 0xF17c
+#define Y_125 0xF17d
+#define Y_126 0xF17e
+#define Y_127 0xF17f
+#define Y_128 0xF180
+#define Y_129 0xF181
+#define Y_130 0xF182
+#define Y_131 0xF183
+#define Y_132 0xF184
+#define Y_133 0xF185
+#define Y_134 0xF186
+#define Y_135 0xF187
+#define Y_136 0xF188
+#define Y_137 0xF189
+#define Y_138 0xF18a
+#define Y_139 0xF18b
+#define Y_140 0xF18c
+#define Y_141 0xF18d
+#define Y_142 0xF18e
+#define Y_143 0xF18f
+#define Y_144 0xF190
+#define Y_145 0xF191
+#define Y_146 0xF192
+#define Y_147 0xF193
+#define Y_148 0xF194
+#define Y_149 0xF195
+#define Y_150 0xF196
+#define Y_151 0xF197
+#define Y_152 0xF198
+#define Y_153 0xF199
+#define Y_154 0xF19a
+#define Y_155 0xF19b
+#define Y_156 0xF19c
+#define Y_157 0xF19d
+#define Y_158 0xF19e
+#define Y_159 0xF19f
+#define Y_160 0xF1a0
+#define Y_161 0xF1a1
+#define Y_162 0xF1a2
+#define Y_163 0xF1a3
+#define Y_164 0xF1a4
+#define Y_165 0xF1a5
+#define Y_166 0xF1a6
+#define Y_167 0xF1a7
+#define Y_168 0xF1a8
+#define Y_169 0xF1a9
+#define Y_170 0xF1aa
+#define Y_171 0xF1ab
+#define Y_172 0xF1ac
+#define Y_173 0xF1ad
+#define Y_174 0xF1ae
+#define Y_175 0xF1af
+#define Y_176 0xF1b0
+#define Y_177 0xF1b1
+#define Y_178 0xF1b2
+#define Y_179 0xF1b3
+#define Y_180 0xF1b4
+#define Y_181 0xF1b5
+#define Y_182 0xF1b6
+#define Y_183 0xF1b7
+#define Y_184 0xF1b8
+#define Y_185 0xF1b9
+#define Y_186 0xF1ba
+#define Y_187 0xF1bb
+#define Y_188 0xF1bc
+#define Y_189 0xF1bd
+#define Y_190 0xF1be
+#define Y_191 0xF1bf
+#define Y_192 0xF1c0
+#define Y_193 0xF1c1
+#define Y_194 0xF1c2
+#define Y_195 0xF1c3
+#define Y_196 0xF1c4
+#define Y_197 0xF1c5
+#define Y_198 0xF1c6
+#define Y_199 0xF1c7
+#define Y_200 0xF1c8
+#define Y_201 0xF1c9
+#define Y_202 0xF1ca
+#define Y_203 0xF1cb
+#define Y_204 0xF1cc
+#define Y_205 0xF1cd
+#define Y_206 0xF1ce
+#define Y_207 0xF1cf
+#define Y_208 0xF1d0
+#define Y_209 0xF1d1
+#define Y_210 0xF1d2
+#define Y_211 0xF1d3
+#define Y_212 0xF1d4
+#define Y_213 0xF1d5
+#define Y_214 0xF1d6
+#define Y_215 0xF1d7
+#define Y_216 0xF1d8
+#define Y_217 0xF1d9
+#define Y_218 0xF1da
+#define Y_219 0xF1db
+#define Y_220 0xF1dc
+#define Y_221 0xF1dd
+#define Y_222 0xF1de
+#define Y_223 0xF1df
+#define Y_224 0xF1e0
+#define Y_225 0xF1e1
+#define Y_226 0xF1e2
+#define Y_227 0xF1e3
+#define Y_228 0xF1e4
+#define Y_229 0xF1e5
+#define Y_230 0xF1e6
+#define Y_231 0xF1e7
+#define Y_232 0xF1e8
+#define Y_233 0xF1e9
+#define Y_234 0xF1ea
+#define Y_235 0xF1eb
+#define Y_236 0xF1ec
+#define Y_237 0xF1ed
+#define Y_238 0xF1ee
+#define Y_239 0xF1ef
+#define Y_240 0xF1f0
+#define Y_241 0xF1f1
+#define Y_242 0xF1f2
+#define Y_243 0xF1f3
+#define Y_244 0xF1f4
+#define Y_245 0xF1f5
+#define Y_246 0xF1f6
+#define Y_247 0xF1f7
+#define Y_248 0xF1f8
+#define Y_249 0xF1f9
+#define Y_250 0xF1fa
+#define Y_251 0xF1fb
+#define Y_252 0xF1fc
+#define Y_253 0xF1fd
+#define Y_254 0xF1fe
+#define Y_255 0xF1ff
+// LUT Parameter (End)
+
+/*------------------------------------------------------------------------------
+ Face Tracking
+------------------------------------------------------------------------------*/
+#define FaceAddrH 0xF200
+#define FaceAddrL 0xF201
+#define FaceWDataH 0xF202
+#define FaceWDataL 0xF203
+#define FaceRDataH 0xF204
+#define FaceRDataL 0xF205
+#define FaceRW 0xF206
+
+#define FaceModeReg 0xF207
+#define FaceFrmComReg 0xF208
+#define FaceFinishReg 0xF209
+#define ROIModeRegH 0xF20A
+#define ROIModeRegL 0xF20B
+#define ROIThick 0xF20C
+#define FaceAFPosH 0xF20F
+#define FaceAFPosL 0xF210
+#define AutoSelAFPos 0xF211
+#define FaceResultCnt 0xF212
+
+#define FaceAStrX_8051H 0xF3F1
+#define FaceAStrX_8051L 0xF3F2
+#define FaceAStrY_8051H 0xF3F3
+#define FaceAStrY_8051L 0xF3F4
+#define FaceAEndX_8051H 0xF3F5
+#define FaceAEndX_8051L 0xF3F6
+#define FaceAEndY_8051H 0xF3F7
+#define FaceAEndY_8051L 0xF3F8
+
+#define FaceBStrX_8051H 0xF3F9
+#define FaceBStrX_8051L 0xF3FA
+#define FaceBStrY_8051H 0xF3FB
+#define FaceBStrY_8051L 0xF3FC
+#define FaceBEndX_8051H 0xF3FD
+#define FaceBEndX_8051L 0xF3FE
+#define FaceBEndY_8051H 0xF3FF
+#define FaceBEndY_8051L 0xF400
+
+#define FaceCStrX_8051H 0xF401
+#define FaceCStrX_8051L 0xF402
+#define FaceCStrY_8051H 0xF403
+#define FaceCStrY_8051L 0xF404
+#define FaceCEndX_8051H 0xF405
+#define FaceCEndX_8051L 0xF406
+#define FaceCEndY_8051H 0xF407
+#define FaceCEndY_8051L 0xF408
+
+#define FaceDStrX_8051H 0xF409
+#define FaceDStrX_8051L 0xF40A
+#define FaceDStrY_8051H 0xF40B
+#define FaceDStrY_8051L 0xF40C
+#define FaceDEndX_8051H 0xF40D
+#define FaceDEndX_8051L 0xF40E
+#define FaceDEndY_8051H 0xF40F
+#define FaceDEndY_8051L 0xF410
+
+#define FaceEStrX_8051H 0xF411
+#define FaceEStrX_8051L 0xF412
+#define FaceEStrY_8051H 0xF413
+#define FaceEStrY_8051L 0xF414
+#define FaceEEndX_8051H 0xF415
+#define FaceEEndX_8051L 0xF416
+#define FaceEEndY_8051H 0xF417
+#define FaceEEndY_8051L 0xF418
+
+#define FaceFStrX_8051H 0xF419
+#define FaceFStrX_8051L 0xF41A
+#define FaceFStrY_8051H 0xF41B
+#define FaceFStrY_8051L 0xF41C
+#define FaceFEndX_8051H 0xF41D
+#define FaceFEndX_8051L 0xF41E
+#define FaceFEndY_8051H 0xF41F
+#define FaceFEndY_8051L 0xF420
+
+#define FaceGStrX_8051H 0xF421
+#define FaceGStrX_8051L 0xF422
+#define FaceGStrY_8051H 0xF423
+#define FaceGStrY_8051L 0xF424
+#define FaceGEndX_8051H 0xF425
+#define FaceGEndX_8051L 0xF426
+#define FaceGEndY_8051H 0xF427
+#define FaceGEndY_8051L 0xF428
+
+#define FaceHStrX_8051H 0xF429
+#define FaceHStrX_8051L 0xF42A
+#define FaceHStrY_8051H 0xF42B
+#define FaceHStrY_8051L 0xF42C
+#define FaceHEndX_8051H 0xF42D
+#define FaceHEndX_8051L 0xF42E
+#define FaceHEndY_8051H 0xF42F
+#define FaceHEndY_8051L 0xF430
+
+#define FaceIStrX_8051H 0xF431
+#define FaceIStrX_8051L 0xF432
+#define FaceIStrY_8051H 0xF433
+#define FaceIStrY_8051L 0xF434
+#define FaceIEndX_8051H 0xF435
+#define FaceIEndX_8051L 0xF436
+#define FaceIEndY_8051H 0xF437
+#define FaceIEndY_8051L 0xF438
+
+#define FaceJStrX_8051H 0xF439
+#define FaceJStrX_8051L 0xF43A
+#define FaceJStrY_8051H 0xF43B
+#define FaceJStrY_8051L 0xF43C
+#define FaceJEndX_8051H 0xF43D
+#define FaceJEndX_8051L 0xF43E
+#define FaceJEndY_8051H 0xF43F
+#define FaceJEndY_8051L 0xF440
+
+#define EnAWBFaceH 0xF467
+#define EnAWBFaceL 0xF468
+#define EnAEFaceH 0xF469
+#define EnAEFaceL 0xF46A
+#define EnAFFaceL 0xF46B
+
+/*------------------------------------------------------------------------------
+ Low Illiminance Image Data Clipping Test
+------------------------------------------------------------------------------*/
+#define En_Debug_LowIll 0xF500
+
+#define Yx_Clip_High 0xF501
+#define Yx_Clip_Low 0xF502
+#define Yx_Target_Value 0xF503
+
+#define Cb_Clip_High 0xF504
+#define Cb_Clip_Low 0xF505
+#define Cb_Target_Value 0xF506
+
+#define Cr_Clip_High 0xF507
+#define Cr_Clip_Low 0xF508
+#define Cr_Target_Value 0xF509
+
+
+typedef enum
+{
+ enISP_AE_ISO_AUTO = 0x00,
+ enISP_AE_ISO_100,
+ enISP_AE_ISO_200,
+ enISP_AE_ISO_300,
+ enISP_AE_ISO_400,
+ enISP_AE_ISO_500,
+ enISP_AE_ISO_600,
+ enISP_AE_ISO_700,
+ enISP_AE_ISO_800
+}enIsp3AEISO; // update by Jacky
+
+typedef enum
+{
+ enISP_Scene_Auto = 0x00,
+ enISP_Scene_Portrait,
+ enISP_Scene_Landscape,
+ enISP_Scene_Indoor,
+ enISP_Scene_Sports,
+ enISP_Scene_Night,
+ enISP_Scene_Candle,
+ enISP_Scene_Fireworks,
+ enISP_Scene_Snow,
+ enISP_Scene_Sunset
+}enIsp3SceneMode; // update by Jacky
+
+typedef struct
+{
+ ClUint_8 bOutPJpeg;
+ ClUint_8 bThumbnail;
+}_tIspOutputModeCtrl;
+
+/* Functions */
+void System_IICWrite( ClUint_8 id, ClUint_8 addr, ClUint_8 data);
+ClUint_16 System_IICRead(ClUint_16 addr);
+
+ClUint_16 CoreISP3_I2C_Read( ClUint_16 addr );
+int CoreISP3_I2C_Write( ClUint_16 addr, ClUint_8 data );
+void CoreISP3_I2C_Write_Bulk( ClUint_16 addr, ClUint_8 data );
+
+#ifdef IIC_BURST_MODE
+void ISP3_FlashromBurstWrite(int writeStartAddress, ClUint_8* data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount));
+#endif //4 IIC_BURST_MODE
+
+void CoreISP3_I2C_Partial_Write( ClUint_16 Addr, ClUint_16 HighBit, ClUint_16 LowBit, ClUint_8 Data );
+Cl_Bool CoreISP3_LSC_TableDownLoad( void );
+ClUint_8 CoreISP3_MCU_CodeDownload( ClUint_8 * pInitialData, ClUint_32 InitialDataSize, enIsp3DownloadMode ModeParam );
+void ISP3_FlashromFormat(void);
+void ISP3_FlashromBlockErase(int eraseStartAddress);
+//void ISP3_FlashromWrite(int writeStartAddress, ClUint_8* data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount) = Cl_Null);
+//void ISP3_FlashromRead(int readStartAddress, ClUint_8 *data, int length, void (*callbackFunc)(ClUint_8 *data, int n, int nCount) = Cl_Null);
+void CoreISP3_Send_Command( unsigned char Cmd_Type );
+void CoreISP3_OutpYCbCr( void );
+void CoreISP3_RGB565_Out( void );
+void CoreISP3_OutpJPEG_Resolution( Cl_Bool bThumbnail , enIsp3OutResolution OutResolution);
+void CoreISP3_OutpJPEG( Cl_Bool bThumbnail );
+void CoreISP3_SetJPEG_Quality_Factor(enIsp3JPEGQF value);
+ClUint_32 CoreISP3_ReadJPEG_Size(void);
+void CoreISP3_SetResolution( enIsp3OutResolution OutResolution , CMD_Mode Mode);
+void CoreISP3_SetAutoExposure( enIsp3FunctionsAE AE_Param );
+void CoreISP3_SetAutoWhiteBalance( enIsp3FunctionsAWB AWB_Param );
+void CoreISP3_SetAutoFocus( enIsp3FunctionsAF AF_Param );
+void CoreISP3_SetAutoFocus_FullScan(void);
+ClUint_32 CoreISP3_GetShutterSpeed(void);
+ClUint_32 CoreISP3_GetAutoFocusState(void);
+ClUint_32 CoreISP3_GetISOGain(void);
+void CoreISP3_SetANR( enISP3FunctionsANRLevel ANR_Param );
+void CoreISP3_SetWDR( _tISP_WDR_CTRL *stIspWdrCtrl );
+void CoreISP3_SetFaceTracking( Cl_Bool FaceTrackingParam );
+void CoreISP3_SetFaceAE( Cl_Bool FaceAEParam );
+void CoreISP3_SetFaceAF( Cl_Bool FaceAFParam );
+void CoreISP3_SetFaceAWB( Cl_Bool FaceAWBParam );
+void CoreISP3_SetFaceRotation( Cl_Bool FaceRotation );
+void CoreISP3_SetFaceROIThick( enIsp3FaceROIThick FaceRoiThickParam );
+void CoreISP3_SetFaceUserMode( enIspFaceUserMode FaceUserModeParam );
+void CoreISP3_SetFaceMaxDetectionCount( enIsp3FaceMaxDetectionCount FaceMaxDetectionParam );
+void CoreISP3_ControlFaceApplication( _tIspFaceDetectionCtrl *stIspFaceDetectionCtrlParam );
+void CoreISP3_FaceTracking_On(void);
+void CoreISP3_FaceTracking_Off(void);
+void CoreISP3_StillStabilizerLevelSetup( ClUint_16 LevelParam );
+void CoreISP3_SetStillStabilizer( _tIspStillStabilizerCtrl *stIspStillStabilizerCtrlParam );
+ClUint_16 CoreISP3_GetZoomSize( ClUint_16 SensorOutput, ClUint_16 DigitalZoomRate );
+//void CoreISP3_DigitalZoomScaleSetup( _tIspDigitalZoomCtrl *stIspDigitalZoomCtrlParam );
+//void CoreISP3_SetDigitalZoom( _tIspDigitalZoomCtrl *stIspDigitalZoomCtrlParam );
+void CoreISP3_SetOutputFormat( _tIspOutputModeCtrl *IspOutputModeCtrlParam );
+void CoreISP3_SetImageEffect( enISPFunctionsImageEffect IspImageEffectParam );
+void CoreISP3_SetClock( void );
+Cl_Bool CoreISP3_Initialize( enIsp3DownloadMode param );
+
+void ISP3_RegWrite_Partial( ClUint_16 addr, ClUint_16 data2, ClUint_16 data1, ClUint_16 data0);
+int ISP3_RegRead(ClUint_16 addr);
+void CoreISP3_SetSensorInfo( enIsp3OutResolution Isp3OutResolution );
+//void CoreISP3_GetSensorInfo( tSensorInfo *IspSensorInfo );
+#ifdef ISP3_ZOOM_ENABLE
+void ISP3_Set_StillWindowsStartX(ClUint_16 nData);
+void ISP3_Set_StillWindowsStartY(ClUint_16 nData);
+void ISP3_Set_StillWindowsWidth(ClUint_16 nData);
+void ISP3_Set_StillWindowsHeight(ClUint_16 nData);
+void ISP3_Set_ScaleInputWindowsWidth(ClUint_16 nData);
+void ISP3_Set_ScaleInputWindowsHeight(ClUint_16 nData);
+void ISP3_Set_ScaleOutputWindowsWidth(ClUint_16 nData);
+void ISP3_Set_ScaleOutputWindowsHeight(ClUint_16 nData);
+void ISP3_Set_JpegWindowsWidth(ClUint_16 nData);
+void ISP3_Set_JpegWindowsHeight(ClUint_16 nData);
+void ISP3_Set_ThumbnailScaleInputWidth(ClUint_16 nData);
+void ISP3_Set_ThumbnailScaleInputHeight(ClUint_16 nData);
+void ISP3_Set_ScalePreviewWindowsInputWidth(ClUint_16 nData);
+void ISP3_Set_ScalePreviewWindowsInputHeight(ClUint_16 nData);
+void ISP3_PreviewZoomScaleSet(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom);
+void ISP3_PreviewZoomScaleSet_YuLong(unsigned int OutputWidth, unsigned int OutputHeight, unsigned int dwZoom);
+void ISP3_ImageCrop(unsigned int sensorOutputWidth, unsigned int sensorOutputHeight,unsigned int CropedWidth,unsigned int CropedHeight, unsigned int OutputWidth,unsigned int OutputHeight);
+float ISP3_SetDigitalZoomRate(float zoomRate);
+float ISP3_SetDigitalZoomRate_Face(float zoomRate, int startPosDiffx, int startPosDiffy);
+void ISP3_ZoomInit(void);
+void ISP3_SetZoomRate(enIsp3ZoomRate rate);
+void Yulong_TestZoom(void);
+void ISP3_SetDigitalZoom(CAM_ZOOM_T rate);
+#endif
+
+
+void CoreISP3_PLLOn(Cl_Bool bOn);
+void CoreISP3_FlickerSuppression(FLICKER_TYPE type);
+void CoreISP3_AE_SetEV(int ev_Y/**< EV : -5~+5, 0:Default, -5: Dark, +5:Bright */);
+void CoreISP3_AE_SetISO(enIsp3AEISO isoLevel/**< ISO Level : 1~8, 0: Auto 1: Low ISO, 8: High ISO*/);
+//float
+ClUint_32 CoreISP3_Get_Version(void);
+void CoreISP3_SetAWBMode(enWB_MANUAL_TYPE type);
+void CoreISP3_Set_WDR_Off(void);
+void CoreISP3_Set_StillStabilizer_On(void);
+void CoreISP3_Set_StillStabilizer_Off(void);
+
+void ISP3_SetSceneMode(enIsp3SceneMode mode);
+
+void CoreISP3_SetBrightness(enIsp3Level_Value val);
+void CoreISP3_SetContrast(enIsp3Level_Value val);
+void CoreISP3_SetSaturation(enIsp3Level_Value val);
+void CoreISP3_SetHue(enIsp3Level_Value val);
+
+void CoreISP3_Brightness_OnOff(Cl_Bool Brightness);
+void CoreISP3_Contrast_OnOff(Cl_Bool Contrast);
+void CoreISP3_Saturation_OnOff(Cl_Bool Saturation);
+void CoreISP3_Hue_OnOff(Cl_Bool Hue);
+
+void CoreISP3_YUV_Swap(enIsp3YUV_Swap mode);
+
+void CoreISP3_TestPatten(void);
+void CoreISP3_PCLK_Inv(void);
+
+void CoreISP3_Mirror_Flip(enIsp3MIRROR_MODE mode);
+
+#ifdef EEPROM_ACCESS_ENABLE
+#define DEV_ID 0xA0 // EEPROM I2C DeviceID
+#define BYTE ClUint_8
+
+int ISP3_LiteOnEEPROM_Write(int startAddress, BYTE *data, int length, void (*callbackFunc)(BYTE *data, int n, int nCount));
+int ISP3_LiteOnEEPROM_Read(int startAddress, BYTE *data, int length, void (*callbackFunc)(BYTE *data, int n, int nCount));
+void EEPROM_Tes_Func(void);
+#endif
+
+#ifdef ISP2_EVB_ENABLE
+#define _ROTATION_NORMAL_ 1
+#define _ROTATION_HORIZONTAL_ 2
+#define _ROTATION_VERTICAL_ 3
+#define _ROTATION_HORIZONTAL_VERTICAL_ 4
+
+#define _VGA_RES_ 0
+#define _QVGA_RES_ 1
+#define _HVGA_RES_ 2
+#define _3M_RES_ 3
+#define _1M_RES_ 4 // 1024x768
+#endif
+
+#ifdef __cplusplus
+//}
+#endif
+
+
+#endif //3 _COREISP3_H_
+
+
diff --git a/drivers/misc/jz_cim/camera_source/isp/isp_camera.c b/drivers/misc/jz_cim/camera_source/isp/isp_camera.c
new file mode 100644
index 00000000000..066f0abda53
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/isp_camera.c
@@ -0,0 +1,464 @@
+/*
+ * linux/drivers/misc/camera_source/isp/camera.c -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <asm/jzsoc.h>
+#include "camera_ifc.h"
+#include "isp.h"
+#include "../../jz_cim_core.h"
+#include "isp_camera.h"
+
+#define CIM_DEBUG
+//#undef CIM_DEBUG
+#ifdef CIM_DEBUG
+#define dprintk(x...) printk(x)
+#else
+#define dprintk(x...)
+#endif
+
+
+//extern void camera_clk_init(void);
+
+/* gpio init */
+#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) || defined(CONFIG_JZ4750_AQUILA)/* board APUS */
+#define GPIO_CAMERA_RST (32*4+8) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_F4760) /* JZ4760 FPGA */
+#define GPIO_CAMERA_RST (32*1+9) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32*1 + 26) /* GPB26 */
+#else
+#error "isp/isp_camera.h , please define camera for your board."
+#endif
+
+
+
+void isp_reset(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(5*32+23);
+ __gpio_clear_pin(5*32+23);
+
+ __gpio_as_output(2*32+31);
+ __gpio_set_pin(2*32+31);
+ mdelay(5);
+ __gpio_clear_pin(2*32+31);
+ mdelay(5);
+ __gpio_set_pin(2*32+31);
+#else
+ __gpio_as_output(GPIO_CAMERA_RST);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+#endif
+}
+
+void isp_power_init(void)
+{
+}
+
+void isp_power_up(void)
+{
+#if defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27);
+ __gpio_clear_pin(32 * 1 + 27);
+#else
+ __gpio_as_output(4*32+23);
+ __gpio_clear_pin(4*32+23);
+#endif
+}
+void isp_power_down(void)
+{
+#if defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27);
+ __gpio_set_pin(32 * 1 + 27);
+#else
+ __gpio_as_output(4*32+23);
+ __gpio_set_pin(4*32+23);
+#endif
+}
+
+void isp_hw_init(void)
+{
+ //camera_reset();//mclk_pin used as reset_pin, so make the mclk_pin as gpio first
+
+ //2.cim power init
+ isp_power_init();
+
+ //3.cim clock init
+ // camera_clk_init();
+
+
+ //4.cim reset pin control
+ isp_reset();//reset
+
+ //1.cim poewerdowen pin control
+ isp_power_up();
+
+}
+
+
+void camera_wb(camera_wb_type id)
+{
+ switch(id)
+ {
+ case CAMERA_WB_MIN_MINUS_1:
+ dprintk("CAMERA_WB_MIN_MINUS_1\n");
+ break;
+ case CAMERA_WB_AUTO :
+ dprintk("CAMERA_WB_AUTO\n");
+ break;
+ case CAMERA_WB_CUSTOM:
+ dprintk("CAMERA_WB_CUSTOM\n");
+ break;
+ case CAMERA_WB_INCANDESCENT:
+ dprintk("CAMERA_WB_INCANDESCENT\n");
+ break;
+ case CAMERA_WB_FLUORESCENT:
+ dprintk("CAMERA_WB_FLUORESCENT\n");
+ break;
+ case CAMERA_WB_DAYLIGHT:
+ dprintk("CAMERA_WB_DAYLIGHT\n");
+ break;
+ case CAMERA_WB_CLOUDY_DAYLIGHT:
+ dprintk("CAMERA_WB_CLOUDY_DAYLIGHT\n");
+ break;
+ case CAMERA_WB_TWILIGHT:
+ dprintk("CAMERA_WB_TWILIGHT\n");
+ break;
+ case CAMERA_WB_SHADE:
+ dprintk("CAMERA_WB_SHADE\n");
+ break;
+ case CAMERA_WB_MAX_PLUS_1:
+ dprintk("CAMERA_WB_MAX_PLUS_1\n");
+ break;
+ }
+}
+
+
+void camera_antibanding(camera_antibanding_type id)
+{
+ switch(id){
+ case CAMERA_ANTIBANDING_OFF:
+ dprintk("\n");
+ break;
+ case CAMERA_ANTIBANDING_60HZ:
+ dprintk("\n");
+ break;
+ case CAMERA_ANTIBANDING_50HZ:
+ dprintk("\n");
+ break;
+ case CAMERA_ANTIBANDING_AUTO:
+ dprintk("\n");
+ break;
+ case CAMERA_MAX_ANTIBANDING:
+ dprintk("\n");
+ break;
+ }
+}
+
+void camera_preview_mode(camera_preview_mode_type id)
+{
+ switch(id){
+ case CAMERA_PREVIEW_MODE_SNAPSHOT:
+ dprintk("CAMERA_PREVIEW_MODE_SNAPSHOT\n");
+ break;
+ case CAMERA_PREVIEW_MODE_MOVIE:
+ dprintk("CAMERA_PREVIEW_MODE_MOVIE\n");
+ break;
+ case CAMERA_MAX_PREVIEW_MODE:
+ dprintk("CAMERA_MAX_PREVIEW_MODE\n");
+ break;
+ }
+}
+
+
+int isp_set_parm(unsigned int id,int32_t parm)
+{
+ int value=0;
+ printk("id=0x%x,parm=0x%x\n",id,parm);
+
+ switch(id){
+ case CAMERA_PARM_STATE:
+ value=CoreISP3_GetAutoFocusState();
+ break;
+ case CAMERA_PARM_BRIGHTNESS:
+ CoreISP3_SetBrightness( parm );
+ break;
+ case CAMERA_PARM_CONTRAST:
+ CoreISP3_SetContrast( parm);
+ break;
+ case CAMERA_PARM_HUE:
+ CoreISP3_SetHue( parm );
+ break;
+ case CAMERA_PARM_SATURATION:
+ CoreISP3_SetSaturation( parm );
+ break;
+ case CAMERA_PARM_WB:
+ CoreISP3_SetAWBMode( parm );
+ break;
+ case CAMERA_PARM_EFFECT:
+ CoreISP3_SetImageEffect( parm );
+ break;
+ // case CAMERA_PARM_FOCUS_USER:
+ // CoreISP3_UserArea_AFOn(int centerX, int centerY, int afWindowWidth, int afWindowHeight);
+ // break;
+ case CAMERA_PARM_AF_MODE:
+ CoreISP3_SetAutoFocus( enISP_FUNC_AF_ON );
+ break;
+ case CAMERA_PARM_FACETRACKING:
+ {
+ if( parm )
+ CoreISP3_FaceTracking_On();
+ else
+ CoreISP3_FaceTracking_Off();
+ }
+ break;
+ //CoreISP3_Mirror_Flip(enIsp3MIRROR_MODE mode);
+ }
+ return value;
+
+}
+/*void camera_set_dimensions(uint16_t picture_width,
+ uint16_t picture_height,
+ uint16_t display_width,
+ uint16_t display_height
+ )
+ {
+ printf("set dimensions picture_width=%d, picture_height=%d,display_width=%d,display_height=%d\n",
+ picture_width,picture_height,display_width,display_height);
+ }
+ void camera_set_position(camera_position_type *position)
+ {
+ }
+ void camera_set_thumbnail_properties(uint32_t width,uint32_t height,uint32_t quality)
+ {
+ }*/
+int isp_set_preview(int width, int height, const char *format)
+{
+
+ //CoreISP3_Initialize( enDownloadMode_SkipedMCUBin );
+ //ISP3_Set_ScaleOutputWindowsHeight(640);
+ //ISP3_Set_ScaleOutputWindowsWidth(480);
+ CoreISP3_SetResolution(enISP_RES_QVGA, CMD_Preview);
+
+ return 0;
+}
+int isp_set_capture(int width, int height, const char *format)
+{
+ CoreISP3_SetResolution(enISP_RES_QXGA, CMD_Capture);
+ return 0;
+}
+
+/*
+ * Sensor Init Routine
+ */
+
+
+int isp_sensor_init(void)
+{
+
+ printk("System_IICRead(0xe060)=0x%x\n",System_IICRead(0xe060));
+ CoreISP3_Initialize(
+ //enDownloadMode_CodeRAM);
+ //enDownloadMode_StackedMem);
+ enDownloadMode_SkipedMCUBin);
+
+ //CoreISP3_RGB565_Out();
+ CoreISP3_OutpYCbCr();
+ CoreISP3_FaceTracking_On();
+ //ISP3_Set_ScaleOutputWindowsHeight(320);
+ //ISP3_Set_ScaleOutputWindowsWidth(240);
+ return 0;
+}
+
+/*
+ CoreISP3_I2C_Write(0xe062, 0x06);// #P pll of XXCLK 48MHz HIVISION
+ CoreISP3_I2C_Write(0xe061, 0x18);// #M
+ CoreISP3_I2C_Write(0xe063, 0x02);// #S GCLK 80Mhz when XCLK 48Mhz
+ CoreISP3_I2C_Write(0xe060, 0x03);// # PLL OFF
+ CoreISP3_I2C_Write(0xe012, 0x01);// # S1MCLK divide based on SCLK
+ mdelay(100);//mdelay( 0x0400);// # delay 100 msec
+ CoreISP3_I2C_Write(0xe010, 0xf0);// # S1_RST=1
+ CoreISP3_I2C_Write(0xe010, 0xd0);// # S1_RST=0
+ mdelay( 0x0064);// # delay 100 msec
+ CoreISP3_I2C_Write(0xe010, 0xf0);// # S1_RST=1
+ CoreISP3_I2C_Write(0xe014, 0x12);// # Cis1IntE 8051CLK, JCLK division //0x__22 Jacky change to 0x12 test
+ CoreISP3_I2C_Write(0xE6a8, 0x06);// # resolution setting when initial
+ CoreISP3_I2C_Write(0xe660, 0xb0);// # sensor initial
+ CoreISP3_I2C_Write(0xe070, 0x05);// # MCU GPIO reset state to low
+ mdelay( 0x0064);// # delay 100 msec
+ CoreISP3_I2C_Write(0xe070, 0x04);// # MCU GPIO reset state to low
+ mdelay( 0x0400);//mdelay( 0x0400);// # delay 100 msec
+ CoreISP3_I2C_Write(0xedf3, 0x00);// #async I/F disable
+ CoreISP3_I2C_Write(0xe060, 0x00);// #PLL On
+ CoreISP3_I2C_Write(0xe050, 0x1A);// #rgb output
+ CoreISP3_I2C_Write(0xe059, 0x82);// #ycbcr
+ CoreISP3_I2C_Write(0xe660, 0xe6);// #face detect on
+ mdelay( 0x0064);// # delay 100 msec
+ CoreISP3_I2C_Write(0xe660, 0x38);// #face tracking on
+ CoreISP3_I2C_Write(0xe660, 0x34);// #face rotate
+ CoreISP3_I2C_Write(0xf20a, 0x03);// #face max count
+ CoreISP3_I2C_Write(0xf20b, 0xff);// #face max count 10
+ */
+
+
+int isp_sensor_probe(void)
+{
+
+#if defined(CONFIG_JZ4750_AQUILA)
+ return 0;
+#endif
+ return -1;
+}
+
+
+int isp_set_balance(balance_flag_t balance_flag,int arg)
+{
+ return 0;
+}
+
+int isp_set_effect(effect_flag_t effect_flag,int arg)
+{
+ return 0;
+}
+
+int isp_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ return 0;
+}
+
+int isp_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+
+}
+
+int isp_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ return 0;
+}
+
+int isp_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+}
+
+
+int isp_set_output_format(pixel_format_flag_t pixel_format_flag,int arg)
+{
+ switch(pixel_format_flag)
+ {
+ case PIXEL_FORMAT_JPEG:
+ printk("isp set output format to jepg");
+ break;
+ case PIXEL_FORMAT_YUV422SP:
+ printk("isp set output format to yuv422sp");
+ break;
+ case PIXEL_FORMAT_YUV420SP:
+ printk("isp set output format to yuv420sp");
+ break;
+ case PIXEL_FORMAT_YUV422I:
+ CoreISP3_OutpYCbCr();
+ printk("isp set output format to yuv422i");
+ break;
+ case PIXEL_FORMAT_RGB565:
+ CoreISP3_RGB565_Out();
+ printk("isp set output format to rgb565");
+ break;
+ }
+ return 0;
+}
+
+int isp_set_resolution(int width,int height,int bpp,pixel_format_flag_t fmt)
+{
+ //not complete yet,see the isp_set_preview and isp_set_capture for details
+
+ if(width == 2048 && height == 1536)
+ CoreISP3_SetResolution(enISP_RES_QXGA, CMD_Capture);
+ if(width == 640 && height == 480)
+ CoreISP3_SetResolution(enISP_RES_QVGA, CMD_Preview);
+ return 0;
+}
+
+struct camera_sensor_ops isp_sensor_ops = {
+ .camera_power_down = isp_power_down,
+ .camera_power_up = isp_power_up,
+ .camera_power_init = isp_power_init,
+ .camera_reset = isp_reset,
+ .camera_hw_init = isp_hw_init,
+ .camera_sensor_init = isp_sensor_init,
+
+ .camera_set_output_format = isp_set_output_format,
+ .camera_set_balance=isp_set_balance,
+ .camera_set_effect=isp_set_effect,
+ .camera_set_antibanding=isp_set_antibanding,
+ .camera_set_flash_mode=isp_set_flash_mode,
+ .camera_set_scene_mode=isp_set_scene_mode,
+ .camera_set_focus_mode=isp_set_focus_mode,
+ .camera_set_resolution = isp_set_resolution,
+
+ .camera_sensor_probe = isp_sensor_probe,
+};
+
+struct resolution_info isp_resolution_table[] = {
+ {2048,1536,16,PIXEL_FORMAT_YUV422I},
+ {640,480,16,PIXEL_FORMAT_YUV422I},
+};
+
+struct camera_sensor_desc isp_sensor_desc = {
+ .name = "isp",
+ .ops = &isp_sensor_ops,
+ .address = 0x78,
+ .camera_clock = CAM_CLOCK,
+ .wait_frames =0,
+
+ .resolution_table = isp_resolution_table,
+ .resolution_table_nr=ARRAY_SIZE(isp_resolution_table),
+
+ .flags={
+ .pixel_format_flag = PIXEL_FORMAT_YUV422I,
+ },
+
+ .preview_parm = {DEF_PRE_WIDTH, DEF_PRE_HEIGHT, DEF_PRE_BPP,PIXEL_FORMAT_YUV422I},
+ .capture_parm = {DEF_CAP_WIDTH, DEF_CAP_HEIGHT, DEF_CAP_BPP,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {MAX_PRE_WIDTH, MAX_PRE_HEIGHT, MAX_PRE_BPP,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {MAX_CAP_WIDTH, MAX_CAP_HEIGHT, MAX_CAP_BPP,PIXEL_FORMAT_YUV422I},
+
+ .cfg_info={
+ .cam_data_pack_mode = CAM_DATA_PACK_MODE,
+ .cam_data_order = CAM_DATA_ORDER,
+ .cam_data_format = CAM_DATA_FORMAT,
+
+ .cam_sample_mode = CAM_SAMPLE_MODE,
+ .cam_dummy_zero = CAM_DUMMY_ZERO,
+ .cam_external_vsync = CAM_EXTERNAL_VSYNC,
+ .cam_bypass = CAM_BYPASS,
+
+ .cam_vsp = CAM_VSP,
+ .cam_hsp = CAM_HSP,
+ .cam_psp = CAM_PSP,
+ .cam_data_inv = CAM_DATA_INV,
+ },
+};
+
+int isp_register(void)
+{
+ camera_sensor_register(&isp_sensor_desc);
+ printk("isp sensor!");
+ return 0;
+}
+
+early_initcall(isp_register);
+
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/isp/isp_camera.h b/drivers/misc/jz_cim/camera_source/isp/isp_camera.h
new file mode 100644
index 00000000000..a17f295a257
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/isp_camera.h
@@ -0,0 +1,59 @@
+/*
+ * linux/drivers/misc/camera_source/isp/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET---------------------
+
+#define CAM_CLOCK 28000000
+
+// MAX SIZE----------------------
+#define MAX_CAP_WIDTH 2048
+#define MAX_CAP_HEIGHT 1536
+
+#define MAX_PRE_WIDTH 640
+#define MAX_PRE_HEIGHT 480
+
+#define MAX_CAP_BPP 16
+#define MAX_PRE_BPP 16
+
+// DEF SIZE----------------------
+#define DEF_CAP_WIDTH 2048
+#define DEF_CAP_HEIGHT 1536
+
+#define DEF_PRE_WIDTH 640
+#define DEF_PRE_HEIGHT 480
+
+#define DEF_CAP_BPP 16
+#define DEF_PRE_BPP 16
+
+
+// DATA SAMPLE--------------------
+
+#define CAM_DATA_PACK_MODE 2
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE 1
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE 1
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE 0
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 1
+#define CAM_DATA_INV 0
+
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/isp/readme b/drivers/misc/jz_cim/camera_source/isp/readme
new file mode 100644
index 00000000000..22a48ab2a0b
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/readme
@@ -0,0 +1,6 @@
+
+This driver is for corelogic isp+samsung_sensor.
+Corelogic isp need fw for sensor.
+the fw is given to us as a bin file ,so we write the tran_data to make it becomea file data.h .
+
+George Zhang
diff --git a/drivers/misc/jz_cim/camera_source/isp/tran_data b/drivers/misc/jz_cim/camera_source/isp/tran_data
new file mode 100644
index 00000000000..da5b31121df
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/tran_data
Binary files differ
diff --git a/drivers/misc/jz_cim/camera_source/isp/tran_data.code b/drivers/misc/jz_cim/camera_source/isp/tran_data.code
new file mode 100644
index 00000000000..424375f94a0
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/isp/tran_data.code
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+void main()
+{ FILE * fd,* fd2;
+ int c,i=0;
+ fd=fopen("./_MCU.BIN","r");
+ fd2=fopen("./data.h","w+");
+ fprintf(fd2,"char ISP3BinaryDataMcu[]={");
+ while((c=fgetc(fd))!=EOF)
+ {
+ if((i%16)==0)
+ fprintf(fd2,"\n");
+ fprintf(fd2,"0x%02x,",c);
+ i++;
+ }
+ fseek(fd2,-1L,SEEK_CUR);
+ fprintf(fd2,"};\n");
+ fprintf(fd2,"#define ISP3BinarySize (sizeof(ISP3BinaryDataMcu)/sizeof(char))\n");
+ fclose(fd);
+ fclose(fd2);
+ fprintf(stdout,"hello\n");
+}
diff --git a/drivers/misc/jz_cim/camera_source/ov2640/Makefile b/drivers/misc/jz_cim/camera_source/ov2640/Makefile
new file mode 100644
index 00000000000..1776236189d
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2640/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_OV2640) += camera.o
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2640/camera.c b/drivers/misc/jz_cim/camera_source/ov2640/camera.c
new file mode 100644
index 00000000000..b24c868a3bb
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2640/camera.c
@@ -0,0 +1,73 @@
+
+
+#include <asm/jzsoc.h>
+
+extern void camera_clk_init(void);
+
+
+/* gpio init */
+#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) || defined(CONFIG_JZ4750_AQUILA)/* board APUS */
+#define GPIO_CAMERA_RST (32*4+8) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_F4760) /* JZ4760 FPGA */
+#define GPIO_CAMERA_RST (32*1+9) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32*1 + 26) /* GPB26 */
+#else
+#error "ov2640/camera.c , please define camera for your board."
+#endif
+
+
+void camera_powerdown() {;}
+void camera_powerup() {;}
+
+
+
+void camera_power_init()
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+#error "ov2640/camera.c ,plesase wite a new camera_power_init()"
+#endif
+}
+
+void camera_reset(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+#error "ov2640/camera.c ,plesase wite a new camera_reset()"
+#else
+ __gpio_as_output(GPIO_CAMERA_RST);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+#endif
+
+}
+
+
+void camera_hw_init(void)
+{
+ camera_reset();//mclk_pin used as reset_pin, so make the mclk_pin as gpio first
+
+ //1.cim poewerdowen pin control
+ camera_powerup();
+
+ //2.cim power init
+ camera_power_init();
+
+ //3.cim clock init
+ //if mclk pin is not used for clk ,init it befor camera_clk_init()!
+ camera_clk_init();
+
+ //4.cim reset pin control
+ camera_reset();
+
+}
+
+int camera_set_init(void){return 1;}
+int camera_set_parm(unsigned int id,int32_t parm) {return 1;}
+int camera_set_parm2(unsigned int id,int32_t parm1,int32_t parm2) {return 1;}
+int camera_set_preview(int width, int height, const char *format) {return 1;}
+int camera_set_capture(int width, int height, const char *format) {return 1;}
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2640/camera.h b/drivers/misc/jz_cim/camera_source/ov2640/camera.h
new file mode 100644
index 00000000000..3029a79e16a
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2640/camera.h
@@ -0,0 +1,56 @@
+/*
+ * linux/drivers/misc/camera_source/ov2640/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET--------------------
+
+#define CAM_CLOCK 24000000
+
+// MAX SIZE---------------------
+#define MAX_PICTURE_WIDTH 1600
+#define MAX_PICTURE_HEIGHT 1200
+
+#define MAX_PREVIEW_WIDTH 640
+#define MAX_PREVIEW_HEIGHT 480
+
+#define MAX_PICTURE_BPP 16
+#define MAX_PREVIEW_BPP 16
+
+// DEFAULT SIZE-----------------
+#define DEF_PICTURE_WIDTH 1600
+#define DEF_PICTURE_HEIGHT 1200
+
+#define DEF_PREVIEW_WIDTH 640
+#define DEF_PREVIEW_HEIGHT 480
+
+#define DEF_PICTURE_BPP 16
+#define DEF_PREVIEW_BPP 16
+
+
+// DATA SAMPLE-------------------
+
+#define CAM_DATA_PACK_MODE 4
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 0
+#define CAM_DATA_INV 0
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/Makefile b/drivers/misc/jz_cim/camera_source/ov2655/Makefile
new file mode 100644
index 00000000000..53aca57e892
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_OV2655) += ov2655_camera.o ov2655_set.o ov2655_set_mode.o
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.c b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.c
new file mode 100644
index 00000000000..843cdce0915
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.c
@@ -0,0 +1,383 @@
+#include <asm/jzsoc.h>
+#include <linux/i2c.h>
+#include "ov2655_camera.h"
+#include "ov2655_set.h"
+#include "ov2655_set_mode.h"
+#include <asm/jzsoc.h>
+
+#define ov2655_DEBUG
+#ifdef ov2655_DEBUG
+#define dprintk(x...) do{printk("ov2655---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+/* gpio init */
+#if defined(CONFIG_JZ4760_PT701)
+#define GPIO_CAMERA_RST (32*3+10) /*GPD10*/
+#define GPIO_CAMERA_PD (32*3+11) /*GPD11*/
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32 * 1 + 26) /* GPB26 */
+#define GPIO_CAMERA_PD (32 * 1 + 27) /* GPB27 */
+#else
+#error "ov2655/ov2655_camera.c , please define camera for your board."
+#endif
+
+
+struct ov2655_sensor ov2655;
+
+void ov2655_power_down(void)
+{
+ __gpio_as_output(GPIO_CAMERA_PD);
+ __gpio_set_pin(GPIO_CAMERA_PD);
+ mdelay(5);
+}
+
+void ov2655_power_up(void)
+{
+ //ov2655_power_on later
+ __gpio_as_output(GPIO_CAMERA_PD);
+ __gpio_clear_pin(GPIO_CAMERA_PD);
+ mdelay(5);
+}
+
+void ov2655_reset(void)
+{
+ __gpio_as_output(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+}
+
+
+int ov2655_set_balance(balance_flag_t balance_flag,int arg)
+{
+ dprintk("ov2655_set_balance");
+ switch(balance_flag)
+ {
+ case WHITE_BALANCE_AUTO:
+ ov2655_set_wb_auto_mode(ov2655.client);
+ dprintk("wb_auto ");
+ break;
+ case WHITE_BALANCE_DAYLIGHT ://ri guang
+ ov2655_set_wb_sunny_mode(ov2655.client);
+ dprintk("wb_daylight ");
+ break;
+ case WHITE_BALANCE_CLOUDY_DAYLIGHT ://ying tian
+ ov2655_set_wb_cloudy_mode(ov2655.client);
+ dprintk("wb_cloudy daylight ");
+ break;
+ case WHITE_BALANCE_INCANDESCENT :
+ ov2655_set_wb_office_mode(ov2655.client);
+ dprintk("wb_incandenscent ");
+ break;
+ }
+ return 0;
+}
+
+int ov2655_set_effect(effect_flag_t effect_flag,int arg)
+{
+ dprintk("ov2655_set_effect");
+ switch(effect_flag)
+ {
+ case EFFECT_NONE:
+ ov2655_set_effect_normal(ov2655.client);
+ dprintk("effect_none");
+ break;
+ case EFFECT_MONO :
+ ov2655_set_effect_blackwhite(ov2655.client);
+ dprintk("effect_mono ");
+ break;
+ case EFFECT_NEGATIVE :
+ ov2655_set_effect_negative(ov2655.client);
+ dprintk("effect_negative ");
+ break;
+ case EFFECT_SOLARIZE ://bao guang
+ dprintk("effect_solarize ");
+ break;
+ case EFFECT_SEPIA :
+ ov2655_set_effect_sepia(ov2655.client);
+ dprintk("effect_sepia ");
+ break;
+ case EFFECT_POSTERIZE ://se diao fen li
+ dprintk("effect_posterize ");
+ break;
+ case EFFECT_WHITEBOARD :
+ dprintk("effect_whiteboard ");
+ break;
+ case EFFECT_BLACKBOARD :
+ dprintk("effect_blackboard ");
+ break;
+ case EFFECT_AQUA ://qian lv se
+ ov2655_set_effect_greenish(ov2655.client);
+ dprintk("effect_aqua ");
+ break;
+ case EFFECT_PASTEL:
+ dprintk("effect_pastel");
+ break;
+ case EFFECT_MOSAIC:
+ dprintk("effect_mosaic");
+ break;
+ case EFFECT_RESIZE:
+ dprintk("effect_resize");
+ break;
+ }
+ return 0;
+}
+
+int ov2655_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ dprintk("ov2655_set_antibanding");
+ switch(antibanding_flag)
+ {
+ case ANTIBANDING_AUTO :
+ ov2655_ab_auto(ov2655.client);
+ dprintk("ANTIBANDING_AUTO ");
+ break;
+ case ANTIBANDING_50HZ :
+ ov2655_ab_50hz(ov2655.client);
+ dprintk("ANTIBANDING_50HZ ");
+ break;
+ case ANTIBANDING_60HZ :
+ ov2655_ab_60hz(ov2655.client);
+ dprintk("ANTIBANDING_60HZ ");
+ break;
+ case ANTIBANDING_OFF :
+ ov2655_ab_off(ov2655.client);
+ dprintk("ANTIBANDING_OFF ");
+ break;
+ }
+ return 0;
+}
+
+
+int ov2655_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+}
+
+int ov2655_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ return 0;
+}
+
+int ov2655_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ return 0;
+}
+
+
+int ov2655_set_fps(int fps)
+{
+ dprintk("set fps : %d",fps);
+ return 0;
+}
+
+int ov2655_set_luma_adaptation(int arg)
+{
+ dprintk("luma_adaptation : %d",arg);
+ return 0;
+}
+
+int ov2655_set_parameter(int cmd, int mode, int arg)
+{
+ switch(cmd)
+ {
+ case CPCMD_SET_BALANCE :
+ ov2655_set_balance(mode,arg);
+ break;
+ case CPCMD_SET_EFFECT :
+ ov2655_set_effect(mode,arg);
+ break;
+ case CPCMD_SET_ANTIBANDING :
+ ov2655_set_antibanding(mode,arg);
+ break;
+ case CPCMD_SET_FLASH_MODE :
+ ov2655_set_flash_mode(mode,arg);
+ break;
+ case CPCMD_SET_SCENE_MODE :
+ ov2655_set_scene_mode(mode,arg);
+ break;
+ case CPCMD_SET_PIXEL_FORMAT :
+ break;
+ case CPCMD_SET_FOCUS_MODE :
+ ov2655_set_focus_mode(mode,arg);
+ break;
+ case CPCMD_SET_PREVIEW_FPS:
+ ov2655_set_fps(arg);
+ break;
+ case CPCMD_SET_NIGHTSHOT_MODE:
+ break;
+ case CPCMD_SET_LUMA_ADAPTATION:
+ ov2655_set_luma_adaptation(arg);
+ break;
+ }
+ return 0;
+}
+
+int ov2655_set_power(int state)
+{
+ switch (state)
+ {
+ case 0:
+ /* hardware power up first */
+ ov2655_power_up();
+ /* software power up later if it implemented */
+ break;
+ case 1:
+ ov2655_power_down();
+ break;
+ case 2:
+ break;
+ default:
+ printk("%s : EINVAL! \n",__FUNCTION__);
+ }
+ return 0;
+}
+
+int ov2655_sensor_init(void)
+{
+ //ov2655_reset();
+ ov2655_init_setting(ov2655.client);
+ return 0;
+}
+
+int ov2655_sensor_probe(void)
+{
+ ov2655_power_up();
+ ov2655_reset();
+
+ int sensor_id = sensor_read_reg16(ov2655.client,0x300a);
+ ov2655_power_down();
+
+ if(sensor_id == 0x26)
+ return 0;
+ printk("ov2655 probe error : id = %x",sensor_id);
+ return -1;
+}
+
+/* sensor_set_function use for init preview or capture.there may be some difference between preview and capture.
+ * so we divided it into two sequences.param: function indicated which function
+ * 0: preview
+ * 1: capture
+ * 2: recording
+ */
+int ov2655_set_function(int function)
+{
+ switch (function)
+ {
+ case 0:
+ preview_set(ov2655.client);
+ break;
+ case 1:
+ capture_set(ov2655.client);
+ break;
+ case 2:
+ break;
+ }
+ return 0;
+}
+
+int ov2655_set_resolution(int width,int height,int bpp,pixel_format_flag_t fmt,camera_mode_t mode)
+{
+ size_switch(ov2655.client,width,height,mode);
+ return 0;
+}
+
+static int ov2655_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ ov2655.client = client;
+ return camera_sensor_register(&ov2655.desc);
+}
+
+struct camera_sensor_ops ov2655_sensor_ops = {
+ .sensor_init = ov2655_sensor_init,
+ .camera_sensor_probe = ov2655_sensor_probe,
+ .sensor_set_function = ov2655_set_function,
+ .sensor_set_resolution = ov2655_set_resolution,
+ .sensor_set_parameter = ov2655_set_parameter,
+ .sensor_set_power = ov2655_set_power,
+};
+
+struct resolution_info ov2655_resolution_table[] = {
+ {1600,1200,16,PIXEL_FORMAT_YUV422I},
+ {1280,1024,16,PIXEL_FORMAT_YUV422I},
+ {1024,768,16,PIXEL_FORMAT_YUV422I},
+ {800,600,16,PIXEL_FORMAT_YUV422I},
+// {640,480,16,PIXEL_FORMAT_YUV422I},
+ {352,288,16,PIXEL_FORMAT_YUV422I}, //must be included
+ {176,144,16,PIXEL_FORMAT_YUV422I}, //must be included in order to recording
+
+};
+
+struct ov2655_sensor ov2655 = {
+ .desc = {
+ .name = "ov2655",
+ .wait_frames = 2,
+
+ .ops = &ov2655_sensor_ops,
+
+ .resolution_table = ov2655_resolution_table,
+ .resolution_table_nr=ARRAY_SIZE(ov2655_resolution_table),
+
+ .capture_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {1600,1200, 16,PIXEL_FORMAT_YUV422I},
+
+ .preview_parm = {800,600, 16,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {800,600, 16,PIXEL_FORMAT_YUV422I},
+
+ .cfg_info = {
+ .configure_register= 0x0
+ |CIM_CFG_PACK_3 /* pack mode : 4 3 2 1 */
+ |CIM_CFG_BYPASS /* Bypass Mode */
+ |CIM_CFG_VSP /* VSYNC Polarity:1-falling edge active */
+ // |CIM_CFG_HSP
+ |CIM_CFG_PCP /* PCLK working edge:1-falling */
+ |CIM_CFG_DSM_GCM, /* Gated Clock Mode */
+ },
+
+ .flags = {
+ .effect_flag = 0
+ |EFFECT_NONE
+ |EFFECT_MONO
+ |EFFECT_SEPIA
+ |EFFECT_NEGATIVE
+ |EFFECT_AQUA,
+ .balance_flag = 0
+ | WHITE_BALANCE_AUTO
+ | WHITE_BALANCE_DAYLIGHT
+ | WHITE_BALANCE_CLOUDY_DAYLIGHT
+ | WHITE_BALANCE_INCANDESCENT
+ | WHITE_BALANCE_FLUORESCENT,
+ .antibanding_flag = ~0x0,
+ .flash_mode_flag = 0,
+ .scene_mode_flag = 0,
+ .pixel_format_flag = 0,
+ .focus_mode_flag = 0,
+ },
+
+ },
+};
+
+static const struct i2c_device_id ov2655_id[] = {
+ { "ov2655", 0 },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(i2c, ov2655_id);
+
+static struct i2c_driver ov2655_driver = {
+ .probe = ov2655_i2c_probe,
+ .id_table = ov2655_id,
+ .driver = {
+ .name = "ov2655",
+ },
+};
+
+static int __init ov2655_i2c_register(void)
+{
+ return i2c_add_driver(&ov2655_driver);
+}
+
+module_init(ov2655_i2c_register);
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.h b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.h
new file mode 100644
index 00000000000..5869d109349
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_camera.h
@@ -0,0 +1,37 @@
+/*
+ * linux/drivers/misc/camera_source/ov2655/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef ov2655_CAMERA_H
+#define ov2655_CAMERA_H
+
+
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+
+/*
+struct private_info
+{
+ int cur_rwidth;
+ int cur_rheight;
+ int cur_mode;
+
+ int cur_focus_mode;
+};
+*/
+
+struct ov2655_sensor
+{
+ struct i2c_client *client;
+// struct private_info pinfo;
+ struct camera_sensor_desc desc;
+};
+
+#endif
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.c b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.c
new file mode 100644
index 00000000000..eeec37c3fa7
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.c
@@ -0,0 +1,718 @@
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+#include <linux/i2c.h>
+#include <asm/jzsoc.h>
+
+#define ov2655_DEBUG
+#ifdef ov2655_DEBUG
+#define dprintk(x...) do{printk("ov2655-\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+
+#define Default_SVGA_Line_Width (1940)
+#define Default_UXGA_Line_Width (1940)
+uint8_t Default_Reg0x3028 = 7;
+uint8_t Default_Reg0x3029 = 147;
+uint8_t Default_Reg0x302a = 4;
+uint8_t Default_Reg0x302b = 212;
+
+#define Default_UXGA_maximum_shutter (1236)
+//#define Preview_dummy_pixel 0
+#define Capture_dummy_pixel (0)
+#define Capture_PCLK_Frequency (36)//Unit is MHz
+#define Preview_PCLK_Frequency (36)//Unit is MHz
+
+uint8_t Preview_Reg0x3000,
+ Preview_Reg0x3002,
+ Preview_Reg0x3003,
+ Preview_Reg0x3013,
+ Reg0x3013,
+ Reg0x3000,
+ Reg0x3002,
+ Reg0x3003;
+
+
+uint16_t Preview_dummy_pixel,
+ Extra_lines,
+ Capture_Banding_Filter,
+ Capture_Gain16,
+ Preview_Gain16,
+ Capture_dummy_line = 63;
+
+uint32_t Preview_Exposure,
+ Shutter,
+ Capture_Max_Gain16,
+ Preview_Line_Width,
+ Capture_Line_Width,
+ Capture_Exposure,
+ Gain_Exposure,
+ Capture_Maximum_Shutter;
+
+
+void preview_set(struct i2c_client *client)
+{
+ dprintk("-preview_set UXGA>SVGA");
+ // transfer from UXGA to SVGA
+ sensor_write_reg16(client,0x300e,0x34);
+ sensor_write_reg16(client,0x3011,0x00);
+ sensor_write_reg16(client,0x3012,0x10);
+ sensor_write_reg16(client,0x302A,0x02);
+ sensor_write_reg16(client,0x302B,0x6a);
+ sensor_write_reg16(client,0x306f,0x14);
+
+ sensor_write_reg16(client,0x3020,0x01);
+ sensor_write_reg16(client,0x3021,0x18);
+ sensor_write_reg16(client,0x3022,0x00);
+ sensor_write_reg16(client,0x3023,0x06);
+ sensor_write_reg16(client,0x3024,0x06);
+ sensor_write_reg16(client,0x3025,0x58);
+ sensor_write_reg16(client,0x3026,0x02);
+ sensor_write_reg16(client,0x3027,0x61);
+ sensor_write_reg16(client,0x3088,0x03);
+ sensor_write_reg16(client,0x3089,0x20);
+ sensor_write_reg16(client,0x308a,0x02);
+ sensor_write_reg16(client,0x308b,0x58);
+ sensor_write_reg16(client,0x3316,0x64);
+ sensor_write_reg16(client,0x3317,0x25);
+ sensor_write_reg16(client,0x3318,0x80);
+ sensor_write_reg16(client,0x3319,0x08);
+ sensor_write_reg16(client,0x331a,0x64);
+ sensor_write_reg16(client,0x331b,0x4b);
+ sensor_write_reg16(client,0x331c,0x00);
+ sensor_write_reg16(client,0x331d,0x38);
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3013,0xf7);
+
+ sensor_write_reg16(client,0x3070,0xb9);
+ sensor_write_reg16(client,0x3071,0x00);
+ sensor_write_reg16(client,0x3072,0x9a);
+ sensor_write_reg16(client,0x3073,0x00);
+ sensor_write_reg16(client,0x301c,0x02);
+ sensor_write_reg16(client,0x301d,0x03);
+} //===preview setting end===
+
+
+void capture_reg_set(struct i2c_client *client)
+{
+ dprintk("capture_reg_set");
+ // ?? -> 1600x1200
+ sensor_write_reg16(client,0x300e,0x34);
+ sensor_write_reg16(client,0x3011,0x01);
+ sensor_write_reg16(client,0x3012,0x00);
+ sensor_write_reg16(client,0x302A,0x04);
+ sensor_write_reg16(client,0x302B,0xd4);
+ sensor_write_reg16(client,0x306f,0x54);
+ sensor_write_reg16(client,0x3020,0x01);
+ sensor_write_reg16(client,0x3021,0x18);
+ sensor_write_reg16(client,0x3022,0x00);
+ sensor_write_reg16(client,0x3023,0x0a);
+ sensor_write_reg16(client,0x3024,0x06);
+ sensor_write_reg16(client,0x3025,0x58);
+ sensor_write_reg16(client,0x3026,0x04);
+ sensor_write_reg16(client,0x3027,0xbc);
+ sensor_write_reg16(client,0x3088,0x06);
+ sensor_write_reg16(client,0x3089,0x40);
+ sensor_write_reg16(client,0x308a,0x04);
+ sensor_write_reg16(client,0x308b,0xb0);
+ sensor_write_reg16(client,0x3316,0x64);
+ sensor_write_reg16(client,0x3317,0x4b);
+ sensor_write_reg16(client,0x3318,0x00);
+ sensor_write_reg16(client,0x3319,0x2c);
+ sensor_write_reg16(client,0x331a,0x64);
+ sensor_write_reg16(client,0x331b,0x4b);
+ sensor_write_reg16(client,0x331c,0x00);
+ sensor_write_reg16(client,0x331d,0x4c);
+ sensor_write_reg16(client,0x3302,0x01);
+}
+
+void p_reg(struct i2c_client *client)
+{
+ printk("\n\n\n=========================================================\n\n\n");
+ printk("0x3000 = 0x%2x\n",sensor_read_reg16(client,0x3000));
+ printk("0x3002 = 0x%2x\n",sensor_read_reg16(client,0x3002));
+ printk("0x3003 = 0x%2x\n",sensor_read_reg16(client,0x3003));
+ printk("\n\n\n=========================================================\n\n\n");
+}
+
+void capture_set(struct i2c_client *client)
+{
+ dprintk("capture_set");
+
+ //Stop AE/AG
+ Reg0x3013 = sensor_read_reg16(client,0x3013);
+ Preview_Reg0x3013 = Reg0x3013;
+ Reg0x3013 = Reg0x3013 & 0xfa;
+ dprintk("-yes-Reg0x3013=%d\n",Reg0x3013);
+
+ sensor_write_reg16(client,0x3013,Reg0x3013);
+
+ Reg0x3002 = sensor_read_reg16(client,0x3002);
+ dprintk("Reg0x3002=%d\n",Reg0x3002);
+ Reg0x3003 = sensor_read_reg16(client,0x3003);
+ dprintk("Reg0x3003=%d\n",Reg0x3003);
+ Shutter = (Reg0x3002<<8) + Reg0x3003;
+ dprintk("Shutter=%d\n",Shutter);
+
+ Preview_Exposure = Shutter ;
+ //Read Back Gain for preview
+ Reg0x3000 = sensor_read_reg16(client,0x3000);
+ dprintk("Reg0x3000=%d\n",Reg0x3000);
+ Preview_Reg0x3000 = Reg0x3000;
+ Preview_Gain16 = (((Reg0x3000 & 0xf0)>>4) + 1) * (16 + (Reg0x3000 & 0x0f));
+ dprintk("Preview_Gain16=%d\n",Preview_Gain16);
+
+ //Maximum gain limitation for capture, Capture_max_gain16 = capture_maximum_gain * 16
+ Capture_Max_Gain16 = 32;
+ dprintk("Capture_Max_Gain16=%d\n",Capture_Max_Gain16);
+ Preview_Line_Width = Default_SVGA_Line_Width ;
+ Capture_Line_Width = Default_UXGA_Line_Width ;
+ Capture_Maximum_Shutter = Default_UXGA_maximum_shutter;
+
+ Capture_Exposure =
+ Preview_Exposure
+ *Capture_PCLK_Frequency
+ /Preview_PCLK_Frequency
+ *Preview_Line_Width
+ /Capture_Line_Width
+ /2;
+
+ dprintk("Capture_Exposure=%d\n",Capture_Exposure);
+
+ Capture_Banding_Filter = Capture_PCLK_Frequency*1000000/ 100/(2*Capture_Line_Width);
+ dprintk("Capture_Banding_Filter=%d\n",Capture_Banding_Filter);
+ Gain_Exposure = Preview_Gain16 * Capture_Exposure*100/85;
+ dprintk("Gain_Exposure=%d\n",Gain_Exposure);
+ if (Gain_Exposure < Capture_Banding_Filter * 16) {//1200
+ // Exposure < 1/100
+ Capture_Exposure = Gain_Exposure /16;
+ Capture_Gain16 = (Gain_Exposure*2 + 1)/Capture_Exposure/2;
+ dprintk("Capture_Gain16=%d\n",Capture_Gain16);
+ }
+ else
+ {
+ if (Gain_Exposure > Capture_Maximum_Shutter * 16) //16720
+ {
+ // Exposure > Capture_Maximum_Shutter
+ dprintk(" 1");
+ Capture_Exposure = Capture_Maximum_Shutter;
+ Capture_Gain16 = (Gain_Exposure*2 + 1)/Capture_Maximum_Shutter/2;
+ dprintk("-Gain_Exposure > Capture_Maximum_Shutter * 16Capture_Gain16=%d\n",Capture_Gain16);
+ if (Capture_Gain16 > Capture_Max_Gain16)
+ {
+ dprintk("2");
+ // gain reach maximum, insert extra line
+ Capture_Exposure = Gain_Exposure*1.1/Capture_Max_Gain16;
+ // Exposure = n/100
+ Capture_Exposure = Gain_Exposure/16/Capture_Banding_Filter;
+ Capture_Exposure = Capture_Exposure * Capture_Banding_Filter;
+ Capture_Gain16 = (Gain_Exposure *2+1)/ Capture_Exposure/2;
+ dprintk("-Capture_Gain16 > Capture_Max_Gain16Capture_Gain16=%d\n",Capture_Gain16);
+ }
+ }
+ else
+ {
+ // 1/100 < Exposure < Capture_Maximum_Shutter, Exposure = n/100
+ dprintk("3");
+ Capture_Exposure = Gain_Exposure /16;
+ Capture_Exposure = Capture_Exposure/Capture_Banding_Filter;
+ dprintk("4");
+ Capture_Exposure = Capture_Exposure * Capture_Banding_Filter;
+ printk("Capture_Exposure = %d\n",Capture_Exposure);
+ printk("Gain_Exposure = %d\n",Gain_Exposure);
+ Capture_Gain16 = (Gain_Exposure*2 +1) / Capture_Exposure/2;
+ dprintk("else-Capture_Gain16=%d\n",Capture_Gain16);
+ }
+ }
+
+
+ //Write Exposure
+ // if (Capture_Exposure > Capture_Maximum_Shutter) {
+ Shutter = Capture_Exposure;
+ dprintk("Write ExposureShutter=%d\n",Shutter);
+ // }
+
+ capture_reg_set(client);
+
+ Reg0x3003 = Shutter & 0x00ff;
+ Reg0x3002 = (Shutter >>8) & 0x00ff;
+ sensor_write_reg16(client,0x3003, Reg0x3003);
+ sensor_write_reg16(client,0x3002, Reg0x3002);
+
+ // Write Gain
+ uint8_t Gain = 0;
+ if (Capture_Gain16 > 16) {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = 0x10;
+ }
+ if (Capture_Gain16 > 16) {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain | 0x20;
+ }
+ if (Capture_Gain16 > 16) {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain | 0x40;
+ }
+ if (Capture_Gain16 > 16) {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain | 0x80;
+ }
+ if (Capture_Gain16 > 16) {
+ Gain = Gain | (Capture_Gain16 -16);
+ }
+ dprintk("Gain=%d\n",Gain);
+ sensor_write_reg16(client,0x3000, Gain);
+
+ p_reg(client);
+}
+
+
+
+void set_size_1600x1200(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_CAPTURE)
+ {
+ //doing nothing
+ }
+}
+
+void set_size_1280x1024(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_CAPTURE)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x05);
+ sensor_write_reg16(client,0x3089,0x00);
+ sensor_write_reg16(client,0x308a,0x04);
+ sensor_write_reg16(client,0x308b,0x00);
+ sensor_write_reg16(client,0x331a,0x50);
+ sensor_write_reg16(client,0x331b,0x40);
+ sensor_write_reg16(client,0x331c,0x00);
+ }
+
+ dprintk("UXGA-> SXGA;1280x1024");
+}
+
+void set_size_1024x768(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_CAPTURE)
+ {
+ sensor_write_reg16(client,0x3011,0x01);
+ sensor_write_reg16(client,0x3088,0x04);
+ sensor_write_reg16(client,0x3089,0x00);
+ sensor_write_reg16(client,0x308a,0x03);
+ sensor_write_reg16(client,0x308b,0x00);
+ sensor_write_reg16(client,0x331a,0x50);
+ sensor_write_reg16(client,0x331b,0x40);
+ sensor_write_reg16(client,0x3302,0x11);
+ }
+
+}
+
+void set_size_800x600(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_PREVIEW)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x03);
+ sensor_write_reg16(client,0x3089,0x20);
+ sensor_write_reg16(client,0x308a,0x02);
+ sensor_write_reg16(client,0x308b,0x58);
+ sensor_write_reg16(client,0x331a,0x64);
+ sensor_write_reg16(client,0x331b,0x4b);
+ sensor_write_reg16(client,0x331c,0x00);
+ }
+ else if(mode == CAMERA_MODE_CAPTURE)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x03);
+ sensor_write_reg16(client,0x3089,0x20);
+ sensor_write_reg16(client,0x308a,0x02);
+ sensor_write_reg16(client,0x308b,0x58);
+ sensor_write_reg16(client,0x331a,0x32);
+ sensor_write_reg16(client,0x331b,0x25);
+ sensor_write_reg16(client,0x331c,0x80);
+ }
+
+ dprintk(" UXGA>SVGA 800x600");
+}
+
+void set_size_640x480(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_PREVIEW)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x02);
+ sensor_write_reg16(client,0x3089,0x80);
+ sensor_write_reg16(client,0x308a,0x01);
+ sensor_write_reg16(client,0x308b,0xe0);
+ sensor_write_reg16(client,0x331a,0x28);
+ sensor_write_reg16(client,0x331b,0x1e);
+ sensor_write_reg16(client,0x331c,0x00);
+ sensor_write_reg16(client,0x3302,0x11);
+ }
+ else if(mode == CAMERA_MODE_CAPTURE)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x02);
+ sensor_write_reg16(client,0x3089,0x80);
+ sensor_write_reg16(client,0x308a,0x01);
+ sensor_write_reg16(client,0x308b,0xe0);
+ sensor_write_reg16(client,0x331a,0x28);
+ sensor_write_reg16(client,0x331b,0x1e);
+ sensor_write_reg16(client,0x331c,0x00);
+ }
+
+ dprintk(" UXGA->VGA 640x480");
+}
+
+void set_size_352x288(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_PREVIEW)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x01);
+ sensor_write_reg16(client,0x3089,0x60);
+ sensor_write_reg16(client,0x308a,0x01);
+ sensor_write_reg16(client,0x308b,0x20);
+ sensor_write_reg16(client,0x331a,0x16);
+ sensor_write_reg16(client,0x331b,0x12);
+ sensor_write_reg16(client,0x331c,0x00);
+
+ }
+
+ dprintk(" UXGA->CIF 352x288");
+}
+
+void set_size_176x144(struct i2c_client *client,int mode)
+{
+ if(mode == CAMERA_MODE_PREVIEW)
+ {
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3088,0x00);
+ sensor_write_reg16(client,0x3089,0xb0);
+ sensor_write_reg16(client,0x308a,0x00);
+ sensor_write_reg16(client,0x308b,0x90);
+ sensor_write_reg16(client,0x331a,0x0b);
+ sensor_write_reg16(client,0x331b,0x09);
+ sensor_write_reg16(client,0x331c,0x00);
+ }
+
+ dprintk(" UXGA->QCIF 176x144");
+}
+
+void size_switch(struct i2c_client *client,int width,int height,int setmode)
+{
+ dprintk("%dx%d - mode(%d)",width,height,setmode);
+
+ if(width == 1600 && height == 1200)
+ {
+ set_size_1600x1200(client,setmode);
+ }
+ else if(width == 1280 && height == 1024)
+ {
+ set_size_1280x1024(client,setmode);
+ }
+ else if(width == 1024 && height == 768)
+ {
+ set_size_1024x768(client,setmode);
+ }
+ else if(width == 800 && height == 600)
+ {
+ set_size_800x600(client,setmode);
+ }
+ else if(width == 640 && height == 480)
+ {
+ set_size_640x480(client,setmode);
+ }
+ else if(width == 352 && height == 288)
+ {
+ set_size_352x288(client,setmode);
+ }
+ else if(width == 176 && height == 144)
+ {
+ set_size_176x144(client,setmode);
+ }
+ else
+ return;
+// mdelay(500);
+}
+
+
+void ov2655_init_setting(struct i2c_client *client)
+{
+ //fish add for debug on 2010.6.3
+ dprintk("-sensor ov2655 is initial 1");
+
+ sensor_write_reg16(client,0x3012,0x80);
+
+ mdelay(10);
+
+ //IO & Clock & Analog Setup
+ sensor_write_reg16(client,0x308c,0x80);
+ sensor_write_reg16(client,0x308d,0x0e);
+ sensor_write_reg16(client,0x360b,0x00);
+ sensor_write_reg16(client,0x30b0,0xff);
+ sensor_write_reg16(client,0x30b1,0xff); //fish mark that B[3] 1 is that pclk pin is output
+ sensor_write_reg16(client,0x30b2,0x24); //fish
+
+ sensor_write_reg16(client,0x300e,0x34);
+ sensor_write_reg16(client,0x300f,0xa6);
+ sensor_write_reg16(client,0x3010,0x81);
+ sensor_write_reg16(client,0x3082,0x01);
+ sensor_write_reg16(client,0x30f4,0x01);
+ sensor_write_reg16(client,0x3090,0x33);
+
+ sensor_write_reg16(client,0x3091,0xc0);
+
+ sensor_write_reg16(client,0x30ac,0x42);
+
+ sensor_write_reg16(client,0x30d1,0x08);
+ sensor_write_reg16(client,0x30a8,0x56);
+ sensor_write_reg16(client,0x3015,0x01);
+ sensor_write_reg16(client,0x3093,0x00);
+ sensor_write_reg16(client,0x307e,0xe5);
+ sensor_write_reg16(client,0x3079,0x00);
+ sensor_write_reg16(client,0x30aa,0x42);
+ sensor_write_reg16(client,0x3017,0x40);
+ sensor_write_reg16(client,0x30f3,0x82);
+ sensor_write_reg16(client,0x306a,0x0c);
+ sensor_write_reg16(client,0x306d,0x00);
+ sensor_write_reg16(client,0x336a,0x3c);
+ sensor_write_reg16(client,0x3076,0x6a);
+ sensor_write_reg16(client,0x30d9,0x95);
+ sensor_write_reg16(client,0x3016,0x82);
+ sensor_write_reg16(client,0x3601,0x30);
+ sensor_write_reg16(client,0x304e,0x88);
+ sensor_write_reg16(client,0x30f1,0x82);
+ sensor_write_reg16(client,0x306f,0x14);
+ sensor_write_reg16(client,0x302a,0x02);
+ sensor_write_reg16(client,0x302b,0x6a);
+
+
+ sensor_write_reg16(client,0x3012,0x10);
+ sensor_write_reg16(client,0x3011,0x01); //fish mark B[6] 0 is that master mode,sensor prov2655ides pclk
+ // sensor_write_reg16(client,0x302a,0x02);
+ // sensor_write_reg16(client,0x302b,0xe6);
+ // sensor_write_reg16(client,0x3028,0x07);
+ // sensor_write_reg16(client,0x3029,0x93);
+ dprintk("-sensor ov2655 is initial 22222222222");
+
+ // sensor_write_reg16(client,0x3391,0x06);
+ // sensor_write_reg16(client,0x3394,0x38);
+ // sensor_write_reg16(client,0x3395,0x38);
+
+ //AEC/AGC
+ sensor_write_reg16(client,0x3013,0xf7);
+ // sensor_write_reg16(client,0x3018,0x78);
+ // sensor_write_reg16(client,0x3019,0x68);
+ // sensor_write_reg16(client,0x301a,0xd4);
+ sensor_write_reg16(client,0x301c,0x13);
+ sensor_write_reg16(client,0x301d,0x17);
+ sensor_write_reg16(client,0x3070,0x5d);
+ sensor_write_reg16(client,0x3072,0x4d);
+
+ //D5060
+ sensor_write_reg16(client,0x30af,0x00);
+ sensor_write_reg16(client,0x3048,0x1f);
+ sensor_write_reg16(client,0x3049,0x4e);
+ sensor_write_reg16(client,0x304a,0x20);
+ sensor_write_reg16(client,0x304f,0x20);
+ sensor_write_reg16(client,0x304b,0x02);
+ sensor_write_reg16(client,0x304c,0x00);
+ sensor_write_reg16(client,0x304d,0x02);
+ sensor_write_reg16(client,0x304f,0x20);
+ sensor_write_reg16(client,0x30a3,0x10);
+ sensor_write_reg16(client,0x3013,0xf7);
+ sensor_write_reg16(client,0x3014,0x44); //84
+ sensor_write_reg16(client,0x3071,0x00);
+ sensor_write_reg16(client,0x3070,0x5d);
+ sensor_write_reg16(client,0x3073,0x00);
+ sensor_write_reg16(client,0x3072,0x4d);
+ sensor_write_reg16(client,0x301c,0x05); //07
+ sensor_write_reg16(client,0x301d,0x06); //08
+ sensor_write_reg16(client,0x304d,0x42);
+ sensor_write_reg16(client,0x304a,0x40);
+ sensor_write_reg16(client,0x304f,0x40);
+ sensor_write_reg16(client,0x3095,0x07);
+ sensor_write_reg16(client,0x3096,0x16);
+ sensor_write_reg16(client,0x3097,0x1d);
+
+ //Window Setup
+ sensor_write_reg16(client,0x300e,0x38);
+
+ sensor_write_reg16(client,0x3020,0x01);
+ sensor_write_reg16(client,0x3021,0x18);
+ sensor_write_reg16(client,0x3022,0x00);
+ sensor_write_reg16(client,0x3023,0x06);
+ sensor_write_reg16(client,0x3024,0x06);
+ dprintk("-sensor ov2655 is initial 33333333333");
+ sensor_write_reg16(client,0x3025,0x58);
+ sensor_write_reg16(client,0x3026,0x02);
+ sensor_write_reg16(client,0x3027,0x61); //5e
+ //800x600
+ sensor_write_reg16(client,0x3088,0x03);
+ sensor_write_reg16(client,0x3089,0x20); //high
+ sensor_write_reg16(client,0x308a,0x02);
+ sensor_write_reg16(client,0x308b,0x58); //width
+
+ sensor_write_reg16(client,0x3316,0x64);
+ sensor_write_reg16(client,0x3317,0x25);
+ sensor_write_reg16(client,0x3318,0x80);
+ sensor_write_reg16(client,0x3319,0x08);
+ sensor_write_reg16(client,0x331a,0x64);
+ sensor_write_reg16(client,0x331b,0x4b);
+ sensor_write_reg16(client,0x331c,0x00);
+ sensor_write_reg16(client,0x331d,0x38);
+ sensor_write_reg16(client,0x3100,0x00);
+
+ //AWB
+ sensor_write_reg16(client,0x3320,0xfa);
+ sensor_write_reg16(client,0x3321,0x11);
+ sensor_write_reg16(client,0x3322,0x92);
+ sensor_write_reg16(client,0x3323,0x01);
+ sensor_write_reg16(client,0x3324,0x97);
+ sensor_write_reg16(client,0x3325,0x02);
+ sensor_write_reg16(client,0x3326,0xff);
+ sensor_write_reg16(client,0x3327,0x0c);
+ sensor_write_reg16(client,0x3328,0x10);
+ sensor_write_reg16(client,0x3329,0x10);
+ sensor_write_reg16(client,0x332a,0x58);
+ sensor_write_reg16(client,0x332b,0x50); //56
+ sensor_write_reg16(client,0x332c,0xbe);
+ sensor_write_reg16(client,0x332d,0xe1);
+ sensor_write_reg16(client,0x332e,0x43); //3a
+ sensor_write_reg16(client,0x332f,0x36); //38
+ sensor_write_reg16(client,0x3330,0x4d);
+ sensor_write_reg16(client,0x3331,0x44);
+ sensor_write_reg16(client,0x3332,0xf8);
+ sensor_write_reg16(client,0x3333,0x0a);
+ sensor_write_reg16(client,0x3334,0xf0);
+ sensor_write_reg16(client,0x3335,0xf0);
+ sensor_write_reg16(client,0x3336,0xf0);
+ sensor_write_reg16(client,0x3337,0x40);
+ sensor_write_reg16(client,0x3338,0x40);
+ sensor_write_reg16(client,0x3339,0x40);
+ sensor_write_reg16(client,0x333a,0x00);
+ sensor_write_reg16(client,0x333b,0x00);
+
+ //Color Matrix
+ dprintk("-sensor ov2655 is initial 4");
+ sensor_write_reg16(client,0x3380,0x28);
+ sensor_write_reg16(client,0x3381,0x48);
+ sensor_write_reg16(client,0x3382,0x10);
+ sensor_write_reg16(client,0x3383,0x23); //22
+ sensor_write_reg16(client,0x3384,0xc0);
+ sensor_write_reg16(client,0x3385,0xe5); //e2
+ sensor_write_reg16(client,0x3386,0xc2); //e2
+ sensor_write_reg16(client,0x3387,0xb3); //f2
+ sensor_write_reg16(client,0x3388,0x0e); //10
+ sensor_write_reg16(client,0x3389,0x98);
+ sensor_write_reg16(client,0x338a,0x01); //00
+
+ //Gamma
+ sensor_write_reg16(client,0x3340,0x0e); //04
+ sensor_write_reg16(client,0x3341,0x1a); //07
+ sensor_write_reg16(client,0x3342,0x31); //19
+ sensor_write_reg16(client,0x3343,0x45); //34
+ sensor_write_reg16(client,0x3344,0x5a); //4a
+ sensor_write_reg16(client,0x3345,0x69); //5a
+ sensor_write_reg16(client,0x3346,0x75); //67
+ sensor_write_reg16(client,0x3347,0x7e); //71
+ sensor_write_reg16(client,0x3348,0x88); //7c
+ sensor_write_reg16(client,0x3349,0x96); //8c
+ sensor_write_reg16(client,0x334a,0xa3); //9b
+ sensor_write_reg16(client,0x334b,0xaf); //a9
+ sensor_write_reg16(client,0x334c,0xc4); //c0
+ sensor_write_reg16(client,0x334d,0xd7); //d5
+ sensor_write_reg16(client,0x334e,0xe8);
+ sensor_write_reg16(client,0x334f,0x20);
+
+ //Lens correction(largon 9310)
+ // sensor_write_reg16(client,0x3090,0x03);
+ // sensor_write_reg16(client,0x307c,0x10); //fish mark 0x307c is used to reverse
+ //R
+ sensor_write_reg16(client,0x3350,0x32); //33
+ sensor_write_reg16(client,0x3351,0x25); //28
+ sensor_write_reg16(client,0x3352,0x80); //00
+ sensor_write_reg16(client,0x3353,0x19); //14
+ sensor_write_reg16(client,0x3354,0x00);
+ sensor_write_reg16(client,0x3355,0x85);
+ //G
+ sensor_write_reg16(client,0x3356,0x32); //35
+ sensor_write_reg16(client,0x3357,0x25); //28
+ sensor_write_reg16(client,0x3358,0x80); //00
+ sensor_write_reg16(client,0x3359,0x1b); //13
+ sensor_write_reg16(client,0x335a,0x00);
+ sensor_write_reg16(client,0x335b,0x85);
+ //B
+ sensor_write_reg16(client,0x335c,0x32);
+ dprintk("-sensor ov2655 is initial 5");
+ sensor_write_reg16(client,0x335d,0x25);
+ sensor_write_reg16(client,0x335e,0x80);
+ sensor_write_reg16(client,0x335f,0x1b);
+ sensor_write_reg16(client,0x3360,0x00);
+ sensor_write_reg16(client,0x3361,0x85);
+
+ sensor_write_reg16(client,0x3363,0x70);
+ sensor_write_reg16(client,0x3364,0x7f);
+ sensor_write_reg16(client,0x3365,0x00);
+ sensor_write_reg16(client,0x3366,0x00);
+ // sensor_write_reg16(client,0x3362,0x90);
+
+ //UVadjust
+ sensor_write_reg16(client,0x3301,0xff);
+ sensor_write_reg16(client,0x338B,0x11);
+ sensor_write_reg16(client,0x338c,0x10);
+ sensor_write_reg16(client,0x338d,0x40);
+
+ //Sharpness/De-noise
+ sensor_write_reg16(client,0x3370,0xd0);
+ dprintk("-sensor ov2655 is initial 6");
+ sensor_write_reg16(client,0x3371,0x00);
+ sensor_write_reg16(client,0x3372,0x00);
+ sensor_write_reg16(client,0x3373,0x40);
+ sensor_write_reg16(client,0x3374,0x10);
+ sensor_write_reg16(client,0x3375,0x10);
+ sensor_write_reg16(client,0x3376,0x04);
+ sensor_write_reg16(client,0x3377,0x00);
+ sensor_write_reg16(client,0x3378,0x04);
+ sensor_write_reg16(client,0x3379,0x80);
+
+ //BLC
+ sensor_write_reg16(client,0x3069,0x84);
+ // sensor_write_reg16(client,0x3087,0x02);
+ sensor_write_reg16(client,0x307c,0x10);
+ sensor_write_reg16(client,0x3087,0x02);
+
+ //Other functions
+ sensor_write_reg16(client,0x3300,0xfc);
+ sensor_write_reg16(client,0x3302,0x11);
+ sensor_write_reg16(client,0x3400,0x03); //fish mark that use YUV422
+ sensor_write_reg16(client,0x3606,0x20);
+ sensor_write_reg16(client,0x3601,0x30);
+ // sensor_write_reg16(client,0x30f3,0x83);
+ sensor_write_reg16(client,0x300e,0x34);
+ sensor_write_reg16(client,0x3011,0x00);
+ sensor_write_reg16(client,0x30f3,0x83);
+ sensor_write_reg16(client,0x304e,0x88);
+
+ //fish add from spec 1.54
+ // sensor_write_reg16(client,0x3090,0x03);
+ // sensor_write_reg16(client,0x30aa,0x32);
+ // sensor_write_reg16(client,0x30a3,0x80);
+ // sensor_write_reg16(client,0x30a1,0x41);
+ // sensor_write_reg16(client,0x363b,0x01);
+ // sensor_write_reg16(client,0x363c,0xf2);
+
+ sensor_write_reg16(client,0x3086,0x0f);
+ sensor_write_reg16(client,0x3086,0x00);
+
+
+ dprintk("-sensor ov2655 is initial 7");
+
+ sensor_write_reg16(client,0x3600,0x84);
+
+} /* ov2655_Write_Sensor_Initial_Setting */
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.h b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.h
new file mode 100644
index 00000000000..7ef3bee8e6f
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set.h
@@ -0,0 +1,14 @@
+#ifndef ov2655_SET_H
+#define ov2655_SET_H
+
+#include<linux/i2c.h>
+
+void ov2655_init_setting(struct i2c_client *client);
+void preview_set(struct i2c_client *client);
+void capture_set(struct i2c_client *client);
+void size_switch(struct i2c_client *client,int width,int height,int setmode);
+
+void ov2655_read_shutter(struct i2c_client *client);
+
+#endif
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.c b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.c
new file mode 100644
index 00000000000..7432589596b
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.c
@@ -0,0 +1,185 @@
+#include <asm/jzsoc.h>
+#include "../../jz_sensor.h"
+#include <linux/i2c.h>
+
+#define ov2655_DEBUG
+#ifdef ov2655_DEBUG
+#define dprintk(x...) do{printk("cm3511---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+
+void night_enable(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x300e, 0x34);
+ sensor_write_reg16(client,0x3011, 0x00);
+ sensor_write_reg16(client,0x302c, 0x00);
+ sensor_write_reg16(client,0x3071, 0x00);
+ sensor_write_reg16(client,0x3070, 0xb9);
+ sensor_write_reg16(client,0x301c, 0x02);
+ sensor_write_reg16(client,0x3073, 0x00);
+ sensor_write_reg16(client,0x3072, 0x9a);
+ sensor_write_reg16(client,0x301d, 0x03);
+ sensor_write_reg16(client,0x3014, 0x0c);
+ sensor_write_reg16(client,0x3015, 0x50);
+ sensor_write_reg16(client,0x302e, 0x00);
+ sensor_write_reg16(client,0x302d, 0x00);
+}
+
+void de_night_disable(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3014, 0x04);
+ sensor_write_reg16(client,0x3015, 0x00);
+ sensor_write_reg16(client,0x302e, 0x00);
+ sensor_write_reg16(client,0x302d, 0x00);
+}
+
+void ov2655_night_select(struct i2c_client *client,int enable)
+{
+}
+/*--------------------------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+
+/*----------------------------------set white balance------------------------------------------------*/
+
+void ov2655_set_wb_auto_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3306,0x00); // select Auto WB
+}
+
+void ov2655_set_wb_sunny_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3306, 0x02); // Disable Auto WB, select Manual WB
+ sensor_write_reg16(client,0x3337, 0x5e);
+ sensor_write_reg16(client,0x3338, 0x40);
+ sensor_write_reg16(client,0x3339, 0x46);
+}
+
+void ov2655_set_wb_cloudy_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3306, 0x82); // Disable Auto WB, select Manual WB
+ sensor_write_reg16(client,0x3337, 0x68); //manual R G B
+ sensor_write_reg16(client,0x3338, 0x40);
+ sensor_write_reg16(client,0x3339, 0x4e);
+}
+
+void ov2655_set_wb_office_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3306, 0x02); // Disable Auto WB, select Manual WB
+ sensor_write_reg16(client,0x3337, 0x52);
+ sensor_write_reg16(client,0x3338, 0x40);
+ sensor_write_reg16(client,0x3339, 0x58);
+}
+
+void ov2655_set_wb_home_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3320,0x9a);
+
+ sensor_write_reg16(client,0x3306, 0x02); // Disable Auto WB, select Manual WB
+ sensor_write_reg16(client,0x3337, 0x44);
+ sensor_write_reg16(client,0x3338, 0x40);
+ sensor_write_reg16(client,0x3339, 0x70);
+}
+
+/*--------------------------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+/*---------------------------------------set banding------------------------------------------------*/
+
+void ov2655_ab_auto(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3014, 0x44); /* enable banding and 50 Hz */
+}
+
+void ov2655_ab_50hz(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3014, 0x84); /* enable banding and 50 Hz */
+}
+
+
+void ov2655_ab_60hz(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3014, 0x04); /* enable banding and 60 Hz */
+}
+
+
+void ov2655_ab_off(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3014, 0x44); /* enable banding and 50 Hz */
+}
+/*--------------------------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------------------------*/
+
+
+
+
+
+/*---------------------------------------set effect------------------------------------------------*/
+
+void ov2655_set_effect_normal(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x00);
+}
+
+void ov2655_set_effect_sepia(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x18);
+ sensor_write_reg16(client,0x3396, 0x40);
+ sensor_write_reg16(client,0x3397, 0xa6);
+}
+
+void ov2655_set_effect_bluish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x18);
+ sensor_write_reg16(client,0x3396, 0xa0);
+ sensor_write_reg16(client,0x3397, 0x40);
+}
+
+void ov2655_set_effect_greenish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x18);
+ sensor_write_reg16(client,0x3396, 0x60);
+ sensor_write_reg16(client,0x3397, 0x60);
+}
+
+void ov2655_set_effect_reddish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x18);
+ sensor_write_reg16(client,0x3396, 0x80);
+ sensor_write_reg16(client,0x3397, 0xc0);
+}
+
+void ov2655_set_effect_yellowish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x18);
+ sensor_write_reg16(client,0x3396, 0x30);
+ sensor_write_reg16(client,0x3397, 0x90);
+}
+
+void ov2655_set_effect_blackwhite(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x20);
+}
+
+void ov2655_set_effect_negative(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3391, 0x40); //b[6] is negative
+}
+
+/*--------------------------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------------------------*/
+
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.h b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.h
new file mode 100644
index 00000000000..6447b8f16b2
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov2655/ov2655_set_mode.h
@@ -0,0 +1,32 @@
+#ifndef ov2655_SET_MODE_H
+#define ov2655_SET_MODE_H
+
+#include<linux/i2c.h>
+
+void ov2655_night_select(struct i2c_client *client,int enable);
+
+void ov2655_set_wb_auto_mode(struct i2c_client *client);
+void ov2655_set_wb_sunny_mode(struct i2c_client *client);
+void ov2655_set_wb_cloudy_mode(struct i2c_client *client);
+void ov2655_set_wb_office_mode(struct i2c_client *client);
+void ov2655_set_wb_home_mode(struct i2c_client *client);
+void ov2655_set_wb_fluorescent_mode(struct i2c_client *client);
+
+
+void ov2655_ab_auto(struct i2c_client *client);
+void ov2655_ab_50hz(struct i2c_client *client);
+void ov2655_ab_60hz(struct i2c_client *client);
+void ov2655_ab_off(struct i2c_client *client);
+
+
+void ov2655_set_effect_normal(struct i2c_client *client);
+void ov2655_set_effect_sepia(struct i2c_client *client);
+void ov2655_set_effect_bluish(struct i2c_client *client);
+void ov2655_set_effect_greenish(struct i2c_client *client);
+void ov2655_set_effect_reddish(struct i2c_client *client);
+void ov2655_set_effect_yellowish(struct i2c_client *client);
+void ov2655_set_effect_blackwhite(struct i2c_client *client);
+void ov2655_set_effect_negative(struct i2c_client *client);
+
+#endif
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/Makefile b/drivers/misc/jz_cim/camera_source/ov3640/Makefile
new file mode 100644
index 00000000000..d293555047e
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_OV3640) += ov3640_camera.o ov3640_set_mode.o ov3640_set.o ov3640_focus.o
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.c b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.c
new file mode 100644
index 00000000000..df6a2d5087f
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.c
@@ -0,0 +1,617 @@
+
+
+#include <asm/jzsoc.h>
+#include <linux/i2c.h>
+
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+
+#include "ov3640_camera.h"
+#include "ov3640_set.h"
+#include "ov3640_set_mode.h"
+#include "ov3640_focus.h"
+
+
+//#define OV3640_DEBUG
+//#undef DEBUG
+
+#ifdef OV3640_DEBUG
+#define dprintk(x...) do{printk("OV3640---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+struct camera_sensor_desc ov3640_sensor_desc;
+
+/* gpio init */
+#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) || defined(CONFIG_JZ4750_AQUILA)/* board APUS */
+#define GPIO_CAMERA_RST (32*4+8)
+#elif defined(CONFIG_JZ4760_ALTAIR)
+#define GPIO_CAMERA_RST (32*4+13) /*GPE13*/
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32*1 + 26) /* GPB26 */
+#else
+#error "ov3640/ov3640_camera.c , please define camera for your board."
+#endif
+
+void ov3640_power_down(void)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(4*32+23);
+ __gpio_set_pin(4*32+23);
+#elif defined(CONFIG_JZ4760_ALTAIR)
+ __gpio_as_output(0*32+27); /* GPA27 */
+ __gpio_set_pin(0*32+27);
+#elif defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27); /* GPB27 */
+ __gpio_set_pin(32 * 1 + 27);
+#endif
+ mdelay(5);
+}
+
+void ov3640_power_up(void)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(4*32+23);
+ __gpio_clear_pin(4*32+23);
+#elif defined(CONFIG_JZ4760_ALTAIR)
+ __gpio_as_output(0*32+27);
+ __gpio_clear_pin(0*32+27);
+#elif defined(CONFIG_JZ4760_LEPUS)
+ __gpio_as_output(32 * 1 + 27); /* GPB27 */
+ __gpio_clear_pin(32 * 1 + 27);
+#endif
+ mdelay(5);
+}
+
+
+int ov3640_set_mclk(unsigned int mclk)
+{
+ /* Set the master clock output */
+ /* If use pll clock, enable it */
+ // __cim_set_master_clk(__cpm_get_hclk(), c->mclk);
+ return 0;//in this board use the extra osc - -20MHZ
+}
+
+void ov3640_reset(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+ __gpio_as_output(5*32+23); /* GPIO_IO_SWETCH_EN */
+ __gpio_clear_pin(5*32+23);
+ __gpio_as_output(2*32+31); /* GPIO_BOOTSEL1 for camera rest*/
+ __gpio_set_pin(2*32+31);
+ mdelay(5);
+ __gpio_clear_pin(2*32+31);
+ mdelay(5);
+ __gpio_set_pin(2*32+31);
+#else
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ __gpio_as_output(GPIO_CAMERA_RST);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+#endif
+}
+
+int ov3640_set_balance(balance_flag_t balance_flag,int arg)
+{
+ dprintk("ov3640_set_balance");
+ switch(balance_flag)
+ {
+ case WHITE_BALANCE_AUTO:
+ ov3640_set_wb_auto_mode(ov3640_sensor_desc.client);
+ dprintk("WHITE_BALANCE_AUTO");
+ break;
+ case WHITE_BALANCE_INCANDESCENT :
+ dprintk("WHITE_BALANCE_INCANDESCENT ");
+ break;
+ case WHITE_BALANCE_FLUORESCENT ://ying guang
+ dprintk("WHITE_BALANCE_FLUORESCENT ");
+ break;
+ case WHITE_BALANCE_WARM_FLUORESCENT :
+ dprintk("WHITE_BALANCE_WARM_FLUORESCENT ");
+ break;
+ case WHITE_BALANCE_DAYLIGHT ://ri guang
+ ov3640_set_wb_sunny_mode(ov3640_sensor_desc.client);
+ dprintk("WHITE_BALANCE_DAYLIGHT ");
+ break;
+ case WHITE_BALANCE_CLOUDY_DAYLIGHT ://ying tian
+ ov3640_set_wb_cloudy_mode(ov3640_sensor_desc.client);
+ dprintk("WHITE_BALANCE_CLOUDY_DAYLIGHT ");
+ break;
+ case WHITE_BALANCE_TWILIGHT :
+ dprintk("WHITE_BALANCE_TWILIGHT ");
+ break;
+ case WHITE_BALANCE_SHADE :
+ dprintk("WHITE_BALANCE_SHADE ");
+ break;
+ }
+
+ return 0;
+}
+int ov3640_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ dprintk("ov3640_set_antibanding");
+ switch(antibanding_flag)
+ {
+ case ANTIBANDING_AUTO :
+ ov3640_ab_auto(ov3640_sensor_desc.client);
+ dprintk("ANTIBANDING_AUTO ");
+ break;
+ case ANTIBANDING_50HZ :
+ ov3640_ab_50hz(ov3640_sensor_desc.client);
+ dprintk("ANTIBANDING_50HZ ");
+ break;
+ case ANTIBANDING_60HZ :
+ ov3640_ab_60hz(ov3640_sensor_desc.client);
+ dprintk("ANTIBANDING_60HZ ");
+ break;
+ case ANTIBANDING_OFF :
+ ov3640_ab_off(ov3640_sensor_desc.client);
+ dprintk("ANTIBANDING_OFF ");
+ break;
+ }
+ return 0;
+}
+
+int ov3640_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("ov3640_set_flash_mode");
+ switch(flash_mode_flag)
+ {
+ case FLASH_MODE_OFF :
+ dprintk("FLASH_MODE_OFF");
+ break;
+ case FLASH_MODE_AUTO :
+ dprintk("FLASH_MODE_AUTO ");
+ break;
+ case FLASH_MODE_ON :
+ dprintk("FLASH_MODE_ON ");
+ break;
+ case FLASH_MODE_RED_EYE:
+ dprintk("FLASH_MODE_RED_EYE ");
+ break;
+ case FLASH_MODE_TORCH:
+ dprintk("FLASH_MODE_TORCH ");
+ break;
+ }
+ return 0;
+
+}
+
+int ov3640_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ dprintk("ov3640_set_scene_mode");
+ switch(scene_mode_flag)
+ {
+ case SCENE_MODE_AUTO :
+ dprintk("SCENE_MODE_AUTO ");
+ break;
+ case SCENE_MODE_ACTION :
+ dprintk("SCENE_MODE_ACTION ");
+ break;
+ case SCENE_MODE_PORTRAIT :
+ dprintk("SCENE_MODE_PORTRAIT ");
+ break;
+ case SCENE_MODE_LANDSCAPE :
+ dprintk("SCENE_MODE_LANDSCAPE ");
+ break;
+ case SCENE_MODE_NIGHT :
+ dprintk("SCENE_MODE_NIGHT ");
+ break;
+ case SCENE_MODE_NIGHT_PORTRAIT :
+ dprintk("SCENE_MODE_NIGHT_PORTRAIT ");
+ break;
+ case SCENE_MODE_THEATRE :
+ dprintk("SCENE_MODE_THEATRE ");
+ break;
+ case SCENE_MODE_BEACH :
+ dprintk("SCENE_MODE_BEACH ");
+ break;
+ case SCENE_MODE_SNOW :
+ dprintk("SCENE_MODE_SNOW ");
+ break;
+ case SCENE_MODE_SUNSET :
+ dprintk("SCENE_MODE_SUNSET ");
+ break;
+ case SCENE_MODE_STEADYPHOTO :
+ dprintk("SCENE_MODE_STEADYPHOTO ");
+ break;
+ case SCENE_MODE_FIREWORKS :
+ dprintk("SCENE_MODE_FIREWORKS ");
+ break;
+ case SCENE_MODE_SPORTS :
+ dprintk("SCENE_MODE_SPORTS ");
+ break;
+ case SCENE_MODE_PARTY :
+ dprintk("SCENE_MODE_PARTY ");
+ break;
+ case SCENE_MODE_CANDLELIGHT :
+ dprintk("SCENE_MODE_CANDLELIGHT ");
+ break;
+ }
+ return 0;
+ return 0;
+}
+
+int ov3640_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("ov3640_set_focus_mode");
+ switch(flash_mode_flag)
+ {
+ case FOCUS_MODE_AUTO:
+ dprintk("FOCUS_MODE_AUTO");
+ break;
+ case FOCUS_MODE_INFINITY:
+ dprintk("FOCUS_MODE_INFINITY");
+ break;
+ case FOCUS_MODE_MACRO:
+ dprintk("FOCUS_MODE_MACRO");
+ break;
+ case FOCUS_MODE_FIXED:
+ dprintk("FOCUS_MODE_FIXED");
+ break;
+ }
+
+ ov3640_set_af_mode(flash_mode_flag);
+ return 0;
+}
+
+int ov3640_set_power(int state)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ switch (state)
+ {
+ case 0:
+ /* hardware power up first */
+ ov3640_power_up();
+ /* software power up later if it implemented */
+ break;
+ case 1:
+ ov3640_power_down();
+ break;
+ case 2:
+ break;
+ default:
+ printk("%s : EINVAL! \n",__FUNCTION__);
+ }
+ return 0;
+}
+
+/* sensor_set_function use for init preview or capture.
+ * there may be some difference between preview and capture.
+ * so we divided it into two sequences.
+ * param: function indicated which function
+ * 0: preview
+ * 1: capture
+ * 2: recording
+ */
+int ov3640_set_effect(effect_flag_t effect_flag,int arg)
+{
+ dprintk("ov3640_set_effect");
+ switch(effect_flag)
+ {
+ case EFFECT_NONE:
+ ov3640_set_effect_normal(ov3640_sensor_desc.client);
+ dprintk("EFFECT_NONE");
+ break;
+ case EFFECT_MONO :
+ ov3640_set_effect_black_white(ov3640_sensor_desc.client);
+ dprintk("EFFECT_MONO ");
+ break;
+ case EFFECT_NEGATIVE :
+ ov3640_set_effect_negative(ov3640_sensor_desc.client);
+ dprintk("EFFECT_NEGATIVE ");
+ break;
+ case EFFECT_SOLARIZE ://bao guang
+ dprintk("EFFECT_SOLARIZE ");
+ break;
+ case EFFECT_SEPIA :
+ ov3640_set_effect_sepia(ov3640_sensor_desc.client);
+ dprintk("EFFECT_SEPIA ");
+ break;
+ case EFFECT_POSTERIZE ://se diao fen li
+ dprintk("EFFECT_POSTERIZE ");
+ break;
+ case EFFECT_WHITEBOARD :
+ dprintk("EFFECT_WHITEBOARD ");
+ break;
+ case EFFECT_BLACKBOARD :
+ dprintk("EFFECT_BLACKBOARD ");
+ break;
+ case EFFECT_AQUA ://qian lv se
+ ov3640_set_effect_greenish(ov3640_sensor_desc.client);
+ dprintk("EFFECT_AQUA ");
+ break;
+ case EFFECT_PASTEL:
+ dprintk("EFFECT_PASTEL");
+ break;
+ case EFFECT_MOSAIC:
+ dprintk("EFFECT_MOSAIC");
+ break;
+ case EFFECT_RESIZE:
+ dprintk("EFFECT_RESIZE");
+ break;
+ }
+
+ return 0;
+}
+
+
+int ov3640_set_output_format(pixel_format_flag_t pixel_format_flag,int arg)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ switch(pixel_format_flag)
+ {
+ case PIXEL_FORMAT_JPEG:
+ printk("ov3640 set output format to jepg");
+ break;
+ case PIXEL_FORMAT_YUV422SP:
+ printk("ov3640 set output format to yuv422sp");
+ break;
+ case PIXEL_FORMAT_YUV420SP:
+ printk("ov3640 set output format to yuv420sp");
+ break;
+ case PIXEL_FORMAT_YUV422I:
+ printk("ov3640 set output format to yuv422i");
+ break;
+ case PIXEL_FORMAT_RGB565:
+ printk("ov3640 set output format to rgb565");
+ break;
+ }
+ return 0;
+}
+
+#if 0
+int ov3640_af_init(struct sensor_af_arg *info)
+{
+ unsigned short *reg = info->buf;
+ unsigned char *value = info->buf+2;
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ if(info->len % 3 != 0)
+ return -1;
+ while(value <= info->buf+info->len)
+ {
+ //printk("--------------------------------%4x %2x\n",*reg,*value);
+ sensor_write_reg16(ov3640_sensor_desc.client,*reg,*value);
+ reg =(unsigned short*)((unsigned char *)reg + 3);
+ value += 3;
+ }
+
+// sensor_write_reg16(ov3640_sensor_desc.client,0x3f00,0x01);//focus overlay
+ return 0;
+}
+#endif
+
+int ov3640_set_function(int function,void *cookie)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ switch (function)
+ {
+ case 0:
+ preview_set(ov3640_sensor_desc.client);
+ break;
+ case 1:
+ capture_set(ov3640_sensor_desc.client);
+ break;
+ case 2:
+ break;
+ case 3:
+ dprintk("---- do focus ---");
+ return ov3640_do_focus(ov3640_sensor_desc.client);
+ case 4:
+ ov3640_af_init(ov3640_sensor_desc.client,cookie);
+ break;
+ case 5:
+ ov3640_stop_focus(ov3640_sensor_desc.client);
+ break;
+ }
+
+ return 0;
+}
+
+int ov3640_set_fps(int fps)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ dprintk("set fps : %d",fps);
+ return 0;
+}
+
+int ov3640_set_night_mode(int enable)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ if(enable)
+ dprintk("nightshot_mode enable!");
+ else
+ dprintk("nightshot_mode disable!");
+
+ __ov3640_set_night_mode(ov3640_sensor_desc.client,enable);
+
+ return 0;
+}
+
+int ov3640_set_luma_adaptation(int arg)
+{
+ dprintk("luma_adaptation : %d",arg);
+ return 0;
+}
+
+int ov3640_set_parameter(int cmd, int mode, int arg)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ switch(cmd)
+ {
+ case CPCMD_SET_BALANCE :
+ ov3640_set_balance(mode,arg);
+ break;
+ case CPCMD_SET_EFFECT :
+ ov3640_set_effect(mode,arg);
+ break;
+ case CPCMD_SET_ANTIBANDING :
+ ov3640_set_antibanding(mode,arg);
+ break;
+ case CPCMD_SET_FLASH_MODE :
+ ov3640_set_flash_mode(mode,arg);
+ break;
+ case CPCMD_SET_SCENE_MODE :
+ ov3640_set_scene_mode(mode,arg);
+ break;
+ case CPCMD_SET_PIXEL_FORMAT :
+ ov3640_set_output_format(mode,arg);
+ break;
+ case CPCMD_SET_FOCUS_MODE :
+ ov3640_set_focus_mode(mode,arg);
+ break;
+ case CPCMD_SET_PREVIEW_FPS:
+ ov3640_set_fps(arg);
+ break;
+ case CPCMD_SET_NIGHTSHOT_MODE:
+ ov3640_set_night_mode(arg);
+ break;
+ case CPCMD_SET_LUMA_ADAPTATION:
+ ov3640_set_luma_adaptation(arg);
+ break;
+ }
+ return 0;
+}
+
+int ov3640_sensor_init(void)
+{
+ dprintk("=======%s:%d\n", __FUNCTION__, __LINE__);
+ ov3640_set_mclk(0);
+ ov3640_reset();
+
+ init_set(ov3640_sensor_desc.client);
+ return 0;
+}
+
+
+int ov3640_sensor_probe(void)
+{
+ int retval = 0;
+ ov3640_power_up();
+ ov3640_reset();
+ retval=sensor_read_reg16(ov3640_sensor_desc.client,0x300a);
+ ov3640_power_down();
+
+ if(retval == 0x36)//read id,ov3640 id is 0x36
+ return 0;
+ return -1;
+}
+
+
+
+int ov3640_set_resolution(int width,int height,int bpp,pixel_format_flag_t fmt,camera_mode_t mode)
+{
+ dprintk("ov3640_set_resolution %d x %d",width,height);
+ size_switch(ov3640_sensor_desc.client,width,height,mode);
+ return 0;
+}
+
+
+static int ov3640_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ printk("=====>enter ov3640 probe\n");
+ ov3640_sensor_desc.client = client;
+ sensor_set_i2c_speed(client,400000);//set ov3640 i2c speed : 400khz
+ camera_sensor_register(&ov3640_sensor_desc);
+
+ return 0;
+}
+
+struct camera_sensor_ops ov3640_sensor_ops = {
+ .sensor_init = ov3640_sensor_init,
+ .sensor_set_function = ov3640_set_function,
+ .sensor_set_resolution = ov3640_set_resolution,
+ .sensor_set_parameter = ov3640_set_parameter,
+ .sensor_set_power = ov3640_set_power,
+
+ .camera_sensor_probe = ov3640_sensor_probe,
+};
+
+
+struct resolution_info ov3640_resolution_table[] = {
+ {2048,1536,16,PIXEL_FORMAT_YUV422I},
+ {1600,1200,16,PIXEL_FORMAT_YUV422I},
+ {1280,1024,16,PIXEL_FORMAT_YUV422I},
+ {1024,768,16,PIXEL_FORMAT_YUV422I},
+ {800,600,16,PIXEL_FORMAT_YUV422I},
+ {800,480,16,PIXEL_FORMAT_YUV422I},
+ {640,480,16,PIXEL_FORMAT_YUV422I},
+// {480,320,16,PIXEL_FORMAT_YUV422I},
+ {352,288,16,PIXEL_FORMAT_YUV422I},
+ {320,240,16,PIXEL_FORMAT_YUV422I},
+ {176,144,16,PIXEL_FORMAT_YUV422I},
+};
+
+
+struct camera_sensor_desc ov3640_sensor_desc = {
+ .name = "ov3640",
+ .camera_clock = CAM_CLOCK,
+ .wait_frames = 2,
+ .client = NULL,
+
+ .ops = &ov3640_sensor_ops,
+
+ .resolution_table = ov3640_resolution_table,
+ .resolution_table_nr=ARRAY_SIZE(ov3640_resolution_table),
+
+ .capture_parm = {2048, 1536, 16,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {2048, 1536, 16,PIXEL_FORMAT_YUV422I},
+
+ .preview_parm = {1024,768, 16,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {1024,768, 16,PIXEL_FORMAT_YUV422I},
+
+ .cfg_info = {
+ .configure_register= 0x0
+ |CIM_CFG_PACK_2 /* pack mode : 3 2 1 4*/
+ |CIM_CFG_BYPASS /* Bypass Mode */
+ //|CIM_CFG_VSP /* VSYNC Polarity:1-falling edge active */
+ |CIM_CFG_PCP /* PCLK working edge:1-falling */
+ |CIM_CFG_DSM_GCM, /* Gated Clock Mode */
+ },
+
+ .flags = {
+ .focus_mode_flag = ~0x0,//FOCUS_MODE_INFINITY | FOCUS_MODE_AUTO,
+ //.scene_mode_flag = ~0x0,
+ .antibanding_flag = ~0x0,
+
+ .effect_flag = EFFECT_NONE
+ |EFFECT_MONO
+ |EFFECT_NEGATIVE
+ |EFFECT_SEPIA
+ |EFFECT_AQUA,
+
+ .balance_flag = WHITE_BALANCE_AUTO | WHITE_BALANCE_CLOUDY_DAYLIGHT | WHITE_BALANCE_DAYLIGHT,
+ },
+};
+
+
+static const struct i2c_device_id ov3640_id[] = {
+ { "ov3640", 0 },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(i2c, ov3640_id);
+
+static struct i2c_driver ov3640_driver = {
+ .probe = ov3640_probe,
+ .id_table = ov3640_id,
+ .driver = {
+ .name = "ov3640",
+ },
+};
+
+static int __init ov3640_register(void)
+{
+ printk("=====>enter ov3640 register......\n");
+ return i2c_add_driver(&ov3640_driver);
+}
+
+module_init(ov3640_register);
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.h b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.h
new file mode 100644
index 00000000000..45b9623bbd9
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_camera.h
@@ -0,0 +1,56 @@
+/*
+ * linux/drivers/misc/camera_source/ov3640/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET--------------------
+
+#define CAM_CLOCK 24000000
+
+// MAX SIZE---------------------
+#define MAX_CAP_WIDTH 2048
+#define MAX_CAP_HEIGHT 1536
+
+#define MAX_PRE_WIDTH 1024
+#define MAX_PRE_HEIGHT 768
+
+#define MAX_CAP_BPP 16
+#define MAX_PRE_BPP 16
+
+// DEFAULT SIZE-----------------
+#define DEF_CAP_WIDTH 2048
+#define DEF_CAP_HEIGHT 1536
+
+#define DEF_PRE_WIDTH 1024
+#define DEF_PRE_HEIGHT 768
+
+#define DEF_CAP_BPP 16
+#define DEF_PRE_BPP 16
+
+
+// DATA SAMPLE------------------
+
+#define CAM_DATA_PACK_MODE 5
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 1
+#define CAM_DATA_INV 0
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.c b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.c
new file mode 100644
index 00000000000..9aa268a42a9
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.c
@@ -0,0 +1,198 @@
+#include "ov3640_focus.h"
+#include <asm/jzsoc.h>
+#include "../../jz_sensor.h"
+#include "../../jz_cim_core.h"
+#include<linux/delay.h>
+
+
+#define REG_CMD 0x3f00
+#define REG_STATE 0x3f07
+
+static int focus_mode = FOCUS_MODE_AUTO;
+
+int ov3640_set_af_mode(int mode)
+{
+ focus_mode = mode;
+ return 0;
+}
+
+
+int ov3640_stop_focus(struct i2c_client *client)
+{
+ sensor_write_reg16(client,REG_CMD,0x08);// ?? -> idle
+ sensor_write_reg16(client,REG_CMD,0x02);// disable overlay
+ return 0;
+}
+
+
+int ov3640_do_focus(struct i2c_client *client)
+{
+ switch(focus_mode)
+ {
+ case FOCUS_MODE_AUTO:
+ return ov3640_do_auto_focus(client);
+ case FOCUS_MODE_MACRO:
+ return ov3640_do_macro_focus(client);
+ case FOCUS_MODE_FIXED:
+ return ov3640_do_fixed_focus(client);
+ case FOCUS_MODE_INFINITY:
+ return ov3640_do_infinity_focus(client);
+ }
+ return 0;
+}
+
+
+int ov3640_do_fixed_focus(struct i2c_client *client)
+{
+ return ov3640_stop_focus(client);
+}
+
+int ov3640_do_infinity_focus(struct i2c_client *client)
+{
+ return ov3640_stop_focus(client);//ov3640 default is infinity focus
+}
+
+int ov3640_do_macro_focus(struct i2c_client *client)
+{
+ int count = 20;
+ unsigned char regSTATE = sensor_read_reg16(client,REG_STATE);
+
+ if(regSTATE == S_STARTUP)
+ {
+ printk("S_STARTUP\n");
+ return -1;
+ }
+ if(regSTATE == S_DRIVER_ERR)
+ {
+ printk("S_DRIVER_ERR\n");
+ return -1;
+ }
+
+ ov3640_stop_focus(client);
+ while(sensor_read_reg16(client,REG_STATE) != S_IDLE && count-- > 0)
+ msleep(5);
+
+ if(count <= 0)
+ {
+ printk("S_IDLE\n");
+ return -1;
+ }
+
+ sensor_write_reg16(client,REG_CMD,0x01);// enable overlay
+#if 1
+#define CHECK_TAG() \
+ do{ \
+ int to = 10; \
+ while(sensor_read_reg16(client,REG_TAG) != 0 && to-- > 0) \
+ msleep(10); \
+ if(to <= 0) \
+ { \
+ ov3640_stop_focus(client); \
+ return -1; \
+ } \
+ }while(0)
+
+ sensor_write_reg16(client,REG_TAG,0x04);// step to nearest
+ sensor_write_reg16(client,REG_CMD,0x05);// idle -> step
+ CHECK_TAG();
+
+ sensor_write_reg16(client,REG_TAG,0x01);// step 1
+ sensor_write_reg16(client,REG_CMD,0x05);// step
+ CHECK_TAG();
+
+ sensor_write_reg16(client,REG_TAG,0x01);// step 1
+ sensor_write_reg16(client,REG_CMD,0x05);// step
+ CHECK_TAG();
+
+ sensor_write_reg16(client,REG_TAG,0x01);// step 1
+ sensor_write_reg16(client,REG_CMD,0x05);// step
+ CHECK_TAG();
+
+ sensor_write_reg16(client,REG_TAG,0x04);
+ sensor_write_reg16(client,REG_PARA0,0xff);
+ sensor_write_reg16(client,REG_CMD,0x05);
+ CHECK_TAG();
+
+ sensor_write_reg16(client,REG_TAG,0x04);
+ sensor_write_reg16(client,REG_PARA0,0x80);
+ sensor_write_reg16(client,REG_CMD,0x05);
+ CHECK_TAG();
+
+#undef CHECK_TAG
+#endif
+ sensor_write_reg16(client,REG_CMD,0x02);// disable overlay
+ return 0;
+}
+
+int ov3640_do_auto_focus(struct i2c_client *client)
+{
+ int count = 20;
+ int successed = -1;
+ unsigned char regSTATE = sensor_read_reg16(client,REG_STATE);
+
+ if(regSTATE == S_STARTUP)
+ {
+ printk("S_STARTUP\n");
+ return -1;
+ }
+ if(regSTATE == S_DRIVER_ERR)
+ {
+ printk("S_DRIVER_ERR\n");
+ return -1;
+ }
+
+ ov3640_stop_focus(client);
+
+ while(sensor_read_reg16(client,REG_STATE) != S_IDLE && count-- > 0)
+ msleep(5);
+
+ if(count <= 0)
+ {
+ printk("S_IDLE\n");
+ return -1;
+ }
+
+ sensor_write_reg16(client,REG_CMD,0x01);// enable overlay
+#if 1
+ sensor_write_reg16(client,REG_CMD,0x03);// idle -> signal mode
+#endif
+
+ count = 12;
+ while(count--)
+ {
+ printk("---------------count %d --- ",count);
+ msleep(80);
+ printk(" -00- ");
+ regSTATE = sensor_read_reg16(client,REG_STATE);
+ printk("%2x\n",regSTATE);
+ if(regSTATE & MODE_STEP_FOCUSED)
+ {
+ successed = 0;
+ break;
+ }
+ }
+
+ sensor_write_reg16(client,REG_CMD,0x02);// disable overlay
+ return successed;
+}
+
+int ov3640_af_init(struct i2c_client *client,struct sensor_af_arg *info)
+{
+ unsigned char *tmp_buf = info->buf;
+ unsigned short reg;
+ unsigned char *value = info->buf+2;
+
+ if(info->len % 3 != 0)
+ return -1;
+ while(value <= info->buf+info->len)
+ {
+ reg = (tmp_buf[1] << 8) + tmp_buf[0];
+ sensor_write_reg16(client,reg,*value);
+ tmp_buf += 3;
+ value += 3;
+ }
+
+ return 0;
+}
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.h b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.h
new file mode 100644
index 00000000000..bee86692ad4
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_focus.h
@@ -0,0 +1,50 @@
+
+#ifndef __OV3640_FOUCS_H__
+#define __OV3640_FOCUS_H__
+
+#include<linux/i2c.h>
+#include"../../jz_cim_core.h"
+
+
+#define S_STARTUP 0xff
+#define S_DRIVER_ERR 0xee
+#define S_IDLE 0x00
+#define S_STEP 0x20
+
+#define STEP_STATE_NO 0x80
+#define MASK_MODECHANGE 0x40
+#define MASK_CAPTURECMD 0x20
+#define RESERVED_INVALID 0x10
+#define MODE_IDLE 0x00
+#define MODE_SINGLE 0x04
+#define MODE_CONTINUE 0x08
+#define MODE_STEP 0x0c
+#define MODE_STEP_INSTRUCTION 0x00
+#define MODE_STEP_FOCUSING 0x01
+#define MODE_STEP_FOCUSED 0x02
+#define MODE_STEP_CAPTURE 0x03
+
+#define STATE_INF (MODE_IDLE|MODE_STEP_INSTRUCTION)
+#define STATE_SINGLE (MODE_SINGLE|MODE_STEP_FOCUSING|MASK_MODECHANGE|MASK_CAPTURECMD)
+
+#define STATE_SUCCESS_S (MODE_SINGLE|MODE_STEP_FOCUSED|MASK_MODECHANGE)
+#define STATE_FAIL_S (MODE_SINGLE|MODE_STEP_FOCUSED|MASK_MODECHANGE|STEP_STATE_NO)
+#define STATE_CAPTURE_S (MODE_SINGLE|MODE_STEP_CAPTURE|MASK_MODECHANGE)
+
+#define REG_CMD 0x3f00
+#define REG_TAG 0x3f01
+#define REG_PARA0 0x3f05
+#define REG_STATE 0x3f07
+
+int ov3640_do_focus(struct i2c_client *client);
+int ov3640_stop_focus(struct i2c_client *client);
+int ov3640_af_init(struct i2c_client *client,struct sensor_af_arg *info);
+int ov3640_set_af_mode(int mode);
+
+
+int ov3640_do_auto_focus(struct i2c_client *client);
+int ov3640_do_fixed_focus(struct i2c_client *client);
+int ov3640_do_infinity_focus(struct i2c_client *client);
+int ov3640_do_macro_focus(struct i2c_client *client);
+
+#endif
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.c b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.c
new file mode 100644
index 00000000000..c860e9569cc
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.c
@@ -0,0 +1,645 @@
+#include <asm/jzsoc.h>
+#include "ov3640_set.h"
+#include "ov3640_focus.h"
+#include "../../jz_sensor.h"
+#include "../../jz_cim_core.h"
+
+static int old_width = -1;
+static int old_height = -1;
+static int mode = -1;
+static int res_mode = -1;
+
+void init_set(struct i2c_client *client)
+{
+ old_width = -1;
+ old_height = -1;
+ mode = -1;
+ res_mode = -1;
+
+ /***************** init reg set **************************/
+ /*** VGA preview (640X480) 30fps 24MCLK input ***********/
+
+ printk("------------------------------------init\n");
+
+ sensor_write_reg16(client,0x3012,0x80);
+ sensor_write_reg16(client,0x304d,0x45);
+ sensor_write_reg16(client,0x30a7,0x5e);
+ sensor_write_reg16(client,0x3087,0x16);
+ sensor_write_reg16(client,0x309C,0x1a);
+ sensor_write_reg16(client,0x30a2,0xe4);
+ sensor_write_reg16(client,0x30aa,0x42);
+ sensor_write_reg16(client,0x30b0,0xff);
+ sensor_write_reg16(client,0x30b1,0xff);
+ sensor_write_reg16(client,0x30b2,0x10);
+ sensor_write_reg16(client,0x300e,0x39);
+ sensor_write_reg16(client,0x300f,0x21);
+ sensor_write_reg16(client,0x3010,0x20);
+ sensor_write_reg16(client,0x304c,0x81);
+ sensor_write_reg16(client,0x30d7,0x10);
+ sensor_write_reg16(client,0x30d9,0x0d);
+ sensor_write_reg16(client,0x30db,0x08);
+ sensor_write_reg16(client,0x3016,0x82);
+ sensor_write_reg16(client,0x3018,0x48);
+ sensor_write_reg16(client,0x3019,0x40);
+ sensor_write_reg16(client,0x301a,0x82);
+ sensor_write_reg16(client,0x307d,0x00);
+ sensor_write_reg16(client,0x3087,0x02);
+ sensor_write_reg16(client,0x3082,0x20);
+ //sensor_write_reg16(client,0x3015,0x12);//zi dong zeng yi
+ sensor_write_reg16(client,0x3015,0x11);
+ sensor_write_reg16(client,0x3014,0x84);
+ sensor_write_reg16(client,0x3013,0xf7);
+ sensor_write_reg16(client,0x303c,0x08);
+ sensor_write_reg16(client,0x303d,0x18);
+ sensor_write_reg16(client,0x303e,0x06);
+ sensor_write_reg16(client,0x303F,0x0c);
+ sensor_write_reg16(client,0x3030,0x62);
+ sensor_write_reg16(client,0x3031,0x26);
+ sensor_write_reg16(client,0x3032,0xe6);
+ sensor_write_reg16(client,0x3033,0x6e);
+ sensor_write_reg16(client,0x3034,0xea);
+ sensor_write_reg16(client,0x3035,0xae);
+ sensor_write_reg16(client,0x3036,0xa6);
+ sensor_write_reg16(client,0x3037,0x6a);
+ sensor_write_reg16(client,0x3104,0x02);
+ sensor_write_reg16(client,0x3105,0xfd);
+ sensor_write_reg16(client,0x3106,0x00);
+ sensor_write_reg16(client,0x3107,0xff);
+ sensor_write_reg16(client,0x3300,0x13);
+ sensor_write_reg16(client,0x3301,0xde);
+ sensor_write_reg16(client,0x3302,0xcf);
+ sensor_write_reg16(client,0x3312,0x26);
+ sensor_write_reg16(client,0x3314,0x42);
+ sensor_write_reg16(client,0x3313,0x2b);
+ sensor_write_reg16(client,0x3315,0x42);
+ sensor_write_reg16(client,0x3310,0xd0);
+ sensor_write_reg16(client,0x3311,0xbd);
+ sensor_write_reg16(client,0x330c,0x18);
+ sensor_write_reg16(client,0x330d,0x18);
+ sensor_write_reg16(client,0x330e,0x56);
+ sensor_write_reg16(client,0x330f,0x5c);
+ sensor_write_reg16(client,0x330b,0x1c);
+ sensor_write_reg16(client,0x3306,0x5c);
+ sensor_write_reg16(client,0x3307,0x11);
+ sensor_write_reg16(client,0x336a,0x52);
+ sensor_write_reg16(client,0x3370,0x46);
+ sensor_write_reg16(client,0x3376,0x38);
+ sensor_write_reg16(client,0x30b8,0x20);
+ sensor_write_reg16(client,0x30b9,0x17);
+ sensor_write_reg16(client,0x30ba,0x04);
+ sensor_write_reg16(client,0x30bb,0x08);
+ sensor_write_reg16(client,0x3507,0x06);
+ sensor_write_reg16(client,0x350a,0x4f);
+ sensor_write_reg16(client,0x3100,0x02);
+ sensor_write_reg16(client,0x3301,0xde);
+ sensor_write_reg16(client,0x3304,0xfc);
+ sensor_write_reg16(client,0x3400,0x00);
+ sensor_write_reg16(client,0x3404,0x00);
+ sensor_write_reg16(client,0x3600,0xc0);
+ sensor_write_reg16(client,0x3088,0x08);
+ sensor_write_reg16(client,0x3089,0x00);
+ sensor_write_reg16(client,0x308a,0x06);
+ sensor_write_reg16(client,0x308b,0x00);
+ sensor_write_reg16(client,0x308d,0x04);
+ sensor_write_reg16(client,0x3086,0x03);
+ sensor_write_reg16(client,0x3086,0x00);
+ sensor_write_reg16(client,0x30a9,0xbd);
+ sensor_write_reg16(client,0x3317,0x04);
+ sensor_write_reg16(client,0x3316,0xf8);
+ sensor_write_reg16(client,0x3312,0x17);
+ sensor_write_reg16(client,0x3314,0x30);
+ sensor_write_reg16(client,0x3313,0x23);
+ sensor_write_reg16(client,0x3315,0x3e);
+ sensor_write_reg16(client,0x3311,0x9e);
+ sensor_write_reg16(client,0x3310,0xc0);
+ sensor_write_reg16(client,0x330c,0x18);
+ sensor_write_reg16(client,0x330d,0x18);
+ sensor_write_reg16(client,0x330e,0x5e);
+ sensor_write_reg16(client,0x330f,0x6c);
+ sensor_write_reg16(client,0x330b,0x1c);
+ sensor_write_reg16(client,0x3306,0x5c);
+ sensor_write_reg16(client,0x3307,0x11);
+ sensor_write_reg16(client,0x3308,0x25);
+ sensor_write_reg16(client,0x3340,0x20);
+ sensor_write_reg16(client,0x3341,0x50);
+ sensor_write_reg16(client,0x3342,0x18);
+ sensor_write_reg16(client,0x3343,0x23);
+ sensor_write_reg16(client,0x3344,0xad);
+ sensor_write_reg16(client,0x3345,0xd0);
+ sensor_write_reg16(client,0x3346,0xb8);
+ sensor_write_reg16(client,0x3347,0xb4);
+ sensor_write_reg16(client,0x3348,0x04);
+ sensor_write_reg16(client,0x3349,0x98);
+ sensor_write_reg16(client,0x3355,0x02);
+ sensor_write_reg16(client,0x3358,0x44);
+ sensor_write_reg16(client,0x3359,0x44);
+ sensor_write_reg16(client,0x3300,0x13);
+ sensor_write_reg16(client,0x3367,0x23);
+ sensor_write_reg16(client,0x3368,0xBB);
+ sensor_write_reg16(client,0x3369,0xD6);
+ sensor_write_reg16(client,0x336A,0x2A);
+ sensor_write_reg16(client,0x336B,0x07);
+ sensor_write_reg16(client,0x336C,0x00);
+ sensor_write_reg16(client,0x336D,0x23);
+ sensor_write_reg16(client,0x336E,0xC3);
+ sensor_write_reg16(client,0x336F,0xDE);
+ sensor_write_reg16(client,0x3370,0x2b);
+ sensor_write_reg16(client,0x3371,0x07);
+ sensor_write_reg16(client,0x3372,0x00);
+ sensor_write_reg16(client,0x3373,0x23);
+ sensor_write_reg16(client,0x3374,0x9e);
+ sensor_write_reg16(client,0x3375,0xD6);
+ sensor_write_reg16(client,0x3376,0x29);
+ sensor_write_reg16(client,0x3377,0x07);
+ sensor_write_reg16(client,0x3378,0x00);
+ sensor_write_reg16(client,0x332a,0x1d);
+ sensor_write_reg16(client,0x331b,0x08);
+ sensor_write_reg16(client,0x331c,0x16);
+ sensor_write_reg16(client,0x331d,0x2d);
+ sensor_write_reg16(client,0x331e,0x54);
+ sensor_write_reg16(client,0x331f,0x66);
+ sensor_write_reg16(client,0x3320,0x73);
+ sensor_write_reg16(client,0x3321,0x80);
+ sensor_write_reg16(client,0x3322,0x8c);
+ sensor_write_reg16(client,0x3323,0x95);
+ sensor_write_reg16(client,0x3324,0x9d);
+ sensor_write_reg16(client,0x3325,0xac);
+ sensor_write_reg16(client,0x3326,0xb8);
+ sensor_write_reg16(client,0x3327,0xcc);
+ sensor_write_reg16(client,0x3328,0xdd);
+ sensor_write_reg16(client,0x3329,0xee);
+ sensor_write_reg16(client,0x332e,0x04);
+ sensor_write_reg16(client,0x332f,0x04);
+ sensor_write_reg16(client,0x3331,0x02);
+ sensor_write_reg16(client,0x3012,0x10);
+ sensor_write_reg16(client,0x3023,0x06);
+ sensor_write_reg16(client,0x3026,0x03);
+ sensor_write_reg16(client,0x3027,0x04);
+ sensor_write_reg16(client,0x302a,0x03);
+ sensor_write_reg16(client,0x302b,0x10);
+ sensor_write_reg16(client,0x3075,0x24);
+ sensor_write_reg16(client,0x300d,0x01);
+ sensor_write_reg16(client,0x30d7,0x90);
+ sensor_write_reg16(client,0x3069,0x04);
+ sensor_write_reg16(client,0x303e,0x00);
+ sensor_write_reg16(client,0x303f,0xc0);
+ sensor_write_reg16(client,0x3302,0xef);
+ sensor_write_reg16(client,0x335f,0x34);
+ sensor_write_reg16(client,0x3360,0x0c);
+ sensor_write_reg16(client,0x3361,0x04);
+ sensor_write_reg16(client,0x3362,0x34);
+ sensor_write_reg16(client,0x3363,0x08);
+ sensor_write_reg16(client,0x3364,0x04);
+ sensor_write_reg16(client,0x3403,0x42);
+ sensor_write_reg16(client,0x3088,0x04);
+ sensor_write_reg16(client,0x3089,0x00);
+ sensor_write_reg16(client,0x308a,0x03);
+ sensor_write_reg16(client,0x308b,0x00);
+ sensor_write_reg16(client,0x300e,0x32);
+ sensor_write_reg16(client,0x300f,0x21);
+ sensor_write_reg16(client,0x3010,0x20);
+ sensor_write_reg16(client,0x304c,0x82);
+ sensor_write_reg16(client,0x3302,0xef);
+ sensor_write_reg16(client,0x335f,0x34);
+ sensor_write_reg16(client,0x3360,0x0c);
+ sensor_write_reg16(client,0x3361,0x04);
+ sensor_write_reg16(client,0x3362,0x12);
+ sensor_write_reg16(client,0x3363,0x88);
+ sensor_write_reg16(client,0x3364,0xe4);
+ sensor_write_reg16(client,0x3403,0x42);
+ sensor_write_reg16(client,0x3088,0x12);
+ sensor_write_reg16(client,0x3089,0x80);
+ sensor_write_reg16(client,0x308a,0x01);
+ sensor_write_reg16(client,0x308b,0xe0);
+ sensor_write_reg16(client,0x304c,0x85);
+ sensor_write_reg16(client,0x300e,0x39);
+ sensor_write_reg16(client,0x300f,0xa1);//12.5fps -> 25fps
+ sensor_write_reg16(client,0x3011,0x00);
+ sensor_write_reg16(client,0x3010,0x81);
+ sensor_write_reg16(client,0x302e,0xA0);
+ sensor_write_reg16(client,0x302d,0x00);
+ sensor_write_reg16(client,0x3071,0x82);
+ sensor_write_reg16(client,0x301C,0x05);
+}
+
+
+void capture_reg_set(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3012,0x00);
+ sensor_write_reg16(client,0x3020,0x01);
+ sensor_write_reg16(client,0x3021,0x1d);
+ sensor_write_reg16(client,0x3022,0x00);
+ sensor_write_reg16(client,0x3023,0x0a);
+ sensor_write_reg16(client,0x3024,0x08);
+ sensor_write_reg16(client,0x3025,0x18);
+ sensor_write_reg16(client,0x3026,0x06);
+ sensor_write_reg16(client,0x3027,0x0c);
+ sensor_write_reg16(client,0x302a,0x06);
+ sensor_write_reg16(client,0x302b,0x20);
+ sensor_write_reg16(client,0x3075,0x44);
+ sensor_write_reg16(client,0x300d,0x00);
+ sensor_write_reg16(client,0x30d7,0x10);
+ sensor_write_reg16(client,0x3069,0x40);
+ sensor_write_reg16(client,0x303e,0x01);
+ sensor_write_reg16(client,0x303f,0x80);
+ sensor_write_reg16(client,0x3302,0xef);
+ sensor_write_reg16(client,0x335f,0x68);
+ sensor_write_reg16(client,0x3360,0x18);
+ sensor_write_reg16(client,0x3361,0x0c);
+ sensor_write_reg16(client,0x3362,0x68);
+ sensor_write_reg16(client,0x3363,0x08);
+ sensor_write_reg16(client,0x3364,0x04);
+ sensor_write_reg16(client,0x3403,0x42);
+ sensor_write_reg16(client,0x3088,0x08);
+ sensor_write_reg16(client,0x3089,0x00);
+ sensor_write_reg16(client,0x308a,0x06);
+ sensor_write_reg16(client,0x308b,0x00);
+ sensor_write_reg16(client,0x300e,0x39);
+ sensor_write_reg16(client,0x300f,0x21);
+ sensor_write_reg16(client,0x3010,0x20);
+ sensor_write_reg16(client,0x304c,0x81);
+ sensor_write_reg16(client,0x3366,0x10);
+ sensor_write_reg16(client,0x3011,0x00);
+
+ sensor_write_reg16(client,0x3f00,0x02);//disable overlay
+}
+
+void preview_set(struct i2c_client *client)
+{
+ if(mode == CAMERA_MODE_PREVIEW) // 0 for preview
+ return;
+
+ /***************** preview reg set **************************/
+
+ printk("------------------------------------preview\n");
+
+ sensor_write_reg16(client,0x3012,0x10);
+ sensor_write_reg16(client,0x3023,0x06);
+ sensor_write_reg16(client,0x3026,0x03);
+ sensor_write_reg16(client,0x3027,0x04);
+ sensor_write_reg16(client,0x302a,0x03);
+ sensor_write_reg16(client,0x302b,0x10);
+ sensor_write_reg16(client,0x3075,0x24);
+ sensor_write_reg16(client,0x300d,0x01);
+ sensor_write_reg16(client,0x30d7,0x90);
+ sensor_write_reg16(client,0x3069,0x04);
+ sensor_write_reg16(client,0x303e,0x00);
+ sensor_write_reg16(client,0x303f,0xc0);
+ sensor_write_reg16(client,0x3302,0xef);
+ sensor_write_reg16(client,0x335f,0x34);
+ sensor_write_reg16(client,0x3360,0x0c);
+ sensor_write_reg16(client,0x3361,0x04);
+ sensor_write_reg16(client,0x3362,0x12);
+ sensor_write_reg16(client,0x3363,0x88);
+ sensor_write_reg16(client,0x3364,0xe4);
+ sensor_write_reg16(client,0x3403,0x42);
+ sensor_write_reg16(client,0x3088,0x12);
+ sensor_write_reg16(client,0x3089,0x80);
+ sensor_write_reg16(client,0x308a,0x01);
+ sensor_write_reg16(client,0x308b,0xe0);
+
+ sensor_write_reg16(client,0x304c,0x85);
+ //sensor_write_reg16(client,0x3366,0x10);
+
+ sensor_write_reg16(client,0x300e,0x39);
+ sensor_write_reg16(client,0x300f,0xa1);//12.5fps -> 25fps
+ sensor_write_reg16(client,0x3010,0x81);
+ sensor_write_reg16(client,0x3011,0x00);
+ sensor_write_reg16(client,0x302e,0xa0);
+ sensor_write_reg16(client,0x302d,0x00);
+ sensor_write_reg16(client,0x3071,0x82);
+ sensor_write_reg16(client,0x301C,0x05);
+
+ sensor_write_reg16(client,0x3100,0x02);
+ sensor_write_reg16(client,0x3301,0xde);
+ sensor_write_reg16(client,0x3304,0xfc);
+ sensor_write_reg16(client,0x3400,0x00);
+ sensor_write_reg16(client,0x3404,0x00);
+ sensor_write_reg16(client,0x3600,0xc0);
+
+ sensor_write_reg16(client,0x3013,0xf7);
+ /************************************************************/
+
+
+ ov3640_stop_focus(client);
+
+ mode = CAMERA_MODE_PREVIEW;
+}
+
+void size_switch(struct i2c_client *client,int width,int height,int setmode)
+{
+ char value;
+
+ if(width == old_width && height == old_height && setmode == res_mode)
+ return;
+
+ if(width == 2048 && height == 1536)
+ {
+ sensor_write_reg16(client,0x304c, 0x81);
+ }
+ else if(width == 1600 && height == 1200)
+ {
+ sensor_write_reg16(client,0x304c, 0x81);
+ }
+ else if(width == 1280 && height == 1024)
+ {
+ sensor_write_reg16(client,0x304c, 0x82);
+ }
+ else if(width == 1024 && height == 768)
+ {
+ sensor_write_reg16(client,0x304c, 0x82);
+ }
+ else if(width == 800 && height == 600)
+ {
+ sensor_write_reg16(client,0x304c, 0x82);
+ }
+ else if(width == 800 && height == 480)
+ {
+ sensor_write_reg16(client,0x304c,0x82);
+ }
+ else if(width == 640 && height == 480)
+ {
+ sensor_write_reg16(client,0x304c, 0x82);
+ }
+ else if(width == 480 && height == 320)
+ {
+ sensor_write_reg16(client,0x304c,0x84);
+ }
+ else if(width == 352 && height == 288)
+ {
+ sensor_write_reg16(client,0x304c, 0x84);
+ }
+ else if(width == 320 && height == 240)
+ {
+ sensor_write_reg16(client,0x304c, 0x84);
+ }
+ else if(width == 176 && height == 144)
+ {
+ sensor_write_reg16(client,0x304c, 0x84);
+ }
+ else
+ return;
+
+ old_width = width;
+ old_height = height;
+ res_mode = setmode;
+
+ value = sensor_read_reg16(client,0x3012);
+
+ if ( (value & 0x70) == 0 ) //FULL MODE
+ {
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x335f, 0x68);
+ sensor_write_reg16(client,0x3360, 0x18);
+ sensor_write_reg16(client,0x3361, 0x0c);
+ }
+ else
+ {
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x335f, 0x34);
+ sensor_write_reg16(client,0x3360, 0x0c);
+ sensor_write_reg16(client,0x3361, 0x04);
+ }
+
+ sensor_write_reg16(client,0x3362, (unsigned char)((((width+8)>>8) & 0x0F) + (((height+4)>>4)&0x70)) );
+ sensor_write_reg16(client,0x3363, (unsigned char)((width+8) & 0xFF) );
+ sensor_write_reg16(client,0x3364, (unsigned char)((height+4) & 0xFF) );
+
+ sensor_write_reg16(client,0x3403, 0x42);
+
+ sensor_write_reg16(client,0x3088, (unsigned char)((width>>8)&0xFF) );
+ sensor_write_reg16(client,0x3089, (unsigned char)(width & 0xFF) );
+ sensor_write_reg16(client,0x308a, (unsigned char)((height>>8)&0xFF) );
+ sensor_write_reg16(client,0x308b, (unsigned char)(height & 0xFF) );
+
+ sensor_write_reg16(client,0x3f00,0x12);//update zone
+}
+
+
+void capture_set(struct i2c_client *client)
+{
+ uint8_t reg0x3001;
+ uint8_t reg0x3002,reg0x3003,reg0x3013;
+ uint8_t reg0x3028,reg0x3029;
+ uint8_t reg0x302a,reg0x302b;
+ uint8_t reg0x302d,reg0x302e;
+ uint16_t shutter;
+ uint16_t extra_lines, Preview_Exposure;
+ uint16_t Preview_Gain16;
+ uint16_t Preview_dummy_pixel;
+ uint16_t Capture_max_gain16, Capture_banding_Filter;
+ uint16_t Preview_line_width,Capture_line_width,Capture_maximum_shutter;
+ uint16_t Capture_Exposure;
+
+ uint8_t Mclk =24; //MHz
+ uint8_t Preview_PCLK_frequency, Capture_PCLK_frequency;
+ uint32_t Gain_Exposure,Capture_Gain16;
+ uint8_t Gain;
+
+ uint8_t capture_max_gain = 31;// parm,from 4* gain to 2* gain
+ uint8_t Default_Reg0x3028 = 0x09;
+ uint8_t Default_Reg0x3029 = 0x47;
+ uint8_t Cap_Default_Reg0x302a = 0x06;
+ uint8_t Cap_Default_Reg0x302b = 0x20;
+ uint16_t capture_Dummy_pixel = 0;
+ uint16_t capture_dummy_lines = 0;
+ //uint16_t Default_XGA_Line_Width = 1188;
+ uint16_t Default_QXGA_Line_Width = 2376;
+ uint16_t Default_QXGA_maximum_shutter = 1563;
+
+ if(mode == CAMERA_MODE_CAPTURE) // 1 for capture
+ return;
+
+ /***************** capture reg set **************************/
+
+ printk("------------------------------------capture\n");
+
+
+
+ // 1. Stop Preview
+ //Stop AE/AG
+ reg0x3013 = sensor_read_reg16(client,0x3013);
+ reg0x3013 = reg0x3013 & 0xf8;
+ sensor_write_reg16(client,0x3013,reg0x3013);
+
+ //Read back preview shutter
+ reg0x3002 = sensor_read_reg16(client,0x3002);
+ reg0x3003 = sensor_read_reg16(client,0x3003);
+ shutter = (reg0x3002 << 8) + reg0x3003;
+
+ //Read back extra line
+ reg0x302d = sensor_read_reg16(client,0x302d);
+ reg0x302e = sensor_read_reg16(client,0x302e);
+ extra_lines = reg0x302e + (reg0x302d << 8);
+ Preview_Exposure = shutter + extra_lines;
+
+ //Read Back Gain for preview
+ reg0x3001 = sensor_read_reg16(client,0x3001);
+ Preview_Gain16 = (((reg0x3001 & 0xf0)>>4) + 1) * (16 + (reg0x3001 & 0x0f));
+
+ //Read back dummy pixels
+ reg0x3028 = sensor_read_reg16(client,0x3028);
+ reg0x3029 = sensor_read_reg16(client,0x3029);
+ Preview_dummy_pixel = (((reg0x3028 - Default_Reg0x3028) & 0xf0)<<8) + reg0x3029-Default_Reg0x3029;
+
+ Preview_PCLK_frequency = (64 - 50) * 1 * Mclk / 1.5 / 2 / 2;
+ Capture_PCLK_frequency = (64 - 57) * 1 * Mclk / 1.5 / 2 / 3; // 7.5fps 56MHz
+
+ // 2.Calculate Capture Exposure
+ Capture_max_gain16 = capture_max_gain;
+
+ //In common, Preview_dummy_pixel,Preview_dummy_line,Capture_dummy_pixel and
+ //Capture_dummy_line can be set to zero.
+ Preview_line_width = Default_QXGA_Line_Width + Preview_dummy_pixel ;
+
+ Capture_line_width = Default_QXGA_Line_Width + capture_Dummy_pixel;
+ if(extra_lines>5000)
+ {
+ Capture_Exposure = 16*11/10*Preview_Exposure * Capture_PCLK_frequency/Preview_PCLK_frequency *Preview_line_width/Capture_line_width;
+ }
+ else if(extra_lines>2000)
+ {
+ Capture_Exposure = 16*18/10*Preview_Exposure * Capture_PCLK_frequency/Preview_PCLK_frequency *Preview_line_width/Capture_line_width;
+ }
+ else if(extra_lines>100)
+ {
+ Capture_Exposure = 16*20/10*Preview_Exposure * Capture_PCLK_frequency/Preview_PCLK_frequency *Preview_line_width/Capture_line_width;
+ }
+ else
+ {
+ Capture_Exposure = 16*22/10*Preview_Exposure * Capture_PCLK_frequency/Preview_PCLK_frequency *Preview_line_width/Capture_line_width;
+ }
+ if(Capture_Exposure == 0)
+ {
+ Capture_Exposure =1 ;
+ }
+
+ //Calculate banding filter value
+ //If (50Hz) {Capture_banding_Filter = Capture_PCLK_Frequency/ 100/ (2*capture_line_width);
+ //else {(60Hz)Capture_banding_Filter = Capture_PCLK_frequency /120 /(2*capture_line_width);
+ Capture_banding_Filter = (uint16_t)((float)Capture_PCLK_frequency * 1000000 / 100/ (2*Capture_line_width)+0.5);
+
+ Capture_maximum_shutter = (Default_QXGA_maximum_shutter + capture_dummy_lines)/Capture_banding_Filter;
+ Capture_maximum_shutter = Capture_maximum_shutter * Capture_banding_Filter;
+
+ //redistribute gain and exposure
+ Gain_Exposure = Preview_Gain16 * Capture_Exposure/16;
+ if( Gain_Exposure ==0)
+ {
+ Gain_Exposure =1;
+ }
+
+ if (Gain_Exposure < (Capture_banding_Filter * 16))
+ {
+ // Exposure < 1/100
+ Capture_Exposure = Gain_Exposure /16;
+ Capture_Gain16 = (Gain_Exposure*2 + 1)/Capture_Exposure/2;
+ }
+ else
+
+ {
+ if (Gain_Exposure > Capture_maximum_shutter * 16)
+ {
+ // Exposure > Capture_Maximum_Shutter
+ Capture_Exposure = Capture_maximum_shutter;
+ Capture_Gain16 = (Gain_Exposure*2 + 1)/Capture_maximum_shutter/2;
+
+ if (Capture_Gain16 > Capture_max_gain16)
+ {
+ // gain reach maximum, insert extra line
+ Capture_Exposure = Gain_Exposure*11/10/Capture_max_gain16;
+ // For 50Hz, Exposure = n/100; For 60Hz, Exposure = n/120
+ Capture_Exposure = Capture_Exposure/Capture_banding_Filter;
+ Capture_Exposure =Capture_Exposure * Capture_banding_Filter;
+ Capture_Gain16 = (Gain_Exposure *2+1)/ Capture_Exposure/2;
+ }
+ }
+ else
+ {
+ // 1/100(120) < Exposure < Capture_Maximum_Shutter, Exposure = n/100(120)
+ Capture_Exposure = Gain_Exposure/16/Capture_banding_Filter;
+ Capture_Exposure = Capture_Exposure * Capture_banding_Filter;
+ Capture_Gain16 = (Gain_Exposure*2 +1) / Capture_Exposure/2;
+ }
+ }
+
+ // 3.Switch to QXGA
+ /*// Write registers, change to QXGA resolution.*/
+/***********************************************************************/
+
+ capture_reg_set(client);
+ // 4.Write Registers
+ //write dummy pixels
+ reg0x3029 = sensor_read_reg16(client,0x3029);
+ reg0x3029 = reg0x3029 + (capture_Dummy_pixel & 0x00ff);
+
+ reg0x3028 = sensor_read_reg16(client,0x3028);
+ reg0x3028 = (reg0x3028 & 0x0f) | ((capture_Dummy_pixel & 0x0f00)>>4);
+
+
+ sensor_write_reg16(client,0x3028, reg0x3028);
+ sensor_write_reg16(client,0x3029, reg0x3029);
+
+ //Write Dummy Lines
+ reg0x302b = (capture_dummy_lines & 0x00ff ) + Cap_Default_Reg0x302b;
+ reg0x302a =( capture_dummy_lines >>8 ) + Cap_Default_Reg0x302a;
+ sensor_write_reg16(client,0x302a, reg0x302a);
+ sensor_write_reg16(client,0x302b, reg0x302b);
+
+ //Write Exposure
+ if (Capture_Exposure > Capture_maximum_shutter)
+ {
+ shutter = Capture_maximum_shutter;
+ extra_lines = Capture_Exposure - Capture_maximum_shutter;
+ }
+ else
+ {
+ shutter = Capture_Exposure;
+ extra_lines = 0;
+ }
+
+ reg0x3003 = shutter & 0x00ff;
+ reg0x3002 = (shutter>>8) & 0x00ff;
+ sensor_write_reg16(client,0x3003, reg0x3003);
+ sensor_write_reg16(client,0x3002, reg0x3002);
+
+ // Write extra line
+ reg0x302e= extra_lines & 0x00ff;
+ reg0x302d= extra_lines >> 8;
+ sensor_write_reg16(client,0x302d, reg0x302d);
+ sensor_write_reg16(client,0x302e, reg0x302e);
+
+ // Write Gain
+ Gain = 0;
+ if (Capture_Gain16 > 31)
+ {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = 0x10;
+ }
+ if (Capture_Gain16 > 31)
+ {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain| 0x20;
+ }
+ if (Capture_Gain16 > 31)
+ {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain | 0x40;
+ }
+ if (Capture_Gain16 > 31)
+ {
+ Capture_Gain16 = Capture_Gain16 /2;
+ Gain = Gain | 0x80;
+ }
+ if (Capture_Gain16 > 16)
+ {
+ Gain = Gain | ((uint32_t)Capture_Gain16 -16);
+ }
+
+ sensor_write_reg16(client,0x3001, Gain+0x05);
+// mdelay(500);
+// sensor_write_reg16(client,0x3001, Gain);
+
+/************************************************************/
+ mode = CAMERA_MODE_CAPTURE;
+}
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.h b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.h
new file mode 100644
index 00000000000..3812ff8e8ea
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set.h
@@ -0,0 +1,16 @@
+//
+// Copyright (c) Ingenic Semiconductor Co., Ltd. 2008.
+//
+
+#ifndef __OV3640SET_H__
+#define __OV3640SET_H__
+
+#include <linux/i2c.h>
+
+void init_set(struct i2c_client *client);
+void preview_set(struct i2c_client *client);
+void capture_set(struct i2c_client *client);
+void size_switch(struct i2c_client *client,int width,int height,int setmode);
+
+
+#endif //__OV3640SET_H__
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.c b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.c
new file mode 100644
index 00000000000..25ff4c06d04
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.c
@@ -0,0 +1,263 @@
+/*
+ * OV3640 CMOS Camera Sensor Initialization
+ */
+
+
+#include <asm/jzsoc.h>
+#include "../../jz_sensor.h"
+#include <linux/i2c.h>
+
+static char save_reg[10];
+static int has_saved = -1;
+
+
+void night_mode(struct i2c_client *client)
+{
+
+ if(has_saved != -1)
+ return;
+
+ save_reg[0]=sensor_read_reg16(client,0x300e);
+ save_reg[1]=sensor_read_reg16(client,0x3011);
+ save_reg[2]=sensor_read_reg16(client,0x3010);
+ save_reg[3]=sensor_read_reg16(client,0x302a);
+ save_reg[4]=sensor_read_reg16(client,0x302b);
+ save_reg[5]=sensor_read_reg16(client,0x302c);
+ save_reg[6]=sensor_read_reg16(client,0x3014);
+ save_reg[7]=sensor_read_reg16(client,0x302e);
+ save_reg[8]=sensor_read_reg16(client,0x302d);
+ save_reg[9]=sensor_read_reg16(client,0x3015);
+ sensor_write_reg16(client,0x300e, 0x32);
+ sensor_write_reg16(client,0x3011, 0x00);
+ sensor_write_reg16(client,0x3010, 0x20);
+ sensor_write_reg16(client,0x302a, 0x03);
+ sensor_write_reg16(client,0x302b, 0x92);//add 130 line
+ sensor_write_reg16(client,0x302c, 0x00);
+ sensor_write_reg16(client,0x3014, 0x0c);
+ sensor_write_reg16(client,0x302e, 0x00);
+ sensor_write_reg16(client,0x302d, 0x00);
+ sensor_write_reg16(client,0x3015, 0x42);
+
+ has_saved = 1;
+}
+
+void de_night_mode(struct i2c_client *client)
+{
+ if(has_saved != 1)
+ return;
+
+ sensor_write_reg16(client,0x300e, save_reg[0]);
+ sensor_write_reg16(client,0x3011, save_reg[1]);
+ sensor_write_reg16(client,0x3010, save_reg[2]);
+ sensor_write_reg16(client,0x302a, save_reg[3]);
+ sensor_write_reg16(client,0x302b, save_reg[4]);
+ sensor_write_reg16(client,0x302c, save_reg[5]);
+ sensor_write_reg16(client,0x3014, save_reg[6]);
+ sensor_write_reg16(client,0x302e, save_reg[7]);
+ sensor_write_reg16(client,0x302d, save_reg[8]);
+ sensor_write_reg16(client,0x3015, save_reg[9]);
+
+ has_saved = -1;
+}
+
+
+void __ov3640_set_night_mode(struct i2c_client *client,int enable)
+{
+ if(enable)
+ night_mode(client);
+ else
+ de_night_mode(client);
+}
+
+
+void ov3640_set_wb_auto_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x332b, 0x00);//AWB auto, bit[3]:0,auto
+}
+
+void ov3640_set_wb_sunny_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x332b, 0x08); //AWB off
+ sensor_write_reg16(client,0x33a7, 0x5e);
+ sensor_write_reg16(client,0x33a8, 0x40);
+ sensor_write_reg16(client,0x33a9, 0x46);
+}
+
+void ov3640_set_wb_cloudy_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x332b, 0x08);
+ sensor_write_reg16(client,0x33a7, 0x68);
+ sensor_write_reg16(client,0x33a8, 0x40);
+ sensor_write_reg16(client,0x33a9, 0x4e);
+}
+
+void ov3640_set_wb_office_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x332b, 0x08);
+ sensor_write_reg16(client,0x33a7, 0x52);
+ sensor_write_reg16(client,0x33a8, 0x40);
+ sensor_write_reg16(client,0x33a9, 0x58);
+}
+
+void ov3640_set_wb_home_mode(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x332b, 0x08);
+ sensor_write_reg16(client,0x33a7, 0x44);
+ sensor_write_reg16(client,0x33a8, 0x40);
+ sensor_write_reg16(client,0x33a9, 0x70);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void ov3640_set_effect_antique(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0x40);
+ sensor_write_reg16(client,0x335b, 0xa6);
+}
+
+void ov3640_set_effect_bluish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0xa0);
+ sensor_write_reg16(client,0x335b, 0x40);
+}
+void ov3640_set_effect_reddish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0x80);
+ sensor_write_reg16(client,0x335b, 0xc0);
+}
+
+void ov3640_set_effect_yellowish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0x30);
+ sensor_write_reg16(client,0x335b, 0x90);
+}
+
+
+void ov3640_set_effect_greenish(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0x60);
+ sensor_write_reg16(client,0x335b, 0x60);
+}
+
+
+void ov3640_set_effect_sepia(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);
+ sensor_write_reg16(client,0x335a, 0x40);
+ sensor_write_reg16(client,0x335b, 0xa6);
+}
+
+
+void ov3640_set_effect_black_white(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x18);//bit[4]fix u enable, bit[3]fix v enable
+ sensor_write_reg16(client,0x335a, 0x80);
+ sensor_write_reg16(client,0x335b, 0x80);
+}
+
+void ov3640_set_effect_negative(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x40);//bit[6] negative
+}
+
+void ov3640_set_effect_normal(struct i2c_client *client)
+{
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x00);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/* Adjust brightness [+1 ,+7] */
+void ov3640_set_adjust_bright (struct i2c_client *client, unsigned int level)
+{
+ char val;
+ val = level-4;
+ val *= 16;
+ printk(" ============== val: %d\n", val );
+ if (val>=0)
+ {
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x04|sensor_read_reg16(client,0x3355)); //bit[2] enable
+ sensor_write_reg16(client,0x3354, 0x01); //bit[3] sign of brightness
+ sensor_write_reg16(client,0x335e, val);
+ }
+ else
+ {
+ val =-val;
+ sensor_write_reg16(client,0x3302, 0xef);
+ sensor_write_reg16(client,0x3355, 0x04|sensor_read_reg16(client,0x3355)); //bit[2] enable
+ sensor_write_reg16(client,0x3354, 0x09); //bit[3] sign of brightness
+ sensor_write_reg16(client,0x335e, val);
+ }
+}
+
+
+
+void ov3640_ab_auto(struct i2c_client *client)
+{
+ unsigned char reg3013,reg3014;
+ reg3013 = sensor_read_reg16(client,0x3013);
+ reg3014 = sensor_read_reg16(client,0x3014);
+
+ reg3013 = (reg3013 & ~(0x20)) | 0x20;
+ sensor_write_reg16(client,0x3013, reg3013);
+ reg3014 = (reg3014 & ~(0xc0)) | 0x40;
+ sensor_write_reg16(client,0x3014, reg3014);
+}
+
+void ov3640_ab_50hz(struct i2c_client *client)
+{
+ unsigned char reg3013,reg3014;
+ reg3013 = sensor_read_reg16(client,0x3013);
+ reg3014 = sensor_read_reg16(client,0x3014);
+
+ reg3013 = (reg3013 & ~(0x20)) | 0x20;
+ sensor_write_reg16(client,0x3013, reg3013);
+ reg3014 = (reg3014 & ~(0xc0)) | 0x80;
+ sensor_write_reg16(client,0x3014, reg3014);
+}
+
+
+void ov3640_ab_60hz(struct i2c_client *client)
+{
+ unsigned char reg3013,reg3014;
+ reg3013 = sensor_read_reg16(client,0x3013);
+ reg3014 = sensor_read_reg16(client,0x3014);
+
+ reg3013 = (reg3013 & ~(0x20)) | 0x20;
+ sensor_write_reg16(client,0x3013, reg3013);
+ reg3014 = (reg3014 & ~(0xc0)) | 0x00;
+ sensor_write_reg16(client,0x3014, reg3014);
+}
+
+
+void ov3640_ab_off(struct i2c_client *client)
+{
+ unsigned char reg3013;
+ reg3013 = sensor_read_reg16(client,0x3013);
+
+ reg3013 = (reg3013 & ~(0x20)) | 0x00;
+ sensor_write_reg16(client,0x3013, reg3013);
+}
+
+
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.h b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.h
new file mode 100644
index 00000000000..71165283888
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov3640/ov3640_set_mode.h
@@ -0,0 +1,32 @@
+#ifndef INCLUDE_FILE_OV3640_SET_MODE_H
+#define INCLUDE_FILE_OV3640_SET_MODE_H
+
+void __ov3640_set_night_mode(struct i2c_client *client,int enable);
+void ov3640_set_adjust_bright (struct i2c_client *client, unsigned int level);
+
+
+void ov3640_set_wb_office_mode(struct i2c_client *client);
+void ov3640_set_wb_home_mode(struct i2c_client *client);
+void ov3640_set_wb_auto_mode(struct i2c_client *client);
+void ov3640_set_wb_sunny_mode(struct i2c_client *client);
+void ov3640_set_wb_cloudy_mode(struct i2c_client *client);
+
+void ov3640_set_effect_normal(struct i2c_client *client);
+void ov3640_set_effect_negative(struct i2c_client *client);
+void ov3640_set_effect_black_white(struct i2c_client *client);
+void ov3640_set_effect_greenish(struct i2c_client *client);
+void ov3640_set_effect_sepia(struct i2c_client *client);
+
+void ov3640_set_effect_antique(struct i2c_client *client);
+void ov3640_set_effect_bluish(struct i2c_client *client);
+void ov3640_set_effect_reddish(struct i2c_client *client);
+void ov3640_set_effect_yellowish(struct i2c_client *client);
+
+
+void ov3640_ab_auto(struct i2c_client *client);
+void ov3640_ab_50hz(struct i2c_client *client);
+void ov3640_ab_60hz(struct i2c_client *client);
+void ov3640_ab_off(struct i2c_client *client);
+
+#endif
+
diff --git a/drivers/misc/jz_cim/camera_source/ov7690/Makefile b/drivers/misc/jz_cim/camera_source/ov7690/Makefile
new file mode 100644
index 00000000000..5cdb7a3cc78
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov7690/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_OV7690) += ov7690_camera.o ov7690_set.o
+
diff --git a/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.c b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.c
new file mode 100644
index 00000000000..6828be308a1
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.c
@@ -0,0 +1,497 @@
+
+#include <asm/jzsoc.h>
+
+#include "ov7690_set.h"
+#include "ov7690_camera.h"
+#include <linux/i2c.h>
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+
+#define OV7690_DEBUG
+//#undef DEBUG
+
+#ifdef OV7690_DEBUG
+#define dprintk(x...) do{printk("OV7690---\t");printk(x);printk("\n");}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+/* define reset and powerdown pin */
+#if defined(CONFIG_JZ4750_AQUILA)
+#define OV7690_RESET_PIN
+#define OV7690_PD_PIN (4*32+8) //GPE8
+#elif defined(CONFIG_JZ4760_ALTAIR)
+#define OV7690_RESET_PIN
+#define OV7690_PD_PIN (1*32+9) //GPB9
+#elif define(CONFIG_JZ4760_LEPUS)
+#define OV7690_RESET_PIN (32 * 1 + 26) /* GPB26 */
+#define OV7690_PD_PIN (32 * 1 + 27) /* GPB27 */
+#endif
+
+
+struct camera_sensor_desc ov7690_sensor_desc;
+struct resolution_info ov7690_resolution_table[];
+struct camera_sensor_ops ov7690_sensor_ops;
+
+/* sensor pravite functions */
+static inline void ov7690_hardware_power_down(void)
+{
+ __gpio_as_output(OV7690_PD_PIN);
+ __gpio_set_pin(OV7690_PD_PIN);
+}
+
+static inline void ov7690_hardware_power_up(void)
+{
+ __gpio_as_output(OV7690_PD_PIN);
+ __gpio_clear_pin(OV7690_PD_PIN);
+ /* short wait for power stable */
+ mdelay(3);
+}
+
+static inline void ov7690_software_power_down(void)
+{
+ /* wait for implement later if we need */
+}
+
+static inline void ov7690_software_power_up(void)
+{
+ /* wait for implement later if we need */
+}
+
+
+
+/* new sensor function interface */
+
+/* sensor_set_power use for change sensor power state
+ * state indicate which state is requested
+ * 0: power up
+ * 1: hardware power down
+ * 2: software power down
+ */
+static int sensor_set_power(int state)
+{
+ switch (state)
+ {
+ case 0:
+ /* hardware power up first */
+ ov7690_hardware_power_up();
+ /* software power up later if it implemented */
+ ov7690_software_power_up();
+ break;
+ case 1:
+ ov7690_hardware_power_down();
+ break;
+ case 2:
+ ov7690_software_power_down();
+ break;
+ default:
+ printk("%s : EINVAL! \n",__FUNCTION__);
+ }
+ return 0;
+}
+
+/* sensor_early_init use for init sensor just after power up.
+ * it do these basic initializations but not related preview or capture.
+ * sensor_early_init should be called once after power up.
+ */
+static int sensor_early_init(void)
+{
+ /* enable power supply first*/
+ ov7690_hardware_power_up();
+
+ /* hardware reset */
+ // no used in ov7690
+
+ /* ov7690 internal registers reset */
+ sensor_write_reg(ov7690_sensor_desc.client, 0x12, 0x80);
+ mdelay(3);
+
+ /* set mclk accroding to sensor need */
+ // ov7690 use external crystal
+
+ /* ov7690 basic register initializations */
+ /* ov7690 GPIO init*/
+ sensor_write_reg(ov7690_sensor_desc.client, 0x0c, 0x16);
+
+ return 0;
+}
+
+
+/* sensor_set_function use for init preview or capture.
+ * there may be some difference between preview and capture.
+ * so we divided it into two sequences.
+ * param: function indicated which function
+ * 0: preview
+ * 1: capture
+ * 2: recording
+ */
+static int sensor_set_function(int function,void *cookie)
+{
+ switch (function)
+ {
+ /* ov7690 has the same initializations sequence */
+ case 0:
+ case 1:
+ case 2:
+ sensor_write_reg(ov7690_sensor_desc.client, 0x41, 0x43);
+ sensor_write_reg(ov7690_sensor_desc.client, 0x81, 0xff);
+ sensor_write_reg(ov7690_sensor_desc.client, 0x21, 0x44);
+ sensor_write_reg(ov7690_sensor_desc.client, 0x16, 0x03);
+ sensor_write_reg(ov7690_sensor_desc.client, 0x39, 0x80);
+
+ // ov7690_set_FPS15(ov7690_sensor_desc.client);
+ ov7690_set_FPS25(ov7690_sensor_desc.client);
+ ov7690_lens_corrention_set(ov7690_sensor_desc.client);
+ ov7690_color_matrix_set(ov7690_sensor_desc.client);
+ ov7690_edge_donoise_set(ov7690_sensor_desc.client);
+ ov7690_uvajust_set(ov7690_sensor_desc.client);
+ ov7690_aec_agc_target_set(ov7690_sensor_desc.client);
+ ov7690_gama_set(ov7690_sensor_desc.client);
+ ov7690_general_control_set(ov7690_sensor_desc.client);
+
+ break;
+ }
+ return 0;
+}
+
+/* sensor_probe use for probe weather the sensor present or not
+ * return 0 means success else means fail
+ */
+static int sensor_probe(void)
+{
+ int ok;
+ unsigned char idh,idl;
+ /* power up and reset sensor first */
+ sensor_early_init();
+
+ idh = sensor_read_reg(ov7690_sensor_desc.client, 0x0a);
+ idl = sensor_read_reg(ov7690_sensor_desc.client, 0x0b);
+
+ /* then probe ,just read the sensor ID */
+ if (idh == 0x76 &&
+ (idl == 0x90 || idl == 0x91)) {
+ printk("ov7690 probe suceess!");
+ ok = 0;
+ } else {
+ printk("ov7690 probe fail !");
+ ok = -1;
+ }
+
+ /* hardware power down before we leave */
+ sensor_set_power(1);
+ return ok;
+}
+
+
+static int sensor_set_resolution(int width, int height, int bpp,
+ pixel_format_flag_t fmt, camera_mode_t mode)
+{
+ /* preview and capture has the same setting */
+ /* so we do not care about mode */
+
+ /* we support YUV422I only now */
+
+ if ((width == 640) && (height == 480))
+ {
+ dprintk("640x480");
+ ov7690_640_480(ov7690_sensor_desc.client);
+ }
+ else if ((width == 480) && (height == 320))
+ {
+ dprintk("480x320");
+ ov7690_480_320(ov7690_sensor_desc.client);
+ }
+ else if ((width == 352) && (height == 288))
+ {
+ dprintk("352x288");
+ ov7690_352_288(ov7690_sensor_desc.client);
+ }
+ else if ((width == 320) && (height == 240))
+ {
+ dprintk("320x240");
+ ov7690_320_240(ov7690_sensor_desc.client);
+ }
+ else if ((width == 176) && (height == 144))
+ {
+ dprintk("176x144");
+ ov7690_176_144(ov7690_sensor_desc.client);
+ }
+ else
+ {
+ dprintk("ov7690 do not support this resolution %dx%d!",width, height);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ov7690_set_balance(balance_flag_t balance_flag, int arg)
+{
+ dprintk("ov7690_set_balance");
+ switch(balance_flag)
+ {
+ case WHITE_BALANCE_AUTO:
+ ov7690_set_wb_auto(ov7690_sensor_desc.client);
+ dprintk("WHITE_BALANCE_AUTO");
+ break;
+ case WHITE_BALANCE_DAYLIGHT :
+ ov7690_set_wb_daylight(ov7690_sensor_desc.client);
+ dprintk("WHITE_BALANCE_DAYLIGHT ");
+ break;
+ case WHITE_BALANCE_CLOUDY_DAYLIGHT :
+ ov7690_set_wb_cloudy(ov7690_sensor_desc.client);
+ dprintk("WHITE_BALANCE_CLOUDY_DAYLIGHT ");
+ break;
+ default:
+ dprintk("ov7690 do not support this WB mode %d!",balance_flag);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ov7690_set_effect(effect_flag_t effect_flag,int arg)
+{
+ dprintk("ov7690_set_effect");
+ switch(effect_flag)
+ {
+ case EFFECT_NONE:
+ ov7690_set_effect_none(ov7690_sensor_desc.client);
+ dprintk("EFFECT_NONE");
+ break;
+ case EFFECT_NEGATIVE :
+ ov7690_set_effect_negative(ov7690_sensor_desc.client);
+ dprintk("EFFECT_NEGATIVE ");
+ break;
+ case EFFECT_MONO :
+ ov7690_set_effect_wb(ov7690_sensor_desc.client);
+ dprintk("EFFECT_MONO ");
+ break;
+ case EFFECT_AQUA ://qian lv se
+ ov7690_set_effect_green(ov7690_sensor_desc.client);
+ dprintk("EFFECT_AQUA ");
+ break;
+ default:
+ dprintk("ov7690 do not support this effect mode %d ",effect_flag);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ov7690_set_antibanding(antibanding_flag_t antibanding_flag,int arg)
+{
+ dprintk("ov7690_set_antibanding");
+ switch(antibanding_flag)
+ {
+ case ANTIBANDING_AUTO :
+ ov7690_set_antibanding_auto(ov7690_sensor_desc.client);
+ dprintk("ANTIBANDING_AUTO ");
+ break;
+ default:
+ dprintk("ov7690 support ANTIBANDING_AUTO only!");
+ return -1;
+ }
+ return 0;
+}
+
+static int ov7690_set_flash_mode(flash_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("ov7690_set_flash_mode");
+ switch(flash_mode_flag)
+ {
+ case FLASH_MODE_OFF :
+ dprintk("FLASH_MODE_OFF");
+ break;
+ default:
+ dprintk("ov7690 support FLASH_MODE_OFF only!");
+ return -1;
+ }
+ return 0;
+
+}
+
+static int ov7690_set_scene_mode(scene_mode_flag_t scene_mode_flag,int arg)
+{
+ dprintk("ov7690_set_scene_mode");
+ switch(scene_mode_flag)
+ {
+ case SCENE_MODE_AUTO :
+ ov7690_set_scene_auto(ov7690_sensor_desc.client);
+ dprintk("SCENE_MODE_AUTO ");
+ break;
+ case SCENE_MODE_NIGHT :
+ ov7690_set_scene_night(ov7690_sensor_desc.client);
+ dprintk("SCENE_MODE_NIGHT");
+ break;
+ default:
+ dprintk("ov7690 do not support this scene mode %d !",scene_mode_flag);
+ return -1;
+ }
+ return 0;
+}
+
+static int ov7690_set_focus_mode(focus_mode_flag_t flash_mode_flag,int arg)
+{
+ dprintk("ov7690_set_focus_mode");
+ switch(flash_mode_flag)
+ {
+ case FOCUS_MODE_AUTO:
+ dprintk("FOCUS_MODE_AUTO");
+ break;
+ default:
+ dprintk("ov7690 support FOCUS_MODE_AUTO only!");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ov7690_set_fps(int arg)
+{
+ dprintk("set fps - %d",arg);
+ return 0;
+}
+
+int ov7690_set_night_mode(int enable)
+{
+ if(enable)
+ dprintk("nightshot_mode enable!");
+ else
+ dprintk("nightshot_mode disable!");
+ return 0;
+}
+
+int ov7690_set_luma_adaptation(int arg)
+{
+ dprintk("luma_adaptation : %d",arg);
+ return 0;
+}
+
+static int sensor_set_parameter(int flag1, int flag2, int arg)
+{
+ /* call ov7690_set_scene_mode
+ * ov7690_set_balance
+ * ov7690_set_effect
+ * ........ and so on
+ */
+ switch (flag1)
+ {
+ case CPCMD_SET_BALANCE:
+ return ov7690_set_balance(flag2, arg);
+ case CPCMD_SET_EFFECT:
+ return ov7690_set_effect(flag2, arg);
+ case CPCMD_SET_ANTIBANDING:
+ return ov7690_set_antibanding(flag2, arg);
+ case CPCMD_SET_FLASH_MODE:
+ return ov7690_set_flash_mode(flag2, arg);
+ case CPCMD_SET_SCENE_MODE:
+ return ov7690_set_scene_mode(flag2, arg);
+ case CPCMD_SET_FOCUS_MODE:
+ return ov7690_set_focus_mode(flag2, arg);
+ case CPCMD_SET_PREVIEW_FPS:
+ ov7690_set_fps(arg);
+ break;
+ case CPCMD_SET_NIGHTSHOT_MODE:
+ ov7690_set_night_mode(arg);
+ break;
+ case CPCMD_SET_LUMA_ADAPTATION:
+ ov7690_set_luma_adaptation(arg);
+ break;
+ default:
+ printk("Not supported parameter setting in ov7690! %d ", flag1);
+ }
+
+
+ // ov7690_set_output_format(PIXEL_FORMAT_YUV422I,0);
+ // sensor_write_reg(ov7690_sensor_desc.client, 0x28, 0x40);
+
+ return 0;
+
+}
+
+struct camera_sensor_ops ov7690_sensor_ops = {
+ .sensor_init = sensor_early_init,
+ .sensor_set_power = sensor_set_power,
+ .sensor_set_function = sensor_set_function,
+ .sensor_set_resolution = sensor_set_resolution,
+ .sensor_set_parameter = sensor_set_parameter,
+ .camera_sensor_probe = sensor_probe,
+};
+
+struct resolution_info ov7690_resolution_table[] = {
+ {640,480,16,PIXEL_FORMAT_YUV422I},
+ //{480,320,16,PIXEL_FORMAT_YUV422I},
+ {352,288,16,PIXEL_FORMAT_YUV422I},
+ {320,240,16,PIXEL_FORMAT_YUV422I},
+ {176,144,16,PIXEL_FORMAT_YUV422I},
+};
+
+struct camera_sensor_desc ov7690_sensor_desc = {
+ .name = "ov7690",
+ .camera_clock = CAM_CLOCK,
+ .wait_frames = 0,
+ .client = NULL,
+
+ .ops = &ov7690_sensor_ops,
+
+ .resolution_table = ov7690_resolution_table,
+ .resolution_table_nr = ARRAY_SIZE(ov7690_resolution_table),
+
+ .capture_parm = {640,480 , DEF_CAP_BPP,PIXEL_FORMAT_YUV422I},
+ .max_capture_parm = {640,480 , MAX_CAP_BPP,PIXEL_FORMAT_YUV422I},
+
+ .preview_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+ .max_preview_parm = {640,480, 16,PIXEL_FORMAT_YUV422I},
+
+ .cfg_info = {
+ .configure_register= 0x0
+ |CIM_CFG_PACK_2 /* pack mode : ???? */
+ |CIM_CFG_BYPASS /* Bypass Mode */
+ |CIM_CFG_VSP /* VSYNC Polarity:1-falling edge active */
+ // |CIM_CFG_PCP /* PCLK working edge:1-falling */
+ |CIM_CFG_DSM_GCM, /* Gated Clock Mode */
+ },
+
+ .flags = {
+ //.focus_mode_flag = FOCUS_MODE_AUTO,
+ .effect_flag = EFFECT_NONE | EFFECT_NEGATIVE | EFFECT_AQUA | EFFECT_MONO,
+ .antibanding_flag = ANTIBANDING_AUTO,
+ .balance_flag = WHITE_BALANCE_AUTO | WHITE_BALANCE_DAYLIGHT | WHITE_BALANCE_CLOUDY_DAYLIGHT,
+ .scene_mode_flag = SCENE_MODE_AUTO | SCENE_MODE_NIGHT,
+ //.flash_mode_flag = FLASH_MODE_OFF,
+
+ },
+
+};
+
+static int ov7690_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ ov7690_sensor_desc.client = client;
+ sensor_set_i2c_speed(client,200000);//set i2c speed : 200khz
+ camera_sensor_register(&ov7690_sensor_desc);
+
+ return 0;
+}
+
+static const struct i2c_device_id ov7690_id[] = {
+ /* name, private data to driver */
+ { "ov7690", 0},
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(i2c, ov7690_id);
+
+static struct i2c_driver ov7690_driver = {
+ .probe = ov7690_probe,
+ .id_table = ov7690_id,
+ .driver = {
+ .name = "ov7690",
+ },
+};
+
+static int __init ov7690_register(void)
+{
+ return i2c_add_driver(&ov7690_driver);
+}
+module_init(ov7690_register);
diff --git a/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.h b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.h
new file mode 100644
index 00000000000..3b30eef9224
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_camera.h
@@ -0,0 +1,56 @@
+/*
+ * linux/drivers/misc/camera_source/ov3640/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET--------------------
+
+#define CAM_CLOCK 24000000
+
+// MAX SIZE---------------------
+#define MAX_CAP_WIDTH 640
+#define MAX_CAP_HEIGHT 480
+
+#define MAX_PRE_WIDTH 640
+#define MAX_PRE_HEIGHT 480
+
+#define MAX_CAP_BPP 16
+#define MAX_PRE_BPP 16
+
+// DEFAULT SIZE-----------------
+#define DEF_CAP_WIDTH 640
+#define DEF_CAP_HEIGHT 480
+
+#define DEF_PRE_WIDTH 640
+#define DEF_PRE_HEIGHT 480
+
+#define DEF_CAP_BPP 16
+#define DEF_PRE_BPP 16
+
+
+// DATA SAMPLE------------------
+
+#define CAM_DATA_PACK_MODE 2
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 1
+#define CAM_DATA_INV 0
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.c b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.c
new file mode 100644
index 00000000000..be72221471d
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.c
@@ -0,0 +1,334 @@
+#include <asm/jzsoc.h>
+
+#include <linux/i2c.h>
+#include "../../jz_cim_core.h"
+#include "../../jz_sensor.h"
+
+/************************FPS Set******************************/
+int ov7690_set_FPS15(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x11, 0x01);
+ sensor_write_reg(client, 0x29, 0x50);
+ sensor_write_reg(client, 0x2a, 0x30);
+ sensor_write_reg(client, 0x2b, 0x08);
+ sensor_write_reg(client, 0x2c, 0x00);
+ sensor_write_reg(client, 0x15, 0x00);
+ sensor_write_reg(client, 0x2d, 0x00);
+ sensor_write_reg(client, 0x2e, 0x00);
+ return 0;
+}
+
+int ov7690_set_FPS25(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x11, 0x00);
+ sensor_write_reg(client, 0x29, 0x50);
+ sensor_write_reg(client, 0x2a, 0x30);
+ sensor_write_reg(client, 0x2b, 0x08);
+ sensor_write_reg(client, 0x2c, 0x67);
+ sensor_write_reg(client, 0x15, 0x00);
+ sensor_write_reg(client, 0x2d, 0x00);
+ sensor_write_reg(client, 0x2e, 0x00);
+
+ return 0;
+}
+
+/************************Format Set******************************/
+int ov7690_format_yuv422(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x12, 0x00);
+ sensor_write_reg(client, 0x82, 0x03);
+ sensor_write_reg(client, 0xd0, 0x48);
+ sensor_write_reg(client, 0x80, 0x7f);
+ sensor_write_reg(client, 0x3e, 0x30);
+ sensor_write_reg(client, 0x22, 0x00);
+ return 0;
+}
+
+
+int ov7690_format_rgb565(struct i2c_client *client)
+{
+ return 0;
+}
+
+/*************************Resolution Set*************************/
+int ov7690_640_480(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x16,0x03);
+ sensor_write_reg(client,0x17,0x69);
+ sensor_write_reg(client,0x18,0xa4);
+ sensor_write_reg(client,0x19,0x0c);
+ sensor_write_reg(client,0x1a,0xf6);
+ sensor_write_reg(client,0x22,0x00);
+ sensor_write_reg(client,0xc8,0x02);
+ sensor_write_reg(client,0xc9,0x80);
+ sensor_write_reg(client,0xca,0x01);
+ sensor_write_reg(client,0xcb,0xe0);
+ sensor_write_reg(client,0xcc,0x02);
+ sensor_write_reg(client,0xcd,0x80);
+ sensor_write_reg(client,0xce,0x01);
+ sensor_write_reg(client,0xcf,0xe0);
+ return 0;
+}
+
+int ov7690_480_320(struct i2c_client *client)
+{
+ sensor_write_reg(client,0xcc,0x01);
+ sensor_write_reg(client,0xcd,0xe0);
+ sensor_write_reg(client,0xce,0x01);
+ sensor_write_reg(client,0xcf,0x40);
+ return 0;
+}
+
+
+int ov7690_352_288(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x16,0x03);
+ sensor_write_reg(client,0x17,0x83);
+ sensor_write_reg(client,0x18,0x97);
+ sensor_write_reg(client,0x19,0x08);
+ sensor_write_reg(client,0x1a,0xf6);
+ sensor_write_reg(client,0x22,0x00);
+ sensor_write_reg(client,0xc8,0x02);
+ sensor_write_reg(client,0xc9,0x4c);
+ sensor_write_reg(client,0xca,0x01);
+ sensor_write_reg(client,0xcb,0xe2);
+ sensor_write_reg(client,0xcc,0x01);
+ sensor_write_reg(client,0xcd,0x60);
+ sensor_write_reg(client,0xce,0x01);
+ sensor_write_reg(client,0xcf,0x20);
+ return 0;
+}
+
+int ov7690_320_240(struct i2c_client *client)
+{
+ sensor_write_reg(client,0x16,0x03);
+ sensor_write_reg(client,0x17,0x69);
+ sensor_write_reg(client,0x18,0xa4);
+ sensor_write_reg(client,0x19,0x08);
+ sensor_write_reg(client,0x1a,0xf6);
+ sensor_write_reg(client,0x22,0x10);
+ sensor_write_reg(client,0xc8,0x02);
+ sensor_write_reg(client,0xc9,0x80);
+ sensor_write_reg(client,0xca,0x01);
+ sensor_write_reg(client,0xcb,0xe2);
+
+ sensor_write_reg(client,0xcc,0x01);
+ sensor_write_reg(client,0xcd,0x40);
+ sensor_write_reg(client,0xce,0x00);
+ sensor_write_reg(client,0xcf,0xf0);
+ return 0;
+}
+
+int ov7690_176_144(struct i2c_client *client)
+{
+
+ sensor_write_reg(client,0x16,0x03);
+ sensor_write_reg(client,0x17,0x83);
+ sensor_write_reg(client,0x18,0x97);
+ sensor_write_reg(client,0x19,0x08);
+ sensor_write_reg(client,0x1a,0xf6);
+ sensor_write_reg(client,0x22,0x10);
+ sensor_write_reg(client,0xc8,0x02);
+ sensor_write_reg(client,0xc9,0x4c);
+ sensor_write_reg(client,0xca,0x01);
+ sensor_write_reg(client,0xcb,0xe2);
+ sensor_write_reg(client,0xcc,0x00);
+ sensor_write_reg(client,0xcd,0xb0);
+ sensor_write_reg(client,0xce,0x00);
+ sensor_write_reg(client,0xcf,0x90);
+ return 0;
+}
+
+/****************lens corrention**********************/
+int ov7690_lens_corrention_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x85, 0x90);
+ sensor_write_reg(client, 0x86, 0x00);
+ sensor_write_reg(client, 0x87, 0x00);
+ sensor_write_reg(client, 0x88, 0x10);
+ sensor_write_reg(client, 0x89, 0x30);
+ sensor_write_reg(client, 0x8a, 0x29);
+ sensor_write_reg(client, 0x8b, 0x26);
+ return 0;
+}
+
+int ov7690_color_matrix_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0xbb, 0x80);
+ sensor_write_reg(client, 0xbc, 0x62);
+ sensor_write_reg(client, 0xbd, 0x1e);
+ sensor_write_reg(client, 0xbe, 0x26);
+ sensor_write_reg(client, 0xbf, 0x7b);
+ sensor_write_reg(client, 0xc0, 0xac);
+ sensor_write_reg(client, 0xc1, 0x1e);
+ return 0;
+}
+
+int ov7690_edge_donoise_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0xb7, 0x0c);
+ sensor_write_reg(client, 0xb8, 0x04);
+ sensor_write_reg(client, 0xb9, 0x00);
+ sensor_write_reg(client, 0xba, 0x04);
+ return 0;
+}
+
+int ov7690_uvajust_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x5a, 0x14);
+ sensor_write_reg(client, 0x5b, 0xa2);
+ sensor_write_reg(client, 0x5c, 0x70);
+ sensor_write_reg(client, 0x5d, 0x20);
+ return 0;
+}
+
+int ov7690_aec_agc_target_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x24, 0x78);
+ sensor_write_reg(client, 0x25, 0x68);
+ sensor_write_reg(client, 0x26, 0xb3);
+ return 0;
+}
+
+int ov7690_gama_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0xa3, 0x08);
+ sensor_write_reg(client, 0xa4, 0x15);
+ sensor_write_reg(client, 0xa5, 0x24);
+ sensor_write_reg(client, 0xa6, 0x45);
+ sensor_write_reg(client, 0xa7, 0x55);
+ sensor_write_reg(client, 0xa8, 0x6a);
+ sensor_write_reg(client, 0xa9, 0x78);
+ sensor_write_reg(client, 0xaa, 0x87);
+ sensor_write_reg(client, 0xab, 0x96);
+ sensor_write_reg(client, 0xac, 0xa3);
+ sensor_write_reg(client, 0xad, 0xb4);
+ sensor_write_reg(client, 0xae, 0xc3);
+ sensor_write_reg(client, 0xaf, 0xd6);
+ sensor_write_reg(client, 0xb0, 0xe6);
+ sensor_write_reg(client, 0xb1, 0xf2);
+ sensor_write_reg(client, 0xb2, 0x12);
+ return 0;
+}
+
+int ov7690_general_control_set(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x14, 0x20);
+ sensor_write_reg(client, 0x13, 0xf7);
+ return 0;
+}
+
+int ov7690_set_wb_auto(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x8c, 0x5c);
+ sensor_write_reg(client, 0x8d, 0x11);
+ sensor_write_reg(client, 0x8e, 0x12);
+ sensor_write_reg(client, 0x8f, 0x19);
+ sensor_write_reg(client, 0x90, 0x50);
+ sensor_write_reg(client, 0x91, 0x20);
+ sensor_write_reg(client, 0x92, 0x99);
+ sensor_write_reg(client, 0x93, 0x91);
+ sensor_write_reg(client, 0x94, 0x0f);
+ sensor_write_reg(client, 0x95, 0x13);
+ sensor_write_reg(client, 0x96, 0xff);
+ sensor_write_reg(client, 0x97, 0x00);
+ sensor_write_reg(client, 0x98, 0x38);
+ sensor_write_reg(client, 0x99, 0x33);
+ sensor_write_reg(client, 0x9a, 0x4f);
+ sensor_write_reg(client, 0x9b, 0x43);
+ sensor_write_reg(client, 0x9c, 0xf0);
+ sensor_write_reg(client, 0x9d, 0xf0);
+ sensor_write_reg(client, 0x9e, 0xf0);
+ sensor_write_reg(client, 0x9f, 0xff);
+ sensor_write_reg(client, 0xa0, 0x60);
+ sensor_write_reg(client, 0xa1, 0x5a);
+ sensor_write_reg(client, 0xa2, 0x10);
+ return 0;
+}
+
+int ov7690_set_wb_daylight(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x13, 0xf5);
+ sensor_write_reg(client, 0x01, 0x5a);
+ sensor_write_reg(client, 0x02, 0x5c);
+ sensor_write_reg(client, 0x15, 0x00);
+ return 0;
+}
+
+int ov7690_set_wb_cloudy(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x13, 0xf5);
+ sensor_write_reg(client, 0x01, 0x58);
+ sensor_write_reg(client, 0x02, 0x60);
+ sensor_write_reg(client, 0x15, 0x00);
+ return 0;
+}
+
+int ov7690_set_effect_none(struct i2c_client *client)
+{
+ unsigned char temp;
+ temp = sensor_read_reg(client, 0x81);
+ temp &= 0xdf;
+ sensor_write_reg(client, 0x81, temp);
+ sensor_write_reg(client, 0x28, 0x00);
+ sensor_write_reg(client, 0xd2, 0x00);
+ return 0;
+}
+
+int ov7690_set_effect_negative(struct i2c_client *client)
+{
+ unsigned char temp;
+ temp = sensor_read_reg(client, 0x81);
+ temp |= 0x20;
+ sensor_write_reg(client, 0x81, temp);
+ sensor_write_reg(client, 0x28, 0x80);
+ sensor_write_reg(client, 0xd2, 0x00);
+ return 0;
+}
+
+int ov7690_set_effect_green(struct i2c_client *client)
+{
+ unsigned char temp;
+ temp = sensor_read_reg(client, 0x81);
+ temp |= 0x20;
+ sensor_write_reg(client, 0x81, temp);
+ sensor_write_reg(client, 0x28, 0x00);
+ sensor_write_reg(client, 0xd2, 0x18);
+ sensor_write_reg(client, 0xda, 0x60);
+ sensor_write_reg(client, 0xdb, 0x60);
+ return 0;
+}
+
+
+int ov7690_set_effect_wb(struct i2c_client *client)
+{
+ unsigned char temp;
+ temp = sensor_read_reg(client, 0x81);
+ temp |= 0x20;
+ sensor_write_reg(client, 0x81, temp);
+ sensor_write_reg(client, 0x28, 0x00);
+ sensor_write_reg(client, 0xd2, 0x18);
+ sensor_write_reg(client, 0xda, 0x80);
+ sensor_write_reg(client, 0xdb, 0x80);
+ return 0;
+}
+
+
+int ov7690_set_antibanding_auto(struct i2c_client *client)
+{
+ return 0;
+}
+
+int ov7690_set_scene_auto(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x13, 0xf7);
+ sensor_write_reg(client, 0x15, 0x00);
+ return 0;
+}
+
+int ov7690_set_scene_night(struct i2c_client *client)
+{
+ sensor_write_reg(client, 0x13, 0xf7);
+ sensor_write_reg(client, 0x15, 0xb8);
+ return 0;
+}
diff --git a/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.h b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.h
new file mode 100644
index 00000000000..e1a192c65e5
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov7690/ov7690_set.h
@@ -0,0 +1,43 @@
+#ifndef OV7690_INIT_H
+#define OV7690_INIT_H
+#include <linux/i2c.h>
+
+
+int ov7690_format_yuv422(struct i2c_client *client);
+int ov7690_format_gbr422(struct i2c_client *client);
+int ov7690_format_rgb565(struct i2c_client *client);
+int ov7690_format_wbcraw(struct i2c_client *client);
+int ov7690_format_cipraw(struct i2c_client *client);
+
+int ov7690_640_480(struct i2c_client *client);
+int ov7690_480_320(struct i2c_client *client);
+int ov7690_352_288(struct i2c_client *client);
+int ov7690_320_240(struct i2c_client *client);
+int ov7690_176_144(struct i2c_client *client);
+
+int ov7690_lens_corrention_set(struct i2c_client *client);
+int ov7690_color_matrix_set(struct i2c_client *client);
+int ov7690_edge_donoise_set(struct i2c_client *client);
+int ov7690_uvajust_set(struct i2c_client *client);
+int ov7690_aec_agc_target_set(struct i2c_client *client);
+int ov7690_gama_set(struct i2c_client *client);
+int ov7690_general_control_set(struct i2c_client *client);
+
+int ov7690_set_wb_auto(struct i2c_client *client);
+int ov7690_set_wb_daylight(struct i2c_client *client);
+int ov7690_set_wb_cloudy(struct i2c_client *client);
+
+int ov7690_set_effect_none(struct i2c_client *client);
+int ov7690_set_effect_negative(struct i2c_client *client);
+int ov7690_set_effect_green(struct i2c_client *client);
+int ov7690_set_effect_wb(struct i2c_client *client);
+
+int ov7690_set_antibanding_auto(struct i2c_client *client);
+
+int ov7690_set_scene_auto(struct i2c_client *client);
+int ov7690_set_scene_night(struct i2c_client *client);
+
+int ov7690_set_FPS15(struct i2c_client *client);
+int ov7690_set_FPS25(struct i2c_client *client);
+
+#endif
diff --git a/drivers/misc/jz_cim/camera_source/ov9650/Makefile b/drivers/misc/jz_cim/camera_source/ov9650/Makefile
new file mode 100644
index 00000000000..a55d01913ee
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov9650/Makefile
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_OV9650) += camera.o
+
diff --git a/drivers/misc/jz_cim/camera_source/ov9650/camera.c b/drivers/misc/jz_cim/camera_source/ov9650/camera.c
new file mode 100644
index 00000000000..f87819d0e80
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov9650/camera.c
@@ -0,0 +1,72 @@
+
+
+#include <asm/jzsoc.h>
+
+extern void camera_clk_init(void);
+
+
+/* gpio init */
+#if defined(CONFIG_JZ4750_APUS) || defined(CONFIG_JZ4750D_FUWA1) || defined(CONFIG_JZ4750_AQUILA)/* board APUS */
+#define GPIO_CAMERA_RST (32*4+8) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_F4760) /* JZ4760 FPGA */
+#define GPIO_CAMERA_RST (32*1+9) /* CIM_MCLK as reset */
+#elif defined(CONFIG_JZ4760_LEPUS)
+#define GPIO_CAMERA_RST (32*1 + 26) /* GPB26 */
+#else
+#error "ov9650/camera.c , please define camera for your board."
+#endif
+
+
+void camera_powerdown() {;}
+void camera_powerup() {;}
+
+
+
+void camera_power_init()
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+#error "ov9650/camera.c ,plesase wite a new camera_power_init()"
+#endif
+}
+
+void camera_reset(void)
+{
+#if defined(CONFIG_JZ4750_AQUILA)
+#error "ov9650/camera.c ,plesase wite a new camera_reset()"
+#else
+ __gpio_as_output(GPIO_CAMERA_RST);
+ __gpio_set_pin(GPIO_CAMERA_RST);
+ mdelay(50);
+ __gpio_clear_pin(GPIO_CAMERA_RST);
+#endif
+
+}
+
+void camera_hw_init(void)
+{
+ camera_reset();//mclk_pin used as reset_pin, so make the mclk_pin as gpio first
+
+ //1.cim poewerdowen pin control
+ camera_powerup();
+
+ //2.cim power init
+ camera_power_init();
+
+ //3.cim clock init
+ //if mclk pin is not used for clk ,init it befor camera_clk_init()!
+ camera_clk_init();
+
+ //4.cim reset pin control
+ camera_reset();
+
+}
+
+int camera_set_init(void){return 1;}
+int camera_set_parm(unsigned int id,int32_t parm) {return 1;}
+int camera_set_parm2(unsigned int id,int32_t parm1,int32_t parm2) {return 1;}
+int camera_set_preview(int width, int height, const char *format) {return 1;}
+int camera_set_capture(int width, int height, const char *format) {return 1;}
+
+
+
+
diff --git a/drivers/misc/jz_cim/camera_source/ov9650/camera.h b/drivers/misc/jz_cim/camera_source/ov9650/camera.h
new file mode 100644
index 00000000000..4ac24930253
--- /dev/null
+++ b/drivers/misc/jz_cim/camera_source/ov9650/camera.h
@@ -0,0 +1,55 @@
+/*
+ * linux/drivers/misc/camera_source/ov9650/camera.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define CAP_WAIT_FRAMES 0
+// CLOCK SET--------------------
+
+#define CAM_CLOCK 24000000
+
+// MAX SIZE---------------------
+#define MAX_PICTURE_WIDTH 1280
+#define MAX_PICTURE_HEIGHT 1024
+
+#define MAX_PREVIEW_WIDTH 640
+#define MAX_PREVIEW_HEIGHT 480
+
+#define MAX_PICTURE_BPP 16
+#define MAX_PREVIEW_BPP 16
+
+// DEFAULT SIZE-----------------
+#define DEF_PICTURE_WIDTH 1280
+#define DEF_PICTURE_HEIGHT 1024
+
+#define DEF_PREVIEW_WIDTH 640
+#define DEF_PREVIEW_HEIGHT 480
+
+#define DEF_PICTURE_BPP 16
+#define DEF_PREVIEW_BPP 16
+
+
+// DATA SAMPLE-------------------
+
+#define CAM_DATA_PACK_MODE 4
+#define CAM_DATA_ORDER 0
+#define CAM_DATA_FORMAT 2 //0--RGB 1--YUV444 2--YUV422 3--ITU656 YUV422
+
+#define CAM_SAMPLE_MODE 2
+#define CAM_DUMMY_ZERO 0 //JUST RGB888 CARE
+#define CAM_EXTERNAL_VSYNC 0 //JUST ITU656 CARE
+#define CAM_BYPASS 1 //JUST RGB to YUV transform CARE
+
+
+
+#define CAM_VSP 1 //VSYNC polarity selection.
+#define CAM_HSP 0 //HSYNC polarity selection.
+#define CAM_PSP 0
+#define CAM_DATA_INV 0
+
diff --git a/drivers/misc/jz_cim/jz_cim_board_altair.c b/drivers/misc/jz_cim/jz_cim_board_altair.c
new file mode 100644
index 00000000000..dab964a0ffd
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_board_altair.c
@@ -0,0 +1,17 @@
+#include <asm/jzsoc.h>
+
+void cim_power_off(void)
+{
+ __camera_power_off();
+ cpm_stop_clock(CGM_CIM);
+}
+
+void cim_power_on(void)
+{
+ __camera_power_on();
+ cpm_start_clock(CGM_CIM);
+}
+
+
+
+
diff --git a/drivers/misc/jz_cim/jz_cim_board_apus.c b/drivers/misc/jz_cim/jz_cim_board_apus.c
new file mode 100644
index 00000000000..850894b25af
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_board_apus.c
@@ -0,0 +1,16 @@
+
+
+#include <asm/jzsoc.h>
+
+#define GPIO_CAMERA_RST (32*4+8) /*GPE8 mclk*/
+
+void cim_power_off(void)
+{
+ __camera_power_off();
+}
+
+void cim_power_on(void)
+{
+ __camera_power_on();
+}
+
diff --git a/drivers/misc/jz_cim/jz_cim_board_aquila.c b/drivers/misc/jz_cim/jz_cim_board_aquila.c
new file mode 100644
index 00000000000..ac826c4f80d
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_board_aquila.c
@@ -0,0 +1,26 @@
+
+
+#include <asm/jzsoc.h>
+
+#if 0
+#define cim_power_off() \
+ do{ \
+ __camera_power_off(); \
+ }while(0)
+
+#define cim_power_on() \
+ do{ \
+ __camera_power_on(); \
+ }while(0)
+#endif
+
+void cim_power_off(void)
+{
+ __camera_power_off();
+}
+
+void cim_power_on(void)
+{
+ __camera_power_on();
+}
+
diff --git a/drivers/misc/jz_cim/jz_cim_board_lepus.c b/drivers/misc/jz_cim/jz_cim_board_lepus.c
new file mode 100644
index 00000000000..ffc35962651
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_board_lepus.c
@@ -0,0 +1,17 @@
+#include <asm/jzsoc.h>
+
+void cim_power_off(void)
+{
+ cpm_stop_clock(CGM_CIM);
+}
+
+void cim_power_on(void)
+{
+ cpm_stop_clock(CGM_CIM);
+ cpm_set_clock(CGU_CIMCLK,24000000);
+ cpm_start_clock(CGM_CIM);
+}
+
+
+
+
diff --git a/drivers/misc/jz_cim/jz_cim_board_pt701.c b/drivers/misc/jz_cim/jz_cim_board_pt701.c
new file mode 100644
index 00000000000..ffc35962651
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_board_pt701.c
@@ -0,0 +1,17 @@
+#include <asm/jzsoc.h>
+
+void cim_power_off(void)
+{
+ cpm_stop_clock(CGM_CIM);
+}
+
+void cim_power_on(void)
+{
+ cpm_stop_clock(CGM_CIM);
+ cpm_set_clock(CGU_CIMCLK,24000000);
+ cpm_start_clock(CGM_CIM);
+}
+
+
+
+
diff --git a/drivers/misc/jz_cim/jz_cim_core.c b/drivers/misc/jz_cim/jz_cim_core.c
new file mode 100644
index 00000000000..443215aa896
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_core.c
@@ -0,0 +1,1601 @@
+/*
+ * linux/drivers/misc/jz_cim.c -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/time.h>
+
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/major.h>
+#include <linux/version.h>
+
+
+#include <asm/cacheflush.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/jzsoc.h>
+
+#include "jz_cim_core.h"
+#include "jz_sensor.h"
+
+MODULE_AUTHOR("sonil<ztyan@ingenic.cn>");
+MODULE_DESCRIPTION("Ingenic Camera interface driver");
+MODULE_LICENSE("GPL");
+
+#define CIM_DEBUG
+#define CIM_I_DEBUG
+
+#undef CIM_I_DEBUG
+#undef CIM_DEBUG
+
+#ifdef CIM_DEBUG
+#define dprintk(x...) do{printk("CIM---\t");printk(x);}while(0)
+#else
+#define dprintk(x...)
+#endif
+
+#ifdef CIM_I_DEBUG
+#define iprintk(x...) do{printk(x);}while(0)
+#else
+#define iprintk(x...)
+#endif
+
+#define CIM_NAME "cim"
+
+#define GET_BUF 2
+#define SWAP_BUF 3
+#define SWAP_NR (GET_BUF+SWAP_BUF)
+
+/*
+ * CIM DMA descriptor
+ */
+enum {TRUE=1,FALSE=0};
+
+struct cim_desc {
+ u32 nextdesc; // Physical address of next desc
+ u32 framebuf; // Physical address of frame buffer
+ u32 frameid; // Frame ID
+ u32 dmacmd; // DMA command
+};
+
+/*
+ * CIM device structure
+ */
+
+struct cim_device
+{
+ cim_config_t cim_cfg;
+
+ struct camera_buffer_info preview_binfo;
+ struct camera_buffer_info capture_binfo;
+
+ unsigned char *mem_base;
+ unsigned int mem_size;
+
+ wait_queue_head_t capture_wait_queue;
+ wait_queue_head_t preview_wait_queue;
+
+ struct list_head sensor_lists;
+ struct global_info ginfo;
+
+ int cim_started;
+ int cim_transfer_started;
+ int preview_timeout_state;
+
+ int sensor_inited;
+};
+
+
+static unsigned int buf_offsize_app_drv;
+static struct cim_device *jz_cim;
+
+static int snapshot_flag __read_mostly = 0;
+
+
+//-------------------------------------------------------------------------------------------
+static spinlock_t fresh_lock = SPIN_LOCK_UNLOCKED;
+static int fresh_id __read_mostly = -1;
+static int fresh_buf __read_mostly;
+static int wait_count __read_mostly;
+
+static struct cim_desc frame_desc[SWAP_NR] __attribute__ ((aligned (16)));
+static struct cim_desc capture_desc __attribute__ ((aligned (16)));
+
+/*====================================================================================
+ * sensor muti-support
+ *===================================================================================*/
+
+static LIST_HEAD(sensor_list);
+static DEFINE_MUTEX(sensor_lock);
+static struct camera_sensor_desc *cur_desc __read_mostly = NULL;
+
+
+/*==========================================================================
+ * File operations
+ *========================================================================*/
+
+static int cim_open(struct inode *inode, struct file *filp);
+static int cim_release(struct inode *inode, struct file *filp);
+static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l);
+static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l);
+static int cim_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int cim_mmap(struct file *file, struct vm_area_struct *vma);
+
+static void cim_framebuffer_destroy(void);
+static int cim_set_function(int function,void *cookie);
+
+static int cim_set_preview_resolution(struct resolution_info param);
+
+static int cim_set_capture_resoultion(struct resolution_info param,int state);
+static int cim_set_output_format(pixel_format_flag_t flag,int arg);
+
+int camera_sensor_register(struct camera_sensor_desc *desc)
+{
+ if(desc==NULL)
+ return -EINVAL;
+
+ desc->sensor_id = 0xffff;
+
+ desc->max_capture_size=
+ desc->max_capture_parm.width
+ *desc->max_capture_parm.height
+ *desc->max_capture_parm.bpp >> 3;
+
+ desc->max_preview_size=
+ desc->max_preview_parm.width
+ *desc->max_preview_parm.height
+ *desc->max_preview_parm.bpp >> 3;
+
+ mutex_lock(&sensor_lock);
+ list_add_tail(&desc->list,&sensor_list);
+ mutex_unlock(&sensor_lock);
+
+ desc->ops->sensor_set_power(1);
+ return 0;
+}
+
+void cim_scan_sensor(void)
+{
+ struct camera_sensor_desc *si;
+ struct list_head *tmp;
+
+ mutex_lock(&sensor_lock);
+ list_for_each_entry(si, &sensor_list, list)
+ {
+ printk("scan sensor:%s\n",si->name);
+
+ if(si->ops->camera_sensor_probe() != 0)
+ {
+ tmp=si->list.prev;
+ list_del(&si->list);
+ si=list_entry(tmp,struct camera_sensor_desc,list);
+ }
+ }
+
+ mutex_unlock(&sensor_lock);
+}
+
+void sensors_make_default(void)
+{
+ struct camera_sensor_desc *si;
+ printk("now we has:\n");
+ mutex_lock(&sensor_lock);
+
+ cur_desc = NULL;
+ list_for_each_entry(si, &sensor_list, list)
+ {
+ si->sensor_id = jz_cim->ginfo.sensor_count;
+ jz_cim->ginfo.sensor_count++;
+ printk("sensor_name:%s\t\tid:%d\n",si->name,si->sensor_id);
+ cur_desc = si;
+ }
+
+ printk("default is %s\n",cur_desc->name);
+ mutex_unlock(&sensor_lock);
+ jz_cim->ginfo.preview_buf_nr = SWAP_NR;
+}
+/*==========================================================================
+ * CIM print operations
+ *========================================================================*/
+static void cim_print_regs(void)
+{
+ printk("REG_CIM_CFG \t= \t0x%08x\n", REG_CIM_CFG);
+ printk("REG_CIM_CTRL \t= \t0x%08x\n", REG_CIM_CTRL);
+ printk("REG_CIM_STATE \t= \t0x%08x\n", REG_CIM_STATE);
+ printk("REG_CIM_IID \t= \t0x%08x\n", REG_CIM_IID);
+ printk("REG_CIM_DA \t= \t0x%08x\n", REG_CIM_DA);
+ printk("REG_CIM_FA \t= \t0x%08x\n", REG_CIM_FA);
+ printk("REG_CIM_FID \t= \t0x%08x\n", REG_CIM_FID);
+ printk("REG_CIM_CMD \t= \t0x%08x\n", REG_CIM_CMD);
+ printk("REG_CIM_SIZE \t= \t0x%08x\n", REG_CIM_SIZE);
+ printk("REG_CIM_OFFSET \t= \t0x%08x\n", REG_CIM_OFFSET);
+}
+
+#if 0
+static void cim_print_buffers(void)
+{
+ int i;
+ printk("cim_tran_buf_id%x\n",cim_tran_buf_id);
+ printk("data_ready_buf_id=0x%x\n",data_ready_buf_id);
+
+ for(i=0;i<3;i++)
+ {
+ printk("cim_framebuf_desc[%d]=0x%x\n",i,cim_frame_desc[i].framebuf);
+ printk("cim_frameid _desc[%d]=0x%x\n",i,cim_frame_desc[i].frameid);
+ printk("cim_dmacmd _desc[%d]=0x%x\n",i,cim_frame_desc[i].dmacmd);
+ printk("cim_nextdesc_desc[%d]=0x%x\n\n",i,cim_frame_desc[i].nextdesc);
+ }
+
+ printk("preview_working_buf=0x%x\n",preview_working_buf);
+ printk("recorder_prepare_buf=0x%x\n",recorder_prepare_buf);
+ printk("recorder_working_buf=0x%x\n\n",recorder_working_buf);
+}
+#endif
+
+/*==========================================================================
+ * Framebuffer allocation and destroy
+ *========================================================================*/
+
+static int cim_init_capture_desc(void)
+{
+ int capture_frmsize = ((cur_desc->capture_parm.width * cur_desc->capture_parm.height
+ * cur_desc->capture_parm.bpp) >> 3);
+
+ dprintk("cap_size=0x%x\n",capture_frmsize);
+
+ capture_desc.framebuf = jz_cim->capture_binfo.base_paddr;;
+ capture_desc.nextdesc = virt_to_phys(&capture_desc);
+ capture_desc.frameid = 0xff;
+ //capture_desc.dmacmd = (capture_frmsize>>2) | CIM_CMD_EOFINT | CIM_CMD_STOP;
+ capture_desc.dmacmd = (capture_frmsize>>2) | CIM_CMD_EOFINT;
+#ifdef CONFIG_SOC_JZ4760
+ capture_desc.dmacmd |= CIM_CMD_OFRCV ;
+#endif
+ if(cur_desc->wait_frames == 0)
+ capture_desc.dmacmd |= CIM_CMD_STOP;
+
+ dma_cache_wback_inv((unsigned long)&capture_desc, sizeof(struct cim_desc));
+ return 0;
+}
+
+static int cim_init_preview_desc(void)
+{
+
+ int i;
+
+ dprintk("=================preview: width = %d height = %d bpp = %d\n",
+ cur_desc->preview_parm.width , cur_desc->preview_parm.height, cur_desc->preview_parm.bpp);
+ int preview_frmsize = ((cur_desc->preview_parm.width * cur_desc->preview_parm.height
+ * cur_desc->preview_parm.bpp) >> 3);
+
+ dprintk("pre_size=0x%x",preview_frmsize);
+
+//--------------------------------------------------------------------------------------------
+
+ for (i= 0; i< SWAP_NR; i++)
+ {
+ frame_desc[i].framebuf = jz_cim->preview_binfo.base_paddr + jz_cim->ginfo.max_preview_size * i;
+ frame_desc[i].frameid = i;
+ frame_desc[i].dmacmd = (preview_frmsize>>2) | CIM_CMD_EOFINT ;
+#ifdef CONFIG_SOC_JZ4760
+ frame_desc[i].dmacmd |= CIM_CMD_OFRCV ;
+#endif
+ frame_desc[i].nextdesc = virt_to_phys(&frame_desc[i+1]);
+ }
+
+ frame_desc[SWAP_BUF-1].nextdesc = virt_to_phys(&frame_desc[0]);
+
+ for(i = 0; i < GET_BUF; i++)
+ {
+ frame_desc[SWAP_BUF+i].nextdesc = virt_to_phys(NULL);
+ }
+
+ for (i = 0; i < SWAP_BUF; i++)
+ dma_cache_wback((unsigned long)(&frame_desc[i]), sizeof(struct cim_desc));
+
+
+//----------------------------------------------------------------------------------------------
+ return 0;
+}
+
+static void cim_framebuffer_destroy(void)
+{
+ if(jz_cim->mem_base != 0)
+ {
+ int page_order;
+ __cim_disable();
+
+ if(jz_cim->mem_size == 0)
+ {
+ dprintk("Original memory is NULL\n");
+ return;
+ }
+ page_order = get_order(jz_cim->mem_size);
+ free_pages((unsigned long)jz_cim->mem_base, page_order);
+ jz_cim->mem_base = 0;
+ dprintk("cim_fb_destory!\n");
+ }
+}
+
+static unsigned int cim_init_fb_info(int swap_nr)
+{
+ unsigned int max_p_size=0,max_c_size=0;
+ struct camera_sensor_desc *si;
+
+ mutex_lock(&sensor_lock);
+ list_for_each_entry(si, &sensor_list, list)
+ {
+ if(si->max_preview_size > max_p_size)
+ max_p_size = si->max_preview_size;
+ if(si->max_capture_size > max_c_size)
+ max_c_size = si->max_capture_size;
+ }
+ mutex_unlock(&sensor_lock);
+
+ dprintk("get_max_mem_size\n");
+ dprintk("preview size = %dKB\n",max_p_size>>10);
+ dprintk("capture size = %dKB\n",max_c_size>>10);
+
+ jz_cim->ginfo.max_preview_size = max_p_size;
+ jz_cim->ginfo.max_capture_size = max_c_size;
+
+ jz_cim->preview_binfo.buffer_size = max_p_size * swap_nr;
+ jz_cim->capture_binfo.buffer_size = max_c_size;
+
+ return max_p_size * swap_nr + max_c_size;
+}
+
+
+static int cim_fb_alloc(void)
+{
+ unsigned int mem_size = 0;
+ int order = 0;
+
+ if (jz_cim->mem_base == 0 )
+ {
+ dprintk("get new page!\n");
+ mem_size=cim_init_fb_info(SWAP_NR);
+ order = get_order(mem_size);
+
+ dprintk("mem_size=%dK\n",mem_size>>10);
+ dprintk("order=%d\n",order);
+
+#if 1
+ jz_cim->mem_base = (unsigned char *)__get_free_pages(GFP_KERNEL, order);
+
+ if (jz_cim->mem_base == NULL)
+ {
+ printk("GET FREE PAGES FAILED!\n");
+ return -ENOMEM;
+ }
+
+ jz_cim->preview_binfo.base_vaddr = (unsigned int)jz_cim->mem_base;
+ jz_cim->preview_binfo.base_paddr = virt_to_phys(jz_cim->mem_base);
+
+ jz_cim->capture_binfo.base_vaddr = (unsigned int)jz_cim->mem_base + jz_cim->preview_binfo.buffer_size;
+ jz_cim->capture_binfo.base_paddr = virt_to_phys(jz_cim->mem_base + jz_cim->preview_binfo.buffer_size);
+
+#endif
+ jz_cim->mem_size = mem_size;
+ jz_cim->ginfo.mmap_size = mem_size;
+ }
+
+ return 0;
+}
+
+
+/*==========================================================================
+ * CIM Module operations
+ *========================================================================*/
+
+static void cim_config(cim_config_t *c)
+{
+
+ REG_CIM_CFG = c->cfg;
+ REG_CIM_CTRL = c->ctrl;
+ REG_CIM_SIZE = c->size;
+ REG_CIM_OFFSET = c->offs;
+
+ if(cur_desc->no_dma) //just for fake sensor test
+ return;
+
+ // Enable sof, eof and stop interrupts
+ __cim_enable_dma();
+
+ __cim_enable_eof_intr();
+
+ __cim_enable_rxfifo_overflow_intr();
+}
+
+static void cim_init_config(struct camera_sensor_desc *desc)
+{
+ if(desc == NULL)
+ return;
+
+ memset(&jz_cim->cim_cfg,0,sizeof(jz_cim->cim_cfg));
+
+ jz_cim->cim_cfg.cfg = cur_desc->cfg_info.configure_register;
+ jz_cim->cim_cfg.cfg &=~CIM_CFG_DMA_BURST_TYPE_MASK;
+#if defined(CONFIG_SOC_JZ4760)
+ jz_cim->cim_cfg.cfg |= CIM_CFG_DMA_BURST_INCR16;
+ jz_cim->cim_cfg.ctrl = CIM_CTRL_DMA_SYNC | CIM_CTRL_FRC_1 | (1<<CIM_CTRL_RXF_TRIG_BIT);// (n+1)*burst = 2*16 = 32 <64
+#else
+ jz_cim->cim_cfg.cfg |= CIM_CFG_DMA_BURST_INCR8;
+ jz_cim->cim_cfg.ctrl = CIM_CTRL_FRC_1 | CIM_CTRL_RXF_TRIG_8 | CIM_CTRL_FAST_MODE; // 16 < 32
+#endif
+
+ return;
+}
+
+
+static int cim_device_init(void)
+{
+ cim_init_config(cur_desc);
+ cim_config(&jz_cim->cim_cfg);
+ return 0;
+}
+
+
+inline void cim_start(void)
+{
+ if(jz_cim->cim_started == TRUE)
+ return;
+
+ jz_cim->cim_started = TRUE;
+
+ cim_power_on();
+ cur_desc->ops->sensor_set_power(0);
+}
+
+static void cim_stop_preview(void)
+{
+ if(jz_cim->cim_transfer_started == 0)
+ return;
+
+ jz_cim->cim_transfer_started = 0;
+
+ __cim_disable();
+ __cim_clear_state();
+ //cur_desc->ops->sensor_set_power(1);
+}
+
+
+static void cim_stop(void)
+{
+ if(cur_desc == NULL || jz_cim->cim_started == FALSE)
+ return;
+
+ cim_stop_preview();
+
+ cur_desc->ops->sensor_set_power(1);
+ cim_power_off();
+
+ jz_cim->cim_started = FALSE;
+ jz_cim->sensor_inited = FALSE;
+}
+
+
+void cim_start_preview(void)
+{
+ if(cur_desc == NULL || jz_cim->cim_transfer_started == 1 || jz_cim->cim_started == FALSE)
+ return;
+
+ __cim_disable();
+
+ fresh_id = -1;
+ fresh_buf = 0;
+
+ jz_cim->cim_transfer_started = 1;
+ cur_desc->ops->sensor_set_power(0);
+
+ cim_device_init();
+
+ if(jz_cim->sensor_inited == FALSE)
+ {
+ cur_desc->ops->sensor_init();
+
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_BALANCE,
+ cur_desc->parms.balance_flag,cur_desc->parms.balance_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_EFFECT,
+ cur_desc->parms.effect_flag,cur_desc->parms.effect_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_ANTIBANDING,
+ cur_desc->parms.antibanding_flag,cur_desc->parms.antibanding_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_FLASH_MODE,
+ cur_desc->parms.flash_mode_flag,cur_desc->parms.flash_mode_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_SCENE_MODE,
+ cur_desc->parms.scene_mode_flag,cur_desc->parms.scene_mode_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_FOCUS_MODE,
+ cur_desc->parms.focus_mode_flag,cur_desc->parms.focus_mode_flag_arg);
+
+ jz_cim->sensor_inited = TRUE;
+ }
+
+ cim_init_preview_desc();
+
+ cim_set_function(0,NULL);
+ cim_set_preview_resolution(cur_desc->preview_parm);
+
+ if(cur_desc->no_dma) //just for fake sensor test
+ return;
+
+ __cim_set_da(virt_to_phys(&frame_desc[0]));
+ __cim_clear_state(); // clear state register
+ __cim_reset_rxfifo(); // resetting rxfifo
+ __cim_unreset_rxfifo();
+ __cim_enable_dma();
+ __cim_enable();
+
+}
+
+#define OUTPUT_TIME() \
+ do{ \
+ struct timeval s; \
+ do_gettimeofday(&s); \
+ printk("%s, %d --- %ld us\n", __FUNCTION__, __LINE__,s.tv_sec * 1000000LL + s.tv_usec); \
+ }while(0)
+
+static int cim_snapshot(void)
+{
+ if(cur_desc == NULL) return -ENODEV;
+
+ wait_count = 0;
+ snapshot_flag = 1;
+
+ __cim_disable();
+ __cim_clear_state(); // clear state register
+ __cim_set_da(virt_to_phys(&capture_desc));
+ __cim_reset_rxfifo(); // resetting rxfifo
+ __cim_unreset_rxfifo();
+
+ dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+
+ cim_device_init();
+
+ if(jz_cim->cim_transfer_started != 1)
+ {
+ cur_desc->ops->sensor_set_power(0);
+
+ if(jz_cim->sensor_inited == FALSE)
+ {
+ cur_desc->ops->sensor_init();
+
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_BALANCE,
+ cur_desc->parms.balance_flag,cur_desc->parms.balance_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_EFFECT,
+ cur_desc->parms.effect_flag,cur_desc->parms.effect_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_ANTIBANDING,
+ cur_desc->parms.antibanding_flag,cur_desc->parms.antibanding_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_FLASH_MODE,
+ cur_desc->parms.flash_mode_flag,cur_desc->parms.flash_mode_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_SCENE_MODE,
+ cur_desc->parms.scene_mode_flag,cur_desc->parms.scene_mode_flag_arg);
+ cur_desc->ops->sensor_set_parameter(CPCMD_SET_FOCUS_MODE,
+ cur_desc->parms.focus_mode_flag,cur_desc->parms.focus_mode_flag_arg);
+
+ jz_cim->sensor_inited = TRUE;
+ }
+
+ jz_cim->cim_transfer_started = 1;
+ }
+
+ cim_init_capture_desc();
+
+ cim_set_function(1,NULL);
+ cim_set_capture_resoultion(cur_desc->capture_parm,1);
+
+ //OUTPUT_TIME();
+ dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ if(unlikely(cur_desc->no_dma)) //just for fake sensor test
+ {
+ if(cur_desc->ops->camera_fill_buffer != NULL)
+ cur_desc->ops->camera_fill_buffer(
+ jz_cim->capture_binfo.base_vaddr,
+ cur_desc
+ );//only for fake camera test
+ }
+ else
+ {
+ dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ dprintk("SNAPSHOT START!");
+ dprintk("SNAPSHOT WRITE DMA PADDR:%u\n",capture_desc.framebuf);
+
+ __cim_enable();
+
+ interruptible_sleep_on(&jz_cim->capture_wait_queue);
+ }
+ //OUTPUT_TIME();
+
+ dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ cim_stop_preview();
+ snapshot_flag = 0;
+
+ return 0;
+}
+/*==========================================================================
+ * Interrupt handler
+ *========================================================================*/
+
+static irqreturn_t cim_irq_handler(int irq, void *dev_id)
+{
+ u32 state = REG_CIM_STATE;
+ unsigned long flags;
+
+ if (state & CIM_STATE_DMA_EOF)
+ {
+ if(likely(snapshot_flag != 1))
+ {
+ spin_lock_irqsave(fresh_lock,flags);
+ jz_cim->preview_timeout_state = 1;
+
+ fresh_id = __cim_get_iid() - 1;
+ if(fresh_id == -1)
+ fresh_id = SWAP_BUF-1;
+
+
+ spin_unlock_irqrestore(fresh_lock,flags);
+
+ if(waitqueue_active(&jz_cim->preview_wait_queue))
+ wake_up_interruptible(&jz_cim->preview_wait_queue);
+
+ REG_CIM_STATE &= ~CIM_STATE_DMA_EOF;
+ return IRQ_HANDLED;
+ }
+ else
+ {
+ dprintk("capture frame wait : %d\n",wait_count);
+
+ ++wait_count;
+#if 0
+ if(wait_count == cur_desc->wait_frames)
+ {
+ capture_desc.dmacmd |= CIM_CMD_STOP;
+ dma_cache_wback((unsigned long)(&capture_desc), sizeof(struct cim_desc));
+ }
+#endif
+
+ if(wait_count >= cur_desc->wait_frames + 1)
+ {
+ __cim_disable();
+ wake_up_interruptible(&jz_cim->capture_wait_queue);
+ __cim_clear_state();
+ return IRQ_HANDLED;
+ }
+
+ REG_CIM_STATE &= ~CIM_STATE_DMA_EOF;
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (state & CIM_STATE_RXF_OF)
+ {
+
+ REG_CIM_STATE &= ~CIM_STATE_VDD;
+ __cim_disable();
+ __cim_reset_rxfifo();
+ __cim_unreset_rxfifo();
+ __cim_clear_state(); // clear state register
+ __cim_enable();
+
+ dprintk("OverFlow interrupt!\n");
+ return IRQ_HANDLED;
+ }
+
+ __cim_clear_state(); // clear state register
+ return IRQ_HANDLED;
+}
+
+static struct file_operations cim_fops =
+{
+ open: cim_open,
+ release: cim_release,
+ read: cim_read,
+ write: cim_write,
+ ioctl: cim_ioctl,
+ mmap: cim_mmap,
+
+};
+
+static int cim_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int cim_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+unsigned int get_phy_addr(unsigned int vaddr)
+{
+ unsigned int addr=vaddr & (PAGE_SIZE-1);
+ pgd_t *pgdir;
+#ifdef CONFIG_PGTABLE_4
+ pud_t *pudir;
+#endif
+ pmd_t *pmdir;
+ pte_t *pte;
+
+ dprintk("current task(%d)'s pgd is 0x%x\n",current->pid,current->mm->pgd);
+
+ pgdir=pgd_offset(current->mm,vaddr);
+ if(pgd_none(*pgdir)||pgd_bad(*pgdir))
+ return -EINVAL;
+
+#ifdef CONFIG_PGTABLE_4
+ pudir=pud_offset(pgdir,vaddr);
+ if(pud_none(*pudir)||pud_bad(*pudir))
+ return -EINVAL;
+
+ pmdir=pmd_offset(pudir,vaddr);
+ if(pmd_none(*pmdir)||pmd_bad(*pmdir))
+ return -EINVAL;
+#else
+ pmdir=pmd_offset((pud_t *)pgdir,vaddr);
+ if(pmd_none(*pmdir)||pmd_bad(*pmdir))
+ return -EINVAL;
+#endif
+
+ pte=pte_offset(pmdir,vaddr);
+
+ if(pte_present(*pte))
+ {
+ return addr | (pte_pfn(*pte)<<PAGE_SHIFT);
+ //pte_page(*pte);
+ }
+
+ return -EINVAL;
+}
+
+static ssize_t cim_read(struct file *filp, char *buf, size_t size, loff_t *l)
+{
+ dprintk("user buf paddr = 0x%x\n",get_phy_addr(buf));
+ return -1;
+}
+
+static ssize_t cim_write(struct file *filp, const char *buf, size_t size, loff_t *l)
+{
+ return -1;
+}
+
+static unsigned int cim_get_preview_buf(int is_pbuf)
+{
+ unsigned int buffer;
+ unsigned long flags;
+ u32 tmp_addr;
+
+ if(unlikely(fresh_id == -1))
+ {
+ iprintk("w");
+ interruptible_sleep_on_timeout(&jz_cim->preview_wait_queue,10*HZ);
+ //cim_print_regs();
+ }
+
+ if(unlikely(jz_cim->preview_timeout_state != 1))
+ return (unsigned int)(~0);
+
+/******/spin_lock_irqsave(fresh_lock,flags);/*********************************************************/
+
+ tmp_addr=frame_desc[fresh_id].framebuf;
+ frame_desc[fresh_id].framebuf=frame_desc[SWAP_BUF+fresh_buf].framebuf;
+ frame_desc[SWAP_BUF+fresh_buf].framebuf=tmp_addr;
+ dma_cache_wback((unsigned long)(&frame_desc[fresh_id]), sizeof(struct cim_desc));
+
+ jz_cim->preview_timeout_state = 0;
+ fresh_id = -1;
+
+/******/spin_unlock_irqrestore(fresh_lock,flags);/*******************************************************/
+
+
+ if(likely(is_pbuf == 1))
+ buffer=(unsigned int)(frame_desc[SWAP_BUF+fresh_buf].framebuf);
+ else
+ buffer=(unsigned int)(phys_to_virt(frame_desc[SWAP_BUF+fresh_buf].framebuf)-buf_offsize_app_drv);
+
+ fresh_buf++;
+ if(fresh_buf >= GET_BUF)
+ fresh_buf =0;
+
+ //iprintk("(%d)",__cim_get_fid());
+ iprintk("(%x)transfer id %d\n",REG_CIM_FA,(REG_CIM_FA - jz_cim->preview_binfo.base_paddr)/jz_cim->ginfo.max_preview_size);
+ iprintk("(%x)return buffer id %d\n",buffer,(buffer-jz_cim->preview_binfo.base_paddr)/jz_cim->ginfo.max_preview_size);
+ return buffer;
+}
+
+static struct camera_sensor_desc *get_sensor_by_id(unsigned int id)
+{
+ struct camera_sensor_desc *si=NULL,*retval=NULL;
+ mutex_lock(&sensor_lock);
+ list_for_each_entry(si, &sensor_list, list)
+ {
+ if(si->sensor_id == id)
+ {
+ retval = si;
+ break;
+ }
+ }
+ mutex_unlock(&sensor_lock);
+
+ return retval;
+}
+
+static int cim_get_support_size(void __user *arg)
+{
+ if(cur_desc == NULL)
+ return -ENODEV;
+ return copy_to_user(arg,cur_desc->resolution_table,
+ (sizeof(struct resolution_info) * cur_desc->resolution_table_nr));
+}
+
+static void fill_info_by_desc(struct sensor_info *info,struct camera_sensor_desc *desc)
+{
+ strcpy(info->name,desc->name);
+ info->sensor_id = desc->sensor_id;
+ dprintk("GET SENSOR INFO (ID : %d NAME : %s )\n",info->sensor_id,info->name);
+ info->resolution_table_nr = desc->resolution_table_nr;
+
+ memcpy(&info->flags,&desc->flags,sizeof(struct mode_flags));
+
+ memcpy(&info->preview_parm,&desc->preview_parm,sizeof(struct resolution_info));
+ memcpy(&info->capture_parm,&desc->capture_parm,sizeof(struct resolution_info));
+
+ memcpy(&info->max_capture_parm,&desc->max_capture_parm,sizeof(struct resolution_info));
+ memcpy(&info->max_preview_parm,&desc->max_preview_parm,sizeof(struct resolution_info));
+}
+
+
+static int cim_get_sensor_info(void __user *arg,struct sensor_info *info)
+{
+ if(cur_desc != NULL)
+ {
+ fill_info_by_desc(info,cur_desc);
+ return copy_to_user(arg,info,sizeof(*info));
+ }
+
+ dprintk("CIM GET SENSOR INFO ERROR:CUR_DESC IS NULL\n");
+ return -ENODEV;
+}
+
+static int cim_enable_image_mode(int image_w,int image_h,int width,int height)
+{
+ int voffset,hoffset;
+
+ voffset = (((height - image_h) / 2) >> 1) << 1;
+ hoffset = (((width - image_w) / 2) >> 1) << 1;
+
+ __cim_set_line(image_h);
+ __cim_set_pixel(image_w);
+
+ __cim_set_v_offset(voffset);
+ __cim_set_h_offset(hoffset);
+
+ __cim_enable_size_func();
+ //REG_CIM_CTRL |= CIM_CTRL_WIN_EN;
+
+ dprintk("enable image mode (real size %d x %d) - %d x %d\n",width,height,image_w,image_h);
+ return 0;
+}
+
+
+static int cim_disable_image_mode(void)
+{
+ __cim_disable_size_func();
+ //REG_CIM_CTRL &= ~CIM_CTRL_WIN_EN;
+ dprintk("disable image mode\n");
+ return 0;
+}
+
+static int cim_set_preview_resolution(struct resolution_info param)
+{
+ int i, max_preview_index, framesize, wpf; /* words per frame */
+
+ dprintk("SET PREVIEW RESOULTION %d\tX\t%d\t%d\n",param.width,param.height,param.bpp);
+
+ if(cur_desc == NULL)
+ return -ENODEV;
+
+ if(param.bpp != 8 || param.bpp != 16 || param.bpp != 32 )
+ param.bpp = cur_desc->preview_parm.bpp;
+ if(param.format == (unsigned int)(-1))
+ param.format= cur_desc->preview_parm.format;
+
+ framesize = (param.width * param.height * param.bpp + 7) >> 3;
+ if (framesize > cur_desc->max_preview_size){
+ dprintk("ERROR! Preview size is too large!\n");
+ return -EINVAL;
+ }
+
+ cur_desc->preview_parm.width = param.width;
+ cur_desc->preview_parm.height = param.height;
+ cur_desc->preview_parm.bpp = param.bpp;
+
+ if(jz_cim->cim_started != TRUE || jz_cim->cim_transfer_started != 1)
+ return -1;
+
+ if(cur_desc->ops->sensor_set_resolution== NULL)
+ return -ENODEV;
+//---------------------------------------------------------------------------
+ for(max_preview_index=0;max_preview_index<cur_desc->resolution_table_nr;max_preview_index++)
+ {
+ if(cur_desc->resolution_table[max_preview_index].width == cur_desc->max_preview_parm.width
+ && cur_desc->resolution_table[max_preview_index].height == cur_desc->max_preview_parm.height)
+ break;
+ }
+
+ for(i=max_preview_index;i<cur_desc->resolution_table_nr;i++)
+ {
+
+ dprintk("request preview size: %d x %d\t\tscan preview size: %d x %d\n",
+ param.width,
+ param.height,
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height);
+ if(param.width == cur_desc->resolution_table[i].width && param.height == cur_desc->resolution_table[i].height)
+ {
+ dprintk("found preview size! now preview size is %d x %d\n",param.width,param.height);
+ break;
+ }
+ }
+
+ if(i >= cur_desc->resolution_table_nr)
+ {
+ dprintk("size not found! use image mode!\n");
+ for(i=cur_desc->resolution_table_nr-1;i>=max_preview_index;i--)
+ {
+ if(
+ cur_desc->resolution_table[i].width >= param.width
+ && cur_desc->resolution_table[i].height >= param.height)
+ break;
+ }
+
+ cim_enable_image_mode(
+ param.width,
+ param.height,
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height);
+
+ cur_desc->ops->sensor_set_resolution(
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height,
+ cur_desc->preview_parm.bpp,
+ cur_desc->preview_parm.format,
+ CAMERA_MODE_PREVIEW);
+
+ dprintk("PREVIEW SIZE:%d x %d\t\tPREVIEW IMAGE:%d x %d\n",
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height,
+ param.width,
+ param.height);
+ }
+ else
+ {
+ cim_disable_image_mode();
+ cur_desc->ops->sensor_set_resolution(
+ cur_desc->preview_parm.width,
+ cur_desc->preview_parm.height,
+ cur_desc->preview_parm.bpp,
+ cur_desc->preview_parm.format,
+ CAMERA_MODE_PREVIEW);
+ }
+//---------------------------------------------------------------------------
+ wpf = (framesize +3) >> 2 ;
+
+ for (i = 0; i < SWAP_NR - 1; i++) {
+ frame_desc[i].dmacmd &= ~CIM_CMD_LEN_MASK;
+ frame_desc[i].dmacmd |= wpf;
+ dma_cache_wback((unsigned long)(&frame_desc[i]), sizeof(struct cim_desc));
+ }
+ return 0;
+}
+
+static int cim_set_capture_resoultion(struct resolution_info param,int state)
+{
+ int i,framesize, wpf,max_capture_index; // words per frame
+
+ dprintk("SET CAPTURE RESOULTION %d\tX\t%d\t%d\n",param.width,param.height,param.bpp);
+
+ if(cur_desc == NULL)
+ return -ENODEV;
+
+ if(param.bpp != 8 || param.bpp != 16 || param.bpp != 32 )
+ param.bpp = cur_desc->capture_parm.bpp;
+ if(param.format == (unsigned int)(-1))
+ param.format= cur_desc->capture_parm.format;
+
+ framesize = (param.width * param.height * param.bpp + 7) >> 3;
+ if (framesize > cur_desc->max_capture_size){
+ dprintk("ERROR! Capture size is too large!\n");
+ return -EINVAL;
+ }
+
+
+ cur_desc->capture_parm.width = param.width;
+ cur_desc->capture_parm.height = param.height;
+ cur_desc->capture_parm.bpp = param.bpp;
+
+ if(state == 0)
+ return 0;
+
+ if(jz_cim->cim_started != TRUE || jz_cim->cim_transfer_started != 1)
+ return -1;
+
+ if(cur_desc->ops->sensor_set_resolution== NULL)
+ return -ENODEV;
+//---------------------------------------------------------------------------------------------
+
+ for(max_capture_index=0;max_capture_index<cur_desc->resolution_table_nr;max_capture_index++)
+ {
+ if(cur_desc->resolution_table[max_capture_index].width == cur_desc->max_capture_parm.width
+ && cur_desc->resolution_table[max_capture_index].height == cur_desc->max_capture_parm.height)
+ break;
+ }
+
+ for(i=max_capture_index;i<cur_desc->resolution_table_nr;i++)
+ {
+
+ dprintk("request capture size: %d x %d\t\tscan capture size: %d x %d\n",
+ param.width,
+ param.height,
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height);
+ if(param.width == cur_desc->resolution_table[i].width && param.height == cur_desc->resolution_table[i].height)
+ {
+ dprintk("found capture size! now capture size is %d x %d\n",param.width,param.height);
+ break;
+ }
+ }
+
+ //if(jz_cim->cim_started == TRUE)
+ //if(jz_cim->cim_transfer_started == 1)
+ if(i >= cur_desc->resolution_table_nr)
+ {
+ dprintk("size not found! use image mode!\n");
+ for(i=cur_desc->resolution_table_nr-1;i>=max_capture_index;i--)
+ {
+ if(cur_desc->resolution_table[i].width > param.width && cur_desc->resolution_table[i].height > param.height)
+ break;
+ }
+
+ cim_enable_image_mode(
+ param.width,
+ param.height,
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height);
+
+ cur_desc->ops->sensor_set_resolution(
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height,
+ cur_desc->capture_parm.bpp,
+ cur_desc->capture_parm.format,
+ CAMERA_MODE_CAPTURE);
+
+ dprintk("CAPTURE SIZE:%d x %d\t\tCAPTURE IMAGE:%d x %d\n",
+ cur_desc->resolution_table[i].width,
+ cur_desc->resolution_table[i].height,
+ param.width,
+ param.height);
+ }
+ else
+ {
+ cim_disable_image_mode();
+ cur_desc->ops->sensor_set_resolution(
+ cur_desc->capture_parm.width,
+ cur_desc->capture_parm.height,
+ cur_desc->capture_parm.bpp,
+ cur_desc->capture_parm.format,
+ CAMERA_MODE_CAPTURE);
+ }
+
+ //---------------------------------------------------------------------------------------------
+ wpf = (framesize + 3) >> 2 ;
+ capture_desc.dmacmd &= ~CIM_CMD_LEN_MASK;
+ capture_desc.dmacmd |= wpf;
+ dma_cache_wback((unsigned long)(&capture_desc), sizeof(struct cim_desc));
+
+ dprintk("SET CAPTURE RESOULTION %d\tX\t%d\t%d\n -- OK!",param.width,param.height,param.bpp);
+ return 0;
+}
+
+static int cim_set_function(int function,void *cookie)
+{
+ if(cur_desc == NULL)
+ return -ENODEV;
+ if(cur_desc->ops->sensor_set_function == NULL)
+ return -ENODEV;
+
+ return cur_desc->ops->sensor_set_function(function,cookie);
+}
+
+
+static int cim_set_output_format(pixel_format_flag_t flag,int arg)
+{
+ return 0;//disabled interface
+
+ dprintk("cim_set_output_format\n");
+ if(cur_desc == NULL)
+ return -ENODEV;
+// if(cur_desc->ops->camera_set_output_format == NULL)
+// return -ENODEV;
+
+ cur_desc->parms.pixel_format_flag = flag;
+ cur_desc->parms.pixel_format_flag_arg = arg;
+
+ if(jz_cim->cim_transfer_started != 1)
+ return 0;
+
+ if(flag == PIXEL_FORMAT_YUV422I)
+ __cim_input_data_format_select_YUV422();
+
+ if(flag == PIXEL_FORMAT_RGB565)
+ ;// __cim_input_data_format_select_RGB();
+
+// cur_desc->ops->camera_set_output_format(flag,arg);
+ return 0;
+}
+
+static int cim_set_param(struct camera_param *cparam)
+{
+ if(cur_desc == NULL)
+ return -ENODEV;
+ if(cur_desc->ops->sensor_set_parameter == NULL)
+ return -ENODEV;
+
+ if(jz_cim->cim_transfer_started == 1 && !cur_desc->no_dma)
+ {
+ REG_CIM_STATE &= ~CIM_STATE_VDD;
+ __cim_disable();
+ }
+
+ switch (cparam->cmd)
+ {
+ case CPCMD_SET_PREVIEW_RESOLUTION:
+ cim_set_preview_resolution(cparam->preview_param);
+ break;
+ case CPCMD_SET_CAPTURE_RESOLUTION:
+ cim_set_capture_resoultion(cparam->capture_param,0);
+ break;
+ case CPCMD_SET_OUTPUT_FORMAT:
+ cim_set_output_format(cparam->flags.pixel_format_flag,cparam->mode_arg);
+ break;
+ case CPCMD_SET_BALANCE:
+ cur_desc->parms.balance_flag = cparam->flags.balance_flag;
+ cur_desc->parms.balance_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.balance_flag,
+ cur_desc->parms.balance_flag_arg);
+ break;
+ case CPCMD_SET_EFFECT:
+ cur_desc->parms.effect_flag = cparam->flags.effect_flag;
+ cur_desc->parms.effect_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.effect_flag,
+ cur_desc->parms.effect_flag_arg);
+ break;
+ case CPCMD_SET_ANTIBANDING:
+ cur_desc->parms.antibanding_flag = cparam->flags.antibanding_flag;
+ cur_desc->parms.antibanding_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.antibanding_flag,
+ cur_desc->parms.antibanding_flag_arg);
+ break;
+ case CPCMD_SET_FLASH_MODE:
+ cur_desc->parms.flash_mode_flag = cparam->flags.flash_mode_flag;
+ cur_desc->parms.flash_mode_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.flash_mode_flag,
+ cur_desc->parms.flash_mode_flag_arg);
+ break;
+ case CPCMD_SET_SCENE_MODE:
+ cur_desc->parms.scene_mode_flag = cparam->flags.scene_mode_flag;
+ cur_desc->parms.scene_mode_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.scene_mode_flag,
+ cur_desc->parms.scene_mode_flag_arg);
+ break;
+ case CPCMD_SET_FOCUS_MODE:
+ cur_desc->parms.focus_mode_flag = cparam->flags.focus_mode_flag;
+ cur_desc->parms.focus_mode_flag_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ cur_desc->parms.focus_mode_flag,
+ cur_desc->parms.focus_mode_flag_arg);
+ break;
+ case CPCMD_SET_PREVIEW_FPS:
+ cur_desc->parms.preview_fps_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ -1,
+ cur_desc->parms.preview_fps_arg);
+ break;
+ case CPCMD_SET_NIGHTSHOT_MODE:
+ cur_desc->parms.nightshot_mode_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ -1,
+ cur_desc->parms.nightshot_mode_arg);
+ break;
+ case CPCMD_SET_LUMA_ADAPTATION:
+ cur_desc->parms.luma_adaptation_arg = cparam->mode_arg;
+ if(jz_cim->cim_transfer_started == 1)
+ cur_desc->ops->sensor_set_parameter(
+ cparam->cmd,
+ -1,
+ cur_desc->parms.luma_adaptation_arg);
+ break;
+
+ default:
+ dprintk("Not supported command: 0x%x\n", cparam->cmd);
+ break;
+ }
+
+ if(jz_cim->cim_transfer_started == 1 && !cur_desc->no_dma)
+ {
+ __cim_clear_state(); // clear state register
+ __cim_reset_rxfifo(); // resetting rxfifo
+ __cim_unreset_rxfifo();
+ __cim_enable();
+ }
+
+ return 0;
+}
+
+
+static unsigned int cim_get_global_info(void __user *argp)
+{
+ return copy_to_user(argp,&(jz_cim->ginfo),sizeof(struct global_info));
+}
+
+
+static int cim_select_sensor(unsigned int sensor_id)
+{
+ struct camera_sensor_desc *tmp;
+ tmp = get_sensor_by_id(sensor_id);
+
+ if(tmp == NULL)
+ return -EFAULT;
+
+ cim_stop_preview();
+ cur_desc->ops->sensor_set_power(1);
+ cur_desc = tmp;
+
+ if(jz_cim->cim_started == TRUE)
+ cur_desc->ops->sensor_set_power(0);
+
+ return 0;
+}
+
+static int cim_set_buffer(void __user *argp, struct camera_buffer_info *binfo)
+{
+ unsigned int mb;
+ struct camera_buffer_info tmp;
+
+ if (copy_from_user(&tmp, argp, sizeof(struct camera_buffer_info)))
+ return -EFAULT;
+
+ if (tmp.buffer_size < binfo->buffer_size)
+ {
+ dprintk("MEM IS TOO SMALL!\n");
+ return -ENOMEM;
+ }
+ memcpy(binfo, &tmp, sizeof(struct camera_buffer_info));
+
+ mb = (unsigned int)jz_cim->mem_base;
+ if ((jz_cim->preview_binfo.base_vaddr != mb)
+ && (jz_cim->capture_binfo.base_vaddr != (mb + jz_cim->preview_binfo.buffer_size)))
+ {
+ cim_framebuffer_destroy();
+ dprintk("CIM FRAME BUFFER DESTORY\n");
+ }
+
+ return 0;
+}
+
+/**************************
+ * IOCTL Handlers *
+ **************************/
+static int cim_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int retval;
+ void __user *argp = (void __user *)arg;
+ switch (cmd)
+ {
+ case IOCTL_CIM_START:
+ {
+ dprintk("IOCTL_START_CIM\n");
+ cim_start();
+ return 0;
+ }
+ case IOCTL_CIM_STOP:
+ {
+ dprintk("IOCTL_STOP_CIM\n");
+ cim_stop();
+ return 0;
+ }
+ case IOCTL_CIM_START_PREVIEW:
+ {
+ dprintk("IOCTL_CIM_START_PREVIEW\n");
+ cim_start_preview();
+ return 0;
+ }
+ case IOCTL_CIM_STOP_PREVIEW:
+ {
+ dprintk("IOCTL_CIM_STOP_PREVIEW\n");
+ cim_stop_preview();
+ return 0;
+ }
+ case IOCTL_CIM_SELECT_SENSOR:
+ {
+ return cim_select_sensor(arg);
+ }
+ case IOCTL_CIM_GET_PREVIEW_PARAM:
+ {
+ return copy_to_user(argp, &cur_desc->preview_parm, sizeof(struct resolution_info)) ? -EFAULT : 0;
+ }
+ case IOCTL_CIM_AF_INIT:
+ {
+ if(jz_cim->cim_started != TRUE || jz_cim->cim_transfer_started != 1)
+ return -1;
+ __cim_disable();
+ __cim_reset_rxfifo();
+ __cim_unreset_rxfifo();
+ __cim_clear_state();
+
+ retval = cim_set_function(4,(void*)arg);
+
+ __cim_enable();
+
+ return retval;
+ }
+ case IOCTL_CIM_GET_CAPTURE_PARAM:
+ {
+ return copy_to_user(argp, &cur_desc->capture_parm, sizeof(struct resolution_info)) ? -EFAULT : 0;
+ }
+ case IOCTL_CIM_GET_CAPTURE_BUF_INFO:
+ {
+ return copy_to_user(argp, &jz_cim->capture_binfo, sizeof(struct camera_buffer_info)) ? -EFAULT : 0;
+ }
+ case IOCTL_CIM_GET_PREVIEW_BUF_INFO:
+ {
+ return copy_to_user(argp, &jz_cim->preview_binfo, sizeof(struct camera_buffer_info)) ? -EFAULT : 0;
+ }
+ case IOCTL_CIM_SET_PREVIEW_MEM:
+ {
+ dprintk("IOCTL_SET_PREVIEW_MEM\n");
+ return cim_set_buffer(argp,&jz_cim->preview_binfo);
+ }
+ case IOCTL_CIM_SET_CAPTURE_MEM:
+ {
+ dprintk("IOCTL_SET_CAPTURE_MEM\n");
+ return cim_set_buffer(argp,&jz_cim->capture_binfo);
+ }
+ case IOCTL_CIM_GET_PREVIEW_OFFSET:
+ {
+ unsigned int offset;
+
+ if(cur_desc->no_dma)
+ {
+ if(cur_desc->ops->camera_fill_buffer != NULL)
+ cur_desc->ops->camera_fill_buffer(
+ jz_cim->preview_binfo.base_vaddr,
+ cur_desc
+ );//only for fake camera test
+ offset = 0;
+ }
+ else
+ {
+ offset = cim_get_preview_buf(1);
+
+ if(offset == (unsigned int)(~0))
+ return -1;
+ offset -= jz_cim->preview_binfo.base_paddr;
+ }
+
+ return copy_to_user(argp, &offset, sizeof(offset)) ? -EFAULT : 0;
+ }
+ case IOCTL_CIM_TAKE_SNAPSHOT:
+ {
+ dprintk("IOCTL_CIM_TAKE_SNAPSHOT\n");
+ return cim_snapshot();
+ }
+ case IOCTL_CIM_GET_GLOBAL_INFO:
+ {
+ dprintk("IOCTL_GET_GLOBAL_INFO\n");
+ return cim_get_global_info(argp);
+ }
+ case IOCTL_CIM_GET_SUPPORT_SIZE:
+ {
+ dprintk("IOCTL_GET_SUPPORT_SIZE\n");
+ return cim_get_support_size(argp);
+ }
+ case IOCTL_CIM_GET_SENSOR_INFO:
+ {
+ struct sensor_info info;
+ dprintk("IOCTL_GET_SENSOR_INFO\n");
+ return cim_get_sensor_info(argp,&info);
+
+ }
+ case IOCTL_CIM_SET_PARAM:
+ {
+ struct camera_param param;
+ if (copy_from_user(&param, (void *)arg, sizeof(param)))
+ return -EFAULT;
+
+ return cim_set_param(&param);
+ }
+ case IOCTL_CIM_STOP_FOCUS:
+ {
+ return cim_set_function(5,NULL);
+ }
+ case IOCTL_CIM_DO_FOCUS:
+ {
+ return cim_set_function(3,NULL);
+ }
+ default:
+ dprintk("Not supported command: 0x%x\n", cmd);
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+//Use mmap /dev/fb can only get a non-cacheable Virtual Address.
+static int cim_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ unsigned long start;
+ unsigned long off;
+ u32 len;
+
+ dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ if( jz_cim->mem_base== 0 )
+ {
+ if (cim_fb_alloc())
+ {
+ dprintk("No mem: Alloc memory for cim DMA\n");
+ return -ENOMEM;
+ }
+ }
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+
+ // frame buffer memory
+ start = virt_to_phys(jz_cim->mem_base);
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + ((unsigned long)jz_cim->mem_size));
+
+ start &= PAGE_MASK;
+
+ if ((vma->vm_end - vma->vm_start + off) > len) {
+ dprintk("Error: vma is larger than memory length\n");
+ return -EINVAL;
+ }
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); // Uncacheable
+#if defined(CONFIG_MIPS32)
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+#endif
+
+ if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+
+ buf_offsize_app_drv =(unsigned int )(jz_cim->mem_base)-(unsigned int )(vma->vm_start);
+
+#if 1
+ dprintk("vma->vm_start: 0x%x\n",vma->vm_start);
+ dprintk("vma->vm_end: 0x%x\n",vma->vm_end);
+ dprintk("vma->vm_pgoff: 0x%x\n",vma->vm_pgoff);
+ dprintk("jz_cim->mem_base(V): 0x%x\n",jz_cim->mem_base);
+ dprintk("jz_cim->mem_base(P): 0x%x\n",virt_to_phys(jz_cim->mem_base));
+ dprintk("jz_cim->mem_size: %dbytes\n",jz_cim->mem_size);
+ dprintk("buf_offsize_app_drv = jz_cim->mem_base-vma->vm_start\n");
+ dprintk("buf_offsize_app_drv = 0x%x\n",buf_offsize_app_drv);
+ dprintk("get_phy_addr test addr = 0x%x\n",get_phy_addr(vma->vm_start));
+#endif
+
+ return 0;
+}
+
+static struct miscdevice cim_dev = {
+ CIM_MINOR,
+ "cim",
+ &cim_fops
+};
+
+
+static int __init cim_init(void)
+{
+ int ret;
+
+ __gpio_as_cim();
+
+ jz_cim = kzalloc(GFP_KERNEL,sizeof(*jz_cim));
+ if(jz_cim == NULL)
+ {
+ dprintk("no memory!\n");
+ return -ENOMEM;
+ }
+
+ cim_power_on();
+
+ cim_scan_sensor();
+
+ cim_power_off();
+
+ sensors_make_default();
+
+ if(cur_desc == NULL)
+ {
+ dprintk("no sensor found!\nCIM exit!");
+ }
+
+ init_waitqueue_head(&jz_cim->capture_wait_queue);
+ init_waitqueue_head(&jz_cim->preview_wait_queue);
+ cim_fb_alloc();
+
+ if ((ret = request_irq(IRQ_CIM, cim_irq_handler, IRQF_DISABLED, CIM_NAME, jz_cim))) {
+ dprintk(KERN_ERR "request_irq return error, ret=%d\n", ret);
+ dprintk(KERN_ERR "CIM could not get IRQ\n");
+ return ret;
+ }
+
+ ret = misc_register(&cim_dev);
+ if (ret < 0) {
+ return ret;
+ }
+
+ printk("Virtual Driver of JZ CIM registered\n");
+ return 0;
+}
+
+static void __exit cim_exit(void)
+{
+ cim_framebuffer_destroy();
+ kfree(jz_cim);
+ misc_deregister(&cim_dev);
+}
+
+
+late_initcall(cim_init);// CIM driver should not be inited before PMU driver inited.
+module_exit(cim_exit);
diff --git a/drivers/misc/jz_cim/jz_cim_core.h b/drivers/misc/jz_cim/jz_cim_core.h
new file mode 100644
index 00000000000..a6e0d46f585
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_cim_core.h
@@ -0,0 +1,346 @@
+/*
+ * linux/drivers/misc/jz_cim.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __JZ_CIM_H__
+#define __JZ_CIM_H__
+
+#include <linux/i2c.h>
+//jz_cim_board_xxxx.c
+extern void cim_power_on(void);
+extern void cim_power_off(void);
+
+/*
+ * IOCTL_XXX commands
+ */
+#define IOCTL_CIM_START 0xf01 // start preview
+#define IOCTL_CIM_STOP 0xf02 // stop preview
+
+#define IOCTL_CIM_START_PREVIEW 0xf03
+#define IOCTL_CIM_STOP_PREVIEW 0xf04
+
+#define IOCTL_CIM_GET_PREVIEW_BUF_INFO 0xf05
+#define IOCTL_CIM_GET_CAPTURE_BUF_INFO 0xf06
+
+#define IOCTL_CIM_GET_PREVIEW_OFFSET 0xf07
+
+#define IOCTL_CIM_GET_GLOBAL_INFO 0xf08
+#define IOCTL_CIM_GET_SENSOR_INFO 0xf09
+
+#define IOCTL_CIM_GET_CAPTURE_PARAM 0xf0a
+#define IOCTL_CIM_GET_PREVIEW_PARAM 0xf0b // get preview size and format
+
+#define IOCTL_CIM_GET_SUPPORT_SIZE 0xf0c
+
+#define IOCTL_CIM_SET_PARAM 0xf0d
+#define IOCTL_CIM_SET_PREVIEW_MEM 0xf0e // alloc mem for buffers by app
+#define IOCTL_CIM_SET_CAPTURE_MEM 0xf0f // alloc mem for buffers by app
+
+
+#define IOCTL_CIM_TAKE_SNAPSHOT 0xf10
+#define IOCTL_CIM_SELECT_SENSOR 0xf11
+#define IOCTL_CIM_DO_FOCUS 0xf12
+#define IOCTL_CIM_AF_INIT 0xf13
+#define IOCTL_CIM_STOP_FOCUS 0xf14
+
+//-----------------------------------------------------------------------------------------------------------------------
+//camera param cmd
+#define CPCMD_SET_PREVIEW_RESOLUTION 0x01
+#define CPCMD_SET_CAPTURE_RESOLUTION 0x02
+#define CPCMD_SET_OUTPUT_FORMAT 0x03
+
+
+#define CPCMD_SET_BALANCE 0x04
+#define CPCMD_SET_EFFECT 0x05
+#define CPCMD_SET_ANTIBANDING 0x06
+#define CPCMD_SET_FLASH_MODE 0x07
+#define CPCMD_SET_SCENE_MODE 0x08
+#define CPCMD_SET_PIXEL_FORMAT 0x09
+#define CPCMD_SET_FOCUS_MODE 0x0a
+#define CPCMD_SET_PREVIEW_FPS 0x0b
+#define CPCMD_SET_NIGHTSHOT_MODE 0x0c
+#define CPCMD_SET_LUMA_ADAPTATION 0x0d
+//-----------------------------------------------------------------------------------------------------------------------
+
+
+// Values for white balance settings.
+#define WHITE_BALANCE_AUTO 0x1<<0
+#define WHITE_BALANCE_INCANDESCENT 0x1<<1
+#define WHITE_BALANCE_FLUORESCENT 0x1<<2
+#define WHITE_BALANCE_WARM_FLUORESCENT 0x1<<3
+#define WHITE_BALANCE_DAYLIGHT 0x1<<4
+#define WHITE_BALANCE_CLOUDY_DAYLIGHT 0x1<<5
+#define WHITE_BALANCE_TWILIGHT 0x1<<6
+#define WHITE_BALANCE_SHADE 0x1<<7
+
+// Values for effect settings.
+#define EFFECT_NONE 0x1<<0
+#define EFFECT_MONO 0x1<<1
+#define EFFECT_NEGATIVE 0x1<<2
+#define EFFECT_SOLARIZE 0x1<<3
+#define EFFECT_SEPIA 0x1<<4
+#define EFFECT_POSTERIZE 0x1<<5
+#define EFFECT_WHITEBOARD 0x1<<6
+#define EFFECT_BLACKBOARD 0x1<<7
+#define EFFECT_AQUA 0x1<<8
+#define EFFECT_PASTEL 0x1<<9
+#define EFFECT_MOSAIC 0x1<<10
+#define EFFECT_RESIZE 0x1<<11
+
+// Values for antibanding settings.
+#define ANTIBANDING_AUTO 0x1<<0
+#define ANTIBANDING_50HZ 0x1<<1
+#define ANTIBANDING_60HZ 0x1<<2
+#define ANTIBANDING_OFF 0x1<<3
+
+// Values for flash mode settings.
+#define FLASH_MODE_OFF 0x1<<0
+#define FLASH_MODE_AUTO 0x1<<1
+#define FLASH_MODE_ON 0x1<<2
+#define FLASH_MODE_RED_EYE 0x1<<3
+#define FLASH_MODE_TORCH 0x1<<4
+
+// Values for scene mode settings.
+#define SCENE_MODE_AUTO 0x1<<0
+#define SCENE_MODE_ACTION 0x1<<1
+#define SCENE_MODE_PORTRAIT 0x1<<2
+#define SCENE_MODE_LANDSCAPE 0x1<<3
+#define SCENE_MODE_NIGHT 0x1<<4
+#define SCENE_MODE_NIGHT_PORTRAIT 0x1<<5
+#define SCENE_MODE_THEATRE 0x1<<6
+#define SCENE_MODE_BEACH 0x1<<7
+#define SCENE_MODE_SNOW 0x1<<8
+#define SCENE_MODE_SUNSET 0x1<<9
+#define SCENE_MODE_STEADYPHOTO 0x1<<10
+#define SCENE_MODE_FIREWORKS 0x1<<11
+#define SCENE_MODE_SPORTS 0x1<<12
+#define SCENE_MODE_PARTY 0x1<<13
+#define SCENE_MODE_CANDLELIGHT 0x1<<14
+
+
+//Formats for setPreviewFormat and setPictureFormat.
+#define PIXEL_FORMAT_YUV422SP 0x1<<0
+#define PIXEL_FORMAT_YUV420SP 0x1<<1
+#define PIXEL_FORMAT_YUV422I 0x1<<2
+#define PIXEL_FORMAT_RGB565 0x1<<3
+#define PIXEL_FORMAT_JPEG 0x1<<4
+
+// Values for focus mode settings.
+#define FOCUS_MODE_AUTO 0x1<<0
+#define FOCUS_MODE_INFINITY 0x1<<1
+#define FOCUS_MODE_MACRO 0x1<<2
+#define FOCUS_MODE_FIXED 0x1<<3
+
+
+//-----------------------------------------------------------------------------------------------------------------------
+typedef unsigned int balance_flag_t;
+typedef unsigned int effect_flag_t;
+typedef unsigned int antibanding_flag_t;
+typedef unsigned int flash_mode_flag_t;
+typedef unsigned int scene_mode_flag_t;
+typedef unsigned int pixel_format_flag_t;
+typedef unsigned int focus_mode_flag_t;
+
+struct resolution_info
+{
+ unsigned int width;
+ unsigned int height;
+ unsigned int bpp;
+ pixel_format_flag_t format;
+};
+
+
+struct mode_flags
+{
+
+ balance_flag_t balance_flag;
+ effect_flag_t effect_flag;
+ antibanding_flag_t antibanding_flag;
+ flash_mode_flag_t flash_mode_flag;
+ scene_mode_flag_t scene_mode_flag;
+ pixel_format_flag_t pixel_format_flag;
+ focus_mode_flag_t focus_mode_flag;
+};
+
+
+struct camera_buffer_info
+{
+ unsigned int base_vaddr;
+ unsigned int base_paddr;
+ unsigned int buffer_size;
+};
+
+struct camera_param
+{
+ unsigned int cmd;
+ struct resolution_info capture_param;
+ struct resolution_info preview_param;
+
+ struct mode_flags flags;
+ int mode_arg;
+};
+
+
+struct global_info
+{
+ unsigned int sensor_count;
+ unsigned int mmap_size;
+ unsigned int max_preview_size;
+ unsigned int preview_buf_nr;
+ unsigned int max_capture_size;
+};
+
+struct sensor_info
+{
+ unsigned int sensor_id;
+ char name[32];
+
+ unsigned int resolution_table_nr;
+ struct mode_flags flags;
+
+
+ struct resolution_info max_preview_parm;
+ struct resolution_info max_capture_parm;
+
+ struct resolution_info preview_parm;
+ struct resolution_info capture_parm;
+};
+
+struct sensor_af_arg
+{
+ int len;
+ unsigned char *buf;
+};
+
+//-----------------------------------------------------------------------
+
+struct camera_parms
+{
+ balance_flag_t balance_flag;
+ effect_flag_t effect_flag;
+ antibanding_flag_t antibanding_flag;
+ flash_mode_flag_t flash_mode_flag;
+ scene_mode_flag_t scene_mode_flag;
+ pixel_format_flag_t pixel_format_flag;
+ focus_mode_flag_t focus_mode_flag;
+
+ int balance_flag_arg;
+ int effect_flag_arg;
+ int antibanding_flag_arg;
+ int flash_mode_flag_arg;
+ int scene_mode_flag_arg;
+ int pixel_format_flag_arg;
+ int focus_mode_flag_arg;
+
+ int preview_fps_arg;
+ int nightshot_mode_arg;
+ int luma_adaptation_arg;
+};
+
+typedef struct{
+ unsigned int cfg;
+ unsigned int ctrl;
+ unsigned int size;
+ unsigned int offs;
+} cim_config_t;
+
+typedef enum{CAMERA_MODE_CAPTURE,CAMERA_MODE_PREVIEW} camera_mode_t;
+
+struct camera_sensor_ops
+{
+ /*
+ *
+ */
+ int (*sensor_init)(void);
+
+ /* sensor_set_function use for init preview or capture.
+ * there may be some difference between preview and capture.
+ * so we divided it into two sequences.
+ * param: function indicated which function
+ * 0: preview
+ * 1: capture
+ * 2: recording
+ * 3: do focus
+ * 4: af init
+ * 5: stop focus
+ */
+ int (*sensor_set_function)(int function,void *cookie);
+
+ /*
+ *
+ */
+ int (*sensor_set_resolution)(int width,int height,int bpp,pixel_format_flag_t fmt,camera_mode_t mode);
+
+ /*
+ *
+ */
+ int (*sensor_set_parameter)(int cmd, int mode, int arg);
+
+
+ /* sensor_set_power use for change sensor power state
+ * state indicate which state is requested
+ * 0: power up
+ * 1: hardware power down
+ * 2: software power down
+ */
+ int (*sensor_set_power)(int state);
+
+
+ /* camera_sensor_probe use for probe weather the sensor present or not
+ * return 0 means success else means fail
+ */
+ int (*camera_sensor_probe)(void);
+
+ /* camera_fill_buffer only for fake sensor test
+ */
+ int (*camera_fill_buffer)(unsigned int addr,void *desc);
+};
+
+struct sensor_cfg_info
+{
+ __u32 configure_register;
+};
+
+struct camera_sensor_desc
+{
+ unsigned int sensor_id;
+ struct list_head list;
+ char name[32];
+ struct i2c_client *client;
+
+ unsigned int camera_clock;
+ unsigned int wait_frames;
+ int no_dma;
+
+ struct resolution_info *resolution_table;
+ unsigned int resolution_table_nr;
+
+ struct mode_flags flags;
+
+ struct resolution_info max_preview_parm;
+ struct resolution_info max_capture_parm;
+
+ struct resolution_info preview_parm;
+ struct resolution_info capture_parm;
+ struct camera_parms parms;
+
+ struct sensor_cfg_info cfg_info;
+
+ unsigned int max_preview_size;
+ unsigned int max_capture_size;
+
+ struct camera_sensor_ops *ops;
+};
+
+
+int camera_sensor_register(struct camera_sensor_desc *desc);
+
+#endif // __JZ_CIM_H__
+
diff --git a/drivers/misc/jz_cim/jz_sensor.c b/drivers/misc/jz_cim/jz_sensor.c
new file mode 100644
index 00000000000..507d2586cc9
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_sensor.c
@@ -0,0 +1,180 @@
+/*
+ * linux/drivers/misc/jz_sensor.c
+ *
+ * Virtual device driver with tricky appoach to manage TCSM
+ *
+ * Copyright (C) 2006 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include "jz_sensor.h"
+
+
+static inline int sensor_i2c_master_recv(struct i2c_client *client, char *buf ,int count);
+static inline int sensor_i2c_master_send(struct i2c_client *client,const char *buf ,int count);
+
+void sensor_set_i2c_speed(struct i2c_client *client,unsigned long speed)
+{
+#if defined(CONFIG_SOC_JZ4760)
+ i2c_jz_setclk(client,speed);
+#endif
+ //printk("set sensor i2c write read speed = %d hz\n",speed);
+}
+
+int sensor_write_reg(struct i2c_client *client,unsigned char reg, unsigned char val)
+{
+ unsigned char msg[2];
+ int ret;
+
+ memcpy(&msg[0], &reg, 1);
+ memcpy(&msg[1], &val, 1);
+
+ ret = sensor_i2c_master_send(client, msg, 2);
+
+ if (ret < 0)
+ {
+ printk("RET<0\n");
+ return ret;
+ }
+ if (ret < 2)
+ {
+ printk("RET<2\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+unsigned char sensor_read_reg(struct i2c_client *client,unsigned char reg)
+{
+ int ret;
+ unsigned char retval;
+
+ ret = sensor_i2c_master_send(client,&reg,1);
+
+ if (ret < 0)
+ return ret;
+ if (ret != 1)
+ return -EIO;
+
+ ret = sensor_i2c_master_recv(client, &retval, 1);
+ if (ret < 0) {
+ printk("%s: ret < 0\n", __FUNCTION__);
+ return ret;
+ }
+ if (ret != 1) {
+ printk("%s: ret != 1\n", __FUNCTION__);
+ return -EIO;
+ }
+ return retval;
+}
+
+
+int sensor_write_reg16(struct i2c_client *client,unsigned short reg, unsigned char val)
+{
+ unsigned char msg[3],tmp;
+ int ret;
+
+ memcpy(&msg[0], &reg, 2);
+ memcpy(&msg[2], &val, 1);
+
+ tmp=msg[0];
+ msg[0]=msg[1];
+ msg[1]=tmp;
+
+ ret = sensor_i2c_master_send(client, msg, 3);
+ if (ret < 0)
+ {
+ printk("RET < 0\n");
+ return ret;
+ }
+ if (ret < 3)
+ {
+ printk("RET<3\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+unsigned char sensor_read_reg16(struct i2c_client *client,unsigned short reg)
+{
+ unsigned char retval;
+ unsigned char msg[2],tmp;
+ int ret;
+
+ memcpy(&msg[0], &reg, 2);
+
+ tmp=msg[0];
+ msg[0]=msg[1];
+ msg[1]=tmp;
+
+
+ ret = sensor_i2c_master_send(client,msg,2);
+
+ if (ret < 0) {
+ printk("%s: ret < 0\n", __FUNCTION__);
+ return ret;
+ }
+
+ if (ret != 2) {
+ printk("%s: ret != 2\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ ret = sensor_i2c_master_recv(client, &retval, 1);
+ if (ret < 0) {
+ printk("%s: ret < 0\n", __FUNCTION__);
+ return ret;
+ }
+ if (ret != 1) {
+ printk("%s: ret != 1\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ //printk("read value = %x\n",(unsigned int)retval);
+ return retval;
+}
+
+static inline int sensor_i2c_master_send(struct i2c_client *client,const char *buf ,int count)
+{
+ int ret;
+ struct i2c_adapter *adap=client->adapter;
+ struct i2c_msg msg;
+
+ msg.addr = client->addr;
+ msg.flags = client->flags & I2C_M_TEN;
+ msg.len = count;
+ msg.buf = (char *)buf;
+ ret = i2c_transfer(adap, &msg, 1);
+
+ /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+ transmitted, else error code. */
+ return (ret == 1) ? count : ret;
+}
+
+static inline int sensor_i2c_master_recv(struct i2c_client *client, char *buf ,int count)
+{
+ struct i2c_adapter *adap=client->adapter;
+ struct i2c_msg msg;
+ int ret;
+
+ msg.addr = client->addr;
+ msg.flags = client->flags & I2C_M_TEN;
+ msg.flags |= I2C_M_RD;
+ msg.len = count;
+ msg.buf = buf;
+ ret = i2c_transfer(adap, &msg, 1);
+
+ /* If everything went ok (i.e. 1 msg transmitted), return #bytes
+ transmitted, else error code. */
+ return (ret == 1) ? count : ret;
+}
+
+
diff --git a/drivers/misc/jz_cim/jz_sensor.h b/drivers/misc/jz_cim/jz_sensor.h
new file mode 100644
index 00000000000..c62c386f7e5
--- /dev/null
+++ b/drivers/misc/jz_cim/jz_sensor.h
@@ -0,0 +1,23 @@
+/*
+ * linux/drivers/misc/jz_sensor.h -- Ingenic CIM driver
+ *
+ * Copyright (C) 2005-2010, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#ifndef __JZ_SENSOR_H__
+#define __JZ_SENSOR_H__
+
+#include<linux/i2c.h>
+
+extern void sensor_set_i2c_speed(struct i2c_client *client,unsigned long speed);
+extern int sensor_write_reg(struct i2c_client *client,unsigned char reg, unsigned char val);
+extern int sensor_write_reg16(struct i2c_client *client,unsigned short reg, unsigned char val);
+extern unsigned char sensor_read_reg(struct i2c_client *client,unsigned char reg);
+extern unsigned char sensor_read_reg16(struct i2c_client *client,unsigned short reg);
+
+#endif
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 15f1c1feccb..75d090cf88f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -251,7 +251,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.mrq.cmd = &brq.cmd;
brq.mrq.data = &brq.data;
-#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0
+#if defined( CONFIG_JZ_BOOT_FROM_MSC0)
brq.cmd.arg = blk_rq_pos(req) + 16384;
#else
brq.cmd.arg = blk_rq_pos(req);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 35199e4fd8d..1e19f986d7d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -141,7 +141,7 @@ static int mmc_decode_csd(struct mmc_card *card)
e = UNSTUFF_BITS(resp, 47, 3);
m = UNSTUFF_BITS(resp, 62, 12);
-#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0
+#if defined(CONFIG_JZ_BOOT_FROM_MSC0)
csd->capacity = (1 + m) << (e + 2);
csd->capacity -= 16384;
#else
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 69f3e710e08..c68e7e5e39f 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -110,7 +110,7 @@ static int mmc_decode_csd(struct mmc_card *card)
e = UNSTUFF_BITS(resp, 47, 3);
m = UNSTUFF_BITS(resp, 62, 12);
-#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0
+#if defined(CONFIG_JZ_BOOT_FROM_MSC0)
csd->capacity = (1 + m) << (e + 2);
csd->capacity -= 16384;
#else
@@ -144,7 +144,7 @@ static int mmc_decode_csd(struct mmc_card *card)
m = UNSTUFF_BITS(resp, 48, 22);
-#ifdef CONFIG_JZ4750_BOOT_FROM_MSC0
+#if defined(CONFIG_JZ_BOOT_FROM_MSC0)
csd->capacity = (1 + m) << 10;
csd->capacity -= 16384;
#else
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index c774b9a9b3e..0d4e673cfd0 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -32,73 +32,145 @@ config JZ_MMC_BUS_4
endchoice
-config MSC0_JZ4750
- tristate "JZ4750 SD/Multimedia Card 0 Interface support"
- depends on SOC_JZ4750 || SOC_JZ4750D
+
+config JZ_MSC0
+ tristate "JZ SOC Multimedia/SD/SDIO host controller 0 support"
+ depends on SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760
help
- This selects the Ingenic JZ4750 SD/Multimedia card 0 Interface.
+ this selects the Ingenic Multimedia/SD/SDIO host controller 0.
If you have a Ingenic platform with a Multimedia Card slot,
- say Y or M here.
+ Say Y or M here.
If unsure, say N.
choice
- depends on MSC0_JZ4750
- prompt "MSC0 BUS Width"
- default JZ4750_MSC0_BUS_4
+ depends on JZ_MSC0
+ prompt "Multimedia/SD/SDIO controller 0 Bus Width"
+ default JZ_MSC0_BUS_4
help
- This defines the BUS Width of the Ingenic JZ4750 SD/Multimedia card Interface.
+ This defines the bus width of the Ingenic Multimedia/SD/SDIO host controller
-config JZ4750_MSC0_BUS_1
- bool "1 Bit Bus"
+config JZ_MSC0_BUS_1
+ bool "1-bit Bus"
help
- 1 Bit SD/Multimedia Card Bus
+ 1-bit Multimedia/SD/SDIO Card Bus
-config JZ4750_MSC0_BUS_4
- bool "4 Bit Bus"
+config JZ_MSC0_BUS_4
+ bool "4-bit Bus"
help
- 4 Bit SD/Multimedia Card Bus
+ 4-bit Multimedia/SD/SDIO Card Bus
-config JZ4750_MSC0_BUS_8
- bool "8 Bit Bus"
+config JZ_MSC0_BUS_8
+ bool "8-bit Bus"
help
- 8 Bit Multimedia Card Bus
+ 8-bit Multimedia/SD/SDIO Card Bus
+ If the controller support 8-bit bus, select this.
+ If unsure, use the default(4-bit) maybe the best choice
endchoice
-config MSC1_JZ4750
- tristate "JZ4750 SD/Multimedia Card 1 Interface support"
- depends on SOC_JZ4750 || SOC_JZ4750D
+config JZ_MSC0_SDIO_SUPPORT
+ bool "SDIO support for Multimedia/SD/SDIO controller 0"
+ depends on JZ_MSC0
help
- This selects the Ingenic JZ4750 SD/Multimedia card 1 Interface.
+ SDIO support for MSC0.
+
+ If unsure,say N.
+
+config JZ_MSC1
+ tristate "JZ SOC Multimedia/SD/SDIO host controller 1 support"
+ depends on SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760
+ help
+ this selects the Ingenic Multimedia/SD/SDIO host controller 1.
If you have a Ingenic platform with a Multimedia Card slot,
- say Y or M here.
+ Say Y or M here.
If unsure, say N.
choice
- depends on MSC1_JZ4750
- prompt "MSC1 BUS Width"
- default JZ4750_MSC1_BUS_4
+ depends on JZ_MSC1
+ prompt "Multimedia/SD/SDIO controller 1 Bus Width"
+ default JZ_MSC1_BUS_4
help
- This defines the BUS Width of the Ingenic JZ4750 SD/Multimedia card Interface.
+ This defines the bus width of the Ingenic Multimedia/SD/SDIO host controller
-config JZ4750_MSC1_BUS_1
- bool "1 Bit Bus"
+config JZ_MSC1_BUS_1
+ bool "1-bit Bus"
help
- 1 Bit SD/Multimedia Card Bus
+ 1-bit Multimedia/SD/SDIO Card Bus
-config JZ4750_MSC1_BUS_4
- bool "4 Bit Bus"
+config JZ_MSC1_BUS_4
+ bool "4-bit Bus"
help
- 4 Bit SD/Multimedia Card Bus
+ 4-bit Multimedia/SD/SDIO Card Bus
+
+config JZ_MSC1_BUS_8
+ bool "8-bit Bus"
+ help
+ 8-bit Multimedia/SD/SDIO Card Bus
+ If the controller support 8-bit bus, select this.
+
+ If unsure, use the default(4-bit) maybe the best choice
+endchoice
+
+config JZ_MSC1_SDIO_SUPPORT
+ bool "SDIO support for Multimedia/SD/SDIO controller 1"
+ depends on JZ_MSC1
+ help
+ SDIO support for MSC1.
+
+ If unsure,say N.
+
+config JZ_MSC2
+ tristate "JZ SOC Multimedia/SD/SDIO host controller 2 support"
+ depends on SOC_JZ4760
+ help
+ this selects the Ingenic Multimedia/SD/SDIO host controller 2.
+ If you have a Ingenic platform with a Multimedia Card slot,
+ Say Y or M here.
+
+ If unsure, say N.
+
+choice
+ depends on JZ_MSC2
+ prompt "Multimedia/SD/SDIO controller 2 Bus Width"
+ default JZ_MSC2_BUS_4
+ help
+ This defines the bus width of the Ingenic Multimedia/SD/SDIO host controller
+
+config JZ_MSC2_BUS_1
+ bool "1-bit Bus"
+ help
+ 1-bit Multimedia/SD/SDIO Card Bus
+
+config JZ_MSC2_BUS_4
+ bool "4-bit Bus"
+ help
+ 4-bit Multimedia/SD/SDIO Card Bus
+
+config JZ_MSC2_BUS_8
+ bool "8-bit Bus"
+ help
+ 8-bit Multimedia/SD/SDIO Card Bus
+ If the controller support 8-bit bus, select this.
+
+ If unsure, use the default(4-bit) maybe the best choice
endchoice
-config JZ4750_BOOT_FROM_MSC0
- tristate "JZ4750 Boot from SD/Multimedia Card Interface support"
- depends on SOC_JZ4750 || SOC_JZ4750D
+config JZ_MSC2_SDIO_SUPPORT
+ bool "SDIO support for Multimedia/SD/SDIO controller 2"
+ depends on JZ_MSC2
+ help
+ SDIO support for MSC1.
+
+ If unsure,say N.
+
+config JZ_BOOT_FROM_MSC0
+ tristate "Boot from Ingenic Multimedia/SD/SDIO Card Interface 0 support"
+ depends on SOC_JZ4750 || SOC_JZ4750D || SOC_JZ4760
+ depends on JZ_MSC0
help
- This selects boot from the Sd/Multimedia Card.
+ This selects boot from the Multimedia/SD/SDIO Card.
If unsure,say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index bbeefce06fa..bbaeeb2fc70 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -7,8 +7,8 @@ ifeq ($(CONFIG_MMC_DEBUG),y)
endif
obj-$(CONFIG_MMC_JZ) += jz_mmc.o
-obj-$(CONFIG_MSC0_JZ4750) += jz4750_mmc.o
-obj-$(CONFIG_MSC1_JZ4750) += jz4750_mmc.o
+obj-$(CONFIG_JZ_MSC0) += jzmmc/
+obj-$(CONFIG_JZ_MSC1) += jzmmc/
obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
obj-$(CONFIG_MMC_PXA) += pxamci.o
diff --git a/drivers/mmc/host/jz4750_mmc.c b/drivers/mmc/host/jz4750_mmc.c
deleted file mode 100644
index 2cfe4228116..00000000000
--- a/drivers/mmc/host/jz4750_mmc.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * linux/drivers/mmc/jz_mmc.c - JZ SD/MMC driver
- *
- * Copyright (C) 2005 - 2008 Ingenic Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/dma-mapping.h>
-#include <linux/mmc/host.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/sd.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/pm.h>
-#include <linux/scatterlist.h>
-
-#include <asm/io.h>
-#include <asm/scatterlist.h>
-#include <asm/jzsoc.h>
-
-#include "jz4750_mmc.h"
-
-#define DRIVER_NAME "jz-mmc"
-
-#define USE_DMA
-
-static int r_type = 0;
-static int rxdmachan = 0;
-static int txdmachan = 0;
-static int mmc_slot_enable = 0;
-static int auto_select_bus = MSC_4BIT_BUS; /* default 4 bit bus*/
-
-/* Start the MMC clock and operation */
-static inline int jz_mmc_start_op(void)
-{
- REG_MSC_STRPCL(MSC_ID) = MSC_STRPCL_START_OP;
-
- return MMC_NO_ERROR;
-}
-
-static inline u32 jz_mmc_calc_clkrt(int is_low, u32 rate)
-{
- u32 clkrt;
- u32 clk_src = is_low ? 24000000 : 48000000;
-
- clkrt = 0;
- while (rate < clk_src) {
- clkrt++;
- clk_src >>= 1;
- }
- return clkrt;
-}
-
-/* Select the MMC clock frequency */
-static int jz_mmc_set_clock(u32 rate)
-{
- int clkrt;
-
- /* __cpm_select_msc_clk_high will select 48M clock for MMC/SD card
- * perhaps this will made some card with bad quality init fail,or
- * bad stabilization.
- */
- if (rate > SD_CLOCK_FAST) {
- __cpm_select_msc_clk_high(MSC_ID,1); /* select clock source from CPM */
- clkrt = jz_mmc_calc_clkrt(0, rate);
- } else {
- __cpm_select_msc_clk(MSC_ID,1); /* select clock source from CPM */
- clkrt = jz_mmc_calc_clkrt(1, rate);
- }
-
-#ifndef CONFIG_FPGA
- REG_MSC_CLKRT(MSC_ID) = clkrt;
-#else
- REG_MSC_CLKRT(MSC_ID) = 7;
-#endif
- return MMC_NO_ERROR;
-}
-
-static void jz_mmc_enable_irq(struct jz_mmc_host *host, unsigned int mask)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- host->imask &= ~mask;
- REG_MSC_IMASK(MSC_ID) = host->imask;
- spin_unlock_irqrestore(&host->lock, flags);
-}
-
-static void jz_mmc_disable_irq(struct jz_mmc_host *host, unsigned int mask)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- host->imask |= mask;
- REG_MSC_IMASK(MSC_ID) = host->imask;
- spin_unlock_irqrestore(&host->lock, flags);
-}
-
-void jz_set_dma_block_size(int dmanr, int nbyte);
-
-#ifdef USE_DMA
-static inline void
-jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(chan);
- clear_dma_ff(chan);
- jz_set_dma_block_size(chan, 32);
- set_dma_mode(chan, mode);
- set_dma_addr(chan, phyaddr);
- set_dma_count(chan, count + 31);
- enable_dma(chan);
- release_dma_lock(flags);
-}
-
-static irqreturn_t jz_mmc_dma_rx_callback(int irq, void *devid)
-{
- int chan = rxdmachan;
-
- disable_dma(chan);
- if (__dmac_channel_address_error_detected(chan)) {
- printk(KERN_DEBUG "%s: DMAC address error.\n",
- __FUNCTION__);
- __dmac_channel_clear_address_error(chan);
- }
- if (__dmac_channel_transmit_end_detected(chan)) {
- __dmac_channel_clear_transmit_end(chan);
- }
- return IRQ_HANDLED;
-}
-static irqreturn_t jz_mmc_dma_tx_callback(int irq, void *devid)
-{
- int chan = txdmachan;
-
- disable_dma(chan);
- if (__dmac_channel_address_error_detected(chan)) {
- printk(KERN_DEBUG "%s: DMAC address error.\n",
- __FUNCTION__);
- __dmac_channel_clear_address_error(chan);
- }
- if (__dmac_channel_transmit_end_detected(chan)) {
- __dmac_channel_clear_transmit_end(chan);
- }
- return IRQ_HANDLED;
-}
-
-/* Prepare DMA to start data transfer from the MMC card */
-static void jz_mmc_rx_setup_data(struct jz_mmc_host *host,
- struct mmc_data *data)
-{
- unsigned int nob = data->blocks;
- int channelrx = rxdmachan;
- int i;
- u32 size;
-
- if (data->flags & MMC_DATA_STREAM)
- nob = 0xffff;
-
- REG_MSC_NOB(MSC_ID) = nob;
- REG_MSC_BLKLEN(MSC_ID) = data->blksz;
- size = nob * data->blksz;
-
- if (data->flags & MMC_DATA_READ) {
- host->dma.dir = DMA_FROM_DEVICE;
- } else {
- host->dma.dir = DMA_TO_DEVICE;
- }
-
- host->dma.len =
- dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- host->dma.dir);
-
- for (i = 0; i < host->dma.len; i++) {
- host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
- host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]);
- dma_cache_wback_inv((unsigned long)
- CKSEG0ADDR(sg_dma_address(data->sg)) +
- data->sg->offset,
- host->sg_cpu[i].dcmd);
- jz_mmc_start_dma(channelrx, host->sg_cpu[i].dtadr,
- host->sg_cpu[i].dcmd, DMA_MODE_READ);
- }
-}
-
-/* Prepare DMA to start data transfer from the MMC card */
-static void jz_mmc_tx_setup_data(struct jz_mmc_host *host,
- struct mmc_data *data)
-{
- unsigned int nob = data->blocks;
- int channeltx = txdmachan;
- int i;
- u32 size;
-
- if (data->flags & MMC_DATA_STREAM)
- nob = 0xffff;
-
- REG_MSC_NOB(MSC_ID) = nob;
- REG_MSC_BLKLEN(MSC_ID) = data->blksz;
- size = nob * data->blksz;
-
- if (data->flags & MMC_DATA_READ) {
- host->dma.dir = DMA_FROM_DEVICE;
- } else {
- host->dma.dir = DMA_TO_DEVICE;
- }
-
- host->dma.len =
- dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- host->dma.dir);
-
- for (i = 0; i < host->dma.len; i++) {
- host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
- host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]);
- dma_cache_wback_inv((unsigned long)
- CKSEG0ADDR(sg_dma_address(data->sg)) +
- data->sg->offset,
- host->sg_cpu[i].dcmd);
- jz_mmc_start_dma(channeltx, host->sg_cpu[i].dtadr,
- host->sg_cpu[i].dcmd, DMA_MODE_WRITE);
- }
-}
-#else
-static void jz_mmc_receive_pio(struct jz_mmc_host *host)
-{
-
- struct mmc_data *data = 0;
- int sg_len = 0, max = 0, count = 0;
- u32 *buf = 0;
- struct scatterlist *sg;
- unsigned int nob;
-
- data = host->mrq->data;
- nob = data->blocks;
- REG_MSC_NOB(MSC_ID) = nob;
- REG_MSC_BLKLEN(MSC_ID) = data->blksz;
-
- max = host->pio.len;
- if (host->pio.index < host->dma.len) {
- sg = &data->sg[host->pio.index];
- buf = sg_virt(sg) + host->pio.offset;
-
- /* This is the space left inside the buffer */
- sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
- /* Check to if we need less then the size of the sg_buffer */
- if (sg_len < max) max = sg_len;
- }
- max = max / 4;
- for(count = 0; count < max; count++) {
- while (REG_MSC_STAT(MSC_ID) & MSC_STAT_DATA_FIFO_EMPTY)
- ;
- *buf++ = REG_MSC_RXFIFO(MSC_ID);
- }
- host->pio.len -= count;
- host->pio.offset += count;
-
- if (sg_len && count == sg_len) {
- host->pio.index++;
- host->pio.offset = 0;
- }
-}
-
-static void jz_mmc_send_pio(struct jz_mmc_host *host)
-{
-
- struct mmc_data *data = 0;
- int sg_len, max, count = 0;
- u32 *wbuf = 0;
- struct scatterlist *sg;
- unsigned int nob;
-
- data = host->mrq->data;
- nob = data->blocks;
-
- REG_MSC_NOB(MSC_ID) = nob;
- REG_MSC_BLKLEN(MSC_ID) = data->blksz;
-
- /* This is the pointer to the data buffer */
- sg = &data->sg[host->pio.index];
- wbuf = sg_virt(sg) + host->pio.offset;
-
- /* This is the space left inside the buffer */
- sg_len = data->sg[host->pio.index].length - host->pio.offset;
-
- /* Check to if we need less then the size of the sg_buffer */
- max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
- max = max / 4;
- for(count = 0; count < max; count++ ) {
- while (REG_MSC_STAT(MSC_ID) & MSC_STAT_DATA_FIFO_FULL)
- ;
- REG_MSC_TXFIFO(MSC_ID) = *wbuf++;
- }
-
- host->pio.len -= count;
- host->pio.offset += count;
-
- if (count == sg_len) {
- host->pio.index++;
- host->pio.offset = 0;
- }
-}
-
-static int
-jz_mmc_prepare_data(struct jz_mmc_host *host, struct mmc_data *data)
-{
- int datalen = data->blocks * data->blksz;
-
- host->dma.dir = DMA_BIDIRECTIONAL;
- host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
- data->sg_len, host->dma.dir);
- if (host->dma.len == 0)
- return -ETIMEDOUT;
-
- host->pio.index = 0;
- host->pio.offset = 0;
- host->pio.len = datalen;
- return 0;
-}
-#endif
-
-static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat);
-
-static void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq)
-{
- host->mrq = NULL;
- host->cmd = NULL;
- host->data = NULL;
- mmc_request_done(host->mmc, mrq);
-}
-
-static void jz_mmc_start_cmd(struct jz_mmc_host *host,
- struct mmc_command *cmd, unsigned int cmdat)
-{
- u32 timeout = 0x3fffff;
- unsigned int stat;
- struct jz_mmc_host *hst = host;
- WARN_ON(host->cmd != NULL);
- host->cmd = cmd;
-
- /* mask interrupts */
- REG_MSC_IMASK(MSC_ID) = 0xffff;
-
- /* clear status */
- REG_MSC_IREG(MSC_ID) = 0xffff;
-
- if (cmd->flags & MMC_RSP_BUSY)
- cmdat |= MSC_CMDAT_BUSY;
-
-#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
- switch (RSP_TYPE(mmc_resp_type(cmd))) {
- case RSP_TYPE(MMC_RSP_R1): /* r1,r1b, r6, r7 */
- cmdat |= MSC_CMDAT_RESPONSE_R1;
- r_type = 1;
- break;
- case RSP_TYPE(MMC_RSP_R3):
- cmdat |= MSC_CMDAT_RESPONSE_R3;
- r_type = 1;
- break;
- case RSP_TYPE(MMC_RSP_R2):
- cmdat |= MSC_CMDAT_RESPONSE_R2;
- r_type = 2;
- break;
- default:
- break;
- }
-
- REG_MSC_CMD(MSC_ID) = cmd->opcode;
-
- /* Set argument */
-#ifdef CONFIG_MSC0_JZ4750
-#ifdef CONFIG_JZ4750_MSC0_BUS_1
- if (cmd->opcode == 6) {
- /* set 1 bit sd card bus*/
- if (cmd->arg ==2)
- REG_MSC_ARG(MSC_ID) = 0;
-
- /* set 1 bit mmc card bus*/
- if (cmd->arg == 0x3b70101) {
- REG_MSC_ARG(MSC_ID) = 0x3b70001;
- }
- } else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-
-#elif defined CONFIG_JZ4750_MSC0_BUS_8
- if (cmd->opcode == 6) {
- /* set 8 bit mmc card bus*/
- if (cmd->arg == 0x3b70101)
- REG_MSC_ARG(MSC_ID) = 0x3b70201;
- else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-
- } else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-#else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-#endif /* CONFIG_JZ4750_MSC0_BUS_1 */
-#else
-#ifdef CONFIG_JZ4750_MSC1_BUS_1
- if (cmd->opcode == 6) {
- /* set 1 bit sd card bus*/
- if (cmd->arg ==2)
- REG_MSC_ARG(MSC_ID) = 0;
-
- /* set 1 bit mmc card bus*/
- if (cmd->arg == 0x3b70101) {
- REG_MSC_ARG(MSC_ID) = 0x3b70001;
- }
- } else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-
-#else
- REG_MSC_ARG(MSC_ID) = cmd->arg;
-#endif /* CONFIG_JZ4750_MSC1_BUS_1 */
-#endif /* CONFIG_MSC0_JZ4750*/
-
- /* Set command */
- REG_MSC_CMDAT(MSC_ID) = cmdat;
-
- /* Send command */
- jz_mmc_start_op();
-
- while (timeout-- && !(REG_MSC_STAT(MSC_ID) & MSC_STAT_END_CMD_RES))
- ;
-
- REG_MSC_IREG(MSC_ID) = MSC_IREG_END_CMD_RES; /* clear irq flag */
- if (cmd->opcode == 12) {
- while (timeout-- && !(REG_MSC_IREG(MSC_ID) & MSC_IREG_PRG_DONE))
- ;
- REG_MSC_IREG(MSC_ID) = MSC_IREG_PRG_DONE; /* clear status */
- }
- if (!mmc_slot_enable) {
- /* It seems that MSC can't report the MSC_STAT_TIME_OUT_RES when
- * card was removed. We force to return here.
- */
- cmd->error = -ETIMEDOUT;
- jz_mmc_finish_request(hst, hst->mrq);
- return;
- }
-
- if (SD_IO_SEND_OP_COND == cmd->opcode) {
- /*
- * Don't support SDIO card currently.
- */
- cmd->error = -ETIMEDOUT;
- jz_mmc_finish_request(hst, hst->mrq);
- return;
- }
-
- /* Check for status */
- stat = REG_MSC_STAT(MSC_ID);
- jz_mmc_cmd_done(hst, stat);
- if (host->data) {
- if (cmd->opcode == MMC_WRITE_BLOCK || cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)
-#ifdef USE_DMA
- jz_mmc_tx_setup_data(host, host->data);
-#else
- jz_mmc_send_pio(host);
- else
- jz_mmc_receive_pio(host);
-#endif
- }
-}
-
-static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat)
-{
- struct mmc_command *cmd = host->cmd;
- int i, temp[16];
- u8 *buf;
- u32 data, v, w1, w2;
-
- if (!cmd)
- return 0;
-
- host->cmd = NULL;
- buf = (u8 *) temp;
- switch (r_type) {
- case 1:
- {
- data = REG_MSC_RES(MSC_ID);
- buf[0] = (data >> 8) & 0xff;
- buf[1] = data & 0xff;
- data = REG_MSC_RES(MSC_ID);
- buf[2] = (data >> 8) & 0xff;
- buf[3] = data & 0xff;
- data = REG_MSC_RES(MSC_ID);
- buf[4] = data & 0xff;
- cmd->resp[0] =
- buf[1] << 24 | buf[2] << 16 | buf[3] << 8 |
- buf[4];
- break;
- }
- case 2:
- {
- data = REG_MSC_RES(MSC_ID);
- v = data & 0xffff;
- for (i = 0; i < 4; i++) {
- data = REG_MSC_RES(MSC_ID);
- w1 = data & 0xffff;
- data = REG_MSC_RES(MSC_ID);
- w2 = data & 0xffff;
- cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8;
- v = w2;
- }
- break;
- }
- case 0:
- break;
- }
- if (stat & MSC_STAT_TIME_OUT_RES) {
- printk("MSC_STAT_TIME_OUT_RES\n");
- cmd->error = -ETIMEDOUT;
- } else if (stat & MSC_STAT_CRC_RES_ERR && cmd->flags & MMC_RSP_CRC) {
- printk("MSC_STAT_CRC\n");
- if (cmd->opcode == MMC_ALL_SEND_CID ||
- cmd->opcode == MMC_SEND_CSD ||
- cmd->opcode == MMC_SEND_CID) {
- /* a bogus CRC error can appear if the msb of
- the 15 byte response is a one */
- if ((cmd->resp[0] & 0x80000000) == 0)
- cmd->error = -EILSEQ;
- }
- }
- /*
- * Did I mention this is Sick. We always need to
- * discard the upper 8 bits of the first 16-bit word.
- */
- if (host->data && cmd->error == 0)
- jz_mmc_enable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
- else
- jz_mmc_finish_request(host, host->mrq);
-
- return 1;
-}
-
-static int jz_mmc_data_done(struct jz_mmc_host *host, unsigned int stat)
-{
- struct mmc_data *data = host->data;
-
- if (!data)
- return 0;
- REG_MSC_IREG(MSC_ID) = MSC_IREG_DATA_TRAN_DONE; /* clear status */
- dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
- host->dma_dir);
- if (stat & MSC_STAT_TIME_OUT_READ) {
- printk("MMC/SD timeout, MMC_STAT 0x%x\n", stat);
- data->error = -ETIMEDOUT;
- } else if (REG_MSC_STAT(MSC_ID) &
- (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR)) {
- printk("MMC/SD CRC error, MMC_STAT 0x%x\n", stat);
- data->error = -EILSEQ;
- }
- /*
- * There appears to be a hardware design bug here. There seems to
- * be no way to find out how much data was transferred to the card.
- * This means that if there was an error on any block, we mark all
- * data blocks as being in error.
- */
- if (data->error == 0)
- data->bytes_xfered = data->blocks * data->blksz;
- else
- data->bytes_xfered = 0;
-
- jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
- host->data = NULL;
- if (host->mrq->stop) {
- jz_mmc_start_cmd(host, host->mrq->stop, 0);
- } else {
- jz_mmc_finish_request(host, host->mrq);
- }
- return 1;
-}
-
-static void jz_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
-{
- struct jz_mmc_host *host = mmc_priv(mmc);
- unsigned int cmdat;
-
- /* Save current request for the future processing */
- host->mrq = mrq;
- host->data = mrq->data;
- cmdat = host->cmdat;
- host->cmdat &= ~MSC_CMDAT_INIT;
-
- if (mrq->data) {
- cmdat &= ~MSC_CMDAT_BUSY;
-#ifdef USE_DMA
- if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6))
-
- cmdat |=
- MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN |
- MSC_CMDAT_DMA_EN;
- else {
-#ifdef CONFIG_MSC0_JZ4750
-#ifdef CONFIG_JZ4750_MSC0_BUS_1
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN |
- MSC_CMDAT_DMA_EN;
-#elif defined CONFIG_JZ4750_MSC0_BUS_4
- if(auto_select_bus == MSC_1BIT_BUS) {
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN |
- MSC_CMDAT_DMA_EN;
- } else {
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT | MSC_CMDAT_DATA_EN |
- MSC_CMDAT_DMA_EN;
- }
-#else
- cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN;
-#endif /* CONFIG_JZ4750_MSC0_BUS_1 */
-#else
-#ifdef CONFIG_JZ4750_MSC1_BUS_1
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN |
- MSC_CMDAT_DMA_EN;
-#else
- cmdat |= MSC_CMDAT_DATA_EN | MSC_CMDAT_DMA_EN;
-#endif /* CONFIG_JZ4750_MSC1_BUS_1 */
-#endif /* CONFIG_MSC0_JZ4750 */
- }
- if (mrq->data->flags & MMC_DATA_WRITE)
- cmdat |= MSC_CMDAT_WRITE;
-
- if (mrq->data->flags & MMC_DATA_STREAM)
- cmdat |= MSC_CMDAT_STREAM_BLOCK;
- if (mrq->cmd->opcode != MMC_WRITE_BLOCK
- && mrq->cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK)
- jz_mmc_rx_setup_data(host, mrq->data);
-#else /*USE_DMA*/
-
- if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6))
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN;
- else {
-#ifdef CONFIG_MSC0_JZ4750
-#ifdef CONFIG_JZ4750_MSC0_BUS_1
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN;
-#elif defined CONFIG_JZ4750_MSC0_BUS_4
- if(auto_select_bus == MSC_1BIT_BUS) {
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN;
- } else {
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT | MSC_CMDAT_DATA_EN;
- }
-#else
- cmdat |= MSC_CMDAT_DATA_EN;
-#endif
-#else
-#ifdef CONFIG_JZ4750_MSC1_BUS_1
- cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
- cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN;
-#else
- cmdat |= MSC_CMDAT_DATA_EN;
-#endif /* CONFIG_JZ4750_MSC1_BUS_1 */
-#endif /* CONFIG_MSC0_JZ4750 */
- }
- if (mrq->data->flags & MMC_DATA_WRITE)
- cmdat |= MSC_CMDAT_WRITE;
-
- if (mrq->data->flags & MMC_DATA_STREAM)
- cmdat |= MSC_CMDAT_STREAM_BLOCK;
- jz_mmc_prepare_data(host, host->data);
-#endif /*USE_DMA*/
- }
- jz_mmc_start_cmd(host, mrq->cmd, cmdat);
-}
-
-static irqreturn_t jz_mmc_irq(int irq, void *devid)
-{
- struct jz_mmc_host *host = devid;
- unsigned int ireg;
- int handled = 0;
-
- ireg = REG_MSC_IREG(MSC_ID);
-
- if (ireg) {
- unsigned stat = REG_MSC_STAT(MSC_ID);
- if (ireg & MSC_IREG_DATA_TRAN_DONE)
- handled |= jz_mmc_data_done(host, stat);
- }
- return IRQ_RETVAL(handled);
-}
-
-/* Returns true if MMC slot is empty */
-static int jz_mmc_slot_is_empty(int slot)
-{
- int empty;
-
-#ifdef CONFIG_FPGA
- return 0;
-#endif
-
-#ifdef CONFIG_MSC1_JZ4750
- empty = (__msc1_card_detected(slot) == 0) ? 1 : 0;
-#else
- empty = (__msc0_card_detected(slot) == 0) ? 1 : 0;
-#endif
-
- if (empty) {
-
- /* wait for card insertion */
-#ifdef CONFIG_SOC_JZ4750
-#ifdef CONFIG_MSC1_JZ4750
- __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN);
-#else
- __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN);
-#endif
-#else
- __gpio_as_irq_fall_edge(MSC1_HOTPLUG_PIN);
-#endif
-
- } else {
- /* wait for card removal */
-#ifdef CONFIG_SOC_JZ4750
-#ifdef CONFIG_MSC1_JZ4750
- __gpio_as_irq_fall_edge(MSC_HOTPLUG_PIN);
-#else
- __gpio_as_irq_rise_edge(MSC_HOTPLUG_PIN);
-#endif
-#else
- __gpio_as_irq_rise_edge(MSC1_HOTPLUG_PIN);
-#endif
- }
-
- return empty;
-}
-
-static irqreturn_t jz_mmc_detect_irq(int irq, void *devid)
-{
- struct jz_mmc_host *host = (struct jz_mmc_host *) devid;
-
- auto_select_bus = MSC_4BIT_BUS;
- if (jz_mmc_slot_is_empty(0)) {
- mmc_slot_enable = 0;
- mmc_detect_change(host->mmc, 50);
- } else {
- mmc_slot_enable = 1;
- mmc_detect_change(host->mmc, 50);
- }
- return IRQ_HANDLED;
-}
-
-static int jz_mmc_get_ro(struct mmc_host *mmc)
-{
- struct jz_mmc_host *host = mmc_priv(mmc);
-
- if (host->pdata && host->pdata->get_ro)
- return host->pdata->get_ro(mmc_dev(mmc));
- /* Host doesn't support read only detection so assume writeable */
- return 0;
-}
-
-/* set clock and power */
-static void jz_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
- struct jz_mmc_host *host = mmc_priv(mmc);
-
- if (ios->clock)
- jz_mmc_set_clock(ios->clock);
-
- if (host->power_mode != ios->power_mode) {
- host->power_mode = ios->power_mode;
-
- if (ios->power_mode == MMC_POWER_ON)
- host->cmdat |= CMDAT_INIT;
- }
-
- if (ios->bus_width == MMC_BUS_WIDTH_4) {
- auto_select_bus = MSC_4BIT_BUS;
- host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
- }
- else if (ios->bus_width == MMC_BUS_WIDTH_8) {
- host->cmdat |= MSC_CMDAT_BUS_WIDTH_8BIT;
- auto_select_bus = MSC_8BIT_BUS;
- } else {
- /* 1 bit bus*/
- host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_8BIT;
- auto_select_bus = MSC_1BIT_BUS;
- }
-}
-
-static const struct mmc_host_ops jz_mmc_ops = {
- .request = jz_mmc_request,
- .get_ro = jz_mmc_get_ro,
- .set_ios = jz_mmc_set_ios,
-};
-
-static int jz_mmc_probe(struct platform_device *pdev)
-{
- int retval;
- struct mmc_host *mmc;
- struct jz_mmc_host *host = NULL;
- int irq;
- struct resource *r;
-
-#ifdef CONFIG_MSC0_JZ4750
-#ifdef CONFIG_SOC_JZ4750
- __gpio_as_msc0_8bit(); // for jz4750
-#else
- __gpio_as_msc0_4bit(); // for jz4750d
-#endif
- __msc0_init_io();
- __msc0_enable_power();
-#else
- __gpio_as_msc1_4bit();
- __msc1_init_io();
- __msc1_enable_power();
-#endif
- __msc_reset(MSC_ID);
- REG_MSC_LPM(MSC_ID) = 0x1;
-
- MMC_IRQ_MASK();
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_irq(pdev, 0);
- if (!r || irq < 0)
- return -ENXIO;
-
- r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
- if (!r)
- return -EBUSY;
-
- mmc = mmc_alloc_host(sizeof(struct jz_mmc_host), &pdev->dev);
- if (!mmc) {
- retval = -ENOMEM;
- goto out;
- }
- mmc->ops = &jz_mmc_ops;
- mmc->f_min = MMC_CLOCK_SLOW;
- mmc->f_max = SD_CLOCK_HIGH;
- /*
- * We can do SG-DMA, but we don't because we never know how much
- * data we successfully wrote to the card.
- */
- mmc->max_phys_segs = NR_SG;
-
- mmc->max_seg_size = PAGE_SIZE * 16;
- mmc->max_req_size = mmc->max_seg_size;
- mmc->max_blk_size = 4095;
- /*
- * Block count register is 16 bits.
- */
- mmc->max_blk_count = 65535;
- host = mmc_priv(mmc);
- host->mmc = mmc;
- host->pdata = pdev->dev.platform_data;
- mmc->ocr_avail = host->pdata ?
- host->pdata->ocr_mask : MMC_VDD_32_33 | MMC_VDD_33_34;
- host->mmc->caps =
- MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
- /*
- *MMC_CAP_4_BIT_DATA (1 << 0) The host can do 4 bit transfers
- *
- */
- host->sg_cpu =
- dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma,
- GFP_KERNEL);
- if (!host->sg_cpu) {
- retval = -ENOMEM;
- goto out;
- }
- spin_lock_init(&host->lock);
- host->irq = IRQ_MSC; /* is it useful ?*/
- host->imask = 0xffff;
- /*
- * Ensure that the host controller is shut down, and setup
- * with our defaults.
- */
- retval = request_irq(IRQ_MSC, jz_mmc_irq, 0, "MMC/SD", host);
- if (retval) {
- printk(KERN_ERR "MMC/SD: can't request MMC/SD IRQ\n");
- return retval;
- }
-
- jz_mmc_slot_is_empty(0);
- /* Request card detect interrupt */
-
- retval = request_irq(MSC_HOTPLUG_IRQ, jz_mmc_detect_irq, 0, //SA_INTERRUPT,
- "MMC card detect", host);
- if (retval) {
- printk(KERN_ERR "MMC/SD: can't request card detect IRQ\n");
- goto err1;
- }
-#ifdef USE_DMA
- /* Request MMC Rx DMA channel */
- rxdmachan =
- jz_request_dma(DMA_ID_MSC_RX, "MMC Rx", jz_mmc_dma_rx_callback,
- 0, host);
- if (rxdmachan < 0) {
- printk(KERN_ERR "jz_request_dma failed for MMC Rx\n");
- goto err2;
- }
-
- if (rxdmachan < HALF_DMA_NUM)
- REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC;
- else
- REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC;
-
- /* Request MMC Tx DMA channel */
- txdmachan =
- jz_request_dma(DMA_ID_MSC_TX, "MMC Tx", jz_mmc_dma_tx_callback,
- 0, host);
- if (txdmachan < 0) {
- printk(KERN_ERR "jz_request_dma failed for MMC Tx\n");
- goto err3;
- }
-
- if (txdmachan < HALF_DMA_NUM)
- REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC;
- else
- REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC;
-
-#endif
- platform_set_drvdata(pdev, mmc);
- mmc_add_host(mmc);
-
- printk(JZ_SOC_NAME ": SD/MMC card driver registered.\n");
-
- /* Detect card during initialization */
-#if defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
- if (!jz_mmc_slot_is_empty(0)) {
- mmc_slot_enable = 1;
- mmc_detect_change(host->mmc, 0);
- }
-#endif
- return 0;
-
-err1:free_irq(IRQ_MSC, &host);
-#ifdef USE_DMA
- err2:jz_free_dma(rxdmachan);
- err3:jz_free_dma(txdmachan);
-#endif
-out:
- if (host) {
- if (host->sg_cpu)
- dma_free_coherent(&pdev->dev, PAGE_SIZE,
- host->sg_cpu, host->sg_dma);
- }
- if (mmc)
- mmc_free_host(mmc);
- return -1;
-}
-
-static int jz_mmc_remove(struct platform_device *pdev)
-{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- unsigned long flags;
-
- platform_set_drvdata(pdev, NULL);
-
- if (mmc) {
- struct jz_mmc_host *host = mmc_priv(mmc);
-
- if (host->pdata && host->pdata->exit)
- host->pdata->exit(&pdev->dev, mmc);
-
- mmc_remove_host(mmc);
-
- local_irq_save(flags);
- __msc0_disable_power();
- jz_free_dma(rxdmachan);
- jz_free_dma(txdmachan);
- free_irq(IRQ_MSC, host);
- local_irq_restore(flags);
- mmc_free_host(mmc);
- }
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int jz_mmc_suspend(struct platform_device *dev, pm_message_t state)
-{
- struct mmc_host *mmc = platform_get_drvdata(dev);
- int ret = 0;
-
- printk("%s(): called.\n", __func__);
-
- if (mmc)
- ret = mmc_suspend_host(mmc, state);
-
- return ret;
-}
-
-static int jz_mmc_resume(struct platform_device *dev)
-{
- struct mmc_host *mmc = platform_get_drvdata(dev);
- int ret = 0;
-
- printk("%s(): called.\n", __func__);
-
- if (mmc)
- ret = mmc_resume_host(mmc);
-
- return ret;
-}
-#else
-#define jz_mmc_suspend NULL
-#define jz_mmc_resume NULL
-#endif
-
-static struct platform_driver jz_mmc_driver = {
- .probe = jz_mmc_probe,
- .remove = jz_mmc_remove,
- .suspend = jz_mmc_suspend,
- .resume = jz_mmc_resume,
- .driver = {
- .name = DRIVER_NAME,
- },
-};
-
-static int __init jz_mmc_init(void)
-{
- return platform_driver_register(&jz_mmc_driver);
-}
-
-static void __exit jz_mmc_exit(void)
-{
- platform_driver_unregister(&jz_mmc_driver);
-}
-
-module_init(jz_mmc_init);
-module_exit(jz_mmc_exit);
-
-MODULE_DESCRIPTION("JZ47XX SD/Multimedia Card Interface Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/jz4750_mmc.h b/drivers/mmc/host/jz4750_mmc.h
deleted file mode 100644
index 8577db68220..00000000000
--- a/drivers/mmc/host/jz4750_mmc.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef __JZ4750_MMC_H__
-#define __JZ4750_MMC_H__
-
-#define MMC_CLOCK_SLOW 400000 /* 400 kHz for initial setup */
-#define MMC_CLOCK_FAST 20000000 /* 20 MHz for maximum for normal operation */
-#define SD_CLOCK_FAST 24000000 /* 24 MHz for SD Cards */
-#define SD_CLOCK_HIGH 24000000 /* 24 MHz for SD Cards */
-#define MMC_NO_ERROR 0
-
-#define NR_SG 1
-
-#ifdef CONFIG_MSC0_JZ4750
-#define MSC_ID 0
-#define MSC_HOTPLUG_IRQ MSC0_HOTPLUG_IRQ
-#define IRQ_MSC IRQ_MSC0
-#define DMA_ID_MSC_RX DMA_ID_MSC0_RX
-#define DMA_ID_MSC_TX DMA_ID_MSC0_TX
-#define MSC_HOTPLUG_PIN MSC0_HOTPLUG_PIN
-#else
-#define MSC_ID 1
-#define MSC_HOTPLUG_IRQ MSC1_HOTPLUG_IRQ
-#define IRQ_MSC IRQ_MSC1
-#define DMA_ID_MSC_RX DMA_ID_MSC1_RX
-#define DMA_ID_MSC_TX DMA_ID_MSC1_TX
-#define MSC_HOTPLUG_PIN MSC1_HOTPLUG_PIN
-#endif
-
-#define MSC_1BIT_BUS 0
-#define MSC_4BIT_BUS 1
-#define MSC_8BIT_BUS 2
-
-#define SZ_4K 0x00001000
-
-struct jz_mmc_host {
- struct mmc_host *mmc;
- spinlock_t lock;
- struct {
- int len;
- int dir;
- } dma;
- struct {
- int index;
- int offset;
- int len;
- } pio;
- int irq;
- unsigned int clkrt;
- unsigned int cmdat;
- unsigned int imask;
- unsigned int power_mode;
- struct jz_mmc_platform_data *pdata;
- struct mmc_request *mrq;
- struct mmc_command *cmd;
- struct mmc_data *data;
- dma_addr_t sg_dma;
- struct jzsoc_dma_desc *sg_cpu;
- unsigned int dma_len;
- unsigned int dma_dir;
-};
-
-#define MMC_IRQ_MASK() \
-do { \
- REG_MSC_IMASK(MSC_ID) = 0xffff; \
- REG_MSC_IREG(MSC_ID) = 0xffff; \
-} while (0)
-
-typedef struct jzsoc_dma_desc {
- volatile u32 ddadr; /* Points to the next descriptor + flags */
- volatile u32 dsadr; /* DSADR value for the current transfer */
- volatile u32 dtadr; /* DTADR value for the current transfer */
- volatile u32 dcmd; /* DCMD value for the current transfer */
-} jzsoc_dma_desc;
-
-#include <linux/interrupt.h>
-
-struct device;
-struct mmc_host;
-
-struct jz_mmc_platform_data {
- unsigned int ocr_mask; /* available voltages */
- unsigned long detect_delay; /* delay in jiffies before detecting cards after interrupt */
- int (*init)(struct device *, irq_handler_t , void *);
- int (*get_ro)(struct device *);
- void (*setpower)(struct device *, unsigned int);
- void (*exit)(struct device *, void *);
-};
-
-#endif /* __JZ4750_MMC_H__ */
diff --git a/drivers/mmc/host/jzmmc/Makefile b/drivers/mmc/host/jzmmc/Makefile
new file mode 100644
index 00000000000..e6247deb7c3
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for MMC/SD host controller drivers
+#
+
+obj-$(CONFIG_JZ_MSC0) += controller/ jz_mmc_main.o
+obj-$(CONFIG_JZ_MSC1) += controller/ jz_mmc_main.o
diff --git a/drivers/mmc/host/jzmmc/controller/Makefile b/drivers/mmc/host/jzmmc/controller/Makefile
new file mode 100644
index 00000000000..fbeb4e61d5d
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for MMC/SD host controller drivers
+#
+
+obj-$(CONFIG_JZ_MSC0) += msc/ dma/ gpio/ jz_mmc_controller.o
+obj-$(CONFIG_JZ_MSC1) += msc/ dma/ gpio/ jz_mmc_controller.o
diff --git a/drivers/mmc/host/jzmmc/controller/dma/Makefile b/drivers/mmc/host/jzmmc/controller/dma/Makefile
new file mode 100644
index 00000000000..322b1b32804
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/dma/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for MMC/SD host controller drivers
+#
+
+obj-$(CONFIG_JZ_MSC0) += jz_mmc_dma.o
+obj-$(CONFIG_JZ_MSC1) += jz_mmc_dma.o
diff --git a/drivers/mmc/host/jzmmc/controller/dma/jz_mmc_dma.c b/drivers/mmc/host/jzmmc/controller/dma/jz_mmc_dma.c
new file mode 100644
index 00000000000..3edd61df5f8
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/dma/jz_mmc_dma.c
@@ -0,0 +1,241 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/dma/jz_mmc_dma.c
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+
+#include <asm/jzsoc.h>
+#include <asm/jzmmc/jz_mmc_dma.h>
+
+void jz_mmc_start_dma(int chan, unsigned long phyaddr, int count, int mode, int ts)
+{
+ unsigned long flags;
+
+ flags = claim_dma_lock();
+ disable_dma(chan);
+ clear_dma_ff(chan);
+ jz_set_dma_block_size(chan, ts);
+ set_dma_mode(chan, mode);
+ set_dma_addr(chan, phyaddr);
+ set_dma_count(chan, count + (ts - 1));
+ enable_dma(chan);
+ release_dma_lock(flags);
+}
+
+void jz_mmc_send_dma(struct jz_mmc_host *host, int chan, unsigned long srcaddr,
+ unsigned long taraddr, int al_count, int unal_count)
+{
+ unsigned long flags;
+ jz_dma_desc *desc;
+ unsigned int next;
+
+ flags = claim_dma_lock();
+
+ memset(host->ua_desc, 0, 4096);
+
+ next = (host->dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4;
+ desc = host->ua_desc;
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS(DMA_TS) |
+ DMAC_DCMD_LINK;
+ desc->dsadr = srcaddr; /* DMA source address */
+ desc->dtadr = taraddr; /* DMA target address */
+ desc->ddadr = (next << 24) | al_count;
+ desc++;
+ desc->dcmd = DMAC_DCMD_SAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
+ DMAC_DCMD_TIE;
+ desc->dsadr = srcaddr + (al_count * DMA_TS); /* DMA source address */
+ desc->dtadr = taraddr; /* DMA target address */
+ desc->ddadr = unal_count; /* counter */
+
+ dma_cache_wback_inv((unsigned long)desc, 2 * (sizeof(jz_dma_desc)));
+
+ /* Setup DMA descriptor address */
+ REG_DMAC_DDA(chan) = host->dma_desc_phys_addr;
+
+ /* Setup request source */
+ if(host->pdev_id == 0)
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC0OUT;
+ else if(host->pdev_id == 1)
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC1OUT;
+ else
+#ifdef DMAC_DRSR_RS_MSC2OUT
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC2OUT;
+#else
+ ;
+#endif
+
+ /* Setup DMA channel control/status register */
+ REG_DMAC_DCCSR(chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */
+
+ /* Enable DMA */
+ REG_DMAC_DMACR(chan / HALF_DMA_NUM) = DMAC_DMACR_DMAE;
+
+ /* DMA doorbell set -- start DMA now ... */
+ REG_DMAC_DMADBSR(chan / HALF_DMA_NUM) = 1 << chan;
+
+ release_dma_lock(flags);
+}
+
+void jz_mmc_receive_dma(struct jz_mmc_host *host, int chan, unsigned long srcaddr,
+ unsigned long taraddr, int al_count, int unal_count)
+{
+ unsigned long flags;
+ jz_dma_desc *desc;
+ unsigned int next;
+
+ flags = claim_dma_lock();
+
+ memset(host->ua_desc, 0, 4096);
+
+ next = (host->dma_desc_phys_addr + (sizeof(jz_dma_desc))) >> 4;
+ desc = host->ua_desc;
+ desc->dcmd = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS(DMA_TS) |
+ DMAC_DCMD_LINK;
+ desc->dsadr = srcaddr; /* DMA source address */
+ desc->dtadr = taraddr; /* DMA target address */
+ desc->ddadr = (next << 24) | al_count;
+ desc++;
+ desc->dcmd = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BIT |
+ DMAC_DCMD_TIE;
+ desc->dsadr = srcaddr; /* DMA source address */
+ desc->dtadr = taraddr + (al_count * DMA_TS); /* DMA target address */
+ desc->ddadr = unal_count; /* counter */
+
+ dma_cache_wback((unsigned long)desc, 2 * (sizeof(jz_dma_desc)));
+
+ /* Setup DMA descriptor address */
+ REG_DMAC_DDA(chan) = host->dma_desc_phys_addr;
+
+ /* Setup request source */
+ if(host->pdev_id == 0)
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC0IN;
+ else if(host->pdev_id == 1)
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC1IN;
+ else
+#ifdef DMAC_DRSR_RS_MSC2IN
+ REG_DMAC_DRSR(chan) = DMAC_DRSR_RS_MSC2IN;
+#else
+ ;
+#endif
+
+ /* Setup DMA channel control/status register */
+ REG_DMAC_DCCSR(chan) = DMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */
+
+ /* Enable DMA */
+ REG_DMAC_DMACR(chan / HALF_DMA_NUM) = DMAC_DMACR_DMAE;
+
+ /* DMA doorbell set -- start DMA now ... */
+ REG_DMAC_DMADBSR(chan / HALF_DMA_NUM) = 1 << chan;
+
+ release_dma_lock(flags);
+}
+
+static irqreturn_t jz_mmc_dma_rx_callback(int irq, void *devid)
+{
+ struct jz_mmc_host *host = devid;
+ int chan = host->dma.rxchannel;
+
+ disable_dma(chan);
+ if (__dmac_channel_address_error_detected(chan)) {
+ printk("%s: DMAC address error.\n",
+ __FUNCTION__);
+ __dmac_channel_clear_address_error(chan);
+ }
+ if (__dmac_channel_transmit_end_detected(chan)) {
+ __dmac_channel_clear_transmit_end(chan);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t jz_mmc_dma_tx_callback(int irq, void *devid)
+{
+ struct jz_mmc_host *host = devid;
+ unsigned int chan = host->dma.txchannel;
+
+ disable_dma(chan);
+ if (__dmac_channel_address_error_detected(chan)) {
+ printk("%s: DMAC address error.\n",
+ __FUNCTION__);
+ __dmac_channel_clear_address_error(chan);
+ }
+ if (__dmac_channel_transmit_end_detected(chan)) {
+ __dmac_channel_clear_transmit_end(chan);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int jz_mmc_init_dma(struct jz_mmc_host *host)
+{
+ host->dma.rxchannel = -1;
+ host->dma.txchannel = -1;
+
+ if (!host->dmares)
+ return -ENODEV;
+
+ host->dma.rxchannel = jz_request_dma(host->dmares->start, "dma-rx", jz_mmc_dma_rx_callback,
+ 0, host);
+ if (host->dma.rxchannel < 0) {
+ printk(KERN_ERR "jz_request_dma failed for MMC Rx\n");
+ goto err1;
+ }
+
+ if (host->dma.rxchannel < 6)
+ REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC;
+ else
+ REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC;
+
+ /* Request MMC Tx DMA channel */
+ host->dma.txchannel = jz_request_dma(host->dmares->end, "dma-tx", jz_mmc_dma_tx_callback,
+ 0, host);
+ if (host->dma.txchannel < 0) {
+ printk(KERN_ERR "jz_request_dma failed for MMC Tx\n");
+ goto err2;
+ }
+
+ if (host->dma.txchannel < 6)
+ REG_DMAC_DMACR(0) |= DMAC_DMACR_FMSC;
+ else
+ REG_DMAC_DMACR(1) |= DMAC_DMACR_FMSC;
+
+ host->dma_buf = (unsigned int *)__get_free_page(GFP_KERNEL);
+
+ /* setup descriptor */
+ host->ua_desc = (jz_dma_desc *)__get_free_page(GFP_KERNEL);
+ host->dma_desc_phys_addr = CPHYSADDR((unsigned long)host->ua_desc);
+
+ memset(host->ua_desc, 0, 4096);
+ dma_cache_wback_inv((unsigned long)host->ua_desc, 4096);
+
+ return 0;
+
+err2:
+ jz_free_dma(host->dma.rxchannel);
+err1:
+ return -ENODEV;
+}
+
+static void jz_mmc_deinit_dma(struct jz_mmc_host *host)
+{
+ free_page((unsigned long)host->ua_desc);
+ free_page((unsigned long)host->dma_buf);
+ jz_free_dma(host->dma.rxchannel);
+ jz_free_dma(host->dma.txchannel);
+}
+
+int jz_mmc_dma_register(struct jz_mmc_dma *dma)
+{
+ if(dma == NULL)
+ return -ENOMEM;
+
+ dma->init = jz_mmc_init_dma;
+ dma->deinit = jz_mmc_deinit_dma;
+
+ return 0;
+}
diff --git a/drivers/mmc/host/jzmmc/controller/gpio/Makefile b/drivers/mmc/host/jzmmc/controller/gpio/Makefile
new file mode 100644
index 00000000000..469757cc539
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/gpio/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for MMC/SD host controller drivers
+#
+
+obj-$(CONFIG_JZ_MSC0) += jz_mmc_gpio.o
+obj-$(CONFIG_JZ_MSC1) += jz_mmc_gpio.o
diff --git a/drivers/mmc/host/jzmmc/controller/gpio/jz_mmc_gpio.c b/drivers/mmc/host/jzmmc/controller/gpio/jz_mmc_gpio.c
new file mode 100644
index 00000000000..6abab079abd
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/gpio/jz_mmc_gpio.c
@@ -0,0 +1,183 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/gpio/jz_mmc_gpio.c
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <asm/jzmmc/jz_mmc_gpio.h>
+
+#define TRY_TIME 10
+#define RETRY_TIME 50
+//#define CARD_REINSERT_DURATTION (5 * HZ)
+//static unsigned long msmsdcc_irqtime = 0;
+
+#if 0
+static irqreturn_t jz_mmc_detect_irq(int irq, void *devid)
+{
+ struct jz_mmc_host *host = (struct jz_mmc_host *) devid;
+
+ printk("jz-mmc: card detect interrupt raised!!! check status......\n");
+
+ if (!host->plat->status) {
+ mmc_detect_change(host->mmc, 50);
+ return IRQ_HANDLED;
+ }
+
+ if (host->plat->status(mmc_dev(host->mmc))) { /* card detected */
+ host->eject = 0;
+ host->plat->plug_change(CARD_INSERTED);
+ } else {
+ host->eject = 1;
+ host->plat->plug_change(CARD_REMOVED);
+ }
+
+ if (host->eject ^ host->oldstat) {
+ mmc_detect_change(host->mmc, 50);
+ }
+
+ host->oldstat = host->eject;
+
+ return IRQ_HANDLED;
+}
+#else
+static void jiq_de_quiver(struct work_struct *ptr){
+ struct jz_mmc_host *host = container_of(ptr, struct jz_mmc_host, gpio_jiq_work);
+ unsigned int time_to_try, i, tmp, counter = 0, result = 1;
+ unsigned long duration;
+
+ if (!host->plat->status) {
+ mmc_detect_change(host->mmc, 0);
+ return;
+ }
+
+ for (time_to_try = 0; time_to_try < RETRY_TIME; time_to_try++) {
+ for (i = 0; i < TRY_TIME; i++) {
+ tmp = (!host->plat->status(mmc_dev(host->mmc))); // tmp = 1 means slot is empty
+ result &= tmp;
+ if( !tmp )
+ counter++;
+ schedule_timeout((10*HZ)/1000);
+ }
+
+ if ( !result ) {
+ // The card is there
+ if (counter == TRY_TIME) {
+ printk("Stable the card is there\n");
+ host->eject = 0;
+ /* wait for card removal */
+ host->plat->plug_change(CARD_INSERTED);
+ enable_irq(host->plat->status_irq);
+
+ goto stable;
+ }
+ /* try again, goto for */
+ counter = 0;
+ result = 1;
+ } else {
+ printk("Stable the slot is empty\n");
+ host->eject = 1;
+ /* wait for card insertion */
+ host->plat->plug_change(CARD_REMOVED);
+ enable_irq(host->plat->status_irq);
+ goto stable;
+ }
+ }
+
+stable:
+ if (host->eject ^ host->oldstat) {
+ /* Delay the process for Card re-insert */
+ //duration = jiffies - msmsdcc_irqtime;
+
+ //if ((!(host->eject)) && (duration < CARD_REINSERT_DURATTION)) {
+ // duration = CARD_REINSERT_DURATTION - duration;
+ //} else {
+ // duration = 0;
+ //}
+
+ mmc_detect_change(host->mmc, 50);
+ //msmsdcc_irqtime = jiffies;
+ if (host->eject)
+ wake_up_interruptible(&host->msc_wait_queue);
+ }
+
+ host->oldstat = host->eject;
+}
+
+static irqreturn_t jz_mmc_detect_irq(int irq, void *devid)
+{
+ struct jz_mmc_host *host = (struct jz_mmc_host *) devid;
+
+ printk("jz-msc%d: detect card......\n", host->pdev_id);
+ disable_irq_nosync(host->plat->status_irq);
+
+ schedule_work( &(((struct jz_mmc_host *) devid)->gpio_jiq_work) );
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int jz_mmc_gpio_init(struct jz_mmc_host *host, struct platform_device *pdev)
+{
+ int ret = 0;
+
+ /*
+ * Setup card detect change
+ */
+ if (host->plat->status_irq) {
+ ret = request_irq(host->plat->status_irq,
+ jz_mmc_detect_irq,
+ 0,
+ "jz-msc (gpio)",
+ host);
+ if (ret) {
+ printk(KERN_ERR "Unable to get slot IRQ %d (%d)\n",
+ host->plat->status_irq, ret);
+ return ret;
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
+
+#if 1
+ INIT_WORK(&(host->gpio_jiq_work), jiq_de_quiver);
+#endif
+
+ // Check if there were any card present
+ if (host->plat->status) {
+ host->eject = !(host->plat->status(mmc_dev(host->mmc)));
+ host->oldstat = host->eject;
+
+ if(host->eject) {
+ host->plat->plug_change(CARD_REMOVED);
+ } else {
+ host->plat->plug_change(CARD_INSERTED);
+ }
+ }
+ } else
+ printk(KERN_ERR "%s: No card detect facilities available\n",
+ mmc_hostname(host->mmc));
+
+ return 0;
+}
+
+static void jz_mmc_gpio_deinit(struct jz_mmc_host *host, struct platform_device *pdev)
+{
+ if(host->plat->status_irq) {
+ free_irq(host->plat->status_irq, &host);
+ device_init_wakeup(&pdev->dev, 0);
+ }
+}
+
+int jz_mmc_gpio_register(struct jz_mmc_gpio *gpio)
+{
+ if(gpio == NULL)
+ return -ENOMEM;
+
+ gpio->init = jz_mmc_gpio_init;
+ gpio->deinit = jz_mmc_gpio_deinit;
+
+ return 0;
+}
diff --git a/drivers/mmc/host/jzmmc/controller/jz_mmc_controller.c b/drivers/mmc/host/jzmmc/controller/jz_mmc_controller.c
new file mode 100644
index 00000000000..8db9ee999a9
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/jz_mmc_controller.c
@@ -0,0 +1,126 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/controller/jz_mmc_controller.c
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <linux/scatterlist.h>
+
+#include <asm/jzsoc.h>
+#include <asm/jzmmc/jz_mmc_msc.h>
+#include <asm/jzmmc/jz_mmc_controller.h>
+
+
+#ifdef USE_DMA
+
+static int data_transmit_dma(struct jz_mmc_host *host)
+{
+ jz_mmc_data_start(host);
+
+ return 0;
+}
+
+#else
+
+static int jz_mmc_prepare_data(struct jz_mmc_host *host)
+{
+ struct mmc_data *data = host->curr.data;
+ int datalen = data->blocks * data->blksz;
+
+ host->dma.dir = DMA_BIDIRECTIONAL;
+ host->dma.len = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, host->dma.dir);
+
+ if (host->dma.len == 0)
+ return -ETIMEDOUT;
+
+ host->pio.index = 0;
+ host->pio.offset = 0;
+ host->pio.len = datalen;
+ return 0;
+}
+
+static int data_transmit_cpu(struct jz_mmc_host *host)
+{
+ jz_mmc_prepare_data(host);
+
+ return 0;
+}
+#endif
+
+static int controller_init(struct jz_mmc_controller *controller, struct jz_mmc_host *host,
+ struct platform_device *pdev)
+{
+ int ret = 0;
+
+ ret = controller->msc.init(host);
+ if(ret) {
+ return ret;
+ }
+
+ ret = controller->gpio.init(host, pdev);
+ if(ret) {
+ goto gpio_failed;
+ }
+
+ ret = controller->dma.init(host);
+ if(ret) {
+ goto dma_failed;
+ }
+
+ return 0;
+
+dma_failed:
+ controller->gpio.deinit(host, pdev);
+gpio_failed:
+ controller->msc.deinit(host);
+ return ret;
+}
+
+static void controller_deinit(struct jz_mmc_host *host, struct platform_device *pdev)
+{
+ struct jz_mmc_functions *functions = host->plat->driver_data;
+
+ functions->gpio_deinit(host, pdev);
+ functions->msc_deinit(host);
+ functions->dma_deinit(host);
+}
+
+int controller_register(struct jz_mmc_controller *controller, struct jz_mmc_host *host)
+{
+ if(controller == NULL)
+ return -ENOMEM;
+
+ jz_mmc_gpio_register(&(controller->gpio));
+ jz_mmc_msc_register(&(controller->msc));
+ jz_mmc_dma_register(&(controller->dma));
+
+ controller->init = controller_init;
+ controller->functions.deinit = controller_deinit;
+#ifdef USE_DMA
+ controller->functions.transmit_data = data_transmit_dma;
+#else
+ controller->functions.transmit_data = data_transmit_cpu;
+#endif
+
+ controller->functions.execute_cmd = controller->msc.execute_cmd;
+ controller->functions.set_clock = controller->msc.set_clock;
+ controller->functions.msc_deinit = controller->msc.deinit;
+ controller->functions.gpio_deinit = controller->gpio.deinit;
+ controller->functions.dma_deinit = controller->dma.deinit;
+
+ host->plat->driver_data = &(controller->functions);
+
+ struct jz_mmc_functions *functions = host->plat->driver_data;
+
+// printk("%s: host->plat->driver_data->set_clock = %x\n", __FUNCTION__, functions->set_clock);
+
+ return 0;
+}
diff --git a/drivers/mmc/host/jzmmc/controller/msc/Makefile b/drivers/mmc/host/jzmmc/controller/msc/Makefile
new file mode 100644
index 00000000000..2538c469be5
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/msc/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for MMC/SD host controller drivers
+#
+
+obj-$(CONFIG_JZ_MSC0) += jz_mmc_msc.o
+obj-$(CONFIG_JZ_MSC1) += jz_mmc_msc.o
diff --git a/drivers/mmc/host/jzmmc/controller/msc/jz_mmc_msc.c b/drivers/mmc/host/jzmmc/controller/msc/jz_mmc_msc.c
new file mode 100644
index 00000000000..fbdfd3862cd
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/controller/msc/jz_mmc_msc.c
@@ -0,0 +1,836 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/msc/jz_mmc_msc.c
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/semaphore.h>
+#include <linux/kthread.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/sdio.h>
+#include <linux/scatterlist.h>
+
+#include <asm/jzsoc.h>
+#include <asm/jzmmc/jz_mmc_msc.h>
+
+#define MSC_STAT_ERR_BITS 0x3f
+
+#if 0
+#define TRACE_CMD_NUM MMC_SWITCH
+#define TRACE_CMD_REQ() \
+ ({ \
+ if ( (TRACE_CMD_NUM == -1) || (TRACE_CMD_NUM == cmd->opcode) ) \
+ printk("execute_cmd: opcode = %d cmdat = %#0x arg = %#0x data_flags = %#0x\n", \
+ cmd->opcode, cmdat, cmdarg, \
+ host->curr.data ? host->curr.data->flags : 0); \
+ })
+
+#define TRACE_CMD_RES() \
+ ({ \
+ if ( (TRACE_CMD_NUM == -1) || (TRACE_CMD_NUM == cmd->opcode) ) \
+ printk("cmd done: r_type = %d resp[0] = %#0x err = %d state = %#0x\n", \
+ host->curr.r_type, cmd->resp[0], cmd->error, \
+ REG_MSC_STAT(host->pdev_id)); \
+ })
+#else
+#define TRACE_CMD_REQ() do { } while(0)
+#define TRACE_CMD_RES() do { } while(0)
+#endif
+
+void jz_mmc_set_clock(struct jz_mmc_host *host, int rate);
+static int jz_mmc_data_done(struct jz_mmc_host *host);
+
+static void msc_irq_mask_all(int msc_id)
+{
+ REG_MSC_IMASK(msc_id) = 0xffff;
+ REG_MSC_IREG(msc_id) = 0xffff;
+}
+
+static void jz_mmc_reset(struct jz_mmc_host *host)
+{
+ REG_MSC_STRPCL(host->pdev_id) = MSC_STRPCL_RESET;
+ while (REG_MSC_STAT(host->pdev_id) & MSC_STAT_IS_RESETTING);
+}
+
+static inline int msc_calc_clkrt(int is_low, u32 rate)
+{
+ u32 clkrt;
+ u32 clk_src = is_low ? 24000000 : 48000000;
+
+ clkrt = 0;
+ while (rate < clk_src) {
+ clkrt++;
+ clk_src >>= 1;
+ }
+ return clkrt;
+}
+
+void jz_mmc_set_clock(struct jz_mmc_host *host, int rate)
+{
+ int clkrt;
+
+ /* __cpm_select_msc_clk_high will select 48M clock for MMC/SD card
+ * perhaps this will made some card with bad quality init fail,or
+ * bad stabilization.
+ */
+
+ // Cause there is only ONE devider in CPM, the clock must only <= 24MHz
+#ifndef CONFIG_SOC_JZ4750
+#if 0
+ if (rate > SD_CLOCK_FAST) {
+ cpm_set_clock(CGU_MSCCLK, 48 * 1000 * 1000);
+ clkrt = msc_calc_clkrt(0, rate);
+ } else {
+ cpm_set_clock(CGU_MSCCLK, 24 * 1000 * 1000);
+ clkrt = msc_calc_clkrt(1, rate);
+ }
+#else
+ if (rate > SD_CLOCK_FAST) {
+ rate = SD_CLOCK_FAST;
+ cpm_set_clock(CGU_MSCCLK, 24 * 1000 * 1000);
+ clkrt = msc_calc_clkrt(1, rate);
+ } else {
+ cpm_set_clock(CGU_MSCCLK, 24 * 1000 * 1000);
+ clkrt = msc_calc_clkrt(1, rate);
+ }
+#endif
+ REG_MSC_CLKRT(host->pdev_id) = clkrt;
+#else
+ /* __cpm_select_msc_clk_high will select 48M clock for MMC/SD card
+ * perhaps this will made some card with bad quality init fail,or
+ * bad stabilization.
+ */
+ if (rate > SD_CLOCK_FAST) {
+ rate = SD_CLOCK_FAST;
+ __cpm_select_msc_clk_high(host->pdev_id,1); /* select clock source from CPM */
+
+ // __cpm_select_msc_clk(host->pdev_id,1); /* select clock source from CPM */
+ clkrt = msc_calc_clkrt(0, rate);
+ } else {
+ __cpm_select_msc_clk(host->pdev_id,1); /* select clock source from CPM */
+ clkrt = msc_calc_clkrt(1, rate);
+ }
+
+ // printk("clock rate = %d\n", __cpm_get_mscclk(0));
+ REG_MSC_CLKRT(host->pdev_id) = clkrt;
+#endif
+}
+
+static void jz_mmc_enable_irq(struct jz_mmc_host *host, unsigned int mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->imask &= ~mask;
+ REG_MSC_IMASK(host->pdev_id) = host->imask;
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void jz_mmc_disable_irq(struct jz_mmc_host *host, unsigned int mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ host->imask |= mask;
+ REG_MSC_IMASK(host->pdev_id) = host->imask;
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void jz_mmc_finish_request(struct jz_mmc_host *host, struct mmc_request *mrq)
+{
+ host->curr.mrq = NULL;
+ host->curr.cmd = NULL;
+ host->curr.data = NULL;
+ mmc_request_done(host->mmc, mrq);
+}
+
+static int jz_mmc_cmd_done(struct jz_mmc_host *host, unsigned int stat)
+{
+ struct mmc_command *cmd = host->curr.cmd;
+ int i, temp[16] = {0};
+ unsigned char *buf;
+ unsigned int data, v, w1, w2;
+
+ if (!cmd)
+ return 0;
+
+ host->curr.cmd = NULL;
+ buf = (u8 *) temp;
+ switch (host->curr.r_type) {
+ case 1:
+ {
+ /*
+ * Did I mention this is Sick. We always need to
+ * discard the upper 8 bits of the first 16-bit word.
+ */
+
+ data = REG_MSC_RES(host->pdev_id);
+ buf[0] = (data >> 8) & 0xff;
+ buf[1] = data & 0xff;
+
+ data = REG_MSC_RES(host->pdev_id);
+ buf[2] = (data >> 8) & 0xff;
+ buf[3] = data & 0xff;
+
+ data = REG_MSC_RES(host->pdev_id);
+ buf[4] = data & 0xff;
+
+ cmd->resp[0] =
+ buf[1] << 24 | buf[2] << 16 | buf[3] << 8 |
+ buf[4];
+
+ // printk("opcode = %d, cmd->resp = 0x%08x\n", cmd->opcode, cmd->resp[0]);
+ break;
+ }
+ case 2:
+ {
+ data = REG_MSC_RES(host->pdev_id);
+ v = data & 0xffff;
+ for (i = 0; i < 4; i++) {
+ data = REG_MSC_RES(host->pdev_id);
+ w1 = data & 0xffff;
+ data = REG_MSC_RES(host->pdev_id);
+ w2 = data & 0xffff;
+ cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8;
+ v = w2;
+ }
+ break;
+ }
+ case 0:
+ break;
+ }
+ if (stat & MSC_STAT_TIME_OUT_RES) {
+ /* :-( our customer do not want to see SO MANY timeouts :-(
+ so only CMD5 can return timeout error!!! */
+
+ /*
+ * Note: we can not return timeout when CMD SD_SWITCH or MMC_SWITCH
+ * because we declared that out host->caps support MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA and MMC_CAP_MMC_HIGHSPEED
+ * if in the future some error occured because of this, we must add some code to remember
+ * which mode(SDIO/SD/MMC) the MSC is in
+ */
+ switch(cmd->opcode) {
+ case SD_IO_SEND_OP_COND:
+ //case SD_SWITCH:
+ //case MMC_SWITCH:
+ case SD_SEND_IF_COND:
+ case MMC_APP_CMD:
+ cmd->error = -ETIMEDOUT;
+ break;
+ default:
+ printk("jz-msc%d: ignored MSC_STAT_TIME_OUT_RES, cmd=%d\n", host->pdev_id, cmd->opcode);
+ }
+ } else if (stat & MSC_STAT_CRC_RES_ERR && cmd->flags & MMC_RSP_CRC) {
+ printk("jz-msc%d: MSC_STAT_CRC, cmd=%d\n", host->pdev_id, cmd->opcode);
+ if (cmd->opcode == MMC_ALL_SEND_CID ||
+ cmd->opcode == MMC_SEND_CSD ||
+ cmd->opcode == MMC_SEND_CID) {
+ /* a bogus CRC error can appear if the msb of
+ the 15 byte response is a one */
+ if ((cmd->resp[0] & 0x80000000) == 0)
+ cmd->error = -EILSEQ;
+ }
+ }
+
+ TRACE_CMD_RES();
+
+ if (host->curr.data && cmd->error == 0){
+ jz_mmc_enable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
+ } else {
+ jz_mmc_finish_request(host, host->curr.mrq);
+ }
+
+ return 1;
+}
+
+#ifdef USE_DMA
+void jz_mmc_data_start(struct jz_mmc_host *host)
+{
+ struct mmc_data *data = host->curr.data;
+ unsigned int nob = data->blocks;
+ unsigned int block_size = data->blksz;
+ //unsigned int *buf = 0;
+ //int count;
+ int unaligned_front, unaligned_behind, tail;
+ int channel;
+ int mode, i;
+
+ if (data->flags & MMC_DATA_WRITE) {
+ channel = host->dma.txchannel;
+ mode = DMA_MODE_WRITE;
+ host->dma.dir = DMA_TO_DEVICE;
+ } else {
+ channel = host->dma.rxchannel;
+ mode = DMA_MODE_READ;
+ host->dma.dir = DMA_FROM_DEVICE;
+ }
+
+ if (data->flags & MMC_DATA_STREAM)
+ nob = 0xffff;
+
+ REG_MSC_NOB(host->pdev_id) = nob;
+ REG_MSC_BLKLEN(host->pdev_id) = block_size;
+
+ host->dma.len =
+ dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+ host->dma.dir);
+
+ for (i = 0; i < host->dma.len; i++) {
+ host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
+ host->sg_cpu[i].dcmd = sg_dma_len(&data->sg[i]);
+
+ unaligned_front = host->sg_cpu[i].dtadr & (DMA_TS - 1); // bytes
+ unaligned_behind = (host->sg_cpu[i].dtadr + host->sg_cpu[i].dcmd) & (DMA_TS - 1); // byte
+
+ if((int)(host->sg_cpu[i].dcmd - unaligned_front) > DMA_TS) {
+
+
+ if(unaligned_front == 0 && unaligned_behind == 0) {
+
+ /*
+ dma_cache_wback_inv((unsigned long)
+ CKSEG0ADDR(sg_dma_address(data->sg)) +
+ data->sg->offset,
+ host->sg_cpu[i].dcmd);
+ */
+ dma_cache_wback_inv((unsigned long)CKSEG0ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+
+ jz_mmc_start_dma(channel, host->sg_cpu[i].dtadr,
+ host->sg_cpu[i].dcmd, mode, DMA_TS);
+
+ host->flag_cp = 0;
+
+ } else {
+ /*
+ printk("%s: addr unaligned\n", __FUNCTION__);
+ printk("host->sg_cpu[i].dtadr = %x\n", host->sg_cpu[i].dtadr);
+ printk("host->sg_cpu[i].dcmd = %d\n", host->sg_cpu[i].dcmd);
+ printk("unaligned_front = %d\n", unaligned_front);
+ printk("unaligned_behind = %d\n", unaligned_behind);
+ */
+
+ memset(host->dma_buf, 0, 4096);
+ tail = host->sg_cpu[i].dcmd % DMA_TS;
+
+ if(tail) {
+ if(mode == DMA_MODE_READ) {
+
+ dma_cache_inv((unsigned long)host->dma_buf, host->sg_cpu[i].dcmd);
+
+ jz_mmc_receive_dma(host, channel, CPHYSADDR(MSC_RXFIFO(host->pdev_id)),
+ CPHYSADDR(host->dma_buf), host->sg_cpu[i].dcmd / DMA_TS,
+ (tail + 3) / 4);
+
+ host->flag_cp = 1;
+
+/*
+ dma_cache_inv((unsigned long)CKSEG0ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+ jz_mmc_start_dma(channel, host->sg_cpu[i].dtadr, host->sg_cpu[i].dcmd,
+ mode, 4);
+
+ host->flag_cp = 0;
+*/
+
+ } else {
+
+ memcpy(host->dma_buf, (void *)CKSEG0ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+
+ dma_cache_wback_inv((unsigned long)host->dma_buf, host->sg_cpu[i].dcmd);
+
+ jz_mmc_send_dma(host, channel, CPHYSADDR(host->dma_buf),
+ CPHYSADDR(MSC_TXFIFO(host->pdev_id)),
+ host->sg_cpu[i].dcmd / DMA_TS, (tail + 3) / 4);
+/*
+ dma_cache_wback_inv((unsigned long)CKSEG0ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+ jz_mmc_start_dma(channel, host->sg_cpu[i].dtadr, host->sg_cpu[i].dcmd,
+ mode, 4);
+*/
+ host->flag_cp = 0;
+ }
+ } else {
+ if(mode == DMA_MODE_READ) {
+/*
+ printk("host->sg_cpu[i].dtadr = %x\n", host->sg_cpu[i].dtadr);
+ printk("unaligned_front = %d\n", unaligned_front);
+ printk("unaligned_behind = %d\n", unaligned_behind);
+ printk("host->sg_cpu[i].dcmd = %d\n", host->sg_cpu[i].dcmd);
+*/
+ dma_cache_inv((unsigned long)host->dma_buf, host->sg_cpu[i].dcmd);
+
+ jz_mmc_start_dma(channel, CPHYSADDR(host->dma_buf), host->sg_cpu[i].dcmd,
+ mode, DMA_TS);
+
+ host->flag_cp = 1;
+
+ } else {
+ memcpy(host->dma_buf, (void *)CKSEG1ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+
+ dma_cache_wback_inv((unsigned long)host->dma_buf, host->sg_cpu[i].dcmd);
+
+ jz_mmc_start_dma(channel, CPHYSADDR(host->dma_buf), host->sg_cpu[i].dcmd,
+ mode, DMA_TS);
+
+ host->flag_cp = 0;
+ }
+ }
+
+ }
+ } else {
+
+ if(mode == DMA_MODE_READ) {
+ dma_cache_inv((unsigned long)CKSEG0ADDR(host->sg_cpu[i].dtadr), host->sg_cpu[i].dcmd);
+ jz_mmc_start_dma(channel, host->sg_cpu[i].dtadr, host->sg_cpu[i].dcmd, mode, 4);
+
+ host->flag_cp = 0;
+ } else {
+ memset(host->dma_buf, 0, 4096);
+ memcpy(host->dma_buf, (void *)CKSEG1ADDR(host->sg_cpu[i].dtadr),
+ host->sg_cpu[i].dcmd);
+
+ dma_cache_wback_inv((unsigned long)host->dma_buf, host->sg_cpu[i].dcmd);
+
+ jz_mmc_start_dma(channel, CPHYSADDR(host->dma_buf), host->sg_cpu[i].dcmd, mode, 4);
+
+ host->flag_cp = 0;
+ }
+ }
+ }
+}
+#else
+
+static void jz_mmc_receive_pio(struct jz_mmc_host *host)
+{
+ struct mmc_data *data = host->curr.data;
+ int sg_len = 0, max = 0, count = 0;
+ unsigned int *buf = 0;
+ struct scatterlist *sg;
+ unsigned int nob;
+
+ nob = data->blocks;
+
+ REG_MSC_NOB(host->pdev_id) = nob;
+ REG_MSC_BLKLEN(host->pdev_id) = data->blksz;
+
+ max = host->pio.len;
+ if (host->pio.index < host->dma.len) {
+ sg = &data->sg[host->pio.index];
+ buf = sg_virt(sg) + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
+ /* Check to if we need less then the size of the sg_buffer */
+ if (sg_len < max) max = sg_len;
+ }
+
+ max = max / 4;
+ for(count = 0; count < max; count++) {
+ while (REG_MSC_STAT(host->pdev_id) & MSC_STAT_DATA_FIFO_EMPTY)
+ ;
+ *buf++ = REG_MSC_RXFIFO(host->pdev_id);
+ }
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (sg_len && count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+}
+
+static void jz_mmc_send_pio(struct jz_mmc_host *host)
+{
+ int sg_len, max, count = 0;
+ unsigned int *wbuf = 0;
+ unsigned int nob;
+ struct mmc_data *data = host->curr.data;
+ struct scatterlist *sg;
+
+ nob = data->blocks;
+
+ REG_MSC_NOB(host->pdev_id) = nob;
+ REG_MSC_BLKLEN(host->pdev_id) = data->blksz;
+
+ /* This is the pointer to the data buffer */
+ sg = &data->sg[host->pio.index];
+ wbuf = sg_virt(sg) + host->pio.offset;
+
+ /* This is the space left inside the buffer */
+ sg_len = data->sg[host->pio.index].length - host->pio.offset;
+
+ /* Check to if we need less then the size of the sg_buffer */
+ max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
+ max = max / 4;
+ for(count = 0; count < max; count++) {
+ while (REG_MSC_STAT(host->pdev_id) & MSC_STAT_DATA_FIFO_FULL)
+ ;
+ REG_MSC_TXFIFO(host->pdev_id) = *wbuf++;
+ }
+
+ host->pio.len -= count;
+ host->pio.offset += count;
+
+ if (count == sg_len) {
+ host->pio.index++;
+ host->pio.offset = 0;
+ }
+}
+
+#endif
+
+static void jz_mmc_execute_cmd(struct jz_mmc_host *host, struct mmc_command *cmd, unsigned int cmdat)
+{
+ u32 timeout = 0x7fffff;
+ unsigned int stat;
+ int err;
+ unsigned int stat_err_bits = 0;
+ u32 cmdarg = 0;
+
+ WARN_ON(host->curr.cmd != NULL);
+ host->curr.cmd = cmd;
+
+ /* mask interrupts */
+ REG_MSC_IMASK(host->pdev_id) = 0xffff;
+
+ /* clear status */
+ REG_MSC_IREG(host->pdev_id) = 0xffff;
+
+ if (cmd->flags & MMC_RSP_BUSY)
+ cmdat |= MSC_CMDAT_BUSY;
+
+ switch (RSP_TYPE(mmc_resp_type(cmd))) {
+ case RSP_TYPE(MMC_RSP_R1): // r1, r1b, r5, r6, r7
+ cmdat |= MSC_CMDAT_RESPONSE_R1;
+ host->curr.r_type = 1;
+ break;
+ case RSP_TYPE(MMC_RSP_R3): // r3, r4
+ cmdat |= MSC_CMDAT_RESPONSE_R3;
+ host->curr.r_type = 1;
+ break;
+ case RSP_TYPE(MMC_RSP_R2): // r2
+ cmdat |= MSC_CMDAT_RESPONSE_R2;
+ host->curr.r_type = 2;
+ break;
+ default:
+ break;
+ }
+
+ REG_MSC_CMD(host->pdev_id) = cmd->opcode;
+
+ cmdarg = cmd->arg;
+
+ /* Set argument */
+ if(host->plat->bus_width == 1) {
+ if (cmd->opcode == 6) {
+ /* set 1 bit sd card bus*/
+ if (cmd->arg == 2) {
+ cmdarg = 0;
+ REG_MSC_ARG(host->pdev_id) = 0;
+ }
+
+ /* set 1 bit mmc card bus*/
+ if (cmd->arg == 0x3b70101) {
+ cmdarg = 0x3b70001;
+ REG_MSC_ARG(host->pdev_id) = 0x3b70001;
+ }
+ } else
+ REG_MSC_ARG(host->pdev_id) = cmd->arg;
+ } else if(host->plat->bus_width == 8) {
+ if (cmd->opcode == 6) {
+ /* set 8 bit mmc card bus*/
+ if (cmd->arg == 0x3b70101) {
+ cmdarg = 0x3b70201;
+ REG_MSC_ARG(host->pdev_id) = 0x3b70201;
+ } else
+ REG_MSC_ARG(host->pdev_id) = cmd->arg;
+ } else
+ REG_MSC_ARG(host->pdev_id) = cmd->arg;
+ } else
+ REG_MSC_ARG(host->pdev_id) = cmd->arg;
+
+ /* Set command */
+ REG_MSC_CMDAT(host->pdev_id) = cmdat;
+
+ TRACE_CMD_REQ();
+
+ /* Send command */
+ REG_MSC_STRPCL(host->pdev_id) = MSC_STRPCL_START_OP;
+
+ while (timeout-- && !((stat = REG_MSC_STAT(host->pdev_id)) & MSC_STAT_END_CMD_RES))
+ ;
+
+ stat_err_bits = stat & MSC_STAT_ERR_BITS;
+
+ if (timeout == 0)
+ printk("wait END_CMD_RES failed!!!\n");
+
+
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_END_CMD_RES; /* clear irq flag */
+
+ if (cmd->flags & MMC_RSP_BUSY) {
+ timeout = 0x7fffff;
+ while (timeout-- && !(REG_MSC_IREG(host->pdev_id) & MSC_IREG_PRG_DONE))
+ ;
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_PRG_DONE; /* clear status */
+ } else {
+ switch(cmd->opcode) { /* R1b cmds need wait PROG_DONE */
+ case 7:
+ case 12:
+ case 28:
+ case 29:
+ case 38:
+ timeout = 0x7fffff;
+ while (timeout-- && !(REG_MSC_IREG(host->pdev_id) & MSC_IREG_PRG_DONE))
+ ;
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_PRG_DONE; /* clear status */
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+
+ if (SD_IO_SEND_OP_COND == cmd->opcode) {
+ if(host->plat->support_sdio == 0) {
+ cmd->error = -ETIMEDOUT;
+ jz_mmc_finish_request(host, host->curr.mrq);
+ return;
+ }
+ }
+
+ //timeout = 0x3fffff;
+ //while ( timeout-- && ((stat = REG_MSC_STAT(host->pdev_id)) & MSC_STAT_CLK_EN))
+ ;
+ //if (timeout == 0)
+ // printk("the clock never stopped!!!\n");
+ //stat |= stat_err_bits;
+ //printk("ireg = %#0x stat = %#0x timeout = %#0x\n", REG_MSC_IREG(host->pdev_id), REG_MSC_STAT(host->pdev_id), timeout);
+ //printk("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
+ //printk("ireg = %#0x stat = %#0x\n", REG_MSC_IREG(host->pdev_id), REG_MSC_STAT(host->pdev_id));
+ //if (MMC_APP_CMD == cmd->opcode)
+ // udelay(100);
+ jz_mmc_cmd_done(host, stat);
+
+#ifdef USE_DMA
+ if (host->curr.data) {
+ if(host->curr.data->flags & MMC_DATA_WRITE)
+ jz_mmc_data_start(host);
+
+ /* in case that the controller never raise interrupt(May be there are some problem, isn't it?), we must finish the request here!!! */
+ //err = wait_event_interruptible(host->msc_wait_queue, ((host->msc_ack) & (!host->eject)));
+ err = wait_event_interruptible_timeout(host->msc_wait_queue, ((host->msc_ack) | host->eject), 2 * HZ);
+ if(err == -ERESTARTSYS) {
+ printk("err == -ERESTARTSYS\n");
+
+ host->curr.mrq->cmd->error = -ENOMEDIUM;
+ jz_mmc_finish_request(host, host->curr.mrq);
+ }
+
+ }
+#else
+
+ if (host->curr.data) {
+ if (host->curr.data->flags & MMC_DATA_READ)
+ jz_mmc_receive_pio(host);
+ else
+ jz_mmc_send_pio(host);
+ }
+#endif
+
+}
+
+static int jz_mmc_data_done(struct jz_mmc_host *host)
+{
+ struct mmc_data *data = host->curr.data;
+ int stat = 0;
+ unsigned int stat_err_bits = 0;
+ u32 timeout = 0x7fffff;
+
+ if (!data)
+ return 0;
+
+ stat = REG_MSC_STAT(host->pdev_id);
+ stat_err_bits = stat & MSC_STAT_ERR_BITS;
+
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_DATA_TRAN_DONE; /* clear status */
+
+ if (host->curr.mrq && (host->curr.mrq->data->flags & MMC_DATA_WRITE)) {
+
+ while (timeout-- && !(REG_MSC_IREG(host->pdev_id) & MSC_IREG_PRG_DONE))
+ ;
+ if (timeout == 0)
+ printk("PRG_DONE not done!!!\n");
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_PRG_DONE; /* clear status */
+ }
+
+#if 1
+ if(host->flag_cp) {
+
+ //memcpy((unsigned long)CKSEG0ADDR(sg_dma_address(data->sg)) +
+ // data->sg->offset, host->dma_buf,
+ // host->sg_cpu[0].dcmd);
+
+ memcpy((void *)CKSEG1ADDR(host->sg_cpu[0].dtadr), host->dma_buf, host->sg_cpu[0].dcmd);
+
+ }
+#endif
+
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma.len,
+ host->dma.dir);
+
+ stat = REG_MSC_STAT(host->pdev_id);
+ stat |= stat_err_bits;
+
+ if (stat & MSC_STAT_TIME_OUT_READ) {
+ printk("MMC/SD/SDIO timeout, MMC_STAT 0x%x opcode = %d data flags = 0x%0x blocks = %d blksz = %d\n",
+ stat,
+ host->curr.mrq? host->curr.mrq->cmd->opcode : -1,
+ data->flags,
+ data->blocks,
+ data->blksz);
+ data->error = -ETIMEDOUT;
+ } else if (stat & (MSC_STAT_CRC_READ_ERROR | MSC_STAT_CRC_WRITE_ERROR)) {
+ printk("jz-msc%d: MMC/SD/SDIO CRC error, MMC_STAT 0x%x, cmd=%d\n",
+ host->pdev_id, stat,
+ host->curr.mrq? host->curr.mrq->cmd->opcode : -1);
+ data->error = -EILSEQ;
+ }
+ /*
+ * There appears to be a hardware design bug here. There seems to
+ * be no way to find out how much data was transferred to the card.
+ * This means that if there was an error on any block, we mark all
+ * data blocks as being in error.
+ */
+ if (data->error == 0)
+ data->bytes_xfered = data->blocks * data->blksz;
+ else
+ data->bytes_xfered = 0;
+
+ jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
+
+ host->curr.data = NULL;
+ if (host->curr.mrq->stop) {
+ jz_mmc_execute_cmd(host, host->curr.mrq->stop, 0);
+ } else {
+ jz_mmc_finish_request(host, host->curr.mrq);
+ }
+
+ return 1;
+}
+
+static void jiq_msc_irq(struct work_struct *ptr)
+{
+ struct jz_mmc_host *host = container_of(ptr, struct jz_mmc_host, msc_jiq_work);
+
+ jz_mmc_data_done(host);
+
+ host->msc_ack = 1;
+ wake_up_interruptible(&host->msc_wait_queue);
+}
+
+
+static irqreturn_t jz_mmc_irq(int irq, void *devid)
+{
+ struct jz_mmc_host *host = devid;
+ unsigned int ireg = 0;
+ int handled = 0;
+
+#if 1
+ ireg = REG_MSC_IREG(host->pdev_id);
+
+ if (ireg) {
+
+ //if(host->curr.data)
+ // handled = 1;
+
+ if (ireg & MSC_IREG_DATA_TRAN_DONE) {
+ //REG_MSC_IREG(host->pdev_id) = MSC_IREG_DATA_TRAN_DONE;
+ jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
+ //schedule_work( &(((struct jz_mmc_host *) devid)->msc_jiq_work) );
+ queue_work(host->msc_work_queue, &(((struct jz_mmc_host *) devid)->msc_jiq_work));
+ //host->msc_ack = 1;
+ //wake_up_interruptible(&host->msc_wait_queue);
+ handled = 1;
+ }
+ }
+
+ return IRQ_RETVAL(handled);
+#endif
+
+#if 0
+ ireg = REG_MSC_IREG(host->pdev_id);
+
+ if (ireg) {
+
+ if (ireg & MSC_IREG_DATA_TRAN_DONE) {
+ REG_MSC_IREG(host->pdev_id) = MSC_IREG_DATA_TRAN_DONE;
+ //while (!(REG_MSC_STAT(host->pdev_id) & MSC_STAT_PRG_DONE)) ;
+ // REG_MSC_IREG(host->pdev_id) = MSC_STAT_PRG_DONE;
+ jz_mmc_disable_irq(host, MSC_IMASK_DATA_TRAN_DONE);
+
+ handled |= jz_mmc_data_done(host);
+
+ host->msc_ack = 1;
+ wake_up_interruptible(&host->msc_wait_queue);
+ }
+ }
+
+ return IRQ_RETVAL(handled);
+#endif
+}
+
+static int jz_mmc_msc_init(struct jz_mmc_host *host)
+{
+ int ret = 0;
+
+ jz_mmc_reset(host);
+ // __msc_start_clk(host->pdev_id);
+ REG_MSC_LPM(host->pdev_id) = 0x1; // Low power mode
+ REG_MSC_RDTO(host->pdev_id) = 0xffff;
+
+ host->msc_ack = 0;
+ init_waitqueue_head(&host->msc_wait_queue);
+
+ msc_irq_mask_all(host->pdev_id);
+
+ ret = request_irq(host->irqres->start, jz_mmc_irq, 0, "jz-msc (msc)", host);
+ if (ret) {
+ printk(KERN_ERR "MMC/SD: can't request MMC/SD IRQ\n");
+ return ret;
+ }
+
+ host->msc_work_queue = create_rt_workqueue("mscworkqueue");
+
+ INIT_WORK(&host->msc_jiq_work, jiq_msc_irq);
+
+ return 0;
+}
+
+static void jz_mmc_msc_deinit(struct jz_mmc_host *host)
+{
+ free_irq(host->irqres->start, &host);
+ destroy_workqueue(host->msc_work_queue);
+}
+
+int jz_mmc_msc_register(struct jz_mmc_msc *msc)
+{
+ if(msc == NULL)
+ return -ENOMEM;
+
+ msc->init = jz_mmc_msc_init;
+ msc->deinit = jz_mmc_msc_deinit;
+ msc->set_clock = jz_mmc_set_clock;
+ msc->execute_cmd = jz_mmc_execute_cmd;
+
+ return 0;
+}
diff --git a/drivers/mmc/host/jzmmc/jz_mmc_main.c b/drivers/mmc/host/jzmmc/jz_mmc_main.c
new file mode 100644
index 00000000000..2c7ecedb4e1
--- /dev/null
+++ b/drivers/mmc/host/jzmmc/jz_mmc_main.c
@@ -0,0 +1,385 @@
+/*
+ * linux/drivers/mmc/host/jz_mmc/jz_mmc_main.c - JZ SD/MMC driver
+ *
+ * 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.
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/pm.h>
+#include <linux/scatterlist.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
+#include <asm/jzsoc.h>
+#include <asm/jzmmc/jz_mmc_host.h>
+#include <asm/jzmmc/jz_mmc_controller.h>
+
+#define NUMBER_OF_CTRL 2
+
+struct jz_mmc_controller controller[NUMBER_OF_CTRL];
+
+static void jz_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct jz_mmc_host *host = mmc_priv(mmc);
+ unsigned int cmdat;
+ struct jz_mmc_functions *functions = host->plat->driver_data;
+
+ cmdat = host->cmdat;
+ host->cmdat &= ~MSC_CMDAT_INIT;
+ host->cmdat &= ~MSC_CMDAT_STREAM_BLOCK;
+
+ if (host->eject) {
+ if (mrq->data && !(mrq->data->flags & MMC_DATA_READ)) {
+ mrq->cmd->error = 0;
+ mrq->data->bytes_xfered = mrq->data->blksz *
+ mrq->data->blocks;
+ } else
+ mrq->cmd->error = -ENOMEDIUM;
+
+ mmc_request_done(mmc, mrq);
+ return;
+ }
+
+ if (host->curr.mrq || host->curr.data || host->curr.cmd) {
+ printk("warning, another request is processing!!!!\n");
+ }
+ host->curr.mrq = mrq;
+ host->curr.data = mrq->data;
+ host->curr.cmd = NULL;
+
+ if(mrq->data) {
+ cmdat &= ~MSC_CMDAT_BUSY;
+
+ if ((mrq->cmd->opcode == 51) | (mrq->cmd->opcode == 8) | (mrq->cmd->opcode == 6)) {
+ cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
+ cmdat |= MSC_CMDAT_BUS_WIDTH_1BIT | MSC_CMDAT_DATA_EN;
+ } else
+ cmdat |= MSC_CMDAT_DATA_EN;
+#ifdef USE_DMA
+ cmdat |= MSC_CMDAT_DMA_EN;
+#endif
+
+ if (mrq->data->flags & MMC_DATA_WRITE)
+ cmdat |= MSC_CMDAT_WRITE;
+
+ if (mrq->data->flags & MMC_DATA_STREAM)
+ cmdat |= MSC_CMDAT_STREAM_BLOCK;
+
+ if (mrq->data->flags & MMC_DATA_READ)
+ functions->transmit_data(host);
+ }
+
+ functions->execute_cmd(host, mrq->cmd, cmdat);
+}
+
+static int jz_mmc_get_ro(struct mmc_host *mmc)
+{
+ struct jz_mmc_host *host = mmc_priv(mmc);
+
+ if(host->plat->write_protect != NULL)
+ return host->plat->write_protect(mmc_dev(host->mmc));
+ else
+ return 0;
+}
+
+static int jz_mmc_get_cd(struct mmc_host *mmc)
+{
+ struct jz_mmc_host *host = mmc_priv(mmc);
+
+ if(host->plat->status != NULL) {
+ return host->plat->status(mmc_dev(host->mmc));
+ }
+ else
+ return 1;
+}
+
+/* set clock and power */
+static void jz_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct jz_mmc_host *host = mmc_priv(mmc);
+ struct jz_mmc_functions *functions = host->plat->driver_data;
+ void *dev;
+
+ if(!functions) {
+// printk("%s: functions is NULL!\n", __FUNCTION__);
+ while(1);
+ }
+
+ if (ios->clock) {
+ functions->set_clock(host, ios->clock);
+ }
+
+ switch(ios->power_mode) {
+ case MMC_POWER_ON:
+ host->plat->power_on((struct device *)dev);
+ host->cmdat |= CMDAT_INIT;
+ break;
+ case MMC_POWER_OFF:
+ host->plat->power_off((struct device *)dev);
+ break;
+ default:
+ break;
+ }
+
+ if (ios->bus_width == MMC_BUS_WIDTH_4) {
+
+ host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
+
+ if(host->plat->bus_width == 4)
+ host->cmdat |= MSC_CMDAT_BUS_WIDTH_4BIT;
+ else
+ host->cmdat |= host->plat->bus_width;
+ } else if (ios->bus_width == MMC_BUS_WIDTH_8) {
+
+ host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_MASK;
+
+ if(host->plat->bus_width == 8)
+ host->cmdat |= MSC_CMDAT_BUS_WIDTH_8BIT;
+// else
+// host->cmdat |= host->plat->bus_width;
+ } else {
+ /* 1 bit bus*/
+ host->cmdat &= ~MSC_CMDAT_BUS_WIDTH_8BIT;
+ }
+}
+
+static const struct mmc_host_ops jz_mmc_ops = {
+ .request = jz_mmc_request,
+ .get_ro = jz_mmc_get_ro,
+ .set_ios = jz_mmc_set_ios,
+ .get_cd = jz_mmc_get_cd,
+};
+
+static int jz_mmc_probe(struct platform_device *pdev)
+{
+ struct jz_mmc_platform_data *plat = pdev->dev.platform_data;
+ struct mmc_host *mmc;
+ struct jz_mmc_host *host = NULL;
+// struct jz_mmc_controller controller;
+ struct jz_mmc_functions *functions;
+
+ struct resource *irqres = NULL;
+ struct resource *memres = NULL;
+ struct resource *dmares = NULL;
+ int i;
+ int ret = 0;
+
+ if (pdev == NULL) {
+ printk(KERN_ERR "%s: pdev is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (!plat) {
+ printk(KERN_ERR "%s: Platform data not available\n", __func__);
+ return -EINVAL;
+ }
+
+
+
+ if (pdev->id < 0 || pdev->id > 1)
+ return -EINVAL;
+
+ plat->cpm_start(&pdev->dev);
+
+ // IORESOURCE_DMA is NOT required
+ if (pdev->resource == NULL || pdev->num_resources < 2) {
+ printk(KERN_ERR "%s: Invalid resource\n", __func__);
+ return -ENXIO;
+ }
+ for (i = 0; i < pdev->num_resources; i++) {
+ if (pdev->resource[i].flags & IORESOURCE_MEM)
+ memres = &pdev->resource[i];
+ if (pdev->resource[i].flags & IORESOURCE_IRQ)
+ irqres = &pdev->resource[i];
+ if (pdev->resource[i].flags & IORESOURCE_DMA)
+ dmares = &pdev->resource[i];
+ }
+ if (!irqres || !memres) {
+ printk(KERN_ERR "%s: Invalid resource\n", __func__);
+ return -ENXIO;
+ }
+ /*
+ * Setup our host structure
+ */
+ mmc = mmc_alloc_host(sizeof(struct jz_mmc_host), &pdev->dev);
+ if (!mmc) {
+ return -ENOMEM;
+ }
+ host = mmc_priv(mmc);
+ host->pdev_id = pdev->id;
+ host->plat = plat;
+ host->mmc = mmc;
+ // base address of MSC controller
+ host->base = ioremap(memres->start, PAGE_SIZE);
+ if (!host->base) {
+ return -ENOMEM;
+ }
+ // back up these info. for future using
+ host->irqres = irqres;
+ host->memres = memres;
+ host->dmares = dmares;
+ host->imask = 0xffff;
+ host->sg_cpu =
+ dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma,
+ GFP_KERNEL);
+ if (!host->sg_cpu) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ spin_lock_init(&host->lock);
+
+ /*
+ * Setup MMC host structure
+ */
+ mmc->ops = &jz_mmc_ops;
+ mmc->f_min = MMC_CLOCK_SLOW;
+ mmc->f_max = SD_CLOCK_HIGH;
+ mmc->ocr_avail = plat->ocr_mask;
+ mmc->caps |= host->plat->max_bus_width;
+ mmc->max_phys_segs = NR_SG;
+ mmc->max_blk_size = 4095;
+ mmc->max_blk_count = 65535;
+
+ mmc->max_req_size = PAGE_SIZE * 16;
+ mmc->max_seg_size = mmc->max_req_size;
+ plat->init(&pdev->dev);
+ plat->power_on(&pdev->dev);
+ /*
+ * Initialize controller and register some functions
+ * From here, we can do everything!
+ */
+ controller_register(&controller[host->pdev_id], host);
+ functions = host->plat->driver_data;
+
+ if(controller[host->pdev_id].init(&controller[host->pdev_id], host, pdev))
+ goto out;
+
+// printk("%s: functions->set_clock = %x jz_mmc_set_clock = %x\n", __FUNCTION__, functions->set_clock, jz_mmc_set_clock);
+ mmc_set_drvdata(pdev, mmc);
+ mmc_add_host(mmc);
+
+ printk("JZ %s driver registered\n", pdev->name);
+
+ return 0;
+
+out:
+ if (host->sg_cpu)
+ dma_free_coherent(&pdev->dev, PAGE_SIZE,
+ host->sg_cpu, host->sg_dma);
+ return -1;
+}
+
+static int jz_mmc_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct jz_mmc_platform_data *plat = pdev->dev.platform_data;
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (mmc) {
+ struct jz_mmc_host *host = mmc_priv(mmc);
+ struct jz_mmc_functions *functions = host->plat->driver_data;
+
+ plat->power_off(&pdev->dev);
+
+ functions->deinit(host, pdev);
+
+ mmc_remove_host(mmc);
+ mmc_free_host(mmc);
+ }
+ return 0;
+}
+
+static int jz_mmc_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ struct jz_mmc_host *host = mmc_priv(mmc);
+ int ret = 0;
+
+ printk("enter jz_mmc_suspend......\n");
+ if (mmc) {
+
+ if (host->plat->detect_pin)
+ enable_irq_wake(host->plat->detect_pin);
+
+ if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) {
+ ret = mmc_suspend_host(mmc, state);
+ }
+
+ }
+ return ret;
+}
+
+static int jz_mmc_resume(struct platform_device *dev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+// struct jz_mmc_host *host = mmc_priv(mmc);
+ int ret = 0;
+
+ printk("enter jz_mmc_resume......\n");
+ if (mmc) {
+ if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) {
+ ret = mmc_resume_host(mmc);
+ //disable_irq_wake(host->plat->detect_pin);
+ }
+
+ }
+
+ return ret;
+}
+
+static struct platform_driver jz_mmc0_driver = {
+ .probe = jz_mmc_probe,
+ .remove = jz_mmc_remove,
+ .suspend = jz_mmc_suspend,
+ .resume = jz_mmc_resume,
+ .driver = {
+ .name = "jz-msc0",
+ },
+};
+
+static struct platform_driver jz_mmc1_driver = {
+ .probe = jz_mmc_probe,
+ .remove = jz_mmc_remove,
+ .suspend = jz_mmc_suspend,
+ .resume = jz_mmc_resume,
+ .driver = {
+ .name = "jz-msc1",
+ },
+};
+
+static int __init jz_mmc_init(void)
+{
+ int ret = 0;
+ printk("here!!!!!jz_mmc_init......\n");
+ ret = platform_driver_register(&jz_mmc0_driver);
+ ret = platform_driver_register(&jz_mmc1_driver);
+
+ return ret;
+}
+
+static void __exit jz_mmc_exit(void)
+{
+ platform_driver_unregister(&jz_mmc1_driver);
+ platform_driver_unregister(&jz_mmc0_driver);
+}
+
+module_init(jz_mmc_init);
+module_exit(jz_mmc_exit);
+
+MODULE_DESCRIPTION("JZ47XX SD/Multimedia Card Interface Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index b04c829b217..93dc054a508 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -29,29 +29,52 @@ config MTD_NAND_JZ4750
help
Support NAND Flash device on Jz4750 board
+config MTD_NAND_JZ4760
+ tristate "Support NAND Flash device on Jz4760 board"
+ depends on SOC_JZ4760
+ help
+ Support NAND Flash device on Jz4760 board
+
+
config MTD_NAND_CS2
- depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750
+ depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 || MTD_NAND_JZ4760
bool 'Use NAND on CS2_N of JZSOC'
default n
config MTD_NAND_CS3
- depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750
+ depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 || MTD_NAND_JZ4760
bool 'Use NAND on CS3_N of JZSOC'
default n
config MTD_NAND_CS4
- depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750
+ depends on MTD_NAND_JZ4740 || MTD_NAND_JZ4750 || MTD_NAND_JZ4760
bool 'Use NAND on CS4_N of JZSOC'
default n
config MTD_NAND_MULTI_PLANE
- depends on MTD_NAND_JZ4730 || MTD_NAND_JZ4740 || MTD_NAND_JZ4750
+ depends on MTD_NAND_JZ4730 || MTD_NAND_JZ4740 || MTD_NAND_JZ4750 || MTD_NAND_JZ4760
bool 'Use multiple planes if the NAND supports'
default y
help
It is just supported on jz4740 now.
+choice
+ prompt "8 bit or 16 bit NAND bus width"
+ default CONFIG_MTD_NAND_BUS_WIDTH_8
+
+config MTD_NAND_BUS_WIDTH_8
+ bool '8 bit'
+ help
+ The bus width of NAND flash is 8 bit.
+
+config MTD_NAND_BUS_WIDTH_16
+ bool '16 bit'
+ help
+ The bus width of NAND flash is 16 bit.
+
+endchoice
-if MTD_NAND_JZ4740 || MTD_NAND_JZ4730 || MTD_NAND_JZ4750
+
+if MTD_NAND_JZ4740 || MTD_NAND_JZ4730 || MTD_NAND_JZ4750 || MTD_NAND_JZ4760
choice
prompt "ECC type"
default CONFIG_MTD_SW_HM_ECC
@@ -70,18 +93,36 @@ config MTD_HW_RS_ECC
config MTD_HW_BCH_ECC
depends on MTD_NAND_JZ4750
bool 'Select hardware BCH ECC'
+
+config MTD_HW_BCH_ECC
+ depends on MTD_NAND_JZ4760
+ bool 'Select hardware BCH ECC'
endchoice
choice
- prompt "4 bit or 8 bit BCH ecc"
- depends on MTD_HW_BCH_ECC
- default CONFIG_MTD_HW_BCH_4BIT
+ prompt "4 bit or 8 bit or 12 bit or 16 bit or 20 bit or 24 bit BCH ecc"
+ depends on MTD_HW_BCH_ECC
+ default CONFIG_MTD_HW_BCH_4BIT
+
+config MTD_HW_BCH_4BIT
+ bool '4 bit'
-config MTD_HW_BCH_4BIT
- bool '4 bit'
+config MTD_HW_BCH_8BIT
+ bool '8 bit'
-config MTD_HW_BCH_8BIT
- bool '8 bit'
+if MTD_NAND_JZ4760
+config MTD_HW_BCH_12BIT
+ bool '12 bit'
+
+config MTD_HW_BCH_16BIT
+ bool '16 bit'
+
+config MTD_HW_BCH_20BIT
+ bool '20 bit'
+
+config MTD_HW_BCH_24BIT
+ bool '24 bit'
+endif
endchoice
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 673c15ce1b3..7cb1f0bc7ae 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -43,5 +43,6 @@ obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
obj-$(CONFIG_MTD_NAND_JZ4730) += jz4730_nand.o
obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o
obj-$(CONFIG_MTD_NAND_JZ4750) += jz4750_nand.o
+obj-$(CONFIG_MTD_NAND_JZ4760) += jz4760_nand.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/jz4760_nand.c b/drivers/mtd/nand/jz4760_nand.c
new file mode 100644
index 00000000000..b105a29f643
--- /dev/null
+++ b/drivers/mtd/nand/jz4760_nand.c
@@ -0,0 +1,2001 @@
+/*
+ * linux/drivers/mtd/nand/jz4760_nand.c
+ *
+ * JZ4760 NAND driver
+ *
+ * Copyright (c) 2005 - 2007 Ingenic Semiconductor Inc.
+ * Author: <lhhuang@ingenic.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/jzsoc.h>
+
+#define BDMAC_DCMD_DS_NAND BDMAC_DCMD_DS_64BYTE
+#define DIV_DS_NAND 64
+
+#define BDMAC_DCMD_DS_BCH BDMAC_DCMD_DS_64BYTE
+#define DIV_DS_BCH 64
+
+#ifdef CONFIG_MTD_NAND_BUS_WIDTH_16
+#define BDMAC_DCMD_DWDH_XX BDMAC_DCMD_DWDH_16
+#else
+#define BDMAC_DCMD_DWDH_XX BDMAC_DCMD_DWDH_8
+#endif
+
+#define USE_DIRECT 1
+#define USE_PN 0
+#define USE_COUNTER 0
+#define COUNT_0 0 /* 1:count the number of 1; 0:count the number of 0 */
+#define PN_ENABLE (1 | PN_RESET)
+#define PN_DISABLE 0
+#define PN_RESET (1 << 1)
+#define COUNTER_ENABLE ((1 << 3) | COUNTER_RESET)
+#define COUNTER_DISABLE (0 << 3)
+#define COUNTER_RESET (1 << 5)
+#define COUNT_FOR_1 (0 << 4)
+#define COUNT_FOR_0 (1 << 4)
+
+#define DEBUG1 0
+#if DEBUG1
+#define dprintk(n,x...) printk(n,##x)
+#else
+#define dprintk(n,x...)
+#endif
+
+#if defined(CONFIG_MTD_HW_BCH_24BIT)
+#define __ECC_ENCODING __ecc_encoding_24bit
+#define __ECC_DECODING __ecc_decoding_24bit
+#define ERRS_SIZE 13 /* 13 words */
+#define PAR_SIZE 78 /* 24-bit */
+#elif defined(CONFIG_MTD_HW_BCH_20BIT)
+#define __ECC_ENCODING __ecc_encoding_20bit
+#define __ECC_DECODING __ecc_decoding_20bit
+#define ERRS_SIZE 11 /* 11 words */
+#define PAR_SIZE 65 /* 20-bit */
+#elif defined(CONFIG_MTD_HW_BCH_16BIT)
+#define __ECC_ENCODING __ecc_encoding_16bit
+#define __ECC_DECODING __ecc_decoding_16bit
+#define ERRS_SIZE 9 /* 9 words */
+#define PAR_SIZE 52 /* 16-bit */
+#elif defined(CONFIG_MTD_HW_BCH_12BIT)
+#define __ECC_ENCODING __ecc_encoding_12bit
+#define __ECC_DECODING __ecc_decoding_12bit
+#define ERRS_SIZE 7 /* 7 words */
+#define PAR_SIZE 39 /* 12-bit */
+#elif defined(CONFIG_MTD_HW_BCH_8BIT)
+#define __ECC_ENCODING __ecc_encoding_8bit
+#define __ECC_DECODING __ecc_decoding_8bit
+#define ERRS_SIZE 5 /* 5 words */
+#define PAR_SIZE 26 /* 8-bit */
+#else
+#define __ECC_ENCODING __ecc_encoding_4bit
+#define __ECC_DECODING __ecc_decoding_4bit
+#define ERRS_SIZE 3 /* 3 words */
+#define PAR_SIZE 13 /* 4-bit */
+#endif
+
+#define NAND_DATA_PORT1 0xBA000000 /* read-write area in static bank 1 */
+#define NAND_DATA_PORT2 0xB4000000 /* read-write area in static bank 2 */
+#define NAND_DATA_PORT3 0xAC000000 /* read-write area in static bank 3 */
+#define NAND_DATA_PORT4 0xA8000000 /* read-write area in static bank 4 */
+
+#define NAND_ADDR_OFFSET0 0x00800000 /* address port offset for share mode */
+#define NAND_CMD_OFFSET0 0x00400000 /* command port offset for share mode */
+#define NAND_ADDR_OFFSET1 0x00000008 /* address port offset for unshare mode */
+#define NAND_CMD_OFFSET1 0x00000004 /* command port offset for unshare mode */
+
+#if defined(CONFIG_MTD_NAND_DMA)
+#define USE_IRQ 1
+enum {
+ NAND_NONE,
+ NAND_PROG,
+ NAND_READ
+};
+static volatile u8 nand_status;
+static volatile int dma_ack = 0;
+static volatile int dma_ack1 = 0;
+static char nand_dma_chan = 1; /* fixed to channel 1 */
+static char bch_dma_chan = 0; /* fixed to channel 0 */
+static u32 *errs;
+static jz_bdma_desc_8word *dma_desc_enc, *dma_desc_enc1, *dma_desc_dec, *dma_desc_dec1, *dma_desc_dec2,
+ *dma_desc_nand_prog, *dma_desc_nand_read;
+#if USE_PN
+static jz_bdma_desc_8word *dma_desc_pPN, *dma_desc_rPN;
+#endif
+static u32 *pval_nand_ddr;
+static u32 *pval_nand_cmd_pgprog; /* for sending 0x11 or 0x10 when programing*/
+#if defined(CONFIG_MTD_NAND_DMABUF)
+u8 *prog_buf, *read_buf;
+#endif
+#if USE_PN
+static u32 *pn_buf;
+#endif
+DECLARE_WAIT_QUEUE_HEAD(nand_prog_wait_queue);
+DECLARE_WAIT_QUEUE_HEAD(nand_read_wait_queue);
+#endif /* CONFIG_MTD_NAND_DMA */
+
+struct buf_be_corrected {
+ u8 *data;
+ u8 *oob;
+};
+
+static u32 addr_offset;
+static u32 cmd_offset;
+
+extern int global_page; /* for two-plane operations */
+extern int global_mafid; /* ID of manufacture */
+
+/*
+ * MTD structure for JzSOC board
+ */
+static struct mtd_info *jz_mtd = NULL;
+extern struct mtd_info *jz_mtd1;
+extern char all_use_planes;
+
+/*
+ * Define partitions for flash devices
+ */
+#if defined(CONFIG_JZ4760_CYGNUS) || defined(CONFIG_JZ4760_LEPUS)
+static struct mtd_partition partition_info[] = {
+ {name:"NAND BOOT partition",
+ offset:0 * 0x100000LL,
+ size:4 * 0x100000LL,
+ use_planes: 0},
+ {name:"NAND KERNEL partition",
+ offset:4 * 0x100000LL,
+ size:4 * 0x100000LL,
+ use_planes: 0},
+ {name:"NAND ROOTFS partition",
+ offset:8 * 0x100000LL,
+ size:120 * 0x100000LL,
+ use_planes: 0},
+ {name:"NAND DATA1 partition",
+ offset:128 * 0x100000LL,
+ size:384 * 0x100000LL,
+ use_planes: 1},
+ {name:"NAND DATA2 partition",
+ offset:512 * 0x100000LL,
+ size:512 * 0x100000LL,
+ use_planes: 1},
+ {name:"NAND VFAT partition",
+ offset:1024 * 0x100000LL,
+ size:1024 * 0x100000LL,
+ use_planes: 1},
+};
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 2, /* reserved blocks of mtd0 */
+ 2, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 20, /* reserved blocks of mtd4 */
+ 20
+}; /* reserved blocks of mtd5 */
+#endif /* CONFIG_JZ4760_CYGNUS || CONFIG_JZ4760_LEPUS */
+
+#if defined(CONFIG_JZ4760_ALTAIR)
+
+/* Reserve 32MB for bootloader, splash1, splash2 and radiofw */
+#define MISC_OFFSET (32 * 0x100000LL)
+
+#define MISC_SIZE ( 1 * 0x100000LL)
+#define RECOVERY_SIZE ( 5 * 0x100000LL)
+#define BOOT_SIZE ( 4 * 0x100000LL)
+#define SYSTEM_SIZE (90 * 0x100000LL)
+#define USERDATA_SIZE (90 * 0x100000LL)
+#define CACHE_SIZE (32 * 0x100000LL)
+#define STORAGE_SIZE (MTDPART_SIZ_FULL)
+
+static struct mtd_partition partition_info[] = {
+
+ /* Android partitions:
+ *
+ * misc@mtd0 : raw
+ * recovery@mtd1: raw
+ * boot@mtd2: raw
+ * system@mtd3: yaffs2
+ * userdata@mtd4: yaffs2
+ * cache@mtd5: yaffs2
+ * storage@mtd6: vfat
+ */
+ {name: "misc",
+ offset: MISC_OFFSET,
+ size: MISC_SIZE,
+ use_planes: 0},
+ {name: "recovery",
+ offset: (MISC_OFFSET+MISC_SIZE),
+ size: RECOVERY_SIZE,
+ use_planes: 0},
+ {name: "boot",
+ offset: (MISC_OFFSET+MISC_SIZE+RECOVERY_SIZE),
+ size: BOOT_SIZE,
+ use_planes: 0},
+ {name: "system",
+ offset: (MISC_OFFSET+MISC_SIZE+RECOVERY_SIZE+BOOT_SIZE),
+ size: SYSTEM_SIZE,
+ use_planes: 0},
+ {name: "userdata",
+ offset: (MISC_OFFSET+MISC_SIZE+RECOVERY_SIZE+BOOT_SIZE+SYSTEM_SIZE),
+ size: USERDATA_SIZE,
+ use_planes: 0},
+ {name: "cache",
+ offset: (MISC_OFFSET+MISC_SIZE+RECOVERY_SIZE+BOOT_SIZE+SYSTEM_SIZE+USERDATA_SIZE),
+ size: CACHE_SIZE,
+ use_planes: 0},
+ {name: "storage",
+ offset: (MISC_OFFSET+MISC_SIZE+RECOVERY_SIZE+BOOT_SIZE+SYSTEM_SIZE+USERDATA_SIZE+CACHE_SIZE),
+ size: STORAGE_SIZE,
+ use_planes: 0}
+};
+
+/* Define max reserved bad blocks for each partition.
+ * This is used by the mtdblock-jz.c NAND FTL driver only.
+ *
+ * The NAND FTL driver reserves some good blocks which can't be
+ * seen by the upper layer. When the bad block number of a partition
+ * exceeds the max reserved blocks, then there is no more reserved
+ * good blocks to be used by the NAND FTL driver when another bad
+ * block generated.
+ */
+static int partition_reserved_badblocks[] = {
+ 10, /* reserved blocks of mtd0 */
+ 10, /* reserved blocks of mtd1 */
+ 10, /* reserved blocks of mtd2 */
+ 10, /* reserved blocks of mtd3 */
+ 10, /* reserved blocks of mtd4 */
+ 10, /* reserved blocks of mtd5 */
+ 12 /* reserved blocks of mtd6 */
+};
+#endif /* CONFIG_JZ4760_ALTAIR */
+
+/*-------------------------------------------------------------------------
+ * Following three functions are exported and used by the mtdblock-jz.c
+ * NAND FTL driver only.
+ */
+
+unsigned short get_mtdblock_write_verify_enable(void)
+{
+#ifdef CONFIG_MTD_MTDBLOCK_WRITE_VERIFY_ENABLE
+ return 1;
+#endif
+ return 0;
+}
+
+EXPORT_SYMBOL(get_mtdblock_write_verify_enable);
+
+unsigned short get_mtdblock_oob_copies(void)
+{
+ return CONFIG_MTD_OOB_COPIES;
+}
+
+EXPORT_SYMBOL(get_mtdblock_oob_copies);
+
+int *get_jz_badblock_table(void)
+{
+ return partition_reserved_badblocks;
+}
+
+EXPORT_SYMBOL(get_jz_badblock_table);
+
+/*-------------------------------------------------------------------------*/
+
+static void jz_hwcontrol(struct mtd_info *mtd, int dat, u32 ctrl)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ u32 nandaddr = (u32)this->IO_ADDR_W;
+ extern u8 nand_nce; /* defined in nand_base.c, indicates which chip select is used for current nand chip */
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_NCE) {
+ switch (nand_nce) {
+ case NAND_NCE1:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT1;
+ REG_NEMC_NFCSR = NEMC_NFCSR_NFCE1 | NEMC_NFCSR_NFE1;
+ break;
+ case NAND_NCE2:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT2;
+ REG_NEMC_NFCSR = NEMC_NFCSR_NFCE2 | NEMC_NFCSR_NFE2;
+ break;
+ case NAND_NCE3:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT3;
+ REG_NEMC_NFCSR = NEMC_NFCSR_NFCE3 | NEMC_NFCSR_NFE3;
+ break;
+ case NAND_NCE4:
+ this->IO_ADDR_W = this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT4;
+ REG_NEMC_NFCSR = NEMC_NFCSR_NFCE4 | NEMC_NFCSR_NFE4;
+ break;
+ default:
+ printk("error: no nand_nce 0x%x\n",nand_nce);
+ break;
+ }
+ } else {
+
+ REG_NEMC_NFCSR = 0;
+ }
+
+ if (ctrl & NAND_ALE)
+ nandaddr = (u32)((u32)(this->IO_ADDR_W) | addr_offset);
+ else
+ nandaddr = (u32)((u32)(this->IO_ADDR_W) & ~addr_offset);
+ if (ctrl & NAND_CLE)
+ nandaddr = (u32)(nandaddr | cmd_offset);
+ else
+ nandaddr = (u32)(nandaddr & ~cmd_offset);
+ }
+
+ this->IO_ADDR_W = (void __iomem *)nandaddr;
+ if (dat != NAND_CMD_NONE) {
+ writeb(dat, this->IO_ADDR_W);
+ /* printk("write cmd:0x%x to 0x%x\n",dat,(u32)this->IO_ADDR_W); */
+ }
+}
+
+static int jz_device_ready(struct mtd_info *mtd)
+{
+ int ready, wait = 10;
+ while (wait--);
+ ready = ((REG_GPIO_PXPIN(0) & 0x00100000) ? 1 : 0);
+ return ready;
+}
+
+/*
+ * NEMC setup
+ */
+static void jz_device_setup(void)
+{
+// PORT 0:
+// PORT 1:
+// PORT 2:
+// PIN/BIT N FUNC0 FUNC1
+// 21 CS1# -
+// 22 CS2# -
+// 23 CS3# -
+// 24 CS4# -
+#define GPIO_CS2_N (32*2+22)
+#define GPIO_CS3_N (32*2+23)
+#define GPIO_CS4_N (32*2+24)
+
+#ifdef CONFIG_MTD_NAND_BUS_WIDTH_16
+#define SMCR_VAL 0x0d444440
+//#define SMCR_VAL 0x0fff7740 //slowest
+ __gpio_as_nand_16bit(1);
+#else
+#define SMCR_VAL 0x0d444400
+//#define SMCR_VAL 0x0fff7700 //slowest
+ __gpio_as_nand_8bit(1);
+#endif
+
+ /* Read/Write timings */
+ REG_NEMC_SMCR1 = SMCR_VAL;
+
+#if defined(CONFIG_MTD_NAND_CS2)
+ __gpio_as_func0(GPIO_CS2_N);
+
+ /* Read/Write timings */
+ REG_NEMC_SMCR2 = SMCR_VAL;
+#endif
+
+#if defined(CONFIG_MTD_NAND_CS3)
+ __gpio_as_func0(GPIO_CS3_N);
+
+ /* Read/Write timings */
+ REG_NEMC_SMCR3 = SMCR_VAL;
+#endif
+
+#if defined(CONFIG_MTD_NAND_CS4)
+ __gpio_as_func0(GPIO_CS4_N);
+
+ /* Read/Write timings */
+ REG_NEMC_SMCR4 = SMCR_VAL;
+#endif
+}
+
+#ifdef CONFIG_MTD_HW_BCH_ECC
+
+static void jzsoc_nand_enable_bch_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ int eccsize = this->ecc.size;
+ int eccsteps = this->ecc.steps / this->planenum;
+ int oob_per_eccsize = this->ecc.layout->eccpos[0] / eccsteps;
+
+ REG_BCH_INTS = 0xffffffff;
+ if (mode == NAND_ECC_READ) {
+ __ECC_DECODING();
+ __ecc_cnt_dec((eccsize + oob_per_eccsize) * 2 + PAR_SIZE);
+#if defined(CONFIG_MTD_NAND_DMA)
+ __ecc_dma_enable();
+#endif
+ }
+
+ if (mode == NAND_ECC_WRITE) {
+ __ECC_ENCODING();
+ __ecc_cnt_enc((eccsize + oob_per_eccsize) * 2);
+#if defined(CONFIG_MTD_NAND_DMA)
+ __ecc_dma_enable();
+#endif
+ }
+}
+
+/**
+ * bch_correct
+ * @dat: data to be corrected
+ * @idx: the index of error bit in an eccsize
+ */
+static void bch_correct(struct mtd_info *mtd, u8 * dat, int idx)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ int eccsize = this->ecc.size;
+ int eccsteps = this->ecc.steps / this->planenum;
+ int ecc_pos = this->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ int i, bit; /* the 'bit' of i byte is error */
+
+ i = (idx - 1) >> 3;
+ bit = (idx - 1) & 0x7;
+
+ dprintk("error:i=%d, bit=%d\n",i,bit);
+
+ if (i < eccsize){
+ ((struct buf_be_corrected *)dat)->data[i] ^= (1 << bit);
+ } else if (i < eccsize + oob_per_eccsize) {
+ ((struct buf_be_corrected *)dat)->oob[i-eccsize] ^= (1 << bit);
+ }
+}
+
+#if defined(CONFIG_MTD_NAND_DMA)
+
+/**
+ * jzsoc_nand_bch_correct_data
+ * @mtd: mtd info structure
+ * @dat: data to be corrected
+ * @errs0: pointer to the dma target buffer of bch decoding which stores BHINTS and
+ * BHERR0~3(8-bit BCH) or BHERR0~1(4-bit BCH)
+ * @calc_ecc: no used
+ */
+static int jzsoc_nand_bch_correct_data(struct mtd_info *mtd, u_char * dat, u_char * errs0, u_char * calc_ecc)
+{
+ u32 stat, i;
+ u32 *errs = (u32 *)errs0;
+ int ret = 0;
+
+ if (REG_BDMAC_DCCSR(0) & BDMAC_DCCSR_BERR) {
+ stat = errs[0];
+ dprintk("stat=%x err0:%x err1:%x \n", stat, errs[1], errs[2]);
+
+ if (stat & BCH_INTS_ERR) {
+ if (stat & BCH_INTS_UNCOR) {
+ printk("NAND: Uncorrectable ECC error\n");
+ return -1;
+ } else {
+ u32 errcnt = (stat & BCH_INTS_ERRC_MASK) >> BCH_INTS_ERRC_BIT;
+ if(errcnt > 24)
+ printk("NAND:err count[%d] is too big\n",errcnt);
+ else
+ {
+ for(i = 0;i < errcnt;i++)
+ {
+ /*errs[i>>2] >> ((i % 2) << 4) means when errcnt is even, errs[index] >> 16*/
+ bch_correct(mtd, dat, ((errs[i>>2] >> ((i % 2) << 4))) & BCH_ERR_INDEX_MASK);
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+#else /* cpu mode */
+
+/**
+ * jzsoc_nand_bch_correct_data
+ * @mtd: mtd info structure
+ * @dat: data to be corrected
+ * @read_ecc: pointer to ecc buffer calculated when nand writing
+ * @calc_ecc: no used
+ */
+static int jzsoc_nand_bch_correct_data(struct mtd_info *mtd, u_char * dat, u_char * read_ecc, u_char * calc_ecc)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ int eccsize = this->ecc.size;
+ int eccbytes = this->ecc.bytes;
+ int eccsteps = this->ecc.steps / this->planenum;
+ int ecc_pos = this->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ short k;
+ u32 stat;
+ int ret = 0;
+
+ /* Write data to REG_BCH_DR */
+ for (k = 0; k < eccsize; k++) {
+ REG_BCH_DR = ((struct buf_be_corrected *)dat)->data[k];
+ }
+ /* Write oob to REG_BCH_DR */
+ for (k = 0; k < oob_per_eccsize; k++) {
+ REG_BCH_DR = ((struct buf_be_corrected *)dat)->oob[k];
+ }
+ /* Write parities to REG_BCH_DR */
+ for (k = 0; k < eccbytes; k++) {
+ REG_BCH_DR = read_ecc[k];
+ }
+
+ /* Wait for completion */
+ __ecc_decode_sync();
+ __ecc_disable();
+
+ /* Check decoding */
+ stat = REG_BCH_INTS;
+
+ if (stat & BCH_INTS_ERR) {
+ /* Error occurred */
+ if (stat & BCH_INTS_UNCOR) {
+ printk("NAND: Uncorrectable ECC error--\n");
+ return -1;
+ } else {
+ u32 errcnt = (stat & BCH_INTS_ERRC_MASK) >> BCH_INTS_ERRC_BIT;
+ switch (errcnt) {
+ case 24:
+ bch_correct(mtd, dat, (REG_BCH_ERR11 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 23:
+ bch_correct(mtd, dat, (REG_BCH_ERR11 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 22:
+ bch_correct(mtd, dat, (REG_BCH_ERR10 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 21:
+ bch_correct(mtd, dat, (REG_BCH_ERR10 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 20:
+ bch_correct(mtd, dat, (REG_BCH_ERR9 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 19:
+ bch_correct(mtd, dat, (REG_BCH_ERR9 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 18:
+ bch_correct(mtd, dat, (REG_BCH_ERR8 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 17:
+ bch_correct(mtd, dat, (REG_BCH_ERR8 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 16:
+ bch_correct(mtd, dat, (REG_BCH_ERR7 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 15:
+ bch_correct(mtd, dat, (REG_BCH_ERR7 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 14:
+ bch_correct(mtd, dat, (REG_BCH_ERR6 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 13:
+ bch_correct(mtd, dat, (REG_BCH_ERR6 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 12:
+ bch_correct(mtd, dat, (REG_BCH_ERR5 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 11:
+ bch_correct(mtd, dat, (REG_BCH_ERR5 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 10:
+ bch_correct(mtd, dat, (REG_BCH_ERR4 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 9:
+ bch_correct(mtd, dat, (REG_BCH_ERR4 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 8:
+ bch_correct(mtd, dat, (REG_BCH_ERR3 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 7:
+ bch_correct(mtd, dat, (REG_BCH_ERR3 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 6:
+ bch_correct(mtd, dat, (REG_BCH_ERR2 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 5:
+ bch_correct(mtd, dat, (REG_BCH_ERR2 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 4:
+ bch_correct(mtd, dat, (REG_BCH_ERR1 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 3:
+ bch_correct(mtd, dat, (REG_BCH_ERR1 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ /* FALL-THROUGH */
+ case 2:
+ bch_correct(mtd, dat, (REG_BCH_ERR0 & BCH_ERR_INDEX_ODD_MASK) >> BCH_ERR_INDEX_ODD_BIT);
+ /* FALL-THROUGH */
+ case 1:
+ bch_correct(mtd, dat, (REG_BCH_ERR0 & BCH_ERR_INDEX_EVEN_MASK) >> BCH_ERR_INDEX_EVEN_BIT);
+ return 0;
+ default:
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+#endif /* CONFIG_MTD_NAND_DMA */
+
+static int jzsoc_nand_calculate_bch_ecc(struct mtd_info *mtd, const u_char * dat, u_char * ecc_code)
+{
+ struct nand_chip *this = (struct nand_chip *)(mtd->priv);
+ int eccsize = this->ecc.size;
+ int eccbytes = this->ecc.bytes;
+ int eccsteps = this->ecc.steps / this->planenum;
+ int ecc_pos = this->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ volatile u8 *paraddr = (volatile u8 *)BCH_PAR0;
+ short i;
+
+ /* Write data to REG_BCH_DR */
+ for (i = 0; i < eccsize; i++) {
+ REG_BCH_DR = ((struct buf_be_corrected *)dat)->data[i];
+ }
+ /* Write oob to REG_BCH_DR */
+ for (i = 0; i < oob_per_eccsize; i++) {
+ REG_BCH_DR = ((struct buf_be_corrected *)dat)->oob[i];
+ }
+ __ecc_encode_sync();
+ __ecc_disable();
+
+ for (i = 0; i < eccbytes; i++) {
+ ecc_code[i] = *paraddr++;
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_MTD_NAND_DMA)
+
+/**
+ * nand_write_page_hwecc_bch - [REPLACABLE] hardware ecc based page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ */
+static void nand_write_page_hwecc_bch0(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t * buf, u8 cmd_pgprog)
+{
+ int eccsize = chip->ecc.size;
+ int eccsteps = chip->ecc.steps / chip->planenum;
+ int eccbytes = chip->ecc.bytes;
+ int ecc_pos = chip->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ int pagesize = mtd->writesize / chip->planenum;
+ int oobsize = mtd->oobsize / chip->planenum;
+ int i, err, timeout;
+ const u8 *databuf;
+ u8 *oobbuf;
+ jz_bdma_desc_8word *desc;
+
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ memcpy(prog_buf, buf, pagesize);
+ memcpy(prog_buf + pagesize, chip->oob_poi, oobsize);
+ dma_cache_wback_inv((u32)prog_buf, pagesize + oobsize);
+#else
+ databuf = buf;
+ oobbuf = chip->oob_poi;
+
+ /* descriptors for encoding data blocks */
+ desc = dma_desc_enc;
+ for (i = 0; i < eccsteps; i++) {
+ desc->dsadr = CPHYSADDR((u32)databuf) + i * eccsize; /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA target address */
+ dprintk("dma_desc_enc:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptors for encoding oob blocks */
+ desc = dma_desc_enc1;
+ for (i = 0; i < eccsteps; i++) {
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + oob_per_eccsize * i; /* DMA source address, 28/4 = 7bytes */
+ desc->dtadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA target address */
+ dprintk("dma_desc_enc1:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptor for nand programing data block */
+ desc = dma_desc_nand_prog;
+ desc->dsadr = CPHYSADDR((u32)databuf); /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)chip->IO_ADDR_W); /* It will be changed when using multiply chip select */
+ dprintk("dma_desc_nand_prog:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+
+ /* descriptor for nand programing oob block */
+ desc++;
+ desc->dsadr = CPHYSADDR((u32)oobbuf); /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)chip->IO_ADDR_W); /* It will be changed when using multiply chip select */
+ dprintk("dma_desc_oob_prog:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+
+ /* descriptor for __nand_cmd(CMD_PGPROG) */
+ desc++;
+ *pval_nand_cmd_pgprog = cmd_pgprog | 0x40000000;
+ desc->dsadr = CPHYSADDR((u32)pval_nand_cmd_pgprog);
+ desc->dtadr = CPHYSADDR((u32)chip->IO_ADDR_R); /* DMA target address: cmdport */
+ if (cmd_pgprog == 0x10)
+ desc->dcmd |= BDMAC_DCMD_LINK; /* __nand_sync() by a DMA descriptor */
+ else if (cmd_pgprog == 0x11)
+ desc->dcmd &= ~BDMAC_DCMD_LINK; /* __nand_sync() by polling */
+
+ dma_cache_wback_inv((u32)dma_desc_enc, (eccsteps * 2 + 2 + 4) * (sizeof(jz_bdma_desc_8word)));
+ dma_cache_wback_inv((u32)databuf, pagesize);
+ dma_cache_wback_inv((u32)oobbuf, oobsize);
+ /* 4*6: pval_nand_ddr, pval_nand_dcs, pval_bch_ddr, pval_bch_dcs, dummy, pval_nand_cmd_pgprog */
+ dma_cache_wback_inv((u32)pval_nand_ddr, 4 * 8); /* 8 words, a cache line */
+#endif
+
+ REG_BDMAC_DCCSR(bch_dma_chan) = 0;
+ REG_BDMAC_DCCSR(nand_dma_chan) = 0;
+
+ /* Setup DMA descriptor address */
+ REG_BDMAC_DDA(bch_dma_chan) = CPHYSADDR((u32)dma_desc_enc);
+#if USE_PN
+ REG_BDMAC_DDA(nand_dma_chan) = CPHYSADDR((u32)dma_desc_pPN);
+#else
+ REG_BDMAC_DDA(nand_dma_chan) = CPHYSADDR((u32)dma_desc_nand_prog);
+#endif
+
+ /* Setup request source */
+ REG_BDMAC_DRSR(bch_dma_chan) = BDMAC_DRSR_RS_BCH_ENC;
+ REG_BDMAC_DRSR(nand_dma_chan) = BDMAC_DRSR_RS_AUTO;
+
+ /* Setup DMA channel control/status register */
+ REG_BDMAC_DCCSR(bch_dma_chan) = BDMAC_DCCSR_DES8 | BDMAC_DCCSR_EN; /* descriptor transfer, clear status, start channel */
+ /* Enable DMA */
+ REG_BDMAC_DMACR |= BDMAC_DMACR_DMAE;
+
+ /* Enable BCH encoding */
+ chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+
+ dma_ack1 = 0;
+ nand_status = NAND_PROG;
+
+ /* DMA doorbell set -- start DMA now ... */
+ __bdmac_channel_set_doorbell(bch_dma_chan);
+
+#if USE_IRQ
+ if (cmd_pgprog == 0x10) {
+ dprintk("nand prog before wake up\n");
+ do {
+ err = wait_event_interruptible_timeout(nand_prog_wait_queue, dma_ack1, 3 * HZ);
+ }while(err == -ERESTARTSYS);
+
+ nand_status = NAND_NONE;
+ dprintk("nand prog after wake up\n");
+ if (!err) {
+ printk("*** NAND WRITE, Warning, wait event 3s timeout!\n");
+ dump_jz_bdma_channel(0);
+ dump_jz_bdma_channel(nand_dma_chan);
+ printk("REG_BCH_CR=%x REG_BCH_CNT=0x%x REG_BCH_INTS=%x\n", REG_BCH_CR, REG_BCH_CNT, REG_BCH_INTS);
+ }
+ dprintk("timeout remain = %d\n", err);
+ } else if (cmd_pgprog == 0x11) {
+ timeout = 100000;
+ while ((!__bdmac_channel_transmit_end_detected(nand_dma_chan)) && (timeout--));
+ if (timeout <= 0)
+ printk("two-plane prog 0x11 timeout!\n");
+ }
+#else
+ timeout = 100000;
+ while ((!__bdmac_channel_transmit_end_detected(nand_dma_chan)) && (timeout--));
+ while(!chip->dev_ready(mtd));
+ if (timeout <= 0)
+ printk("not use irq, prog timeout!\n");
+#endif
+}
+
+static void nand_write_page_hwecc_bch(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t * buf)
+{
+ nand_write_page_hwecc_bch0(mtd, chip, buf, 0x10);
+}
+
+static void nand_write_page_hwecc_bch_planes(struct mtd_info *mtd, struct nand_chip *chip, const uint8_t * buf)
+{
+ int page;
+ int pagesize = mtd->writesize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x80, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ {
+ if(global_mafid == 0x2c)
+ chip->cmdfunc(mtd, 0x80, 0x00, page);
+ else
+ chip->cmdfunc(mtd, 0x80, 0x00, 0x00);
+ }
+ else
+ chip->cmdfunc(mtd, 0x80, 0x00, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ nand_write_page_hwecc_bch0(mtd, chip, buf, 0x11);
+ chip->cmdfunc(mtd, 0x81, 0x00, page + ppb);
+ nand_write_page_hwecc_bch0(mtd, chip, buf + pagesize, 0x10);
+}
+
+#else /* nand write in cpu mode */
+
+static void nand_write_page_hwecc_bch(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps / chip->planenum;
+ int oob_per_eccsize = chip->ecc.layout->eccpos[0] / eccsteps;
+ int oobsize = mtd->oobsize / chip->planenum;
+ int ecctotal = chip->ecc.total / chip->planenum;
+ uint8_t *p = (uint8_t *)buf;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ static struct buf_be_corrected buf_calc0;
+ struct buf_be_corrected *buf_calc = &buf_calc0;
+
+ for (i = 0; i < eccsteps; i++, p += eccsize) {
+ buf_calc->data = (u8 *)buf + eccsize * i;
+ buf_calc->oob = chip->oob_poi + oob_per_eccsize * i;
+ chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
+ chip->ecc.calculate(mtd, (u8 *)buf_calc, &ecc_calc[eccbytes*i]);
+ chip->write_buf(mtd, p, eccsize);
+ }
+
+ for (i = 0; i < ecctotal; i++)
+ chip->oob_poi[eccpos[i]] = ecc_calc[i];
+
+ chip->write_buf(mtd, chip->oob_poi, oobsize);
+}
+
+/* nand write using two-plane mode */
+static void nand_write_page_hwecc_bch_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int pagesize = mtd->writesize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+ int page;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x80, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ {
+ if(global_mafid == 0x2c)
+ chip->cmdfunc(mtd, 0x80, 0x00, page);
+ else
+ chip->cmdfunc(mtd, 0x80, 0x00, 0x00);
+ }
+ else
+ chip->cmdfunc(mtd, 0x80, 0x00, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ nand_write_page_hwecc_bch(mtd, chip, buf);
+
+ chip->cmdfunc(mtd, 0x11, -1, -1); /* send cmd 0x11 */
+ ndelay(100);
+ while(!chip->dev_ready(mtd));
+
+ chip->cmdfunc(mtd, 0x81, 0x00, page + ppb); /* send cmd 0x81 */
+ nand_write_page_hwecc_bch(mtd, chip, buf + pagesize);
+}
+#endif /* CONFIG_MTD_NAND_DMA */
+
+/**
+ * nand_read_page_hwecc_bch - [REPLACABLE] hardware ecc based page read function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ *
+ * Not for syndrome calculating ecc controllers which need a special oob layout
+ */
+#if defined(CONFIG_MTD_NAND_DMA)
+static int nand_read_page_hwecc_bch0(struct mtd_info *mtd, struct nand_chip *chip, uint8_t * buf, u32 page)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccsteps = chip->ecc.steps / chip->planenum;
+ int eccbytes = chip->ecc.bytes;
+ int ecc_pos = chip->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ int pagesize = mtd->writesize / chip->planenum;
+ int oobsize = mtd->oobsize / chip->planenum;
+ u8 *databuf, *oobbuf;
+ jz_bdma_desc_8word *desc;
+ int err;
+ u32 addrport, cmdport;
+ static struct buf_be_corrected buf_correct0;
+
+ addrport = (u32)(chip->IO_ADDR_R) | addr_offset;
+ cmdport = (u32)(chip->IO_ADDR_R) | cmd_offset;
+
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ databuf = read_buf;
+ oobbuf = read_buf + pagesize;
+
+ dma_cache_inv((u32)read_buf, pagesize + oobsize); // databuf should be invalidated.
+ memset(errs, 0, eccsteps * ERRS_SIZE * 4);
+ dma_cache_wback_inv((u32)errs, eccsteps * ERRS_SIZE * 4);
+#else
+
+ databuf = buf;
+ oobbuf = chip->oob_poi;
+
+ /* descriptor for nand reading data block */
+ desc = dma_desc_nand_read;
+ desc->dsadr = CPHYSADDR((u32)chip->IO_ADDR_R); /* It will be changed when using multiply chip select */
+ desc->dtadr = CPHYSADDR((u32)databuf); /* DMA target address */
+
+ dprintk("desc_nand_read:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+
+ /* descriptor for nand reading oob block */
+ desc++;
+ desc->dsadr = CPHYSADDR((u32)chip->IO_ADDR_R); /* It will be changed when using multiply chip select */
+ desc->dtadr = CPHYSADDR((u32)oobbuf); /* DMA target address */
+ dprintk("desc_oob_read:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+
+ /* descriptors for data to be written to bch */
+ desc = dma_desc_dec;
+ for (i = 0; i < eccsteps; i++) {
+ desc->dsadr = CPHYSADDR((u32)databuf) + i * eccsize; /* DMA source address */
+ dprintk("dma_desc_dec:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptors for oob to be written to bch */
+ desc = dma_desc_dec1;
+ for (i = 0; i < eccsteps; i++) {
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + oob_per_eccsize * i; /* DMA source address */
+ dprintk("dma_desc_dec1:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptors for parities to be written to bch */
+ desc = dma_desc_dec2;
+ for (i = 0; i < eccsteps; i++) {
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA source address */
+ dprintk("dma_desc_dec2:desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ dma_cache_wback_inv((u32)dma_desc_nand_read, (2 + eccsteps * 3) * (sizeof(jz_bdma_desc_8word)));
+
+ memset(errs, 0, eccsteps * ERRS_SIZE * 4);
+ dma_cache_inv((u32)databuf, pagesize); // databuf should be invalidated.
+ dma_cache_inv((u32)oobbuf, oobsize); // oobbuf should be invalidated too
+ dma_cache_wback_inv((u32)errs, eccsteps * ERRS_SIZE * 4);
+#endif
+ REG_BDMAC_DCCSR(bch_dma_chan) = 0;
+ REG_BDMAC_DCCSR(nand_dma_chan) = 0;
+
+ /* Setup DMA descriptor address */
+#if USE_PN
+ REG_BDMAC_DDA(nand_dma_chan) = CPHYSADDR((u32)dma_desc_rPN);
+#else
+ REG_BDMAC_DDA(nand_dma_chan) = CPHYSADDR((u32)dma_desc_nand_read);
+#endif
+ REG_BDMAC_DDA(bch_dma_chan) = CPHYSADDR((u32)dma_desc_dec);
+
+ /* Setup request source */
+#if USE_PN
+ REG_BDMAC_DRSR(nand_dma_chan) = BDMAC_DRSR_RS_AUTO;
+#else
+ REG_BDMAC_DRSR(nand_dma_chan) = BDMAC_DRSR_RS_NAND;
+#endif
+ REG_BDMAC_DRSR(bch_dma_chan) = BDMAC_DRSR_RS_BCH_DEC;
+
+ /* Enable DMA */
+ REG_BDMAC_DMACR |= BDMAC_DMACR_DMAE;
+
+ /* Enable BCH decoding */
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+
+ dma_ack = 0;
+ nand_status = NAND_READ;
+ /* DMA doorbell set -- start nand DMA now ... */
+ __bdmac_channel_set_doorbell(nand_dma_chan);
+
+ /* Setup DMA channel control/status register */
+ REG_BDMAC_DCCSR(nand_dma_chan) = BDMAC_DCCSR_DES8 | BDMAC_DCCSR_EN;
+
+#define __nand_cmd(n) (REG8(cmdport) = (n))
+#define __nand_addr(n) (REG8(addrport) = (n))
+
+ __nand_cmd(NAND_CMD_READ0);
+
+ __nand_addr(0);
+ if (pagesize != 512)
+ __nand_addr(0);
+
+ __nand_addr(page & 0xff);
+ __nand_addr((page >> 8) & 0xff);
+
+ /* One more address cycle for the devices whose number of page address bits > 16 */
+ if (((chip->chipsize >> chip->page_shift) >> 16) > 0)
+ __nand_addr((page >> 16) & 0xff);
+
+ if (pagesize != 512)
+ __nand_cmd(NAND_CMD_READSTART);
+
+#if USE_IRQ
+ do {
+ err = wait_event_interruptible_timeout(nand_read_wait_queue, dma_ack, 3 * HZ);
+ }while(err == -ERESTARTSYS);
+ nand_status = NAND_NONE;
+
+ if (!err) {
+ printk("*** NAND READ, Warning, wait event 3s timeout!\n");
+ dump_jz_bdma_channel(0);
+ dump_jz_bdma_channel(nand_dma_chan);
+ printk("REG_BCH_CR=%x REG_BCH_CNT=0x%x REG_BCH_INTS=%x\n", REG_BCH_CR, REG_BCH_CNT, REG_BCH_INTS);
+ }
+ dprintk("timeout remain = %d\n", err);
+#else
+ int timeout;
+ timeout = 100000;
+ while ((!__bdmac_channel_transmit_end_detected(bch_dma_chan)) && (timeout--));
+ if (timeout <= 0) {
+ printk("not use irq, NAND READ timeout!\n");
+ }
+#endif
+
+ for (i = 0; i < eccsteps; i++) {
+ int stat;
+ struct buf_be_corrected *buf_correct = &buf_correct0;
+
+ buf_correct->data = databuf + eccsize * i;
+ buf_correct->oob = oobbuf + oob_per_eccsize * i;
+
+ stat = chip->ecc.correct(mtd, (u8 *)buf_correct, (u8 *)&errs[i * ERRS_SIZE], NULL);
+ if (stat < 0)
+ {
+ printk("ecc Uncorrectable:global_page = %d,chip->planenum = %d\n",global_page,chip->planenum);
+ mtd->ecc_stats.failed++;
+ }
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ memcpy(buf, read_buf, pagesize);
+ memcpy(chip->oob_poi, read_buf + pagesize, oobsize);
+#endif
+ return 0;
+}
+
+static int nand_read_page_hwecc_bch(struct mtd_info *mtd, struct nand_chip *chip, uint8_t * buf)
+{
+ u32 page = global_page;
+
+ nand_read_page_hwecc_bch0(mtd, chip, buf, page);
+ return 0;
+}
+
+static int nand_read_page_hwecc_bch_planes(struct mtd_info *mtd, struct nand_chip *chip, uint8_t * buf)
+{
+ u32 page;
+ int pagesize = mtd->writesize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* read 1st page */
+ nand_read_page_hwecc_bch0(mtd, chip, buf, page);
+
+ /* read 2nd page */
+ nand_read_page_hwecc_bch0(mtd, chip, buf + pagesize, page + ppb);
+ return 0;
+}
+
+#else /* nand read in cpu mode */
+
+static int nand_read_page_hwecc_bch(struct mtd_info *mtd, struct nand_chip *chip, uint8_t * buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps / chip->planenum;
+ int ecc_pos = chip->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ uint8_t *ecc_calc = chip->buffers->ecccalc;
+ uint8_t *ecc_code = chip->buffers->ecccode;
+ uint32_t *eccpos = chip->ecc.layout->eccpos;
+ int pagesize = mtd->writesize / chip->planenum;
+ int oobsize = mtd->oobsize / chip->planenum;
+ int ecctotal = chip->ecc.total / chip->planenum;
+ static struct buf_be_corrected buf_correct0;
+
+ chip->read_buf(mtd, buf, pagesize);
+ chip->read_buf(mtd, chip->oob_poi, oobsize);
+
+ for (i = 0; i < ecctotal; i++) {
+ ecc_code[i] = chip->oob_poi[eccpos[i]];
+ }
+
+ for (i = 0; i < eccsteps; i++) {
+ int stat;
+ struct buf_be_corrected *buf_correct = &buf_correct0;
+
+ buf_correct->data = buf + eccsize * i;
+ buf_correct->oob = chip->oob_poi + oob_per_eccsize * i;
+
+ chip->ecc.hwctl(mtd, NAND_ECC_READ);
+ stat = chip->ecc.correct(mtd, (u8 *)buf_correct, &ecc_code[eccbytes*i], &ecc_calc[eccbytes*i]);
+ if (stat < 0)
+ {
+ printk("ecc Uncorrectable:global_page = %d,chip->planenum = %d\n",global_page,chip->planenum);
+ mtd->ecc_stats.failed++;
+ }
+ else
+ mtd->ecc_stats.corrected += stat;
+ }
+
+ return 0;
+}
+
+static int nand_read_page_hwecc_bch_planes(struct mtd_info *mtd, struct nand_chip *chip, uint8_t * buf)
+{
+ int pagesize = mtd->writesize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+ uint32_t page;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* Read first page */
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+ nand_read_page_hwecc_bch(mtd, chip, buf);
+
+ /* Read 2nd page */
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page + ppb);
+ nand_read_page_hwecc_bch(mtd, chip, buf+pagesize);
+ return 0;
+}
+#endif /* CONFIG_MTD_NAND_DMA */
+
+#endif /* CONFIG_MTD_HW_BCH_ECC */
+
+/* read oob using two-plane mode */
+static int nand_read_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ int global_page, int sndcmd)
+{
+ int page;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* Read first page OOB */
+ if (sndcmd) {
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ }
+ chip->read_buf(mtd, chip->oob_poi, oobsize);
+ /* Read second page OOB */
+ page += ppb;
+ if (sndcmd) {
+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+ sndcmd = 0;
+ }
+ chip->read_buf(mtd, chip->oob_poi+oobsize, oobsize);
+ return 0;
+}
+
+/* write oob using two-plane mode */
+static int nand_write_oob_std_planes(struct mtd_info *mtd, struct nand_chip *chip,
+ int global_page)
+{
+ int status = 0, page;
+ const uint8_t *buf = chip->oob_poi;
+ int pagesize = mtd->writesize >> 1;
+ int oobsize = mtd->oobsize >> 1;
+ int ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x80, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ {
+ if(global_mafid == 0x2c)
+ chip->cmdfunc(mtd, 0x80, pagesize, page);
+ else
+ chip->cmdfunc(mtd, 0x80, pagesize, 0x00);
+ }
+ else
+ chip->cmdfunc(mtd, 0x80, pagesize, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ chip->write_buf(mtd, buf, oobsize);
+ /* Send first command to program the OOB data */
+ chip->cmdfunc(mtd, 0x11, -1, -1);
+ ndelay(100);
+ status = chip->waitfunc(mtd, chip);
+
+ page += ppb;
+ buf += oobsize;
+ chip->cmdfunc(mtd, 0x81, pagesize, page);
+ chip->write_buf(mtd, buf, oobsize);
+ /* Send command to program the OOB data */
+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+ /* Wait long R/B */
+ ndelay(100);
+ status = chip->waitfunc(mtd, chip);
+
+ return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/* nand erase using two-plane mode */
+static void single_erase_cmd_planes(struct mtd_info *mtd, int global_page)
+{
+ struct nand_chip *chip = mtd->priv;
+ int page, ppb = mtd->erasesize / mtd->writesize;
+
+ page = (global_page / ppb) * ppb + global_page; /* = global_page%ppb + (global_page/ppb)*ppb*2 */
+
+ /* send cmd 0x60, the MSB should be valid if realplane is 4 */
+ if (chip->realplanenum == 2)
+ {
+ if(global_mafid == 0x2c)
+ chip->cmdfunc(mtd, 0x60, -1, page);
+ else
+ chip->cmdfunc(mtd, 0x60, -1, 0x00);
+ }
+ else
+ chip->cmdfunc(mtd, 0x60, -1, page & (1 << (chip->chip_shift - chip->page_shift)));
+
+ page += ppb;
+ chip->cmdfunc(mtd, 0x60, -1, page & (~(ppb-1))); /* send cmd 0x60 */
+
+ chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); /* send cmd 0xd0 */
+ /* Do not need wait R/B or check status */
+}
+
+#if defined(CONFIG_MTD_NAND_DMA)
+
+#if USE_IRQ
+static irqreturn_t nand_dma_irq(int irq, void *dev_id)
+{
+ u8 dma_chan;
+ volatile int wakeup = 0;
+
+ dma_chan = irq - IRQ_BDMA_0;
+
+ dprintk("jz4760_dma_irq %d, channel %d\n", irq, dma_chan);
+
+ if (__bdmac_channel_transmit_halt_detected(dma_chan)) {
+ __bdmac_channel_clear_transmit_halt(dma_chan);
+ wakeup = 1;
+ printk("DMA HALT\n");
+ }
+
+ if (__bdmac_channel_address_error_detected(dma_chan)) {
+
+ REG_BDMAC_DCCSR(dma_chan) &= ~BDMAC_DCCSR_EN; /* disable DMA */
+ __bdmac_channel_clear_address_error(dma_chan);
+
+ REG_BDMAC_DSAR(dma_chan) = 0; /* reset source address register */
+ REG_BDMAC_DTAR(dma_chan) = 0; /* reset destination address register */
+
+ /* clear address error in BDMACR */
+ REG_BDMAC_DMACR &= ~(1 << 2);
+ wakeup = 1;
+ printk("DMA address error!\n");
+ }
+
+#if 0
+
+ while (!__bdmac_channel_transmit_end_detected(dma_chan));
+
+ if (__bdmac_channel_count_terminated_detected(dma_chan)) {
+ dprintk("DMA CT\n");
+ __bdmac_channel_clear_count_terminated(dma_chan);
+ wakeup = 0;
+ }
+#endif
+
+ if (__bdmac_channel_transmit_end_detected(dma_chan)) {
+ dprintk("DMA TT\n");
+ REG_BDMAC_DCCSR(dma_chan) &= ~BDMAC_DCCSR_EN; /* disable DMA */
+ __bdmac_channel_clear_transmit_end(dma_chan);
+ wakeup = 1;
+ }
+
+ if (wakeup) {
+ dprintk("ack %d irq , wake up dma_chan %d nand_status %d\n", dma_ack, dma_chan, nand_status);
+ /* wakeup wait event */
+ if ((dma_chan == nand_dma_chan) && (nand_status == NAND_PROG)) {
+ dprintk("nand prog dma irq, wake up----\n");
+ dma_ack1 = 1;
+ wake_up_interruptible(&nand_prog_wait_queue);
+ }
+
+ if ((dma_chan == bch_dma_chan) && (nand_status == NAND_READ)) {
+ dprintk("nand read irq, wake up----\n");
+ dma_ack = 1;
+ wake_up_interruptible(&nand_read_wait_queue);
+ }
+ wakeup = 0;
+ }
+
+ return IRQ_HANDLED;
+}
+#endif /* USE_IRQ */
+
+static int jz4760_nand_dma_init(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ int eccsize = chip->ecc.size;
+ int eccsteps = chip->ecc.steps / chip->planenum;
+ int eccbytes = chip->ecc.bytes;
+ int ecc_pos = chip->ecc.layout->eccpos[0];
+ int oob_per_eccsize = ecc_pos / eccsteps;
+ int pagesize = mtd->writesize / chip->planenum;
+ int oobsize = mtd->oobsize / chip->planenum;
+ int i, err;
+ jz_bdma_desc_8word *desc, *dma_desc_bch_ddr, *dma_desc_nand_ddr, *dma_desc_nand_cmd_pgprog;
+ u32 *pval_nand_dcs, *pval_bch_ddr, *pval_bch_dcs, *dummy;
+ u32 next;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ u8 *oobbuf;
+#endif
+
+#if USE_IRQ
+ if ((err = request_irq(IRQ_BDMA_0 + nand_dma_chan, nand_dma_irq, IRQF_DISABLED, "nand_dma", NULL))) {
+ printk("can't reqeust DMA nand channel.\n");
+ return 0;
+ }
+
+ if ((err = request_irq(IRQ_BDMA_0 + bch_dma_chan, nand_dma_irq, IRQF_DISABLED, "bch_dma", NULL))) {
+ printk("bch_dma irq request err\n");
+ return 0;
+ }
+#endif
+
+#if USE_PN
+ dma_desc_pPN = (jz_bdma_desc_8word *)__get_free_page(GFP_KERNEL);
+ dma_desc_rPN = (jz_bdma_desc_8word *)__get_free_page(GFP_KERNEL);
+ pn_buf = kmalloc(2 * sizeof(unsigned int), GFP_KERNEL);
+
+ memset(dma_desc_pPN, 0, 4096);
+ memset(dma_desc_rPN, 0, 4096);
+ memset(pn_buf, 0, 2 * sizeof(unsigned int));
+
+ #if USE_COUNTER
+ *pn_buf = PN_ENABLE | COUNTER_ENABLE;
+ #if COUNT_0
+ *pn_buf |= COUNT_FOR_0;
+ #endif
+ #else
+ *pn_buf = PN_ENABLE;
+ #endif
+
+ *(pn_buf + 1) = PN_DISABLE;
+ dma_cache_wback_inv((unsigned int)pn_buf, 2 * sizeof(unsigned int));
+#endif /* USE_PN */
+
+ __bdmac_channel_enable_clk(nand_dma_chan);
+ __bdmac_channel_enable_clk(bch_dma_chan);
+
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ if (pagesize < 4096) {
+ read_buf = prog_buf = (u8 *) __get_free_page(GFP_KERNEL);
+ } else {
+ read_buf = prog_buf = (u8 *) __get_free_pages(GFP_KERNEL, 1);
+ }
+ if (!read_buf)
+ return -ENOMEM;
+#endif
+ /* space for the error reports of bch decoding((4 * ERRS_SIZE * eccsteps) bytes), and the space for the value
+ * of ddr and dcs of channel 0 and channel nand_dma_chan (4 * (2 + 2) bytes) */
+ errs = (u32 *)kmalloc(4 * (2 + 2 + ERRS_SIZE * eccsteps), GFP_KERNEL);
+ if (!errs)
+ return -ENOMEM;
+
+ pval_nand_ddr = errs + ERRS_SIZE * eccsteps;
+ pval_nand_dcs = pval_nand_ddr + 1;
+ pval_bch_ddr = pval_nand_dcs + 1;
+ pval_bch_dcs = pval_bch_ddr + 1;
+ /* space for nand prog waiting target, the content is useless */
+ dummy = pval_bch_dcs + 1;
+ /* space to store CMD_PGPROG(0x10) or 0x11 */
+ pval_nand_cmd_pgprog = (u32 *)(dummy + 1);
+
+ /* desc can't across 4KB boundary, as desc base address is fixed */
+ /* space of descriptors for nand reading data and oob blocks */
+ dma_desc_nand_read = (jz_bdma_desc_8word *) __get_free_page(GFP_KERNEL);
+ if (!dma_desc_nand_read)
+ return -ENOMEM;
+ memset(dma_desc_nand_read, 0 ,4096);
+
+ /* space of descriptors for bch decoding */
+ dma_desc_dec = dma_desc_nand_read + 2;
+ dma_desc_dec1 = dma_desc_dec + eccsteps;
+ dma_desc_dec2 = dma_desc_dec + eccsteps * 2;
+
+ /* space of descriptors for notifying bch channel */
+ dma_desc_bch_ddr = dma_desc_dec2 + eccsteps;
+
+ /* space of descriptors for bch encoding */
+ dma_desc_enc = dma_desc_bch_ddr + 2;
+ dma_desc_enc1 = dma_desc_enc + eccsteps;
+
+ /* space of descriptors for nand programing data and oob blocks */
+ dma_desc_nand_prog = dma_desc_enc1 + eccsteps;
+
+ /* space of descriptors for nand prog waiting, including pgprog and sync */
+ dma_desc_nand_cmd_pgprog = dma_desc_nand_prog + 2;
+
+ /* space of descriptors for notifying nand channel, including ddr and dcsr */
+ dma_desc_nand_ddr = dma_desc_nand_cmd_pgprog + 2;
+
+/*************************************
+ * Setup of nand programing descriptors
+ *************************************/
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ oobbuf = prog_buf + pagesize;
+#endif
+ /* set descriptor for encoding data blocks */
+ desc = dma_desc_enc;
+ for (i = 0; i < eccsteps; i++) {
+ next = CPHYSADDR((u32)dma_desc_enc1) + i * (sizeof(jz_bdma_desc_8word));
+
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_8 |
+ BDMAC_DCMD_DS_BCH | BDMAC_DCMD_LINK;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)prog_buf) + i * eccsize; /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA target address */
+#endif
+ desc->dcnt = eccsize / DIV_DS_BCH; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_BCH_ENC;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+ desc++;
+ }
+
+ /* set descriptor for encoding oob blocks */
+ desc = dma_desc_enc1;
+ for (i = 0; i < eccsteps; i++) {
+ next = CPHYSADDR((u32)dma_desc_enc) + (i + 1) * (sizeof(jz_bdma_desc_8word));
+
+ desc->dcmd =
+ BDMAC_DCMD_BLAST | BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_8 |
+ BDMAC_DCMD_DWDH_8 | BDMAC_DCMD_DS_8BIT | BDMAC_DCMD_LINK;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + oob_per_eccsize * i; /* DMA source address, 28/4 = 7bytes */
+ desc->dtadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA target address */
+#endif
+ desc->dcnt = oob_per_eccsize; /* size: 7 bytes -> 2 words */
+ desc->dreqt = BDMAC_DRSR_RS_BCH_ENC;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+ desc++;
+ }
+
+ next = CPHYSADDR((u32)dma_desc_nand_ddr);
+ desc--;
+ desc->ddadr = next;
+
+ /* set the descriptor to set door bell of nand_dma_chan for programing nand */
+ desc = dma_desc_nand_ddr;
+ *pval_nand_ddr = 1 << nand_dma_chan;
+ next = CPHYSADDR((u32)dma_desc_nand_ddr) + sizeof(jz_bdma_desc_8word);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((u32)pval_nand_ddr); /* DMA source address */
+ desc->dtadr = CPHYSADDR(BDMAC_DMADBSR); /* nand_dma_chan's descriptor addres register */
+ desc->dcnt = 1; /* size: 1 word */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+ dprintk("*pval_nand_ddr=0x%x\n", *pval_nand_ddr);
+
+ /* set the descriptor to write dccsr of nand_dma_chan for programing nand, dccsr should be set at last */
+ desc++;
+ *pval_nand_dcs = BDMAC_DCCSR_DES8 | BDMAC_DCCSR_EN; /* set value for writing ddr to enable channel nand_dma_chan */
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT;
+ desc->dsadr = CPHYSADDR((u32)pval_nand_dcs); /* DMA source address */
+ desc->dtadr = CPHYSADDR(BDMAC_DCCSR(nand_dma_chan)); /* address of dma door bell set register */
+ desc->dcnt = 1; /* size: 1 word */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ dprintk("*pval_nand_dcs=0x%x\n", *pval_nand_dcs);
+
+#if USE_PN
+ desc = dma_desc_pPN;
+ next = CPHYSADDR((u32)dma_desc_nand_prog);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((unsigned int)pn_buf); /* DMA source address */
+ desc->dtadr = CPHYSADDR(NEMC_PNCR); /* DMA target address */
+ desc->dcnt = 1; /* size: 6 words */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+#endif
+
+ /* set descriptor for nand programing data block */
+ desc = dma_desc_nand_prog;
+ next = CPHYSADDR((u32)dma_desc_nand_prog) + sizeof(jz_bdma_desc_8word);
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_NAND | BDMAC_DCMD_LINK;
+#if USE_DIRECT
+ desc->dcmd |= BDMAC_DCMD_NWR;
+#endif
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)prog_buf); /* DMA source address */
+#endif
+ desc->dtadr = CPHYSADDR((u32)(chip->IO_ADDR_W)); /* DMA target address */
+ desc->dcnt = pagesize / DIV_DS_NAND; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+ /* set descriptor for nand programing oob block */
+ desc++;
+#if USE_PN
+ next = CPHYSADDR((unsigned long)dma_desc_pPN + sizeof(jz_bdma_desc_8word));
+#else
+ next = CPHYSADDR((u32)dma_desc_nand_cmd_pgprog);
+#endif
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_NAND | BDMAC_DCMD_LINK;
+#if USE_DIRECT
+ desc->dcmd |= BDMAC_DCMD_NWR;
+#endif
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)oobbuf); /* DMA source address */
+#endif
+ desc->dtadr = CPHYSADDR((u32)(chip->IO_ADDR_W)); /* DMA target address: dataport */
+ desc->dcnt = oobsize / DIV_DS_NAND; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+#if USE_PN
+ desc = dma_desc_pPN + 1;
+ next = CPHYSADDR((u32)dma_desc_nand_cmd_pgprog);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((unsigned int)pn_buf) + 4; /* DMA source address */
+ desc->dtadr = CPHYSADDR(NEMC_PNCR); /* DMA target address */
+ desc->dcnt = 1; /* size: 6 words */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+#endif
+
+ /* set descriptor for __nand_cmd(CMD_PGPROG) */
+ desc = dma_desc_nand_cmd_pgprog;
+ *pval_nand_cmd_pgprog = NAND_CMD_PAGEPROG | 0x40000000;
+ next = CPHYSADDR((u32)dma_desc_nand_cmd_pgprog) + sizeof(jz_bdma_desc_8word);
+ desc->dcmd =
+ BDMAC_DCMD_NAC | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_XX | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((u32)pval_nand_cmd_pgprog); /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)chip->IO_ADDR_R); /* DMA target address: cmdport */
+ desc->dcnt = 1; /* size: 1 byte */
+ desc->dnt = 0;
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+ /* set descriptor for __nand_sync() */
+ desc++;
+#if USE_IRQ
+ desc->dcmd =
+ BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_TIE;
+#else
+ desc->dcmd =
+ BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT;
+#endif
+ desc->dsadr = CPHYSADDR((u32)pval_nand_ddr); /* DMA source address */
+ desc->dtadr = CPHYSADDR((u32)dummy); /* DMA target address, the content is useless */
+ desc->dcnt = 1; /* size: 1 word */
+ desc->dnt = 1;
+ desc->dreqt = BDMAC_DRSR_RS_NAND;
+ dprintk("1cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+ /* eccsteps*2 + 2 + 2 + 2:
+ dma_desc_enc + dma_desc_enc1 + dma_desc_nand_prog(oob) + dma_desc_nand_ddr(csr)
+ + dma_desc_nand_cmd_pgprog(sync) */
+ dma_cache_wback_inv((u32)dma_desc_enc, (eccsteps * 2 + 2 + 2 + 2) * (sizeof(jz_bdma_desc_8word)));
+ /* 4*6: pval_nand_ddr, pval_nand_dcs, pval_bch_ddr, pval_bch_dcs, dummy, pval_nand_cmd_pgprog */
+ dma_cache_wback_inv((u32)pval_nand_ddr, 4 * 8); /* 8 words, a cache line */
+#if USE_PN
+ dma_cache_wback_inv((unsigned long)dma_desc_pPN, 2*(sizeof(jz_bdma_desc_8word)));
+#endif
+
+/*************************************
+ * Setup of nand reading descriptors
+ *************************************/
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ oobbuf = read_buf + pagesize;
+#endif
+
+#if USE_PN
+ desc = dma_desc_rPN;
+ next = CPHYSADDR((u32)dma_desc_nand_read);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((u32)pn_buf); /* DMA source address */
+ desc->dtadr = CPHYSADDR(NEMC_PNCR); /* DMA target address */
+ desc->dcnt = 1; /* size: 6 words */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+#endif
+
+ /* set descriptor for nand reading data block */
+ desc = dma_desc_nand_read;
+ next = CPHYSADDR((u32)dma_desc_nand_read) + sizeof(jz_bdma_desc_8word);
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_NAND | BDMAC_DCMD_LINK;
+#if USE_DIRECT
+ desc->dcmd |= BDMAC_DCMD_NRD;
+#endif
+ desc->dsadr = CPHYSADDR((u32)(chip->IO_ADDR_R)); /* DMA source address */
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dtadr = CPHYSADDR((u32)read_buf); /* DMA target address */
+#endif
+ desc->dcnt = pagesize / DIV_DS_NAND; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_NAND;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+ /* set descriptor for nand reading oob block */
+ desc++;
+#if USE_PN
+ next = CPHYSADDR((u32)dma_desc_rPN + sizeof(jz_bdma_desc_8word));
+#else
+ next = CPHYSADDR((u32)dma_desc_bch_ddr);
+#endif
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_NAND | BDMAC_DCMD_LINK;
+#if USE_DIRECT
+ desc->dcmd |= BDMAC_DCMD_NRD;
+#endif
+ desc->dsadr = CPHYSADDR((u32)(chip->IO_ADDR_R)); /* DMA source address */
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dtadr = CPHYSADDR((u32)oobbuf); /* DMA target address */
+#endif
+ desc->dcnt = oobsize / DIV_DS_NAND; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+ dprintk("cmd:%x sadr:%x tadr:%x dadr:%x\n", desc->dcmd, desc->dsadr, desc->dtadr, desc->ddadr);
+
+#if USE_PN
+ desc = dma_desc_rPN + 1;
+ next = CPHYSADDR((u32)dma_desc_bch_ddr);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((u32)pn_buf) + 4; /* DMA source address */
+ desc->dtadr = CPHYSADDR(NEMC_PNCR); /* DMA target address */
+ desc->dcnt = 1; /* size: 6 words */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+#endif
+
+ /* set the descriptor to set door bell for bch */
+ desc = dma_desc_bch_ddr;
+ *pval_bch_ddr = BDMAC_DMADBSR_DBS0; // set value for writing ddr to enable channel 0
+ next = CPHYSADDR((u32)dma_desc_bch_ddr) + sizeof(jz_bdma_desc_8word);
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+ desc->dsadr = CPHYSADDR((u32)pval_bch_ddr); /* DMA source address */
+ desc->dtadr = CPHYSADDR(BDMAC_DMADBSR); /* channel 1's descriptor addres register */
+ desc->dcnt = 1; /* size: 1 word */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+ desc->ddadr = next;
+
+ /* set descriptor for writing dcsr */
+ desc++;
+ *pval_bch_dcs = BDMAC_DCCSR_DES8 | BDMAC_DCCSR_EN; // set value for writing ddr to enable channel 1
+ desc->dcmd = BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT;
+ desc->dsadr = CPHYSADDR((u32)pval_bch_dcs); /* DMA source address */
+ desc->dtadr = CPHYSADDR(BDMAC_DCCSR(bch_dma_chan)); /* address of dma door bell set register */
+ desc->dcnt = 1; /* size: 1 word */
+ desc->dreqt = BDMAC_DRSR_RS_AUTO;
+
+ /* descriptors for data to be written to bch */
+ desc = dma_desc_dec;
+ for (i = 0; i < eccsteps; i++) {
+ next = CPHYSADDR((u32)dma_desc_dec1 + i * (sizeof(jz_bdma_desc_8word)));
+
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_32 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_BCH | BDMAC_DCMD_LINK;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)read_buf) + i * eccsize; /* DMA source address */
+#endif
+ desc->dtadr = CPHYSADDR((u32)errs) + i * 4 * ERRS_SIZE; /* DMA target address */
+ desc->dcnt = eccsize / DIV_DS_BCH; /* size: eccsize bytes */
+ desc->dreqt = BDMAC_DRSR_RS_BCH_DEC;
+ desc->ddadr = next;
+ dprintk("desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptors for oob to be written to bch */
+ desc = dma_desc_dec1;
+ for (i = 0; i < eccsteps; i++) {
+ next = CPHYSADDR((u32)dma_desc_dec2 + i * (sizeof(jz_bdma_desc_8word)));
+
+ desc->dcmd =
+ BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_8 | BDMAC_DCMD_DWDH_32 |
+ BDMAC_DCMD_DS_8BIT | BDMAC_DCMD_LINK;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + oob_per_eccsize * i; /* DMA source address */
+#endif
+ desc->dtadr = CPHYSADDR((u32)errs) + i * 4 * ERRS_SIZE; /* DMA target address */
+ desc->dcnt = oob_per_eccsize; /* size: 7 bytes */
+ desc->dreqt = BDMAC_DRSR_RS_BCH_DEC;
+ desc->ddadr = next;
+ dprintk("desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+
+ /* descriptors for parities to be written to bch */
+ desc = dma_desc_dec2;
+ for (i = 0; i < eccsteps; i++) {
+ next = CPHYSADDR((u32)dma_desc_dec) + (i + 1) * (sizeof(jz_bdma_desc_8word));
+
+ desc->dcmd =
+ BDMAC_DCMD_BLAST | BDMAC_DCMD_SAI | BDMAC_DCMD_DAI | BDMAC_DCMD_SWDH_8 |
+ BDMAC_DCMD_DWDH_32 | BDMAC_DCMD_DS_32BIT | BDMAC_DCMD_LINK;
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ desc->dsadr = CPHYSADDR((u32)oobbuf) + ecc_pos + i * eccbytes; /* DMA source address */
+#endif
+ desc->dtadr = CPHYSADDR((u32)errs) + i * 4 * ERRS_SIZE; /* DMA target address */
+ desc->dcnt = (eccbytes + 3) / 4; /* size: eccbytes bytes */
+ desc->dreqt = BDMAC_DRSR_RS_BCH_DEC;
+ desc->ddadr = next;
+ dprintk("desc:%x cmd:%x sadr:%x tadr:%x dadr:%x\n", (u32)desc, desc->dcmd, desc->dsadr, desc->dtadr,
+ desc->ddadr);
+ desc++;
+ }
+ desc--;
+ desc->dcmd &= ~BDMAC_DCMD_LINK;
+#if USE_IRQ
+ desc->dcmd |= BDMAC_DCMD_TIE;
+#endif
+
+ dma_cache_wback_inv((u32)dma_desc_nand_read, (2 + 2 + eccsteps * 3) * (sizeof(jz_bdma_desc_8word)));
+ dma_cache_wback_inv((u32)pval_bch_ddr, 4 * 2); /* two words */
+#if USE_PN
+ dma_cache_wback_inv((unsigned long)dma_desc_rPN, 2*(sizeof(jz_bdma_desc_8word)));
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_MTD_NAND_DMA */
+/*
+ * Main initialization routine
+ */
+int __init jznand_init(void)
+{
+ struct nand_chip *this;
+ int nr_partitions, ret, i;
+
+ printk(KERN_INFO "JZ NAND init");
+#if defined(CONFIG_MTD_NAND_DMA)
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ printk(KERN_INFO " DMA mode, using DMA buffer in NAND driver.\n");
+#else
+ printk(KERN_INFO " DMA mode, using DMA buffer in upper layer.\n");
+#endif
+#else
+ printk(KERN_INFO " CPU mode.\n");
+#endif
+
+ cpm_start_clock(CGM_BDMA);
+
+ /* Allocate memory for MTD device structure and private data */
+ jz_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
+ if (!jz_mtd) {
+ printk("Unable to allocate JzSOC NAND MTD device structure.\n");
+ return -ENOMEM;
+ }
+
+ /* Allocate memory for NAND when using only one plane */
+ jz_mtd1 = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
+ if (!jz_mtd1) {
+ printk ("Unable to allocate JzSOC NAND MTD device structure 1.\n");
+ kfree(jz_mtd);
+ return -ENOMEM;
+ }
+
+ /* Get pointer to private data */
+ this = (struct nand_chip *)(&jz_mtd[1]);
+
+ /* Initialize structures */
+ memset((char *)jz_mtd, 0, sizeof(struct mtd_info));
+ memset((char *)this, 0, sizeof(struct nand_chip));
+
+#ifdef CONFIG_MTD_NAND_BUS_WIDTH_16
+ this->options |= NAND_BUSWIDTH_16;
+#endif
+
+ /* Link the private data with the MTD structure */
+ jz_mtd->priv = this;
+
+
+ addr_offset = NAND_ADDR_OFFSET0;
+ cmd_offset = NAND_CMD_OFFSET0;
+
+ /* Set & initialize NAND Flash controller */
+ jz_device_setup();
+
+ /* Set address of NAND IO lines to static bank1 by default */
+ this->IO_ADDR_R = (void __iomem *)NAND_DATA_PORT1;
+ this->IO_ADDR_W = (void __iomem *)NAND_DATA_PORT1;
+ this->cmd_ctrl = jz_hwcontrol;
+ this->dev_ready = jz_device_ready;
+
+#ifdef CONFIG_MTD_HW_BCH_ECC
+ this->ecc.calculate = jzsoc_nand_calculate_bch_ecc;
+ this->ecc.correct = jzsoc_nand_bch_correct_data;
+ this->ecc.hwctl = jzsoc_nand_enable_bch_hwecc;
+ this->ecc.mode = NAND_ECC_HW;
+ this->ecc.size = 512;
+ this->ecc.read_page = nand_read_page_hwecc_bch;
+ this->ecc.write_page = nand_write_page_hwecc_bch;
+#if defined(CONFIG_MTD_HW_BCH_24BIT)
+ this->ecc.bytes = 39;
+#elif defined(CONFIG_MTD_HW_BCH_20BIT)
+ this->ecc.bytes = 33;
+#elif defined(CONFIG_MTD_HW_BCH_16BIT)
+ this->ecc.bytes = 26;
+#elif defined(CONFIG_MTD_HW_BCH_12BIT)
+ this->ecc.bytes = 20;
+#elif defined(CONFIG_MTD_HW_BCH_8BIT)
+ this->ecc.bytes = 13;
+#else
+ this->ecc.bytes = 7;
+#endif
+#endif
+
+#ifdef CONFIG_MTD_SW_HM_ECC
+ this->ecc.mode = NAND_ECC_SOFT;
+#endif
+ /* 20 us command delay time */
+ this->chip_delay = 20;
+ /* Scan to find existance of the device */
+ ret = nand_scan_ident(jz_mtd, NAND_MAX_CHIPS);
+
+ if (!ret) {
+ if (this->planenum == 2) {
+ /* reset nand functions */
+ this->erase_cmd = single_erase_cmd_planes;
+ this->ecc.read_page = nand_read_page_hwecc_bch_planes;
+ this->ecc.write_page = nand_write_page_hwecc_bch_planes;
+ this->ecc.read_oob = nand_read_oob_std_planes;
+ this->ecc.write_oob = nand_write_oob_std_planes;
+
+ printk(KERN_INFO "Nand using two-plane mode, "
+ "and resized to writesize:%d oobsize:%d blocksize:0x%x \n",
+ jz_mtd->writesize, jz_mtd->oobsize, jz_mtd->erasesize);
+ }
+ }
+
+ /* Determine whether all the partitions will use multiple planes if supported */
+ nr_partitions = sizeof(partition_info) / sizeof(struct mtd_partition);
+ all_use_planes = 1;
+ for (i = 0; i < nr_partitions; i++) {
+ all_use_planes &= partition_info[i].use_planes;
+ }
+
+ if (!ret)
+ ret = nand_scan_tail(jz_mtd);
+
+ if (ret){
+ kfree (jz_mtd1);
+ kfree (jz_mtd);
+ return -ENXIO;
+ }
+
+#if defined(CONFIG_MTD_NAND_DMA)
+ jz4760_nand_dma_init(jz_mtd);
+#endif
+
+ ((struct nand_chip *) (&jz_mtd1[1]))->ecc.read_page = nand_read_page_hwecc_bch;
+ ((struct nand_chip *) (&jz_mtd1[1]))->ecc.write_page = nand_write_page_hwecc_bch;
+
+ /* Register the partitions */
+ printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nr_partitions, jz_mtd->name);
+
+ if ((this->planenum == 2) && !all_use_planes) {
+ for (i = 0; i < nr_partitions; i++) {
+ if (partition_info[i].use_planes)
+ add_mtd_partitions(jz_mtd, &partition_info[i], 1);
+ else
+ add_mtd_partitions(jz_mtd1, &partition_info[i], 1);
+ }
+ } else {
+ kfree(jz_mtd1);
+ add_mtd_partitions(jz_mtd, partition_info, nr_partitions);
+ }
+ return 0;
+}
+
+module_init(jznand_init);
+
+/*
+ * Clean up routine
+ */
+#ifdef MODULE
+
+#if defined(CONFIG_MTD_NAND_DMA)
+static int jz4760_nand_dma_exit(struct mtd_info *mtd)
+{
+ int pagesize = mtd->writesize / chip->planenum;
+
+#if USE_IRQ
+ free_irq(IRQ_BDMA_0 + nand_dma_chan, NULL);
+ free_irq(IRQ_BDMA_0 + bch_dma_chan, NULL);
+#endif
+
+ /* space for the error reports of bch decoding((4 * 5 * eccsteps) bytes),
+ * and the space for the value of ddr and dcs of channel 0 and channel
+ * nand_dma_chan (4 * (2 + 2) bytes) */
+ kfree(errs);
+
+ /* space for dma_desc_nand_read contains dma_desc_nand_prog,
+ * dma_desc_enc and dma_desc_dec */
+ free_page((u32)dma_desc_nand_read);
+
+#if defined(CONFIG_MTD_NAND_DMABUF)
+ if (pagesize < 4096) {
+ free_page((u32)prog_buf);
+ } else {
+ free_pages((u32)prog_buf, 1);
+ }
+#endif
+
+#if USE_PN
+ free_page((u32)dma_desc_pPN);
+ free_page((u32)dma_desc_rPN);
+ kfree(pn_buf);
+#endif
+
+ return 0;
+}
+#endif
+
+static void __exit jznand_cleanup(void)
+{
+#if defined(CONFIG_MTD_NAND_DMA)
+ jz4760_nand_dma_exit(jz_mtd);
+#endif
+
+ /* Unregister partitions */
+ del_mtd_partitions(jz_mtd);
+
+ /* Unregister the device */
+ del_mtd_device(jz_mtd);
+
+ /* Free the MTD device structure */
+ if ((this->planenum == 2) && !all_use_planes)
+ kfree (jz_mtd1);
+ kfree(jz_mtd);
+}
+
+module_exit(jznand_cleanup);
+#endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 39f21d5f321..38dcee7469a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -218,13 +218,23 @@ config JZ_ETH
config JZCS8900
tristate "JZ CS8900A Ethernet support"
- depends on NET_ETHERNET && (SOC_JZ4740 || SOC_JZ4750)
+ depends on NET_ETHERNET && (SOC_JZ4740 || SOC_JZ4750 || SOC_JZ4760 )
help
Say Y for support of JZ CS8900A Ethernet interface.
To compile this driver as a module, choose M here: the module
will be called jzcs8900a.
+config JZ4760_ETH
+ tristate "JZ4760 On-Chip Ethernet support"
+ depends on NET_ETHERNET && (SOC_JZ4760 || SOC_JZ4810 || JZ_FPGA)
+ help
+ Say Y for support of JZ4760 On-Chip Ethernet interface.
+
+ To compile this driver as a module, choose M here: the module
+ will be called jz4760_eth.
+
+
config MACB
tristate "Atmel MACB support"
depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b90ef6b65f8..b723ed5fac6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -105,6 +105,7 @@ obj-$(CONFIG_PHYLIB) += phy/
obj-$(CONFIG_JZ_ETH) += jz_eth.o
obj-$(CONFIG_JZCS8900) += jzcs8900a.o
+obj-$(CONFIG_JZ4760_ETH) += jz4760_eth.o
obj-$(CONFIG_SUNDANCE) += sundance.o
obj-$(CONFIG_HAMACHI) += hamachi.o
diff --git a/drivers/net/jz4760_eth.c b/drivers/net/jz4760_eth.c
new file mode 100644
index 00000000000..aced853a23f
--- /dev/null
+++ b/drivers/net/jz4760_eth.c
@@ -0,0 +1,1970 @@
+/*
+ * linux/drivers/net/jz4760_eth.c
+ *
+ * Jz4760 On-Chip ethernet driver.
+ *
+ * Copyright (C) 2005 - 2007 Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/skbuff.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/kthread.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <asm/cacheops.h>
+#include <asm/jzsoc.h>
+
+#include "jz4760_eth.h"
+
+#define P2ADDR(a) (((unsigned long)(a) & 0x1fffffff) | 0xa0000000)
+#define P1ADDR(a) (((unsigned long)(a) & 0x1fffffff) | 0x80000000)
+
+#if 0
+#define DUMP_RX_BUF_ADDR_MAX 256
+#define DUMP_TX_BUF_ADDR_MAX 256
+
+static unsigned int rx_buf_addr_array[DUMP_RX_BUF_ADDR_MAX] = {0};
+static int rx_buf_addr_array_idx = 0;
+static unsigned int tx_buf_addr_array[DUMP_TX_BUF_ADDR_MAX] = {0};
+static int tx_buf_addr_array_idx = 0;
+
+static void dump_eth_rx_addr()
+{
+ int i;
+ for (i = 0; i < rx_buf_addr_array_idx; i++) {
+ printk("rx_buf_addr_array[%d] = 0x%08x\n", i, rx_buf_addr_array[i]);
+ }
+}
+static void dump_eth_tx_addr()
+{
+ int i;
+ for (i = 0; i < tx_buf_addr_array_idx; i++) {
+ printk("tx_buf_addr_array[%d] = 0x%08x\n", i, tx_buf_addr_array[i]);
+ }
+}
+#endif
+
+//#define USE_RMII 1
+//#define ETH_DEBUG
+#ifdef ETH_DEBUG
+#define DBPRINTK(fmt,args...) printk(KERN_DEBUG fmt,##args)
+#else
+#define DBPRINTK(fmt,args...) do {} while(0)
+#endif
+
+#define errprintk(fmt,args...) printk(KERN_ERR fmt,##args);
+#define infoprintk(fmt,args...) printk(KERN_INFO fmt,##args);
+
+#define DRV_NAME "jz4760_eth"
+#define DRV_VERSION "0.1"
+#define DRV_AUTHOR "Jason Wang <xwang@ingenic.cn>"
+#define DRV_DESC "JzSOC 4760 On-chip Ethernet driver"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+MODULE_PARM_DESC(debug, "i");
+MODULE_PARM_DESC(hwaddr,"s");
+
+/*
+ * Local variables
+ */
+static struct net_device *netdev;
+static char * hwaddr = NULL;
+static int debug = -1;
+static struct mii_if_info mii_info;
+
+/*
+ * Local routines
+ */
+static irqreturn_t jz_eth_interrupt(int irq, void *dev_id);
+static int link_check_thread (void *data);
+
+#if 0
+/*
+ * Get MAC address
+ */
+
+#define I2C_DEVICE 0x57
+#define MAC_OFFSET 64
+
+extern void i2c_open(void);
+extern void i2c_close(void);
+extern int i2c_read(unsigned char device, unsigned char *buf,
+ unsigned char address, int count);
+#endif
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+static int ethaddr_cmd = 0;
+static unsigned char ethaddr_hex[6];
+
+static int __init ethernet_addr_setup(char *str)
+{
+ if (!str) {
+ printk("ethaddr not set in command line\n");
+ return -1;
+ }
+ ethaddr_cmd = 1;
+ str2eaddr(ethaddr_hex, str);
+
+ return 0;
+}
+
+__setup("ethaddr=", ethernet_addr_setup);
+
+static int get_mac_address(struct net_device *dev)
+{
+ int i;
+ unsigned char flag0=0;
+ unsigned char flag1=0xff;
+
+ dev->dev_addr[0] = 0xff;
+ if (hwaddr != NULL) {
+ /* insmod jz-ethc.o hwaddr=00:ef:a3:c1:00:10 */
+ str2eaddr(dev->dev_addr, hwaddr);
+ } else if (ethaddr_cmd) {
+ /* linux command line: ethaddr=00:ef:a3:c1:00:10 */
+ for (i=0; i<6; i++)
+ dev->dev_addr[i] = ethaddr_hex[i];
+ } else {
+#if 0
+ /* mac address in eeprom: byte 0x40-0x45 */
+ i2c_open();
+ i2c_read(I2C_DEVICE, dev->dev_addr, MAC_OFFSET, 6);
+ i2c_close();
+#endif
+ }
+
+ /* check whether valid MAC address */
+ for (i=0; i<6; i++) {
+ flag0 |= dev->dev_addr[i];
+ flag1 &= dev->dev_addr[i];
+ }
+ if ((dev->dev_addr[0] & 0xC0) || (flag0 == 0) || (flag1 == 0xff)) {
+ printk("WARNING: There is not MAC address, use default ..\n");
+ dev->dev_addr[0] = 0x00;
+ dev->dev_addr[1] = 0xef;
+ dev->dev_addr[2] = 0xa3;
+ dev->dev_addr[3] = 0xc1;
+ dev->dev_addr[4] = 0x00;
+ dev->dev_addr[5] = 0x10;
+ dev->dev_addr[5] = 0x03;
+ }
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------*/
+
+static u32 jz_eth_curr_mode(struct net_device *dev);
+
+/*
+ * Link check routines
+ */
+static void start_check(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+ struct task_struct *t;
+
+ np->thread_die = 0;
+ init_waitqueue_head(&np->thr_wait);
+ init_completion(&np->thr_exited);
+
+ t = kthread_create(link_check_thread,(void *)dev, dev->name);
+ if (IS_ERR(t))
+ errprintk("%s: Unable to start kernel thread\n",dev->name);
+ np->thread = t;
+}
+
+static int close_check(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+ int ret = 0;
+
+ if (np->thread != NULL) {
+ np->thread_die = 1;
+ wmb();
+ send_sig(SIGTERM, np->thread, 1);
+ if (ret) {
+ errprintk("%s: Unable to signal thread\n", dev->name);
+ return 1;
+ }
+ wait_for_completion (&np->thr_exited);
+ }
+ return 0;
+}
+
+static int link_check_thread(void *data)
+{
+ struct net_device *dev=(struct net_device *)data;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)netdev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unsigned char current_link;
+ unsigned long timeout;
+
+ daemonize("%s", dev->name);
+ spin_lock_irq(&current->sighand->siglock);
+ sigemptyset(&current->blocked);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ strncpy(current->comm, dev->name, sizeof(current->comm) - 1);
+ current->comm[sizeof(current->comm) - 1] = '\0';
+
+ while (1) {
+ timeout = 3*HZ;
+ do {
+ timeout = interruptible_sleep_on_timeout(&np->thr_wait, timeout);
+ /* make swsusp happy with our thread */
+// if (current->flags & PF_FREEZE)
+// refrigerator(PF_FREEZE);
+ } while (!signal_pending(current) && (timeout > 0));
+
+ if (signal_pending (current)) {
+ spin_lock_irq(&current->sighand->siglock);
+ flush_signals(current);
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+
+ if (np->thread_die)
+ break;
+
+ current_link = mii_link_ok(&mii_info);
+ if (np->link_state != current_link) {
+ if (current_link) {
+ infoprintk("%s: Ethernet Link OK!\n", dev->name);
+ jz_eth_curr_mode(dev);
+ netif_carrier_on(dev);
+ } else {
+ errprintk("%s: Ethernet Link offline!\n", dev->name);
+ netif_carrier_off(dev);
+ }
+ }
+ np->link_state = current_link;
+
+ }
+ complete_and_exit(&np->thr_exited, 0);
+}
+
+static void skb_dump(struct sk_buff *skb)
+{
+ printk("skb ----------- [ 0x%08x ]\n", (unsigned int)skb);
+ printk("head = 0x%08x, data = 0x%08x, tail = 0x%08x, end = 0x%08x\n",
+ (unsigned int)(skb->head), (unsigned int)(skb->data),
+ (unsigned int)(skb->tail), (unsigned int)(skb->end));
+ printk("truesize = %d (0x%08x), len = %d (0x%08x)\n",
+ skb->truesize, skb->truesize, skb->len, skb->len);
+ printk("headroom = %d (0x%08x), tailroom = %d (0x%08x)\n",
+ skb_headroom(skb), skb_headroom(skb), skb_tailroom(skb), skb_tailroom(skb));
+ printk("---------------------------\n");
+}
+
+#ifdef ETH_DEBUG
+
+static void priv_data_dump(struct jz_eth_private *priv)
+{
+ printk("---- priv [0x%08x] -----------------------\n"
+ "tx_ring = 0x%08x, rx_ring = 0x%08x\n"
+ "dma_tx_ring = 0x%08x, dma_rx_ring = 0x%08x\n"
+ "dma_rx_buf = 0x%08x, vaddr_rx_buf = 0x%08x\n"
+ "rx_head = 0x%08x, tx_head = 0x%08x\n"
+ "tx_tail = 0x%08x, tx_full = 0x%08x, tx_skb = 0x%08x\n"
+ "---------------------------\n",
+ (unsigned int)priv,
+ (unsigned int)priv->tx_ring, (unsigned int)priv->rx_ring,
+ (unsigned int)priv->dma_tx_ring, (unsigned int)priv->dma_rx_ring,
+ (unsigned int)priv->dma_rx_buf, (unsigned int)priv->vaddr_rx_buf,
+ (unsigned int)priv->rx_head, (unsigned int)priv->tx_head,
+ (unsigned int)priv->tx_tail, (unsigned int)priv->tx_full, (unsigned int)priv->tx_skb);
+}
+
+static void desc_dump(struct jz_eth_private *np)
+{
+ int i;
+
+ printk("==================================================\n");
+
+ dma_cache_inv((unsigned int)np->tx_ring, sizeof(jz_desc_t) * NUM_TX_DESCS);
+ dma_cache_inv((unsigned int)np->rx_ring, sizeof(jz_desc_t) * NUM_RX_DESCS);
+
+ for (i = 0; i < NUM_TX_DESCS; i++) {
+ printk("tx desc %2d :[0x%08x], addr = 0x%08x, pkt_size = 0x%08x, next = 0x%08x\n",
+ i, (unsigned int)&(np->tx_ring[i]), (unsigned int)np->tx_ring[i].pkt_addr,
+ (unsigned int)np->tx_ring[i].pkt_size, (unsigned int)np->tx_ring[i].next_desc);
+ }
+
+ printk("\n");
+
+ for (i = 0; i < 30/*NUM_RX_DESCS*/; i++) {
+ printk("rx desc %2d :[0x%08x], addr = 0x%08x, pkt_size = 0x%08x, next = 0x%08x\n",
+ i, (unsigned int)&(np->rx_ring[i]), (unsigned int)np->rx_ring[i].pkt_addr,
+ (unsigned int)np->rx_ring[i].pkt_size, (unsigned int)np->rx_ring[i].next_desc);
+ }
+
+ printk("REG32(ETH_DMA_TDR) = 0x%08x\nREG32(ETH_DMA_RDR) = 0x%08x\n",
+ REG32(ETH_DMA_TDR), REG32(ETH_DMA_RDR));
+
+ printk("t pkt_addr = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_TDR)))->pkt_addr);
+ printk("t pkt_size = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_TDR)))->pkt_size);
+ printk("t next_desc = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_TDR)))->next_desc);
+
+ printk("r pkt_addr = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_RDR)))->pkt_addr);
+ printk("r pkt_size = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_RDR)))->pkt_size);
+ printk("r next_desc = 0x%08x\n", ((jz_desc_t *)P2ADDR(REG32(ETH_DMA_RDR)))->next_desc);
+
+ //priv_data_dump(np);
+ printk("==================================================\n");
+}
+
+static void dma_regs_dump(char *str)
+{
+ printk("%s", str);
+ printk("==================================================\n");
+ printk("DMA_TCR = 0x%08x DMA_TDR = 0x%08x\n", REG32(ETH_DMA_TCR), REG32(ETH_DMA_TDR));
+ printk("DMA_TSR = 0x%08x DMA_RCR = 0x%08x\n", REG32(ETH_DMA_TSR), REG32(ETH_DMA_RCR));
+ printk("DMA_RDR = 0x%08x DMA_RSR = 0x%08x\n", REG32(ETH_DMA_RDR), REG32(ETH_DMA_RSR));
+ printk("DMA_IMR = 0x%08x DMA_IR = 0x%08x\n", REG32(ETH_DMA_IMR), REG32(ETH_DMA_IR));
+ printk("==================================================\n");
+}
+
+static void mac_regs_dump(void)
+{
+ printk("==================================================\n");
+ printk("MAC_MCR1 = 0x%08x MAC_MCR2 = 0x%08x\n", REG32(ETH_MAC_MCR1), REG32(ETH_MAC_MCR2));
+ printk("MAC_IPGR = 0x%08x MAC_NIPGR= 0x%08x\n", REG32(ETH_MAC_IPGR), REG32(ETH_MAC_NIPGR));
+ printk("MAC_CWR = 0x%08x MAC_MFR = 0x%08x\n", REG32(ETH_MAC_CWR), REG32(ETH_MAC_MFR));
+ printk("MAC_PSR = 0x%08x MAC_TR = 0x%08x\n", REG32(ETH_MAC_PSR), REG32(ETH_MAC_TR));
+ printk("MAC_MCFGR= 0x%08x MAC_MCMDR= 0x%08x\n", REG32(ETH_MAC_MCFGR), REG32(ETH_MAC_MCMDR));
+ printk("MAC_MADRR= 0x%08x MAC_MINDR= 0x%08x\n", REG32(ETH_MAC_MADRR), REG32(ETH_MAC_MINDR));
+ printk("MAC_SA0 = 0x%08x MAC_SA1 = 0x%08x MAC_SA2 = 0x%08x\n",
+ REG32(ETH_MAC_SA0), REG32(ETH_MAC_SA1), REG32(ETH_MAC_SA2));
+ printk("==================================================\n");
+}
+
+static void fifo_regs_dump(void)
+{
+ printk("==================================================\n");
+ printk("FIFO_CR0 = 0x%08x\n", REG32(ETH_FIFO_CR0));
+ printk("FIFO_CR1 = 0x%08x\n", REG32(ETH_FIFO_CR1));
+ printk("FIFO_CR2 = 0x%08x\n", REG32(ETH_FIFO_CR2));
+ printk("FIFO_CR3 = 0x%08x\n", REG32(ETH_FIFO_CR3));
+ printk("FIFO_CR4 = 0x%08x\n", REG32(ETH_FIFO_CR4));
+ printk("FIFO_CR5 = 0x%08x\n", REG32(ETH_FIFO_CR5));
+#if 0
+ printk("RAR0 = 0x%08x RAR1 = 0x%08x\n", REG32(ETH_FIFO_RAR0), REG32(ETH_FIFO_RAR1));
+ printk("RAR2 = 0x%08x RAR3 = 0x%08x\n", REG32(ETH_FIFO_RAR2), REG32(ETH_FIFO_RAR3));
+ printk("RAR4 = 0x%08x RAR5 = 0x%08x\n", REG32(ETH_FIFO_RAR4), REG32(ETH_FIFO_RAR5));
+ printk("RAR6 = 0x%08x RAR7 = 0x%08x\n", REG32(ETH_FIFO_RAR6), REG32(ETH_FIFO_RAR7));
+#endif
+ printk("==================================================\n");
+}
+
+static void stat_regs_dump(void)
+{
+
+ printk("==================================================\n");
+ printk("ETH_STAT_TR64= 0x%08x, ETH_STAT_TR127= 0x%08x, ETH_STAT_TR255= 0x%08x, ETH_STAT_TR511= 0x%08x\n",
+ REG32(ETH_STAT_TR64), REG32(ETH_STAT_TR127), REG32(ETH_STAT_TR255), REG32(ETH_STAT_TR511));
+ printk("ETH_STAT_TR1K= 0x%08x, ETH_STAT_TRMAX= 0x%08x, ETH_STAT_TRMGV= 0x%08x\n",
+ REG32(ETH_STAT_TR1K), REG32(ETH_STAT_TRMAX), REG32(ETH_STAT_TRMGV));
+
+ printk("------\nETH_STAT_RBYT= 0x%08x, ETH_STAT_RPKT= 0x%08x, ETH_STAT_RFCS= 0x%08x, ETH_STAT_RMCA= 0x%08x\n",
+ REG32(ETH_STAT_RBYT), REG32(ETH_STAT_RPKT), REG32(ETH_STAT_RFCS), REG32(ETH_STAT_RMCA));
+ printk("ETH_STAT_RDRP= 0x%08x\n", REG32(ETH_STAT_RDRP));
+
+ printk("------\nETH_STAT_TBYT= 0x%08x, ETH_STAT_TPKT= 0x%08x, ETH_STAT_TFCS = 0x%08x, ETH_STAT_TNCL= 0x%08x\n",
+ REG32(ETH_STAT_TBYT), REG32(ETH_STAT_TPKT), REG32(ETH_STAT_TFCS), REG32(ETH_STAT_TNCL));
+ printk("ETH_STAT_TDRP= 0x%08x\n", REG32(ETH_STAT_TDRP));
+ printk("==================================================\n");
+
+/*
+ printk("==================================================\n");
+
+ printk("ETH_STAT_TR64= 0x%08x, ETH_STAT_TR127= 0x%08x, ETH_STAT_TR255= 0x%08x, ETH_STAT_TR511= 0x%08x\n",
+ REG32(ETH_STAT_TR64), REG32(ETH_STAT_TR127), REG32(ETH_STAT_TR255), REG32(ETH_STAT_TR511));
+ printk("ETH_STAT_TR1K= 0x%08x, ETH_STAT_TRMAX= 0x%08x, ETH_STAT_TRMGV= 0x%08x\n",
+ REG32(ETH_STAT_TR1K), REG32(ETH_STAT_TRMAX), REG32(ETH_STAT_TRMGV));
+ printk("ETH_STAT_RBYT= 0x%08x, ETH_STAT_RPKT= 0x%08x, ETH_STAT_RFCS= 0x%08x, ETH_STAT_RMCA= 0x%08x\n",
+ REG32(ETH_STAT_RBYT), REG32(ETH_STAT_RPKT), REG32(ETH_STAT_RFCS), REG32(ETH_STAT_RMCA));
+ printk("ETH_STAT_RBCA= 0x%08x, ETH_STAT_RXCF= 0x%08x, ETH_STAT_RXPF= 0x%08x, ETH_STAT_RXUO= 0x%08x\n",
+ REG32(ETH_STAT_RBCA), REG32(ETH_STAT_RXCF), REG32(ETH_STAT_RXPF), REG32(ETH_STAT_RXUO));
+ printk("ETH_STAT_RALN= 0x%08x, ETH_STAT_RFLR= 0x%08x, ETH_STAT_RCDE= 0x%08x, ETH_STAT_RCSE= 0x%08x\n",
+ REG32(ETH_STAT_RALN), REG32(ETH_STAT_RFLR), REG32(ETH_STAT_RCDE), REG32(ETH_STAT_RCSE));
+ printk("ETH_STAT_RUND= 0x%08x, ETH_STAT_ROVR= 0x%08x, ETH_STAT_RFRG= 0x%08x, ETH_STAT_RJBR= 0x%08x\n",
+ REG32(ETH_STAT_RUND), REG32(ETH_STAT_ROVR), REG32(ETH_STAT_RFRG), REG32(ETH_STAT_RJBR));
+ printk("ETH_STAT_RDRP= 0x%08x\n", REG32(ETH_STAT_RDRP));
+ printk("ETH_STAT_TBYT= 0x%08x, ETH_STAT_TPKT= 0x%08x, ETH_STAT_TMCA= 0x%08x, ETH_STAT_TBCA= 0x%08x\n",
+ REG32(ETH_STAT_TBYT), REG32(ETH_STAT_TPKT), REG32(ETH_STAT_TMCA), REG32(ETH_STAT_TBCA));
+ printk("ETH_STAT_TXPF= 0x%08x, ETH_STAT_TDFR= 0x%08x, ETH_STAT_TEDF= 0x%08x, ETH_STAT_TSCL= 0x%08x\n",
+ REG32(ETH_STAT_TXPF), REG32(ETH_STAT_TDFR), REG32(ETH_STAT_TEDF), REG32(ETH_STAT_TSCL));
+ printk("ETH_STAT_TMCL= 0x%08x, ETH_STAT_TLCL= 0x%08x, ETH_STAT_TXCL= 0x%08x, ETH_STAT_TNCL= 0x%08x\n",
+ REG32(ETH_STAT_TMCL), REG32(ETH_STAT_TLCL), REG32(ETH_STAT_TXCL), REG32(ETH_STAT_TNCL));
+ printk("ETH_STAT_TPFH= 0x%08x, ETH_STAT_TDRP= 0x%08x, ETH_STAT_TJBR= 0x%08x, ETH_STAT_TFCS= 0x%08x\n",
+ REG32(ETH_STAT_TPFH), REG32(ETH_STAT_TDRP), REG32(ETH_STAT_TJBR), REG32(ETH_STAT_TFCS));
+ printk("ETH_STAT_TXCF= 0x%08x, ETH_STAT_TOVR= 0x%08x, ETH_STAT_TUND= 0x%08x, ETH_STAT_TFRG= 0x%08x\n",
+ REG32(ETH_STAT_TXCF), REG32(ETH_STAT_TOVR), REG32(ETH_STAT_TUND), REG32(ETH_STAT_TFRG));
+ printk("ETH_STAT_CAR1= 0x%08x, ETH_STAT_CAR2= 0x%08x, ETH_STAT_CARM1= 0x%08x, ETH_STAT_CARM2= 0x%08x\n",
+ REG32(ETH_STAT_CAR1), REG32(ETH_STAT_CAR2), REG32(ETH_STAT_CARM1), REG32(ETH_STAT_CARM2));
+ printk("==================================================\n");
+*/
+}
+
+static void counters_dump(struct jz_eth_private *np)
+{
+ int i = 0;
+
+ printk("\n");
+
+ do {
+ printk("cnts[%d] = %d\n", i, np->carry_counters[i]);
+ } while (++i < STAT_CNT_NUM);
+}
+
+static void sal_regs_dump(void)
+{
+ printk("==================================================\n");
+ printk("ETH_SAL_AFR = 0x%08x, ETH_SAL_HT1 = 0x%08x, ETH_SAL_HT2 = 0x%08x\n",
+ REG32(ETH_SAL_AFR), REG32(ETH_SAL_HT1), REG32(ETH_SAL_HT2));
+ printk("==================================================\n");
+}
+
+/*
+ * Display ethernet packet header
+ * This routine is used for test function
+ */
+static void eth_dbg_rx(struct sk_buff *skb, int len)
+{
+ int i, j;
+
+ printk("R: %02x:%02x:%02x:%02x:%02x:%02x <- %02x:%02x:%02x:%02x:%02x:%02x len/SAP:%02x%02x [%d]\n",
+ (u8)skb->data[0], (u8)skb->data[1], (u8)skb->data[2], (u8)skb->data[3], (u8)skb->data[4],
+ (u8)skb->data[5], (u8)skb->data[6], (u8)skb->data[7], (u8)skb->data[8], (u8)skb->data[9],
+ (u8)skb->data[10], (u8)skb->data[11], (u8)skb->data[12], (u8)skb->data[13], len);
+
+ for (j = 0; len > 0; j += 16, len -= 16) {
+ printk(" %03x: ",j);
+ for (i = 0; i < 16 && i < len; i++) {
+ printk("%02x ", (u8)skb->data[i + j]);
+ }
+ printk("\n");
+ }
+ return;
+}
+
+static void eth_dbg_tx(struct sk_buff *skb, int len)
+{
+
+ int i, j;
+
+ printk("T: %02x:%02x:%02x:%02x:%02x:%02x <- %02x:%02x:%02x:%02x:%02x:%02x len/SAP:%02x%02x [%d]\n",
+ (u8)skb->data[0], (u8)skb->data[1], (u8)skb->data[2], (u8)skb->data[3],
+ (u8)skb->data[4], (u8)skb->data[5], (u8)skb->data[6], (u8)skb->data[7],
+ (u8)skb->data[8], (u8)skb->data[9], (u8)skb->data[10], (u8)skb->data[11],
+ (u8)skb->data[12], (u8)skb->data[13], len);
+
+ for (j = 0; len > 0; j += 16, len -= 16) {
+ printk(" %03x: ",j);
+ for (i = 0; i < 16 && i < len; i++) {
+ printk("%02x ", (u8)skb->data[i+j]);
+ }
+ printk("\n");
+ }
+ return;
+}
+
+#if 0
+/*
+ * Show all mii registers - this routine is used for test
+ */
+static void mii_db_out(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unsigned int mii_test;
+
+ mii_test = mdio_read(dev,np->valid_phy,MII_BMCR);
+ DBPRINTK("BMCR ====> 0x%4.4x \n",mii_test);
+
+ mii_test = mdio_read(dev,np->valid_phy,MII_BMSR);
+ DBPRINTK("BMSR ====> 0x%4.4x \n",mii_test);
+
+ mii_test = mdio_read(dev,np->valid_phy,MII_ANAR);
+ DBPRINTK("ANAR ====> 0x%4.4x \n",mii_test);
+
+ mii_test = mdio_read(dev,np->valid_phy,MII_ANLPAR);
+ DBPRINTK("ANLPAR ====> 0x%4.4x \n",mii_test);
+
+ mii_test = mdio_read(dev,np->valid_phy,16);
+ DBPRINTK("REG16 ====> 0x%4.4x \n",mii_test);
+
+ mii_test = mdio_read(dev,np->valid_phy,17);
+ DBPRINTK("REG17 ====> 0x%4.4x \n",mii_test);
+}
+#endif
+
+#endif // ETH_DEBUG
+
+/*
+ * MII operation routines
+ */
+static inline void mii_wait(void)
+{
+ int i;
+// for (i = 0; i < MAX_WAIT; i++, mdelay(1)) {
+ for (i = 0; i < MAX_WAIT; i++, mdelay(20)) { /* Cynthia, Test, 2010-05-14 */
+ if (!__mac_mii_is_busy())
+ return ;
+ }
+
+// printk("\nMAC_MCMDR= 0x%04x MAC_MADRR= 0x%04x MAC_MINDR = 0x%04x\n",
+// REG16(ETH_MAC_MCMDR), REG16(ETH_MAC_MADRR), REG16(ETH_MAC_MINDR));
+
+ if (i == MAX_WAIT)
+ printk("MII wait timeout\n");
+}
+
+static int mdio_read(struct net_device *dev,int phy_id, int location)
+{
+ int retval = 0;
+
+ __mac_send_mii_read_cmd(phy_id, location, MII_NO_SCAN);
+ mii_wait();
+ retval = __mac_mii_read_data();
+
+ return retval;
+
+}
+
+static void mdio_write(struct net_device *dev,int phy_id, int location, int data)
+{
+ __mac_send_mii_write_cmd(phy_id, location, data);
+ mii_wait();
+}
+
+
+/*
+ * Search MII phy
+ */
+static int jz_search_mii_phy(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ int phy, phy_idx = 0;
+
+ np->valid_phy = 0xff;
+ for (phy = 0; phy < 32; phy++) {
+ int mii_status = mdio_read(dev, phy, 1);
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx] = phy;
+ np->ecmds[phy_idx].speed=SPEED_100;
+ np->ecmds[phy_idx].duplex=DUPLEX_FULL;
+ np->ecmds[phy_idx].port=PORT_MII;
+ np->ecmds[phy_idx].transceiver=XCVR_INTERNAL;
+ np->ecmds[phy_idx].phy_address=np->phys[phy_idx];
+ np->ecmds[phy_idx].autoneg=AUTONEG_ENABLE;
+ np->ecmds[phy_idx].advertising=(ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full);
+ phy_idx++;
+ }
+ }
+ if (phy_idx == 1) {
+ np->valid_phy = np->phys[0];
+ np->phy_type = 0;
+ }
+ if (phy_idx != 0) {
+ phy = np->valid_phy;
+ np->advertising = mdio_read(dev,phy, 4);
+ }
+ return phy_idx;
+}
+
+#if 1 // multicast
+
+/*
+ * CRC calc for Destination Address for gets hashtable index
+ */
+#define POLYNOMIAL 0x04c11db7UL
+static u16 jz_hashtable_index(u8 *addr)
+{
+#if 1
+ u32 crc = 0xffffffff, msb;
+ int i, j;
+ u32 byte;
+ for (i = 0; i < 6; i++) {
+ byte = *addr++;
+ for (j = 0; j < 8; j++) {
+ msb = crc >> 31;
+ crc <<= 1;
+ if (msb ^ (byte & 1)) crc ^= POLYNOMIAL;
+ byte >>= 1;
+ }
+ }
+ return ((int)(crc >> 26));
+#endif
+#if 0
+ int crc = -1;
+ int length=6;
+ int bit;
+ unsigned char current_octet;
+ while (--length >= 0) {
+ current_octet = *addr++;
+ for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+ crc = (crc << 1) ^ ((crc < 0) ^ (current_octet & 1) ?
+ POLYNOMIAL : 0);
+ }
+ return ((int)(crc >> 26));
+#endif
+}
+
+/*
+ * Multicast filter and config multicast hash table
+ */
+#define MULTICAST_FILTER_LIMIT 64
+
+static void jz_set_multicast_list(struct net_device *dev)
+{
+ int i, hash_index;
+ u32 hash_h, hash_l, hash_bit;
+
+ if (dev->flags & IFF_PROMISC) {
+ /* Accept any kinds of packets */
+ __sal_set_mode(AFR_PRO);
+ __sal_set_hash_table(0xffffffff, 0xffffffff);
+
+ printk("%s: Enter promisc mode!\n",dev->name);
+ } else if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > MULTICAST_FILTER_LIMIT)) {
+ /* Accept all multicast packets */
+ __sal_set_mode(AFR_PRM);
+ __sal_set_hash_table(0xffffffff, 0xffffffff);
+ printk("%s: Enter allmulticast mode! %d \n",dev->name,dev->mc_count);
+ } else if (dev->flags & IFF_MULTICAST) {
+ /* Update multicast hash table */
+ struct dev_mc_list *mclist;
+ __sal_get_hash_table(hash_h, hash_l);
+
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next)
+ {
+ hash_index = jz_hashtable_index(mclist->dmi_addr);
+ hash_bit=0x00000001;
+ hash_bit <<= (hash_index & 0x1f);
+ if (hash_index > 0x1f)
+ hash_h |= hash_bit;
+ else
+ hash_l |= hash_bit;
+
+#ifdef ETH_DEBUG
+ DBPRINTK("----------------------------\n");
+ {
+ int j;
+ for (j=0;j<mclist->dmi_addrlen;j++)
+ printk("%2.2x:",mclist->dmi_addr[j]);
+ printk("\n");
+ }
+#endif
+ //printk("dmi.addrlen => %d\n",mclist->dmi_addrlen);
+ //printk("dmi.users => %d\n",mclist->dmi_users);
+ //printk("dmi.gusers => %d\n",mclist->dmi_users);
+ }
+ __sal_set_hash_table(hash_h, hash_l);
+
+ __sal_set_mode(AFR_AMC);
+
+ //printk("This is multicast hash table high bits [%4.4x]\n",readl(ETH_SAL_HT1));
+ //printk("This is multicast hash table low bits [%4.4x]\n",readl(ETH_SAL_HT2));
+ //printk("%s: Enter multicast mode!\n",dev->name);
+ }
+}
+#endif // multicast
+
+static inline int jz_phy_reset(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unsigned int mii_reg0;
+ unsigned int count;
+
+ mii_reg0 = mdio_read(dev,np->valid_phy, MII_BMCR);
+ mii_reg0 |= MII_CR_RST;
+
+ mdio_write(dev, np->valid_phy, MII_BMCR, mii_reg0); //reset phy
+ for (count = 0; count < 2000; count++) {
+ mdelay(1);
+ mii_reg0 = mdio_read(dev,np->valid_phy, MII_BMCR);
+ if (!(mii_reg0 & MII_CR_RST))
+ break; //reset completed
+ }
+
+ if (count == 2000)
+ return 1; //phy error
+ else
+ return 0;
+}
+
+/*
+ * Start Auto-Negotiation function for PHY
+ */
+/*
+static int jz_autonet_complete(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ int count;
+ u32 mii_reg1, timeout = 3000;
+
+ for (count = 0; count < timeout; count++) {
+ mdelay(1);
+ mii_reg1 = mdio_read(dev,np->valid_phy, MII_BMSR);
+ if (mii_reg1 & 0x0020)
+ break;
+ }
+ //mii_db_out(dev); //for debug to display all register of MII
+ if (count >= timeout)
+ return 1; //auto negotiation error
+ else
+ return 0;
+}
+*/
+
+/*
+ * Get current mode of eth phy
+ */
+static u32 jz_eth_curr_mode(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unsigned int mii_reg17;
+ u32 flag = 0;
+
+ mii_reg17 = mdio_read(dev,np->valid_phy,MII_DSCSR);
+ np->media = mii_reg17>>12;
+ if (np->media==8) {
+ infoprintk("%s: Current Operation Mode is [100M Full Duplex]",dev->name);
+ flag = 0;
+ np->full_duplex=1;
+ }
+ if (np->media==4) {
+ infoprintk("%s: Current Operation Mode is [100M Half Duplex]",dev->name);
+ flag = 0;
+ np->full_duplex=0;
+ }
+ if (np->media==2) {
+ infoprintk("%s: Current Operation Mode is [10M Full Duplex]",dev->name);
+ np->full_duplex=1;
+ }
+ if (np->media==1) {
+ infoprintk("%s: Current Operation Mode is [10M Half Duplex]",dev->name);
+ np->full_duplex=0;
+ }
+ printk("\n");
+ return flag;
+}
+
+static void config_mac(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ u32 mac_cfg_1 = 0, mac_cfg_2 = 0;
+
+ // Enable tx & rx flow control, enable receive
+ mac_cfg_1 = MCR1_TFC | MCR1_RFC | MCR1_RE;
+
+#ifdef USE_RMII
+ // Enable RMII
+ mac_cfg_1 |= 1 << 13;
+#endif
+
+ // Enable loopack mode
+ //mac_cfg_1 |= MCR1_LB;
+
+ /* bit 7 bit 6 bit 5
+ MCR2_ADPE MCR2_VPE MCR2_PCE
+ x x 0 No pad, check CRC
+ > 0 0 1 Pad to 60B, append CRC
+ x 1 1 Pad to 64B, append CRC
+ 1 0 1 if un-tagged, Pad to 60B, append CRC
+ if VLAN tagged, Pad to 64B, append CRC
+
+ if set MCR2_PCE(bit 5)
+ MCR2_CE(bit 4) must be set.
+
+ We need to pad frame to 60B and append 4-byte CRC.
+ */
+
+ mac_cfg_2 = MCR2_PCE | MCR2_CE;
+
+ // Pure preamble enforcement
+ //mac_cfg_2 |= MCR2_PPE;
+
+ // Frame length checking
+ mac_cfg_2 |= MCR2_FLC;
+
+ if (np->full_duplex) {
+ mac_cfg_2 |= MCR2_FD;
+ __mac_set_IPGR(0x15);
+
+ } else {
+
+ __mac_set_IPGR(0x12);
+ }
+
+ REG16(ETH_MAC_MCR1) = mac_cfg_1;
+ REG16(ETH_MAC_MCR2) = mac_cfg_2;
+
+ __mac_set_NIPGR1(0x0c);
+ __mac_set_NIPGR2(0x12);
+
+ //mac_regs_dump();
+}
+
+static void config_fifo(void)
+{
+ int i;
+
+ __fifo_reset_all();
+
+ REG32(ETH_FIFO_CR0) |= 0x80000000;
+
+ /* 4k rx FiFo */
+
+ __fifo_set_fr_threshold(0x180);
+ __fifo_set_high_wm(0x200);
+ __fifo_set_low_wm(0x40);
+
+ /* 4k tx FiFo */
+/*
+ __fifo_set_ft_threshold(0x0200);
+ __fifo_set_ft_high_wm(0x0300);
+*/
+ /* for 2k FiFo both tx */
+ __fifo_set_ft_threshold(0x0180);
+ __fifo_set_ft_high_wm(0x01b0);
+
+ __fifo_set_XOFF_RTX(4);
+ __fifo_set_pause_control();
+
+ REG32(ETH_FIFO_CR4) &= 0x0000;
+ REG32(ETH_FIFO_CR5) |= 0xffff;
+
+ __fifo_set_drop_cond(RSV_CRCE);
+ __fifo_set_dropdc_cond(RSV_CRCE);
+
+ __fifo_set_drop_cond(RSV_MP);
+ __fifo_set_dropdc_cond(RSV_MP);
+
+ __fifo_set_drop_cond(RSV_BP);
+ __fifo_set_dropdc_cond(RSV_BP);
+
+ __fifo_set_drop_cond(RSV_LCE);
+ __fifo_set_dropdc_cond(RSV_LCE);
+
+ __fifo_enable_all_modules();
+
+ for (i = 0;
+ i < MAX_WAIT && !__fifo_all_enabled();
+ i++, udelay(100)) {
+ ;
+ }
+
+ if (i == MAX_WAIT) {
+ printk("config_fifo: Wait time out !\n");
+ return;
+ }
+ //fifo_regs_dump();
+}
+
+static void config_sal(void)
+{
+ /* SAL config */
+ __sal_set_mode(AFR_AMC | AFR_ABC);
+ __sal_set_hash_table(0, 0);
+}
+
+/*
+static void config_stat(void)
+{
+ __stat_disable();
+ __stat_clear_counters();
+ // clear carry registers
+ REG32(ETH_STAT_CAR1) = REG32(ETH_STAT_CAR1);
+ REG32(ETH_STAT_CAR2) = REG32(ETH_STAT_CAR2);
+ __stat_disable_carry_irq();
+ __stat_enable_carry_irq();
+ //printk("CARM1 = 0x%08x, CARM2 = 0x%08x\n", REG32(ETH_STAT_CARM1), REG32(ETH_STAT_CARM2));
+
+ __stat_enable();
+ printk("Enable eth stat module.\n");
+
+}
+*/
+
+static int autonet_complete(struct net_device *dev)
+{
+ int i;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ for (i = 0;
+ i < MAX_WAIT && !(mdio_read(dev, np->valid_phy, MII_BMSR) & 0x0020);
+ i++, udelay(10)) {
+ ;
+ }
+
+ if (i == MAX_WAIT) {
+ printk("%s: Autonet time out!\n", dev->name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void config_phy(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ u32 mii_anlpar, phy_mode;
+
+ mii_anlpar = mdio_read(dev, np->valid_phy, MII_ANLPAR);
+
+ if (mii_anlpar != 0xffff) {
+ mii_anlpar = mdio_read(dev, np->valid_phy, MII_ANLPAR); // read twice to make data stable
+ if ((mii_anlpar & 0x0100) || (mii_anlpar & 0x01C0) == 0x0040) {
+ np->full_duplex = 1;
+ }
+ phy_mode = mii_anlpar >> 5;
+
+#ifdef USE_RMII
+
+ if (phy_mode & MII_ANLPAR_100M)
+ REG32(ETH_MAC_PSR) |= PSR_OS;
+#endif
+
+ printk("%s: Setting %s %s-duplex based on MII tranceiver #%d\n",
+ dev->name, (phy_mode & MII_ANLPAR_100M) ? "100Mbps" : "10Mbps",
+ np->full_duplex ? "full" : "half", np->mii_phy_cnt);
+
+ } else {
+ printk("%s: config_phy: MII_ANLPAR is 0xFFFF, may be error ???\n", dev->name);
+ }
+
+}
+
+/*
+ * Ethernet device hardware init
+ * This routine initializes the ethernet device hardware and PHY
+ */
+static int jz_init_hw(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ struct ethtool_cmd ecmd;
+ int i;
+
+#ifdef CONFIG_SOC_JZ4810
+ __gpio_as_eth();
+#endif
+
+ __eth_disable_irq();
+ __mac_set_mii_clk(0x7);
+ __mac_reset();
+
+#if 0
+ /* MII operation */
+ if (jz_phy_reset(dev)) {
+ errprintk("Ethernet PHY device does not reset!\n");
+ //return operation not permitted
+ return -EPERM;
+ }
+#endif
+
+ __eth_set_mac_address(dev->dev_addr[0], dev->dev_addr[1],
+ dev->dev_addr[2], dev->dev_addr[3],
+ dev->dev_addr[4], dev->dev_addr[5]);
+
+ printk("%s: JZ On-Chip ethernet (MAC ", dev->name);
+ for (i = 0; i < 5; i++) {
+ printk("%2.2x:", dev->dev_addr[i]);
+ }
+ printk("%2.2x, IRQ %d)\n", dev->dev_addr[i], dev->irq);
+
+ np->mii_phy_cnt = jz_search_mii_phy(dev);
+ printk("%s: Found %d PHY on JZ MAC\n", dev->name, np->mii_phy_cnt);
+// New code, could make it work on 100M mode ...
+ if (autonet_complete(dev))
+ printk("ETH Auto-Negotiation failed\n");
+
+ config_phy(dev);
+// old configuration
+ mii_info.phy_id = np->valid_phy;
+ mii_info.dev = dev;
+ mii_info.mdio_read = &mdio_read;
+ mii_info.mdio_write = &mdio_write;
+
+ ecmd.speed = SPEED_100;
+ ecmd.duplex = DUPLEX_FULL;
+ ecmd.port = PORT_MII;
+ ecmd.transceiver = XCVR_INTERNAL;
+ ecmd.phy_address = np->valid_phy;
+ ecmd.autoneg = AUTONEG_ENABLE;
+
+/*
+ mii_ethtool_sset(&mii_info, &ecmd);
+ if (jz_autonet_complete(dev))
+ errprintk("%s: Ethernet Module AutoNegotiation failed\n",dev->name);
+ mii_ethtool_gset(&mii_info, &ecmd);
+
+ infoprintk("%s: Provide Modes: ",dev->name);
+ for (i = 0; i < 5;i++)
+ if (ecmd.advertising & (1<<i))
+ printk("(%d)%s", i+1, media_types[i]);
+ printk("\n");
+
+ flag = jz_eth_curr_mode(dev);
+*/
+
+ config_mac(dev);
+
+ config_fifo();
+
+ config_sal();
+
+// config_stat();
+
+ /* Set base address of TX and RX descriptors */
+ __eth_set_rx_desc_addr(np->dma_rx_ring);
+ __eth_set_tx_desc_addr(np->dma_tx_ring);
+
+ /* Burst length: 4, 8 or 16 */
+ //__eth_dma_set_burst_len(BURST_LEN_4);
+
+ //dma_regs_dump("set burst length\n");
+
+ /* Clear status registers */
+ __eth_clear_rx_flags();
+ __eth_clear_rx_pkt_cnt();
+ __eth_clear_tx_flags();
+ __eth_clear_tx_pkt_cnt();
+
+ __eth_enable_irq();
+ __eth_dma_rx_enable();
+
+ return 0;
+}
+
+static void jz_eth_read_stats(struct jz_eth_private *np, int carry1, int carry2)
+{
+ return ;
+
+ if (carry1 != 0) {
+ if (carry1 & CAR1_RPK) np->carry_counters[CNT_RPKT]++;
+ if (carry1 & CAR1_RBY) np->carry_counters[CNT_RBYT]++;
+ if (carry1 & CAR1_RFC) np->carry_counters[CNT_RFCS]++;
+ if (carry1 & CAR1_RDR) np->carry_counters[CNT_RDRP]++;
+ if (carry1 & CAR1_RMC) np->carry_counters[CNT_RMCA]++;
+ printk("carry1 = 0x%08x\n", carry1);
+ }
+
+ if (carry2 != 0) {
+ if (carry2 & CAR2_TPK) np->carry_counters[CNT_TPKT]++;
+ if (carry2 & CAR2_TBY) np->carry_counters[CNT_TBYT]++;
+ if (carry2 & CAR2_TFC) np->carry_counters[CNT_TFCS]++;
+ if (carry2 & CAR2_TDP) np->carry_counters[CNT_TDRP]++;
+ if (carry2 & CAR2_TNC) np->carry_counters[CNT_TNCL]++;
+ printk("carry2 = 0x%08x\n", carry2);
+ }
+
+ np->stats.rx_packets = REG32(ETH_STAT_RPKT) + (np->carry_counters[CNT_RPKT] << 18);
+ np->stats.tx_packets = REG32(ETH_STAT_TPKT) + (np->carry_counters[CNT_TPKT] << 18);
+ np->stats.rx_bytes = REG32(ETH_STAT_RBYT) + (np->carry_counters[CNT_RBYT] << 24);
+ np->stats.tx_bytes = REG32(ETH_STAT_TBYT) + (np->carry_counters[CNT_TBYT] << 24);
+ np->stats.rx_errors = REG32(ETH_STAT_RFCS) + (np->carry_counters[CNT_RFCS] << 12);
+ np->stats.tx_errors = REG32(ETH_STAT_TFCS) + (np->carry_counters[CNT_TFCS] << 12);
+ np->stats.rx_dropped = REG32(ETH_STAT_RDRP) + (np->carry_counters[CNT_RDRP] << 12);
+ np->stats.tx_dropped = REG32(ETH_STAT_TDRP) + (np->carry_counters[CNT_TDRP] << 12);
+ np->stats.multicast = REG32(ETH_STAT_RMCA) + (np->carry_counters[CNT_RMCA] << 18);
+ np->stats.collisions = REG32(ETH_STAT_TNCL) + (np->carry_counters[CNT_TNCL] << 13);
+
+ //counters_dump(np);
+
+}
+
+static int jz_eth_open(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ int retval, i;
+
+ retval = request_irq(dev->irq, jz_eth_interrupt, 0, dev->name, dev);
+ if (retval) {
+ errprintk("%s: Unable to get IRQ %d .\n", dev->name, dev->irq);
+ return -EAGAIN;
+ }
+
+ for (i = 0; i < NUM_RX_DESCS; i++) {
+ np->rx_ring[i].pkt_addr = cpu_to_le32(np->dma_rx_buf + i * RX_BUF_SIZE);
+ np->rx_ring[i].pkt_size = cpu_to_le32(EMPTY_FLAG_MASK);
+ np->rx_ring[i].next_desc= cpu_to_le32(np->dma_rx_ring + (i+1) * sizeof (jz_desc_t));
+ }
+ np->rx_ring[NUM_RX_DESCS - 1].next_desc = cpu_to_le32(np->dma_rx_ring);
+
+ for (i = 0; i < NUM_TX_DESCS; i++) {
+ np->tx_ring[i].pkt_addr = cpu_to_le32(0);
+ np->tx_ring[i].pkt_size = cpu_to_le32(EMPTY_FLAG_MASK);
+ np->tx_ring[i].next_desc= cpu_to_le32(np->dma_tx_ring + (i+1) * sizeof (jz_desc_t));
+ }
+ np->tx_ring[NUM_TX_DESCS - 1].next_desc = cpu_to_le32(np->dma_tx_ring);
+
+ np->rx_head = 0;
+ np->tx_head = np->tx_tail = 0;
+
+ //desc_dump(dev);
+
+ for (i = 0; i < STAT_CNT_NUM; i++) {
+ np->carry_counters[i] = 0;
+ }
+
+ jz_init_hw(dev);
+
+ dev->trans_start = jiffies;
+ netif_start_queue(dev);
+ start_check(dev);
+
+ return 0;
+}
+
+static int jz_eth_close(struct net_device *dev)
+{
+ netif_stop_queue(dev);
+ close_check(dev);
+
+ __eth_disable();
+
+ free_irq(dev->irq, dev);
+ return 0;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the device open or closed.
+ */
+static struct net_device_stats * jz_eth_get_stats(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+// unsigned int flags;
+
+// spin_lock_irqsave(&np->lock, flags);
+
+ jz_eth_read_stats(np, 0, 0);
+
+// spin_unlock_irqrestore(&np->lock, flags);
+
+ return &np->stats;
+}
+
+/*
+ * ethtool routines
+ */
+static int jz_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ u32 ethcmd;
+
+ /* dev_ioctl() in ../../net/core/dev.c has already checked
+ capable(CAP_NET_ADMIN), so don't bother with that here. */
+
+ if (get_user(ethcmd, (u32 *)useraddr))
+ return -EFAULT;
+
+ switch (ethcmd) {
+
+ case ETHTOOL_GDRVINFO: {
+ struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+ strcpy (info.driver, DRV_NAME);
+ strcpy (info.version, DRV_VERSION);
+ strcpy (info.bus_info, "OCS");
+ if (copy_to_user (useraddr, &info, sizeof (info)))
+ return -EFAULT;
+ return 0;
+ }
+
+ /* get settings */
+ case ETHTOOL_GSET: {
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ spin_lock_irq(&np->lock);
+ mii_ethtool_gset(&mii_info, &ecmd);
+ spin_unlock_irq(&np->lock);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+ }
+ /* set settings */
+ case ETHTOOL_SSET: {
+ int r;
+ struct ethtool_cmd ecmd;
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ spin_lock_irq(&np->lock);
+ r = mii_ethtool_sset(&mii_info, &ecmd);
+ spin_unlock_irq(&np->lock);
+ return r;
+ }
+ /* restart autonegotiation */
+ case ETHTOOL_NWAY_RST: {
+ return mii_nway_restart(&mii_info);
+ }
+ /* get link status */
+ case ETHTOOL_GLINK: {
+ struct ethtool_value edata = {ETHTOOL_GLINK};
+ edata.data = mii_link_ok(&mii_info);
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+
+ /* get message-level */
+ case ETHTOOL_GMSGLVL: {
+ struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+ edata.data = debug;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+ /* set message-level */
+ case ETHTOOL_SMSGLVL: {
+ struct ethtool_value edata;
+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
+ return -EFAULT;
+ debug = edata.data;
+ return 0;
+ }
+
+ default:
+ break;
+ }
+
+ return -EOPNOTSUPP;
+}
+
+/*
+ * Config device
+ */
+static int jz_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ struct mii_ioctl_data *data, rdata;
+
+ switch (cmd) {
+ case SIOCETHTOOL:
+ return jz_ethtool_ioctl(dev, (void *) rq->ifr_data);
+ case SIOCGMIIPHY:
+ case SIOCDEVPRIVATE:
+ data = (struct mii_ioctl_data *)&rq->ifr_data;
+ data->phy_id = np->valid_phy;
+ case SIOCGMIIREG:
+ case SIOCDEVPRIVATE+1:
+ data = (struct mii_ioctl_data *)&rq->ifr_data;
+ data->val_out = mdio_read(dev,np->valid_phy, data->reg_num & 0x1f);
+ return 0;
+ case SIOCSMIIREG:
+ case SIOCDEVPRIVATE+2:
+ data = (struct mii_ioctl_data *)&rq->ifr_data;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ mdio_write(dev,np->valid_phy, data->reg_num & 0x1f, data->val_in);
+ return 0;
+ case READ_COMMAND:
+ data = (struct mii_ioctl_data *)rq->ifr_data;
+ if (copy_from_user(&rdata,data,sizeof(rdata)))
+ return -EFAULT;
+ rdata.val_out = mdio_read(dev,rdata.phy_id, rdata.reg_num & 0x1f);
+ if (copy_to_user(data,&rdata,sizeof(rdata)))
+ return -EFAULT;
+ return 0;
+ case WRITE_COMMAND:
+ if (np->phy_type==1) {
+ data = (struct mii_ioctl_data *)rq->ifr_data;
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&rdata,data,sizeof(rdata)))
+ return -EFAULT;
+ mdio_write(dev,rdata.phy_id, rdata.reg_num & 0x1f, rdata.val_in);
+ }
+ return 0;
+ case GETDRIVERINFO:
+ if (np->phy_type==1) {
+ data = (struct mii_ioctl_data *)rq->ifr_data;
+ if (copy_from_user(&rdata,data,sizeof(rdata)))
+ return -EFAULT;
+ rdata.val_in = 0x1;
+ rdata.val_out = 0x00d0;
+ if (copy_to_user(data,&rdata,sizeof(rdata)))
+ return -EFAULT;
+ }
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+/*
+ * Received one packet
+ */
+static void eth_rxready(struct net_device *dev, int counter)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ jz_desc_t *rx_current_desc;
+ struct sk_buff *skb;
+ unsigned char *pkt_ptr;
+ u32 pkt_len;
+
+ int counter_bak = counter;
+ int i = 0;
+
+ /* empty_flag == 0 */
+ while (counter-- > 0) {
+ i++;
+
+ rx_current_desc = &(np->rx_ring[np->rx_head]);
+ //dma_cache_inv((unsigned int)rx_current_desc, sizeof(jz_desc_t));
+
+ if (__desc_get_empty_flag(le32_to_cpu(rx_current_desc->pkt_size))) {
+ printk("%s: ?????????? fix me ??? %s, %d\n", dev->name, __FUNCTION__, __LINE__);
+ printk("counter_bak = %d, counter = %d\n", counter_bak, counter);
+ return ;
+ }
+
+ pkt_ptr = (unsigned char *)((rx_current_desc->pkt_addr) | 0xa0000000);
+ pkt_len = (__desc_get_pkt_size(le32_to_cpu(rx_current_desc->pkt_size))) - 4;
+
+ np->stats.rx_packets++;
+ np->stats.rx_bytes += pkt_len;
+
+ skb = dev_alloc_skb(pkt_len + 2);
+ if (skb == NULL) {
+ printk("%s: Memory squeeze, dropping. dev_alloc_skb(0x%08x)\n",
+ dev->name, pkt_len + 2);
+ np->stats.rx_dropped++;
+ __eth_reduce_pkt_recv_cnt();
+ //break;
+ return ;
+ }
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte align */
+
+#if 0
+ rx_buf_addr_array[rx_buf_addr_array_idx] = (unsigned int)skb;
+ rx_buf_addr_array_idx == DUMP_RX_BUF_ADDR_MAX - 1 ? rx_buf_addr_array_idx = 0 : rx_buf_addr_array_idx++;
+#endif
+
+ dma_cache_inv((unsigned int)pkt_ptr, pkt_len);
+ memcpy(skb->data, pkt_ptr, pkt_len);
+ skb_put(skb, pkt_len);
+ skb->protocol = eth_type_trans(skb,dev);
+
+ netif_rx(skb); /* pass the packet to upper layers */
+ dev->last_rx = jiffies;
+
+ __eth_reduce_pkt_recv_cnt();
+
+ rx_current_desc->pkt_size = EMPTY_FLAG_MASK;
+
+ //dma_cache_wback((unsigned int)rx_current_desc, sizeof(jz_desc_t));
+
+ np->rx_head == NUM_RX_DESCS - 1 ? np->rx_head = 0 : np->rx_head++;
+ BUG_ON(np->rx_head >= NUM_RX_DESCS);
+ }
+
+ if (i == 0) {
+ printk("%s: eth_rxready ... BUG_ON\n", dev->name);
+ BUG_ON(1);
+ } else {
+ __eth_dma_rx_enable();
+ }
+}
+
+/*
+ * Tx timeout routine
+ */
+static void jz_eth_tx_timeout(struct net_device *dev)
+{
+ jz_init_hw(dev);
+ netif_wake_queue(dev);
+}
+
+/*
+ * One packet was transmitted
+ */
+static void eth_txdone(struct net_device *dev, int counter)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ int tx_tail = np->tx_tail;
+
+ while (counter-- > 0) {
+
+#if NUM_RX_DESCS == 1
+ int entry = 0;
+#else
+ int entry = tx_tail % NUM_TX_DESCS;
+#endif
+
+ /* Free the original skb */
+ if (np->tx_skb[entry]) {
+ np->stats.tx_packets++;
+ np->stats.tx_bytes += le32_to_cpu(np->tx_ring[entry].pkt_size);
+
+ dev_kfree_skb_irq(np->tx_skb[entry]);
+
+ np->tx_skb[entry] = 0;
+ } else {
+ printk("%s: ?????????? fix me ??? %s, %d\n", dev->name, __FUNCTION__, __LINE__);
+ //desc_dump(dev);
+ //dma_regs_dump("");
+ }
+
+ tx_tail++;
+ __eth_reduce_pkt_sent_cnt();
+ }
+
+ if (np->tx_full && (tx_tail + NUM_TX_DESCS > np->tx_head + 1)) {
+ /* The ring is no longer full */
+ np->tx_full = 0;
+ netif_start_queue(dev);
+ }
+ np->tx_tail = tx_tail;
+}
+
+/*
+ * Update the tx descriptor
+ */
+static void load_tx_packet(struct net_device *dev, char *buf, u32 length, struct sk_buff *skb)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ int entry = np->tx_head % NUM_TX_DESCS;
+ int i;
+
+
+#if 0
+ tx_buf_addr_array[tx_buf_addr_array_idx] = (unsigned int)cpu_to_le32(virt_to_bus(buf));
+ tx_buf_addr_array_idx == DUMP_TX_BUF_ADDR_MAX - 1 ? tx_buf_addr_array_idx = 0 : tx_buf_addr_array_idx++;
+#endif
+
+ np->tx_ring[entry].pkt_addr = cpu_to_le32(virt_to_bus(buf));
+ np->tx_ring[entry].pkt_size = cpu_to_le32(length & ~EMPTY_FLAG_MASK);
+ np->tx_skb[entry] = skb;
+
+ /* Notice us when will send a packet which begin with address: xxx1(binary) */
+ if (unlikely(np->tx_ring[entry].pkt_addr & 0x1)) {
+ skb_dump(skb);
+ printk("desc.pktaddr = 0x%08x\n", np->tx_ring[entry].pkt_addr);
+ for (i = -2; i < 16; i++) {
+ printk("%02x ", *((unsigned char *)le32_to_cpu(bus_to_virt(np->tx_ring[entry].pkt_addr)) + i));
+ }
+ printk("\n");
+ for (i = -2; i < 16; i++) {
+ printk("%02x ", *((unsigned char *)le32_to_cpu(buf) + i));
+ }
+ printk("\n");
+ for (i = -2; i < 16; i++) {
+ printk("%02x ", *((unsigned char *)(bus_to_virt(np->tx_ring[entry].pkt_addr)) + i));
+ }
+ printk("\n");
+ }
+}
+
+/*
+ * Transmit one packet
+ */
+static int jz_eth_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+ u32 length;
+
+ if (np->tx_full) {
+ return 0;
+ }
+
+ length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+ dma_cache_wback((unsigned long)skb->data, length);
+
+ load_tx_packet(dev, (char *)skb->data, length, skb);
+
+ spin_lock_irq(&np->lock);
+
+ np->tx_head++;
+
+ /* Start TX */
+ __eth_dma_tx_enable();
+
+ /* for timeout */
+ dev->trans_start = jiffies;
+
+ if (np->tx_tail + NUM_TX_DESCS > np->tx_head + 1) {
+ np->tx_full = 0;
+ } else {
+ np->tx_full = 1;
+ netif_stop_queue(dev);
+ }
+
+ spin_unlock_irq(&np->lock);
+ return 0;
+}
+
+/*
+ * Interrupt service routine
+ */
+static irqreturn_t jz_eth_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+ unsigned int tx_sts;
+ unsigned int rx_sts;
+ unsigned int counter;
+ unsigned int carry1 = 0;
+ unsigned int carry2 = 0;
+
+ spin_lock(&np->lock);
+
+ __eth_disable_irq();
+
+ /* Read tx & rx state reg, which indicate action */
+ tx_sts = REG32(ETH_DMA_TSR);
+ rx_sts = REG32(ETH_DMA_RSR);
+
+ __eth_clear_tx_flags(); /* Clear UNDERRUN and BUSERROR */
+ __eth_clear_rx_flags(); /* Clear OVERFLOW and BUSERROR */
+
+ /* Tx PKTSENT: one or more frames have already been sent. Current tx round has completed. */
+ if (tx_sts & TSR_PKTSENT) {
+ /* To clear counter and PKTSENT bit,
+ * __eth_reduce_pkt_sent_cnt() was called inside */
+ counter = (tx_sts & TSR_PKTCNT_MASK) >> 16;
+ if (counter != 0) {
+ eth_txdone(dev, counter);
+ } else {
+ printk("%s: Packet has been sent but counter is 0\n", dev->name);
+ BUG_ON(1);
+ }
+ }
+
+ /* Rx PKTRECV: one frame has already been received. Receive frame until there is no PKTRECV */
+ if (rx_sts & RSR_PKTRECV) {
+ /* To reduce counter and PKTRECV bit,
+ * __eth_reduce_pkt_recv_cnt() must called after each round */
+ counter = (rx_sts & RSR_PKTCNT_MASK) >> 16;
+ if (counter != 0) {
+ eth_rxready(dev, counter);
+ } else {
+ printk("%s: Packet has been received but count is 0\n", dev->name);
+ BUG_ON(1);
+ }
+ }
+
+ if ( !(tx_sts & TSR_FLAGS) && !(rx_sts & RSR_FLAGS) ) {
+ carry1 = REG32(ETH_STAT_CAR1);
+ carry2 = REG32(ETH_STAT_CAR2);
+ REG32(ETH_STAT_CAR1) = carry1;
+ REG32(ETH_STAT_CAR2) = carry2;
+
+/*
+ if (carry1 || carry2) {
+ jz_eth_read_stats(np, carry1, carry2);
+ } else {
+ printk("tx_sts = 0x%08x, rx_sts = 0x%08x\n", tx_sts, rx_sts);
+ printk("BUG: interrupt, no irq source\n");
+ BUG_ON(1);
+ }
+*/
+ goto _exit_irq;
+ }
+
+ /* Fatal bus error */
+ if (tx_sts & TSR_BUSERR || rx_sts & RSR_BUSERR) {
+ __eth_disable();
+ printk("%s: Fatal bus error occurred, sts=[%#8x %#8x], device stopped.\n", dev->name, tx_sts, rx_sts);
+ goto _exit_irq;
+ }
+
+ /* Rx overflow */
+ if (rx_sts & RSR_OVERFLOW) {
+ printk("RX_OVERFLOW\n");
+ __eth_dma_rx_disable();
+ }
+
+ /* Tx underrun, it occurred after every tx round */
+ if (tx_sts & TSR_UNDERRUN) {
+ //printk("TX_UNDERRUN\n");
+ }
+
+_exit_irq:
+
+ __eth_enable_irq();
+
+ spin_unlock(&np->lock);
+
+ return IRQ_HANDLED;
+}
+
+#if 0 //def CONFIG_PM
+/*
+ * Suspend the ETH interface.
+ */
+static int jz_eth_suspend(struct net_device *dev, int state)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *jep = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *jep = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unsigned long flags, tmp;
+
+ printk("ETH suspend\n");
+
+ if (!netif_running(dev)) {
+ return 0;
+ }
+
+ netif_device_detach(dev);
+
+ spin_lock_irqsave(&jep->lock, flags);
+
+ /* Disable interrupts, stop Tx and Rx. */
+ __eth_disable_irq();
+ __eth_disable();
+ __stat_disable_carry_irq();
+
+ spin_unlock_irqrestore(&jep->lock, flags);
+
+ return 0;
+}
+
+/*
+ * Resume the ETH interface.
+ */
+static int jz_eth_resume(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ printk("ETH resume.\n");
+
+ if (!netif_running(dev))
+ return 0;
+
+ jz_init_hw(dev);
+
+ netif_device_attach(dev);
+ jz_eth_tx_timeout(dev);
+ netif_wake_queue(dev);
+
+ return 0;
+}
+
+static int jz_eth_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+ int ret;
+
+ if (!dev->data)
+ return -EINVAL;
+
+ switch (rqst) {
+ case PM_SUSPEND:
+ ret = jz_eth_suspend((struct net_device *)dev->data, (int)data);
+ break;
+
+ case PM_RESUME:
+ ret = jz_eth_resume((struct net_device *)dev->data);
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+#endif /* CONFIG_PM */
+
+
+// Cynthia added
+static const struct net_device_ops jz_netdev_ops = {
+
+ .ndo_open = jz_eth_open,
+ .ndo_stop = jz_eth_close,
+ .ndo_start_xmit = jz_eth_send_packet,
+ .ndo_get_stats = jz_eth_get_stats,
+ .ndo_set_multicast_list = jz_set_multicast_list,
+ .ndo_do_ioctl = jz_eth_ioctl,
+ .ndo_tx_timeout = jz_eth_tx_timeout,
+
+};
+
+ //=== Cynthia end == //
+
+
+static int __init jz_eth_init(void)
+{
+ struct net_device *dev;
+ struct jz_eth_private *np;
+ int err;
+
+ dev = alloc_etherdev(sizeof(struct jz_eth_private));
+ if (!dev) {
+ printk(KERN_ERR "%s: Alloc_etherdev failed\n", DRV_NAME);
+ return -ENOMEM;
+ }
+ netdev = dev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ np = (struct jz_eth_private *)P2ADDR(dev->priv);
+ dev->priv = np;
+#else
+ np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+ memset(np, 0, sizeof(struct jz_eth_private));
+
+ np->vaddr_rx_buf = (u32)dma_alloc_noncoherent(NULL, NUM_RX_DESCS * RX_BUF_SIZE,
+ &np->dma_rx_buf, 0);
+
+ if (!np->vaddr_rx_buf) {
+ printk(KERN_ERR "%s: Cannot alloc dma buffers\n", DRV_NAME);
+ unregister_netdev(dev);
+ free_netdev(dev);
+ return -ENOMEM;
+ }
+
+ np->dma_rx_ring = (unsigned int)(np->rx_ring) & 0xfffffff;
+ np->dma_tx_ring = (unsigned int)(np->tx_ring) & 0xfffffff;
+
+ np->full_duplex = 1;
+ np->link_state = 1;
+
+ spin_lock_init(&np->lock);
+
+ ether_setup(dev); // ?? the function has already been called in alloc_etherdev
+ dev->irq = IRQ_ETH;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ dev->open = jz_eth_open;
+ dev->stop = jz_eth_close;
+ dev->hard_start_xmit = jz_eth_send_packet;
+ dev->get_stats = jz_eth_get_stats;
+ dev->set_multicast_list = jz_set_multicast_list;
+ dev->do_ioctl = jz_eth_ioctl;
+ dev->tx_timeout = jz_eth_tx_timeout;
+
+#else
+ dev->netdev_ops = &jz_netdev_ops; // Cynthia zhzhao added 20100514
+#endif
+
+ dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+ // configure MAC address
+ get_mac_address(dev);
+
+ if ((err = register_netdev(dev)) != 0) {
+ printk("%s: Cannot register net device, error %d\n",
+ DRV_NAME, err);
+ free_netdev(dev);
+ return -ENOMEM;
+ }
+
+#if 0 // CONFIG_PM
+ np->pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, jz_eth_pm_callback);
+ if (np->pmdev) {
+ np->pmdev->data = dev;
+ }
+#endif
+
+ return 0;
+}
+
+static void __exit jz_eth_exit(void)
+{
+ struct net_device *dev = netdev;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+ struct jz_eth_private *np = (struct jz_eth_private *)dev->priv;
+#else
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(dev));
+#endif
+
+ unregister_netdev(dev);
+ dma_free_noncoherent(NULL, NUM_RX_DESCS * RX_BUF_SIZE,
+ (void *)np->vaddr_rx_buf, np->dma_rx_buf);
+ free_netdev(dev);
+}
+
+module_init(jz_eth_init);
+module_exit(jz_eth_exit);
+
+#if 0
+void eth_debug_show_priv_at_oops(void)
+{
+ printk("()()()()()()()()()()()()\n");
+ printk("netdev_priv(dev) = 0x%08x\n", (unsigned int)netdev_priv(netdev));
+ printk("()()()()()()()()()()()()\n");
+}
+
+void eth_debug_at_oops(void)
+{
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(netdev));
+ printk("=-=-=-=-=-=-=-=-=-=-=-=-=-=-= np = 0x%08x >>>\n", (unsigned int)np);
+ dump_eth_tx_addr();
+ desc_dump(np);
+ priv_data_dump(np);
+ printk("=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <<<\n");
+ //dma_regs_dump("--------- dump dma regs\n");
+}
+
+void eth_debug_show_status(void)
+{
+ struct jz_eth_private *np = (struct jz_eth_private *)P2ADDR(netdev_priv(netdev));
+ printk("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+ printk("tx_packet = %u, tx_bytes = %u\n", np->stats.tx_packets, np->stats.tx_bytes);
+ printk("rx_packet = %u, rx_bytes = %u\n", np->stats.rx_packets, np->stats.rx_bytes);
+ printk("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+}
+
+EXPORT_SYMBOL(eth_debug_show_priv_at_oops);
+EXPORT_SYMBOL(eth_debug_at_oops);
+EXPORT_SYMBOL(eth_debug_show_status);
+#endif
diff --git a/drivers/net/jz4760_eth.h b/drivers/net/jz4760_eth.h
new file mode 100644
index 00000000000..bf9bfba1ac7
--- /dev/null
+++ b/drivers/net/jz4760_eth.h
@@ -0,0 +1,1054 @@
+/*
+ * Jz4760 On-Chip ethernet driver.
+ *
+ * Copyright (C) 2005 - 2007 Ingenic Semiconductor Inc. Jason<xwang@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 __JZ4760_ETH_H__
+#define __JZ4760_ETH_H__
+
+
+// ----------------------------------------------------------------------------------
+// PE-MACMII registers (16-bit)
+// ----------------------------------------------------------------------------------
+
+#define ETH_MAC_MCR1 (ETHC_BASE + 0x00 )// MAC configuration register #1
+#define ETH_MAC_MCR2 (ETHC_BASE + 0x04 )// MAC configuration register #2
+#define ETH_MAC_IPGR (ETHC_BASE + 0x08 )// Back-to-Back Inter-Packet-Gap register
+#define ETH_MAC_NIPGR (ETHC_BASE + 0x0c )// Non-Back-to-Back Inter-Packet-Gap register
+#define ETH_MAC_CWR (ETHC_BASE + 0x10 )// Collision Window / Retry register
+#define ETH_MAC_MFR (ETHC_BASE + 0x14 )// Maximum Frame register
+#define ETH_MAC_PSR (ETHC_BASE + 0x18 )// PHY Support register (SMII / RMII / PMD / ENDEC)
+#define ETH_MAC_TR (ETHC_BASE + 0x1c )// Test register
+#define ETH_MAC_MCFGR (ETHC_BASE + 0x20 )// MII Mgmt Configuration
+#define ETH_MAC_MCMDR (ETHC_BASE + 0x24 )// MII Mgmt Command
+#define ETH_MAC_MADRR (ETHC_BASE + 0x28 )// MII Mgmt Address
+#define ETH_MAC_MWTDR (ETHC_BASE + 0x2c )// MII Mgmt Write Data
+#define ETH_MAC_MRDDR (ETHC_BASE + 0x30 )// MII Mgmt Read Data
+#define ETH_MAC_MINDR (ETHC_BASE + 0x34 )// MII Mgmt Indicators
+
+#define ETH_MAC_SA0 (ETHC_BASE + 0x40 )// Station Address
+#define ETH_MAC_SA1 (ETHC_BASE + 0x44 )// Station Address
+#define ETH_MAC_SA2 (ETHC_BASE + 0x48 )// Station Address
+
+// Constants for ETH_MAC_MCR1 register
+#define MCR1_SOFTRST (1 << 15) // Soft reset
+#define MCR1_SMLTRST (1 << 14) // Simulation reset
+#define MCR1_MCSRRST (1 << 11) // MAC Control Sublayer / Rx domain logic reset
+#define MCR1_RFUNRST (1 << 10) // Rx Function logic reset
+#define MCR1_MCSTRST (1 << 9) // MAC Control Sublayer / Tx domain logic reset
+#define MCR1_TFUNRST (1 << 8) // Tx Function logic reset
+#define MCR1_LB (1 << 4) // Tx interface loop back to Rx interface
+#define MCR1_TFC (1 << 3) // Enable Tx flow control
+#define MCR1_RFC (1 << 2) // Enable Rx flow control
+#define MCR1_PARF (1 << 1) // Pass all receive frames
+#define MCR1_RE (1 << 0) // Enable receive
+
+// Constants for ETH_MAC_MCR2 register
+#define MCR2_ED (1 << 14) // Defer to carrier indefinitely as per the Standard
+#define MCR2_BPNB (1 << 13) // Back Pressure / No Backoff
+#define MCR2_NB (1 << 12) // No Backoff
+#define MCR2_LPE (1 << 9) // Long Preamble Enforcement
+#define MCR2_PPE (1 << 8) // Pure Preamble Enforcement
+#define MCR2_ADPE (1 << 7) // Auto-Detect Pad Enable
+#define MCR2_VPE (1 << 6) // VLAN Pad Enable
+#define MCR2_PCE (1 << 5) // Pad / CRC Enable
+#define MCR2_CE (1 << 4) // CRC Enable
+#define MCR2_DC (1 << 3) // Delayed CRC
+#define MCR2_HFE (1 << 2) // Huge Frame Enable
+#define MCR2_FLC (1 << 1) // Frame Length Checking
+#define MCR2_FD (1 << 0) // Full-Duplex
+
+// Contants for ETH_MAC_IPGR register
+#define IPGR_MASK 0x007f // In Full-Duplex the recommended value is 0x15(21d)
+
+// Contants for ETH_MAC_NIPGR register
+#define NIPGR_P1_MASK 0x7f00 // The recommended value is 0xC(12d)
+#define NIPGR_P2_MASK 0x007f // The recommended value is 0x12(18d)
+
+// Contants for ETH_MAC_CWR register
+#define CWR_CW_MASK 0x3f00 // Collision window, Default value is 0x37(55d)
+#define CWR_RM_MASK 0x000f // Retry time, default & standard is 0xF(15d)
+
+// Contants for ETH_MAC_PSR register
+#define PSR_RIM (1 << 15) // Reset Interface Module
+#define PSR_PM (1 << 12) // PHY Module
+#define PSR_RPERMII (1 << 11) // Reset PERMII
+#define PSR_OS (1 << 8) // Operating Speed
+#define PSR_RPE100M (1 << 7) // Reset PE100M module
+#define PSR_FQ (1 << 6) // Force Quiet
+#define PSR_NC (1 << 5) // No Cipher
+#define PSR_DLF (1 << 4) // Disable Link Fail
+#define PSR_RPE10T (1 << 3) // Reset PE10T module
+#define PSR_EJP (1 << 1) // Enable Jabber Protection
+#define PSR_BM (1 << 0) // Bit Mode
+
+// Contants for ETH_MAC_TR register
+#define TR_TB (1 << 2) // Test Backpressure
+#define TR_TP (1 << 1) // Test Pause
+#define TR_SPQ (1 << 0) // Shortcut Pause Quanta
+
+// Contants for ETH_MAC_MCFGR register
+#define MCFGR_RST (1 << 15) // Reset MII Mgmt
+#define MCFGR_CS_MASK 0x001c // Clock Reset
+#define MCFGR_SP (1 << 1) // Suppress Preamble
+#define MCFGR_SI (1 << 0) // Scan Increment
+
+// Contants for ETH_MAC_MCMDR register
+#define MCMDR_SCAN (1 << 1) // Cause MII Mgmt module to perform Read cycles continuously
+#define MCMDR_READ (1 << 0) // Cause MII Mgmt module to perform single Read cycles
+#define MII_SCAN (1 << 1)
+#define MII_NO_SCAN 0
+
+// Contants for ETH_MAC_MADRR register
+#define MADRR_PA_MASK 0x1f00 // PHY Address
+#define MADRR_RA_MASK 0x001f // Register Address
+
+// Contants for ETH_MAC_MINDR register
+#define MINDR_LF (1 << 3) // Link Fail
+#define MINDR_NV (1 << 2) // Not Valid
+#define MINDR_S (1 << 1) // Scanning
+#define MINDR_BUSY (1 << 0) // Busy
+
+// ----------------------------------------------------------------------------------
+// M-AHBE DMA control and status registers (32-bit)
+// ----------------------------------------------------------------------------------
+
+#define ETH_DMA_TCR (ETHC_BASE + 0x180)// Transmit control
+#define ETH_DMA_TDR (ETHC_BASE + 0x184)// Pointer to Transmit Descriptor
+#define ETH_DMA_TSR (ETHC_BASE + 0x188)// Transmit Status
+#define ETH_DMA_RCR (ETHC_BASE + 0x18c)// Receive Control
+#define ETH_DMA_RDR (ETHC_BASE + 0x190)// Pointer to Receive Descriptor
+#define ETH_DMA_RSR (ETHC_BASE + 0x194)// Receive Status
+#define ETH_DMA_IMR (ETHC_BASE + 0x198)// Interrupt Mask
+#define ETH_DMA_IR (ETHC_BASE + 0x19c)// Interrupts
+/* ETH_DMA_IR = ETH_DMA_IMR _AND_ corresponding status flags which in ETH_DMA_TSR and ETH_DMA_RSR
+ *
+ * ETH_DMA_IR is read only, so the way to disable all interrupt is clear ETH_DMA_IMR or ETH_DMA_T(R)SR.
+ * Clear ETH_DMA_IMR is better. Then read status and call handle routine.
+ * Reset ETH_DMA_IMR after all interrupt-enabled status flags be cleared.
+ */
+
+// Constants for ETH_DMA_TCR register
+#define TCR_ENABLE (1 << 0) // Enable DMA tx packet transfers
+
+// Constants for ETH_DMA_TSR register
+#define TSR_PKTSENT (1 << 0) // Indicates packet(s) have(has) been successfully txed
+#define TSR_UNDERRUN (1 << 1) // Set whenever DMA controller reads a Empty Flag
+#define TSR_BUSERR (1 << 3) // Indicates that DMA controller found tx bus error
+#define TSR_PKTCNT_MASK (0xFF << 16) // Bit mask of tx packet counter
+#define TSR_FLAGS (TSR_PKTSENT | TSR_UNDERRUN | TSR_BUSERR)
+
+// Constants for ETH_DMA_RCR register
+#define RCR_ENABLE (1 << 0) // Enable DMA rx packet transfers
+
+// Constants for ETH_DMA_RSR register
+#define RSR_PKTRECV (1 << 0) // Indicates packet(s) have(has) been successfully rxed
+#define RSR_OVERFLOW (1 << 2) // Set whenever DMA controller reads a Non-Empty Flag
+#define RSR_BUSERR (1 << 3) // Indicates that DMA controller found rx bus error
+#define RSR_PKTCNT_MASK (0xFF << 16) // Bit mask of rx packet counter
+#define RSR_FLAGS (RSR_PKTRECV | RSR_OVERFLOW | RSR_BUSERR)
+
+// Constants for ETH_DMA_IMR register
+#define IMR_PKTSENT (1 << 0) // Packet sent interrupt mask
+#define IMR_UNDERRUN (1 << 1) // Underrun interrupt mask
+#define IMR_TBUSERR (1 << 3) // Tx bus error interrupt mask
+#define IMR_PKTRECV (1 << 4) // Packet received interrupt mask
+#define IMR_OVERFLOW (1 << 6) // Overflow interrupt mask
+#define IMR_RBUSERR (1 << 7) // Rx bus error interrupt mask
+#define IMR_ALL_IRQ (IMR_UNDERRUN | IMR_TBUSERR | IMR_OVERFLOW | IMR_RBUSERR | IMR_PKTRECV)
+//#define IMR_ALL_IRQ (IMR_UNDERRUN | IMR_TBUSERR | IMR_OVERFLOW | IMR_RBUSERR | IMR_PKTSENT | IMR_PKTRECV)
+
+#define BURST_LEN_LO (1 << 27)
+#define BURST_LEN_HI (1 << 28)
+// Burst length configuration.
+// HI LO Burst length
+// 0 0 4
+// 0 1 8
+// 1 0 16
+// 1 1 4
+#define BURST_LEN_4 (0 << 27)
+#define BURST_LEN_8 (1 << 27)
+#define BURST_LEN_16 (2 << 27)
+
+// ----------------------------------------------------------------------------------
+// M-MIIFIF (32-bits) registers (32-bit)
+// ----------------------------------------------------------------------------------
+
+#define ETH_FIFO_CR0 (ETHC_BASE + 0x3c )// Configuration Register 0
+#define ETH_FIFO_CR1 (ETHC_BASE + 0x4c )// Configuration Register 1
+#define ETH_FIFO_CR2 (ETHC_BASE + 0x50 )// Configuration Register 2
+#define ETH_FIFO_CR3 (ETHC_BASE + 0x54 )// Configuration Register 3
+#define ETH_FIFO_CR4 (ETHC_BASE + 0x58 )// Configuration Register 4
+#define ETH_FIFO_CR5 (ETHC_BASE + 0x5c )// Configuration Register 5
+
+#define ETH_FIFO_RAR0 (ETHC_BASE + 0x60 )// RAM Access Register 0
+#define ETH_FIFO_RAR1 (ETHC_BASE + 0x64 )// RAM Access Register 1
+#define ETH_FIFO_RAR2 (ETHC_BASE + 0x68 )// RAM Access Register 2
+#define ETH_FIFO_RAR3 (ETHC_BASE + 0x6c )// RAM Access Register 3
+#define ETH_FIFO_RAR4 (ETHC_BASE + 0x70 )// RAM Access Register 4
+#define ETH_FIFO_RAR5 (ETHC_BASE + 0x74 )// RAM Access Register 5
+#define ETH_FIFO_RAR6 (ETHC_BASE + 0x78 )// RAM Access Register 6
+#define ETH_FIFO_RAR7 (ETHC_BASE + 0x7c )// RAM Access Register 7
+
+// Constants for ETH_FIFO_CR0 register
+#define FTF_EN_RPLY (1 << 20) // Indicate whether mmiitfif_fab module is enabled
+#define STF_EN_RPLY (1 << 19) // Indicate whether mmiitfif_sys module is enabled
+#define FRF_EN_RPLY (1 << 18) // Indicate whether mmiirfif_fab module is enabled
+#define SRF_EN_RPLY (1 << 17) // Indicate whether mmiirfif_sys module is enabled
+#define WTM_EN_RPLY (1 << 16) // Indicate whether mmiitfif_wtm module is enabled
+#define ALL_EN_RPLY (FTF_EN_RPLY | STF_EN_RPLY | FRF_EN_RPLY | SRF_EN_RPLY | WTM_EN_RPLY)
+
+#define FTF_EN_REQ (1 << 12) // Request enable/disable -ing the mmiitfif_fab module
+#define STF_EN_REQ (1 << 11) // Request enable/disable -ing the mmiitfif_sys module
+#define FRF_EN_REQ (1 << 10) // Request enable/disable -ing the mmiirfif_fab module
+#define SRF_EN_REQ (1 << 9) // Request enable/disable -ing the mmiirfif_sys module
+#define WTM_EN_REQ (1 << 8) // Request enable/disable -ing the mmiitfif_wtm module
+#define ALL_EN_REQ (FTF_EN_REQ | STF_EN_REQ | FRF_EN_REQ | SRF_EN_REQ | WTM_EN_REQ)
+
+#define FTF_RST (1 << 4) // Reset mmiitfif_fab module
+#define STF_RST (1 << 3) // Reset mmiitfif_sys module
+#define FRT_RST (1 << 2) // Reset mmiirfif_fab module
+#define SRF_RST (1 << 1) // Reset mmiirfif_sys module
+#define WTM_RST (1 << 0) // Reset mmiitfif_wtm module
+#define ALL_RST (FTF_RST | STF_RST | FRT_RST | SRF_RST | WTM_RST)
+
+// Constants for ETH_FIFO_CR1 register
+#define CFG_FR_TH_MASK (0x0fff << 16) // Fabric Receive Threshold mask
+#define CFG_XOFF_RTX_MASK 0xffff // ??????????????
+
+// Constants for ETH_FIFO_CR2 register
+#define CFG_H_WM_MASK (0x1fff << 16) // Receive RAM high watermark mask
+#define CFG_L_WM_MASK 0x1fff // Receive RAM low watermark mask
+
+// Constants for ETH_FIFO_CR3 register
+#define CFG_H_WM_FT_MASK (0x0fff << 16) // ??????????????
+#define CFG_FT_TH_MASK 0xffff // Fabric Transmit Threshold mask
+
+// Constants for ETH_FIFO_CR4 register
+#define HST_FLT_RFRM_MASK 0xffff // Indicate drop condition
+
+// Constants for ETH_FIFO_CR5 register
+#define CFG_H_DPLX (1 << 22) // Enable Half-duplex backpressure as flow control mchm
+#define CFG_SR_FULL (1 << 21) // Indicate whether FIFO storage has been met or exceeded
+#define CFG_SR_FULL_CLR (1 << 20) // Clear CFG_SR_FULL bit
+#define CLK_EN_MODE (1 << 19) //
+#define HST_DR_LT_64 (1 << 18) // Drop the frame which less than 16 bit length
+#define HST_FLT_RFRMDC_MASK (0xffff) // Indicate drop condition ... which don't care
+
+// Constants for ETH_FIFO_RAR0 register
+#define RAR0_HT_W_REQ (1 << 31) // Host Tx RAM write request
+#define RAR0_HT_W_ACK (1 << 30) // Host Tx RAM write acknowledge
+#define RAR0_HT_W_CD_MASK (0xff << 16) // Host Tx RAM write control data
+#define RAR0_HT_W_ADDR_MASK (0x3ff << 0) // Host Tx RAM write address, [9:0] 10 bit, (4k RAM / 4 = 1024)
+
+// Constants for ETH_FIFO_RAR2 register
+#define RAR2_HT_R_REQ (1 << 31) // Host Tx RAM read request
+#define RAR2_HT_R_ACK (1 << 30) // Host Tx RAM read acknowledge
+#define RAR2_HT_R_CD_MASK (0xff << 16) // Host Tx RAM read control data
+#define RAR2_HT_R_ADDR_MASK (0x3ff << 0) // Host Tx RAM read address, [9:0] 10 bit
+
+// Constants for ETH_FIFO_RAR4 register
+#define RAR4_HR_W_REQ (1 << 31) // Host Rx RAM write request
+#define RAR4_HR_W_ACK (1 << 30) // Host Rx RAM write acknowledge
+#define RAR4_HR_W_CD_MASK (0xf << 16) // Host Rx RAM write control data
+#define RAR4_HR_W_ADDR_MASK (0x3ff << 0) // Host Rx RAM write address
+
+// Constants for ETH_FIFO_RAR6 register
+#define RAR4_HR_R_REQ (1 << 31) // Host Rx RAM read request
+#define RAR4_HR_R_ACK (1 << 30) // Host Rx RAM read acknowledge
+#define RAR4_HR_R_CD_MASK (0xf << 16) // Host Rx RAM read control data
+#define RAR4_HR_R_ADDR_MASK (0x3ff << 0) // Host Rx RAM read address
+
+// ----------------------------------------------------------------------------------
+// PE-MSTAT registers (32-bit)
+// ----------------------------------------------------------------------------------
+
+// Several control signal
+#define ETH_STAT_CR ETH_DMA_IMR // Use high 3 bits of ETH_DMA_IMR
+#define STAT_EN (1 << 31) // Enable PE-MSTAT module
+#define STAT_CL (1 << 30) // Clear counters, need voltage jump
+#define STAT_AZ (1 << 29) // Enable Auto-Zero after read
+
+// Combined transmit and receive counters. [17 : 0] available
+#define ETH_STAT_TR64 (ETHC_BASE + 0x80 )// Tx & Rx 64 bytes frame counter
+#define ETH_STAT_TR127 (ETHC_BASE + 0x84 )// Tx & Rx 65 ~ 127 bytes frame counter
+#define ETH_STAT_TR255 (ETHC_BASE + 0x88 )// Tx & Rx 128 ~ 255 bytes frame counter
+#define ETH_STAT_TR511 (ETHC_BASE + 0x8c )// Tx & Rx 256 ~ 511 bytes frame counter
+#define ETH_STAT_TR1K (ETHC_BASE + 0x90 )// Tx & Rx 512 ~ 1023 bytes frame counter
+#define ETH_STAT_TRMAX (ETHC_BASE + 0x94 )// Tx & Rx 1024 ~ 1518 bytes frame counter
+#define ETH_STAT_TRMGV (ETHC_BASE + 0x98 )// Tx & Rx 1519 ~ 1522 bytes good VLAN frame counter
+
+// Receive counters
+#define ETH_STAT_RBYT (ETHC_BASE + 0x9c )// Rx Byte counter [23 : 0]
+#define ETH_STAT_RPKT (ETHC_BASE + 0xa0 )// Rx Packet counter [17 : 0]
+#define ETH_STAT_RFCS (ETHC_BASE + 0xa4 )// Rx FCS Error counter [11 : 0]
+#define ETH_STAT_RMCA (ETHC_BASE + 0xa8 )// Rx Multicast packet counter [17 : 0]
+#define ETH_STAT_RBCA (ETHC_BASE + 0xac )// Rx Broadcast packet counter [21 : 0]
+#define ETH_STAT_RXCF (ETHC_BASE + 0xb0 )// Rx Control frame packet counter [17 : 0]
+#define ETH_STAT_RXPF (ETHC_BASE + 0xb4 )// Rx PAUSE frame packet counter [11 : 0]
+#define ETH_STAT_RXUO (ETHC_BASE + 0xb8 )// Rx Unkown OP code counter [11 : 0]
+#define ETH_STAT_RALN (ETHC_BASE + 0xbc )// Rx Alignment Error counter [11 : 0]
+#define ETH_STAT_RFLR (ETHC_BASE + 0xc0 )// Rx Frame Length Error counter [15 : 0]
+#define ETH_STAT_RCDE (ETHC_BASE + 0xc4 )// Rx Code Error counter [11 : 0]
+#define ETH_STAT_RCSE (ETHC_BASE + 0xc8 )// Rx Carrier Sense Error counter [11 : 0]
+#define ETH_STAT_RUND (ETHC_BASE + 0xcc )// Rx Undersize packet counter [11 : 0]
+#define ETH_STAT_ROVR (ETHC_BASE + 0xd0 )// Rx Oversize packet counter [11 : 0]
+#define ETH_STAT_RFRG (ETHC_BASE + 0xd4 )// Rx Fragments counter [11 : 0]
+#define ETH_STAT_RJBR (ETHC_BASE + 0xd8 )// Rx Jabber counter [11 : 0]
+#define ETH_STAT_RDRP (ETHC_BASE + 0xdc )// Rx Drop [11 : 0]
+
+// Transmit counters
+#define ETH_STAT_TBYT (ETHC_BASE + 0xe0 )// Tx Byte counter [23 : 0]
+#define ETH_STAT_TPKT (ETHC_BASE + 0xe4 )// Tx Packet counter [17 : 0]
+#define ETH_STAT_TMCA (ETHC_BASE + 0xe8 )// Tx Multicast packet counter [17 : 0]
+#define ETH_STAT_TBCA (ETHC_BASE + 0xec )// Tx Broadcast packet counter [17 : 0]
+#define ETH_STAT_TXPF (ETHC_BASE + 0xf0 )// Tx PAUSE frame packet counter [11 : 0]
+#define ETH_STAT_TDFR (ETHC_BASE + 0xf4 )// Tx Deferral packet counter [11 : 0]
+#define ETH_STAT_TEDF (ETHC_BASE + 0xf8 )// Tx Excessive Deferral packet counter [11 : 0]
+#define ETH_STAT_TSCL (ETHC_BASE + 0xfc )// Tx Single Collision packet counter [11 : 0]
+#define ETH_STAT_TMCL (ETHC_BASE + 0x100)// Tx Multiple Collision packet counte [11 : 0]
+#define ETH_STAT_TLCL (ETHC_BASE + 0x104)// Tx Late Collision packet counter [11 : 0]
+#define ETH_STAT_TXCL (ETHC_BASE + 0x108)// Tx Excessive Collision packet counter [11 : 0]
+#define ETH_STAT_TNCL (ETHC_BASE + 0x10c)// Tx Total Collision packet counter [12 : 0]
+#define ETH_STAT_TPFH (ETHC_BASE + 0x110)// Tx PAUSE frames Honored counter [11 : 0]
+#define ETH_STAT_TDRP (ETHC_BASE + 0x114)// Tx Drop frame counter [11 : 0]
+#define ETH_STAT_TJBR (ETHC_BASE + 0x118)// Tx Jabber frame counter [11 : 0]
+#define ETH_STAT_TFCS (ETHC_BASE + 0x11c)// Tx FCS Error counter [11 : 0]
+#define ETH_STAT_TXCF (ETHC_BASE + 0x120)// Tx Control frame counter [11 : 0]
+#define ETH_STAT_TOVR (ETHC_BASE + 0x124)// Tx Oversize frame counter [11 : 0]
+#define ETH_STAT_TUND (ETHC_BASE + 0x128)// Tx Undersize frame counter [11 : 0]
+#define ETH_STAT_TFRG (ETHC_BASE + 0x12c)// Tx Fragments frame counter [11 : 0]
+
+// Carry registers
+#define ETH_STAT_CAR1 (ETHC_BASE + 0x130)// Carry Register 1
+#define ETH_STAT_CAR2 (ETHC_BASE + 0x134)// Carry Register 2
+#define ETH_STAT_CARM1 (ETHC_BASE + 0x138)// Carry Mask Register 1
+#define ETH_STAT_CARM2 (ETHC_BASE + 0x13c)// Carry Mask Register 2
+
+// Constants for ETH_STAT_CAR*
+#define CAR1_TR64 (1 << 31)
+#define CAR1_TR127 (1 << 30)
+#define CAR1_TR255 (1 << 29)
+#define CAR1_TR511 (1 << 28)
+#define CAR1_TR1K (1 << 27)
+#define CAR1_TRMAX (1 << 26)
+#define CAR1_TRMGV (1 << 25)
+#define CAR1_RBY (1 << 16)
+#define CAR1_RPK (1 << 15)
+#define CAR1_RFC (1 << 14)
+#define CAR1_RMC (1 << 13)
+#define CAR1_RBC (1 << 12)
+#define CAR1_RXC (1 << 11)
+#define CAR1_RXP (1 << 10)
+#define CAR1_RXU (1 << 9)
+#define CAR1_RAL (1 << 8)
+#define CAR1_RFL (1 << 7)
+#define CAR1_RCD (1 << 6)
+#define CAR1_RCS (1 << 5)
+#define CAR1_RUN (1 << 4)
+#define CAR1_ROV (1 << 3)
+#define CAR1_RFR (1 << 2)
+#define CAR1_RJB (1 << 1)
+#define CAR1_RDR (1 << 0)
+
+#define CAR2_TJB (1 << 19)
+#define CAR2_TFC (1 << 18)
+#define CAR2_TCF (1 << 17)
+#define CAR2_TOV (1 << 16)
+#define CAR2_TUN (1 << 15)
+#define CAR2_TFG (1 << 14)
+#define CAR2_TBY (1 << 13)
+#define CAR2_TPK (1 << 12)
+#define CAR2_TMC (1 << 11)
+#define CAR2_TBC (1 << 10)
+#define CAR2_TPF (1 << 9)
+#define CAR2_TDF (1 << 8)
+#define CAR2_TED (1 << 7)
+#define CAR2_TSC (1 << 6)
+#define CAR2_TMA (1 << 5)
+#define CAR2_TLC (1 << 4)
+#define CAR2_TXC (1 << 3)
+#define CAR2_TNC (1 << 2)
+#define CAR2_TPH (1 << 1)
+#define CAR2_TDP (1 << 0)
+
+#define CARM1_TR64 (1 << 31)
+#define CARM1_TR127 (1 << 30)
+#define CARM1_TR255 (1 << 29)
+#define CARM1_TR511 (1 << 28)
+#define CARM1_TR1K (1 << 27)
+#define CARM1_TRMAX (1 << 26)
+#define CARM1_TRMGV (1 << 25)
+#define CARM1_RBY (1 << 16)
+#define CARM1_RPK (1 << 15)
+#define CARM1_RFC (1 << 14)
+#define CARM1_RMC (1 << 13)
+#define CARM1_RBC (1 << 12)
+#define CARM1_RXC (1 << 11)
+#define CARM1_RXP (1 << 10)
+#define CARM1_RXU (1 << 9)
+#define CARM1_RAL (1 << 8)
+#define CARM1_RFL (1 << 7)
+#define CARM1_RCD (1 << 6)
+#define CARM1_RCS (1 << 5)
+#define CARM1_RUN (1 << 4)
+#define CARM1_ROV (1 << 3)
+#define CARM1_RFR (1 << 2)
+#define CARM1_RJB (1 << 1)
+#define CARM1_RDR (1 << 0)
+
+#define CARM2_TJB (1 << 19)
+#define CARM2_TFC (1 << 18)
+#define CARM2_TCF (1 << 17)
+#define CARM2_TOV (1 << 16)
+#define CARM2_TUN (1 << 15)
+#define CARM2_TFG (1 << 14)
+#define CARM2_TBY (1 << 13)
+#define CARM2_TPK (1 << 12)
+#define CARM2_TMC (1 << 11)
+#define CARM2_TBC (1 << 10)
+#define CARM2_TPF (1 << 9)
+#define CARM2_TDF (1 << 8)
+#define CARM2_TED (1 << 7)
+#define CARM2_TSC (1 << 6)
+#define CARM2_TMA (1 << 5)
+#define CARM2_TLC (1 << 4)
+#define CARM2_TXC (1 << 3)
+#define CARM2_TNC (1 << 2)
+#define CARM2_TPH (1 << 1)
+#define CARM2_TDP (1 << 0)
+
+// ----------------------------------------------------------------------------------
+// PE-SAL registers (32-bit)
+// ----------------------------------------------------------------------------------
+
+#define ETH_SAL_AFR (ETHC_BASE + 0x1a0)// Address Filter Register
+#define ETH_SAL_HT1 (ETHC_BASE + 0x1a4)// Hash Table [64 : 32]
+#define ETH_SAL_HT2 (ETHC_BASE + 0x1a8)// Hash Table [31 : 0 ]
+
+// Constants for ETH_SAL_AFR
+#define AFR_PRO (1 << 3) // Promiscuous mode
+#define AFR_PRM (1 << 2) // Accept Multicast
+#define AFR_AMC (1 << 1) // Accept Multicast qualified
+#define AFR_ABC (1 << 0) // Accept Broadcast
+
+// ----------------------------------------------------------------------------------
+// MISC definition
+// ----------------------------------------------------------------------------------
+
+// Receive Status Vector
+#define RSV_RVTD (1 << 30) // Receive VLAN Type detected
+#define RSV_RUO (1 << 29) // Receive Unsupported Op-code
+#define RSV_RPCF (1 << 28) // Receive Pause Control Frame
+#define RSV_RCF (1 << 27) // Receive Control Frame
+#define RSV_DN (1 << 26) // Dribble Nibble
+#define RSV_BP (1 << 25) // Broadcast Packet
+#define RSV_MP (1 << 24) // Multicast Packet
+#define RSV_OK (1 << 23) // Receive OK
+#define RSV_LOR (1 << 22) // Length Out of Range
+#define RSV_LCE (1 << 21) // Length Check Error
+#define RSV_CRCE (1 << 20) // CRC Error
+#define RSV_RCV (1 << 19) // Receive Code Violation
+#define RSV_CEPS (1 << 18) // Carrier Event Previously Seen
+#define RSV_REPS (1 << 17) // RXDV Event Previously Seen
+#define RSV_PPI (1 << 16) // Packet Previously Ignored
+
+// ----------------------------------------------------------------------------------
+// MII Registers and Definitions
+// ----------------------------------------------------------------------------------
+
+#define MII_BMCR 0x00 /* MII Management Control Register */
+#define MII_BMSR 0x01 /* MII Management Status Register */
+#define MII_ID1 0x02 /* PHY Identifier Register 0 */
+#define MII_ID2 0x03 /* PHY Identifier Register 1 */
+#define MII_ANAR 0x04 /* Auto Negotiation Advertisement */
+#define MII_ANLPAR 0x05 /* Auto Negotiation Link Partner Ability */
+#define MII_ANER 0x06 /* Auto Negotiation Expansion */
+#define MII_ANP 0x07 /* Auto Negotiation Next Page TX */
+#define MII_DSCR 0x10 /* Davicom Specified Configration Register */
+#define MII_DSCSR 0x11 /* Davicom Specified Configration/Status Register */
+#define MII_10BTCSR 0x12 /* 10base-T Specified Configration/Status Register */
+
+#define MII_PREAMBLE 0xffffffff /* MII Management Preamble */
+#define MII_TEST 0xaaaaaaaa /* MII Test Signal */
+#define MII_STRD 0x06 /* Start of Frame+Op Code: use low nibble */
+#define MII_STWR 0x0a /* Start of Frame+Op Code: use low nibble */
+
+// MII Management Control Register
+#define MII_CR_RST 0x8000 /* RESET the PHY chip */
+#define MII_CR_LPBK 0x4000 /* Loopback enable */
+#define MII_CR_SPD 0x2000 /* 0: 10Mb/s; 1: 100Mb/s */
+#define MII_CR_10 0x0000 /* Set 10Mb/s */
+#define MII_CR_100 0x2000 /* Set 100Mb/s */
+#define MII_CR_ASSE 0x1000 /* Auto Speed Select Enable */
+#define MII_CR_PD 0x0800 /* Power Down */
+#define MII_CR_ISOL 0x0400 /* Isolate Mode */
+#define MII_CR_RAN 0x0200 /* Restart Auto Negotiation */
+#define MII_CR_FDM 0x0100 /* Full Duplex Mode */
+#define MII_CR_CTE 0x0080 /* Collision Test Enable */
+
+// MII Management Status Register
+#define MII_SR_T4C 0x8000 /* 100BASE-T4 capable */
+#define MII_SR_TXFD 0x4000 /* 100BASE-TX Full Duplex capable */
+#define MII_SR_TXHD 0x2000 /* 100BASE-TX Half Duplex capable */
+#define MII_SR_TFD 0x1000 /* 10BASE-T Full Duplex capable */
+#define MII_SR_THD 0x0800 /* 10BASE-T Half Duplex capable */
+#define MII_SR_ASSC 0x0020 /* Auto Speed Selection Complete*/
+#define MII_SR_RFD 0x0010 /* Remote Fault Detected */
+#define MII_SR_ANC 0x0008 /* Auto Negotiation capable */
+#define MII_SR_LKS 0x0004 /* Link Status */
+#define MII_SR_JABD 0x0002 /* Jabber Detect */
+#define MII_SR_XC 0x0001 /* Extended Capabilities */
+
+// MII Management Auto Negotiation Advertisement Register
+#define MII_ANAR_TAF 0x03e0 /* Technology Ability Field */
+#define MII_ANAR_T4AM 0x0200 /* T4 Technology Ability Mask */
+#define MII_ANAR_TXAM 0x0180 /* TX Technology Ability Mask */
+#define MII_ANAR_FDAM 0x0140 /* Full Duplex Technology Ability Mask */
+#define MII_ANAR_HDAM 0x02a0 /* Half Duplex Technology Ability Mask */
+#define MII_ANAR_100M 0x0380 /* 100Mb Technology Ability Mask */
+#define MII_ANAR_10M 0x0060 /* 10Mb Technology Ability Mask */
+#define MII_ANAR_CSMA 0x0001 /* CSMA-CD Capable */
+
+// MII Management Auto Negotiation Remote End Register
+#define MII_ANLPAR_NP 0x8000 /* Next Page (Enable) */
+#define MII_ANLPAR_ACK 0x4000 /* Remote Acknowledge */
+#define MII_ANLPAR_RF 0x2000 /* Remote Fault */
+#define MII_ANLPAR_TAF 0x03e0 /* Technology Ability Field */
+#define MII_ANLPAR_T4AM 0x0200 /* T4 Technology Ability Mask */
+#define MII_ANLPAR_TXAM 0x0180 /* TX Technology Ability Mask */
+#define MII_ANLPAR_FDAM 0x0140 /* Full Duplex Technology Ability Mask */
+#define MII_ANLPAR_HDAM 0x02a0 /* Half Duplex Technology Ability Mask */
+#define MII_ANLPAR_100M 0x0380 /* 100Mb Technology Ability Mask */
+#define MII_ANLPAR_10M 0x0060 /* 10Mb Technology Ability Mask */
+#define MII_ANLPAR_CSMA 0x0001 /* CSMA-CD Capable */
+
+// Media / mode state machine definitions
+// User selectable:
+#define TP 0x0040 /* 10Base-T (now equiv to _10Mb) */
+#define TP_NW 0x0002 /* 10Base-T with Nway */
+#define BNC 0x0004 /* Thinwire */
+#define AUI 0x0008 /* Thickwire */
+#define BNC_AUI 0x0010 /* BNC/AUI on DC21040 indistinguishable */
+#define _10Mb 0x0040 /* 10Mb/s Ethernet */
+#define _100Mb 0x0080 /* 100Mb/s Ethernet */
+#define AUTO 0x4000 /* Auto sense the media or speed */
+
+// Internal states
+#define NC 0x0000 /* No Connection */
+#define ANS 0x0020 /* Intermediate AutoNegotiation State */
+#define SPD_DET 0x0100 /* Parallel speed detection */
+#define INIT 0x0200 /* Initial state */
+#define EXT_SIA 0x0400 /* External SIA for motherboard chip */
+#define ANS_SUSPECT 0x0802 /* Suspect the ANS (TP) port is down */
+#define TP_SUSPECT 0x0803 /* Suspect the TP port is down */
+#define BNC_AUI_SUSPECT 0x0804 /* Suspect the BNC or AUI port is down */
+#define EXT_SIA_SUSPECT 0x0805 /* Suspect the EXT SIA port is down */
+#define BNC_SUSPECT 0x0806 /* Suspect the BNC port is down */
+#define AUI_SUSPECT 0x0807 /* Suspect the AUI port is down */
+#define MII 0x1000 /* MII on the 21143 */
+
+// ----------------------------------------------------------------------------------
+// Device data and structure
+// ----------------------------------------------------------------------------------
+
+#define READ_COMMAND (SIOCDEVPRIVATE+4)
+#define WRITE_COMMAND (SIOCDEVPRIVATE+5)
+#define GETDRIVERINFO (SIOCDEVPRIVATE+6)
+
+#define ETH_TX_TIMEOUT (6*HZ)
+
+#define RX_BUF_SIZE (1536 + 64)
+
+#define NUM_RX_DESCS 64
+#define NUM_TX_DESCS 16
+
+#define MAX_WAIT 2000
+
+#define STAT_INTERVAL HZ * 3
+
+// Constants for DMA descriptor
+#define EMPTY_FLAG_MASK (0x01 << 31)
+#define FTPP_FLAGS_MASK (0x1f << 16)
+#define FTCFRM_MASK (0x01 << 20)
+#define FTPP_PADMODE_MASK (0x03 << 18)
+#define FTPP_GENFCS_MASK (0x01 << 17)
+#define FTPP_EN_MASK (0x01 << 16)
+
+#define PKT_SIZE_MASK (0x0FFF)
+
+/*
+static const char *media_types[] = {
+ "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ",
+ "100baseTx-FD", "100baseT4", 0
+};
+*/
+
+typedef struct {
+ unsigned int pkt_addr; // phy addr
+ unsigned int pkt_size; // include empty flag
+ unsigned int next_desc; // phy addr
+
+ unsigned int for_align; // for 4-word alignment
+} jz_desc_t;
+
+
+enum counters{
+// CNT_TR64,
+// CNT_TR127,
+// CNT_TR255,
+// CNT_TR511,
+// CNT_TR1K,
+// CNT_TRMAX,
+// CNT_TRMGV,
+ CNT_RBYT,
+ CNT_RPKT,
+ CNT_RFCS,
+ CNT_RMCA,
+// CNT_RBCA,
+// CNT_RXCF,
+// CNT_RXPF,
+// CNT_RXUO,
+// CNT_RALN,
+// CNT_RFLR,
+// CNT_RCDE,
+// CNT_RCSE,
+// CNT_RUND,
+// CNT_ROVR,
+// CNT_RFRG,
+// CNT_RJBR,
+ CNT_RDRP,
+ CNT_TBYT,
+ CNT_TPKT,
+// CNT_TMCA,
+// CNT_TBCA,
+// CNT_TXPF,
+// CNT_TDFR,
+// CNT_TEDF,
+// CNT_TSCL,
+// CNT_TMCL,
+// CNT_TLCL,
+// CNT_TXCL,
+ CNT_TNCL,
+// CNT_TPFH,
+ CNT_TDRP,
+// CNT_TJBR,
+ CNT_TFCS,
+// CNT_TXCF,
+// CNT_TOVR,
+// CNT_TUND,
+// CNT_TFRG,
+
+ STAT_CNT_NUM
+};
+
+
+/* Allocate by alloc_etherdev, which could ensure the struct was 32-byte align */
+struct jz_eth_private {
+
+ jz_desc_t tx_ring[NUM_TX_DESCS]; /* transmit descriptors, 4-word align */
+ jz_desc_t rx_ring[NUM_RX_DESCS]; /* receive descriptors, 4-word align */
+
+ dma_addr_t dma_tx_ring; /* bus address of tx ring */
+ dma_addr_t dma_rx_ring; /* bus address of rx ring */
+ dma_addr_t dma_rx_buf; /* DMA address of rx buffer */
+ unsigned int vaddr_rx_buf; /* virtual address of rx buffer */
+
+ unsigned int rx_head; /* first rx descriptor */
+ unsigned int tx_head; /* first tx descriptor */
+ unsigned int tx_tail; /* last unacked transmit packet */
+ unsigned int tx_full; /* transmit buffers are full */
+ struct sk_buff *tx_skb[NUM_TX_DESCS]; /* skbuffs for packets to transmit */
+
+ struct net_device_stats stats;
+ unsigned int carry_counters[STAT_CNT_NUM];
+
+ spinlock_t lock;
+
+ int media; /* Media (eg TP), mode (eg 100B)*/
+ int full_duplex; /* Current duplex setting */
+ int link_state;
+ char phys[32]; /* List of attached PHY devices */
+ char valid_phy; /* Current linked phy-id with MAC */
+ int mii_phy_cnt;
+ int phy_type; /* 1-RTL8309,0-DVCOM */
+ struct ethtool_cmd ecmds[32];
+ u16 advertising; /* NWay media advertisement */
+
+ struct task_struct *thread; /* Link cheak thread */
+ int thread_die;
+ struct completion thr_exited;
+ wait_queue_head_t thr_wait;
+
+ struct pm_dev *pmdev;
+};
+
+// ----------------------------------------------------------------------------------
+// Operation defination
+// ----------------------------------------------------------------------------------
+
+// Operations of ETH DMA
+#define __eth_dma_tx_enable() \
+do { \
+ REG32(ETH_DMA_TCR) |= TCR_ENABLE; \
+} while(0)
+
+#define __eth_dma_tx_disable() \
+do { \
+ REG32(ETH_DMA_TCR) &= ~TCR_ENABLE; \
+} while(0)
+
+#define __eth_dma_set_burst_len(len_macro) \
+do { \
+ REG32(ETH_DMA_IMR) &= ~(BURST_LEN_LO | BURST_LEN_HI); \
+ REG32(ETH_DMA_IMR) |= (len_macro); \
+} while(0)
+
+#define __eth_set_tx_desc_addr(desc_addr) \
+do { \
+ REG32(ETH_DMA_TDR) = desc_addr; \
+} while(0)
+
+#define __eth_get_flag_pkt_sent() (REG32(ETH_DMA_TSR) & TSR_PKTSENT)
+#define __eth_get_flag_underrun() (REG32(ETH_DMA_TSR) & TSR_UNDERRUN)
+#define __eth_get_flag_tx_bus_err() (REG32(ETH_DMA_TSR) & TSR_BUSERR)
+#define __eth_get_tx_pkt_cnt() ((REG32(ETH_DMA_TSR) & TSR_PKTCNT_MASK) >> 0x10)
+
+#define __eth_reduce_pkt_sent_cnt() (REG32(ETH_DMA_TSR) |= TSR_PKTSENT)
+#define __eth_clear_flag_underrun() (REG32(ETH_DMA_TSR) |= TSR_UNDERRUN)
+#define __eth_clear_flag_tx_bus_err() (REG32(ETH_DMA_TSR) |= TSR_BUSERR)
+#define __eth_clear_tx_pkt_cnt() \
+do { \
+ unsigned int tmp_cnt = __eth_get_tx_pkt_cnt(); \
+ for (; tmp_cnt > 0; tmp_cnt--) \
+ __eth_reduce_pkt_sent_cnt(); \
+} while(0)
+
+
+
+#define __eth_dma_rx_enable() \
+do { \
+ REG32(ETH_DMA_RCR) |= RCR_ENABLE; \
+} while(0)
+
+#define __eth_dma_rx_disable() \
+do { \
+ REG32(ETH_DMA_RCR) &= ~RCR_ENABLE; \
+} while(0)
+
+#define __eth_set_rx_desc_addr(desc_addr) \
+do { \
+ REG32(ETH_DMA_RDR) = desc_addr; \
+} while(0)
+
+#define __eth_get_flag_pkt_recv() (REG32(ETH_DMA_RSR) & RSR_PKTRECV)
+#define __eth_get_flag_overflow() (REG32(ETH_DMA_RSR) & RSR_OVERFLOW)
+#define __eth_get_flag_rx_bus_err() (REG32(ETH_DMA_RSR) & RSR_BUSERR)
+#define __eth_get_rx_pkt_cnt() ((REG32(ETH_DMA_RSR) & RSR_PKTCNT_MASK) >> 0x10)
+
+#define __eth_reduce_pkt_recv_cnt() (REG32(ETH_DMA_RSR) |= RSR_PKTRECV)
+#define __eth_clear_flag_overflow() (REG32(ETH_DMA_RSR) |= RSR_OVERFLOW)
+#define __eth_clear_flag_rx_bus_err() (REG32(ETH_DMA_RSR) |= RSR_BUSERR)
+#define __eth_clear_rx_pkt_cnt() \
+do { \
+ unsigned int tmp_cnt = __eth_get_rx_pkt_cnt(); \
+ for (; tmp_cnt > 0; tmp_cnt--) \
+ __eth_reduce_pkt_recv_cnt(); \
+} while(0)
+
+#define __eth_clear_rx_flags() \
+do { \
+ /*__eth_clear_rx_pkt_cnt();*/ \
+ REG32(ETH_DMA_RSR) = RSR_OVERFLOW | RSR_BUSERR; \
+} while(0)
+
+#define __eth_clear_tx_flags() \
+do { \
+ /*__eth_clear_tx_pkt_cnt();*/ \
+ REG32(ETH_DMA_TSR) = TSR_UNDERRUN | TSR_BUSERR; \
+} while(0)
+
+#define __eth_enable_irq() \
+do { \
+ REG32(ETH_DMA_IMR) |= IMR_ALL_IRQ; \
+} while(0)
+
+#define __eth_disable_irq() \
+do { \
+ REG32(ETH_DMA_IMR) &= ~IMR_ALL_IRQ; \
+} while(0)
+
+#define __eth_enable() \
+do { \
+ __eth_dma_tx_enable(); \
+ __eth_dma_rx_enable(); \
+} while(0)
+
+#define __eth_disable() \
+do { \
+ __eth_dma_tx_disable(); \
+ __eth_dma_rx_disable(); \
+} while(0)
+
+#define __eth_set_mac_address(b1, b2, b3, b4, b5, b6) \
+do { \
+ REG16(ETH_MAC_SA0) = ((b1) << 8) | ((b2) & 0xff); \
+ REG16(ETH_MAC_SA1) = ((b3) << 8) | ((b4) & 0xff); \
+ REG16(ETH_MAC_SA2) = ((b5) << 8) | ((b6) & 0xff); \
+} while(0)
+
+
+// Operations of ETH MAC registers
+#define __mac_reset() \
+do { \
+ REG16(ETH_MAC_MCR1) |= MCR1_SOFTRST; \
+ udelay(1000); \
+ REG16(ETH_MAC_MCR1) &= ~MCR1_SOFTRST; \
+} while(0)
+
+#define __mac_get_IPGR() (REG16(ETH_MAC_IPGR) & IPGR_MASK)
+
+#define __mac_set_IPGR(ipgt) \
+do { \
+ REG16(ETH_MAC_IPGR) = ipgt; \
+} while(0)
+
+#define __mac_get_NIPGR1() ((REG16(ETH_MAC_NIPGR) & NIPGR_P1_MASK) >> 8)
+
+#define __mac_set_NIPGR1(v1) \
+do { \
+ REG16(ETH_MAC_NIPGR) |= ((v1) << 8) & NIPGR_P1_MASK; \
+} while(0)
+
+#define __mac_get_NIPGR2() (REG16(ETH_MAC_NIPGR) & NIPGR_P2_MASK)
+
+#define __mac_set_NIPGR2(v2) \
+do { \
+ REG16(ETH_MAC_NIPGR) |= (v2) & NIPGR_P2_MASK; \
+} while(0)
+
+#define __mac_get_collision_window() ((REG16(ETH_MAC_CWR) & CWR_CW_MASK) >> 8)
+
+#define __mac_set_collision_window(cw) \
+do { \
+ REG16(ETH_MAC_CWR) |= ((cw) << 8) & CWR_CW_MASK; \
+} while(0)
+
+#define __mac_get_retx_maximum() (REG16(ETH_MAC_CWR) & CWR_RM_MASK)
+
+#define __mac_set_retx_maximum(rm) \
+do { \
+ REG16(ETH_MAC_CWR) |= (rm) & CWR_RM_MASK; \
+} while(0)
+
+#define __mac_get_max_frame_length() (REG16(ETH_MAC_MFR))
+
+#define __mac_set_max_frame_length(len) \
+do { \
+ REG16(ETH_MAC_MFR) = len; \
+} while(0)
+
+#define __mac_set_mii_clk(_clkdiv) \
+do { \
+ REG16(ETH_MAC_MCFGR) |= ((_clkdiv) << 2) & MCFGR_CS_MASK; \
+} while(0)
+
+#define __mac_set_mii_address(pa, ra) \
+do { \
+ REG16(ETH_MAC_MADRR) = \
+ (((pa) << 8)& MADRR_PA_MASK)|((ra) & MADRR_RA_MASK); \
+} while(0)
+
+
+#define __mac_send_mii_read_cmd(pa, ra, scan) \
+do { \
+ __mac_set_mii_address(pa, ra); \
+ REG16(ETH_MAC_MCMDR) &= ~MCMDR_SCAN & ~MCMDR_READ; \
+ REG16(ETH_MAC_MCMDR) |= MCMDR_READ | ((scan) & MCMDR_SCAN); \
+} while(0)
+
+#define __mac_send_mii_write_cmd(pa, ra, wdata) \
+do { \
+ __mac_set_mii_address(pa, ra); \
+ REG16(ETH_MAC_MCMDR) &= ~MCMDR_SCAN & ~MCMDR_READ; \
+ __mac_mii_write_data(wdata); \
+} while(0)
+
+#define __mac_mii_write_data(_2byte) (REG16(ETH_MAC_MWTDR) = _2byte)
+
+#define __mac_mii_read_data() REG16(ETH_MAC_MRDDR)
+
+#define __mac_mii_is_busy() (REG16(ETH_MAC_MINDR) & MINDR_BUSY)
+
+// Operations of ETH FIFO registers
+#define __fifo_enable_all_modules() \
+do { \
+ REG32(ETH_FIFO_CR0) |= ALL_EN_REQ; \
+} while(0)
+
+#define __fifo_enable_all_modules_finish() \
+do { \
+ REG32(ETH_FIFO_CR0) &= ~ALL_EN_REQ; \
+} while(0)
+
+// All enabled mean all reply bits were set except SRF_EN_RPLY...
+#define __fifo_all_enabled() ((REG32(ETH_FIFO_CR0) & (ALL_EN_RPLY & ~SRF_EN_RPLY)) == (ALL_EN_RPLY & ~SRF_EN_RPLY))
+
+#define __fifo_reset_all() \
+do { \
+ REG32(ETH_FIFO_CR0) |= ALL_RST; \
+ REG32(ETH_FIFO_CR0) &= ~ALL_RST; \
+} while(0)
+
+#define __fifo_set_fr_threshold(_th) \
+do { \
+ REG32(ETH_FIFO_CR1) &= ~CFG_FR_TH_MASK; \
+ REG32(ETH_FIFO_CR1) |= ((_th) << 16) & CFG_FR_TH_MASK; \
+} while(0)
+
+#define __fifo_set_XOFF_RTX(_th) \
+do { \
+ REG32(ETH_FIFO_CR1) &= ~CFG_XOFF_RTX_MASK; \
+ REG32(ETH_FIFO_CR1) |= (_th) & CFG_XOFF_RTX_MASK; \
+} while(0)
+
+#define __fifo_set_high_wm(_th) \
+do { \
+ REG32(ETH_FIFO_CR2) &= ~CFG_H_WM_MASK; \
+ REG32(ETH_FIFO_CR2) |= ((_th) << 16) & CFG_H_WM_MASK; \
+} while(0)
+
+#define __fifo_set_low_wm(_th) \
+do { \
+ REG32(ETH_FIFO_CR2) &= ~CFG_L_WM_MASK; \
+ REG32(ETH_FIFO_CR2) |= (_th) & CFG_L_WM_MASK; \
+} while(0)
+
+#define __fifo_set_ft_high_wm(_th) \
+do { \
+ REG32(ETH_FIFO_CR3) &= ~CFG_H_WM_FT_MASK; \
+ REG32(ETH_FIFO_CR3) |= ((_th) << 16) & CFG_H_WM_FT_MASK; \
+} while(0)
+
+#define __fifo_set_ft_threshold(_th) \
+do { \
+ REG32(ETH_FIFO_CR3) &= ~CFG_FT_TH_MASK; \
+ REG32(ETH_FIFO_CR3) |= (_th) & CFG_FT_TH_MASK; \
+} while(0)
+
+#define __fifo_set_drop_cond(_cdt) \
+do { \
+ REG32(ETH_FIFO_CR4) |= ((_cdt) >> 16) & HST_FLT_RFRM_MASK; \
+} while(0)
+
+#define __fifo_set_dropdc_cond(_cdt) \
+do { \
+ REG32(ETH_FIFO_CR5) &= ~(((_cdt)>>16) & HST_FLT_RFRMDC_MASK); \
+} while(0)
+
+#define __fifo_set_pause_control() \
+do { \
+ REG32(ETH_FIFO_CR5) &= ~CFG_H_DPLX; \
+} while(0)
+
+#define __fifo_set_clk_enable_mode() \
+do { \
+ REG32(ETH_FIFO_CR5) |= CLK_EN_MODE; \
+} while(0)
+
+#define __fifo_set_half_duplex() \
+do { \
+ REG32(ETH_FIFO_CR5) |= CFG_H_DPLX; \
+} while(0)
+
+#define __fifo_drop_lt64_frame() \
+do { \
+ REG32(ETH_FIFO_CR5) |= HST_DR_LT_64; \
+} while(0)
+
+// Operations of ETH STAT registers
+#define __stat_enable() \
+do { \
+ REG32(ETH_STAT_CR) |= STAT_EN; \
+} while(0)
+
+#define __stat_disable() \
+do { \
+ REG32(ETH_STAT_CR) &= ~STAT_EN; \
+} while(0)
+
+#define __stat_clear_counters() \
+do { \
+ REG32(ETH_STAT_CR) &= ~STAT_CL; \
+ REG32(ETH_STAT_CR) |= STAT_CL; \
+} while(0)
+
+#define __stat_enable_auto_zero() \
+do { \
+ REG32(ETH_STAT_CR) |= STAT_AZ; \
+} while(0)
+
+#define __stat_disable_auto_zero() \
+do { \
+ REG32(ETH_STAT_CR) &= ~STAT_AZ; \
+} while(0)
+
+#define __stat_enable_carry_irq() \
+do { \
+ __stat_unmask1(CARM1_RPK | CARM1_RBY | CARM1_RFC | CARM1_RDR | CARM1_RMC);\
+ __stat_unmask2(CARM2_TPK | CARM2_TBY | CARM2_TFC | CARM2_TDP | CARM2_TNC);\
+} while(0)
+
+#define __stat_disable_carry_irq() \
+do { \
+ __stat_unmask1(0); \
+ __stat_unmask2(0); \
+} while(0)
+
+#define __stat_unmask1(_counter) \
+do { \
+ REG32(ETH_STAT_CARM1) = ~(_counter); \
+} while(0)
+
+#define __stat_unmask2(_counter) \
+do { \
+ REG32(ETH_STAT_CARM2) = ~(_counter); \
+} while(0)
+
+// Operations of ETH SAL registers
+
+// Anyhow, enable broadcast ...
+#define __sal_set_mode(_mode) \
+do { \
+ REG32(ETH_SAL_AFR) = (_mode) | AFR_ABC; \
+} while(0)
+
+#define __sal_set_hash_table(_hi32, _lo32) \
+do { \
+ REG32(ETH_SAL_HT1) = _hi32; \
+ REG32(ETH_SAL_HT2) = _lo32; \
+} while(0)
+
+#define __sal_get_hash_table(_hi32, _lo32) \
+do { \
+ _hi32 = REG32(ETH_SAL_HT1); \
+ _lo32 = REG32(ETH_SAL_HT2); \
+} while(0)
+
+// Operations of DMA descripter
+#define __desc_get_empty_flag(pktsize) (pktsize & EMPTY_FLAG_MASK)
+#define __desc_get_FTPP_flags(pktsize) ((pktsize & FTPP_FLAGS_MASK) >> 16)
+#define __desc_get_FTCFRM_flag(pktsize) (pktsize & FTCFRM_MASK)
+#define __desc_get_FTPP_PADMODE_flag(pktsize) ((pktsize & FTPP_PADMODE_MASK) >> 18)
+#define __desc_get_FTPP_GENFCS_flag(pktsize) (pktsize & FTPP_GENFCS_MASK)
+#define __desc_get_FTPP_enable_flag(pktsize) (pktsize & FTPP_EN_MASK)
+#define __desc_get_pkt_size(pktsize) (pktsize & PKT_SIZE_MASK)
+
+
+
+#endif
diff --git a/drivers/net/jzcs8900a.c b/drivers/net/jzcs8900a.c
index 03aa8bce17e..0b45081b3a2 100644
--- a/drivers/net/jzcs8900a.c
+++ b/drivers/net/jzcs8900a.c
@@ -57,6 +57,7 @@
#define FULL_DUPLEX
#define INT_PIN 0
+
#ifdef CONFIG_SOC_JZ4740
#define CIRRUS_DEFAULT_IO 0xa8000000
#define CIRRUS_DEFAULT_IRQ 107
@@ -70,7 +71,13 @@
#define CIRRUS_DEFAULT_IRQ (32*2 +6+48)
#endif
-
+#elif CONFIG_SOC_JZ4760
+#ifdef CONFIG_JZ4760_LEPUS
+#define CIRRUS_DEFAULT_IO 0xb4000000
+#elif CONFIG_JZ4760_CYGNUS
+#define CIRRUS_DEFAULT_IO 0xb5000000
+#endif
+#define CIRRUS_DEFAULT_IRQ (GPIO_NET_INT + IRQ_GPIO_0)
#endif
typedef struct {
@@ -108,6 +115,29 @@ static void gpio_init_cs8900(void)
#endif
REG_EMC_SMCR3 |= (1 << 6); //16bit
+
+#elif CONFIG_SOC_JZ4760
+
+#ifdef CONFIG_JZ4760_LEPUS
+ /* We use CS6 with 16-bit data width */
+ __gpio_as_func0(32 * 0 + 26); /* GPA26 CS6# */
+ __gpio_as_func0(32 * 0 + 16); /* GPA16 RD# */
+ __gpio_as_func0(32 * 0 + 17); /* GPA17 WE# */
+
+ REG_EMC_SMCR6 &= ~EMC_SMCR_BW_MASK;
+ REG_EMC_SMCR6 |= EMC_SMCR_BW_16BIT;
+
+#elif CONFIG_JZ4760_CYGNUS
+ /* We use CS5 with 16-bit data width */
+ __gpio_as_func0(32 * 0 + 25); /* GPA25 CS5# */
+ __gpio_as_func0(32 * 0 + 16); /* GPA16 RD# */
+ __gpio_as_func0(32 * 0 + 17); /* GPA17 WE# */
+
+ REG_EMC_SMCR5 &= ~EMC_SMCR_BW_MASK;
+ REG_EMC_SMCR5 |= EMC_SMCR_BW_16BIT;
+#endif
+ __gpio_as_irq_high_level(GPIO_NET_INT); /* irq */
+ __gpio_disable_pull(GPIO_NET_INT); /* disable pull */
#endif
udelay(1);
}
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
new file mode 100644
index 00000000000..300f0ed9475
--- /dev/null
+++ b/drivers/usb/gadget/u_serial.h
@@ -0,0 +1,67 @@
+/*
+ * u_serial.h - interface to USB gadget "serial port"/TTY utilities
+ *
+ * Copyright (C) 2008 David Brownell
+ * Copyright (C) 2008 by Nokia Corporation
+ *
+ * This software is distributed under the terms of the GNU General
+ * Public License ("GPL") as published by the Free Software Foundation,
+ * either version 2 of that License or (at your option) any later version.
+ */
+
+#ifndef __U_SERIAL_H
+#define __U_SERIAL_H
+
+#include <linux/usb/composite.h>
+#include <linux/usb/cdc.h>
+
+/*
+ * One non-multiplexed "serial" I/O port ... there can be several of these
+ * on any given USB peripheral device, if it provides enough endpoints.
+ *
+ * The "u_serial" utility component exists to do one thing: manage TTY
+ * style I/O using the USB peripheral endpoints listed here, including
+ * hookups to sysfs and /dev for each logical "tty" device.
+ *
+ * REVISIT at least ACM could support tiocmget() if needed.
+ *
+ * REVISIT someday, allow multiplexing several TTYs over these endpoints.
+ */
+struct gserial {
+ struct usb_function func;
+
+ /* port is managed by gserial_{connect,disconnect} */
+ struct gs_port *ioport;
+
+ struct usb_ep *in;
+ struct usb_ep *out;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
+
+ /* REVISIT avoid this CDC-ACM support harder ... */
+ struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */
+
+ /* notification callbacks */
+ void (*connect)(struct gserial *p);
+ void (*disconnect)(struct gserial *p);
+ int (*send_break)(struct gserial *p, int duration);
+};
+
+/* utilities to allocate/free request and buffer */
+struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t flags);
+void gs_free_req(struct usb_ep *, struct usb_request *req);
+
+/* port setup/teardown is handled by gadget driver */
+int gserial_setup(struct usb_gadget *g, unsigned n_ports);
+void gserial_cleanup(void);
+
+/* connect/disconnect is handled by individual functions */
+int gserial_connect(struct gserial *, u8 port_num);
+void gserial_disconnect(struct gserial *);
+
+/* functions are bound to configurations by a config or gadget driver */
+int acm_bind_config(struct usb_configuration *c, u8 port_num);
+int gser_bind_config(struct usb_configuration *c, u8 port_num);
+int obex_bind_config(struct usb_configuration *c, u8 port_num);
+
+#endif /* __U_SERIAL_H */
diff --git a/drivers/usb/host/ohci-jz.c b/drivers/usb/host/ohci-jz.c
index 4c43925509b..4391f7514b0 100644
--- a/drivers/usb/host/ohci-jz.c
+++ b/drivers/usb/host/ohci-jz.c
@@ -28,6 +28,36 @@
extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
+/* FIXME: when port 2.6.29's cpm to jz4750, remove me!!! */
+#ifdef CONFIG_SOC_JZ4760
+static void jz_start_ohc(struct platform_device *dev)
+{
+ printk(KERN_DEBUG __FILE__
+ ": starting JZ OHCI USB Controller\n");
+
+ /* Set UHC clock and start */
+ cpm_set_clock(CGU_UHCCLK, 48 * 1000 * 1000);
+ cpm_start_clock(CGM_UHC);
+
+ /* enable host controller */
+ cpm_uhc_phy(1);
+
+ printk(KERN_DEBUG __FILE__
+ ": Clock to USB host has been enabled \n");
+}
+
+static void jz_stop_ohc(struct platform_device *dev)
+{
+ printk(KERN_DEBUG __FILE__
+ ": stopping JZ OHCI USB Controller\n");
+
+ /* disable host controller */
+ cpm_uhc_phy(0);
+
+ cpm_stop_clock(CGM_UHC);
+}
+
+#else /* !CONFIG_SOC_JZ4760 */
static void jz_start_ohc(struct platform_device *dev)
{
@@ -45,6 +75,7 @@ static void jz_start_ohc(struct platform_device *dev)
": Clock to USB host has been enabled \n");
}
+
static void jz_stop_ohc(struct platform_device *dev)
{
printk(KERN_DEBUG __FILE__
@@ -55,7 +86,7 @@ static void jz_stop_ohc(struct platform_device *dev)
#endif
__cpm_stop_uhc();
}
-
+#endif /* CONFIG_SOC_JZ4760 */
/*-------------------------------------------------------------------------*/
@@ -200,6 +231,7 @@ static const struct hc_driver ohci_jz_hc_driver = {
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
+
#ifdef CONFIG_PM
.bus_suspend = ohci_bus_suspend,
.bus_resume = ohci_bus_resume,
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 803adcb5ac1..d2aa076dfbe 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -8,7 +8,7 @@ comment "Enable Host or Gadget support to see Inventra options"
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
config USB_MUSB_HDRC
- depends on (USB || USB_GADGET) && HAVE_CLK
+ depends on (USB || USB_GADGET) # && HAVE_CLK
depends on !SUPERH
select NOP_USB_XCEIV if ARCH_DAVINCI
select TWL4030_USB if MACH_OMAP_3430SDP
@@ -41,6 +41,7 @@ config USB_MUSB_SOC
default y if ARCH_OMAP34XX
default y if (BF54x && !BF544)
default y if (BF52x && !BF522 && !BF523)
+ default y if (SOC_JZ4760)
comment "DaVinci 35x and 644x USB support"
depends on USB_MUSB_HDRC && ARCH_DAVINCI
@@ -54,6 +55,9 @@ comment "OMAP 343x high speed USB support"
comment "Blackfin high speed USB Support"
depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523))
+comment "Ingenic OTG USB support"
+ depends on USB_MUSB_HDRC && SOC_JZ4760
+
config USB_TUSB6010
boolean "TUSB 6010 support"
depends on USB_MUSB_HDRC && !USB_MUSB_SOC
@@ -121,6 +125,9 @@ config USB_MUSB_OTG
to match your requirements.
endchoice
+config USB_MUSB_PERIPHERAL_HOTPLUG
+ bool "Support Ingenic USB Device Controller Hotplug"
+ depends on SOC_JZ4760
# enable peripheral support (including with OTG)
config USB_GADGET_MUSB_HDRC
@@ -154,7 +161,7 @@ config MUSB_PIO_ONLY
config USB_INVENTRA_DMA
bool
depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY
- default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN
+ default ARCH_OMAP2430 || ARCH_OMAP34XX || BLACKFIN || SOC_JZ4760
help
Enable DMA transfers using Mentor's engine.
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 85710ccc188..30789ae9076 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -6,6 +6,10 @@ musb_hdrc-objs := musb_core.o
obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o
+ifeq ($(CONFIG_SOC_JZ4760),y)
+ musb_hdrc-objs += jz4760.o
+endif
+
ifeq ($(CONFIG_ARCH_DAVINCI),y)
musb_hdrc-objs += davinci.o
endif
diff --git a/drivers/usb/musb/jz4760.c b/drivers/usb/musb/jz4760.c
new file mode 100644
index 00000000000..0d0cd34dd14
--- /dev/null
+++ b/drivers/usb/musb/jz4760.c
@@ -0,0 +1,293 @@
+/*
+ * Author: River <zwang@ingenic.cn>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/jzsoc.h>
+
+#include "musb_core.h"
+
+static inline void jz_musb_phy_enable(void)
+{
+ printk(KERN_INFO "jz4760: Enable USB PHY.\n");
+
+ __cpm_enable_otg_phy();
+
+ /* Wait PHY Clock Stable. */
+ udelay(300);
+
+ return;
+}
+
+static inline void jz_musb_phy_disable(void)
+{
+ printk(KERN_INFO "jz4760: Disable USB PHY.\n");
+
+ __cpm_suspend_otg_phy();
+
+ return;
+}
+
+static inline void jz_musb_phy_reset(void)
+{
+ REG_CPM_USBPCR |= USBPCR_POR;
+ udelay(30);
+ REG_CPM_USBPCR &= ~USBPCR_POR;
+
+ udelay(300);
+
+ return;
+}
+
+static inline void jz_musb_set_device_only_mode(void)
+{
+ printk(KERN_INFO "jz4760: Device only mode.\n");
+
+ /* Device Mode. */
+ REG_CPM_USBPCR &= ~(1 << 31);
+
+ REG_CPM_USBPCR |= USBPCR_VBUSVLDEXT;
+
+ return;
+}
+
+static inline void jz_musb_set_normal_mode(void)
+{
+ printk(KERN_INFO "jz4760: Normal mode.\n");
+
+ __gpio_as_otg_drvvbus();
+
+ /* OTG Mode. */
+ REG_CPM_USBPCR |= (1 << 31);
+
+ REG_CPM_USBPCR &= ~((1 << 24) | (1 << 23) | (1 << 20));
+
+ REG_CPM_USBPCR |= ((1 << 28) | (1 << 29));
+ return;
+}
+
+static inline void jz_musb_init(struct musb *musb)
+{
+ /* fil */
+ REG_CPM_USBVBFIL = 0x80;
+
+ /* rdt */
+ REG_CPM_USBRDT = 0x96;
+
+ /* rdt - filload_en */
+ REG_CPM_USBRDT |= (1 << 25);
+
+ /* TXRISETUNE & TXVREFTUNE. */
+ REG_CPM_USBPCR &= ~0x3f;
+ REG_CPM_USBPCR |= 0x35;
+
+ if (is_host_enabled(musb)) {
+ jz_musb_set_normal_mode();
+ }else
+ jz_musb_set_device_only_mode();
+
+ jz_musb_phy_reset();
+
+ return;
+}
+
+int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+{
+ return 0;
+}
+
+void musb_platform_enable(struct musb *musb)
+{
+ jz_musb_phy_enable();
+
+ return;
+}
+
+void musb_platform_disable(struct musb *musb)
+{
+ jz_musb_phy_disable();
+
+ return;
+}
+
+static void jz_musb_set_vbus(struct musb *musb, int is_on)
+{
+ u8 devctl;
+ /* HDRC controls CPEN, but beware current surges during device
+ * connect. They can trigger transient overcurrent conditions
+ * that must be ignored.
+ */
+
+ devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+
+ if (is_on) {
+ musb->is_active = 1;
+ musb->xceiv->default_a = 1;
+ musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+ devctl |= MUSB_DEVCTL_SESSION;
+
+ MUSB_HST_MODE(musb);
+ } else {
+ musb->is_active = 0;
+
+ /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
+ * jumping right to B_IDLE...
+ */
+
+ musb->xceiv->default_a = 0;
+ musb->xceiv->state = OTG_STATE_B_IDLE;
+ devctl &= ~MUSB_DEVCTL_SESSION;
+
+ MUSB_DEV_MODE(musb);
+ }
+ musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+
+ DBG(1, "VBUS %s, devctl %02x "
+ /* otg %3x conf %08x prcm %08x */ "\n",
+ otg_state_string(musb),
+ musb_readb(musb->mregs, MUSB_DEVCTL));
+}
+
+/* ---------------------- OTG ID PIN Routines ---------------------------- */
+
+#define __GPIO(p, n) (32 * (p - 'A') + n)
+
+#ifdef CONFIG_JZ4760_CYGNUS
+#define GPIO_OTG_ID_PIN __GPIO('F', 3)
+#elif CONFIG_JZ4760_LEPUS
+#define GPIO_OTG_ID_PIN __GPIO('E', 2)
+#endif
+
+#define GPIO_OTG_ID_IRQ (IRQ_GPIO_0 + GPIO_OTG_ID_PIN)
+#define GPIO_OTG_STABLE_JIFFIES 10
+
+static struct timer_list otg_id_pin_stable_timer;
+
+static unsigned int read_gpio_pin(unsigned int pin, unsigned int loop)
+{
+ unsigned int t, v;
+ unsigned int i;
+
+ i = loop;
+
+ v = t = 0;
+
+ while (i--) {
+ t = __gpio_get_pin(pin);
+ if (v != t)
+ i = loop;
+
+ v = t;
+ }
+
+ return v;
+}
+
+static void do_otg_id_pin_state(struct musb *musb)
+{
+ unsigned int default_a;
+ unsigned int pin = read_gpio_pin(GPIO_OTG_ID_PIN, 5000);
+
+ default_a = !pin;
+
+ musb->xceiv->default_a = default_a;
+
+ jz_musb_set_vbus(musb, default_a);
+
+ if (pin) {
+ /* B */
+ __gpio_as_irq_fall_edge(GPIO_OTG_ID_PIN);
+ } else {
+
+ /* A */
+ if (is_otg_enabled(musb))
+ __gpio_as_irq_rise_edge(GPIO_OTG_ID_PIN);
+ }
+
+ return;
+}
+
+static void otg_id_pin_stable_func(unsigned long data)
+{
+ struct musb *musb = (struct musb *)data;
+
+ do_otg_id_pin_state(musb);
+
+ return;
+}
+
+static irqreturn_t jz_musb_otg_id_irq(int irq, void *data)
+{
+ mod_timer(&otg_id_pin_stable_timer, GPIO_OTG_STABLE_JIFFIES + jiffies);
+
+ return IRQ_HANDLED;
+}
+
+static int otg_id_pin_setup(struct musb *musb)
+{
+ int rv;
+
+ /* Update OTG ID PIN state. */
+ do_otg_id_pin_state(musb);
+
+ setup_timer(&otg_id_pin_stable_timer, otg_id_pin_stable_func, (unsigned long)musb);
+
+ rv = request_irq(GPIO_OTG_ID_IRQ, jz_musb_otg_id_irq,
+ IRQF_DISABLED, "otg-id-irq", musb);
+ if (rv) {
+ pr_err("Failed to request OTG_ID_IRQ.\n");
+ return rv;
+ }
+
+ return rv;
+}
+
+static void otg_id_pin_cleanup(struct musb *musb)
+{
+ free_irq(GPIO_OTG_ID_IRQ, "otg-id-irq");
+ del_timer(&otg_id_pin_stable_timer);
+
+ return;
+}
+
+/* ---------------------------------------------------------------- */
+
+int __init musb_platform_init(struct musb *musb)
+{
+ int rv = 0;
+
+ musb->xceiv = otg_get_transceiver();
+ if (!musb->xceiv) {
+ pr_err("HS USB OTG: no transceiver configured\n");
+ return -ENODEV;
+ }
+
+ musb->b_dma_share_usb_irq = 1;
+ musb->board_set_vbus = jz_musb_set_vbus;
+
+ jz_musb_init(musb);
+
+ /* host mode and otg(host) depend on the id pin */
+ if (is_host_enabled(musb))
+ rv = otg_id_pin_setup(musb);
+
+ return rv;
+}
+
+int musb_platform_exit(struct musb *musb)
+{
+ jz_musb_phy_disable();
+
+ if (is_host_enabled(musb))
+ otg_id_pin_cleanup(musb);
+
+ return 0;
+}
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c7c1ca0494c..51c64ff157a 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -977,10 +977,13 @@ static void musb_shutdown(struct platform_device *pdev)
spin_lock_irqsave(&musb->lock, flags);
musb_platform_disable(musb);
musb_generic_disable(musb);
+
+#ifdef HAVE_CLK
if (musb->clock) {
clk_put(musb->clock);
musb->clock = NULL;
}
+#endif
spin_unlock_irqrestore(&musb->lock, flags);
/* FIXME power down */
@@ -1476,26 +1479,37 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || defined (CONFIG_SOC_JZ4760)
static irqreturn_t generic_interrupt(int irq, void *__hci)
{
unsigned long flags;
- irqreturn_t retval = IRQ_NONE;
struct musb *musb = __hci;
+ irqreturn_t rv, rv_dma, rv_usb;
+
+ rv = rv_dma = rv_usb = IRQ_NONE;
+
spin_lock_irqsave(&musb->lock, flags);
+#if defined(CONFIG_USB_INVENTRA_DMA)
+ if (musb->b_dma_share_usb_irq)
+ rv_dma = musb_call_dma_controller_irq(irq, musb);
+#endif
+
musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
if (musb->int_usb || musb->int_tx || musb->int_rx)
- retval = musb_interrupt(musb);
+ rv_usb = musb_interrupt(musb);
spin_unlock_irqrestore(&musb->lock, flags);
- return retval;
+ rv = (rv_dma == IRQ_HANDLED || rv_usb == IRQ_HANDLED) ?
+ IRQ_HANDLED : IRQ_NONE;
+
+ return rv;
}
#else
@@ -1854,10 +1868,12 @@ static void musb_free(struct musb *musb)
musb_platform_exit(musb);
musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+#ifdef HAVE_CLK
if (musb->clock) {
clk_disable(musb->clock);
clk_put(musb->clock);
}
+#endif
#ifdef CONFIG_USB_MUSB_OTG
put_device(musb->xceiv->dev);
@@ -1927,6 +1943,7 @@ bad_config:
musb->set_clock = plat->set_clock;
musb->min_power = plat->min_power;
+#ifdef HAVE_CLK
/* Clock usage is chip-specific ... functional clock (DaVinci,
* OMAP2430), or PHY ref (some TUSB6010 boards). All this core
* code does is make sure a clock handle is available; platform
@@ -1940,6 +1957,7 @@ bad_config:
goto fail;
}
}
+#endif
/* The musb_platform_init() call:
* - adjusts musb->mregs and musb->isr if needed,
@@ -1981,11 +1999,12 @@ bad_config:
/* be sure interrupts are disabled before connecting ISR */
musb_platform_disable(musb);
musb_generic_disable(musb);
-
+
/* setup musb parts of the core (especially endpoints) */
status = musb_core_init(plat->config->multipoint
? MUSB_CONTROLLER_MHDRC
: MUSB_CONTROLLER_HDRC, musb);
+
if (status < 0)
goto fail2;
@@ -2057,6 +2076,7 @@ bad_config:
? 'B' : 'A'));
} else /* peripheral is enabled */ {
+
MUSB_DEV_MODE(musb);
musb->xceiv->default_a = 0;
musb->xceiv->state = OTG_STATE_B_IDLE;
@@ -2098,8 +2118,11 @@ fail:
dev_err(musb->controller,
"musb_init_controller failed with status %d\n", status);
+#ifdef HAVE_CLK
if (musb->clock)
clk_put(musb->clock);
+#endif
+
device_init_wakeup(dev, 0);
musb_free(musb);
@@ -2187,10 +2210,13 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
*/
}
+#ifdef HAVE_CLK
if (musb->set_clock)
musb->set_clock(musb->clock, 0);
else
clk_disable(musb->clock);
+#endif
+
spin_unlock_irqrestore(&musb->lock, flags);
return 0;
}
@@ -2201,11 +2227,12 @@ static int musb_resume_early(struct platform_device *pdev)
if (!musb->clock)
return 0;
-
+#ifdef HAVE_CLK
if (musb->set_clock)
musb->set_clock(musb->clock, 1);
else
clk_enable(musb->clock);
+#endif
/* for static cmos like DaVinci, register values were preserved
* unless for some reason the whole soc powered down or the USB
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 381d648a36b..2c9282199ac 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -438,6 +438,7 @@ struct musb {
struct usb_gadget g; /* the gadget */
struct usb_gadget_driver *gadget_driver; /* its driver */
#endif
+ unsigned int b_dma_share_usb_irq;
struct musb_hdrc_config *config;
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 0a2c4e3602c..2c1cba3b7eb 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -148,6 +148,10 @@ dma_channel_status(struct dma_channel *c)
* Controllers manage dma channels.
*/
struct dma_controller {
+ /* Added by River - For DMA IRQ Sharing. */
+ u8 int_hsdma;
+ /* End added. */
+
int (*start)(struct dma_controller *);
int (*stop)(struct dma_controller *);
struct dma_channel *(*channel_alloc)(struct dma_controller *,
@@ -163,10 +167,10 @@ struct dma_controller {
/* called after channel_program(), may indicate a fault */
extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
-
extern struct dma_controller *__init
dma_controller_create(struct musb *, void __iomem *);
extern void dma_controller_destroy(struct dma_controller *);
+extern irqreturn_t musb_call_dma_controller_irq(int irq, struct musb *musb);
#endif /* __MUSB_DMA_H__ */
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 8b3c4e2ed7b..cfed9af3f5a 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -45,6 +45,9 @@
#include "musb_core.h"
+#ifdef CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG
+#include "vbus_hotplug.c"
+#endif
/* MUSB PERIPHERAL status 3-mar-2006:
*
@@ -1662,6 +1665,13 @@ int __init musb_gadget_setup(struct musb *musb)
status = device_register(&musb->g.dev);
if (status != 0)
the_gadget = NULL;
+
+#ifdef CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG
+ status = musb_gadget_hotplug_setup(musb);
+ if (status != 0)
+ the_gadget = NULL;
+#endif
+
return status;
}
@@ -1674,6 +1684,68 @@ void musb_gadget_cleanup(struct musb *musb)
the_gadget = NULL;
}
+#ifdef CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG
+static void stop_activity(struct musb *musb,
+ struct usb_gadget_driver *driver);
+
+static int jz_musb_vbus_hotplug_event(struct notifier_block *n,
+ unsigned long val, void *data)
+{
+ struct musb *musb = the_gadget;
+
+ unsigned long flags;
+
+ int state = *((int *)data);
+
+ D("Called.\n");
+
+ if (!musb || !musb->gadget_driver)
+ return 0;
+
+ switch (val) {
+ case UH_NOTIFY_CABLE_STATE:
+ switch (state) {
+ case UH_CABLE_STATE_OFFLINE:
+ case UH_CABLE_STATE_POWER:
+ D("OFFLINE.\n");
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+ musb_gadget_vbus_draw(&musb->g, 0);
+ musb->xceiv->state = OTG_STATE_UNDEFINED;
+ stop_activity(musb, musb->gadget_driver);
+ musb->is_active = 0;
+
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+ break;
+
+ case UH_CABLE_STATE_USB:
+ D("ONLINE.\n");
+
+ spin_lock_irqsave(&musb->lock, flags);
+
+ musb->xceiv->gadget = &musb->g;
+ musb->xceiv->state = OTG_STATE_B_IDLE;
+ musb->is_active = 1;
+
+ if (!is_otg_enabled(musb))
+ musb_start(musb);
+
+ spin_unlock_irqrestore(&musb->lock, flags);
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static struct notifier_block jz_musb_vbus_hotplug_nb = {
+ .notifier_call = jz_musb_vbus_hotplug_event,
+};
+#endif
+
/*
* Register the gadget driver. Used by gadget drivers when
* registering themselves with the controller.
@@ -1733,6 +1805,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
spin_lock_irqsave(&musb->lock, flags);
+#ifdef CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG
+ uh_register_notifier(&jz_musb_vbus_hotplug_nb);
+#else
+
otg_set_peripheral(musb->xceiv, &musb->g);
musb->is_active = 1;
@@ -1746,6 +1822,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
musb_start(musb);
otg_set_peripheral(musb->xceiv, &musb->g);
+#endif
spin_unlock_irqrestore(&musb->lock, flags);
@@ -1829,6 +1906,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (!driver || !driver->unbind || !musb)
return -EINVAL;
+#ifdef CONFIG_USB_MUSB_PERIPHERAL_HOTPLUG
+ uh_unregister_notifier(&jz_musb_vbus_hotplug_nb);
+#endif
/* REVISIT always use otg_set_peripheral() here too;
* this needs to shut down the OTG engine.
*/
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index b06e9ef00cf..108d7e07c3e 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -39,7 +39,7 @@
#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
&& !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
- && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN)
+ && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) && !defined(CONFIG_SOC_JZ4760)
static inline void readsl(const void __iomem *addr, void *buf, int len)
{ insl((unsigned long)addr, buf, len); }
static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 5e83f96d6b7..5c597189942 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -234,7 +234,7 @@ static int dma_channel_abort(struct dma_channel *channel)
return 0;
}
-static irqreturn_t dma_controller_irq(int irq, void *private_data)
+irqreturn_t dma_controller_irq(int irq, void *private_data)
{
struct musb_dma_controller *controller = private_data;
struct musb *musb = controller->private_data;
@@ -245,7 +245,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
irqreturn_t retval = IRQ_NONE;
- unsigned long flags;
+ unsigned long flags = 0;
u8 bchannel;
u8 int_hsdma;
@@ -253,9 +253,14 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
u32 addr;
u16 csr;
- spin_lock_irqsave(&musb->lock, flags);
+ if (!musb->b_dma_share_usb_irq) {
+ spin_lock_irqsave(&musb->lock, flags);
+
+ int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
+ }else{
+ int_hsdma = controller->controller.int_hsdma;
+ }
- int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
if (!int_hsdma)
goto done;
@@ -331,7 +336,9 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
retval = IRQ_HANDLED;
done:
- spin_unlock_irqrestore(&musb->lock, flags);
+ if (!musb->b_dma_share_usb_irq)
+ spin_unlock_irqrestore(&musb->lock, flags);
+
return retval;
}
@@ -357,10 +364,27 @@ dma_controller_create(struct musb *musb, void __iomem *base)
struct platform_device *pdev = to_platform_device(dev);
int irq = platform_get_irq(pdev, 1);
- if (irq == 0) {
- dev_err(dev, "No DMA interrupt line!\n");
- return NULL;
+ u8 nr_dma_channel;
+
+ /* Modified by River - Get DMA Channels from RAMINFO. */
+ nr_dma_channel = musb_readb(musb->mregs, MUSB_RAMINFO);
+ nr_dma_channel >>= 4;
+
+ /* Modified by River - DMA Share IRQ with USB. */
+ if (musb->b_dma_share_usb_irq) {
+ irq = 0;
+
+ dev_info(dev, "DMA IRQ: Shared. DMA Channels: %d.\n", nr_dma_channel);
+ }else{
+ irq = platform_get_irq(pdev, 1);
+ if (irq == 0) {
+ dev_err(dev, "No DMA interrupt line!\n");
+ return NULL;
+ }
+
+ dev_info(dev, "DMA IRQ: %d. DMA Channels: %d.\n", irq, nr_dma_channel);
}
+ /* End modified */
controller = kzalloc(sizeof(*controller), GFP_KERNEL);
if (!controller)
@@ -377,15 +401,40 @@ dma_controller_create(struct musb *musb, void __iomem *base)
controller->controller.channel_program = dma_channel_program;
controller->controller.channel_abort = dma_channel_abort;
- if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
- dev_name(musb->controller), &controller->controller)) {
- dev_err(dev, "request_irq %d failed!\n", irq);
- dma_controller_destroy(&controller->controller);
+ /* Modified by River - DMA Share IRQ with USB. */
+ if (irq) {
+ if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
+ dev_name(musb->controller), &controller->controller)) {
+ dev_err(dev, "request_irq %d failed!\n", irq);
+ dma_controller_destroy(&controller->controller);
- return NULL;
+ return NULL;
+ }
}
controller->irq = irq;
return &controller->controller;
}
+
+/* Added by river - For DMA IRQ Sharing */
+static u8 dma_controller_fetch_intr(struct dma_controller *c)
+{
+ struct musb_dma_controller *mc = container_of(c, struct musb_dma_controller, controller);
+
+ c->int_hsdma = musb_readb(mc->base, MUSB_HSDMA_INTR);
+
+ return c->int_hsdma;
+}
+
+irqreturn_t musb_call_dma_controller_irq(int irq, struct musb *musb)
+{
+ if (!musb->b_dma_share_usb_irq)
+ return IRQ_NONE;
+
+ if (dma_controller_fetch_intr(musb->dma_controller))
+ return dma_controller_irq(irq, (void *)musb->dma_controller);
+
+ return IRQ_NONE;
+}
+/* End added */
diff --git a/drivers/usb/musb/vbus_hotplug.c b/drivers/usb/musb/vbus_hotplug.c
new file mode 100644
index 00000000000..eb7fe0ad9f5
--- /dev/null
+++ b/drivers/usb/musb/vbus_hotplug.c
@@ -0,0 +1,782 @@
+/*
+ * Ingenic USB Device Controller Hotplug Driver.
+ *
+ * Author: River Wang <zwang@ingenic.cn>
+ */
+
+/*
+How to use
+
+1. Basic usage:
+All controlling interfaces are locacated in /sys/devices/platform/jz4740_udc/.
+[uh_cable]: It indicates the status of the cable: offline/power/usb.
+
+2. Asychronous notification:
+You can use a non-blocking PF_NETLINK socket to receive the uevent sent by udc_houplug. DRIVER & UDC_HOTPLUG_CABLE_STATE varible in uevent can be used to get the status of UDC cable.
+
+3. Notification mode & Gadget loading:
+There are two notification modes can be configured by [uh_notify_mode]: auto/manual.
+Auto: When a USB cable with active signals is plugged in, the udc_hotplug driver will broadcast this event to jz4740_udc & userspace app, and jz4740_udc will try to activate the current gadget.
+
+This mode is used when userspace APP only wants to get the cable status notification.
+
+Manual: The event will only be broadcast to userspace APP. When APP decides to how to handle this event, It can make it with [uh_notify]:
+auto: The udc_hotplug driver broadcast the latest cable status to jz4740_udc.
+offline/power/usb:....
+
+This mode is recommended when multiple gadgets are used. Userspace APP is notified by the uevent, load the specific gadget module by insmod, then set [uh_notify] to broadcat the event at last.
+*/
+
+#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 <linux/kobject.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+
+#include <asm/jzsoc.h>
+
+#define D(msg, fmt...)
+//#define D(msg, fmt...) \
+ printk(KERN_ERR JZ_VH_PFX": %s(): "msg, __func__, ##fmt)
+
+#define JZ_VH_PFX "jz_vbus_hotplug"
+
+#define NR_UDC_WAIT_INTR_LOOP (5 * 1000 * 1000)
+
+#define DEFAULT_KEEP_ALIVE_TIMER_INTERVAL (2 * HZ)
+#define DEFAULT_KEEP_ALIVE_COUNTER_LIMIT 2
+
+#define __GPIO(p, n) (32 * (p - 'A') + n)
+
+#define OTG_HOTPLUG_PIN __GPIO('E', 19)
+#define OTG_HOTPLUG_IRQ (IRQ_GPIO_0 + OTG_HOTPLUG_PIN)
+
+typedef enum {
+ UH_NOTIFY_CABLE_STATE = 0,
+}uh_notify_type_t;
+
+typedef enum {
+ UH_CABLE_STATE_OFFLINE = 0,
+ UH_CABLE_STATE_POWER,
+ UH_CABLE_STATE_USB,
+}uh_cable_state_t;
+
+typedef enum {
+ UH_THREAD_STATE_IDLE = 0,
+ UH_THREAD_STATE_START,
+ UH_THREAD_STATE_BUSY,
+ UH_THREAD_STATE_DONE,
+}uh_thread_state_t;
+
+/* UDC Flag bits */
+enum {
+ BIT_UH_ENABLE,
+
+ /* State changed ?*/
+ BIT_CABLE_STATE_CHANGE,
+
+ BIT_DO_DETECT,
+ BIT_DO_NOTIFY,
+
+ /* Keep alive */
+ BIT_KEEP_ALIVE,
+ BIT_KEEP_ALIVE_STOP,
+};
+
+#define DO_DETECT (1 << BIT_DO_DETECT)
+#define DO_NOTIFY (1 << BIT_DO_NOTIFY)
+#define DO_ALL ( DO_DETECT | DO_NOTIFY)
+
+struct uh_data {
+ unsigned long flags;
+
+ /* Notifier */
+ struct blocking_notifier_head notifier_head;
+
+ /* Thread */
+ struct task_struct *kthread;
+
+ int b_notify_mode;
+
+ /* Wait queue */
+ wait_queue_head_t kthread_wq; /* Kernel thread sleep here. */
+ wait_queue_head_t timer_wq; /* Wake up when timer is finished. */
+ wait_queue_head_t finish_wq; /* Wake up when thread is finished. */
+
+ uh_thread_state_t thread_state;
+ uh_cable_state_t cable_state;
+ uh_cable_state_t cable_detect_state;
+
+ struct timer_list stable_timer;
+ struct timer_list keep_alive_timer; /* Keep alive */
+
+ unsigned long keep_alive_counter_limit;
+ unsigned long keep_alive_timer_interval;
+ unsigned long keep_alive_counter;
+
+ int gpio_irq;
+ int gpio_pin;
+
+ struct platform_device *pdev;
+};
+
+static struct uh_data *g_puh_data = NULL;
+
+static inline void uh_start_work(struct uh_data *uh, int work)
+{
+ if (work & DO_DETECT) {
+ set_bit(BIT_DO_DETECT, &uh->flags);
+ }
+
+ if (work & DO_NOTIFY) {
+ set_bit(BIT_DO_NOTIFY, &uh->flags);
+ }
+
+ mod_timer(&uh->stable_timer, 1 + jiffies);
+
+ return;
+}
+
+static inline void set_cable_state(struct uh_data *uh, uh_cable_state_t state)
+{
+ if (uh->cable_state != state) {
+ D("Cable state: %d -> %d.\n", uh->cable_state, state);
+
+ uh->cable_state = state;
+ set_bit(BIT_CABLE_STATE_CHANGE, &uh->flags);
+ }
+
+ return;
+}
+
+static void uh_stable_timer_func(unsigned long data)
+{
+ struct uh_data *uh = (struct uh_data *)data;
+
+ D("Called.\n");
+
+ if (!test_bit(BIT_UH_ENABLE, &uh->flags))
+ return;
+
+ uh->thread_state = UH_THREAD_STATE_START;
+
+ /* Start. */
+ wake_up_process(uh->kthread);
+
+ return;
+}
+
+/* Do cable detection */
+static void cable_detect(struct uh_data *uh)
+{
+ if (__gpio_get_pin(uh->gpio_pin)) {
+ D("Cable online.\n");
+
+ uh->cable_detect_state = UH_CABLE_STATE_POWER;
+
+ }else {
+ D("Cable offline.\n");
+
+ clear_bit(BIT_KEEP_ALIVE, &uh->flags);
+
+ uh->cable_detect_state = UH_CABLE_STATE_OFFLINE;
+ }
+
+ return;
+}
+
+/* USB is active ? */
+static int usb_is_active(void)
+{
+ unsigned long timeout = NR_UDC_WAIT_INTR_LOOP;
+ unsigned long frame_no = REG16(USB_REG_FRAME);
+
+ /*
+ Some power charger may cause fake SOF,
+ We must handle this situation.
+ - River.
+ */
+
+ int counter = 7;
+
+ while (timeout && counter) {
+ if (frame_no != REG16(USB_REG_FRAME)) {
+ if (!--counter)
+ break;
+
+ /* Wait next frame. */
+ frame_no = REG16(USB_REG_FRAME);
+ }
+
+ timeout --;
+ }
+
+ D("timout: %lu, counter: %d.\n", timeout, counter);
+
+ return timeout ? 1 : 0;
+}
+
+/* Really do USB detection */
+static int do_usb_detect(struct uh_data *uh)
+{
+ int rv;
+
+ D("Called.\n");
+
+ __intc_mask_irq(IRQ_OTG);
+
+ /* Now enable PHY to start detect */
+ __cpm_enable_otg_phy();
+
+ /* 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;
+
+ rv = usb_is_active();
+
+ /* Detect finish ,clean every thing */
+ /* Disconnect from usb */
+ REG8(USB_REG_POWER) &= ~USB_POWER_SOFTCONN;
+
+ /* Disable the USB PHY */
+ __cpm_suspend_otg_phy();
+
+ /* Clear IRQs */
+ REG16(USB_REG_INTRINE) = 0;
+ REG16(USB_REG_INTROUTE) = 0;
+ REG8(USB_REG_INTRUSBE) = 0;
+
+ __intc_ack_irq(IRQ_OTG);
+ __intc_unmask_irq(IRQ_OTG);
+
+ 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 (uh->cable_detect_state != UH_CABLE_STATE_OFFLINE) {
+ D("Do real detection.\n");
+ rv = do_usb_detect(uh);
+ }else{
+ D("No need to do real detection.\n");
+ }
+
+ if (rv) {
+ /* Online. */
+ uh->cable_detect_state = UH_CABLE_STATE_USB;
+ }else{
+ /* No USB Signal. */
+ if (uh->cable_detect_state == UH_CABLE_STATE_POWER) {
+ /* TODO: Wait USB alive again. */
+ }
+ }
+
+ return;
+}
+
+static void do_wait(struct uh_data *uh)
+{
+ D("Called.\n");
+
+ wait_event(uh->kthread_wq, uh->thread_state == UH_THREAD_STATE_START);
+
+ uh->thread_state = UH_THREAD_STATE_BUSY;
+
+ return;
+}
+
+/* Called from kernel thread */
+static void do_detect(struct uh_data *uh)
+{
+ D("Called.\n");
+
+ if (!test_and_clear_bit(BIT_DO_DETECT, &uh->flags))
+ return;
+
+ D("Do detect.\n");
+
+ if(__gpio_get_pin(uh->gpio_pin)) {
+ cable_detect(uh);
+ usb_detect(uh);
+
+ set_cable_state(uh, uh->cable_detect_state);
+ }else{
+ set_cable_state(uh, UH_CABLE_STATE_OFFLINE);
+ }
+
+ return;
+}
+
+static void __do_notify(struct uh_data *uh)
+{
+ D("Called.\n");
+
+ if (test_and_clear_bit(BIT_CABLE_STATE_CHANGE, &uh->flags)) {
+ D("Kick notifier chain.\n");
+
+ blocking_notifier_call_chain(&uh->notifier_head,
+ UH_NOTIFY_CABLE_STATE, &uh->cable_state);
+
+
+ D("Send uevent to userspace.\n");
+
+ switch (uh->cable_state) {
+ case UH_CABLE_STATE_USB:
+ kobject_uevent(&uh->pdev->dev.kobj, KOBJ_ADD);
+ break;
+
+ case UH_CABLE_STATE_POWER:
+ kobject_uevent(&uh->pdev->dev.kobj, KOBJ_CHANGE);
+ break;
+
+ case UH_CABLE_STATE_OFFLINE:
+ kobject_uevent(&uh->pdev->dev.kobj, KOBJ_REMOVE);
+ break;
+ }
+ }
+
+ return;
+}
+
+static inline void do_notify(struct uh_data *uh)
+{
+ if (!uh->b_notify_mode) /* Auto nofity mode. */
+ set_bit(BIT_DO_NOTIFY, &uh->flags);
+
+ if (test_and_clear_bit(BIT_DO_NOTIFY, &uh->flags))
+ __do_notify(uh);
+
+ return;
+}
+
+static inline void do_done(struct uh_data *uh)
+{
+ D("Done.\n");
+
+ uh->thread_state = UH_THREAD_STATE_IDLE;
+
+ wake_up(&uh->finish_wq);
+
+ return;
+}
+
+/* Kernel thread */
+static int uh_thread(void *data)
+{
+ struct uh_data *uh = (struct uh_data *)data;
+
+ while (!kthread_should_stop()) {
+ do_wait(uh);
+
+ if (kthread_should_stop())
+ break;
+
+ do_detect(uh);
+
+ do_notify(uh);
+
+ do_done(uh);
+ }
+
+ D("Exit.\n");
+
+ return 0;
+}
+
+static irqreturn_t uh_irq(int irq, void *dev_id)
+{
+ struct uh_data *uh = (struct uh_data *)dev_id;
+
+ D("Called.\n");
+
+ uh_start_work(uh, DO_DETECT);
+
+ return IRQ_HANDLED;
+}
+
+static void uh_init_gpio(struct uh_data *uh)
+{
+ /* get current pin level */
+ __gpio_disable_pull(uh->gpio_pin);
+ __gpio_as_input(uh->gpio_pin);
+
+ udelay(1);
+
+ /* 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(uh->gpio_pin);
+
+ return;
+}
+
+static void uh_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->flags)
+ && !(--uh->keep_alive_counter)) {
+
+ if (!usb_is_active()) {
+ D("Timeout.\n");
+
+ clear_bit(BIT_KEEP_ALIVE, &uh->flags);
+
+ if (uh->cable_state == UH_CABLE_STATE_USB)
+ set_cable_state(uh, UH_CABLE_STATE_POWER);
+
+ uh_start_work(uh, DO_NOTIFY);
+ }
+ }
+
+ /* Set next active time. */
+ if (test_bit(BIT_KEEP_ALIVE, &uh->flags)) {
+ mod_timer(&uh->keep_alive_timer, uh->keep_alive_timer_interval + jiffies);
+ }else{
+ D("Timer will stop.\n");
+
+ set_bit(BIT_KEEP_ALIVE_STOP, &uh->flags);
+ wake_up(&uh->timer_wq);
+ }
+
+ return;
+}
+
+static void uh_set_counter(unsigned long timer_interval_in_jiffies, unsigned long counter_limit)
+{
+ struct uh_data *uh = g_puh_data;
+
+ uh->keep_alive_timer_interval = timer_interval_in_jiffies;
+ uh->keep_alive_counter_limit = counter_limit;
+
+ uh->keep_alive_counter = uh->keep_alive_counter_limit;
+
+ return;
+}
+
+static void uh_disable(void)
+{
+ struct uh_data *uh = g_puh_data;
+
+ /* Disable the source of input. */
+ clear_bit(BIT_UH_ENABLE, &uh->flags);
+
+ if (test_and_clear_bit(BIT_KEEP_ALIVE, &uh->flags))
+ /* Wait timer stop. */
+ wait_event(uh->timer_wq, test_and_clear_bit(BIT_KEEP_ALIVE_STOP, &uh->flags));
+
+ /* Wait thread idle. */
+ wait_event(uh->finish_wq, uh->thread_state == UH_THREAD_STATE_IDLE);
+
+ return;
+}
+
+static void uh_enable(void)
+{
+ struct uh_data *uh = g_puh_data;
+
+ set_bit(BIT_UH_ENABLE, &uh->flags);
+
+ return;
+}
+
+static void uh_alive(void)
+{
+ struct uh_data *uh = g_puh_data;
+
+ if (!test_bit(BIT_UH_ENABLE, &uh->flags))
+ return;
+
+ /* Reset counter */
+ uh->keep_alive_counter = uh->keep_alive_counter_limit;
+
+ /* We are alive. */
+ if (!test_bit(BIT_KEEP_ALIVE, &uh->flags)) {
+ D("Active timer.\n");
+
+ /* Active timer. */
+ set_bit(BIT_KEEP_ALIVE, &uh->flags);
+ clear_bit(BIT_KEEP_ALIVE_STOP, &uh->flags);
+
+ mod_timer(&uh->keep_alive_timer, 3 + jiffies);
+ }
+
+ return;
+}
+
+int uh_register_notifier(struct notifier_block *n)
+{
+ struct uh_data *uh = g_puh_data;
+
+ D("Register notifier: 0x%p.\n", (void *)n);
+
+ BUG_ON(!n->notifier_call);
+
+ /* Notify in auto mode. */
+ if (!uh->b_notify_mode)
+ n->notifier_call(n, UH_NOTIFY_CABLE_STATE, &uh->cable_state);
+
+ return blocking_notifier_chain_register(&uh->notifier_head, n);
+}EXPORT_SYMBOL(uh_register_notifier);
+
+int uh_unregister_notifier(struct notifier_block *n)
+{
+ struct uh_data *uh = g_puh_data;
+
+ int rv;
+
+ D("Unregister notifier: 0x%p.\n", (void *)n);
+
+ /* Wait all stop. */
+ uh_disable();
+
+ rv = blocking_notifier_chain_unregister(&uh->notifier_head, n);
+
+ uh_enable();
+
+ uh_start_work(uh, DO_DETECT); /* Update status. */
+
+ return rv;
+}EXPORT_SYMBOL(uh_unregister_notifier);
+
+static ssize_t show_cable(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ struct uh_data *uh = g_puh_data;
+
+ char *s = NULL;
+
+ switch (uh->cable_state) {
+ case UH_CABLE_STATE_OFFLINE:
+ s = "offline";
+ break;
+
+ case UH_CABLE_STATE_POWER:
+ s = "power";
+ break;
+
+ case UH_CABLE_STATE_USB:
+ s = "usb";
+ break;
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", s);
+}
+
+static ssize_t show_notify_mode(struct device *device, struct device_attribute *attr,
+ char *buf)
+{
+ struct uh_data *uh = g_puh_data;
+
+ char *s = uh->b_notify_mode ? "manual" : "auto";
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", s);
+}
+
+static ssize_t store_notify_mode(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct uh_data *uh = g_puh_data;
+
+ if (!strncmp(buf, "auto", 4)) {
+ uh->b_notify_mode = 0;
+ }else if (!strncmp(buf, "manual", 6)) {
+ uh->b_notify_mode = 1;
+ }
+
+ return count;
+}
+
+
+static ssize_t store_notify(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct uh_data *uh = g_puh_data;
+
+ if (!strncmp(buf, "auto", 4)) {
+ uh_start_work(uh, DO_ALL);
+ }
+
+ return count;
+}
+
+static struct device_attribute uh_sysfs_attrs[] = {
+ __ATTR(uh_cable, S_IRUGO|S_IWUSR, show_cable, NULL),
+ __ATTR(uh_notify_mode, S_IRUGO|S_IWUSR, show_notify_mode, store_notify_mode),
+ __ATTR(uh_notify, S_IRUGO|S_IWUSR, NULL, store_notify),
+};
+
+static int uh_register_attr(struct platform_device *pdev)
+{
+ int i, error = 0;
+
+ for (i = 0; i < ARRAY_SIZE(uh_sysfs_attrs); i++) {
+ error = device_create_file(&pdev->dev, &uh_sysfs_attrs[i]);
+
+ if (error)
+ break;
+ }
+
+ if (error) {
+ while (--i >= 0)
+ device_remove_file(&pdev->dev, &uh_sysfs_attrs[i]);
+ }
+
+ return 0;
+}
+
+static void uh_unregister_attr(struct platform_device *pdev)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(uh_sysfs_attrs); i++)
+ device_remove_file(&pdev->dev, &uh_sysfs_attrs[i]);
+}
+
+static int uh_setup(struct platform_device *pdev, int gpio_irq, int gpio_pin)
+{
+ 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 JZ_VH_PFX": Failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+
+ uh = g_puh_data;
+
+ uh->pdev = pdev;
+ uh->gpio_irq = gpio_irq;
+ uh->gpio_pin = gpio_pin;
+
+ set_bit(1, &status);
+
+ init_waitqueue_head(&uh->kthread_wq);
+ init_waitqueue_head(&uh->timer_wq);
+ init_waitqueue_head(&uh->finish_wq);
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&uh->notifier_head);
+
+ setup_timer(&uh->keep_alive_timer, uh_keep_alive_timer_func, (unsigned long)uh);
+ setup_timer(&uh->stable_timer, uh_stable_timer_func, (unsigned long)uh);
+
+ uh->kthread = kthread_run(uh_thread, uh, "kuhd");
+ if (IS_ERR(uh->kthread)) {
+ printk(KERN_ERR JZ_VH_PFX": Failed to create UDC hotplug monitor thread.\n");
+ rv = PTR_ERR(uh->kthread);
+ goto err;
+ }
+
+ set_bit(2, &status);
+
+ uh_init_gpio(uh);
+
+ rv = uh_register_attr(pdev);
+ if (rv) {
+ printk(KERN_ERR JZ_VH_PFX": Failed to register UDC sysfs interface.\n");
+ goto err;
+ }
+
+ set_bit(3, &status);
+
+ rv = request_irq(uh->gpio_irq, uh_irq, 0, JZ_VH_PFX, uh);
+ if (rv) {
+ printk(KERN_ERR JZ_VH_PFX": Could not get udc hotplug irq %d\n", uh->gpio_irq);
+ goto err;
+ }
+
+ uh_enable();
+
+ uh_set_counter(DEFAULT_KEEP_ALIVE_TIMER_INTERVAL, DEFAULT_KEEP_ALIVE_COUNTER_LIMIT);
+
+ uh_start_work(uh, DO_DETECT);
+
+ printk(KERN_ERR JZ_VH_PFX": Registered.\n");
+
+ return 0;
+
+err:
+ if (test_bit(3, &status)) {
+ uh_unregister_attr(pdev);
+ }
+
+ if (test_bit(2, &status)) {
+ uh->thread_state = UH_THREAD_STATE_START;
+ kthread_stop(uh->kthread);
+ }
+
+ if (test_bit(1, &status)) {
+ kfree(g_puh_data);
+ }
+
+ return rv;
+}
+
+static int musb_gadget_hotplug_setup(struct musb *musb)
+{
+ struct platform_device *pdev = (struct platform_device *)
+ container_of(musb->controller, struct platform_device, dev);
+ int rv;
+
+ rv = uh_setup(pdev, OTG_HOTPLUG_IRQ, OTG_HOTPLUG_PIN);
+ if (rv)
+ printk("uh_setup failed.\n");
+
+ return rv;
+}
+
+static void uh_cleanup(struct platform_device *pdev)
+{
+ struct uh_data *uh = g_puh_data;
+
+ uh_disable();
+
+ free_irq(uh->gpio_irq, uh);
+
+ /* Let our thread to exit. */
+ uh->thread_state = UH_THREAD_STATE_START;
+ kthread_stop(uh->kthread);
+
+ uh_unregister_attr(pdev);
+ kfree(uh);
+
+ return;
+}
+
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f146de3f34c..4d600b21503 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -237,14 +237,55 @@ config FB_TILEBLITTING
comment "Frame buffer hardware drivers"
depends on FB
+
+config FB_JZ475X
+ tristate "JZ475X LCD Controller Driver Support (Staging. Only used for test.)"
+ depends on FB && (SOC_JZ4750 || SOC_JZ4750D)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ default n
+
+config FB_JZ475X_TVE_PAL_OUTPUT
+ tristate "JZ475X TVE PAL Output Support"
+ depends on FB_JZ475X
+ ---help---
+ default n
+
+config FB_JZ475X_TVE_NTSC_OUTPUT
+ tristate "JZ475X TVE NTSC Output Support"
+ depends on FB_JZ475X
+ ---help---
+ default n
+
+config FB_JZ475X_LCD_OUTPUT
+ tristate "JZ475X LCD Output Support"
+ depends on FB_JZ475X
+ default y
+ ---help---
+ default n
+
+choice
+ depends on FB_JZ475X_LCD_OUTPUT
+ prompt "LCD Output Support"
+ default FB_JZ475X_LCD_PANEL_AUO_A043FL01V2
+ ---help---
+ Please select the lcd panel in you board
+
+config FB_JZ475X_LCD_PANEL_AUO_A043FL01V2
+ bool "AUO A043FL01V2 TFT panel (480x272)(24bits)"
+
+endchoice
+
config FB_JZSOC
- tristate "JZSOC LCD controller support"
+ tristate "JZSOC LCD/EPD controller support"
depends on FB && JZSOC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
- JZSOC LCD Controller and Smart LCD Controller driver support.
+ JZSOC LCD Controller, Smart LCD Controller driver support and EPD Controller driver support.
config FB_JZ4740_SLCD
tristate "JZ4740 Smart LCD controller support"
@@ -458,6 +499,131 @@ config JZ4750D_VGA_DISPLAY
depends on SOC_JZ4750D
bool "Jz4750D VGA Display"
endchoice
+
+config FB_JZ4760_LCD
+ tristate "JZ4760 LCD Controller support"
+ depends on FB_JZSOC && (SOC_JZ4760)
+ ---help---
+ JZ4760 LCD Controller driver.
+ JZ4760 LCD Controller support OSD function(refer jz4760_lcdc_spec.pdf).JZ4760 LCD OSD implement 2 framebuffer layers: foreground0 and foreground1. JZ4760 LCD driver support only foreground0 default.
+
+config FB_JZ4760_LCD_USE_2LAYER_FRAMEBUFFER
+ bool "JZ4760 LCD driver 2 layers framebuffer support."
+ depends on FB_JZ4760_LCD
+ ---help---
+ JZ4760 LCD driver support only foreground0 by default.
+ If you need both foreground0 and foreground1, please select this.
+
+config FB_JZ4760_TVE
+ tristate "JZ4760 TV Encode support"
+ depends on FB_JZSOC && FB_JZ4760_LCD
+ default n
+
+config JZ4760_IPU_MM
+ tristate "JZ4760 IPU MM support"
+ depends on FB_JZSOC && FB_JZ4760_LCD
+ default y
+ ---help---
+ Enable IPU Memory Management system.
+ It will reserve 16MB / 16MB + 4MB as IPU Framebuffer on JZ4750 / JZ4755.
+ Enable this if you want to use IPU.
+
+config FB_JZ4760_SLCD
+ bool
+ depends on FB_JZ4760_LCD
+ default n
+choice
+ depends on FB_JZ4760_LCD
+ prompt "JZ4760 LCD Panels Support"
+ default JZ4760_LCD_SAMSUNG_LTP400WQF02
+ ---help---
+ Please select the lcd panel in you board
+
+config JZ4760_LCD_SAMSUNG_LTP400WQF01
+ bool "SAMSUNG LTP400WQF01 TFT panel (480x272)(16bits)"
+
+config JZ4760_LCD_SAMSUNG_LTP400WQF02
+ bool "SAMSUNG LTP400WQF02 TFT panel (480x272)(18bits)"
+
+config JZ4760_LCD_AUO_A043FL01V2
+ bool "AUO A043FL01V2 TFT panel (480x272)(24bits)"
+
+config JZ4760_LCD_FOXCONN_PT035TN01
+ bool "FOXCONN PT035TN01 TFT panel (320x240,3.5in)(18bit-parallel mode)"
+
+config JZ4760_LCD_INNOLUX_PT035TN01_SERIAL
+ bool "INNOLUX PT035TN01 TFT panel (320x240,3.5in)(8bit-serial mode)"
+
+config JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA
+ bool "TOPPOLY_TD025THEA7 TFT panel(320x240)(serial RGB delta mode)"
+
+config JZ4760_LCD_TOPPOLY_TD043MGEB1
+ bool "TOPPOLY_TD043MGEB1 TFT panel(800x480)(24bit mode)"
+
+config JZ4760_LCD_TRULY_TFTG320240DTSW_18BIT
+ bool "TRULY_TFTG320240DTSW TFT panel (320x240) (Parallel 18bit mode)"
+
+config JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W
+ bool "TRULY_TFT_GG1P0319LTSW_W (240x320) (Smart LCD 16bit)"
+
+config JZ4760_SLCD_KGM701A3_TFT_SPFD5420A
+ bool "KGM701A3_TFT_SPFD5420A (400x240) (Smart LCD 18bit)"
+ select FB_JZ4750_SLCD
+
+config JZ4760_VGA_DISPLAY
+ depends on SOC_JZ4760
+ bool "Jz4760 VGA Display"
+endchoice
+
+
+config FB_JZ4760_EPD
+ tristate "JZ4760 EPD Controller support"
+ depends on FB_JZSOC && (SOC_JZ4760)
+ ---help---
+ JZ4760 EPD Controller driver.
+ JZ4760 EPD Controller support OSD function(refer jz4760_epdc_spec.pdf).JZ4760 EPD OSD implement 2 framebuffer layers: foreground0 and foreground1. JZ4760 EPD driver support only foreground0 default.
+
+
+choice
+ depends on FB_JZ4760_EPD
+ prompt "JZ4760 LCD OSD Mode select"
+ default JZ4760_LCD_USE_2LAYER_FG
+
+config JZ4760_LCD_USE_FG0_ONLY
+ bool "Only use foreground 0"
+
+config JZ4760_LCD_USE_FG1_ONLY
+ bool "Only use foreground 1"
+
+config JZ4760_LCD_USE_2LAYER_FG
+ bool "Use two-layer foregrounds."
+endchoice
+
+#config CONFIG_JZ4760_LCD_USE_2LAYER_FG #FB_JZ4760_EPD_USE_2LAYER_FRAMEBUFFER
+# bool "JZ4760 EPD driver 2 layers framebuffer support."
+# depends on FB_JZ4760_EPD
+# ---help---
+# JZ4760 EPD driver support only foreground0 by default.
+# If you need both foreground0 and foreground1, please select this.
+
+choice
+ depends on FB_JZ4760_EPD
+ prompt "JZ4760 EPD Panels Support"
+ default JZ4760_EPSON_EPD_DISPLAY
+ ---help---
+ Please select the lcd panel in you board
+config JZ4760_AUO_EPD_DISPLAY
+ bool "Jz4760 AUO EPD Display"
+
+config JZ4760_EPSON_EPD_DISPLAY
+ bool "Jz4760 EPSON Eink EPD Display"
+
+config JZ4760_OED_EPD_DISPLAY
+ bool "Jz4760 OED EPD Display"
+
+endchoice
+
+
config FB_CIRRUS
tristate "Cirrus Logic support"
depends on FB && (ZORRO || PCI)
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 5a3c60d0477..e55a3d65272 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -28,10 +28,16 @@ obj-$(CONFIG_FB_DDC) += fb_ddc.o
obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
# Hardware specific drivers go first
+obj-$(CONFIG_FB_JZ475X) += jz475x/
+
obj-$(CONFIG_FB_JZLCD_4730_4740) += jzlcd.o
obj-$(CONFIG_FB_JZ4740_SLCD) += jz4740_slcd.o
obj-$(CONFIG_FB_JZ4750_LCD) += jz4750_lcd.o
obj-$(CONFIG_FB_JZ4750_TVE) += jz4750_tve.o
+obj-$(CONFIG_FB_JZ4760_LCD) += jz4760_lcd.o
+obj-$(CONFIG_FB_JZ4760_TVE) += jz4760_tve.o
+
+obj-$(CONFIG_FB_JZ4760_EPD) += jz4760_epd.o
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
obj-$(CONFIG_FB_ARC) += arcfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
diff --git a/drivers/video/jz4750_lcd.c b/drivers/video/jz4750_lcd.c
index 6bbc38ebf73..c5f06272b5d 100644
--- a/drivers/video/jz4750_lcd.c
+++ b/drivers/video/jz4750_lcd.c
@@ -56,57 +56,13 @@ MODULE_DESCRIPTION("Jz4750 LCD Controller driver");
MODULE_AUTHOR("Wolfgang Wang, <lgwang@ingenic.cn>");
MODULE_LICENSE("GPL");
+#define D(fmt, args...) \
+// printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
-//#define DEBUG
-#undef DEBUG
+#define E(fmt, args...) \
+ printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
-#ifdef DEBUG
-#define dprintk(x...) printk(x)
-#define print_dbg(f, arg...) printk("dbg::" __FILE__ ",LINE(%d): " f "\n", __LINE__, ## arg)
-#else
-#define dprintk(x...)
-#define print_dbg(f, arg...) do {} while (0)
-#endif
-
-#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
-#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
-#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
-
-struct lcd_cfb_info {
- struct fb_info fb;
- struct display_switch *dispsw;
- signed int currcon;
- int func_use_count;
-
- struct {
- u16 red, green, blue;
- } palette[NR_PALETTE];
-#ifdef CONFIG_PM
- struct pm_dev *pm;
-#endif
- int b_lcd_display;
- int b_lcd_pwm;
- int backlight_level;
-};
-
-static struct lcd_cfb_info *jz4750fb_info;
-static struct jz4750_lcd_dma_desc *dma_desc_base;
-static struct jz4750_lcd_dma_desc *dma0_desc_palette, *dma0_desc0, *dma0_desc1, *dma1_desc0, *dma1_desc1;
-#define DMA_DESC_NUM 6
-
-static unsigned char *lcd_palette;
-static unsigned char *lcd_frame0;
-static unsigned char *lcd_frame1;
-
-static struct jz4750_lcd_dma_desc *dma0_desc_cmd0, *dma0_desc_cmd;
-static unsigned char *lcd_cmdbuf ;
-
-static void jz4750fb_set_mode( struct jz4750lcd_info * lcd_info );
-static void jz4750fb_deep_set_mode( struct jz4750lcd_info * lcd_info );
-
-static int jz4750fb_set_backlight_level(int n);
-static int jz4750fb_lcd_display_on(void);
-static int jz4750fb_lcd_display_off(void);
+#define JZ_FB_DEBUG 0
struct jz4750lcd_info jz4750_lcd_panel = {
#if defined(CONFIG_JZ4750_LCD_SAMSUNG_LTP400WQF02)
@@ -366,10 +322,9 @@ struct jz4750lcd_info jz4750_info_tve = {
},
};
-
struct jz4750lcd_info *jz4750_lcd_info = &jz4750_lcd_panel; /* default output to lcd panel */
-#ifdef DEBUG
+#if JZ_FB_DEBUG
static void print_lcdc_registers(void) /* debug */
{
/* LCD Controller Resgisters */
@@ -462,6 +417,69 @@ static void print_lcdc_registers(void) /* debug */
#define print_lcdc_registers()
#endif
+struct lcd_cfb_info {
+ struct fb_info fb;
+ struct {
+ u16 red, green, blue;
+ } palette[NR_PALETTE];
+
+ int b_lcd_display;
+ int b_lcd_pwm;
+ int backlight_level;
+};
+
+static struct lcd_cfb_info *jz4750fb_info;
+static struct jz4750_lcd_dma_desc *dma_desc_base;
+static struct jz4750_lcd_dma_desc *dma0_desc_palette, *dma0_desc0, *dma0_desc1, *dma1_desc0, *dma1_desc1;
+
+#define DMA_DESC_NUM 6
+
+static unsigned char *lcd_palette;
+static unsigned char *lcd_frame0;
+static unsigned char *lcd_frame1;
+
+static struct jz4750_lcd_dma_desc *dma0_desc_cmd0, *dma0_desc_cmd;
+static unsigned char *lcd_cmdbuf;
+
+static void jz4750fb_set_mode( struct jz4750lcd_info * lcd_info );
+static void jz4750fb_deep_set_mode( struct jz4750lcd_info * lcd_info );
+
+static int jz4750fb_set_backlight_level(int n);
+
+static int screen_on(void);
+static int screen_off(void);
+
+static void ctrl_enable(void)
+{
+ REG_LCD_STATE = 0; /* clear lcdc status */
+ __lcd_slcd_special_on();
+ __lcd_clr_dis();
+ __lcd_set_ena(); /* enable lcdc */
+
+ return;
+}
+
+static void ctrl_disable(void)
+{
+ if ( jz4750_lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD ||
+ jz4750_lcd_info->panel.cfg & LCD_CFG_TVEN ) /* */
+ __lcd_clr_ena(); /* Smart lcd and TVE mode only support quick disable */
+ else {
+ int cnt;
+ /* when CPU main freq is 336MHz,wait for 16ms */
+ cnt = 336000 * 16;
+ __lcd_set_dis(); /* regular disable */
+ while(!__lcd_disable_done() && cnt) {
+ cnt--;
+ }
+ if (cnt == 0)
+ printk("LCD disable timeout! REG_LCD_STATE=0x%08xx\n",REG_LCD_STATE);
+ REG_LCD_STATE &= ~LCD_STATE_LDD;
+ }
+
+ return;
+}
+
static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
@@ -475,7 +493,7 @@ static int jz4750fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
unsigned short *ptr, ctmp;
-// print_dbg("regno:%d,RGBt:(%d,%d,%d,%d)\t", regno, red, green, blue, transp);
+// D("regno:%d,RGBt:(%d,%d,%d,%d)\t", regno, red, green, blue, transp);
if (regno >= NR_PALETTE)
return 1;
@@ -637,94 +655,92 @@ static int jz4750fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long
void __user *argp = (void __user *)arg;
-// struct jz4750lcd_info *lcd_info = jz4750_lcd_info;
-
-
switch (cmd) {
case FBIOSETBACKLIGHT:
jz4750fb_set_backlight_level(arg);
+
break;
case FBIODISPON:
- REG_LCD_STATE = 0; /* clear lcdc status */
- __lcd_slcd_special_on();
- __lcd_clr_dis();
- __lcd_set_ena(); /* enable lcdc */
-
- jz4750fb_lcd_display_on();
+ ctrl_enable();
+ screen_on();
+
break;
case FBIODISPOFF:
- jz4750fb_lcd_display_off();
+ screen_off();
+ ctrl_disable();
- if ( jz4750_lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD ||
- jz4750_lcd_info->panel.cfg & LCD_CFG_TVEN ) /* */
- __lcd_clr_ena(); /* Smart lcd and TVE mode only support quick disable */
- else {
- int cnt;
- /* when CPU main freq is 336MHz,wait for 16ms */
- cnt = 336000 * 16;
- __lcd_set_dis(); /* regular disable */
- while(!__lcd_disable_done() && cnt) {
- cnt--;
- }
- if (cnt == 0)
- printk("LCD disable timeout! REG_LCD_STATE=0x%08xx\n",REG_LCD_STATE);
- REG_LCD_STATE &= ~LCD_STATE_LDD;
- }
break;
+
case FBIOPRINT_REG:
print_lcdc_registers();
+
break;
+
case FBIO_GET_MODE:
- print_dbg("fbio get mode\n");
+ D("fbio get mode\n");
+
if (copy_to_user(argp, jz4750_lcd_info, sizeof(struct jz4750lcd_info)))
return -EFAULT;
+
break;
+
case FBIO_SET_MODE:
- print_dbg("fbio set mode\n");
+ D("fbio set mode\n");
+
if (copy_from_user(jz4750_lcd_info, argp, sizeof(struct jz4750lcd_info)))
return -EFAULT;
+
/* set mode */
jz4750fb_set_mode(jz4750_lcd_info);
+
break;
+
case FBIO_DEEP_SET_MODE:
- print_dbg("fbio deep set mode\n");
+ D("fbio deep set mode\n");
+
if (copy_from_user(jz4750_lcd_info, argp, sizeof(struct jz4750lcd_info)))
return -EFAULT;
+
jz4750fb_deep_set_mode(jz4750_lcd_info);
+
break;
+
#ifdef CONFIG_FB_JZ4750_TVE
case FBIO_MODE_SWITCH:
- print_dbg("lcd mode switch between tve and lcd, arg=%lu\n", arg);
- switch ( arg ) {
- case PANEL_MODE_TVE_PAL: /* switch to TVE_PAL mode */
- case PANEL_MODE_TVE_NTSC: /* switch to TVE_NTSC mode */
- jz4750lcd_info_switch_to_TVE(arg);
- jz4750tve_init(arg); /* tve controller init */
- udelay(100);
- jz4750tve_enable_tve();
- /* turn off lcd backlight */
- jz4750fb_lcd_display_off();
- break;
- case PANEL_MODE_LCD_PANEL: /* switch to LCD mode */
- default :
- /* turn off TVE, turn off DACn... */
- jz4750tve_disable_tve();
- jz4750_lcd_info = &jz4750_lcd_panel;
- /* turn on lcd backlight */
- jz4750fb_lcd_display_on();
- break;
+ D("FBIO_MODE_SWITCH");
+ switch (arg) {
+ case PANEL_MODE_TVE_PAL: /* switch to TVE_PAL mode */
+ case PANEL_MODE_TVE_NTSC: /* switch to TVE_NTSC mode */
+ jz4750lcd_info_switch_to_TVE(arg);
+ jz4750tve_init(arg); /* tve controller init */
+ udelay(100);
+ jz4750tve_enable_tve();
+ /* turn off lcd backlight */
+ screen_off();
+ break;
+ case PANEL_MODE_LCD_PANEL: /* switch to LCD mode */
+ default :
+ /* turn off TVE, turn off DACn... */
+ jz4750tve_disable_tve();
+ jz4750_lcd_info = &jz4750_lcd_panel;
+ /* turn on lcd backlight */
+ screen_on();
+ break;
}
+
jz4750fb_deep_set_mode(jz4750_lcd_info);
+
break;
+
case FBIO_GET_TVE_MODE:
- print_dbg("fbio get TVE mode\n");
+ D("fbio get TVE mode\n");
if (copy_to_user(argp, jz4750_tve_info, sizeof(struct jz4750tve_info)))
return -EFAULT;
break;
case FBIO_SET_TVE_MODE:
- print_dbg("fbio set TVE mode\n");
+ D("fbio set TVE mode\n");
if (copy_from_user(jz4750_tve_info, argp, sizeof(struct jz4750tve_info)))
return -EFAULT;
/* set tve mode */
@@ -746,7 +762,7 @@ static int jz4750fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
unsigned long start;
unsigned long off;
u32 len;
- dprintk("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ D("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
off = vma->vm_pgoff << PAGE_SHIFT;
//fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
@@ -802,13 +818,13 @@ static int jz4750fb_set_par(struct fb_info *info)
*/
static int jz4750fb_blank(int blank_mode, struct fb_info *info)
{
- dprintk("jz4750 fb_blank %d %p", blank_mode, info);
+ D("jz4750 fb_blank %d %p", blank_mode, info);
switch (blank_mode) {
case FB_BLANK_UNBLANK:
//case FB_BLANK_NORMAL:
/* Turn on panel */
__lcd_set_ena();
- jz4750fb_lcd_display_on();
+ screen_on();
break;
@@ -847,7 +863,7 @@ static int jz4750fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *i
}
dy = var->yoffset;
- print_dbg("var.yoffset: %d", dy);
+ D("var.yoffset: %d", dy);
if (dy) {
dma0_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame0 + (cfb->fb.fix.line_length * dy));
dma_cache_wback((unsigned int)(dma0_desc0), sizeof(struct jz4750_lcd_dma_desc));
@@ -1038,7 +1054,6 @@ static int jz4750fb_set_var(struct fb_var_screeninfo *var, int con,
* defaults used to create new consoles.
*/
fb_set_cmap(&cfb->fb.cmap, &cfb->fb);
- dprintk("jz4750fb_set_var: after fb_set_cmap...\n");
return 0;
}
@@ -1056,7 +1071,6 @@ static struct lcd_cfb_info * jz4750fb_alloc_fb_info(void)
memset(cfb, 0, sizeof(struct lcd_cfb_info) );
- cfb->currcon = -1;
cfb->backlight_level = LCD_DEFAULT_BACKLIGHT;
strcpy(cfb->fb.fix.id, "jz-lcd");
@@ -1094,11 +1108,29 @@ static struct lcd_cfb_info * jz4750fb_alloc_fb_info(void)
fb_alloc_cmap(&cfb->fb.cmap, 256, 0);
break;
}
- dprintk("fb_alloc_cmap,fb.cmap.len:%d....\n", cfb->fb.cmap.len);
+ D("fb_alloc_cmap,fb.cmap.len:%d....\n", cfb->fb.cmap.len);
return cfb;
}
+static int bpp_to_data_bpp(int bpp)
+{
+ switch (bpp) {
+ case 32:
+ case 16:
+ break;
+
+ case 15:
+ bpp = 16;
+ break;
+
+ default:
+ bpp = -EINVAL;
+ }
+
+ return bpp;
+}
+
/*
* Map screen memory
*/
@@ -1107,11 +1139,10 @@ static int jz4750fb_map_smem(struct lcd_cfb_info *cfb)
unsigned long page;
unsigned int page_shift, needroom, needroom1, bpp, w, h;
- bpp = jz4750_lcd_info->osd.fg0.bpp;
- if ( bpp == 18 || bpp == 24)
- bpp = 32;
- if ( bpp == 15 )
- bpp = 16;
+ bpp = bpp_to_data_bpp(jz4750_lcd_info->osd.fg0.bpp);
+
+ D("FG0 BPP: %d, Data BPP: %d.", jz4750_lcd_info->osd.fg0.bpp, bpp);
+
#ifndef CONFIG_FB_JZ4750_TVE
w = jz4750_lcd_info->osd.fg0.w;
h = jz4750_lcd_info->osd.fg0.h;
@@ -1120,12 +1151,11 @@ static int jz4750fb_map_smem(struct lcd_cfb_info *cfb)
h = ( jz4750_lcd_info->osd.fg0.h > TVE_HEIGHT_PAL )?jz4750_lcd_info->osd.fg0.h:TVE_HEIGHT_PAL;
#endif
needroom1 = needroom = ((w * bpp + 7) >> 3) * h;
+
#if defined(CONFIG_FB_JZ4750_LCD_USE_2LAYER_FRAMEBUFFER)
- bpp = jz4750_lcd_info->osd.fg1.bpp;
- if ( bpp == 18 || bpp == 24)
- bpp = 32;
- if ( bpp == 15 )
- bpp = 16;
+ bpp = bpp_to_data_bpp(jz4750_lcd_info->osd.fg1.bpp);
+
+ D("FG1 BPP: %d, Data BPP: %d.", jz4750_lcd_info->osd.fg1.bpp, bpp);
#ifndef CONFIG_FB_JZ4750_TVE
w = jz4750_lcd_info->osd.fg1.w;
@@ -1137,7 +1167,6 @@ static int jz4750fb_map_smem(struct lcd_cfb_info *cfb)
needroom += ((w * bpp + 7) >> 3) * h;
#endif // two layer
-
for (page_shift = 0; page_shift < 12; page_shift++)
if ((PAGE_SIZE << page_shift) >= needroom)
break;
@@ -1152,7 +1181,6 @@ static int jz4750fb_map_smem(struct lcd_cfb_info *cfb)
dma_desc_base = (struct jz4750_lcd_dma_desc *)((void*)lcd_palette + ((PALETTE_SIZE+3)/4)*4);
#if defined(CONFIG_FB_JZ4750_SLCD)
-
lcd_cmdbuf = (unsigned char *)__get_free_pages(GFP_KERNEL, 0);
memset((void *)lcd_cmdbuf, 0, PAGE_SIZE);
@@ -1542,7 +1570,7 @@ static void jz4750fb_set_panel_mode( struct jz4750lcd_info * lcd_info )
static void jz4750fb_set_osd_mode( struct jz4750lcd_info * lcd_info )
{
- dprintk("%s, %d\n", __FILE__, __LINE__ );
+ D("%s, %d\n", __FILE__, __LINE__ );
lcd_info->osd.osd_ctrl &= ~(LCD_OSDCTRL_OSDBPP_MASK);
if ( lcd_info->osd.fg1.bpp == 15 )
lcd_info->osd.osd_ctrl |= LCD_OSDCTRL_OSDBPP_15_16|LCD_OSDCTRL_RGB555;
@@ -1636,7 +1664,7 @@ static void jz4750fb_foreground_resize( struct jz4750lcd_info * lcd_info )
/* wait change ready??? */
// while ( REG_LCD_OSDS & LCD_OSDS_READY ) /* fix in the future, Wolfgang, 06-20-2008 */
- print_dbg("wait LCD_OSDS_READY\n");
+ D("wait LCD_OSDS_READY\n");
if ( lcd_info->osd.fg_change & FG0_CHANGE_SIZE ) { /* change FG0 size */
if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* output to TV */
@@ -1716,7 +1744,7 @@ static void jz4750fb_change_clock( struct jz4750lcd_info * lcd_info )
val--;
__cpm_set_pixdiv(val);
- dprintk("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
+ D("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
#if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */
val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
@@ -1734,7 +1762,7 @@ static void jz4750fb_change_clock( struct jz4750lcd_info * lcd_info )
else { /* LCDC output to LCD panel */
val = __cpm_get_pllout2() / pclk; /* pclk */
val--;
- dprintk("ratio: val = %d\n", val);
+ D("ratio: val = %d\n", val);
if ( val > 0x7ff ) {
printk("pixel clock divid is too large, set it to 0x7ff\n");
val = 0x7ff;
@@ -1742,7 +1770,7 @@ static void jz4750fb_change_clock( struct jz4750lcd_info * lcd_info )
__cpm_set_pixdiv(val);
- dprintk("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
+ D("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
#if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */
val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
val =__cpm_get_pllout2() / val;
@@ -1756,8 +1784,8 @@ static void jz4750fb_change_clock( struct jz4750lcd_info * lcd_info )
}
- dprintk("REG_CPM_LPCDR=0x%08x\n", REG_CPM_LPCDR);
- dprintk("REG_CPM_CPCCR=0x%08x\n", REG_CPM_CPCCR);
+ D("REG_CPM_LPCDR=0x%08x\n", REG_CPM_LPCDR);
+ D("REG_CPM_CPCCR=0x%08x\n", REG_CPM_CPCCR);
jz_clocks.pixclk = __cpm_get_pixclk();
printk("LCDC: PixClock:%d\n", jz_clocks.pixclk);
@@ -1821,7 +1849,7 @@ static irqreturn_t jz4750fb_interrupt_handler(int irq, void *dev_id)
static int irqcnt=0;
state = REG_LCD_STATE;
- dprintk("In the lcd interrupt handler, state=0x%x\n", state);
+ D("In the lcd interrupt handler, state=0x%x\n", state);
if (state & LCD_STATE_EOF) /* End of frame */
REG_LCD_STATE = state & ~LCD_STATE_EOF;
@@ -1857,8 +1885,9 @@ static int jz4750_fb_suspend(struct platform_device *pdev, pm_message_t state)
{
printk("%s(): called.\n", __func__);
- __lcd_clr_ena(); /* Quick Disable */
- jz4750fb_lcd_display_off();
+ screen_off();
+ ctrl_disable();
+
__cpm_stop_lcd();
return 0;
@@ -1874,6 +1903,7 @@ static int jz4750_fb_resume(struct platform_device *pdev)
printk("%s(): called.\n", __func__);
__cpm_start_lcd();
+
__gpio_set_pin(GPIO_DISP_OFF_N);
__lcd_special_on();
__lcd_set_ena();
@@ -1891,7 +1921,7 @@ static int jz4750_fb_resume(struct platform_device *pdev)
/* The following routine is only for test */
-#ifdef DEBUG
+#if JZ_FB_DEBUG
static void test_gpio(int gpio_num, int delay) {
__gpio_as_output(gpio_num);
while(1) {
@@ -2106,7 +2136,7 @@ static void display_h_color_bar(int w, int h, int bpp) {
*
* - River.
*/
-static int jz4750fb_lcd_display_off(void)
+static int screen_off(void)
{
struct lcd_cfb_info *cfb = jz4750fb_info;
@@ -2125,7 +2155,7 @@ static int jz4750fb_lcd_display_off(void)
return 0;
}
-static int jz4750fb_lcd_display_on(void)
+static int screen_on(void)
{
struct lcd_cfb_info *cfb = jz4750fb_info;
@@ -2244,10 +2274,9 @@ static int jz4750fb_device_attr_unregister(struct fb_info *fb_info)
}
/* End */
-static int __devinit jz4750_fb_probe(struct platform_device *dev)
+static void gpio_init(void)
{
- struct lcd_cfb_info *cfb;
- int err = 0;
+ __lcd_display_pin_init();
/* gpio init __gpio_as_lcd */
if (jz4750_lcd_info->panel.cfg & LCD_CFG_MODE_TFT_16BIT)
@@ -2256,6 +2285,7 @@ static int __devinit jz4750_fb_probe(struct platform_device *dev)
__gpio_as_lcd_24bit();
else
__gpio_as_lcd_18bit();
+
/* In special mode, we only need init special pin,
* as general lcd pin has init in uboot */
#if defined(CONFIG_SOC_JZ4750) || defined(CONFIG_SOC_JZ4750D)
@@ -2269,90 +2299,122 @@ static int __devinit jz4750_fb_probe(struct platform_device *dev)
;
}
#endif
- if ( jz4750_lcd_info->osd.fg0.bpp > 16 &&
- jz4750_lcd_info->osd.fg0.bpp < 32 ) {
- jz4750_lcd_info->osd.fg0.bpp = 32;
+
+ return;
+}
+
+static void set_bpp_to_ctrl_bpp(void)
+{
+ switch (jz4750_lcd_info->osd.fg0.bpp) {
+ case 15:
+ case 16:
+ break;
+
+ case 17 ... 32:
+ jz4750_lcd_info->osd.fg0.bpp = 32;
+ break;
+
+ default:
+ E("FG0: BPP (%d) not support, Set BPP 32.\n",
+ jz4750_lcd_info->osd.fg0.bpp);
+
+ jz4750_lcd_info->osd.fg0.bpp = 32;
+ break;
}
- switch ( jz4750_lcd_info->osd.fg1.bpp ) {
- case 15:
- case 16:
- break;
- case 17 ... 32:
- jz4750_lcd_info->osd.fg1.bpp = 32;
- break;
- default:
- printk("jz4750fb fg1 not support bpp(%d), force to 32bpp\n",
- jz4750_lcd_info->osd.fg1.bpp);
- jz4750_lcd_info->osd.fg1.bpp = 32;
+ switch (jz4750_lcd_info->osd.fg1.bpp) {
+ case 15:
+ case 16:
+ break;
+
+ case 17 ... 32:
+ jz4750_lcd_info->osd.fg1.bpp = 32;
+ break;
+
+ default:
+ E("FG1: BPP (%d) not support, Set BPP 32.\n",
+ jz4750_lcd_info->osd.fg1.bpp);
+
+ jz4750_lcd_info->osd.fg1.bpp = 32;
+ break;
}
- __lcd_clr_dis();
- __lcd_clr_ena();
+ return;
+}
+
+static void slcd_init(void)
+{
/* Configure SLCD module for setting smart lcd control registers */
#if defined(CONFIG_FB_JZ4750_SLCD)
- __lcd_as_smart_lcd();
- __slcd_disable_dma();
- __init_slcd_bus(); /* Note: modify this depend on you lcd */
+ __lcd_as_smart_lcd();
+ __slcd_disable_dma();
+ __init_slcd_bus(); /* Note: modify this depend on you lcd */
#endif
- /* init clk */
- jz4750fb_change_clock(jz4750_lcd_info);
- __lcd_display_pin_init();
- __lcd_slcd_special_on();
+ return;
+}
+
+static int __devinit jz4750_fb_probe(struct platform_device *dev)
+{
+ struct lcd_cfb_info *cfb;
+ int rv = 0;
+
cfb = jz4750fb_alloc_fb_info();
if (!cfb)
goto failed;
- err = jz4750fb_map_smem(cfb);
- if (err)
+ screen_off();
+ ctrl_disable();
+
+ gpio_init();
+ slcd_init();
+
+ set_bpp_to_ctrl_bpp();
+
+ /* init clk */
+ jz4750fb_change_clock(jz4750_lcd_info);
+
+ rv = jz4750fb_map_smem(cfb);
+ if (rv)
goto failed;
- jz4750fb_deep_set_mode( jz4750_lcd_info );
+ jz4750fb_deep_set_mode(jz4750_lcd_info);
- err = register_framebuffer(&cfb->fb);
- if (err < 0) {
- dprintk("jzfb_init(): register framebuffer err.\n");
+ rv = register_framebuffer(&cfb->fb);
+ if (rv < 0) {
+ D("Failed to register framebuffer device.");
goto failed;
}
+
printk("fb%d: %s frame buffer device, using %dK of video memory\n",
cfb->fb.node, cfb->fb.fix.id, cfb->fb.fix.smem_len>>10);
jz4750fb_device_attr_register(&cfb->fb);
if (request_irq(IRQ_LCD, jz4750fb_interrupt_handler, IRQF_DISABLED,
- "lcd", 0)) {
- err = -EBUSY;
+ "lcd", 0)) {
+ D("Faield to request LCD IRQ.\n");
+ rv = -EBUSY;
goto failed;
}
-#if 0
- /*
- * Note that the console registers this as well, but we want to
- * power down the display prior to sleeping.
- */
- cfb->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, jzlcd_pm_callback);
- if (cfb->pm)
- cfb->pm->data = cfb;
-#endif
-
- __lcd_set_ena(); /* enalbe LCD Controller */
- jz4750fb_lcd_display_on();
+ ctrl_enable();
+ screen_on();
-#ifdef DEBUG
+#if JZ_FB_DEBUG
display_h_color_bar(jz4750_lcd_info->osd.fg0.w, jz4750_lcd_info->osd.fg0.h, jz4750_lcd_info->osd.fg0.bpp);
-#endif
+
print_lcdc_registers();
+#endif
return 0;
failed:
- print_dbg();
jz4750fb_unmap_smem(cfb);
jz4750fb_free_fb_info(cfb);
- return err;
+ return rv;
}
static int __devexit jz4750_fb_remove(struct platform_device *pdev)
diff --git a/drivers/video/jz475x/Makefile b/drivers/video/jz475x/Makefile
new file mode 100644
index 00000000000..684d3e1798e
--- /dev/null
+++ b/drivers/video/jz475x/Makefile
@@ -0,0 +1 @@
+obj-y += jz-fb.o
diff --git a/drivers/video/jz475x/abi.h b/drivers/video/jz475x/abi.h
new file mode 100644
index 00000000000..d103b7c3bb1
--- /dev/null
+++ b/drivers/video/jz475x/abi.h
@@ -0,0 +1,114 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * ABI between Kernel Driver and Userspace Driver
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifndef __JZ_FB_ABI_H__
+#define __JZ_FB_ABI_H__
+
+#include "config.h"
+
+/* Window Attribute. */
+struct jz_fb_win_attr_info {
+ int enable;
+
+ unsigned int x;
+ unsigned int y;
+ unsigned int w;
+ unsigned int h;
+
+ unsigned int bpp;
+};
+
+/* Output Panel State. */
+enum {
+ JZ_FB_PANEL_STATE_POWER_OFF = 0,
+ JZ_FB_PANEL_STATE_POWER_ON,
+ JZ_FB_PANEL_STATE_SCREEN_OFF,
+ JZ_FB_PANEL_STATE_SCREEN_ON,
+};
+
+/* ----------- Common --------------- */
+enum {
+ JZ_FB_CMD_COMMON_GET_STATE = 0,
+ JZ_FB_CMD_COMMON_SET_POWER,
+ JZ_FB_CMD_COMMON_SET_SCREEN,
+
+ JZ_FB_CMD_COMMON_GET_WIN_ATTR,
+ JZ_FB_CMD_COMMON_SET_WIN_ATTR,
+
+ JZ_FB_CMD_COMMON_SELECT_OT,
+ JZ_FB_CMD_COMMON_END,
+};
+
+struct jz_fb_common_control {
+ int id;
+ int command;
+ int v;
+
+ /* TODO: We may support runtime changes in future. */
+ int active_now;
+
+ struct jz_fb_win_attr_info win_attr[JZ_FB_NR_MAX_FG];
+};
+
+/* Command: GET_STATE. Return value: */
+enum {
+ JZ_FB_CMD_COMMON_STATE_OT_POWER = (1 << 0),
+ JZ_FB_CMD_COMMON_STATE_OT_ENABLE = (1 << 1),
+ JZ_FB_CMD_COMMON_STATE_CTRL_ENABLE = (1 << 2),
+};
+
+/* --------- OUTPUT PATH: LCD --------------- */
+
+/* COMMAND. */
+enum {
+ JZ_FB_CMD_LCD_GET_BACKLIGHT = JZ_FB_CMD_COMMON_END,
+ JZ_FB_CMD_LCD_SET_BACKLIGHT,
+};
+
+struct jz_fb_lcd_control {
+ struct jz_fb_common_control common;
+};
+
+/* -------- OUTPUT PATH: TV NTSC/PAL -------- */
+/* COMMAND. */
+enum {
+ JZ_FB_CMD_TVE_GET_PATH = JZ_FB_CMD_COMMON_END,
+ JZ_FB_CMD_TVE_SET_PATH,
+};
+
+/* TVE Output Path. */
+enum {
+ JZ_FB_TVE_PATH_CVBS = 0,
+ JZ_FB_TVE_PATH_SVIDEO,
+
+#ifdef CONFIG_SOC_JZ4750D
+ JZ_FB_TVE_PATH_YUV,
+#endif
+
+};
+
+struct jz_fb_tve_control {
+ struct jz_fb_common_control common;
+};
+
+#endif /* Define __JZ_FB_ABI_H__ */
diff --git a/drivers/video/jz475x/common.c b/drivers/video/jz475x/common.c
new file mode 100644
index 00000000000..6464289df2c
--- /dev/null
+++ b/drivers/video/jz475x/common.c
@@ -0,0 +1,33 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Common Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static inline unsigned long dma_align_size(unsigned long size)
+{
+ unsigned long align = JZ_FB_DMA_ALIGN;
+
+ size = (size + align - 1) / align * align;
+
+ return size;
+}
+
+
diff --git a/drivers/video/jz475x/config.h b/drivers/video/jz475x/config.h
new file mode 100644
index 00000000000..1cf20f2f491
--- /dev/null
+++ b/drivers/video/jz475x/config.h
@@ -0,0 +1,104 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * SOC & Driver Config.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifndef __JZ_FB_CONFIG_H__
+#define __JZ_FB_CONFIG_H__
+
+#ifdef __KERNEL__
+#include <linux/autoconf.h>
+#else
+#include "userspace-config.h"
+#endif
+
+#ifdef __KERNEL__
+/* DEBUG. */
+#define JZ_FB_DEBUG 0
+#define JZ_FB_DEBUG_DUMP 0 /* Dump Structures. */
+#endif
+
+/* --------------- CONFIG FOR JZ4750 ---------------- */
+#ifdef CONFIG_SOC_JZ4750
+
+/* Limits. */
+#define JZ_FB_NR_MAX_DMA_DESC 6
+#define JZ_FB_NR_MAX_FB_MEM 3
+#define JZ_FB_NR_MAX_FG 2
+
+/* REVIST: ALIGN. */
+#define JZ_FB_DMA_ALIGN 4
+#define JZ_FB_WIN_POS_ALIGN 2
+#define JZ_FB_WIN_SIZE_ALIGN 2
+
+/* Config. */
+#define JZ_FB_8WORD_DMA_DESC 1
+
+#define HAVE_TVE 1
+
+#endif
+
+/* --------------- CONFIG FOR JZ4755 ---------------- */
+#ifdef CONFIG_SOC_JZ4750D
+
+/* Limits. */
+#define JZ_FB_NR_MAX_DMA_DESC 6
+#define JZ_FB_NR_MAX_FB_MEM 3
+#define JZ_FB_NR_MAX_FG 2
+
+/* REVIST: ALIGN. */
+#define JZ_FB_DMA_ALIGN 4
+#define JZ_FB_WIN_POS_ALIGN 2
+#define JZ_FB_WIN_SIZE_ALIGN 2
+
+/* Config. */
+#define JZ_FB_8WORD_DMA_DESC 1
+
+#define HAVE_TVE 1
+#endif
+
+#ifdef __KERNEL__
+
+/* ------------- JZ_FB_DEBUG ----------- */
+#if JZ_FB_DEBUG
+#define D(fmt, args...) \
+ printk(KERN_ERR "%s(): LINE: %d "fmt"\n", __func__, __LINE__, ##args)
+#else
+#define D(fmt, args...)
+#endif
+
+/* ------------- JZ_FB_DEBUG_DUMP ------------- */
+#if JZ_FB_DEBUG_DUMP
+#define DUMP(fmt, args...) \
+ printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
+#else
+#define DUMP(fmt, args...)
+#endif
+
+#define E(fmt, args...) \
+ printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
+
+#define I(fmt, args...) \
+ printk(KERN_INFO JZ_SOC_NAME": "DRV_NAME": "fmt"\n", ##args)
+
+#endif /* Define __KERNEL__ */
+
+#endif
diff --git a/drivers/video/jz475x/core/desc.c b/drivers/video/jz475x/core/desc.c
new file mode 100644
index 00000000000..e6a4bd4322a
--- /dev/null
+++ b/drivers/video/jz475x/core/desc.c
@@ -0,0 +1,346 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * DMA Descirptor Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static void dump_desc(struct jz_fb_dma_desc *desc)
+{
+ DUMP("HW_DESC: Virt: 0x%08lx, Phys: 0x%08lx", &desc->hw_desc,
+ virt_to_phys(&desc->hw_desc));
+ DUMP("=================================================");
+ DUMP("next_desc: 0x%08lx.", desc->hw_desc.next_desc);
+ DUMP("databuf: 0x%08lx.", desc->hw_desc.databuf);
+ DUMP("frame_id: 0x%08lx.", desc->hw_desc.frame_id);
+ DUMP("cmd: 0x%08lx.", desc->hw_desc.cmd);
+
+#ifdef JZ_FB_8WORD_DMA_DESC
+ DUMP("offsize: 0x%08lx.", desc->hw_desc.offsize);
+ DUMP("page_width: 0x%08lx.", desc->hw_desc.page_width);
+ DUMP("cmd_num: 0x%08lx.", desc->hw_desc.cmd_num);
+ DUMP("desc_size: 0x%08lx.", desc->hw_desc.desc_size);
+#endif
+
+ return;
+}
+
+static inline void dma_desc_wback_inv(struct jz_fb_dma_desc *desc)
+{
+ dma_cache_wback((unsigned long)&desc->hw_desc, sizeof(dma_desc_t));
+
+ return;
+}
+
+static unsigned long dma_desc_pool_init(struct jz_fb_win_info *win)
+{
+ void *mem = win->dma_desc_pool;
+
+ int i;
+
+ win->dma_desc_data_start = NULL;
+ win->dma_desc_last_no_data = NULL;
+
+ for (i = 0; i < JZ_FB_NR_MAX_DMA_DESC; i++) {
+ win->dma_desc[i] = mem;
+
+ win->dma_desc[i]->use = 0;
+ win->dma_desc[i]->mem = NULL;
+
+ win->dma_desc[i]->index = i;
+ win->dma_desc[i]->win = win;
+
+ mem += sizeof(struct jz_fb_dma_desc);
+ }
+
+ return sizeof(struct jz_fb_dma_desc) * JZ_FB_NR_MAX_DMA_DESC;
+}
+
+static struct jz_fb_dma_desc *dma_desc_get(struct jz_fb_win_info *win)
+{
+ struct jz_fb_dma_desc *desc;
+
+ int i;
+
+ for (i = 0; i < JZ_FB_NR_MAX_DMA_DESC; i++) {
+ if (!win->dma_desc[i]->use) {
+ desc = win->dma_desc[i];
+ desc->use = 1;
+
+ memset(&desc->hw_desc, 0, sizeof(dma_desc_t));
+
+ return desc;
+ }
+ }
+
+ return NULL;
+}
+
+static void dma_desc_put(struct jz_fb_dma_desc *desc)
+{
+ desc->use = 0;
+
+ return;
+}
+
+static void dma_desc_init(struct jz_fb_dma_desc *desc)
+{
+ /* TODO: Setup DMA Descriptor as static/dynamic config.
+ like EOF etc.
+ */
+
+ desc->hw_desc.next_desc = virt_to_phys(&desc->hw_desc);
+ desc->hw_desc.frame_id = desc->index;
+
+ INIT_LIST_HEAD(&desc->list);
+ INIT_LIST_HEAD(&desc->group);
+
+ return;
+}
+
+static void dma_desc_set_mem(struct jz_fb_dma_desc *desc, void *mem)
+{
+ desc->mem = mem;
+ desc->hw_desc.databuf = virt_to_phys(mem);
+
+ return;
+}
+
+static void dma_desc_set_data_size(struct jz_fb_dma_desc *desc,
+ unsigned long size)
+{
+ desc->hw_desc.cmd |= dma_align_size(size) / 4; /* Word. */
+
+ return;
+}
+
+static void dma_desc_set_area_size(struct jz_fb_dma_desc *desc, unsigned int w,
+ unsigned int h)
+{
+ desc->hw_desc.desc_size = HW_AREA_SIZE(w, h);
+
+ return;
+}
+
+/* REVIST: The exact meaning of offsize and page_width. */
+void dma_desc_set_stride(struct jz_fb_dma_desc *desc,
+ unsigned long offsize, unsigned long page_width)
+{
+ desc->hw_desc.offsize = dma_align_size(offsize) / 4;
+ desc->hw_desc.page_width = dma_align_size(page_width) / 4;
+
+ return;
+}
+
+static void dma_desc_set_as_palette(struct jz_fb_dma_desc *desc)
+{
+ desc->hw_desc.cmd |= LCD_CMD_PAL;
+
+ return;
+}
+
+static void dma_desc_set_as_cmd(struct jz_fb_dma_desc *desc)
+{
+ desc->hw_desc.cmd |= LCD_CMD_CMD;
+
+ return;
+}
+
+static void dma_desc_set_chain_head(struct jz_fb_dma_desc *desc)
+{
+ struct jz_fb_ot_info *ot = desc->win->ctrl->ot;
+ struct jz_fb_reg_info *reg = &ot->reg_info;
+
+ int win_index = desc->win->index;
+
+ dma_desc_wback_inv(desc);
+
+ if (win_index == 0) {
+ REG_LCD_DA0 = reg->lcd_da0 = virt_to_phys(&desc->hw_desc);
+ }else{
+ REG_LCD_DA1 = reg->lcd_da1 = virt_to_phys(&desc->hw_desc);
+ }
+
+ return;
+}
+
+static void dma_desc_set_data_head(struct jz_fb_dma_desc *desc)
+{
+ struct jz_fb_win_info *win = desc->win;
+
+ if (!win->dma_desc_last_no_data) {
+ dma_desc_set_chain_head(desc);
+ }else{
+ win->dma_desc_last_no_data->hw_desc.next_desc = virt_to_phys(&desc->hw_desc);
+
+ dma_desc_wback_inv(win->dma_desc_last_no_data);
+ dma_desc_wback_inv(desc);
+ }
+
+
+ return;
+}
+
+static struct jz_fb_dma_desc *dma_desc_mem_to_desc(struct jz_fb_win_info *win, void *mem)
+{
+ int i;
+
+ for (i = 0; i < JZ_FB_NR_MAX_DMA_DESC; i++) {
+ if (win->dma_desc[i]->use
+ && win->dma_desc[i]->mem == mem) {
+
+ return win->dma_desc[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* Add a node to a group. */
+static void dma_desc_group_add(struct jz_fb_dma_desc *desc,
+ struct jz_fb_dma_desc *head)
+{
+ struct jz_fb_dma_desc *tail;
+
+ tail = list_entry(head->group.prev, struct jz_fb_dma_desc, group);
+
+ tail->hw_desc.next_desc = virt_to_phys(&desc->hw_desc);
+ desc->hw_desc.next_desc = virt_to_phys(&head->hw_desc);
+
+ dma_desc_wback_inv(desc);
+ dma_desc_wback_inv(tail);
+
+ list_add_tail(&desc->group, &head->group);
+
+ return;
+}
+
+/* Add a group or node to DMA Chain. */
+static void dma_desc_chain_add_tail(struct jz_fb_dma_desc *desc,
+ struct jz_fb_dma_desc *chain_head)
+{
+ struct jz_fb_dma_desc *chain_tail, *desc_tail;
+
+ chain_tail = list_entry(chain_head->list.prev, struct jz_fb_dma_desc, list);
+
+ if (!list_empty(&desc->group)) {
+ desc_tail = list_entry(desc->group.prev, struct jz_fb_dma_desc, group);
+ }else{
+ desc_tail = desc;
+ }
+
+ dma_desc_wback_inv(desc);
+
+ desc_tail->hw_desc.next_desc = virt_to_phys(&chain_head->hw_desc);
+ chain_tail->hw_desc.next_desc = virt_to_phys(&desc->hw_desc);
+
+ dma_desc_wback_inv(desc_tail);
+ dma_desc_wback_inv(chain_tail);
+
+ list_add_tail(&desc->list, &chain_head->list);
+
+ return;
+}
+
+/* Delete a node / group from DMA Chain. */
+static void dma_desc_chain_del(struct jz_fb_dma_desc *desc)
+{
+ struct jz_fb_dma_desc *prev, *prev_tail, *next;
+ struct jz_fb_win_info *win = desc->win;
+
+ if (list_empty(&desc->list)) /* Always deleted ? */
+ return;
+
+ prev = list_entry(desc->list.prev, struct jz_fb_dma_desc, list);
+
+ /* Prev is in group ? */
+ if (!list_empty(&prev->group)) {
+ /* Get Prev group tail. */
+ prev_tail = list_entry(prev->group.prev, struct jz_fb_dma_desc, group);
+ }else{
+ prev_tail = prev;
+ }
+
+ next = list_entry(desc->list.next, struct jz_fb_dma_desc, list);
+
+ /* Should we choose new data head ? */
+ if (desc == win->dma_desc_data_start) {
+ /* Setup New data head. */
+ if(!win->dma_desc_last_no_data) {
+ dma_desc_set_chain_head(next);
+ }else{
+ dma_desc_set_data_head(next);
+ }
+
+ win->dma_desc_data_start = next;
+ }
+
+ /* Remove us from the chain Prev group tail -> next group Head. */
+ prev_tail->hw_desc.next_desc = virt_to_phys(&next->hw_desc);
+
+ dma_desc_wback_inv(prev_tail);
+
+ list_del(&desc->list);
+
+ return;
+}
+
+static void dma_desc_add_to_chain(struct jz_fb_dma_desc *desc)
+{
+ struct jz_fb_win_info *win = desc->win;
+
+ if (!win->dma_desc_data_start) {
+ /* Empty. */
+ if (!win->dma_desc_last_no_data) {
+ /* Chain head. */
+ dma_desc_set_chain_head(desc);
+ }else{
+ /* Only Data head. */
+ dma_desc_set_data_head(desc);
+ }
+
+ win->dma_desc_data_start = desc;
+
+ return;
+ }else{
+ /* Link node or group to the end of the DMA chain. */
+ dma_desc_chain_add_tail(desc, win->dma_desc_data_start);
+ }
+
+ dma_desc_wback_inv(desc);
+
+ return;
+}
+
+static void dma_desc_del_from_chain(struct jz_fb_dma_desc *desc)
+{
+ struct jz_fb_win_info *win = desc->win;
+
+ if (!win->dma_desc_data_start) /* Data Chain is empty. */
+ return;
+
+ /* Must be 1 node / group in Data chain. */
+ if (list_empty(&win->dma_desc_data_start->list))
+ return;
+
+ dma_desc_chain_del(desc);
+
+ return;
+}
+
diff --git a/drivers/video/jz475x/core/framebuffer.c b/drivers/video/jz475x/core/framebuffer.c
new file mode 100644
index 00000000000..fae3958589d
--- /dev/null
+++ b/drivers/video/jz475x/core/framebuffer.c
@@ -0,0 +1,356 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Framebuffer Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+/* ------------ Framebuffer ----------------- */
+static void dump_fb_info_var(struct fb_var_screeninfo *var)
+{
+ DUMP("Framebuffer VAR Info: ");
+ DUMP("=============================================");
+
+ DUMP("var->xres: 0x%08lx.",var->xres);
+ DUMP("var->yres: 0x%08lx.",var->yres);
+ DUMP("var->xres_virtual: 0x%08lx.",var->xres_virtual);
+ DUMP("var->yres_virtual: 0x%08lx.",var->yres_virtual);
+ DUMP("var->xoffset: 0x%08lx.",var->xoffset);
+ DUMP("var->yoffset: 0x%08lx.",var->yoffset);
+ DUMP("var->bits_per_pixel: 0x%08lx.",var->bits_per_pixel);
+ DUMP("var->grayscale: 0x%08lx.",var->grayscale);
+ DUMP("var->nonstd: 0x%08lx.",var->nonstd);
+ DUMP("var->activate: 0x%08lx.",var->activate);
+ DUMP("var->height: 0x%08lx.",var->height);
+ DUMP("var->width: 0x%08lx.",var->width);
+ DUMP("var->accel_flags: 0x%08lx.",var->accel_flags);
+ DUMP("var->pixclock: 0x%08lx.",var->pixclock);
+ DUMP("var->left_margin: 0x%08lx.",var->left_margin);
+ DUMP("var->right_margin: 0x%08lx.",var->right_margin);
+ DUMP("var->upper_margin: 0x%08lx.",var->upper_margin);
+ DUMP("var->lower_margin: 0x%08lx.",var->lower_margin);
+ DUMP("var->hsync_len: 0x%08lx.",var->hsync_len);
+ DUMP("var->vsync_len: 0x%08lx.",var->vsync_len);
+ DUMP("var->sync: 0x%08lx.",var->sync);
+ DUMP("var->vmode: 0x%08lx.",var->vmode);
+ DUMP("var->rotate: 0x%08lx.",var->rotate);
+
+ return;
+}
+
+static void dump_fb_info_fix(struct fb_fix_screeninfo *fix)
+{
+ DUMP("Framebuffer FIX Info: ");
+ DUMP("=============================================");
+
+ DUMP("fix->id: %s.",fix->id);
+
+ DUMP("fix->smem_start: 0x%08lx.",fix->smem_start);
+ DUMP("fix->smem_len: 0x%08lx.",fix->smem_len);
+ DUMP("fix->type: 0x%08lx.",fix->type);
+ DUMP("fix->type_aux: 0x%08lx.",fix->type_aux);
+ DUMP("fix->visual: 0x%08lx.",fix->visual);
+ DUMP("fix->xpanstep: 0x%08lx.",fix->xpanstep);
+ DUMP("fix->ypanstep: 0x%08lx.",fix->ypanstep);
+ DUMP("fix->ywrapstep: 0x%08lx.",fix->ywrapstep);
+ DUMP("fix->line_length: 0x%08lx.",fix->line_length);
+ DUMP("fix->mmio_start: 0x%08lx.",fix->mmio_start);
+ DUMP("fix->mmio_len: 0x%08lx.",fix->mmio_len);
+ DUMP("fix->accel: 0x%08lx.",fix->accel);
+
+ return;
+}
+
+static inline int bpp_to_data_bpp(int bpp)
+{
+ switch (bpp) {
+ case 32:
+ case 16:
+ break;
+
+ case 15:
+ bpp = 16;
+ break;
+
+ default:
+ bpp = -EINVAL;
+ }
+
+ return bpp;
+}
+
+static void *alloc_framebuffer(unsigned long len)
+{
+ void *mem;
+
+ unsigned int page_shift;
+ unsigned long page;
+
+ for (page_shift = 0; page_shift < 12; page_shift++)
+ if ((PAGE_SIZE << page_shift) >= len)
+ break;
+
+ mem = (void *)__get_free_pages(GFP_KERNEL, page_shift);
+ if (!mem) {
+ return NULL;
+ }
+
+ for (page = (unsigned long)mem;
+ page < PAGE_ALIGN((unsigned long)mem + (PAGE_SIZE << page_shift));
+ page += PAGE_SIZE) {
+ SetPageReserved(virt_to_page((void*)page));
+ }
+
+ memset(mem, 0, PAGE_SIZE << page_shift);
+
+ D("Allocate framebuffer: Real Size: 0x%08lx, Virt: 0x%08lx, Phys: 0%08lx",
+ PAGE_SIZE << page_shift, (unsigned long)mem, virt_to_phys(mem));
+
+ return mem;
+}
+
+static int free_framebuffer(void *mem)
+{
+ return 0;
+}
+
+/* Add framebuffer to Win Framebuffer Pool. */
+static int add_framebuffer_to_win(struct jz_fb_win_info *win, void *mem)
+{
+ int i;
+
+ D("Called.");
+
+ for (i = 0; i < JZ_FB_NR_MAX_FB_MEM; i++) {
+ if (!win->fb_mem[i]) {
+ win->fb_mem[i] = mem;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static int set_drv_framebuffer(struct jz_fb_win_info *win, void *mem)
+{
+ D("Called.");
+
+ win->fb.fix.smem_start = virt_to_phys(mem);
+ win->fb.fix.smem_len = win->fb_mem_len;
+ win->fb.screen_base = (unsigned char *)(((unsigned long)mem&0x1fffffff) | 0xa0000000);
+
+ return 0;
+}
+
+static int alloc_cmap(struct jz_fb_win_info *win, unsigned int bpp)
+{
+ int rv;
+
+ switch (bpp) {
+ case 1:
+ rv = fb_alloc_cmap(&win->fb.cmap, 4, 0);
+ break;
+ case 2:
+ rv = fb_alloc_cmap(&win->fb.cmap, 8, 0);
+ break;
+ case 4:
+ rv = fb_alloc_cmap(&win->fb.cmap, 32, 0);
+ break;
+ case 8:
+
+ default:
+ rv = fb_alloc_cmap(&win->fb.cmap, 256, 0);
+ break;
+ }
+
+ return rv;
+}
+
+static void free_cmap(struct jz_fb_win_info *win)
+{
+ fb_dealloc_cmap(&win->fb.cmap);
+
+ return;
+}
+
+static struct fb_ops jz_fb_ops;
+
+static int fb_info_set_color(struct fb_info *info)
+{
+ struct fb_fix_screeninfo *fix = &info->fix;
+ struct fb_var_screeninfo *var = &info->var;
+
+ D("Called.");
+
+ dump_fb_info_var(var);
+
+ switch (var->bits_per_pixel) {
+ case 1: /* Mono */
+ fix->visual = FB_VISUAL_MONO01;
+ fix->line_length = (var->xres * var->bits_per_pixel) / 8;
+
+ break;
+
+ case 2: /* Mono */
+ var->red.offset = 0;
+ var->red.length = 2;
+ var->green.offset = 0;
+ var->green.length = 2;
+ var->blue.offset = 0;
+ var->blue.length = 2;
+
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ fix->line_length = (var->xres * var->bits_per_pixel) / 8;
+
+ break;
+
+ case 4: /* PSEUDOCOLOUR */
+ var->red.offset = 0;
+ var->red.length = 4;
+ var->green.offset = 0;
+ var->green.length = 4;
+ var->blue.offset = 0;
+ var->blue.length = 4;
+
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ fix->line_length = var->xres / 2;
+
+ break;
+
+ case 8: /* PSEUDOCOLOUR, 256 */
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ fix->line_length = var->xres;
+
+ break;
+
+ case 15: /* DIRECTCOLOUR, 32k */
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ fix->visual = FB_VISUAL_DIRECTCOLOR;
+ fix->line_length = var->xres_virtual * 2;
+
+ break;
+
+ case 16: /* DIRECTCOLOUR, 64k */
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->line_length = var->xres_virtual * 2;
+
+ break;
+
+ case 17 ... 32:
+ /* DIRECTCOLOUR, 256 */
+ var->bits_per_pixel = 32;
+
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ fix->line_length = var->xres_virtual * 4;
+
+ break;
+
+ default:
+ E("BPP %d not support.", var->bits_per_pixel);
+
+ return -EINVAL;
+ }
+
+ D("fix->line_length: 0x%08x.", fix->line_length);
+
+ fb_set_cmap(&info->cmap, info);
+
+ return 0;
+}
+
+/* Fiil FB Info. */
+static int win_fb_info_setup(struct jz_fb_win_info *win)
+{
+ struct jz_fb_ctrl *ctrl = win->ctrl;
+
+ int rv;
+
+ strcpy(win->fb.fix.id, DRV_NAME);
+
+ win->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ win->fb.fix.type_aux = 0;
+ win->fb.fix.xpanstep = 0;
+ win->fb.fix.ypanstep = 1;
+ win->fb.fix.ywrapstep = 0;
+ win->fb.fix.accel = FB_ACCEL_NONE;
+
+ win->fb.fbops = &jz_fb_ops;
+ win->fb.flags = FBINFO_FLAG_DEFAULT;
+
+ win->fb.var.nonstd = 0;
+ win->fb.var.activate = FB_ACTIVATE_NOW;
+ win->fb.var.accel_flags = 0;
+ win->fb.var.vmode = FB_VMODE_NONINTERLACED;
+
+ win->fb.var.xres = WIN_W(win);
+ win->fb.var.yres = WIN_H(win);
+ win->fb.var.xres_virtual = WIN_W(win);
+ win->fb.var.yres_virtual = WIN_H(win);
+ win->fb.var.bits_per_pixel = WIN_BPP(win);
+ win->fb.var.xoffset = 0;
+ win->fb.var.yoffset = 0;
+
+ win->fb.var.pixclock = ctrl->pixclock;
+
+ win->fb.var.left_margin = 0;
+ win->fb.var.right_margin = 0;
+ win->fb.var.upper_margin = 0;
+ win->fb.var.lower_margin = 0;
+ win->fb.var.hsync_len = 0;
+ win->fb.var.vsync_len = 0;
+ win->fb.var.sync = 0;
+
+ win->fb.pseudo_palette = (void *)(win + 1);
+
+ rv = fb_info_set_color(&win->fb);
+ if (rv) {
+ return rv;
+ }
+
+ return rv;
+}
diff --git a/drivers/video/jz475x/core/hw.c b/drivers/video/jz475x/core/hw.c
new file mode 100644
index 00000000000..6ce59e851b5
--- /dev/null
+++ b/drivers/video/jz475x/core/hw.c
@@ -0,0 +1,632 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * HW Controller Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static int jz_fb_hw_bpp_to_palette_size(unsigned int bpp)
+{
+ int size;
+
+ /* More details can be found in LCDC Spec. */
+ switch (bpp) {
+ case 1:
+ size = 1; /* 1 word. */
+ break;
+ case 2:
+ size = 2; /* 2 words. */
+ break;
+ case 4:
+ size = 8; /* 8 words. */
+ break;
+ case 8:
+ size = 128; /* 128 words. */
+ break;
+
+ default:
+ return -1;
+ }
+
+ return size * 4;
+}
+
+static void jz_fb_hw_ot_power_on(struct jz_fb_ctrl *ctrl, int force)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+
+ D("Called.");
+
+ if (!force && ot->power) {
+ D("Already Power ON.");
+ return;
+ }
+
+ if (ot) {
+ if (ot->ops->start)
+ ot->ops->start(ot);
+
+ ot->power = 1;
+ }else{
+ E("No output attached.");
+ }
+
+ return;
+}
+
+static void jz_fb_hw_ot_power_off(struct jz_fb_ctrl *ctrl, int force)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+
+ D("Called.");
+
+ if (!force && !ot->power) {
+ D("Already Power Down.");
+ return;
+ }
+
+ if (ot) {
+ if (ot->ops->stop)
+ ot->ops->stop(ot);
+
+ ot->power = 0;
+ }else{
+ E("No output attached.");
+ }
+
+ return;
+}
+
+static void jz_fb_hw_ot_enable(struct jz_fb_ctrl *ctrl, int force)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+
+ unsigned int delay;
+
+ D("Called.");
+
+ if (!force && ot->state) {
+ D("Already enable.");
+ return;
+ }
+
+ if (ot) {
+ delay = ot->config->enable_delay_ms;
+
+ if (ot->ops->enable) {
+ if (delay)
+ mdelay(delay);
+
+ ot->ops->enable(ot);
+ }
+
+ ot->state = 1;
+ }else{
+ E("No output attached.");
+ }
+
+ return;
+}
+
+static void jz_fb_hw_ot_disable(struct jz_fb_ctrl *ctrl, int force)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+
+ D("Called.");
+
+ if (!force && !ot->state) {
+ D("Already Disable.");
+ return;
+ }
+
+ if (ot) {
+ if (ot->ops->disable)
+ ot->ops->disable(ot);
+
+ ot->state = 0;
+ }else{
+ E("No output attached.");
+ }
+
+ return;
+}
+
+static void jz_fb_hw_ctrl_enable(struct jz_fb_ctrl *ctrl, int force)
+{
+ D("Called.");
+
+ if (!force && ctrl->state) {
+ D("Already Enable.");
+ return;
+ }
+
+ REG_LCD_STATE = 0; /* clear lcdc status */
+
+ __lcd_clr_dis();
+ __lcd_set_ena(); /* enable lcdc */
+
+ ctrl->state = 1;
+
+ return;
+}
+
+static void jz_fb_hw_ctrl_disable(struct jz_fb_ctrl *ctrl, int force)
+{
+ D("Called.");
+
+ if (!force && !ctrl->state) {
+ D("Already Disable.");
+ return;
+ }
+
+ if (ctrl->ot->use_quick_disable) {
+ D("Quick Disable");
+ __lcd_clr_ena();
+ }else {
+ /* when CPU main freq is 336MHz,wait for 16ms */
+ int cnt = 336000 * 16;
+
+ __lcd_set_dis(); /* regular disable */
+ while(!__lcd_disable_done() && cnt) {
+ cnt--;
+ }
+
+ D("Normal Disable");
+ if (cnt == 0)
+ E("LCD disable timeout! REG_LCD_STATE=0x%08xx", REG_LCD_STATE);
+
+ REG_LCD_STATE &= ~LCD_STATE_LDD;
+ }
+
+ ctrl->state = 0;
+
+ return;
+}
+
+static void jz_fb_hw_set_panel_info(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_panel_info *panel = ctrl->ot->config->panel;
+ struct jz_fb_reg_info *reg = &ctrl->ot->reg_info;
+
+ D("Called.");
+
+ /* Collect Panel Config. */
+ reg->lcd_cfg |= panel->lcd_cfg;
+ reg->lcd_ctrl |= panel->lcd_ctrl;
+
+ switch (panel->lcd_cfg & LCD_CFG_MODE_MASK ) {
+ case LCD_CFG_MODE_GENERIC_TFT:
+ case LCD_CFG_MODE_INTER_CCIR656:
+ case LCD_CFG_MODE_NONINTER_CCIR656:
+ default:
+ reg->lcd_vat = (((panel->blw + panel->w + panel->elw + panel->hsw)) << 16) | (panel->vsw + panel->bfw + panel->h + panel->efw);
+ reg->lcd_dah = ((panel->hsw + panel->blw) << 16) | (panel->hsw + panel->blw + panel->w);
+ reg->lcd_dav = ((panel->vsw + panel->bfw) << 16) | (panel->vsw + panel->bfw + panel->h);
+ reg->lcd_hsync = (0 << 16) | panel->hsw;
+ reg->lcd_vsync = (0 << 16) | panel->vsw;
+ break;
+ }
+
+ return;
+}
+
+static void jz_fb_hw_set_ot_info(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_reg_info *reg = &ctrl->ot->reg_info;
+
+ D("Called.");
+
+ /* Use RGB -> YUV? */
+ if (ctrl->ot->use_rgb_to_yuv) {
+ D("Use RGB->YUV.");
+
+ reg->lcd_rgbc |= LCD_RGBC_YCC;
+ }
+
+ /* Set Panel Background Color. */
+ reg->lcd_bgc = ctrl->ot->config->background_color;
+
+ return;
+}
+
+static int jz_fb_hw_set_win_bpp(struct jz_fb_win_info *win, unsigned int bpp)
+{
+ struct jz_fb_reg_info *reg = &win->ctrl->ot->reg_info;
+
+ D("Called.");
+
+ if (win->index == 0) {
+ reg->lcd_ctrl &= ~LCD_CTRL_BPP_MASK;
+
+ if (bpp == 1)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_1;
+ else if (bpp == 2)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_2;
+ else if (bpp == 4)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_4;
+ else if (bpp == 8)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_8;
+ else if (bpp == 15)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB555;
+ else if (bpp == 16)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB565;
+ else if (bpp > 16 && bpp <= 32)
+ reg->lcd_ctrl |= LCD_CTRL_BPP_18_24;
+ else
+ return -1;
+
+ }else if (win->index == 1) {
+ reg->lcd_osdctrl &= ~LCD_CTRL_BPP_MASK;
+
+ if (bpp == 15)
+ reg->lcd_osdctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB555;
+ else if (bpp == 16)
+ reg->lcd_osdctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB565;
+ else if (bpp > 16 && bpp <= 32)
+ reg->lcd_osdctrl |= LCD_CTRL_BPP_18_24;
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+static void jz_fb_hw_set_win_enable(struct jz_fb_win_info *win, int enable)
+{
+ struct jz_fb_reg_info *reg = &win->ctrl->ot->reg_info;
+
+ D("Called.");
+
+ if (win->index == 0) {
+ if (enable)
+ reg->lcd_osdc |= LCD_OSDC_F0EN;
+ else
+ reg->lcd_osdc &= ~LCD_OSDC_F0EN;
+ }else if (win->index == 1) {
+ if (enable)
+ reg->lcd_osdc |= LCD_OSDC_F1EN;
+ else
+ reg->lcd_osdc &= ~LCD_OSDC_F1EN;
+ }
+
+ return;
+}
+
+static void jz_fb_hw_set_win_area(struct jz_fb_win_info *win, unsigned int x,
+ unsigned int y, unsigned int w, unsigned int h)
+{
+ struct jz_fb_reg_info *reg = &win->ctrl->ot->reg_info;
+
+ D("Called.");
+
+ if (win->index == 0) {
+ reg->lcd_xyp0 = HW_AREA_POS(x, y);
+ reg->lcd_size0 = HW_AREA_SIZE(w, h);
+ }else if (win->index == 1) {
+ reg->lcd_xyp1 = HW_AREA_POS(x, y);
+ reg->lcd_size1 = HW_AREA_SIZE(w, h);
+ }
+
+ return;
+}
+
+static void jz_fb_hw_set_dma_desc_format(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_reg_info *reg = &ctrl->ot->reg_info;
+
+#ifdef JZ_FB_8WORD_DMA_DESC
+ reg->lcd_cfg |= LCD_CFG_NEWDES;
+#else
+ reg->lcd_cfg &= ~LCD_CFG_NEWDES;
+#endif
+
+ return;
+}
+
+static void jz_fb_hw_set_win_info(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_win_info *win;
+ struct jz_fb_win_attr_info *wa;
+
+ struct jz_fb_reg_info *reg = &ctrl->ot->reg_info;
+
+ int i;
+
+ D("Called.");
+
+ /* REVIST: Can we leave OSDEN set when F0EN and F1EN is disabled? */
+ reg->lcd_osdc |= LCD_OSDC_OSDEN;
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ win = ctrl->win[i];
+ wa = &win->attr;
+
+ jz_fb_hw_set_win_enable(win, wa->enable);
+ jz_fb_hw_set_win_area(win, wa->x, wa->y, wa->w, wa->h);
+ jz_fb_hw_set_win_bpp(win, wa->bpp);
+ }
+
+ return;
+}
+
+static inline void dump_registers(void)
+{
+ DUMP("Dump LCDC Registers: ");
+ DUMP("======================================");
+ DUMP("REG_LCD_CFG:\t0x%08x", REG_LCD_CFG);
+ DUMP("REG_LCD_CTRL:\t0x%08x", REG_LCD_CTRL);
+ DUMP("REG_LCD_STATE:\t0x%08x", REG_LCD_STATE);
+ DUMP("REG_LCD_OSDC:\t0x%08x", REG_LCD_OSDC);
+ DUMP("REG_LCD_OSDCTRL:\t0x%08x", REG_LCD_OSDCTRL);
+ DUMP("REG_LCD_OSDS:\t0x%08x", REG_LCD_OSDS);
+ DUMP("REG_LCD_BGC:\t0x%08x", REG_LCD_BGC);
+ DUMP("REG_LCD_KEK0:\t0x%08x", REG_LCD_KEY0);
+ DUMP("REG_LCD_KEY1:\t0x%08x", REG_LCD_KEY1);
+ DUMP("REG_LCD_ALPHA:\t0x%08x", REG_LCD_ALPHA);
+ DUMP("REG_LCD_IPUR:\t0x%08x", REG_LCD_IPUR);
+ DUMP("REG_LCD_VAT:\t0x%08x", REG_LCD_VAT);
+ DUMP("REG_LCD_DAH:\t0x%08x", REG_LCD_DAH);
+ DUMP("REG_LCD_DAV:\t0x%08x", REG_LCD_DAV);
+ DUMP("REG_LCD_XYP0:\t0x%08x", REG_LCD_XYP0);
+ DUMP("REG_LCD_XYP1:\t0x%08x", REG_LCD_XYP1);
+ DUMP("REG_LCD_SIZE0:\t0x%08x", REG_LCD_SIZE0);
+ DUMP("REG_LCD_SIZE1:\t0x%08x", REG_LCD_SIZE1);
+ DUMP("REG_LCD_RGBC\t0x%08x", REG_LCD_RGBC);
+ DUMP("REG_LCD_VSYNC:\t0x%08x", REG_LCD_VSYNC);
+ DUMP("REG_LCD_HSYNC:\t0x%08x", REG_LCD_HSYNC);
+ DUMP("REG_LCD_PS:\t0x%08x", REG_LCD_PS);
+ DUMP("REG_LCD_CLS:\t0x%08x", REG_LCD_CLS);
+ DUMP("REG_LCD_SPL:\t0x%08x", REG_LCD_SPL);
+ DUMP("REG_LCD_REV:\t0x%08x", REG_LCD_REV);
+ DUMP("REG_LCD_IID:\t0x%08x", REG_LCD_IID);
+ DUMP("REG_LCD_DA0:\t0x%08x", REG_LCD_DA0);
+ DUMP("REG_LCD_SA0:\t0x%08x", REG_LCD_SA0);
+ DUMP("REG_LCD_FID0:\t0x%08x", REG_LCD_FID0);
+ DUMP("REG_LCD_CMD0:\t0x%08x", REG_LCD_CMD0);
+ DUMP("REG_LCD_OFFS0:\t0x%08x", REG_LCD_OFFS0);
+ DUMP("REG_LCD_PW0:\t0x%08x", REG_LCD_PW0);
+ DUMP("REG_LCD_CNUM0:\t0x%08x", REG_LCD_CNUM0);
+ DUMP("REG_LCD_DESSIZE0:\t0x%08x", REG_LCD_DESSIZE0);
+ DUMP("REG_LCD_DA1:\t0x%08x", REG_LCD_DA1);
+ DUMP("REG_LCD_SA1:\t0x%08x", REG_LCD_SA1);
+ DUMP("REG_LCD_FID1:\t0x%08x", REG_LCD_FID1);
+ DUMP("REG_LCD_CMD1:\t0x%08x", REG_LCD_CMD1);
+ DUMP("REG_LCD_OFFS1:\t0x%08x", REG_LCD_OFFS1);
+ DUMP("REG_LCD_PW1:\t0x%08x", REG_LCD_PW1);
+ DUMP("REG_LCD_CNUM1:\t0x%08x", REG_LCD_CNUM1);
+ DUMP("REG_LCD_DESSIZE1:\t0x%08x", REG_LCD_DESSIZE1);
+ DUMP("==================================");
+ DUMP("REG_LCD_VSYNC:\t%d:%d", REG_LCD_VSYNC>>16, REG_LCD_VSYNC&0xfff);
+ DUMP("REG_LCD_HSYNC:\t%d:%d", REG_LCD_HSYNC>>16, REG_LCD_HSYNC&0xfff);
+ DUMP("REG_LCD_VAT:\t%d:%d", REG_LCD_VAT>>16, REG_LCD_VAT&0xfff);
+ DUMP("REG_LCD_DAH:\t%d:%d", REG_LCD_DAH>>16, REG_LCD_DAH&0xfff);
+ DUMP("REG_LCD_DAV:\t%d:%d", REG_LCD_DAV>>16, REG_LCD_DAV&0xfff);
+ DUMP("==================================");
+ /* Smart LCD Controller Resgisters */
+ DUMP("REG_SLCD_CFG:\t0x%08x", REG_SLCD_CFG);
+ DUMP("REG_SLCD_CTRL:\t0x%08x", REG_SLCD_CTRL);
+ DUMP("REG_SLCD_STATE:\t0x%08x", REG_SLCD_STATE);
+ DUMP("==================================");
+ /* TVE Controller Resgisters */
+ DUMP("REG_TVE_CTRL:\t0x%08x", REG_TVE_CTRL);
+ DUMP("REG_TVE_FRCFG:\t0x%08x", REG_TVE_FRCFG);
+ DUMP("REG_TVE_SLCFG1:\t0x%08x", REG_TVE_SLCFG1);
+ DUMP("REG_TVE_SLCFG2:\t0x%08x", REG_TVE_SLCFG2);
+ DUMP("REG_TVE_SLCFG3:\t0x%08x", REG_TVE_SLCFG3);
+ DUMP("REG_TVE_LTCFG1:\t0x%08x", REG_TVE_LTCFG1);
+ DUMP("REG_TVE_LTCFG2:\t0x%08x", REG_TVE_LTCFG2);
+ DUMP("REG_TVE_CFREQ:\t0x%08x", REG_TVE_CFREQ);
+ DUMP("REG_TVE_CPHASE:\t0x%08x", REG_TVE_CPHASE);
+ DUMP("REG_TVE_CBCRCFG:\t0x%08x", REG_TVE_CBCRCFG);
+ DUMP("REG_TVE_WSSCR:\t0x%08x", REG_TVE_WSSCR);
+ DUMP("REG_TVE_WSSCFG1:\t0x%08x", REG_TVE_WSSCFG1);
+ DUMP("REG_TVE_WSSCFG2:\t0x%08x", REG_TVE_WSSCFG2);
+ DUMP("REG_TVE_WSSCFG3:\t0x%08x", REG_TVE_WSSCFG3);
+ DUMP("==================================");
+
+ return;
+}
+
+void dump_reg_info(struct jz_fb_reg_info *reg)
+{
+ DUMP("Dump reg_info: ");
+ DUMP("======================================");
+
+ DUMP("reg->lcd_cfg: 0x%08lx.", reg->lcd_cfg);
+ DUMP("reg->lcd_ctrl: 0x%08lx.", reg->lcd_ctrl);
+ DUMP("reg->lcd_vat: 0x%08lx.", reg->lcd_vat);
+ DUMP("reg->lcd_dah: 0x%08lx.", reg->lcd_dah);
+ DUMP("reg->lcd_dav: 0x%08lx.", reg->lcd_dav);
+ DUMP("reg->lcd_hsync: 0x%08lx.", reg->lcd_hsync);
+ DUMP("reg->lcd_vsync: 0x%08lx.", reg->lcd_vsync);
+ DUMP("reg->lcd_bgc: 0x%08lx.", reg->lcd_bgc);
+ DUMP("reg->lcd_da0: 0x%08lx.", reg->lcd_da0);
+ DUMP("reg->lcd_da1: 0x%08lx.", reg->lcd_da1);
+
+ return;
+}
+
+static void jz_fb_hw_write_reg(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_reg_info *reg = &ctrl->ot->reg_info;
+
+ D("Called.");
+
+ /* TODO:
+ Use flags in reg_info to divide function blocks regs IO.
+ */
+
+ REG_LCD_CFG = reg->lcd_cfg; /* LCDC Configure Register */
+ REG_LCD_CTRL = reg->lcd_ctrl; /* LCDC Controll Register */
+ REG_LCD_OSDC = reg->lcd_osdc; /* F0, F1, alpha, */
+ REG_LCD_OSDCTRL = reg->lcd_osdctrl; /* IPUEN, bpp */
+ REG_LCD_BGC = reg->lcd_bgc;
+ REG_LCD_KEY0 = reg->lcd_key0;
+ REG_LCD_KEY1 = reg->lcd_key1;
+ REG_LCD_ALPHA = reg->lcd_alpha;
+ REG_LCD_IPUR = reg->lcd_ipur;
+ REG_LCD_RGBC = reg->lcd_rgbc;
+ REG_LCD_VAT = reg->lcd_vat;
+ REG_LCD_DAH = reg->lcd_dah;
+ REG_LCD_DAV = reg->lcd_dav;
+ REG_LCD_VSYNC = reg->lcd_vsync;
+ REG_LCD_HSYNC = reg->lcd_hsync;
+ REG_LCD_PS = reg->lcd_ps;
+ REG_LCD_REV = reg->lcd_rev;
+ REG_LCD_XYP0 = reg->lcd_xyp0;
+ REG_LCD_XYP1 = reg->lcd_xyp1;
+ REG_LCD_SIZE0 = reg->lcd_size0;
+ REG_LCD_SIZE1 = reg->lcd_size1;
+ REG_LCD_DA0 = reg->lcd_da0;
+ REG_LCD_DA1 = reg->lcd_da1;
+
+ dump_registers();
+
+ return;
+}
+
+static void jz_fb_hw_set_pixclock(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+ struct jz_fb_panel_info *panel = ot->config->panel;
+
+ unsigned int pixclock, refresh_rate;
+ unsigned int w, h;
+
+ unsigned int v;
+
+ D("Called.");
+
+ refresh_rate = panel->fclk;
+
+ if (ot->use_tve) {
+ pixclock = 27000000;
+ }else{
+ if ((panel->lcd_cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_SERIAL_TFT) {
+ /* serial mode: Hsync period = 3*Width_Pixel */
+ w = (panel->w * 3 + panel->hsw + panel->elw + panel->blw);
+ h = (panel->h + panel->vsw + panel->efw + panel->bfw);
+
+ pixclock = w * h * refresh_rate;
+ }else {
+ w = (panel->w + panel->hsw + panel->elw + panel->blw);
+ h = (panel->h + panel->vsw + panel->efw + panel->bfw);
+
+ pixclock = w * h * refresh_rate;
+ }
+ }
+
+ ctrl->pixclock = pixclock;
+
+ /* ------------ HW: Set LCD Controller ---------------- */
+ __cpm_stop_lcd();
+
+ if (ot->use_tve) {
+ REG_CPM_LPCDR |= CPM_LPCDR_LTCS;
+ __cpm_select_pixclk_tve();
+ }else{
+ REG_CPM_LPCDR &= ~CPM_LPCDR_LTCS;
+ __cpm_select_pixclk_lcd();
+ }
+
+ v = __cpm_get_pllout2() / pixclock;
+ v--;
+
+ __cpm_set_pixdiv(v);
+
+#if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */
+ v = pixclock * 3 ; /* LCDClock > 2.5*Pixclock */
+
+ v = (__cpm_get_pllout()) / v;
+ if (v > 0x1f) {
+ printk("lcd clock divide is too large, set it to 0x1f\n");
+ v = 0x1f;
+ }
+
+ __cpm_set_ldiv(v);
+#endif
+
+ REG_CPM_CPCCR |= CPM_CPCCR_CE; /* update divide */
+
+ jz_clocks.pixclk = __cpm_get_pixclk();
+
+#if defined(CONFIG_SOC_JZ4750) /* Jz4750D don't use LCLK */
+ jz_clocks.lcdclk = __cpm_get_lcdclk();
+ I("LCD Controller Clock: %dMHz.", jz_clocks.lcdclk / 1000 / 1000);
+#endif
+
+ I("Pixel Clock: %dMHz.", pixclock / 1000 / 1000);
+
+ __cpm_start_lcd();
+
+ mdelay(1);
+
+ return;
+}
+
+static void jz_fb_hw_setup(struct jz_fb_ctrl *ctrl)
+{
+ struct jz_fb_ot_info *ot = ctrl->ot;
+ struct jz_fb_win_info *win;
+
+ int i, j;
+
+ D("Called.");
+
+ memset(&ot->reg_info, 0, (sizeof(struct jz_fb_reg_info)));
+
+ /* Step 1: Set Pixel Clock. */
+ jz_fb_hw_set_pixclock(ctrl);
+
+ /* Step 2: Build DMA Descriptor Chain. */
+ jz_fb_hw_set_dma_desc_format(ctrl);
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ win = ctrl->win[i];
+
+ /* Prepare DMA Descriptors. */
+ ot->desc_ops->cleanup(win);
+ ot->desc_ops->setup(win);
+
+ /* Attach All Framebuffer Memory Blocks. */
+ for (j = 0; j < JZ_FB_NR_MAX_FB_MEM; j++) {
+ if (win->fb_mem[j]) {
+ D("Win %d: Attach Framebufer : 0x%p.", i, win->fb_mem[j]);
+
+ ot->desc_ops->attach(win, win->fb_mem[j]);
+ }
+ }
+ }
+
+ /* Step 3: Set Panel Info. */
+ jz_fb_hw_set_panel_info(ctrl);
+
+ /* Step 4: Set OT Info. */
+ jz_fb_hw_set_ot_info(ctrl);
+
+ /* Step 5: Set All Win Info. */
+ jz_fb_hw_set_win_info(ctrl);
+
+ /* Step 6: Write all result to HW. */
+ jz_fb_hw_write_reg(ctrl);
+
+ /* Done. */
+ return;
+}
+
diff --git a/drivers/video/jz475x/core/ot.c b/drivers/video/jz475x/core/ot.c
new file mode 100644
index 00000000000..a6053c81ba4
--- /dev/null
+++ b/drivers/video/jz475x/core/ot.c
@@ -0,0 +1,167 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Output Control Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+struct jz_fb_ot_scan_info {
+ unsigned int max_w;
+ unsigned int max_h;
+ unsigned int max_bpp;
+};
+
+static inline unsigned int bpp_to_ctrl_bpp(int bpp)
+{
+ switch (bpp) {
+ case 15:
+ case 16:
+ break;
+
+ case 17 ... 32:
+ bpp = 32;
+
+ break;
+
+ default:
+ E("BPP (%d) not support, Set BPP 32.\n", bpp);
+
+ bpp = 32;
+
+ break;
+ }
+
+ return bpp;
+}
+
+static void jz_fb_ot_scan(struct jz_fb_ctrl *ctrl,
+ struct jz_fb_ot_scan_info *info)
+{
+ struct jz_fb_ot_info *o;
+ jz_fb_ot_init_t *init;
+
+ struct jz_fb_win_attr_info *a;
+
+ unsigned int n = sizeof(jz_fb_ots) / sizeof(struct jz_fb_ot_info *);
+
+ unsigned int i, j;
+ unsigned int v;
+
+ info->max_w = info->max_h = info->max_bpp = 0;
+
+ for (i = 0; i < n; i++) {
+ o = jz_fb_ots[i];
+ init = jz_fb_ot_inits[i];
+
+ /* Step 1: OT ID & Parent. */
+ o->id = i;
+ o->ctrl = ctrl;
+
+ /* Step 2: OT Initializer. */
+ init(o);
+
+ /* Step 3: Glue & Config. */
+ for (j = 0; j < JZ_FB_NR_MAX_FG; j++) {
+ a = &o->config->win_init_config[j];
+
+ /* Win BPP Glue.*/
+ a->bpp = bpp_to_ctrl_bpp(a->bpp);
+
+ /* Load INIT config as first runtime config. */
+ o->config->win_runtime_config[j] = *a;
+ }
+
+ /* Step 4: Collect Max Panel Info. */
+ v = o->config->panel->w;
+ if (info->max_w < v)
+ info->max_w = v;
+
+ v = o->config->panel->h;
+ if (info->max_h < v)
+ info->max_h = v;
+
+ /* Max Win BPP Glue. */
+ v = o->config->max_win_bpp;
+
+ o->config->max_win_bpp = bpp_to_ctrl_bpp(v);
+
+ if (info->max_bpp < v)
+ info->max_bpp = v;
+
+ D("Output: %s ID: %d Current Max w: %u, h: %u, bpp: %u.",
+ o->name, o->id, info->max_w,
+ info->max_h, info->max_bpp);
+
+ I("Found Output: %s, ID: %d.", o->name, o->id);
+ }
+
+ return;
+}
+
+static int jz_fb_ot_load_runtime_config(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_win_info *win;
+ struct jz_fb_win_attr_info *a = ot->config->win_runtime_config;
+
+ int i;
+
+ D("Called.");
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ win = ot->ctrl->win[i];
+ D("Attr: enable: %d, w: %d, h: %d, x: %d, y: %d, bpp: %d.",
+ a->enable, a->w, a->h, a->x, a->y, a->bpp);
+
+ jz_fb_win_set_attr(win, a + i);
+ }
+
+ return 0;
+}
+
+static int jz_fb_ot_set_current(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_ctrl *ctrl = &jz_fb_ctrl;
+ struct jz_fb_win_info *win;
+
+ int i;
+
+ jz_fb_hw_ot_disable(ctrl, 1);
+ jz_fb_hw_ctrl_disable(ctrl, 1);
+ jz_fb_hw_ot_power_off(ctrl, 1);
+
+ ctrl->ot = ot;
+
+ /* Load OT Runtime Config. */
+ jz_fb_ot_load_runtime_config(ot);
+
+ jz_fb_hw_setup(ctrl);
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ win = ctrl->win[i];
+
+ /* Update FB_INFO. */
+ win_fb_info_setup(win);
+ }
+
+ jz_fb_hw_ot_power_on(ctrl, 1);
+ jz_fb_hw_ctrl_enable(ctrl, 1);
+ jz_fb_hw_ot_enable(ctrl, 1);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/core/win.c b/drivers/video/jz475x/core/win.c
new file mode 100644
index 00000000000..26343c4d8f4
--- /dev/null
+++ b/drivers/video/jz475x/core/win.c
@@ -0,0 +1,179 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Foreground Control Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static void update_fb_data_size(struct jz_fb_win_info *win)
+{
+ struct jz_fb_win_attr_info *wa = &win->attr;
+
+ D("Called.");
+
+ D("w: 0x%08x, h: 0x%08x, bpp: 0x%08x.", wa->w, wa->h, wa->bpp);
+
+ win->fb_line_len = dma_align_size(wa->w * bpp_to_data_bpp(wa->bpp) / 8);
+ win->fb_frame_len = win->fb_line_len * wa->h;
+
+ D("win->fb_line_len: 0x%08x, win->fb_frame_len: 0x%08x",
+ win->fb_line_len, win->fb_frame_len);
+ return;
+}
+
+static struct jz_fb_win_info *alloc_win(unsigned int w, unsigned int h, unsigned int bpp)
+{
+ struct jz_fb_win_info *win;
+
+ void *fb_mem;
+
+ unsigned long status = 0;
+
+ int rv;
+
+ D("Called.");
+
+ /* Step 1: FB Info. */
+ win = kzalloc(sizeof(struct jz_fb_win_info) + sizeof(u32) * 16, GFP_KERNEL);
+ if (!win) {
+ E("Failed to allocate framebuffer info.");
+ return NULL;
+ }
+
+ set_bit(0, &status);
+
+ /* Step 2: DMA Palette and Descriptors. */
+ win->misc_mem_start = (void *)__get_free_page(GFP_KERNEL);
+ if (!win->misc_mem_start) {
+ E("Faield to allocate memory for palette and descriptor.");
+ goto err;
+ }
+
+ D("Misc MEM start: Virt: 0x%p, Phys: 0x%08lx.", win->misc_mem_start,
+ virt_to_phys(win->misc_mem_start));
+
+ set_bit(1, &status);
+
+ win->misc_mem_cur = win->misc_mem_start;
+
+ /* Step 3: DMA Palette. */
+ win->dma_palette = win->misc_mem_cur;
+
+ D("DMA Palette MEM Start: Virt: 0x%p, Phys: 0x%08lx.", win->misc_mem_cur,
+ virt_to_phys(win->misc_mem_cur));
+
+ win->misc_mem_cur += dma_align_size(PALETTE_SIZE);
+
+ D("DMA Palette MEM Size: 0x%lx", dma_align_size(PALETTE_SIZE));
+
+ /* Step 4: DMA Descriptor Pool. */
+ D("DMA Descriptor Pool Start: Virt: 0x%p, Phys: 0x%08lx.", win->misc_mem_cur,
+ virt_to_phys(win->misc_mem_cur));
+
+ win->dma_desc_pool = win->misc_mem_cur;
+ win->misc_mem_cur += dma_desc_pool_init(win);
+
+ /* Step 5: Framebuffer. */
+ bpp = bpp_to_data_bpp(bpp);
+
+ win->fb_mem_len = ((w * bpp + 7) >> 3) * h;
+
+ fb_mem = alloc_framebuffer(win->fb_mem_len);
+ if (!fb_mem) {
+ E("Failed to allocate framebuffer.");
+ goto err;
+ }
+
+ D("Framebuffer MEM Block Size: 0x%08x.", win->fb_mem_len);
+
+ set_bit(2, &status);
+
+ rv = add_framebuffer_to_win(win, fb_mem);
+ if (rv) {
+ E("Framebuffer Pool is Full. ");
+ goto err;
+ }
+
+ /* Always set first block as DRV Framebuffer. */
+ set_drv_framebuffer(win, fb_mem);
+
+ rv = alloc_cmap(win, bpp);
+ if (rv) {
+ E("Failed to allocate color map.");
+ goto err;
+ }
+
+ return win;
+
+err:
+ if (test_bit(2, &status))
+ free_framebuffer(win);
+
+ if (test_bit(1, &status))
+ __free_page(win->misc_mem_start);
+
+ if (test_bit(0, &status))
+ kfree(win);
+
+ return NULL;
+}
+
+static void free_win(struct jz_fb_win_info *win)
+{
+ int i;
+
+ D("Called.");
+
+ /* Free all framebuffers in WIN. */
+ for (i = 0; i < JZ_FB_NR_MAX_FB_MEM; i++) {
+ if (win->fb_mem[i]) {
+ free_framebuffer(win->fb_mem[i]);
+ }
+ }
+
+ /* Free color maps. */
+ free_cmap(win);
+
+ /* Free Misc Memory. */
+ __free_page(win->misc_mem_start);
+
+ /* Free Win. */
+ kfree(win);
+
+ return;
+}
+
+static int jz_fb_win_set_attr(struct jz_fb_win_info *win, struct jz_fb_win_attr_info *attr)
+{
+ D("Called.");
+
+ memcpy(&win->attr, attr, sizeof(struct jz_fb_win_attr_info));
+
+ update_fb_data_size(win);
+
+ return 0;
+}
+
+static inline int jz_fb_win_active_attr(struct jz_fb_win_info *win)
+{
+ D("Called.");
+
+ /* Not implentmend yet. */
+ return 0;
+}
diff --git a/drivers/video/jz475x/drv/ctrl-drv.c b/drivers/video/jz475x/drv/ctrl-drv.c
new file mode 100644
index 00000000000..06ee49b4da8
--- /dev/null
+++ b/drivers/video/jz475x/drv/ctrl-drv.c
@@ -0,0 +1,122 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Control Driver.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#define CTRL_DRV_POSTFIX "-ctrl"
+
+static inline struct jz_fb_ot_info *minor_to_ot(int minor)
+{
+ struct jz_fb_ot_info *ot;
+
+ unsigned int i;
+
+ D("Called.");
+
+ for (i = 0; i < sizeof(jz_fb_ots) / sizeof(struct jz_fb_ot_info *); i++) {
+ ot = jz_fb_ots[i];
+ if (ot->miscdev->minor == minor) {
+ D("Output: %s is located.", ot->name);
+ return ot;
+ }
+ }
+
+ return NULL;
+}
+
+static int ctrl_drv_ioctl(struct inode *inode,
+ struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct jz_fb_ot_info *ot;
+
+ int rv;
+
+ D("Called.");
+
+ ot = minor_to_ot(iminor(inode));
+ if (!ot) {
+ E("Miscdevice (minor: %d) not found.", iminor(inode));
+ return -ENODEV;
+ }
+
+ mutex_lock(&ot->ctrl_drv_lock);
+
+ /* Dispatch control to specific output. */
+ rv = ot->ops->control(ot, (void __user *)arg);
+
+ mutex_unlock(&ot->ctrl_drv_lock);
+
+ return rv;
+}
+
+static const struct file_operations ctrl_drv_misc_fops = {
+ .ioctl = ctrl_drv_ioctl,
+};
+
+static int ctrl_drv_setup(struct jz_fb_ot_info *ot)
+{
+ struct miscdevice *dev;
+
+ void *mem;
+
+ size_t size;
+
+ int rv;
+
+ mutex_init(&ot->ctrl_drv_lock);
+
+ size = sizeof(struct miscdevice) + sizeof(ot->name) + sizeof(CTRL_DRV_POSTFIX);
+
+ mem = kzalloc(size, GFP_KERNEL);
+ if (!mem) {
+ return -ENOMEM;
+ }
+
+ dev = mem;
+ dev->name = mem + sizeof(struct miscdevice);
+
+ /* Control Path Name. */
+ strcpy((char *)dev->name, ot->name);
+ strcat((char *)dev->name, CTRL_DRV_POSTFIX);
+
+ dev->minor = MISC_DYNAMIC_MINOR;
+ dev->fops = &ctrl_drv_misc_fops;
+
+ rv = misc_register(dev);
+ if (rv) {
+ kfree(dev);
+ return rv;
+ }
+
+ ot->miscdev = dev;
+
+ I("Create Control Path: %s, minor: %d.", dev->name, dev->minor);
+
+ return 0;
+}
+
+static int ctrl_drv_cleanup(struct jz_fb_ot_info *ot)
+{
+ misc_deregister(ot->miscdev);
+ kfree(ot->miscdev);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/drv/fb-drv.c b/drivers/video/jz475x/drv/fb-drv.c
new file mode 100644
index 00000000000..22ce518e85e
--- /dev/null
+++ b/drivers/video/jz475x/drv/fb-drv.c
@@ -0,0 +1,303 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Linux Framebuffer Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int jz_fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct jz_fb_win_info *win = container_of(info, struct jz_fb_win_info, fb);
+ struct jz_fb_panel_info *panel = win->ctrl->ot->config->panel;
+
+ unsigned short *ptr, ctmp;
+
+#if 0 /* REVISIT. */
+ if (regno >= NR_PALETTE)
+ return 1;
+#endif
+
+ if (info->var.bits_per_pixel <= 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ red &= 0xff;
+ green &= 0xff;
+ blue &= 0xff;
+ }
+
+ switch (info->var.bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (((panel->lcd_cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_SINGLE_MSTN ) ||
+ ((panel->lcd_cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_DUAL_MSTN )) {
+ ctmp = (77L * red + 150L * green + 29L * blue) >> 8;
+ ctmp = ((ctmp >> 3) << 11) | ((ctmp >> 2) << 5) |
+ (ctmp >> 3);
+ } else {
+ /* RGB 565 */
+ if (((red >> 3) == 0) && ((red >> 2) != 0))
+ red = 1 << 3;
+ if (((blue >> 3) == 0) && ((blue >> 2) != 0))
+ blue = 1 << 3;
+ ctmp = ((red >> 3) << 11)
+ | ((green >> 2) << 5) | (blue >> 3);
+ }
+
+ ptr = (unsigned short *)win->dma_palette;
+ ptr = (unsigned short *)(((u32)ptr)|0xa0000000);
+ ptr[regno] = ctmp;
+
+ break;
+
+ case 15:
+ if (regno < 16)
+ ((u32 *)info->pseudo_palette)[regno] =
+ ((red >> 3) << 10) |
+ ((green >> 3) << 5) |
+ (blue >> 3);
+ break;
+ case 16:
+ if (regno < 16) {
+ ((u32 *)info->pseudo_palette)[regno] =
+ ((red >> 3) << 11) |
+ ((green >> 2) << 5) |
+ (blue >> 3);
+ }
+ break;
+ case 17 ... 32:
+ if (regno < 16)
+ ((u32 *)info->pseudo_palette)[regno] =
+ (red << 16) |
+ (green << 8) |
+ (blue << 0);
+ break;
+ }
+
+ return 0;
+}
+
+static int jz_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ unsigned long start;
+ unsigned long off;
+ u32 len;
+
+ D("Called.");
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+
+ /* frame buffer memory */
+ start = info->fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
+ start &= PAGE_MASK;
+
+ if ((vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Uncacheable */
+
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+static int jz_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ D("Called.");
+
+ return 0;
+}
+
+static int jz_fb_set_par(struct fb_info *info)
+{
+ D("Called.");
+
+ return 0;
+}
+
+static int jz_fb_blank(int blank_mode, struct fb_info *info)
+{
+ struct jz_fb_ctrl *ctrl = &jz_fb_ctrl;
+
+ D("Called.");
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ jz_fb_hw_ot_power_on(ctrl, 1);
+ jz_fb_hw_ctrl_enable(ctrl, 1);
+ jz_fb_hw_ot_enable(ctrl, 1);
+
+ break;
+
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ jz_fb_hw_ot_disable(ctrl, 1);
+ jz_fb_hw_ctrl_disable(ctrl, 1);
+ jz_fb_hw_ot_power_off(ctrl, 1);
+
+
+ break;
+
+ default:
+ E("Unsupport blank mode.");
+ break;
+
+ }
+
+ return 0;
+}
+
+static int jz_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ D("Called.");
+
+ return 0;
+}
+
+/* use default function cfb_fillrect, cfb_copyarea, cfb_imageblit */
+static struct fb_ops jz_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = jz_fb_setcolreg,
+ .fb_check_var = jz_fb_check_var,
+ .fb_set_par = jz_fb_set_par,
+ .fb_blank = jz_fb_blank,
+ .fb_pan_display = jz_fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = jz_fb_mmap,
+};
+
+static irqreturn_t jz_fb_interrupt_handler(int irq, void *dev_id)
+{
+ unsigned int state;
+ static int irqcnt=0;
+
+ state = REG_LCD_STATE;
+ D("In the lcd interrupt handler, state=0x%x", state);
+
+ if (state & LCD_STATE_EOF) /* End of frame */
+ REG_LCD_STATE = state & ~LCD_STATE_EOF;
+
+ if (state & LCD_STATE_IFU0) {
+ printk("%s, InFiFo0 underrun\n", __FUNCTION__);
+ REG_LCD_STATE = state & ~LCD_STATE_IFU0;
+ }
+
+ if (state & LCD_STATE_IFU1) {
+ printk("%s, InFiFo1 underrun\n", __FUNCTION__);
+ REG_LCD_STATE = state & ~LCD_STATE_IFU1;
+ }
+
+ if (state & LCD_STATE_OFU) { /* Out fifo underrun */
+ REG_LCD_STATE = state & ~LCD_STATE_OFU;
+ if ( irqcnt++ > 100 ) {
+ __lcd_disable_ofu_intr();
+ printk("disable Out FiFo underrun irq.\n");
+ }
+ printk("%s, Out FiFo underrun.\n", __FUNCTION__);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * Suspend the LCDC.
+ */
+static int jz_fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct jz_fb_ctrl *ctrl = &jz_fb_ctrl;
+
+ D("Called.");
+
+ jz_fb_hw_ot_disable(ctrl, 1);
+ jz_fb_hw_ctrl_disable(ctrl, 1);
+ jz_fb_hw_ot_power_off(ctrl, 1);
+
+ return 0;
+}
+
+/*
+ * Resume the LCDC.
+ */
+static int jz_fb_resume(struct platform_device *pdev)
+{
+ struct jz_fb_ctrl *ctrl = &jz_fb_ctrl;
+
+ D("Called.");
+
+ jz_fb_hw_ot_power_on(ctrl, 1);
+ jz_fb_hw_ctrl_enable(ctrl, 1);
+ jz_fb_hw_ot_enable(ctrl, 1);
+
+ return 0;
+}
+
+#else
+#define jzfb_suspend NULL
+#define jzfb_resume NULL
+#endif /* CONFIG_PM */
+
+static int fb_drv_setup(struct jz_fb_win_info *win)
+{
+ int rv;
+
+ dump_fb_info_fix(&win->fb.fix);
+ dump_fb_info_var(&win->fb.var);
+
+ rv = register_framebuffer(&win->fb);
+ if (rv) {
+ E("Failed to register Linux Framebuferr Driver.");
+ return rv;
+ }
+
+ return rv;
+}
+
+static int fb_drv_cleanup(struct jz_fb_win_info *win)
+{
+ return 0;
+}
+
diff --git a/drivers/video/jz475x/jz-fb.c b/drivers/video/jz475x/jz-fb.c
new file mode 100644
index 00000000000..4e2db7418f2
--- /dev/null
+++ b/drivers/video/jz475x/jz-fb.c
@@ -0,0 +1,305 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original version:
+ * Author: Wolfgang Wang, Lemon Liu, Emily Feng.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/jzsoc.h>
+
+#include "jz-fb.h"
+
+#define DRV_NAME "jz-fb"
+#define DRV_VERSION "V0.1"
+
+static int default_output_id = 0;
+
+static struct jz_fb_ctrl jz_fb_ctrl;
+
+/* ----------------- COMMON Routines ---------------------- */
+#include "common.c"
+/* -------------------------------------------------------- */
+
+/* ----------------- OUTPUT Config ------------------------ */
+#include "output/config.c"
+/* -------------------------------------------------------- */
+
+/* ------------------ Core Function Block. ---------------- */
+#include "core/desc.c"
+#include "core/hw.c"
+#include "core/framebuffer.c"
+#include "core/win.c"
+#include "core/ot.c"
+/* -------------------------------------------------------- */
+
+/* ------------------ OUTPUT ------------------------------ */
+#include "output/output.c"
+/* -------------------------------------------------------- */
+
+/* ---------------- Driver Interface. --------------------- */
+#include "drv/fb-drv.c"
+#include "drv/ctrl-drv.c"
+/* -------------------------------------------------------- */
+
+static struct jz_fb_ot_info *id_to_ot(int id)
+{
+ int i;
+
+ for (i = 0; i < sizeof(jz_fb_ots) / sizeof(struct jz_fb_ot_info *); i++) {
+ if (jz_fb_ots[i]->id == id)
+ return jz_fb_ots[i];
+ }
+
+ return NULL;
+}
+
+static int jz_fb_drv_alloc(struct jz_fb_ctrl *ctrl,
+ struct jz_fb_ot_scan_info *scan)
+{
+ struct jz_fb_win_info *win;
+
+ int i;
+
+ int rv = 0;
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ win = alloc_win(scan->max_w,
+ scan->max_h, scan->max_bpp);
+
+ if (!win) {
+ E("Failed to allocate win info for FG %d.", i);
+ rv = -ENOMEM;
+
+ break;
+ }
+
+ win->index = i;
+ win->ctrl = ctrl;
+
+ ctrl->win[i] = win;
+ }
+
+ D("Called.");
+
+ if (rv) {
+ while (--i >= 0) {
+ if (ctrl->win[i])
+ free_win(ctrl->win[i]);
+ }
+
+ return rv;
+ }
+
+ return 0;
+}
+
+static int jz_fb_drv_free(struct jz_fb_ctrl *ctrl)
+{
+ int i;
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ if (ctrl->win[i])
+ free_win(ctrl->win[i]);
+ }
+
+ return 0;
+}
+
+static int jz_fb_drv_setup(struct jz_fb_ctrl *ctrl)
+{
+ int rv;
+
+ int i;
+
+ /* Setup Linux Framebuffer Driver for every window. */
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ if (ctrl->win) {
+ rv = fb_drv_setup(ctrl->win[i]);
+ if (rv) {
+ return rv;
+ }
+ }
+ }
+
+ /* Setup Control Driver for every output path. */
+ for (i = 0; i < sizeof(jz_fb_ots) / sizeof(struct jz_fb_ot_info *); i++) {
+ rv = ctrl_drv_setup(jz_fb_ots[i]);
+ if (rv) {
+ return rv;
+ }
+ }
+
+ return 0;
+}
+
+static int jz_fb_drv_cleanup(struct jz_fb_ctrl *ctrl)
+{
+ int rv;
+
+ int i;
+
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++) {
+ if (ctrl->win) {
+ rv = fb_drv_cleanup(ctrl->win[i]);
+ if (rv) {
+ return rv;
+ }
+ }
+ }
+
+ for (i = 0; i < sizeof(jz_fb_ots) / sizeof(struct jz_fb_ot_info *); i++) {
+ rv = ctrl_drv_cleanup(jz_fb_ots[i]);
+ if (rv) {
+ return rv;
+ }
+ }
+
+
+ return 0;
+}
+
+static int __devinit jz_fb_probe(struct platform_device *dev)
+{
+ struct jz_fb_ctrl *ctrl = &jz_fb_ctrl;
+ struct jz_fb_ot_scan_info scan;
+
+ unsigned long status = 0;
+
+ int rv = 0;
+
+ /* 1. Scan & Initialize All Outputs. */
+ jz_fb_ot_scan(ctrl, &scan);
+
+ D("Final: Max: w: %u, h: %u, bpp: %u.", scan.max_w, scan.max_h, scan.max_bpp);
+
+ /* 2. Locate the default OT. */
+ ctrl->ot = id_to_ot(default_output_id);
+ if (!ctrl->ot) {
+ E("Default Output not found: ID: %d.\n", default_output_id);
+ return rv;
+ }
+
+ /* 3. All allocations. */
+ rv = jz_fb_drv_alloc(ctrl, &scan);
+ if (rv) {
+ E("Failed to allocate FB Driver Layer.");
+ return rv;
+ }
+
+ set_bit(0, &status);
+
+ /* 4. Select OT & Init HW & FB_INFO. */
+ jz_fb_ot_set_current(ctrl->ot);
+
+ if (request_irq(IRQ_LCD, jz_fb_interrupt_handler, IRQF_DISABLED,
+ DRV_NAME, 0)) {
+ E("Failed to request LCDC IRQ.");
+ rv = -EBUSY;
+ goto err;
+ }
+
+ set_bit(1, &status);
+
+ /* 5. DRV Layer Setup. */
+ rv = jz_fb_drv_setup(ctrl);
+ if (rv) {
+ E("Failed to setup DRV layer.");
+ goto err;
+ }
+
+ I("Registered.");
+
+ return rv;
+
+err:
+ if (test_bit(0, &status)) {
+ jz_fb_drv_free(ctrl);
+ }
+
+ if (test_bit(1, &status)) {
+ jz_fb_hw_ot_disable(ctrl, 1);
+ jz_fb_hw_ctrl_disable(ctrl, 1);
+ jz_fb_hw_ot_power_off(ctrl, 1);
+
+ free_irq(IRQ_LCD, DRV_NAME);
+ }
+
+ return rv;
+}
+
+static int __devexit jz_fb_remove(struct platform_device *pdev)
+{
+ struct jz_fb_ctrl *ctrl= &jz_fb_ctrl;
+
+ jz_fb_hw_ot_disable(ctrl, 1);
+ jz_fb_hw_ctrl_disable(ctrl, 1);
+ jz_fb_hw_ot_power_off(ctrl, 1);
+
+ free_irq(IRQ_LCD, DRV_NAME);
+
+ jz_fb_drv_cleanup(ctrl);
+ jz_fb_drv_free(ctrl);
+
+ return 0;
+}
+
+static struct platform_driver jz_fb_driver = {
+ .probe = jz_fb_probe,
+ .remove = jz_fb_remove,
+ .suspend = jz_fb_suspend,
+ .resume = jz_fb_resume,
+ .driver = {
+ .name = "jz-lcd",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init jz_fb_init(void)
+{
+ return platform_driver_register(&jz_fb_driver);
+}
+
+static void __exit jz_fb_cleanup(void)
+{
+ platform_driver_unregister(&jz_fb_driver);
+}
+
+module_init(jz_fb_init);
+module_exit(jz_fb_cleanup);
diff --git a/drivers/video/jz475x/jz-fb.h b/drivers/video/jz475x/jz-fb.h
new file mode 100644
index 00000000000..9de42c7f626
--- /dev/null
+++ b/drivers/video/jz475x/jz-fb.h
@@ -0,0 +1,237 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifndef __JZ_FB_H__
+#define __JZ_FB_H__
+
+#include <linux/miscdevice.h>
+
+#include "config.h"
+#include "abi.h"
+
+#define NR_PALETTE 256
+#define PALETTE_SIZE (NR_PALETTE * 2)
+
+#define HW_AREA_POS(x, y) ( y << 16 | x)
+#define HW_AREA_SIZE(w, h) ( h << 16 | w)
+
+/* For 8 word DMA Descriptor. */
+#ifdef JZ_FB_8WORD_DMA_DESC
+struct jz_lcdc_8word_dma_desc {
+ uint32_t next_desc; /* LCDDAx */
+ uint32_t databuf; /* LCDSAx */
+ uint32_t frame_id; /* LCDFIDx */
+ uint32_t cmd; /* LCDCMDx */
+ uint32_t offsize; /* Stride Offsize(in word) */
+ uint32_t page_width; /* Stride Pagewidth(in word) */
+ uint32_t cmd_num; /* Command Number(for SLCD) */
+ uint32_t desc_size; /* Foreground Size */
+};
+
+typedef struct jz_lcdc_8word_dma_desc dma_desc_t;
+#endif
+
+/* For 4 word DMA Descriptor. */
+#ifdef JZ_FB_4WORD_DMA_DESC
+struct jz_lcdc_4word_dma_desc {
+ unsigned int next_desc; /* LCDDAx */
+ unsigned int databuf; /* LCDSAx */
+ unsigned int frame_id; /* LCDFIDx */
+ unsigned int cmd; /* LCDCMDx */
+};
+
+typedef struct jz_lcdc_4word_dma_desc dma_desc_t;
+#endif
+
+struct jz_fb_ot_info;
+struct jz_fb_win_info;
+
+struct jz_fb_dma_desc {
+ dma_desc_t hw_desc;
+
+ int index;
+ int use;
+ void *mem;
+
+ struct jz_fb_win_info *win;
+ struct list_head list;
+ struct list_head group;
+};
+
+struct jz_fb_panel_ops {
+ int (*normal)(struct jz_fb_ot_info *ot);
+ int (*idle)(struct jz_fb_ot_info *ot);
+ int (*on)(struct jz_fb_ot_info *ot);
+ int (*off)(struct jz_fb_ot_info *ot);
+ int (*get_backlight)(struct jz_fb_ot_info *ot);
+ int (*set_backlight)(struct jz_fb_ot_info *ot, int value);
+};
+
+struct jz_fb_panel_info {
+ unsigned long lcd_ctrl; /* panel mode and pin usage etc. */
+ unsigned long lcd_cfg; /* panel mode and pin usage etc. */
+ unsigned int w; /* Panel Width(in pixel) */
+ unsigned int h; /* Panel Height(in line) */
+ unsigned int fclk; /* frame clk */
+ unsigned int hsw; /* hsync width, in pclk */
+ unsigned int vsw; /* vsync width, in line count */
+ unsigned int elw; /* end of line, in pclk */
+ unsigned int blw; /* begin of line, in pclk */
+ unsigned int efw; /* end of frame, in line count */
+ unsigned int bfw; /* begin of frame, in line count */
+};
+
+struct jz_fb_panel_config {
+ struct jz_fb_panel_ops *ops;
+ struct jz_fb_panel_info *panel;
+
+ struct jz_fb_win_attr_info win_runtime_config[JZ_FB_NR_MAX_FG];
+
+ /* For Panel Private Routines. */
+ void *priv;
+
+ struct jz_fb_win_attr_info *win_init_config;
+
+ unsigned int enable_delay_ms;
+
+ int backlight;
+ int use_palette;
+ unsigned int background_color;
+ unsigned int max_win_bpp;
+};
+
+struct jz_fb_reg_info {
+ /* Used to config specified function block's register. */
+ unsigned long flags;
+
+ unsigned long lcd_cfg;
+ unsigned long lcd_ctrl;
+ unsigned long lcd_osdc;
+ unsigned long lcd_osdctrl;
+ unsigned long lcd_bgc;
+ unsigned long lcd_key0;
+ unsigned long lcd_key1;
+ unsigned long lcd_alpha;
+ unsigned long lcd_ipur;
+ unsigned long lcd_rgbc;
+ unsigned long lcd_vat;
+ unsigned long lcd_dah;
+ unsigned long lcd_dav;
+ unsigned long lcd_xyp0;
+ unsigned long lcd_xyp1;
+ unsigned long lcd_size0;
+ unsigned long lcd_size1;
+ unsigned long lcd_vsync;
+ unsigned long lcd_hsync;
+ unsigned long lcd_ps;
+ unsigned long lcd_rev;
+ unsigned long lcd_da0;
+ unsigned long lcd_da1;
+};
+
+struct jz_fb_ot_ops {
+ void (*enable)(struct jz_fb_ot_info *);
+ void (*disable)(struct jz_fb_ot_info *);
+ void (*start)(struct jz_fb_ot_info *);
+ void (*stop)(struct jz_fb_ot_info *);
+ int (*control)(struct jz_fb_ot_info *, void *);
+};
+
+struct jz_fb_ot_desc_ops {
+ int (*setup)(struct jz_fb_win_info *);
+ void (*cleanup)(struct jz_fb_win_info *);
+ int (*attach)(struct jz_fb_win_info *, void *);
+ int (*detach)(struct jz_fb_win_info *, void *);
+};
+
+struct jz_fb_ot_info {
+ char *name;
+ int id;
+
+ int state;
+ int power;
+
+ int use_quick_disable;
+ int use_tve;
+ int use_rgb_to_yuv;
+
+ struct jz_fb_ot_ops *ops;
+ struct jz_fb_ot_desc_ops *desc_ops;
+ struct jz_fb_panel_config *config;
+
+ struct jz_fb_reg_info reg_info;
+
+ struct mutex ctrl_drv_lock;
+ struct miscdevice *miscdev;
+
+ struct jz_fb_ctrl *ctrl;
+};
+
+struct jz_fb_ctrl;
+
+#define WIN_X(win) (win->attr.x)
+#define WIN_Y(win) (win->attr.y)
+
+#define WIN_W(win) (win->attr.w)
+#define WIN_H(win) (win->attr.h)
+
+#define WIN_BPP(win) (win->attr.bpp)
+
+struct jz_fb_win_info {
+ int index;
+
+ struct jz_fb_win_attr_info attr;
+
+ struct fb_info fb;
+
+ /* DMA Descriptor Pool. */
+ struct jz_fb_dma_desc *dma_desc[JZ_FB_NR_MAX_DMA_DESC];
+ struct jz_fb_dma_desc *dma_desc_data_start;
+ struct jz_fb_dma_desc *dma_desc_last_no_data;
+
+ void *dma_desc_pool;
+
+ /* Framebuffer Pool. */
+ void *fb_mem[JZ_FB_NR_MAX_FB_MEM];
+ unsigned int fb_mem_len; /* Framebuffer Block Size. */
+
+ /* Runtime WIN data size. */
+ unsigned int fb_line_len;
+ unsigned int fb_frame_len;
+
+ void *dma_palette;
+
+ void *misc_mem_start;
+ void *misc_mem_cur;
+
+ struct jz_fb_ctrl *ctrl;
+};
+
+struct jz_fb_ctrl {
+ int state;
+
+ unsigned int pixclock;
+
+ struct jz_fb_ot_info *ot;
+ struct jz_fb_win_info *win[JZ_FB_NR_MAX_FG];
+};
+
+#endif /* __JZ_FB_H__ */
diff --git a/drivers/video/jz475x/output/config.c b/drivers/video/jz475x/output/config.c
new file mode 100644
index 00000000000..fe15ba3cb5c
--- /dev/null
+++ b/drivers/video/jz475x/output/config.c
@@ -0,0 +1,75 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Output Config.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifdef CONFIG_FB_JZ475X_LCD_OUTPUT
+static struct jz_fb_ot_info jz_fb_lcd_ot_info;
+
+static int lcd_output_init(struct jz_fb_ot_info *);
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_PAL_OUTPUT
+static struct jz_fb_ot_info jz_fb_tve_pal_ot_info;
+
+static int tve_pal_output_init(struct jz_fb_ot_info *);
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT
+static struct jz_fb_ot_info jz_fb_tve_ntsc_ot_info;
+
+static int tve_ntsc_output_init(struct jz_fb_ot_info *);
+#endif
+
+static struct jz_fb_ot_info *jz_fb_ots [] = {
+
+#ifdef CONFIG_FB_JZ475X_LCD_OUTPUT
+ &jz_fb_lcd_ot_info,
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_PAL_OUTPUT
+ &jz_fb_tve_pal_ot_info,
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT
+ &jz_fb_tve_ntsc_ot_info,
+#endif
+
+};
+
+typedef int jz_fb_ot_init_t(struct jz_fb_ot_info *);
+
+static jz_fb_ot_init_t *jz_fb_ot_inits [] = {
+
+#ifdef CONFIG_FB_JZ475X_LCD_OUTPUT
+ &lcd_output_init,
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_PAL_OUTPUT
+ &tve_pal_output_init,
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT
+ &tve_ntsc_output_init,
+#endif
+
+};
+
diff --git a/drivers/video/jz475x/output/control.c b/drivers/video/jz475x/output/control.c
new file mode 100644
index 00000000000..f88b81d7547
--- /dev/null
+++ b/drivers/video/jz475x/output/control.c
@@ -0,0 +1,100 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Output Common Control Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+/* Handle Common Controls. */
+static int do_ot_common_control(struct jz_fb_ot_info *ot,
+ struct jz_fb_common_control *c, void __user *p)
+{
+ int rv = 0;
+
+ int i;
+
+ switch (c->command) {
+ case JZ_FB_CMD_COMMON_GET_STATE:
+ c->v = 0;
+
+ if (ot->power)
+ c->v |= JZ_FB_CMD_COMMON_STATE_OT_POWER;
+
+ if (ot->state)
+ c->v |= JZ_FB_CMD_COMMON_STATE_OT_ENABLE;
+
+ if (ot->ctrl->state)
+ c->v |= JZ_FB_CMD_COMMON_STATE_CTRL_ENABLE;
+
+ if (copy_to_user(p, c, sizeof(struct jz_fb_common_control)))
+ rv = -EFAULT;
+
+ break;
+
+ case JZ_FB_CMD_COMMON_SET_POWER:
+ if (c->v) {
+ jz_fb_hw_ot_power_on(ot->ctrl, 0);
+ }else{
+ jz_fb_hw_ot_power_off(ot->ctrl, 0);
+ }
+
+ break;
+
+ case JZ_FB_CMD_COMMON_SET_SCREEN:
+ if (c->v) {
+ jz_fb_hw_ot_enable(ot->ctrl, 0);
+ }else{
+ jz_fb_hw_ot_disable(ot->ctrl, 0);
+ }
+
+ break;
+
+ case JZ_FB_CMD_COMMON_GET_WIN_ATTR:
+ memcpy(c->win_attr, ot->config->win_runtime_config, sizeof(c->win_attr));
+ if (copy_to_user(p, c, sizeof(struct jz_fb_common_control)))
+ rv = -EFAULT;
+
+ break;
+
+ case JZ_FB_CMD_COMMON_SET_WIN_ATTR:
+ memcpy(ot->config->win_runtime_config, c->win_attr, sizeof(c->win_attr));
+ /* OT WIN Runtime CONFIG -> Current WIN Attr.
+ This allow each OT having its own Runtime ATTR.
+ */
+
+ jz_fb_ot_load_runtime_config(ot);
+
+ if (c->active_now) {
+ for (i = 0; i < JZ_FB_NR_MAX_FG; i++)
+ jz_fb_win_active_attr(ot->ctrl->win[i]);
+ }
+
+ /* Attr will be actived when OT is re-selected. */
+ break;
+
+ case JZ_FB_CMD_COMMON_SELECT_OT:
+ rv = jz_fb_ot_set_current(ot);
+
+ break;
+
+ }
+
+ return rv;
+}
+
diff --git a/drivers/video/jz475x/output/lcd/auo-a043fl01v2.c b/drivers/video/jz475x/output/lcd/auo-a043fl01v2.c
new file mode 100644
index 00000000000..1f352f080a6
--- /dev/null
+++ b/drivers/video/jz475x/output/lcd/auo-a043fl01v2.c
@@ -0,0 +1,169 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * LCD PANEL: AUO A043FL01V2 on APUS / CETUS Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifdef CONFIG_FB_JZ475X_LCD_PANEL_AUO_A043FL01V2
+static struct jz_fb_panel_info auo_panel_info = {
+ .lcd_ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16,
+ .lcd_cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER /* Underrun recover */
+
+ /* ---------------- CUSTOM: Modify these by your panel. -----------*/
+ | LCD_CFG_MODE_GENERIC_TFT /* General TFT panel */
+ | LCD_CFG_MODE_TFT_24BIT /* output 18bpp */
+ | LCD_CFG_HSP /* Hsync polarity: active low */
+ | LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ 480, 272, 60, 41, 10, 8, 4, 4, 2,
+ /* --------------------------------------------------------------- */
+};
+
+/* ------ CUSTOM: Modify these by your board. --------- */
+/* Get Backlight Level. */
+static int auo_panel_get_backlight(struct jz_fb_ot_info *ot)
+{
+ D("Called.");
+
+ return ot->config->backlight;
+}
+
+/* Set Backlight & PWM. */
+static int auo_panel_set_backlight(struct jz_fb_ot_info *ot, int backlight)
+{
+ D("Called.");
+
+ ot->config->backlight = backlight;
+
+ return 0;
+}
+
+/*
+ For Display ON / OFF.
+ Enablie / Disable Backlight / PWM Here.
+*/
+static int auo_panel_on(struct jz_fb_ot_info *ot)
+{
+ D("Called.");
+
+ __gpio_set_pin(GPIO_LCD_PWM);
+ __gpio_as_output(GPIO_LCD_PWM);
+
+ return 0;
+}
+
+static int auo_panel_off(struct jz_fb_ot_info *ot)
+{
+ D("Called.");
+
+ __gpio_clear_pin(GPIO_LCD_PWM);
+ __gpio_as_output(GPIO_LCD_PWM);
+
+ return 0;
+}
+
+/*
+ For PM / Init Routines.
+ Set GPIO Pins to normal/idle state.
+ Enable / Disable VCC_EN/PWM etc..
+ */
+
+static int auo_panel_normal(struct jz_fb_ot_info *ot)
+{
+ D("Called.");
+
+ __gpio_as_lcd_24bit();
+
+#ifdef CONFIG_JZ4750_APUS
+ __gpio_clear_pin(GPIO_LCD_VCC_EN_N);
+#endif
+
+#ifdef CONFIG_JZ4750D_CETUS
+ __gpio_set_pin(GPIO_LCD_VCC_EN_N);
+#endif
+
+ __gpio_as_output(GPIO_LCD_VCC_EN_N);
+
+ return 0;
+}
+
+static int auo_panel_idle(struct jz_fb_ot_info *ot)
+{
+ D("Called.");
+
+#ifdef CONFIG_JZ4750_APUS
+ __gpio_set_pin(GPIO_LCD_VCC_EN_N);
+#endif
+
+#ifdef CONFIG_JZ4750D_CETUS
+ __gpio_clear_pin(GPIO_LCD_VCC_EN_N);
+#endif
+ __gpio_as_output(GPIO_LCD_VCC_EN_N);
+
+ return 0;
+}
+/* ---------------------------------------------------------- */
+
+static struct jz_fb_panel_ops auo_panel_ops = {
+ .get_backlight = auo_panel_get_backlight,
+ .set_backlight = auo_panel_set_backlight,
+
+ .normal = auo_panel_normal,
+ .idle = auo_panel_idle,
+
+ .on = auo_panel_on,
+ .off = auo_panel_off,
+};
+
+/* ------------ CUSTOM: Modify these by your need. ----------- */
+struct jz_fb_win_attr_info auo_win_init_config[] = {
+ [0] = {
+ .enable = 1,
+ .x = 0,
+ .y = 0,
+ .w = 480,
+ .h = 272,
+ .bpp = 32,
+ },
+ [1] = {
+ .enable = 1,
+ .x = 0,
+ .y = 0,
+ .w = 480,
+ .h = 272,
+ .bpp = 32,
+ },
+};
+/* ----------------------------------------------------------- */
+
+struct jz_fb_panel_config lcd_output_panel_config = {
+ .ops = &auo_panel_ops,
+ .panel = &auo_panel_info,
+ .win_init_config = auo_win_init_config,
+
+/* -------------- CUSTOM: Modify these by your need. --------- */
+ .enable_delay_ms = 80, /* Delay in ms before backlight is enabled. */
+ .backlight = 80,
+ .use_palette = 0,
+ .max_win_bpp = 32,
+ .background_color = 0x000000FF,
+/* ----------------------------------------------------------- */
+};
+
+#endif /* Define CONFIG_FB_JZ475X_LCD_PANEL_AUO_A043FL01V2 */
diff --git a/drivers/video/jz475x/output/lcd/lcd-control.c b/drivers/video/jz475x/output/lcd/lcd-control.c
new file mode 100644
index 00000000000..bef78bafbf5
--- /dev/null
+++ b/drivers/video/jz475x/output/lcd/lcd-control.c
@@ -0,0 +1,73 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * LCD Output Specific Control Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static int lcd_output_control(struct jz_fb_ot_info *ot,
+ void __user *p)
+{
+ struct jz_fb_panel_config *config = ot->config;
+
+ struct jz_fb_lcd_control lc;
+ struct jz_fb_common_control *c;
+
+ int rv = 0;
+
+ if (copy_from_user(&lc, p, sizeof(struct jz_fb_lcd_control))) {
+ E("Failed to do copy_from_user.\n");
+ return -EFAULT;
+ }
+
+ c = &lc.common;
+
+ /* Check Output ID - Prevent Userspace APP walk the error path. */
+ if (c->id != ot->id) {
+ E("Bad Output ID for LCD Path: %s.", ot->miscdev->name);
+ return -EINVAL;
+ }
+
+ switch (c->command) {
+ case JZ_FB_CMD_LCD_GET_BACKLIGHT:
+ c->v = config->ops->get_backlight(ot);
+
+ D("Get Backlight: Value: %d.", c->v);
+
+ if (copy_to_user(p, &lc, sizeof(struct jz_fb_lcd_control))) {
+ E("Failed to do copy_to_user.\n");
+ return -EFAULT;
+ }
+
+ break;
+
+ case JZ_FB_CMD_LCD_SET_BACKLIGHT:
+ D("Set Backlight: Value: %d.", c->v);
+
+ rv = config->ops->set_backlight(ot, c->v);
+ break;
+
+ default:
+ rv = do_ot_common_control(ot, c, p);
+ break;
+ }
+
+ return rv;
+}
+
diff --git a/drivers/video/jz475x/output/lcd/lcd-output.c b/drivers/video/jz475x/output/lcd/lcd-output.c
new file mode 100644
index 00000000000..b591b03622a
--- /dev/null
+++ b/drivers/video/jz475x/output/lcd/lcd-output.c
@@ -0,0 +1,193 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * LCD Output Main Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifdef CONFIG_FB_JZ475X_LCD_OUTPUT
+
+/* -------- CUSTOM: Add your specific panel here. ----------- */
+#include "auo-a043fl01v2.c"
+/* ---------------------------------------------------------- */
+
+static int lcd_output_desc_setup(struct jz_fb_win_info *win)
+{
+ struct jz_fb_panel_config *c = win->ctrl->ot->config;
+ struct jz_fb_dma_desc *desc;
+
+ D("Called.");
+
+ /* Setup DMA Palette Descriptor. */
+ if (c->use_palette && win->index == 0) { /* Palette cannot be used on FG1. */
+ unsigned long palette_size =
+ jz_fb_hw_bpp_to_palette_size(win->attr.bpp);
+
+ D("Use Palette.");
+
+ desc = dma_desc_get(win);
+ if (!desc) {
+ return -ENOMEM;
+ }
+
+ dma_desc_init(desc);
+
+ dma_desc_set_mem(desc, win->dma_palette);
+ dma_desc_set_data_size(desc, palette_size);
+
+ dma_desc_set_as_palette(desc);
+
+ /* Set as DMA Descriptor Chain Head. */
+ dma_desc_set_chain_head(desc);
+
+ win->dma_desc_last_no_data = desc;
+ }
+
+ return 0;
+}
+
+static void lcd_output_desc_cleanup(struct jz_fb_win_info *win)
+{
+ /* Clean up ALL. */
+ dma_desc_pool_init(win);
+
+ return;
+}
+
+/* Dynamically Attach / Detach Framebuffer */
+/* LCD Output: 1 Descriptor -> 1 Framebuffer. */
+static int lcd_output_desc_attach(struct jz_fb_win_info *win, void *mem)
+{
+ /* Get new descriptor. */
+ struct jz_fb_dma_desc *desc = dma_desc_get(win);
+ struct jz_fb_win_attr_info *a = &win->attr;
+
+ D("Called.");
+
+ if (!desc) {
+ return -ENOMEM;
+ }
+
+ dma_desc_init(desc);
+
+ /* Attach framebuffer to desciptors. */
+ dma_desc_set_mem(desc, mem);
+ dma_desc_set_data_size(desc, win->fb_frame_len);
+
+ dma_desc_set_area_size(desc, a->w, a->h);
+
+ dma_desc_add_to_chain(desc);
+
+ dump_desc(desc);
+
+ return 0;
+}
+
+static int lcd_output_desc_detach(struct jz_fb_win_info *win, void *mem)
+{
+ struct jz_fb_dma_desc *desc;
+
+ /* Find descriptor by mem pointer. */
+ desc = dma_desc_mem_to_desc(win, mem);
+ if (!desc) {
+ return -ENODEV;
+ }
+
+ dma_desc_del_from_chain(desc);
+
+ /* Release descriptor. */
+ dma_desc_put(desc);
+
+ return 0;
+}
+
+static struct jz_fb_ot_desc_ops lcd_output_desc_ops = {
+ .setup = lcd_output_desc_setup,
+ .attach = lcd_output_desc_attach,
+ .detach = lcd_output_desc_detach,
+ .cleanup = lcd_output_desc_cleanup,
+};
+
+static void lcd_output_enable(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_panel_config *c = ot->config;
+
+ /* Call specific panel screen on routines. */
+ c->ops->on(ot);
+
+ return;
+}
+
+static void lcd_output_disable(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_panel_config *c = ot->config;
+
+ /* Call specific panel screen off routines. */
+ c->ops->off(ot);
+
+ return;
+}
+
+static void lcd_output_start(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_panel_config *c = ot->config;
+
+ /* Call specific panel working routines. */
+ c->ops->normal(ot);
+
+ return;
+}
+
+static void lcd_output_stop(struct jz_fb_ot_info *ot)
+{
+ struct jz_fb_panel_config *c = ot->config;
+
+ /* Call specific panel suspend routines. */
+ c->ops->idle(ot);
+
+ return;
+}
+
+#include "lcd-control.c"
+
+static struct jz_fb_ot_ops lcd_output_ops = {
+ .enable = lcd_output_enable,
+ .disable = lcd_output_disable,
+ .start = lcd_output_start,
+ .stop = lcd_output_stop,
+ .control = lcd_output_control,
+};
+
+static int lcd_output_init(struct jz_fb_ot_info *ot)
+{
+ ot->name = "lcd-ot";
+
+ ot->use_quick_disable = 0;
+ ot->use_tve = 0;
+ ot->use_rgb_to_yuv = 0;
+
+ ot->desc_ops = &lcd_output_desc_ops;
+ ot->ops = &lcd_output_ops;
+
+ ot->config = &lcd_output_panel_config;
+
+ return 0;
+}
+
+#endif /* CONFIG_FB_JZ475X_LCD_OUTPUT */
diff --git a/drivers/video/jz475x/output/output.c b/drivers/video/jz475x/output/output.c
new file mode 100644
index 00000000000..e1f8ee283c9
--- /dev/null
+++ b/drivers/video/jz475x/output/output.c
@@ -0,0 +1,38 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Output Main Path.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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 "control.c"
+
+#ifdef CONFIG_FB_JZ475X_LCD_OUTPUT
+#include "lcd/lcd-output.c"
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_PAL_OUTPUT
+#include "tve/tve-pal-output.c"
+#endif
+
+#ifdef CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT
+#include "tve/tve-ntsc-output.c"
+#endif
+
+
diff --git a/drivers/video/jz475x/output/tve/tve-common.c b/drivers/video/jz475x/output/tve/tve-common.c
new file mode 100644
index 00000000000..bec5da1723b
--- /dev/null
+++ b/drivers/video/jz475x/output/tve/tve-common.c
@@ -0,0 +1,169 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * TVE Common Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifndef __JZ_FB_TVE_COMMON__
+#define __JZ_FB_TVE_COMMON__
+
+static int tve_output_desc_setup(struct jz_fb_win_info *win)
+{
+ D("Called.");
+
+ return 0;
+}
+
+static void tve_output_desc_cleanup(struct jz_fb_win_info *win)
+{
+ /* Clean up ALL. */
+ dma_desc_pool_init(win);
+
+ return;
+}
+
+/* Dynamically Attach / Detach Framebuffer */
+/* TVE Output: 2 Descriptors -> 1 Framebuffer. */
+static int tve_output_desc_attach(struct jz_fb_win_info *win, void *mem)
+{
+ /* Get new descriptor. */
+ struct jz_fb_dma_desc *top, *bottom;
+ struct jz_fb_win_attr_info *a = &win->attr;
+
+ D("Called.");
+
+ top = dma_desc_get(win);
+ if (!top) {
+ return -ENOMEM;
+ }
+
+ bottom = dma_desc_get(win);
+ if (!bottom) {
+ return -ENOMEM;
+ }
+
+ dma_desc_init(top);
+ dma_desc_init(bottom);
+
+ /* Attach framebuffer to desciptors. */
+ dma_desc_set_mem(top, mem);
+ dma_desc_set_mem(bottom, mem);
+
+ if (win->fb_frame_len & 0x1) {
+ dma_desc_set_data_size(top, win->fb_frame_len / 2 + win->fb_line_len);
+ dma_desc_set_data_size(bottom, win->fb_frame_len / 2 - win->fb_line_len);
+ }else{
+ dma_desc_set_data_size(top, win->fb_frame_len / 2);
+ dma_desc_set_data_size(bottom, win->fb_frame_len / 2);
+ }
+
+ dma_desc_set_area_size(top, a->w, a->h);
+ dma_desc_set_area_size(bottom, a->w, a->h);
+
+ dma_desc_set_stride(top, win->fb_line_len, win->fb_line_len);
+ dma_desc_set_stride(bottom, win->fb_line_len, win->fb_line_len);
+
+ /* Add bottom to top's group -> Link bottom after top. */
+ dma_desc_group_add(bottom, top);
+
+ dma_desc_add_to_chain(top);
+
+ dump_desc(top);
+ dump_desc(bottom);
+
+ return 0;
+}
+
+static int tve_output_desc_detach(struct jz_fb_win_info *win, void *mem)
+{
+ struct jz_fb_dma_desc *desc, *node;
+
+ struct list_head *pos, *n;
+
+ /* Locate descriptor by mem pointer. */
+ desc = dma_desc_mem_to_desc(win, mem);
+ if (!desc) {
+ return -ENODEV;
+ }
+
+ /* Remove us from current chain. */
+ dma_desc_del_from_chain(desc);
+
+ /* Release Group. */
+ list_for_each_safe(pos, n, &desc->group) {
+ node = list_entry(pos, struct jz_fb_dma_desc, group);
+
+ list_del(pos);
+ dma_desc_put(node);
+ }
+
+ /* Release descriptor. */
+ dma_desc_put(desc);
+
+ return 0;
+}
+
+static struct jz_fb_ot_desc_ops tve_output_desc_ops = {
+ .setup = tve_output_desc_setup,
+ .attach = tve_output_desc_attach,
+ .detach = tve_output_desc_detach,
+ .cleanup = tve_output_desc_cleanup,
+};
+
+#include "tve-hw.c"
+
+static void tve_output_start(struct jz_fb_ot_info *ot)
+{
+ jz_fb_tve_set_output((int)ot->config->priv);
+ jz_fb_tve_start();
+
+ return;
+}
+
+static void tve_output_stop(struct jz_fb_ot_info *ot)
+{
+ jz_fb_tve_stop();
+
+ return;
+}
+
+static inline int tve_output_get_path(struct jz_fb_ot_info *ot)
+{
+ return (int)(ot->config->priv);
+}
+
+static inline int tve_output_set_path(struct jz_fb_ot_info *ot, int path)
+{
+ int rv;
+
+ rv = jz_fb_tve_valid_output(path);
+ if (rv) {
+ E("Invaild Output Path: %d.", path);
+ return rv;
+ }
+
+ ot->config->priv = (void *)path;
+
+ return 0;
+}
+
+#include "tve-control.c"
+
+#endif
diff --git a/drivers/video/jz475x/output/tve/tve-control.c b/drivers/video/jz475x/output/tve/tve-control.c
new file mode 100644
index 00000000000..1e706e46e06
--- /dev/null
+++ b/drivers/video/jz475x/output/tve/tve-control.c
@@ -0,0 +1,64 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * TVE Common Control Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+static int tve_output_control(struct jz_fb_ot_info *ot,
+ void __user *p)
+{
+ struct jz_fb_tve_control lc;
+ struct jz_fb_common_control *c = &lc.common;
+
+ int rv = 0;
+
+ if (copy_from_user(&lc, p, sizeof(struct jz_fb_tve_control))) {
+ E("Failed to do copy_from_user.\n");
+ return -EFAULT;
+ }
+
+ /* Prevent Userspace APP walk the error path. */
+ if (c->id != ot->id) {
+ E("Bad Output ID for TVE Path: %s.", ot->miscdev->name);
+ return -EINVAL;
+ }
+
+ switch (c->command) {
+ case JZ_FB_CMD_TVE_GET_PATH:
+ c->v = tve_output_get_path(ot);
+
+ if (copy_to_user(p, &lc, sizeof(struct jz_fb_tve_control))) {
+ E("Failed to do copy_to_user().");
+ rv = -EFAULT;
+ }
+
+ break;
+
+ case JZ_FB_CMD_TVE_SET_PATH:
+ rv = tve_output_set_path(ot, c->v);
+ break;
+
+ default:
+ rv = do_ot_common_control(ot, c, p);
+ break;
+ }
+
+ return rv;
+}
diff --git a/drivers/video/jz475x/output/tve/tve-hw.c b/drivers/video/jz475x/output/tve/tve-hw.c
new file mode 100644
index 00000000000..13d34792243
--- /dev/null
+++ b/drivers/video/jz475x/output/tve/tve-hw.c
@@ -0,0 +1,272 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * TVE Controller Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+/* TV parameter */
+#define TVE_WIDTH_PAL 720
+#define TVE_HEIGHT_PAL 573
+#define TVE_FREQ_PAL 50
+#define TVE_WIDTH_NTSC 720
+#define TVE_HEIGHT_NTSC 482
+#define TVE_FREQ_NTSC 60
+
+struct jz_fb_tve_regs {
+ unsigned int ctrl;
+ unsigned int frcfg;
+ unsigned int slcfg1;
+ unsigned int slcfg2;
+ unsigned int slcfg3;
+ unsigned int ltcfg1;
+ unsigned int ltcfg2;
+ unsigned int cfreq;
+ unsigned int cphase;
+ unsigned int cbcrcfg;
+ unsigned int wsscr;
+ unsigned int wsscfg1;
+ unsigned int wsscfg2;
+ unsigned int wsscfg3;
+};
+
+struct jz_fb_tve_info {
+ int output;
+ int standard;
+ int b_enable;
+
+ struct jz_fb_tve_regs regs;
+};
+
+enum {
+ JZ_FB_TVE_STANDARD_PAL = 0,
+ JZ_FB_TVE_STANDARD_NTSC,
+};
+
+static struct jz_fb_tve_info g_tve_info;
+
+static struct jz_fb_tve_regs tve_pal_regs_config = {
+ .ctrl = (4 << TVE_CTRL_YCDLY_BIT) | TVE_CTRL_SYNCT | TVE_CTRL_PAL | TVE_CTRL_SWRST,
+ .frcfg = (23 << TVE_FRCFG_L1ST_BIT) | (625 << TVE_FRCFG_NLINE_BIT),
+ .slcfg1 = (800<<TVE_SLCFG1_WHITEL_BIT) | (282<<TVE_SLCFG1_BLACKL_BIT),
+ .slcfg2 = (296<<TVE_SLCFG2_VBLANKL_BIT) | (240<<TVE_SLCFG2_BLANKL_BIT),
+ .slcfg3 = (72 <<TVE_SLCFG3_SYNCL_BIT),
+ .ltcfg1 = (20<<TVE_LTCFG1_FRONTP_BIT) | (63<<TVE_LTCFG1_HSYNCW_BIT) | (78<<TVE_LTCFG1_BACKP_BIT),
+ .ltcfg2 = (1440 << TVE_LTCFG2_ACTLIN_BIT) | (24 << TVE_LTCFG2_PREBW_BIT) | (68 << TVE_LTCFG2_BURSTW_BIT),
+ .cfreq = 0x2a098acb,
+ .cphase = (0 << TVE_CPHASE_INITPH_BIT) | (0 << TVE_CPHASE_ACTPH_BIT) | (1 << TVE_CPHASE_CCRSTP_BIT),
+ .cbcrcfg = (32<<TVE_CBCRCFG_CBBA_BIT) | (59<<TVE_CBCRCFG_CRBA_BIT) | (137<<TVE_CBCRCFG_CBGAIN_BIT) | (137<<TVE_CBCRCFG_CRGAIN_BIT), /* CBGAIN CRGAIN??? */
+ .wsscr = 0x00000070, /* default value */
+ .wsscfg1 = 0x0,
+ .wsscfg2 = 0x0,
+ .wsscfg3 = 0x0,
+};
+
+struct jz_fb_tve_regs tve_ntsc_regs_config = {
+ .ctrl = (4 << TVE_CTRL_YCDLY_BIT) | TVE_CTRL_SWRST,
+ .frcfg = (21 << TVE_FRCFG_L1ST_BIT) | (525 << TVE_FRCFG_NLINE_BIT),
+ .slcfg1 = (800<<TVE_SLCFG1_WHITEL_BIT) | (282<<TVE_SLCFG1_BLACKL_BIT),
+ .slcfg2 = (296<<TVE_SLCFG2_VBLANKL_BIT) | (240<<TVE_SLCFG2_BLANKL_BIT),
+ .slcfg3 = (72 <<TVE_SLCFG3_SYNCL_BIT),
+ .ltcfg1 = (16<<TVE_LTCFG1_FRONTP_BIT) | (63<<TVE_LTCFG1_HSYNCW_BIT) | (59<<TVE_LTCFG1_BACKP_BIT),
+ .ltcfg2 = (1440 << TVE_LTCFG2_ACTLIN_BIT) | (22 << TVE_LTCFG2_PREBW_BIT) | (68 << TVE_LTCFG2_BURSTW_BIT),
+ .cfreq = 0x21f07c1f,
+ .cphase = (0x17 << TVE_CPHASE_INITPH_BIT) | (0 << TVE_CPHASE_ACTPH_BIT) | (1 << TVE_CPHASE_CCRSTP_BIT),
+ .cbcrcfg = (59<<TVE_CBCRCFG_CBBA_BIT) | (0<<TVE_CBCRCFG_CRBA_BIT) | (137<<TVE_CBCRCFG_CBGAIN_BIT) | (137<<TVE_CBCRCFG_CRGAIN_BIT),
+ .wsscr = 0x00000070, /* default value */
+ .wsscfg1 = 0x0,
+ .wsscfg2 = 0x0,
+ .wsscfg3 = 0x0,
+};
+
+static void jz_fb_tve_write_regs(struct jz_fb_tve_regs *tve)
+{
+ REG_TVE_CTRL = tve->ctrl;
+ REG_TVE_FRCFG = tve->frcfg;
+ REG_TVE_SLCFG1 = tve->slcfg1;
+ REG_TVE_SLCFG2 = tve->slcfg2;
+ REG_TVE_SLCFG3 = tve->slcfg3;
+ REG_TVE_LTCFG1 = tve->ltcfg1;
+ REG_TVE_LTCFG2 = tve->ltcfg2;
+ REG_TVE_CFREQ = tve->cfreq;
+ REG_TVE_CPHASE = tve->cphase;
+ REG_TVE_CBCRCFG = tve->cbcrcfg;
+ REG_TVE_WSSCR = tve->wsscr;
+ REG_TVE_WSSCFG1 = tve->wsscfg1;
+ REG_TVE_WSSCFG2 = tve->wsscfg2;
+ REG_TVE_WSSCFG3 = tve->wsscfg3;
+}
+
+static void jz_fb_tve_dac_power_on(struct jz_fb_tve_info *info)
+{
+ unsigned long v = REG_TVE_CTRL;
+
+ v &= ~(TVE_CTRL_DAPD | TVE_CTRL_DAPD1 | TVE_CTRL_DAPD2);
+
+ switch (info->output) {
+ case JZ_FB_TVE_PATH_CVBS:
+ v |= TVE_CTRL_DAPD;
+ break;
+
+ case JZ_FB_TVE_PATH_SVIDEO:
+
+#ifdef CONFIG_SOC_JZ4750D
+ case JZ_FB_TVE_PATH_YUV:
+#endif
+ v |= (TVE_CTRL_DAPD | TVE_CTRL_DAPD1 | TVE_CTRL_DAPD2);
+ break;
+
+ }
+
+ REG_TVE_CTRL = v;
+
+ return;
+}
+
+static void jz_fb_tve_dac_power_off(struct jz_fb_tve_info *info)
+{
+ REG_TVE_CTRL &= ~(TVE_CTRL_DAPD | TVE_CTRL_DAPD1 | TVE_CTRL_DAPD2);
+
+ return;
+}
+
+static void jz_fb_tve_load_standard(struct jz_fb_tve_info *info)
+{
+ switch (info->standard) {
+ case JZ_FB_TVE_STANDARD_PAL:
+ memcpy(&info->regs,
+ &tve_pal_regs_config, sizeof(struct jz_fb_tve_regs));
+ break;
+
+ case JZ_FB_TVE_STANDARD_NTSC:
+ memcpy(&info->regs,
+ &tve_ntsc_regs_config, sizeof(struct jz_fb_tve_regs));
+ break;
+ }
+
+ return;
+}
+
+static void jz_fb_tve_select_output(struct jz_fb_tve_info *info)
+{
+ switch (info->output) {
+
+#ifdef CONFIG_SOC_JZ4750D
+ case JZ_FB_TVE_PATH_YUV:
+ info->regs.ctrl |= TVE_CTRL_EYCBCR;
+ break;
+#endif
+
+ case JZ_FB_TVE_PATH_CVBS:
+ info->regs.ctrl |= TVE_CTRL_ECVBS;
+ break;
+
+ case JZ_FB_TVE_PATH_SVIDEO:
+ break;
+ }
+
+ return;
+}
+
+static void jz_fb_tve_start(void)
+{
+ struct jz_fb_tve_info *info = &g_tve_info;
+
+ jz_fb_tve_load_standard(info);
+ jz_fb_tve_select_output(info);
+
+ jz_fb_tve_write_regs(&info->regs);
+
+ jz_fb_tve_dac_power_on(info);
+ REG_TVE_CTRL &= ~TVE_CTRL_SWRST;
+
+ info->b_enable = 1;
+
+ return;
+}
+
+static void jz_fb_tve_stop(void)
+{
+ struct jz_fb_tve_info *info = &g_tve_info;
+
+ jz_fb_tve_dac_power_off(info);
+ REG_TVE_CTRL |= TVE_CTRL_SWRST;
+
+ info->b_enable = 0;
+
+ return;
+}
+
+static int jz_fb_tve_set_standard(int standard)
+{
+ struct jz_fb_tve_info *info = &g_tve_info;
+
+ int rv = 0;
+
+ switch (standard) {
+ case JZ_FB_TVE_STANDARD_PAL:
+ case JZ_FB_TVE_STANDARD_NTSC:
+ info->standard = standard;
+
+ break;
+ default:
+ rv = -EINVAL;
+
+ break;
+ }
+
+ return rv;
+}
+
+static int jz_fb_tve_valid_output(int output)
+{
+ int rv = 0;
+
+ switch (output) {
+ case JZ_FB_TVE_PATH_CVBS:
+ case JZ_FB_TVE_PATH_SVIDEO:
+
+#ifdef CONFIG_SOC_JZ4750D
+ case JZ_FB_TVE_PATH_YUV:
+#endif
+ break;
+ default:
+ rv = -EINVAL;
+
+ break;
+ }
+
+ return rv;
+}
+
+static int jz_fb_tve_set_output(int output)
+{
+ struct jz_fb_tve_info *info = &g_tve_info;
+
+ int rv;
+
+ rv = jz_fb_tve_valid_output(output);
+ if (rv)
+ return rv;
+
+ info->output = output;
+
+ return 0;
+}
+
diff --git a/drivers/video/jz475x/output/tve/tve-ntsc-output.c b/drivers/video/jz475x/output/tve/tve-ntsc-output.c
new file mode 100644
index 00000000000..637ba32ced9
--- /dev/null
+++ b/drivers/video/jz475x/output/tve/tve-ntsc-output.c
@@ -0,0 +1,99 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * TVE NTSC Output Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifdef CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT
+
+#include "tve-common.c"
+
+static struct jz_fb_panel_info tve_ntsc_output_panel_info = {
+ .lcd_ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* Underrun recover */
+ .lcd_cfg = LCD_CFG_RECOVER | LCD_CFG_TVEN
+ | LCD_CFG_MODE_INTER_CCIR656,
+ TVE_WIDTH_NTSC, TVE_HEIGHT_NTSC, TVE_FREQ_NTSC, 0, 0, 0, 0, 0, 0,
+};
+
+/* ------------ CUSTOM: Modify these by your need. ----------- */
+struct jz_fb_win_attr_info tve_ntsc_output_win_init_config[] = {
+ [0] = {
+ .enable = 1,
+ .x = 0,
+ .y = 0,
+ .w = TVE_WIDTH_NTSC,
+ .h = TVE_HEIGHT_NTSC,
+ .bpp = 32,
+ },
+ [1] = {
+ .enable = 0,
+ .x = 0,
+ .y = 0,
+ .w = TVE_WIDTH_NTSC,
+ .h = TVE_HEIGHT_NTSC,
+ .bpp = 32,
+ },
+};
+/* ----------------------------------------------------------- */
+struct jz_fb_panel_config tve_ntsc_output_panel_config = {
+ .win_init_config = tve_ntsc_output_win_init_config,
+ .panel = &tve_ntsc_output_panel_info,
+ .use_palette = 0,
+
+/* -------------- CUSTOM: Modify these by your need. --------- */
+ .max_win_bpp = 32,
+ .background_color = 0x000000FF,
+/* ----------------------------------------------------------- */
+};
+
+#include "tve-common.c"
+
+static void tve_ntsc_output_start(struct jz_fb_ot_info *ot)
+{
+ jz_fb_tve_set_standard(JZ_FB_TVE_STANDARD_NTSC);
+
+ tve_output_start(ot);
+
+ return;
+}
+
+static struct jz_fb_ot_ops tve_ntsc_output_ops = {
+ .start = tve_ntsc_output_start,
+ .stop = tve_output_stop,
+ .control = tve_output_control,
+};
+
+static int tve_ntsc_output_init(struct jz_fb_ot_info *ot)
+{
+ ot->name = "tve-ntsc-ot";
+
+ ot->use_quick_disable = 1;
+ ot->use_tve = 1;
+ ot->use_rgb_to_yuv = 1;
+
+ ot->desc_ops = &tve_output_desc_ops;
+ ot->ops = &tve_ntsc_output_ops;
+
+ ot->config = &tve_ntsc_output_panel_config;
+
+ return 0;
+}
+
+#endif /* CONFIG_FB_JZ475X_TVE_NTSC_OUTPUT */
diff --git a/drivers/video/jz475x/output/tve/tve-pal-output.c b/drivers/video/jz475x/output/tve/tve-pal-output.c
new file mode 100644
index 00000000000..4be78db82ce
--- /dev/null
+++ b/drivers/video/jz475x/output/tve/tve-pal-output.c
@@ -0,0 +1,98 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * TVE PAL Output Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#ifdef CONFIG_FB_JZ475X_TVE_PAL_OUTPUT
+
+#include "tve-common.c"
+
+static struct jz_fb_panel_info tve_pal_output_panel_info = {
+ .lcd_ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* Underrun recover */
+ .lcd_cfg = LCD_CFG_RECOVER
+ | LCD_CFG_TVEN | LCD_CFG_TVEPEH
+ | LCD_CFG_MODE_INTER_CCIR656,
+ TVE_WIDTH_PAL, TVE_HEIGHT_PAL, TVE_FREQ_PAL, 0, 0, 0, 0, 0, 0,
+};
+
+/* ------------ CUSTOM: Modify these by your need. ----------- */
+struct jz_fb_win_attr_info tve_pal_output_win_init_config[] = {
+ [0] = {
+ .enable = 1,
+ .x = 0,
+ .y = 0,
+ .w = TVE_WIDTH_PAL,
+ .h = TVE_HEIGHT_PAL,
+ .bpp = 32,
+ },
+ [1] = {
+ .enable = 0,
+ .x = 0,
+ .y = 0,
+ .w = TVE_WIDTH_PAL,
+ .h = TVE_HEIGHT_PAL,
+ .bpp = 32,
+ },
+};
+/* ----------------------------------------------------------- */
+struct jz_fb_panel_config tve_pal_output_panel_config = {
+ .win_init_config = tve_pal_output_win_init_config,
+ .panel = &tve_pal_output_panel_info,
+ .use_palette = 0,
+
+/* -------------- CUSTOM: Modify these by your need. --------- */
+ .max_win_bpp = 32,
+ .background_color = 0x000000FF,
+/* ----------------------------------------------------------- */
+};
+
+static void tve_pal_output_start(struct jz_fb_ot_info *ot)
+{
+ jz_fb_tve_set_standard(JZ_FB_TVE_STANDARD_PAL);
+
+ tve_output_start(ot);
+
+ return;
+}
+
+static struct jz_fb_ot_ops tve_pal_output_ops = {
+ .start = tve_pal_output_start,
+ .stop = tve_output_stop,
+ .control = tve_output_control,
+};
+
+static int tve_pal_output_init(struct jz_fb_ot_info *ot)
+{
+ ot->name = "tve-pal-ot";
+
+ ot->use_quick_disable = 1;
+ ot->use_tve = 1;
+ ot->use_rgb_to_yuv = 1;
+
+ ot->desc_ops = &tve_output_desc_ops;
+ ot->ops = &tve_pal_output_ops;
+
+ ot->config = &tve_pal_output_panel_config;
+
+ return 0;
+}
+
+#endif /* CONFIG_FB_JZ475X_TVE_PAL_OUTPUT */
diff --git a/drivers/video/jz475x/test/Makefile b/drivers/video/jz475x/test/Makefile
new file mode 100644
index 00000000000..b17da8389e3
--- /dev/null
+++ b/drivers/video/jz475x/test/Makefile
@@ -0,0 +1,23 @@
+CC := mipsel-linux-gcc
+DESTDIR := /home/zwang
+
+TARGET := fb_fill \
+ fb_info \
+ fb_v_colorbar \
+ fb_h_colorbar \
+ lcd_ot_ctrl \
+ tve_pal_ot_ctrl \
+ tve_ntsc_ot_ctrl
+
+.PHONY: all install clean
+
+%.o : %.c
+ $(CC) $(CFLAGS) $(CWARN) $(CDEFS) $(CINCLUDE) -c -o $@ $<
+
+all: $(TARGET)
+
+install: $(TARGET)
+ cp -av $(TARGET) $(DESTDIR)
+
+clean:
+ rm -rf $(TARGET)
diff --git a/drivers/video/jz475x/test/fb_common.c b/drivers/video/jz475x/test/fb_common.c
new file mode 100644
index 00000000000..1a6b31bd81e
--- /dev/null
+++ b/drivers/video/jz475x/test/fb_common.c
@@ -0,0 +1,88 @@
+/*
+ * Framebuffer Test Common Routines.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <linux/fb.h>
+
+struct fb {
+ int fd;
+ uint32_t w;
+ uint32_t h;
+ uint32_t bpp;
+ uint32_t bpp_byte;
+ uint32_t mem_size;
+ void *mem;
+};
+
+int fb_open(char *name, struct fb *fb)
+{
+ struct fb_var_screeninfo var;
+
+ int rv;
+
+ fb->fd = open(name, O_RDWR);
+ if (fb->fd == -1) {
+ perror("open():");
+ return -1;
+ }
+
+ rv = ioctl(fb->fd, FBIOGET_VSCREENINFO, &var);
+ if (rv) {
+ perror("ioctl");
+ close(fb->fd);
+ return -1;
+ }
+
+ fb->w = var.xres;
+ fb->h = var.yres;
+ fb->bpp = var.bits_per_pixel;
+ fb->bpp_byte = fb->bpp / 8;
+ fb->mem_size = fb->w * fb->h * fb->bpp_byte;
+
+ fb->mem = mmap(NULL, fb->mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0L);
+ if (fb->mem == (void *)-1) {
+ perror("mmap():");
+ close(fb->fd);
+ return -1;
+ }
+
+ fprintf(stderr, "%s(): w: %d h: %d bpp: %d bpp_byte: %d mem_size: 0x%lu mem: %p.\n", __func__, fb->w, fb->h, fb->bpp, fb->bpp_byte, fb->mem_size, fb->mem);
+
+ return 0;
+}
+
+int fb_close(struct fb *fb)
+{
+ close(fb->fd);
+ munmap(fb->mem, fb->mem_size);
+
+ return 0;
+}
+
diff --git a/drivers/video/jz475x/test/fb_fill.c b/drivers/video/jz475x/test/fb_fill.c
new file mode 100644
index 00000000000..df88d147266
--- /dev/null
+++ b/drivers/video/jz475x/test/fb_fill.c
@@ -0,0 +1,76 @@
+/*
+ * Framebuffer Fill Test.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "fb_common.c"
+
+int main(int argc, char **argv)
+{
+ struct fb fb;
+ uint32_t word;
+
+ void *mem;
+ int fd;
+
+ char *p;
+
+ uint32_t i;
+
+ int rv;
+
+ if (argc != 3)
+ return -1;
+
+ word = strtoul(argv[2], &p, 16);
+ if (*p != '\0') {
+ fprintf(stderr, "Invalid value.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ rv = fb_open(argv[1], &fb);
+ if (rv) {
+ fprintf(stderr, "Failed to open framebuffer device.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ fprintf(stderr, "Word: 0x%x, Bpp_byte: 0x%u.\n", word, fb.bpp_byte);
+
+ mem = fb.mem;
+
+ for (i = 0; i < fb.mem_size; i += fb.bpp_byte) {
+ memcpy(mem, &word, fb.bpp_byte);
+ mem += fb.bpp_byte;
+ }
+
+ fb_close(&fb);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/fb_h_colorbar.c b/drivers/video/jz475x/test/fb_h_colorbar.c
new file mode 100644
index 00000000000..1a2da3c03de
--- /dev/null
+++ b/drivers/video/jz475x/test/fb_h_colorbar.c
@@ -0,0 +1,138 @@
+/*
+ * Framebuffer H Color Bar.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "fb_common.c"
+
+static void display_h_color_bar(int *ptr, int w, int h, int bpp) {
+ int i, data = 0;
+ int wpl; //word_per_line
+ wpl = w*bpp/32;
+ if (!(bpp > 8))
+ for (i = 0;i < wpl*h;i++) {
+ switch(bpp){
+ case 1:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%2)*0xffffffff;
+ *ptr++ = data;
+ break;
+ case 2:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%4)*0x55555555;
+ *ptr++ = data;
+ break;
+ case 4:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%16)*0x11111111;
+ *ptr++ = data;
+ break;
+ case 8:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%256)*0x01010101;
+ *ptr++ = data;
+ break;
+ }
+ }
+ else {
+
+ switch(bpp) {
+ case 15:
+ case 16:
+ for (i = 0;i < wpl*h;i++) {
+ if (((i/(wpl*8)) % 8) == 0)
+ *ptr++ = 0xffffffff;
+ else if (((i/(wpl*8)) % 8) == 1)
+ *ptr++ = 0xf800f800;
+ else if (((i/(wpl*8)) % 8) == 2)
+ *ptr++ = 0xffe0ffe0;
+ else if (((i/(wpl*8)) % 8) == 3)
+ *ptr++ = 0x07e007e0;
+ else if (((i/(wpl*8)) % 8) == 4)
+ *ptr++ = 0x07ff07ff;
+ else if (((i/(wpl*8)) % 8) == 5)
+ *ptr++ = 0x001f001f;
+ else if (((i/(wpl*8)) % 8) == 6)
+ *ptr++ = 0xf81ff81f;
+ else if (((i/(wpl*8)) % 8) == 7)
+ *ptr++ = 0x00000000;
+ }
+ break;
+ case 18:
+ case 24:
+ case 32:
+ default:
+ for (i = 0;i < wpl*h;i++) {
+ if (((i/(wpl*8)) % 8) == 7)
+ *ptr++ = 0xffffff;
+ else if (((i/(wpl*8)) % 8) == 2)
+ *ptr++ = 0xff0000;
+ else if (((i/(wpl*8)) % 8) == 4)
+ *ptr++ = 0xffff00;
+ else if (((i/(wpl*8)) % 8) == 6)
+ *ptr++ = 0x00ff00;
+ else if (((i/(wpl*8)) % 8) == 1)
+ *ptr++ = 0x00ffff;
+ else if (((i/(wpl*8)) % 8) == 3)
+ *ptr++ = 0x0000ff;
+ else if (((i/(wpl*8)) % 8) == 5)
+ *ptr++ = 0x000000;
+ else if (((i/(wpl*8)) % 8) == 0)
+ *ptr++ = 0xff00ff;
+ }
+ break;
+ }
+
+ }
+
+}
+
+int main(int argc, char **argv)
+{
+ struct fb fb;
+
+ int rv;
+
+ if (argc != 2)
+ return -1;
+
+ rv = fb_open(argv[1], &fb);
+ if (rv) {
+ exit(EXIT_FAILURE);
+ }
+
+ display_h_color_bar(fb.mem, fb.w, fb.h, fb.bpp);
+
+ fb_close(&fb);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/fb_info.c b/drivers/video/jz475x/test/fb_info.c
new file mode 100644
index 00000000000..4b4c5ecfdb7
--- /dev/null
+++ b/drivers/video/jz475x/test/fb_info.c
@@ -0,0 +1,126 @@
+/*
+ * Dump Framebuffer Info.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <linux/fb.h>
+
+#define DUMP(fmt, args...) \
+ fprintf(stderr, fmt"\n", ##args)
+
+/* ------------ Framebuffer ----------------- */
+static void dump_fb_info_var(struct fb_var_screeninfo *var)
+{
+ DUMP("Framebuffer VAR Info: ");
+ DUMP("=============================================");
+
+ DUMP("var->xres: 0x%08lx.",var->xres);
+ DUMP("var->yres: 0x%08lx.",var->yres);
+ DUMP("var->xres_virtual: 0x%08lx.",var->xres_virtual);
+ DUMP("var->yres_virtual: 0x%08lx.",var->yres_virtual);
+ DUMP("var->xoffset: 0x%08lx.",var->xoffset);
+ DUMP("var->yoffset: 0x%08lx.",var->yoffset);
+ DUMP("var->bits_per_pixel: 0x%08lx.",var->bits_per_pixel);
+ DUMP("var->grayscale: 0x%08lx.",var->grayscale);
+ DUMP("var->nonstd: 0x%08lx.",var->nonstd);
+ DUMP("var->activate: 0x%08lx.",var->activate);
+ DUMP("var->height: 0x%08lx.",var->height);
+ DUMP("var->width: 0x%08lx.",var->width);
+ DUMP("var->accel_flags: 0x%08lx.",var->accel_flags);
+ DUMP("var->pixclock: 0x%08lx.",var->pixclock);
+ DUMP("var->left_margin: 0x%08lx.",var->left_margin);
+ DUMP("var->right_margin: 0x%08lx.",var->right_margin);
+ DUMP("var->upper_margin: 0x%08lx.",var->upper_margin);
+ DUMP("var->lower_margin: 0x%08lx.",var->lower_margin);
+ DUMP("var->hsync_len: 0x%08lx.",var->hsync_len);
+ DUMP("var->vsync_len: 0x%08lx.",var->vsync_len);
+ DUMP("var->sync: 0x%08lx.",var->sync);
+ DUMP("var->vmode: 0x%08lx.",var->vmode);
+ DUMP("var->rotate: 0x%08lx.",var->rotate);
+
+ return;
+}
+
+static void dump_fb_info_fix(struct fb_fix_screeninfo *fix)
+{
+ DUMP("Framebuffer FIX Info: ");
+ DUMP("=============================================");
+
+ DUMP("fix->id: %s.",fix->id);
+
+ DUMP("fix->smem_start: 0x%08lx.",fix->smem_start);
+ DUMP("fix->smem_len: 0x%08lx.",fix->smem_len);
+ DUMP("fix->type: 0x%08lx.",fix->type);
+ DUMP("fix->type_aux: 0x%08lx.",fix->type_aux);
+ DUMP("fix->visual: 0x%08lx.",fix->visual);
+ DUMP("fix->xpanstep: 0x%08lx.",fix->xpanstep);
+ DUMP("fix->ypanstep: 0x%08lx.",fix->ypanstep);
+ DUMP("fix->ywrapstep: 0x%08lx.",fix->ywrapstep);
+ DUMP("fix->line_length: 0x%08lx.",fix->line_length);
+ DUMP("fix->mmio_start: 0x%08lx.",fix->mmio_start);
+ DUMP("fix->mmio_len: 0x%08lx.",fix->mmio_len);
+ DUMP("fix->accel: 0x%08lx.",fix->accel);
+
+ return;
+}
+
+int main(int argc, char **argv)
+{
+ struct fb_var_screeninfo var;
+ struct fb_fix_screeninfo fix;
+
+ int fd;
+
+ int rv;
+
+ if (argc != 2)
+ return -1;
+
+ fd = open(argv[1], O_RDWR);
+ if (fd == -1) {
+ perror("open():");
+ exit(EXIT_FAILURE);
+ }
+
+ rv = ioctl(fd, FBIOGET_VSCREENINFO, &var);
+ if (rv) {
+ perror("ioctl():");
+ exit(EXIT_FAILURE);
+ }
+
+ rv = ioctl(fd, FBIOGET_FSCREENINFO, &fix);
+ if (rv) {
+ perror("ioctl():");
+ exit(EXIT_FAILURE);
+ }
+
+ dump_fb_info_var(&var);
+ dump_fb_info_fix(&fix);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/fb_v_colorbar.c b/drivers/video/jz475x/test/fb_v_colorbar.c
new file mode 100644
index 00000000000..8e7ab73b0ee
--- /dev/null
+++ b/drivers/video/jz475x/test/fb_v_colorbar.c
@@ -0,0 +1,163 @@
+/*
+ * Framebuffer V Color Bar.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "fb_common.c"
+
+static void display_v_color_bar(int *ptr, int w, int h, int bpp) {
+ int i, j, wpl, data = 0;
+ wpl = w*bpp/32;
+ if (!(bpp > 8))
+ switch(bpp){
+ case 1:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ *ptr++ = 0x00ff00ff;
+ }
+ break;
+ case 2:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ data = (i%4)*0x55555555;
+ *ptr++ = data;
+ }
+ break;
+ case 4:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ data = (i%16)*0x11111111;
+ *ptr++ = data;
+ }
+ break;
+ case 8:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i+=2) {
+ data = (i%(256))*0x01010101;
+ *ptr++ = data;
+ *ptr++ = data;
+ }
+ break;
+ }
+ else {
+ switch(bpp) {
+ case 16:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/4)%8==0)
+ *ptr++ = 0xffffffff;
+ else if ((i/4)%8==1)
+ *ptr++ = 0xf800f800;
+ else if ((i/4)%8==2)
+ *ptr++ = 0xffe0ffe0;
+ else if ((i/4)%8==3)
+ *ptr++ = 0x07e007e0;
+ else if ((i/4)%8==4)
+ *ptr++ = 0x07ff07ff;
+ else if ((i/4)%8==5)
+ *ptr++ = 0x001f001f;
+ else if ((i/4)%8==6)
+ *ptr++ = 0xf81ff81f;
+ else if ((i/4)%8==7)
+ *ptr++ = 0x00000000;
+ }
+ break;
+ case 18:
+ case 24:
+ case 32:
+ default:
+#if 1
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/8)%8==7)
+ *ptr++ = 0xffffff;
+ else if ((i/8)%8==1)
+ *ptr++ = 0xff0000;
+ else if ((i/8)%8==2)
+ *ptr++ = 0xffff00;
+ else if ((i/8)%8==3)
+ *ptr++ = 0x00ff00;
+ else if ((i/8)%8==4)
+ *ptr++ = 0x00ffff;
+ else if ((i/8)%8==5)
+ *ptr++ = 0x0000ff;
+ else if ((i/8)%8==6)
+ *ptr++ = 0xff00ff;
+ else if ((i/8)%8==0)
+ *ptr++ = 0x000000;
+ }
+#else
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/8)%8==7)
+ *ptr++ = 0x00ff0000;
+ else if ((i/8)%8==1)
+ *ptr++ = 0xffff0000;
+ else if ((i/8)%8==2)
+ *ptr++ = 0x20ff0000;
+ else if ((i/8)%8==3)
+ *ptr++ = 0x40ff0000;
+ else if ((i/8)%8==4)
+ *ptr++ = 0x60ff0000;
+ else if ((i/8)%8==5)
+ *ptr++ = 0x80ff0000;
+ else if ((i/8)%8==6)
+ *ptr++ = 0xa0ff0000;
+ else if ((i/8)%8==0)
+ *ptr++ = 0xc0ff0000;
+ }
+#endif
+ break;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ struct fb fb;
+
+ int rv;
+
+ if (argc != 2)
+ return -1;
+
+ rv = fb_open(argv[1], &fb);
+ if (rv) {
+ exit(EXIT_FAILURE);
+ }
+
+ display_v_color_bar(fb.mem, fb.w, fb.h, fb.bpp);
+
+ fb_close(&fb);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/lcd_ot_ctrl.c b/drivers/video/jz475x/test/lcd_ot_ctrl.c
new file mode 100644
index 00000000000..97d31ba8060
--- /dev/null
+++ b/drivers/video/jz475x/test/lcd_ot_ctrl.c
@@ -0,0 +1,167 @@
+/*
+ * LCD Output Path Control.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "../abi.h"
+
+int main(int argc, char **argv)
+{
+ struct jz_fb_lcd_control control;
+ struct jz_fb_common_control *c = &control.common;
+
+ int fd;
+ int rv;
+
+ if (argc < 2)
+ return -1;
+
+ fd = open("/dev/lcd-ot-ctrl", O_RDWR);
+ if (fd == -1) {
+ perror("open():");
+ exit(EXIT_FAILURE);
+ }
+
+ c->id = 0;
+
+ if (!strcmp(argv[1], "power")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_COMMON_SET_POWER;
+ c->v = strcmp(argv[2], "off");
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ }else if (!strcmp(argv[1], "screen")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_COMMON_SET_SCREEN;
+ c->v = strcmp(argv[2], "off");
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ }else if (!strcmp(argv[1], "get_attr")) {
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ fprintf(stderr, "Current Win ATTR:\n");
+ fprintf(stderr, "WIN 0: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[0].enable,
+ c->win_attr[0].x,
+ c->win_attr[0].y,
+ c->win_attr[0].w,
+ c->win_attr[0].h,
+ c->win_attr[0].bpp);
+
+ fprintf(stderr, "WIN 1: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[1].enable,
+ c->win_attr[1].x,
+ c->win_attr[1].y,
+ c->win_attr[1].w,
+ c->win_attr[1].h,
+ c->win_attr[1].bpp);
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "set_attr")) {
+ /* 1 2 3 4 5 6 7 8 9 */
+ /* set_attr [win index] [enable] [x] [y] [w] [h] [bpp] [active] */
+
+ unsigned int index = atoi(argv[2]);
+ unsigned int enable = atoi(argv[3]);
+ unsigned int x = atoi(argv[4]);
+ unsigned int y = atoi(argv[5]);
+ unsigned int w = atoi(argv[6]);
+ unsigned int h = atoi(argv[7]);
+ unsigned int bpp = atoi(argv[8]);
+ unsigned int active = atoi(argv[9]);
+
+ if (argc < 9 || index > JZ_FB_NR_MAX_FG)
+ return -1;
+
+ /* Get current win attr. */
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ c->command = JZ_FB_CMD_COMMON_SET_WIN_ATTR;
+
+ c->active_now = active;
+
+ c->win_attr[index].enable = enable;
+ c->win_attr[index].x = x;
+ c->win_attr[index].y = y;
+ c->win_attr[index].w = w;
+ c->win_attr[index].h = h;
+ c->win_attr[index].bpp = bpp;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+ }else if (!strcmp(argv[1], "select")) {
+ c->command = JZ_FB_CMD_COMMON_SELECT_OT;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ }
+
+ close(fd);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/tve_ntsc_ot_ctrl.c b/drivers/video/jz475x/test/tve_ntsc_ot_ctrl.c
new file mode 100644
index 00000000000..b969bf53a2e
--- /dev/null
+++ b/drivers/video/jz475x/test/tve_ntsc_ot_ctrl.c
@@ -0,0 +1,189 @@
+/*
+ * LCD Output Path Control.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "../abi.h"
+
+#define TVE_NTSC_PATH "/dev/tve-ntsc-ot-ctrl"
+#define TVE_NTSC_ID 2
+
+int main(int argc, char **argv)
+{
+ struct jz_fb_lcd_control control;
+ struct jz_fb_common_control *c = &control.common;
+
+ int fd;
+ int rv;
+
+ if (argc < 2)
+ return -1;
+
+ fd = open(TVE_NTSC_PATH, O_RDWR);
+ if (fd == -1) {
+ perror("open():");
+ exit(EXIT_FAILURE);
+ }
+
+ c->id = TVE_NTSC_ID;
+
+ if (!strcmp(argv[1], "power")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_COMMON_SET_POWER;
+ c->v = strcmp(argv[2], "off");
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+ }else if (!strcmp(argv[1], "get_attr")) {
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ fprintf(stderr, "Current Win ATTR:\n");
+ fprintf(stderr, "WIN 0: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[0].enable,
+ c->win_attr[0].x,
+ c->win_attr[0].y,
+ c->win_attr[0].w,
+ c->win_attr[0].h,
+ c->win_attr[0].bpp);
+
+ fprintf(stderr, "WIN 1: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[1].enable,
+ c->win_attr[1].x,
+ c->win_attr[1].y,
+ c->win_attr[1].w,
+ c->win_attr[1].h,
+ c->win_attr[1].bpp);
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "set_attr")) {
+ /* 1 2 3 4 5 6 7 8 9 */
+ /* set_attr [win index] [enable] [x] [y] [w] [h] [bpp] [active] */
+
+ unsigned int index = atoi(argv[2]);
+ unsigned int enable = atoi(argv[3]);
+ unsigned int x = atoi(argv[4]);
+ unsigned int y = atoi(argv[5]);
+ unsigned int w = atoi(argv[6]);
+ unsigned int h = atoi(argv[7]);
+ unsigned int bpp = atoi(argv[8]);
+ unsigned int active = atoi(argv[9]);
+
+ if (argc < 9 || index > JZ_FB_NR_MAX_FG)
+ return -1;
+
+ /* Get current win attr. */
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ c->command = JZ_FB_CMD_COMMON_SET_WIN_ATTR;
+
+ c->active_now = active;
+
+ c->win_attr[index].enable = enable;
+ c->win_attr[index].x = x;
+ c->win_attr[index].y = y;
+ c->win_attr[index].w = w;
+ c->win_attr[index].h = h;
+ c->win_attr[index].bpp = bpp;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "select")) {
+ c->command = JZ_FB_CMD_COMMON_SELECT_OT;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "get_path")) {
+ if (argc < 2)
+ return -1;
+
+ c->command = JZ_FB_CMD_TVE_GET_PATH;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ fprintf(stderr, "Current TVE Path: %d.\n", c->v);
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "set_path")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_TVE_SET_PATH;
+ c->v = atoi(argv[2]);
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ close(fd);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/test/tve_pal_ot_ctrl.c b/drivers/video/jz475x/test/tve_pal_ot_ctrl.c
new file mode 100644
index 00000000000..f0b3aea6677
--- /dev/null
+++ b/drivers/video/jz475x/test/tve_pal_ot_ctrl.c
@@ -0,0 +1,189 @@
+/*
+ * LCD Output Path Control.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@ingenic.cn>
+ *
+ * Based on original LCDC Driver.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <string.h>
+
+#include "../abi.h"
+
+#define TVE_PAL_PATH "/dev/tve-pal-ot-ctrl"
+#define TVE_PAL_ID 1
+
+int main(int argc, char **argv)
+{
+ struct jz_fb_lcd_control control;
+ struct jz_fb_common_control *c = &control.common;
+
+ int fd;
+ int rv;
+
+ if (argc < 2)
+ return -1;
+
+ fd = open(TVE_PAL_PATH, O_RDWR);
+ if (fd == -1) {
+ perror("open():");
+ exit(EXIT_FAILURE);
+ }
+
+ c->id = TVE_PAL_ID;
+
+ if (!strcmp(argv[1], "power")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_COMMON_SET_POWER;
+ c->v = strcmp(argv[2], "off");
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+ }else if (!strcmp(argv[1], "get_attr")) {
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ fprintf(stderr, "Current Win ATTR:\n");
+ fprintf(stderr, "WIN 0: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[0].enable,
+ c->win_attr[0].x,
+ c->win_attr[0].y,
+ c->win_attr[0].w,
+ c->win_attr[0].h,
+ c->win_attr[0].bpp);
+
+ fprintf(stderr, "WIN 1: enable: %d, x: %d, y: %d, w: %d, h: %d, bpp: %d.\n",
+ c->win_attr[1].enable,
+ c->win_attr[1].x,
+ c->win_attr[1].y,
+ c->win_attr[1].w,
+ c->win_attr[1].h,
+ c->win_attr[1].bpp);
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "set_attr")) {
+ /* 1 2 3 4 5 6 7 8 9 */
+ /* set_attr [win index] [enable] [x] [y] [w] [h] [bpp] [active] */
+
+ unsigned int index = atoi(argv[2]);
+ unsigned int enable = atoi(argv[3]);
+ unsigned int x = atoi(argv[4]);
+ unsigned int y = atoi(argv[5]);
+ unsigned int w = atoi(argv[6]);
+ unsigned int h = atoi(argv[7]);
+ unsigned int bpp = atoi(argv[8]);
+ unsigned int active = atoi(argv[9]);
+
+ if (argc < 9 || index > JZ_FB_NR_MAX_FG)
+ return -1;
+
+ /* Get current win attr. */
+ c->command = JZ_FB_CMD_COMMON_GET_WIN_ATTR;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ c->command = JZ_FB_CMD_COMMON_SET_WIN_ATTR;
+
+ c->active_now = active;
+
+ c->win_attr[index].enable = enable;
+ c->win_attr[index].x = x;
+ c->win_attr[index].y = y;
+ c->win_attr[index].w = w;
+ c->win_attr[index].h = h;
+ c->win_attr[index].bpp = bpp;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "select")) {
+ c->command = JZ_FB_CMD_COMMON_SELECT_OT;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "get_path")) {
+ if (argc < 2)
+ return -1;
+
+ c->command = JZ_FB_CMD_TVE_GET_PATH;
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ fprintf(stderr, "Current TVE Path: %d.\n", c->v);
+
+ return 0;
+
+ }else if (!strcmp(argv[1], "set_path")) {
+ if (argc < 3)
+ return -1;
+
+ c->command = JZ_FB_CMD_TVE_SET_PATH;
+ c->v = atoi(argv[2]);
+
+ rv = ioctl(fd, 0, &control);
+ if (rv) {
+ perror("ioctl");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ close(fd);
+
+ return 0;
+}
diff --git a/drivers/video/jz475x/userspace-config.h b/drivers/video/jz475x/userspace-config.h
new file mode 100644
index 00000000000..b95d4f21b56
--- /dev/null
+++ b/drivers/video/jz475x/userspace-config.h
@@ -0,0 +1,22 @@
+/*
+ * Ingenic JZ475X Display Controllers Driver.
+ *
+ * Copyright (C) 2005-2010 Ingenic Semiconductor Inc.
+ * Author: River Wang <zwang@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.
+ *
+ */
+
+#define CONFIG_SOC_JZ4750 1
diff --git a/drivers/video/jz4760_epd.c b/drivers/video/jz4760_epd.c
new file mode 100644
index 00000000000..8e0f1f8efb0
--- /dev/null
+++ b/drivers/video/jz4760_epd.c
@@ -0,0 +1,3079 @@
+/*
+ * linux/drivers/video/jz4760_lcd.c -- Ingenic Jz4760 LCD frame buffer device
+ *
+ * Copyright (C) 2005-2008, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * --------------------------------
+ * NOTE:
+ * This LCD driver support TFT16 TFT32 LCD, not support STN and Special TFT LCD
+ * now.
+ * It seems not necessory to support STN and Special TFT.
+ * If it's necessary, update this driver in the future.
+ * <Wolfgang Wang, Jun 10 2008>
+ */
+/*
+ * Added Electronic paper support <Cynthia zhao, Jun 2010>
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/pm.h>
+#include <linux/leds.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/jzsoc.h>
+
+#include "console/fbcon.h"
+
+#include "jz4760_epd.h"
+
+#include "jzepd.c"
+
+#define DRIVER_NAME "jz-lcd"
+
+#ifdef CONFIG_JZ4760_SLCD_KGM701A3_TFT_SPFD5420A
+#include "jz_kgm_spfd5420a.h"
+#endif
+
+MODULE_DESCRIPTION("Jz4760 LCD Controller driver");
+MODULE_AUTHOR("Wolfgang Wang <lgwang@ingenic.cn>, Lemon Liu <zyliu@ingenic.cn>");
+MODULE_LICENSE("GPL");
+
+#define LCD_DEBUG
+//#undef LCD_DEBUG
+
+#ifdef LCD_DEBUG
+#define dprintk(x...) printk(x)
+#define print_dbg(f, arg...) printk("dbg::" __FILE__ ",LINE(%d): " f "\n", __LINE__, ## arg)
+#else
+#define dprintk(x...)
+#define print_dbg(f, arg...) do {} while (0)
+#endif
+
+#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
+#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
+#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
+
+#define JZ_LCD_ID "jz-lcd"
+#define ANDROID_NUMBER_OF_BUFFERS 2
+
+struct lcd_cfb_info {
+ struct fb_info fb0; /* foreground 0 */
+ struct fb_info fb; /* foreground 1 */
+ struct display_switch *dispsw;
+ signed int currcon;
+ int func_use_count;
+
+ struct {
+ u16 red, green, blue;
+ } palette[NR_PALETTE];
+#ifdef CONFIG_PM
+ struct pm_dev *pm;
+#endif
+};
+
+static int lcd_backlight_level = 100;
+static struct lcd_cfb_info *jz4760fb_info;
+static int current_dma0_id, current_dma1_id;
+static struct jz4760_lcd_dma_desc *dma_desc_base;
+static struct jz4760_lcd_dma_desc *dma0_desc_palette, *dma0_desc0, *dma0_desc1, *dma1_desc0, *dma1_desc1;
+
+#define DMA_DESC_NUM 9
+
+unsigned char *lcd_palette;
+static unsigned char *lcd_frame0;
+static unsigned char *lcd_frame;
+
+#define EPD_MODE_PAL 1
+
+/*because sdram can't support above 16 frames, so we should do sth. By Cynthia 2010*/
+#define NR_DMA1_DESC_EPD 1
+#define NR_DMA_DESC_EPD_PER_GROUP 17 //16 frames + 1 palette
+#define NR_EPD_PAL 12 // 12 paletteswe should surport 12 palette, 16 frame per palette, so we can support 12*16=192frames
+#define NR_DMA_DESC_EPD NR_DMA_DESC_EPD_PER_GROUP*NR_EPD_PAL
+static unsigned int palette_offset = 16*16*4; //(Bytes) per frame is 16 word, totally 16frame per palette
+static struct jz4760_lcd_dma_desc *dma_desc_epd[NR_DMA_DESC_EPD];
+static struct jz4760_lcd_dma_desc *dma0_desc_palette_epd[NR_EPD_PAL];
+
+
+int use_fg1_only = 0;
+int use_fg0_only = 0;
+int use_2layer_Fg = 1;
+
+
+/*Cynthia zhao add end*/
+
+
+/* APP */
+
+static void jz4760fb_deep_set_mode( struct jz4760lcd_info * lcd_info );
+static void print_lcdc_registers(void);
+#ifdef CONFIG_FB_JZ4760_TVE
+static void jz4760lcd_info_switch_to_TVE(int mode);
+static void jz4760lcd_info_switch_to_lcd(void);
+#endif
+
+static int jz4760fb0_foreground_resize(struct jz4760lcd_osd_t *lcd_osd_info);
+static int jz4760fb0_foreground_move(struct jz4760lcd_osd_t *lcd_osd_info);
+
+static int jz4760fb_foreground_resize(struct jz4760lcd_osd_t *lcd_osd_info);
+static int jz4760fb_foreground_move(struct jz4760lcd_osd_t *lcd_osd_info);
+
+
+struct jz4760lcd_info jz4760_lcd_panel = {
+#if defined(CONFIG_JZ4760_LCD_SAMSUNG_LTP400WQF02)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_18BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 480, 272, 60, 41, 10, 2, 2, 2, 2,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN, /* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_AUO_A043FL01V2)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 480, 272, 60, 41, 10, 8, 4, 4, 2,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | LCD_OSDC_ALPHAEN,// | /* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0x80000000, /* disable colorkey */
+// .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xff, /* alpha value */
+// .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_SLCD | /* Underrun recover*/
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SLCD, /* TFT Smart LCD panel */
+ .slcd_cfg = SLCD_CFG_DWIDTH_16BIT | SLCD_CFG_CWIDTH_16BIT | SLCD_CFG_CS_ACTIVE_LOW | SLCD_CFG_RS_CMD_LOW | SLCD_CFG_CLK_ACTIVE_FALLING | SLCD_CFG_TYPE_PARALLEL,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 240, 320, 60, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN,/* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 240, 320}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 240, 320}, /* bpp, x, y, w, h */
+ },
+
+#elif defined(CONFIG_JZ4760_LCD_FOXCONN_PT035TN01)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 24bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP | /* Vsync polarity: leading edge is falling edge */
+ LCD_CFG_PCP, /* Pix-CLK polarity: data translations at falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 320, 240, 80, 1, 1, 10, 50, 10, 13
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN, /* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SERIAL_TFT | /* Serial TFT panel */
+ LCD_CFG_MODE_TFT_18BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP | /* Vsync polarity: leading edge is falling edge */
+ LCD_CFG_PCP, /* Pix-CLK polarity: data translations at falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 320, 240, 60, 1, 1, 10, 50, 10, 13
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN, /* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_SLCD_KGM701A3_TFT_SPFD5420A)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_SLCD | /* Underrun recover*/
+// LCD_CFG_DITHER | /* dither */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SLCD, /* TFT Smart LCD panel */
+ .slcd_cfg = SLCD_CFG_DWIDTH_18BIT | SLCD_CFG_CWIDTH_18BIT | SLCD_CFG_CS_ACTIVE_LOW | SLCD_CFG_RS_CMD_LOW | SLCD_CFG_CLK_ACTIVE_FALLING | SLCD_CFG_TYPE_PARALLEL,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 400, 240, 60, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN, /* Use OSD mode */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 400, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 400, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_VGA_DISPLAY)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER |/* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+// 800, 600, 60, 128, 4, 40, 88, 0, 23
+ 640, 480, 54, 96, 2, 16, 48, 10, 33
+// 1280, 720, 50, 152, 15, 22, 200, 14, 1
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 640, 480}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 640, 480}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER |/* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_32, /* 16words burst, enable out FIFO underrun irq */
+ 800, 600, 60, 128, 4, 40, 88, 0, 23
+
+// 1280, 720, 50, 152, 15, 22, 200, 14, 1
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+#if EPD_MODE_PAL
+ LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+#else
+ LCD_OSDC_F1EN,
+#endif
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0x0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+#if EPD_MODE_PAL
+
+ .fg0 = {4, 0, 0, 800, 600}, /* bpp, x, y, w, h */
+// .fg0 = {4, 0, 0, 0, 0}, /* bpp, x, y, w, h */
+ .fg1 = {4, 0, 0, 800, 600}, /* bpp, x, y, w, h */
+#else
+
+ .fg0 = {2, 0, 0, 800, 600}, /* bpp, x, y, w, h */
+// .fg0 = {4, 0, 0, 0, 0}, /* bpp, x, y, w, h */
+ .fg1 = {2, 0, 0, 800, 600}, /* bpp, x, y, w, h */
+#endif
+ },
+#else
+#error "Select LCD panel first!!!"
+#endif
+};
+
+#ifdef CONFIG_FB_JZ4760_TVE
+struct jz4760lcd_info jz4760_info_tve = {
+ .panel = {
+ .w = TVE_WIDTH_PAL, TVE_HEIGHT_PAL, TVE_FREQ_PAL, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .rgb_ctrl = LCD_RGBC_YCC, /* enable RGB => YUV */
+ .fg0 = {32,}, /* */
+ .fg1 = {32,},
+ },
+};
+#endif
+
+struct jz4760lcd_info *jz4760_lcd_info = &jz4760_lcd_panel; /* default output to lcd panel */
+
+
+
+static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+void print_epd_regs(void)
+{
+ printk("REG_EPD_CTRL1 \t= 0x%08x\n",REG_EPD_CTRL1);
+ printk("REG_EPD_CTRL2 \t= 0x%08x\n",REG_EPD_CTRL2);
+ printk("REG_EPD_CTRL3 \t= 0x%08x\n",REG_EPD_CTRL3);
+ printk("REG_EPD_CTRL4 \t= 0x%08x\n",REG_EPD_CTRL4);
+ printk("REG_EPD_CTRL5 \t= 0x%08x\n",REG_EPD_CTRL5);
+ printk("REG_EPD_CTRL6 \t= 0x%08x\n",REG_EPD_CTRL6);
+ printk("REG_EPD_CTRL7 \t= 0x%08x\n",REG_EPD_CTRL7);
+ printk("REG_EPD_CTRL8 \t= 0x%08x\n",REG_EPD_CTRL8);
+ printk("REG_EPD_CTRL9 \t= 0x%08x\n",REG_EPD_CTRL9);
+ printk("REG_LCD_VAT \t= 0x%08x\n",REG_LCD_VAT);
+ printk("REG_LCD_PS \t= 0x%08x\n",REG_LCD_PS);
+ printk("REG_LCD_CLS \t= 0x%08x\n",REG_LCD_CLS);
+ printk("REG_LCD_VSYNC \t= 0x%08x\n",REG_LCD_VSYNC);
+ printk("REG_LCD_HSYNC \t= 0x%08x\n",REG_LCD_HSYNC);
+ printk("\n");
+ printk("REG_EPD_CTRL1 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL1);
+ printk("REG_EPD_CTRL2 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL2);
+ printk("REG_EPD_CTRL3 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL3);
+ printk("REG_EPD_CTRL4 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL4);
+ printk("REG_EPD_CTRL5 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL5);
+ printk("REG_EPD_CTRL6 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL6);
+ printk("REG_EPD_CTRL7 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL7);
+ printk("REG_EPD_CTRL8 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL8);
+ printk("REG_EPD_CTRL9 \t= 0x%08x\n",(unsigned int)&REG_EPD_CTRL9);
+ printk("REG_LCD_VAT \t= 0x%08x\n",(unsigned int)&REG_LCD_VAT);
+ printk("REG_LCD_PS \t= 0x%08x\n",(unsigned int)&REG_LCD_PS);
+ printk("REG_LCD_CLS \t= 0x%08x\n",(unsigned int)&REG_LCD_CLS);
+ printk("REG_LCD_VSYNC \t= 0x%08x\n",(unsigned int)&REG_LCD_VSYNC);
+ printk("REG_LCD_HSYNC \t= 0x%08x\n",(unsigned int)&REG_LCD_HSYNC);
+
+ printk("REG_LCD_XYP0 \t= 0x%X\n",REG_LCD_XYP0);
+ printk("REG_LCD_XYP1 \t= 0x%X\n",REG_LCD_XYP1);
+ printk("REG_LCD_SIZE0 \t= 0x%X\n",REG_LCD_SIZE0);
+ printk("REG_LCD_SIZE1 \t= 0x%X\n",REG_LCD_SIZE1);
+ printk("REG_LCD_OSDCTRL \t= 0x%X\n",REG_LCD_OSDCTRL);
+ printk("REG_LCD_OSDC \t= 0x%X\n",REG_LCD_OSDC);
+
+
+ /* LCD Controller Resgisters */
+ printk("REG_LCD_CFG:\t0x%08x\n", REG_LCD_CFG);
+ printk("REG_LCD_CTRL:\t0x%08x\n", REG_LCD_CTRL);
+ printk("REG_LCD_STATE:\t0x%08x\n", REG_LCD_STATE);
+ printk("REG_LCD_OSDC:\t0x%08x\n", REG_LCD_OSDC);
+ printk("REG_LCD_OSDCTRL:\t0x%08x\n", REG_LCD_OSDCTRL);
+ printk("REG_LCD_OSDS:\t0x%08x\n", REG_LCD_OSDS);
+ printk("REG_LCD_BGC:\t0x%08x\n", REG_LCD_BGC);
+ printk("REG_LCD_KEK0:\t0x%08x\n", REG_LCD_KEY0);
+ printk("REG_LCD_KEY1:\t0x%08x\n", REG_LCD_KEY1);
+ printk("REG_LCD_ALPHA:\t0x%08x\n", REG_LCD_ALPHA);
+ printk("REG_LCD_IPUR:\t0x%08x\n", REG_LCD_IPUR);
+ printk("REG_LCD_VAT:\t0x%08x\n", REG_LCD_VAT);
+ printk("REG_LCD_DAH:\t0x%08x\n", REG_LCD_DAH);
+ printk("REG_LCD_DAV:\t0x%08x\n", REG_LCD_DAV);
+ printk("REG_LCD_XYP0:\t0x%08x\n", REG_LCD_XYP0);
+ printk("REG_LCD_XYP1:\t0x%08x\n", REG_LCD_XYP1);
+ printk("REG_LCD_SIZE0:\t0x%08x\n", REG_LCD_SIZE0);
+ printk("REG_LCD_SIZE1:\t0x%08x\n", REG_LCD_SIZE1);
+ printk("REG_LCD_RGBC\t0x%08x\n", REG_LCD_RGBC);
+ printk("REG_LCD_VSYNC:\t0x%08x\n", REG_LCD_VSYNC);
+ printk("REG_LCD_HSYNC:\t0x%08x\n", REG_LCD_HSYNC);
+ printk("REG_LCD_PS:\t0x%08x\n", REG_LCD_PS);
+ printk("REG_LCD_CLS:\t0x%08x\n", REG_LCD_CLS);
+ printk("REG_LCD_SPL:\t0x%08x\n", REG_LCD_SPL);
+ printk("REG_LCD_REV:\t0x%08x\n", REG_LCD_REV);
+ printk("REG_LCD_IID:\t0x%08x\n", REG_LCD_IID);
+ printk("REG_LCD_DA0:\t0x%08x\n", REG_LCD_DA0);
+ printk("REG_LCD_SA0:\t0x%08x\n", REG_LCD_SA0);
+ printk("REG_LCD_FID0:\t0x%08x\n", REG_LCD_FID0);
+ printk("REG_LCD_CMD0:\t0x%08x\n", REG_LCD_CMD0);
+ printk("REG_LCD_OFFS0:\t0x%08x\n", REG_LCD_OFFS0);
+ printk("REG_LCD_PW0:\t0x%08x\n", REG_LCD_PW0);
+ printk("REG_LCD_CNUM0:\t0x%08x\n", REG_LCD_CNUM0);
+ printk("REG_LCD_DESSIZE0:\t0x%08x\n", REG_LCD_DESSIZE0);
+ printk("REG_LCD_DA1:\t0x%08x\n", REG_LCD_DA1);
+ printk("REG_LCD_SA1:\t0x%08x\n", REG_LCD_SA1);
+ printk("REG_LCD_FID1:\t0x%08x\n", REG_LCD_FID1);
+ printk("REG_LCD_CMD1:\t0x%08x\n", REG_LCD_CMD1);
+ printk("REG_LCD_OFFS1:\t0x%08x\n", REG_LCD_OFFS1);
+ printk("REG_LCD_PW1:\t0x%08x\n", REG_LCD_PW1);
+ printk("REG_LCD_CNUM1:\t0x%08x\n", REG_LCD_CNUM1);
+ printk("REG_LCD_DESSIZE1:\t0x%08x\n", REG_LCD_DESSIZE1);
+ printk("==================================\n");
+ printk("REG_LCD_VSYNC:\t%d:%d\n", REG_LCD_VSYNC>>16, REG_LCD_VSYNC&0xfff);
+ printk("REG_LCD_HSYNC:\t%d:%d\n", REG_LCD_HSYNC>>16, REG_LCD_HSYNC&0xfff);
+ printk("REG_LCD_VAT:\t%d:%d\n", REG_LCD_VAT>>16, REG_LCD_VAT&0xfff);
+ printk("REG_LCD_DAH:\t%d:%d\n", REG_LCD_DAH>>16, REG_LCD_DAH&0xfff);
+ printk("REG_LCD_DAV:\t%d:%d\n", REG_LCD_DAV>>16, REG_LCD_DAV&0xfff);
+ printk("==================================\n");
+
+ /* Smart LCD Controller Resgisters */
+ printk("REG_SLCD_CFG:\t0x%08x\n", REG_SLCD_CFG);
+ printk("REG_SLCD_CTRL:\t0x%08x\n", REG_SLCD_CTRL);
+ printk("REG_SLCD_STATE:\t0x%08x\n", REG_SLCD_STATE);
+ printk("==================================\n");
+
+ /* TVE Controller Resgisters */
+ printk("REG_TVE_CTRL:\t0x%08x\n", REG_TVE_CTRL);
+ printk("REG_TVE_FRCFG:\t0x%08x\n", REG_TVE_FRCFG);
+ printk("REG_TVE_SLCFG1:\t0x%08x\n", REG_TVE_SLCFG1);
+ printk("REG_TVE_SLCFG2:\t0x%08x\n", REG_TVE_SLCFG2);
+ printk("REG_TVE_SLCFG3:\t0x%08x\n", REG_TVE_SLCFG3);
+ printk("REG_TVE_LTCFG1:\t0x%08x\n", REG_TVE_LTCFG1);
+ printk("REG_TVE_LTCFG2:\t0x%08x\n", REG_TVE_LTCFG2);
+ printk("REG_TVE_CFREQ:\t0x%08x\n", REG_TVE_CFREQ);
+ printk("REG_TVE_CPHASE:\t0x%08x\n", REG_TVE_CPHASE);
+ printk("REG_TVE_CBCRCFG:\t0x%08x\n", REG_TVE_CBCRCFG);
+ printk("REG_TVE_WSSCR:\t0x%08x\n", REG_TVE_WSSCR);
+ printk("REG_TVE_WSSCFG1:\t0x%08x\n", REG_TVE_WSSCFG1);
+ printk("REG_TVE_WSSCFG2:\t0x%08x\n", REG_TVE_WSSCFG2);
+ printk("REG_TVE_WSSCFG3:\t0x%08x\n", REG_TVE_WSSCFG3);
+
+ printk("==================================\n");
+
+ if ( 0 ) {
+ unsigned int * pii = (unsigned int *)dma_desc_base;
+ int i, j;
+ for (j=0;j< DMA_DESC_NUM ; j++) {
+ printk("dma_desc%d(0x%08x):\n", j, (unsigned int)pii);
+ for (i =0; i<8; i++ ) {
+ printk("\t\t0x%08x\n", *pii++);
+ }
+ }
+ }
+
+
+ if ( 0 ) {
+ unsigned int * pii = (unsigned int *)dma_desc_base;
+ int i, j;
+ for (j=0;j< NR_DMA_DESC_EPD ; j++) {
+ printk("zhihui::dma_desc%d(0x%08x):\n", j, (unsigned int)pii);
+ for (i =0; i<8; i++ ) {
+ printk("\t\t0x%08x\n", *pii++);
+ }
+ }
+ }
+
+
+}
+
+void init_epd_controller(void)
+{
+
+ REG_EPD_CTRL1 = 0x04ea6600; /*c0*/ //for eink
+// REG_EPD_CTRL1 = 0x04ea4600; /*c0*/ // for oed 20100607
+// REG_EPD_CTRL1 = 0x04ea7600; /*c0*/
+ REG_EPD_CTRL2 = 0x0fa20c82; /*c0*/
+ REG_EPD_CTRL3 = 0x00320032; /*c0*/
+ REG_EPD_CTRL4 = 0xff01580e; /*cc*/
+
+ REG_EPD_CTRL4 = (0xff01580e); /*cc*/ //epd dma interrupt enable
+
+// REG_EPD_CTRL4 = 0xff01500e; /*cc*/ /* each frame irq enable */
+ REG_EPD_CTRL5 = 0x035a1024; /*d0*/ /* each update irq enable */
+// REG_EPD_CTRL5 = 0x035a2525; /*d0*/ /* each update irq enable */
+ REG_EPD_CTRL6 = 0x01ad01ad; /*d4*/
+ REG_EPD_CTRL7 = 0x04e40034; /*d8*/
+ REG_EPD_CTRL8 = 0x00010001; /*dc*/
+ REG_EPD_CTRL9 = 0x00010001; /*e0*/
+ REG_LCD_VAT = 0x04ea026a; /* 0c*/
+// REG_LCD_PS = 0x00380358; /*18*/
+// REG_LCD_CLS = 0x00080260; /*1c*/
+ REG_LCD_PS = 0x00380358; /*18*/
+ REG_LCD_CLS = 0x00080260; /*1c*/
+
+ REG_LCD_VSYNC = 0x00000004; /*04*/
+ REG_LCD_HSYNC = 0x04ea0028; /*08*/
+
+ REG_SLCD_CTRL |= SLCD_CTRL_DMA_MODE;
+
+ __lcd_set_ena();
+
+ print_epd_regs();
+
+ REG_EPD_CTRL5 |= 1<<0 ;//EPD_CTRL5_EPD_EN;
+
+}
+
+#endif
+
+/************************************
+ * Jz475X Framebuffer ops
+ ************************************/
+
+static int jz4760fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+
+ if (use_fg1_only || use_2layer_Fg){
+
+ struct fb_info *fb = info;
+ if (regno >= NR_PALETTE)
+ return 1;
+ if (fb->var.bits_per_pixel <= 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ red &= 0xff;
+ green &= 0xff;
+ blue &= 0xff;
+ }
+
+ switch (fb->var.bits_per_pixel) {
+ case 15:
+ if (regno < 16)
+ ((u32 *)fb->pseudo_palette)[regno] =
+ ((red >> 3) << 10) |
+ ((green >> 3) << 5) |
+ (blue >> 3);
+ break;
+ case 16:
+ if (regno < 16) {
+ ((u32 *)fb->pseudo_palette)[regno] =
+ ((red >> 3) << 11) |
+ ((green >> 2) << 5) |
+ (blue >> 3);
+ }
+ break;
+ case 30:
+ if (regno < 16)
+ ((u32 *)fb->pseudo_palette)[regno] =
+ (red << 20) |
+ (green << 10) |
+ (blue << 0);
+ case 17 ... 29:
+ case 31 ... 32:
+ if (regno < 16)
+ ((u32 *)fb->pseudo_palette)[regno] =
+ (red << 16) |
+ (green << 8) |
+ (blue << 0);
+
+ break;
+ }
+
+ }
+ if (use_fg0_only || use_2layer_Fg){
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ unsigned short *ptr, ctmp;
+
+ if (regno >= NR_PALETTE)
+ return 1;
+
+ cfb->palette[regno].red = red ;
+ cfb->palette[regno].green = green;
+ cfb->palette[regno].blue = blue;
+ if (cfb->fb0.var.bits_per_pixel <= 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ red &= 0xff;
+ green &= 0xff;
+ blue &= 0xff;
+ }
+ switch (cfb->fb0.var.bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (((jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_SINGLE_MSTN ) ||
+ ((jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_DUAL_MSTN )) {
+ ctmp = (77L * red + 150L * green + 29L * blue) >> 8;
+ ctmp = ((ctmp >> 3) << 11) | ((ctmp >> 2) << 5) |
+ (ctmp >> 3);
+ } else {
+ /* RGB 565 */
+ if (((red >> 3) == 0) && ((red >> 2) != 0))
+ red = 1 << 3;
+ if (((blue >> 3) == 0) && ((blue >> 2) != 0))
+ blue = 1 << 3;
+ ctmp = ((red >> 3) << 11)
+ | ((green >> 2) << 5) | (blue >> 3);
+ }
+
+ ptr = (unsigned short *)lcd_palette;
+ ptr = (unsigned short *)(((u32)ptr)|0xa0000000);
+ ptr[regno] = ctmp;
+
+ break;
+
+ case 15:
+ if (regno < 16)
+ ((u32 *)cfb->fb0.pseudo_palette)[regno] =
+ ((red >> 3) << 10) |
+ ((green >> 3) << 5) |
+ (blue >> 3);
+ break;
+ case 16:
+ if (regno < 16) {
+ ((u32 *)cfb->fb0.pseudo_palette)[regno] =
+ ((red >> 3) << 11) |
+ ((green >> 2) << 5) |
+ (blue >> 3);
+ }
+ break;
+ case 17 ... 29:
+ case 31 ... 32:
+ if (regno < 16)
+ ((u32 *)cfb->fb0.pseudo_palette)[regno] =
+ (red << 16) |
+ (green << 8) |
+ (blue << 0);
+
+
+ break;
+ }
+
+
+
+
+ }
+
+ return 0;
+
+}
+static int jz4760fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ void __user *argp = (void __user *)arg;
+
+
+ switch (cmd) {
+
+ case GET_EPD_INFO:
+ {
+
+ struct epd_info {
+ void * frame_index_buffer;
+ unsigned long frame_index_buffer_phys;
+ unsigned long frame_index_buffer_size;
+ void * frame_buffer_old;
+ unsigned long frame_buffer_old_phys;
+ unsigned long frame_buffer_old_size;
+ void * frame_buffer_new;
+ unsigned long frame_buffer_new_phys;
+ unsigned long frame_buffer_new_size;
+ }epd;
+ epd.frame_index_buffer = lcd_palette;
+ epd.frame_index_buffer_phys = virt_to_phys(lcd_palette);
+ epd.frame_index_buffer_size = 4096;
+
+ epd.frame_buffer_old = lcd_frame;
+ epd.frame_buffer_old_phys = virt_to_phys(lcd_frame);
+
+ epd.frame_buffer_old_size = 800*600/2;
+ epd.frame_buffer_new = lcd_frame0;
+ epd.frame_buffer_new_phys = virt_to_phys(lcd_frame0);
+
+ epd.frame_buffer_new_size = 800*600/2;
+ copy_to_user(argp, &epd, sizeof(epd));
+
+
+ break;
+ }
+ case START_EPD_TRANS:
+ {
+
+ REG_EPD_CTRL2 |= EPD_CTRL2_PWRON;
+ __lcd_clr_ena();
+
+ break;
+ }
+ case SET_EPD_MOD:
+ {
+ set_epd_mod(arg);
+ break;
+ }
+
+ case SET_GRAY_LEVEL:
+ {
+ epd_gray_level = *(unsigned long *)arg;
+ break;
+ }
+ case SET_HAND_WRITING:
+ {
+ handwriting_palette();
+ break;
+ }
+ case SET_HAND_WRITING_DMA:
+ {
+ REG_LCD_OSDCTRL &= ~0x7 ;
+ REG_LCD_OSDCTRL |= 1 << 0 ;
+ REG_LCD_OSDC &= ~(1<<3);
+ REG_LCD_CMD1 = (800*600/2)/8;
+ use_fg1_only=1;
+ use_fg0_only=0;
+ use_2layer_Fg =0;
+ break;
+ }
+ case CANCEL_HANDWRITING_DMA:
+ {
+ REG_LCD_OSDCTRL &= ~0x7 ;
+ REG_LCD_OSDCTRL |= 1 << 1 ;
+ REG_LCD_OSDC |= (1<<3);
+ REG_LCD_CMD1 = (800*600/2)/4;
+ use_fg1_only=0;
+ use_2layer_Fg =1;
+ break;
+ }
+
+ default:
+ printk("%s, unknown command(0x%x)", __FILE__, cmd);
+ break;
+ }
+
+ return ret;
+}
+
+
+/* Use mmap /dev/fb can only get a non-cacheable Virtual Address. */
+static int jz4760fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ if (use_fg1_only || use_2layer_Fg){
+ struct fb_info *fb = info;
+ unsigned long start;
+ unsigned long off;
+ u32 len;
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ //fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
+
+ /* frame buffer memory */
+ start = fb->fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + fb->fix.smem_len);
+ start &= PAGE_MASK;
+
+ if ((vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Uncacheable */
+
+
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ }
+ if (use_fg1_only || use_2layer_Fg){
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ unsigned long start;
+ unsigned long off;
+ u32 len;
+
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ //fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
+
+ /* frame buffer memory */
+ start = cfb->fb0.fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + cfb->fb0.fix.smem_len);
+ start &= PAGE_MASK;
+
+ if ((vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Uncacheable */
+
+
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ }
+ return 0;
+}
+
+
+/* checks var and eventually tweaks it to something supported,
+ * DO NOT MODIFY PAR */
+static int jz4760fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+
+ if((var->rotate & 1) != (info->var.rotate & 1)) {
+ if((var->xres != info->var.yres) ||
+ (var->yres != info->var.xres) ||
+ (var->xres_virtual != info->var.yres) ||
+ (var->yres_virtual >
+ info->var.xres * ANDROID_NUMBER_OF_BUFFERS) ||
+ (var->yres_virtual < info->var.xres )) {
+ return -EINVAL;
+ }
+ }
+ else {
+ if((var->xres != info->var.xres) ||
+ (var->yres != info->var.yres) ||
+ (var->xres_virtual != info->var.xres) ||
+ (var->yres_virtual >
+ info->var.yres * ANDROID_NUMBER_OF_BUFFERS) ||
+ (var->yres_virtual < info->var.yres )) {
+ return -EINVAL;
+ }
+ }
+ if((var->xoffset != info->var.xoffset) ||
+ (var->bits_per_pixel != info->var.bits_per_pixel)) {// ||
+// (var->grayscale != info->var.grayscale)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+/*
+ * set the video mode according to info->var
+ */
+static int jz4760fb_set_par(struct fb_info *info)
+{
+ dprintk("jz4760fb_set_par, not implemented\n");
+ return 0;
+}
+
+
+/*
+ * (Un)Blank the display.
+ * Fix me: should we use VESA value?
+ */
+static int jz4760fb_blank(int blank_mode, struct fb_info *info)
+{
+ printk("jz4760 fb_blank %d %p", blank_mode, info);
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ //case FB_BLANK_NORMAL:
+ /* Turn on panel */
+ __lcd_set_ena();
+ __lcd_display_on();
+ break;
+
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+ /* Turn off panel */
+ break;
+ default:
+ break;
+
+ }
+ return 0;
+}
+
+/*
+ * pan display
+ */
+static int jz4760fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct fb_info *fb = info;
+ int dy;
+ if (!var || !fb) {
+ return -EINVAL;
+ }
+
+ if (var->xoffset - fb->var.xoffset) {
+ /* No support for X panning for now! */
+ return -EINVAL;
+ }
+ /* TODO: Wait for current frame to finished */
+ dy = var->yoffset;// - fb->var.yoffset;
+ if(use_fg1_only){
+ if (dy) {
+ dma1_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame + (fb->fix.line_length * dy));
+ dma_cache_wback((unsigned int)(dma1_desc0), sizeof(struct jz4760_lcd_dma_desc));
+
+ }
+ else {
+ dma1_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame);
+ dma_cache_wback((unsigned int)(dma1_desc0), sizeof(struct jz4760_lcd_dma_desc));
+ }
+ }
+ else{
+ if (dy) {
+ dma0_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame0 + (fb->fix.line_length * dy));
+ dma_cache_wback((unsigned int)(dma0_desc0), sizeof(struct jz4760_lcd_dma_desc));
+
+ }
+ else {
+ dma0_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame0);
+ dma_cache_wback((unsigned int)(dma0_desc0), sizeof(struct jz4760_lcd_dma_desc));
+ }
+ }
+ return 0;
+}
+
+
+static struct fb_ops jz4760fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = jz4760fb_setcolreg,
+ .fb_check_var = jz4760fb_check_var,
+ .fb_set_par = jz4760fb_set_par,
+ .fb_blank = jz4760fb_blank,
+ .fb_pan_display = jz4760fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = jz4760fb_mmap,
+ .fb_ioctl = jz4760fb_ioctl,
+};
+
+static int jz4760fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+
+ struct fb_info *fb = info;
+ struct jz4760lcd_info *lcd_info = jz4760_lcd_info;
+ int chgvar = 0;
+
+ if (con == 0) {
+ var->height = lcd_info->osd.fg0.h; /* tve mode */
+ var->width = lcd_info->osd.fg0.w;
+ var->bits_per_pixel = lcd_info->osd.fg0.bpp;
+ }
+ else {
+ var->height = lcd_info->osd.fg1.h;
+ var->width = lcd_info->osd.fg1.w;
+ var->bits_per_pixel = lcd_info->osd.fg1.bpp;
+ }
+
+ var->vmode = FB_VMODE_NONINTERLACED;
+// var->vmode = FB_VMODE_DOUBLE
+ var->activate = fb->var.activate;
+ var->xres = var->width;
+ var->yres = var->height;
+ var->xres_virtual = var->width;
+ var->yres_virtual = var->height * ANDROID_NUMBER_OF_BUFFERS;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->pixclock = KHZ2PICOS(jz_clocks.pixclk/1000);
+
+ var->left_margin = lcd_info->panel.elw;
+ var->right_margin = lcd_info->panel.blw;
+ var->upper_margin = lcd_info->panel.efw;
+ var->lower_margin = lcd_info->panel.bfw;
+ var->hsync_len = lcd_info->panel.hsw;
+ var->vsync_len = lcd_info->panel.vsw;
+ var->sync = 0;
+ var->activate = FB_ACTIVATE_NOW;
+
+
+ /*
+ * CONUPDATE and SMOOTH_XPAN are equal. However,
+ * SMOOTH_XPAN is only used internally by fbcon.
+ */
+ if (var->vmode & FB_VMODE_CONUPDATE) {
+ var->vmode |= FB_VMODE_YWRAP;
+ var->xoffset = fb->var.xoffset;
+ var->yoffset = fb->var.yoffset;
+ }
+
+ if (var->activate & FB_ACTIVATE_TEST)
+ return 0;
+
+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+ return -EINVAL;
+
+ if (fb->var.xres != var->xres)
+ chgvar = 1;
+ if (fb->var.yres != var->yres)
+ chgvar = 1;
+ if (fb->var.xres_virtual != var->xres_virtual)
+ chgvar = 1;
+ if (fb->var.yres_virtual != var->yres_virtual)
+ chgvar = 1;
+ if (fb->var.bits_per_pixel != var->bits_per_pixel)
+ chgvar = 1;
+
+ //display = fb_display + con;
+
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+
+ switch(var->bits_per_pixel){
+ case 1: /* Mono */
+ fb->fix.visual = FB_VISUAL_MONO01;
+ fb->fix.line_length = (var->xres * var->bits_per_pixel) / 8;
+ break;
+ case 2: /* Mono */
+ var->red.offset = 0;
+ var->red.length = 2;
+ var->green.offset = 0;
+ var->green.length = 2;
+ var->blue.offset = 0;
+ var->blue.length = 2;
+
+ fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ fb->fix.line_length = (var->xres * var->bits_per_pixel) / 8;
+ break;
+ case 4: /* PSEUDOCOLOUR*/
+ var->red.offset = 0;
+ var->red.length = 4;
+ var->green.offset = 0;
+ var->green.length = 4;
+ var->blue.offset = 0;
+ var->blue.length = 4;
+
+ fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ fb->fix.line_length = var->xres / 2;
+ break;
+ case 8: /* PSEUDOCOLOUR, 256 */
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+
+ fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ fb->fix.line_length = var->xres ;
+ break;
+ case 15: /* DIRECTCOLOUR, 32k */
+ var->bits_per_pixel = 15;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ fb->fix.visual = FB_VISUAL_DIRECTCOLOR;
+ fb->fix.line_length = var->xres_virtual * 2;
+ break;
+ case 16: /* DIRECTCOLOUR, 64k */
+ var->bits_per_pixel = 16;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ fb->fix.visual = FB_VISUAL_TRUECOLOR;
+ fb->fix.line_length = var->xres_virtual * 2;
+ break;
+ case 30:
+ /* DIRECTCOLOUR, 256 */
+ var->bits_per_pixel = 32;
+
+ var->red.offset = 20;
+ var->red.length = 10;
+ var->green.offset = 10;
+ var->green.length = 10;
+ var->blue.offset = 0;
+ var->blue.length = 10;
+ var->transp.offset = 30;
+ var->transp.length = 2;
+
+ fb->fix.visual = FB_VISUAL_TRUECOLOR;
+ fb->fix.line_length = var->xres_virtual * 4;
+ break;
+ case 17 ... 29:
+ case 31 ... 32:
+ /* DIRECTCOLOUR, 256 */
+ var->bits_per_pixel = 32;
+
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+
+ fb->fix.visual = FB_VISUAL_TRUECOLOR;
+ fb->fix.line_length = var->xres_virtual * 4;
+ break;
+
+ default: /* in theory this should never happen */
+ printk(KERN_WARNING "%s: don't support for %dbpp\n",
+ fb->fix.id, var->bits_per_pixel);
+ break;
+ }
+
+ fb->var = *var;
+ fb->var.activate &= ~FB_ACTIVATE_ALL;
+
+ /*
+ * Update the old var. The fbcon drivers still use this.
+ * Once they are using cfb->fb.var, this can be dropped.
+ * --rmk
+ */
+ //display->var = cfb->fb.var;
+ /*
+ * If we are setting all the virtual consoles, also set the
+ * defaults used to create new consoles.
+ */
+ fb_set_cmap(&fb->cmap, fb);
+ return 0;
+}
+
+static struct lcd_cfb_info * jz4760fb_alloc_fb_info(void)
+{
+ struct lcd_cfb_info *cfb;
+ cfb = kmalloc(sizeof(struct lcd_cfb_info) + sizeof(u32) * 16, GFP_KERNEL);
+
+ if (!cfb)
+ return NULL;
+
+ jz4760fb_info = cfb;
+
+ memset(cfb, 0, sizeof(struct lcd_cfb_info) );
+
+ cfb->currcon = -1;
+
+ if (use_fg1_only || use_2layer_Fg){
+ /* Foreground 1 -- fb */
+ strcpy(cfb->fb.fix.id, "jzlcd-fg1");
+ cfb->fb.flags = FBINFO_FLAG_DEFAULT;
+ cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ cfb->fb.fix.type_aux = 0;
+ cfb->fb.fix.xpanstep = 1;
+ cfb->fb.fix.ypanstep = 1;
+ cfb->fb.fix.ywrapstep = 0;
+ cfb->fb.fix.accel = FB_ACCEL_NONE;
+
+ cfb->fb.var.nonstd = 0;
+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
+ cfb->fb.var.height = -1;
+ cfb->fb.var.width = -1;
+ cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
+
+ cfb->fb.fbops = &jz4760fb_ops;
+ cfb->fb.flags = FBINFO_FLAG_DEFAULT;
+
+ cfb->fb.pseudo_palette = (void *)(cfb + 1);
+
+ switch (jz4760_lcd_info->osd.fg1.bpp) {
+ case 1:
+ fb_alloc_cmap(&cfb->fb.cmap, 4, 0);
+ break;
+ case 2:
+ fb_alloc_cmap(&cfb->fb.cmap, 8, 0);
+ break;
+ case 4:
+ fb_alloc_cmap(&cfb->fb.cmap, 32, 0);
+ break;
+ case 8:
+
+ default:
+ fb_alloc_cmap(&cfb->fb.cmap, 256, 0);
+ break;
+ }
+ }
+
+ if (use_fg0_only || use_2layer_Fg){
+ /* Foreground 0 -- fb0 */
+ strcpy(cfb->fb0.fix.id, "jzlcd-fg0");
+ cfb->fb0.fix.type = FB_TYPE_PACKED_PIXELS;
+ cfb->fb0.fix.type_aux = 0;
+ cfb->fb0.fix.xpanstep = 1;
+ cfb->fb0.fix.ypanstep = 1;
+ cfb->fb0.fix.ywrapstep = 0;
+ cfb->fb0.fix.accel = FB_ACCEL_NONE;
+
+ cfb->fb0.var.nonstd = 0;
+ cfb->fb0.var.activate = FB_ACTIVATE_NOW;
+ cfb->fb0.var.height = -1;
+ cfb->fb0.var.width = -1;
+ cfb->fb0.var.accel_flags = FB_ACCELF_TEXT;
+
+ cfb->fb0.fbops = &jz4760fb_ops;
+ cfb->fb0.flags = FBINFO_FLAG_DEFAULT;
+
+ cfb->fb0.pseudo_palette = (void *)(cfb + 1);
+
+ switch (jz4760_lcd_info->osd.fg0.bpp) {
+ case 1:
+ fb_alloc_cmap(&cfb->fb0.cmap, 4, 0);
+ break;
+ case 2:
+ fb_alloc_cmap(&cfb->fb0.cmap, 8, 0);
+ break;
+ case 4:
+ fb_alloc_cmap(&cfb->fb0.cmap, 32, 0);
+ break;
+ case 8:
+
+ default:
+ fb_alloc_cmap(&cfb->fb0.cmap, 256, 0);
+ break;
+ }
+ }
+ dprintk("fb_alloc_cmap, fb.cmap.len:%d, fb0.cmap.len:%d....\n", cfb->fb.cmap.len, cfb->fb0.cmap.len);
+ return cfb;
+}
+static void fill_fb_newbuff(unsigned char *fb)
+{
+ int i,j;
+ unsigned char *c = (unsigned char *)fb;
+ unsigned char dat = 0;
+#if EPD_MODE_PAL
+ memset(c,0xff,800*600/4);
+ return;
+#endif
+ for(i = 0;i < 600;i++)
+ for(j = 0; j < 400;j++)
+ {
+
+ *c = (dat & 0xf) | (((dat + 1) & 0xf) << 4);
+ c++;
+ dat += 2;
+
+ }
+
+
+}
+static void fill_fb_oldbuff(unsigned char *fb)
+{
+ int i,j,count = 1;
+ unsigned char *csave = (unsigned char *)fb;
+ unsigned char *c = csave;
+ unsigned char dat = 0;
+#if EPD_MODE_PAL
+ memset(c,0xff,800*600/4);
+ return;
+#endif
+ for(i = 0;i < 600;i++)
+ for(j = 0; j < 400;j++)
+ {
+
+ *c = (dat & 0xf) | ((dat & 0xf) << 4);
+ if((count & 0x7) == 0)
+ dat++;
+ count++;
+ c++;
+ }
+
+}
+static void check_fb_new_old_buf(unsigned char *newfb,unsigned char *oldfb)
+{
+ unsigned char *new = newfb;
+ unsigned char newc,oldc;
+ unsigned char *c = (unsigned char *)oldfb;
+ int i;
+ for(i = 0;i < 100;i++)
+ {
+
+ newc = *new++;
+ oldc = ((*c++ & 0xf) << 4);
+ if(((i+1) % 16) == 0)
+ c++;
+ // printk("dat = 0x%X 0x%X\n",(oldc | (newc & 0xf)),(oldc | ((newc >> 4) & 0xf)));
+ }
+
+}
+/*
+ * Map screen memory
+ */
+static int jz4760fb_map_smem(struct lcd_cfb_info *cfb)
+{
+ unsigned long page;
+ unsigned int page_shift, needroom = 0, needroom1=0, bpp, w, h;
+ unsigned char *fb_palette, *fb_frame;
+
+ /* caculate the mem size of Foreground 0 */
+ if (use_fg0_only || use_2layer_Fg)
+ {
+ bpp = jz4760_lcd_info->osd.fg0.bpp;
+ if (bpp == 18 || bpp == 24)
+ bpp = 32;
+ if (bpp == 15)
+ bpp = 16;
+#ifndef CONFIG_FB_JZ4760_TVE
+ w = jz4760_lcd_info->osd.fg0.w;
+ h = jz4760_lcd_info->osd.fg0.h;
+#else
+ w = (jz4760_lcd_info->osd.fg0.w > TVE_WIDTH_PAL) ? jz4760_lcd_info->osd.fg0.w : TVE_WIDTH_PAL;
+ h = (jz4760_lcd_info->osd.fg0.h > TVE_HEIGHT_PAL) ? jz4760_lcd_info->osd.fg0.h : TVE_HEIGHT_PAL;
+#endif
+
+ needroom1 = needroom = ((w * bpp + 7) >> 3) * h * ANDROID_NUMBER_OF_BUFFERS;
+ }
+
+ /* caculate the mem size of Foreground 1 */
+ if (use_fg1_only || use_2layer_Fg){
+ bpp = jz4760_lcd_info->osd.fg1.bpp;
+ if (bpp == 18 || bpp == 24)
+ bpp = 32;
+ if (bpp == 15)
+ bpp = 16;
+#ifndef CONFIG_FB_JZ4760_TVE
+ w = jz4760_lcd_info->osd.fg1.w;
+ h = jz4760_lcd_info->osd.fg1.h;
+#else /* CONFIG_FB_JZ4760_TVE */
+ w = (jz4760_lcd_info->osd.fg1.w > TVE_WIDTH_PAL) ? jz4760_lcd_info->osd.fg1.w : TVE_WIDTH_PAL;
+ h = (jz4760_lcd_info->osd.fg1.h > TVE_HEIGHT_PAL) ? jz4760_lcd_info->osd.fg1.h : TVE_HEIGHT_PAL;
+#endif
+ needroom += ((w * bpp + 7) >> 3) * h;
+
+ }
+/* end of alloc Foreground 1 mem */
+ needroom += PAGE_SIZE; // for
+ /* Alloc memory */
+ for (page_shift = 0; page_shift < 12; page_shift++)
+ if ((PAGE_SIZE << page_shift) >= needroom)
+ break;
+// fb_palette = (unsigned char *)__get_free_pages(GFP_KERNEL, 0);
+ fb_palette = (unsigned char *)__get_free_pages(GFP_KERNEL, 1); // for init palette which need big room
+
+ fb_frame = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);
+ if ((!fb_palette) || (!fb_frame))
+ return -ENOMEM;
+ memset((void *)fb_palette, 0, PAGE_SIZE);
+ memset((void *)fb_frame, 0, PAGE_SIZE << page_shift);
+
+// memset((void *)fb_frame, 0xff, PAGE_SIZE << page_shift);
+
+ lcd_palette = fb_palette;
+// dma_desc_base = (struct jz4760_lcd_dma_desc *)__get_free_pages(GFP_KERNEL, 0);
+ dma_desc_base = (struct jz4760_lcd_dma_desc *)__get_free_pages(GFP_KERNEL, 1);
+
+ /*
+ * Set page reserved so that mmap will work. This is necessary
+ * since we'll be remapping normal memory.
+ */
+ page = (unsigned long)lcd_palette;
+ SetPageReserved(virt_to_page((void*)page));
+
+ page = (unsigned long)dma_desc_base;
+ SetPageReserved(virt_to_page((void*)page));
+
+ for (page = (unsigned long)fb_frame;
+ page < PAGE_ALIGN((unsigned long)fb_frame + (PAGE_SIZE<<page_shift));
+ page += PAGE_SIZE) {
+ SetPageReserved(virt_to_page((void*)page));
+ }
+
+ if (use_fg1_only || use_2layer_Fg){
+
+ lcd_frame = (unsigned char *)(((unsigned int)fb_frame + needroom1 + PAGE_MASK) & PAGE_MASK);
+ cfb->fb.fix.smem_start = virt_to_phys((void *)lcd_frame);
+ cfb->fb.fix.smem_len = needroom - needroom1; /* page_shift/2 ??? */
+ cfb->fb.screen_base =
+ (unsigned char *)(((unsigned int)lcd_frame&0x1fffffff) | 0xa0000000);
+ if (!cfb->fb.screen_base) {
+ printk("jz4760fb, %s: unable to map screen memory\n", cfb->fb.fix.id);
+ return -ENOMEM;
+ }
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+
+ memset((void *)lcd_frame, 0xff, cfb->fb.fix.smem_len);
+
+ printk("%s %d set lcd frame 0xff\n",__FUNCTION__,__LINE__);
+#endif
+ }
+
+ if (use_fg0_only || use_2layer_Fg){
+ lcd_frame0 = fb_frame;
+ cfb->fb0.fix.smem_start = virt_to_phys((void *)lcd_frame0);
+ cfb->fb0.fix.smem_len = needroom1; /* page_shift/2 ??? */
+
+ cfb->fb0.screen_base =
+ (unsigned char *)(((unsigned int)lcd_frame0&0x1fffffff) | 0xa0000000);
+ if (!cfb->fb0.screen_base) {
+ printk("jz4760fb0, %s: unable to map screen memory\n", cfb->fb0.fix.id);
+ return -ENOMEM;
+ }
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+
+ memset((void *)lcd_frame0, 0xff, cfb->fb0.fix.smem_len);
+ {
+ unsigned char * newfb = (unsigned char *)lcd_frame0;
+ unsigned char * oldfb = (unsigned char *)lcd_frame;
+ fill_fb_newbuff(newfb);
+ fill_fb_oldbuff(oldfb);
+ check_fb_new_old_buf(newfb,oldfb);
+ }
+ dma_cache_wback_inv((unsigned int)lcd_frame0,800*600/2);
+ dma_cache_wback_inv((unsigned int)lcd_frame,800*600/2);
+
+#endif
+ }
+
+ return 0;
+}
+
+static void jz4760fb_free_fb_info(struct lcd_cfb_info *cfb)
+{
+ if (cfb) {
+ fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
+ kfree(cfb);
+ }
+}
+
+static void jz4760fb_unmap_smem(struct lcd_cfb_info *cfb)
+{
+ struct page * map = NULL;
+ unsigned char *tmp;
+ unsigned int page_shift, needroom, bpp, w, h;
+ bpp = jz4760_lcd_info->osd.fg0.bpp;
+ if ( bpp == 18 || bpp == 24)
+ bpp = 32;
+ if ( bpp == 15 )
+ bpp = 16;
+ w = jz4760_lcd_info->osd.fg0.w;
+ h = jz4760_lcd_info->osd.fg0.h;
+ needroom = ((w * bpp + 7) >> 3) * h;
+ if (use_2layer_Fg){
+ bpp = jz4760_lcd_info->osd.fg1.bpp;
+ if ( bpp == 18 || bpp == 24)
+ bpp = 32;
+ if ( bpp == 15 )
+ bpp = 16;
+ w = jz4760_lcd_info->osd.fg1.w;
+ h = jz4760_lcd_info->osd.fg1.h;
+ needroom += ((w * bpp + 7) >> 3) * h;
+ }
+
+ for (page_shift = 0; page_shift < 12; page_shift++)
+ if ((PAGE_SIZE << page_shift) >= needroom)
+ break;
+
+ if (cfb && cfb->fb.screen_base) {
+ iounmap(cfb->fb.screen_base);
+ cfb->fb.screen_base = NULL;
+ release_mem_region(cfb->fb.fix.smem_start,
+ cfb->fb.fix.smem_len);
+ }
+
+ if (lcd_palette) {
+ map = virt_to_page(lcd_palette);
+ clear_bit(PG_reserved, &map->flags);
+ free_pages((int)lcd_palette, 0);
+ }
+
+ if (lcd_frame0) {
+ for (tmp=(unsigned char *)lcd_frame0;
+ tmp < lcd_frame0 + (PAGE_SIZE << page_shift);
+ tmp += PAGE_SIZE) {
+ map = virt_to_page(tmp);
+ clear_bit(PG_reserved, &map->flags);
+ }
+ free_pages((int)lcd_frame0, page_shift);
+ }
+}
+
+/************************************
+ * Jz475X Chipset OPS
+ ************************************/
+
+/*
+ * switch to tve mode from lcd mode
+ * mode:
+ * PANEL_MODE_TVE_PAL: switch to TVE_PAL mode
+ * PANEL_MODE_TVE_NTSC: switch to TVE_NTSC mode
+ */
+static void print_lcdc_registers(void) /* debug */
+{
+#ifdef DEBUG
+ /* LCD Controller Resgisters */
+ printk("REG_LCD_CFG:\t0x%08x\n", REG_LCD_CFG);
+ printk("REG_LCD_CTRL:\t0x%08x\n", REG_LCD_CTRL);
+ printk("REG_LCD_STATE:\t0x%08x\n", REG_LCD_STATE);
+ printk("REG_LCD_OSDC:\t0x%08x\n", REG_LCD_OSDC);
+ printk("REG_LCD_OSDCTRL:\t0x%08x\n", REG_LCD_OSDCTRL);
+ printk("REG_LCD_OSDS:\t0x%08x\n", REG_LCD_OSDS);
+ printk("REG_LCD_BGC:\t0x%08x\n", REG_LCD_BGC);
+ printk("REG_LCD_KEK0:\t0x%08x\n", REG_LCD_KEY0);
+ printk("REG_LCD_KEY1:\t0x%08x\n", REG_LCD_KEY1);
+ printk("REG_LCD_ALPHA:\t0x%08x\n", REG_LCD_ALPHA);
+ printk("REG_LCD_IPUR:\t0x%08x\n", REG_LCD_IPUR);
+ printk("REG_LCD_VAT:\t0x%08x\n", REG_LCD_VAT);
+ printk("REG_LCD_DAH:\t0x%08x\n", REG_LCD_DAH);
+ printk("REG_LCD_DAV:\t0x%08x\n", REG_LCD_DAV);
+ printk("REG_LCD_XYP0:\t0x%08x\n", REG_LCD_XYP0);
+ printk("REG_LCD_XYP1:\t0x%08x\n", REG_LCD_XYP1);
+ printk("REG_LCD_SIZE0:\t0x%08x\n", REG_LCD_SIZE0);
+ printk("REG_LCD_SIZE1:\t0x%08x\n", REG_LCD_SIZE1);
+ printk("REG_LCD_RGBC\t0x%08x\n", REG_LCD_RGBC);
+ printk("REG_LCD_VSYNC:\t0x%08x\n", REG_LCD_VSYNC);
+ printk("REG_LCD_HSYNC:\t0x%08x\n", REG_LCD_HSYNC);
+ printk("REG_LCD_PS:\t0x%08x\n", REG_LCD_PS);
+ printk("REG_LCD_CLS:\t0x%08x\n", REG_LCD_CLS);
+ printk("REG_LCD_SPL:\t0x%08x\n", REG_LCD_SPL);
+ printk("REG_LCD_REV:\t0x%08x\n", REG_LCD_REV);
+ printk("REG_LCD_IID:\t0x%08x\n", REG_LCD_IID);
+ printk("REG_LCD_DA0:\t0x%08x\n", REG_LCD_DA0);
+ printk("REG_LCD_SA0:\t0x%08x\n", REG_LCD_SA0);
+ printk("REG_LCD_FID0:\t0x%08x\n", REG_LCD_FID0);
+ printk("REG_LCD_CMD0:\t0x%08x\n", REG_LCD_CMD0);
+ printk("REG_LCD_OFFS0:\t0x%08x\n", REG_LCD_OFFS0);
+ printk("REG_LCD_PW0:\t0x%08x\n", REG_LCD_PW0);
+ printk("REG_LCD_CNUM0:\t0x%08x\n", REG_LCD_CNUM0);
+ printk("REG_LCD_DESSIZE0:\t0x%08x\n", REG_LCD_DESSIZE0);
+ printk("REG_LCD_DA1:\t0x%08x\n", REG_LCD_DA1);
+ printk("REG_LCD_SA1:\t0x%08x\n", REG_LCD_SA1);
+ printk("REG_LCD_FID1:\t0x%08x\n", REG_LCD_FID1);
+ printk("REG_LCD_CMD1:\t0x%08x\n", REG_LCD_CMD1);
+ printk("REG_LCD_OFFS1:\t0x%08x\n", REG_LCD_OFFS1);
+ printk("REG_LCD_PW1:\t0x%08x\n", REG_LCD_PW1);
+ printk("REG_LCD_CNUM1:\t0x%08x\n", REG_LCD_CNUM1);
+ printk("REG_LCD_DESSIZE1:\t0x%08x\n", REG_LCD_DESSIZE1);
+ printk("==================================\n");
+ printk("REG_LCD_VSYNC:\t%d:%d\n", REG_LCD_VSYNC>>16, REG_LCD_VSYNC&0xfff);
+ printk("REG_LCD_HSYNC:\t%d:%d\n", REG_LCD_HSYNC>>16, REG_LCD_HSYNC&0xfff);
+ printk("REG_LCD_VAT:\t%d:%d\n", REG_LCD_VAT>>16, REG_LCD_VAT&0xfff);
+ printk("REG_LCD_DAH:\t%d:%d\n", REG_LCD_DAH>>16, REG_LCD_DAH&0xfff);
+ printk("REG_LCD_DAV:\t%d:%d\n", REG_LCD_DAV>>16, REG_LCD_DAV&0xfff);
+ printk("==================================\n");
+
+ /* Smart LCD Controller Resgisters */
+ printk("REG_SLCD_CFG:\t0x%08x\n", REG_SLCD_CFG);
+ printk("REG_SLCD_CTRL:\t0x%08x\n", REG_SLCD_CTRL);
+ printk("REG_SLCD_STATE:\t0x%08x\n", REG_SLCD_STATE);
+ printk("==================================\n");
+
+ /* TVE Controller Resgisters */
+ printk("REG_TVE_CTRL:\t0x%08x\n", REG_TVE_CTRL);
+ printk("REG_TVE_FRCFG:\t0x%08x\n", REG_TVE_FRCFG);
+ printk("REG_TVE_SLCFG1:\t0x%08x\n", REG_TVE_SLCFG1);
+ printk("REG_TVE_SLCFG2:\t0x%08x\n", REG_TVE_SLCFG2);
+ printk("REG_TVE_SLCFG3:\t0x%08x\n", REG_TVE_SLCFG3);
+ printk("REG_TVE_LTCFG1:\t0x%08x\n", REG_TVE_LTCFG1);
+ printk("REG_TVE_LTCFG2:\t0x%08x\n", REG_TVE_LTCFG2);
+ printk("REG_TVE_CFREQ:\t0x%08x\n", REG_TVE_CFREQ);
+ printk("REG_TVE_CPHASE:\t0x%08x\n", REG_TVE_CPHASE);
+ printk("REG_TVE_CBCRCFG:\t0x%08x\n", REG_TVE_CBCRCFG);
+ printk("REG_TVE_WSSCR:\t0x%08x\n", REG_TVE_WSSCR);
+ printk("REG_TVE_WSSCFG1:\t0x%08x\n", REG_TVE_WSSCFG1);
+ printk("REG_TVE_WSSCFG2:\t0x%08x\n", REG_TVE_WSSCFG2);
+ printk("REG_TVE_WSSCFG3:\t0x%08x\n", REG_TVE_WSSCFG3);
+
+ printk("==================================\n");
+
+ if ( 1 ) {
+ unsigned int * pii = (unsigned int *)dma_desc_base;
+ int i, j;
+ //for (j=0;j< DMA_DESC_NUM ; j++) {
+ for (j=0;j< NR_DMA_DESC_EPD ; j++) {
+ printk("dma_desc%d(0x%08x):\n", j, (unsigned int)pii);
+ for (i =0; i<8; i++ ) {
+ printk("\t\t0x%08x\n", *pii++);
+ }
+ }
+ }
+
+
+
+#endif
+}
+
+#ifdef CONFIG_FB_JZ4760_TVE
+static void jz4760lcd_info_switch_to_TVE(int mode)
+{
+ struct jz4760lcd_info *info;
+ struct jz4760lcd_osd_t *osd_lcd;
+ struct jz4760lcd_panel_t *panel_lcd;
+ int x, y, w, h;
+
+ info = &jz4760_info_tve;
+
+ /* Set to tve mode */
+ info->panel.cfg = jz4760_lcd_panel.panel.cfg;
+ info->panel.cfg |= LCD_CFG_TVEN | LCD_CFG_MODE_INTER_CCIR656; /* Interlace CCIR656 mode */
+ info->panel.ctrl = jz4760_lcd_panel.panel.ctrl;
+ info->osd.rgb_ctrl = LCD_RGBC_YCC; /* enable RGB => YUV */
+
+ /* Copy current to keep the old style */
+ osd_lcd = &jz4760_lcd_panel.osd;
+ panel_lcd = &jz4760_lcd_panel.panel;
+
+ switch ( mode ) {
+ case PANEL_MODE_TVE_PAL:
+ info->panel.cfg |= LCD_CFG_TVEPEH; /* TVE PAL enable extra halfline signal */
+ info->panel.w = TVE_WIDTH_PAL;
+ info->panel.h = TVE_HEIGHT_PAL;
+ info->panel.fclk = TVE_FREQ_PAL;
+
+ /* set Foreground 0 */
+ w = osd_lcd->fg0.w / panel_lcd->w * TVE_WIDTH_PAL;
+ h = osd_lcd->fg0.h / panel_lcd->h * TVE_HEIGHT_PAL;
+ x = osd_lcd->fg0.x / panel_lcd->w * TVE_WIDTH_PAL;
+ y = osd_lcd->fg0.y / panel_lcd->h * TVE_HEIGHT_PAL;
+ info->osd.fg0.bpp = osd_lcd->fg0.bpp;
+ info->osd.fg0.x = x;
+ info->osd.fg0.y = y;
+ info->osd.fg0.w = w;
+ info->osd.fg0.h = h;
+
+ /* set Foreground 1 */
+ w = osd_lcd->fg1.w / panel_lcd->w * TVE_WIDTH_PAL;
+ h = osd_lcd->fg1.h / panel_lcd->h * TVE_HEIGHT_PAL;
+ x = osd_lcd->fg1.x / panel_lcd->w * TVE_WIDTH_PAL;
+ y = osd_lcd->fg1.y / panel_lcd->h * TVE_HEIGHT_PAL;
+ info->osd.fg1.bpp = 32; /* use RGB888 in TVE mode*/
+ info->osd.fg1.x = x;
+ info->osd.fg1.y = y;
+ info->osd.fg1.w = w;
+ info->osd.fg1.h = h;
+ break;
+
+ case PANEL_MODE_TVE_NTSC:
+ info->panel.cfg &= ~LCD_CFG_TVEPEH; /* TVE NTSC disable extra halfline signal */
+ info->panel.w = TVE_WIDTH_NTSC;
+ info->panel.h = TVE_HEIGHT_NTSC;
+ info->panel.fclk = TVE_FREQ_NTSC;
+ w = osd_lcd->fg0.w / panel_lcd->w * TVE_WIDTH_PAL;
+ h = osd_lcd->fg0.h / panel_lcd->h * TVE_HEIGHT_NTSC;
+ x = osd_lcd->fg0.x / panel_lcd->w * TVE_WIDTH_NTSC;
+ y = osd_lcd->fg0.y / panel_lcd->h * TVE_HEIGHT_NTSC;
+ info->osd.fg0.bpp = osd_lcd->fg0.bpp;
+ info->osd.fg0.x = x;
+ info->osd.fg0.y = y;
+ info->osd.fg0.w = w;
+ info->osd.fg0.h = h;
+
+ w = osd_lcd->fg1.w / panel_lcd->w * TVE_WIDTH_PAL;
+ h = osd_lcd->fg1.h / panel_lcd->h * TVE_HEIGHT_NTSC;
+ x = osd_lcd->fg1.x / panel_lcd->w * TVE_WIDTH_NTSC;
+ y = osd_lcd->fg1.y / panel_lcd->h * TVE_HEIGHT_NTSC;
+ info->osd.fg1.bpp = 32; /* use RGB888 int TVE mode */
+ info->osd.fg1.x = x;
+ info->osd.fg1.y = y;
+ info->osd.fg1.w = w;
+ info->osd.fg1.h = h;
+ break;
+ default:
+ printk("%s, %s: Unknown tve mode\n", __FILE__, __FUNCTION__);
+ }
+ jz4760_lcd_info = &jz4760_info_tve;
+}
+
+/*
+ * switch to lcd mode from TVE mode
+ */
+
+static void jz4760lcd_info_switch_to_lcd(void)
+{
+ struct jz4760lcd_info *info;
+ struct jz4760lcd_osd_t *osd_lcd;
+ struct jz4760lcd_panel_t *panel_lcd;
+ int x, y, w, h;
+
+ info = &jz4760_lcd_panel;
+
+ /* set to tve mode */
+ info->panel.cfg = jz4760_info_tve.panel.cfg;
+ info->panel.cfg &= ~(LCD_CFG_TVEN | LCD_CFG_MODE_INTER_CCIR656); /* Interlace CCIR656 mode */
+ info->panel.ctrl = jz4760_info_tve.panel.ctrl;
+ info->osd.rgb_ctrl &= ~LCD_RGBC_YCC; /* enable YUV => RGB*/
+
+ /* */
+ osd_lcd = &jz4760_info_tve.osd;
+ panel_lcd = &jz4760_info_tve.panel;
+
+ /* set Foreground 0 */
+ w = osd_lcd->fg0.w / panel_lcd->w * info->panel.w;
+ h = osd_lcd->fg0.h / panel_lcd->h * info->panel.h;
+ x = osd_lcd->fg0.x / panel_lcd->w * info->panel.w;
+ y = osd_lcd->fg0.y / panel_lcd->h * info->panel.h;
+ info->osd.fg0.x = x;
+ info->osd.fg0.y = y;
+ info->osd.fg0.w = w;
+ info->osd.fg0.h = h;
+
+ /* set Foreground 1 */
+ w = osd_lcd->fg1.w / panel_lcd->w * info->panel.w;
+ h = osd_lcd->fg1.h / panel_lcd->h * info->panel.h;
+ x = osd_lcd->fg1.x / panel_lcd->w * info->panel.w;
+ y = osd_lcd->fg1.y / panel_lcd->h * info->panel.h;
+ info->osd.fg1.x = x;
+ info->osd.fg1.y = y;
+ info->osd.fg1.w = w;
+ info->osd.fg1.h = h;
+
+ jz4760_lcd_info = &jz4760_lcd_panel;
+}
+#endif
+/*for epd: we use 12 palettes, with 16 per palette, tatally 192 frames . BY Cynthia zhzhao 20100602*/
+
+static void jz4760fb_epd_descriptor_init( struct jz4760lcd_info * lcd_info )
+{
+ unsigned int pal_size;
+ int fg0_line_size, fg0_frm_size, fg1_line_size, fg1_frm_size;
+ int size0, size1;
+ int i;
+ unsigned int palette_id ;//which palette
+// pal_size = palette_offset;
+ pal_size = 1024;
+ /* DMA Descriptor. */
+ for (i = 0; i < NR_DMA_DESC_EPD + NR_DMA1_DESC_EPD; i++)
+ dma_desc_epd[i] = dma_desc_base+i;
+
+ /* Foreground 0, caculate size */
+ if ( lcd_info->osd.fg0.x >= lcd_info->panel.w )
+ lcd_info->osd.fg0.x = lcd_info->panel.w - 1;
+ if ( lcd_info->osd.fg0.y >= lcd_info->panel.h )
+ lcd_info->osd.fg0.y = lcd_info->panel.h - 1;
+ if ( lcd_info->osd.fg0.x + lcd_info->osd.fg0.w > lcd_info->panel.w )
+ lcd_info->osd.fg0.w = lcd_info->panel.w - lcd_info->osd.fg0.x;
+ if ( lcd_info->osd.fg0.y + lcd_info->osd.fg0.h > lcd_info->panel.h )
+ lcd_info->osd.fg0.h = lcd_info->panel.h - lcd_info->osd.fg0.y;
+
+ size0 = lcd_info->osd.fg0.h << 16 | lcd_info->osd.fg0.w;
+ fg0_line_size = (lcd_info->osd.fg0.w * (lcd_info->osd.fg0.bpp) / 8);
+ fg0_line_size = ((fg0_line_size + 3) >> 2) << 2; /* word aligned */
+ fg0_frm_size = fg0_line_size * lcd_info->osd.fg0.h;
+
+ dma0_desc_palette = dma_desc_epd[0];
+
+ /*The first Palette Descriptor */
+ palette_id=0;
+ dma0_desc_palette_epd[palette_id]= dma_desc_epd[0];
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+// printk("dma0_desc_palette_epd[%d]->databuf addr(%p) desc(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id],(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=1;i<NR_DMA_DESC_EPD_PER_GROUP;i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ /* frame phys addr */
+ dma0_desc0->databuf = virt_to_phys((void *)(lcd_frame0));
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+
+// printk("dma_desc_epd[%d](0x%08x) databuf(0x%08x) nex_Desc(0x%08x) frame_id(0x%08x) cmd(0x%08x) \n",i,dma_desc_epd[i],dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+ }
+
+
+ /*The second Palette Descriptor */
+ palette_id=1;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+
+ //printk("dma_desc_epd[%d](0x%08x) databuf(0x%08x) nex_Desc(0x%08x) frame_id(0x%08x) cmd(0x%08x) \n",i,dma_desc_epd[i],dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+ }
+
+
+ /* The third Palette Descriptor */
+ palette_id=2;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma_desc_epd[%d](0x%08x) databuf(0x%08x) nex_Desc(0x%08x) frame_id(0x%08x) cmd(0x%08x) \n",i,dma_desc_epd[i],dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+ }
+
+ /* The forth Palette Descriptor */
+ palette_id=3;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+
+ // printk("dma_desc_epd[%d](0x%08x) databuf(0x%08x) nex_Desc(0x%08x) frame_id(0x%08x) cmd(0x%08x) \n",i,dma_desc_epd[i],dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+ }
+
+ /* The fifth Palette Descriptor */
+ palette_id=4;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+
+ }
+
+ /* The sixth Palette Descriptor */
+ palette_id=5;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+ }
+
+
+
+ /* The seventh Palette Descriptor */
+ palette_id=6;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+ }
+
+
+
+ /* The eighth Palette Descriptor */
+ palette_id=7;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+ }
+
+
+ /* The ninth Palette Descriptor */
+ palette_id=8;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+
+ }
+
+
+ /* The tenth Palette Descriptor */
+ palette_id=9;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+ }
+
+
+ /* The eleventh Palette Descriptor */
+ palette_id=10;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)(lcd_palette + palette_offset*palette_id));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+ else{
+ dma0_desc_palette_epd[palette_id+1] = dma0_desc0+1;/* frame phys addr */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette_epd[palette_id+1]);
+ }
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ //printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+ }
+
+
+ /* The tewlvth Palette Descriptor */
+ palette_id=11;
+
+ dma0_desc_palette_epd[palette_id]->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[NR_DMA_DESC_EPD_PER_GROUP*palette_id+1]);
+ dma0_desc_palette_epd[palette_id]->databuf = (unsigned int)virt_to_phys((void *)((lcd_palette + palette_offset*palette_id)));
+ dma0_desc_palette_epd[palette_id]->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette_epd[palette_id]->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+ dma0_desc_palette_epd[palette_id]->offsize = 0x00000000; /* Palette Descriptor */
+
+ //printk("dma0_desc_palette_epd[%d]->databuf addr(%p) nex_Desc (%p) frame_id (0x%08x) cmd (0x%08x) \n",palette_id,(void*)dma0_desc_palette_epd[palette_id]->databuf,(void *)dma0_desc_palette_epd[palette_id]->next_desc,dma0_desc_palette_epd[palette_id]->frame_id ,dma0_desc_palette_epd[palette_id]->cmd);
+
+
+
+ /* next */
+ for(i=(NR_DMA_DESC_EPD_PER_GROUP*palette_id+1);i<(NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1));i++){
+
+ dma0_desc0 = dma_desc_epd[i];
+ if (i != (NR_DMA_DESC_EPD_PER_GROUP*(palette_id+1) - 1))
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0+1);
+
+ else{
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma_desc_epd[0]);
+
+ }
+
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ /* frame id */
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+ /* others */
+ dma0_desc0->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize =0;
+ dma0_desc0->page_width = 0;
+ dma0_desc0->desc_size = size0;
+ // printk("dma0_desc0->databuf 0x%08x nex_Desc (0x%08x) frame_id (0x%08x) cmd (0x%08x) \n",dma0_desc0->databuf,dma0_desc0->next_desc,dma0_desc0->frame_id ,dma0_desc0->cmd);
+
+
+
+ }
+
+
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_palette_epd[0]);
+
+#if EPD_MODE_PAL
+ REG_LCD_SIZE0 = size0;
+#else
+ dma0_desc0->cmd = 0;
+ dma0_desc0->desc_size = 0;
+ REG_LCD_DA0 = virt_to_phys(dma0_desc0); //tft
+ REG_LCD_SIZE0 = 0;
+
+#endif
+ current_dma0_id = 0;//dma0_desc0;
+
+ /*=========== fg1 descriptor ===========*/
+ dma1_desc0 = dma_desc_base + NR_DMA_DESC_EPD;
+ /* Foreground 1, caculate size */
+ if ( lcd_info->osd.fg1.x >= lcd_info->panel.w )
+ lcd_info->osd.fg1.x = lcd_info->panel.w - 1;
+ if ( lcd_info->osd.fg1.y >= lcd_info->panel.h )
+ lcd_info->osd.fg1.y = lcd_info->panel.h - 1;
+ if ( lcd_info->osd.fg1.x + lcd_info->osd.fg1.w > lcd_info->panel.w )
+ lcd_info->osd.fg1.w = lcd_info->panel.w - lcd_info->osd.fg1.x;
+ if ( lcd_info->osd.fg1.y + lcd_info->osd.fg1.h > lcd_info->panel.h )
+ lcd_info->osd.fg1.h = lcd_info->panel.h - lcd_info->osd.fg1.y;
+
+
+ size1 = lcd_info->osd.fg1.h << 16 | lcd_info->osd.fg1.w;
+ fg1_line_size = lcd_info->osd.fg1.w*lcd_info->osd.fg1.bpp/8;
+ fg1_line_size = ((fg1_line_size+3)>>2)<<2; /* word aligned */
+ fg1_frm_size = fg1_line_size * lcd_info->osd.fg1.h;
+ printk("%s: fg1_frm_size: %d \n",__func__,fg1_frm_size/4);
+ dma1_desc0->next_desc = (unsigned int)virt_to_phys(dma1_desc0);
+ /* frame phys addr */
+ dma1_desc0->databuf = virt_to_phys((void *)lcd_frame);
+
+ /* frame id */
+ dma1_desc0->frame_id = (unsigned int)0x0da10000; /* DMA1'0 */
+
+ dma1_desc0->cmd = fg1_frm_size/4;
+ dma1_desc0->offsize = 0;
+ dma1_desc0->page_width = 0;
+ dma1_desc0->desc_size = size1;
+
+ //printk("dma1_desc0(0x%08x) databuf(0x%08x) nex_Desc(0x%08x) frame_id(0x%08x) cmd(0x%08x) \n",dma1_desc0,dma1_desc0->databuf,dma1_desc0->next_desc,dma1_desc0->frame_id ,dma1_desc0->cmd);
+
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0); /* set Dma-chan1's Descripter Addrress */
+ REG_LCD_SIZE1 = size1;
+ current_dma1_id = 0;//dma1_desc0;
+
+
+ dma_cache_wback((unsigned int)(dma_desc_base), (NR_DMA_DESC_EPD + NR_DMA1_DESC_EPD)*sizeof(struct jz4760_lcd_dma_desc));
+}
+
+static void jz4760fb_set_panel_mode(struct jz4760lcd_info * lcd_info)
+{
+ struct jz4760lcd_panel_t *panel = &lcd_info->panel;
+
+ /* set bpp */
+ lcd_info->panel.ctrl &= ~LCD_CTRL_BPP_MASK;
+ if ( lcd_info->osd.fg0.bpp == 1 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_1;
+ else if ( lcd_info->osd.fg0.bpp == 2 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_2;
+ else if ( lcd_info->osd.fg0.bpp == 4 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_4;
+ else if ( lcd_info->osd.fg0.bpp == 8 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_8;
+ else if ( lcd_info->osd.fg0.bpp == 15 ) {
+ lcd_info->osd.fg0.bpp = 16;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB555;
+ }
+ else if ( lcd_info->osd.fg0.bpp == 16 ) {
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB565;
+ lcd_info->panel.ctrl &= ~LCD_CTRL_RGB555;
+ }
+ else if ( lcd_info->osd.fg0.bpp == 30) {
+ lcd_info->osd.fg0.bpp = 32;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_30;
+ }
+ else if ( lcd_info->osd.fg0.bpp > 16 && lcd_info->osd.fg0.bpp < 32+1 ) {
+ lcd_info->osd.fg0.bpp = 32;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_18_24;
+ }
+ else {
+ printk("The BPP %d is not supported\n", lcd_info->osd.fg0.bpp);
+ lcd_info->osd.fg0.bpp = 32;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_18_24;
+ }
+
+ lcd_info->panel.cfg |= LCD_CFG_NEWDES; /* use 8words descriptor always */
+ REG_LCD_CTRL = lcd_info->panel.ctrl; /* LCDC Controll Register */
+
+ REG_LCD_CFG = lcd_info->panel.cfg; /* LCDC Configure Register */
+ REG_SLCD_CFG = lcd_info->panel.slcd_cfg; /* Smart LCD Configure Register */
+
+ if ( lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD ) /* enable Smart LCD DMA */
+ REG_SLCD_CTRL = SLCD_CTRL_DMA_EN;
+
+ switch ( lcd_info->panel.cfg & LCD_CFG_MODE_MASK ) {
+ case LCD_CFG_MODE_GENERIC_TFT:
+ case LCD_CFG_MODE_INTER_CCIR656:
+ case LCD_CFG_MODE_NONINTER_CCIR656:
+ case LCD_CFG_MODE_SLCD:
+ default: /* only support TFT16 TFT32, not support STN and Special TFT by now(10-06-2008)*/
+ REG_LCD_VAT = (((panel->blw + panel->w + panel->elw + panel->hsw)) << 16) | (panel->vsw + panel->bfw + panel->h + panel->efw);
+ REG_LCD_DAH = ((panel->hsw + panel->blw) << 16) | (panel->hsw + panel->blw + panel->w);
+ REG_LCD_DAV = ((panel->vsw + panel->bfw) << 16) | (panel->vsw + panel->bfw + panel->h);
+ REG_LCD_HSYNC = (0 << 16) | panel->hsw;
+ REG_LCD_VSYNC = (0 << 16) | panel->vsw;
+ break;
+ }
+}
+
+
+//static void jz4760fb_set_osd_mode( struct jz4760lcd_info * lcd_info )
+static void jz4760fb_set_osd_mode(struct jz4760lcd_osd_t *lcd_osd_info)
+{
+ lcd_osd_info->osd_ctrl &= ~(LCD_OSDCTRL_OSDBPP_MASK);
+ if(lcd_osd_info->fg1.bpp == 2)
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_2;
+ else if(lcd_osd_info->fg1.bpp == 4)
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_4;
+ else if ( lcd_osd_info->fg1.bpp == 15 )
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_15_16|LCD_OSDCTRL_RGB555;
+ else if ( lcd_osd_info->fg1.bpp == 16 ) {
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_15_16;
+ lcd_osd_info->osd_ctrl &= ~LCD_OSDCTRL_RGB555;
+ }
+ else if (lcd_osd_info->fg1.bpp == 30) {
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_30;
+ }
+ else {
+ lcd_osd_info->fg1.bpp = 32;
+ lcd_osd_info->osd_ctrl |= LCD_OSDCTRL_OSDBPP_18_24;
+ }
+
+
+ REG_LCD_OSDC = lcd_osd_info->osd_cfg; /* F0, F1, alpha, */
+
+ REG_LCD_OSDCTRL = lcd_osd_info->osd_ctrl; /* IPUEN, bpp */
+ REG_LCD_RGBC = lcd_osd_info->rgb_ctrl;
+ REG_LCD_BGC = lcd_osd_info->bgcolor;
+ REG_LCD_KEY0 = lcd_osd_info->colorkey0;
+ REG_LCD_KEY1 = lcd_osd_info->colorkey1;
+ REG_LCD_ALPHA = lcd_osd_info->alpha;
+ REG_LCD_IPUR = lcd_osd_info->ipu_restart;
+}
+
+
+
+/* Change Position of Foreground 0 */
+static int jz4760fb0_foreground_move(struct jz4760lcd_osd_t *lcd_osd_info)
+{
+ int pos;
+ int j, count;
+ /*
+ * Foreground, only one of the following can be change at one time:
+ * 1. F0 size, 2. F0 position, 3. F1 size, 4. F1 position
+ *
+ * The rules of fg0 position:
+ * fg0.x + fg0.w <= panel.w;
+ * fg0.y + fg0.h <= panel.h;
+ *
+ * When output is LCD panel, fg.y can be odd number or even number.
+ * When output is TVE, as the TVE has odd frame and even frame,
+ * to simplified operation, fg.y should be even number always.
+ *
+ */
+
+ /* Foreground 0 */
+ if (lcd_osd_info->fg0.x + lcd_osd_info->fg0.w > jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg0.x = jz4760_lcd_info->panel.w - lcd_osd_info->fg0.w;
+ if (lcd_osd_info->fg0.y + lcd_osd_info->fg0.h > jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg0.y = jz4760_lcd_info->panel.h - lcd_osd_info->fg0.h;
+
+ if (lcd_osd_info->fg0.x >= jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg0.x = jz4760_lcd_info->panel.w - 1;
+ if (lcd_osd_info->fg0.y >= jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg0.y = jz4760_lcd_info->panel.h - 1;
+
+ pos = lcd_osd_info->fg0.y << 16 | lcd_osd_info->fg0.x;
+ if (REG_LCD_XYP0 == pos){
+ printk("FG0: same position\n");
+ return 0;
+ }
+
+ REG_LCD_XYP0 = pos;
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+ while(!(REG_LCD_OSDS & LCD_OSDS_READY));
+ j = count;
+ msleep(40);
+ while((REG_LCD_OSDCTRL & LCD_OSDCTRL_CHANGES) && j--);
+ if(j == 0) {
+ printk("Error FG0 Position: Wait change fail.\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+/* Change Window size of Foreground 0 */
+static int jz4760fb0_foreground_resize(struct jz4760lcd_osd_t *lcd_osd_info)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+ int size, fg0_line_size, fg0_frm_size;
+// int desc_len = sizeof(struct jz4760_lcd_dma_desc);
+ /*
+ * NOTE:
+ * Foreground change sequence:
+ * 1. Change Position Registers -> LCD_OSDCTL.Change;
+ * 2. LCD_OSDCTRL.Change -> descripter->Size
+ * Foreground, only one of the following can be change at one time:
+ * 1. F0 size;
+ * 2. F0 position
+ * 3. F1 size
+ * 4. F1 position
+ */
+
+ /*
+ * The rules of f0, f1's position:
+ * f0.x + f0.w <= panel.w;
+ * f0.y + f0.h <= panel.h;
+ *
+ * When output is LCD panel, fg.y and fg.h can be odd number or even number.
+ * When output is TVE, as the TVE has odd frame and even frame,
+ * to simplified operation, fg.y and fg.h should be even number always.
+ *
+ */
+ /* Foreground 0 */
+ if (lcd_osd_info->fg0.x + lcd_osd_info->fg0.w > jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg0.w = jz4760_lcd_info->panel.w - lcd_osd_info->fg0.x;
+ if (lcd_osd_info->fg0.y + lcd_osd_info->fg0.h > jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg0.h = jz4760_lcd_info->panel.h - lcd_osd_info->fg0.y;
+
+ size = lcd_osd_info->fg0.h << 16 | lcd_osd_info->fg0.w;
+
+ if (REG_LCD_SIZE0 == size) {
+ printk("FG0: same size\n");
+ return 0;
+ }
+
+ fg0_line_size = lcd_osd_info->fg0.w * lcd_osd_info->fg0.bpp / 8;
+ fg0_line_size = ((fg0_line_size + 3) >> 2) << 2; /* word aligned */
+ fg0_frm_size = fg0_line_size * lcd_osd_info->fg0.h;
+
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+ /* set change bit */
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+
+ if (jz4760_lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* output to TV */
+ dma0_desc0->cmd = dma0_desc1->cmd = (fg0_frm_size/4)/2;
+ dma0_desc0->offsize = dma0_desc1->offsize
+ = fg0_line_size/4;
+ dma0_desc0->page_width = dma0_desc1->page_width
+ = fg0_line_size/4;
+ dma0_desc1->databuf = virt_to_phys((void *)(lcd_frame0 + fg0_line_size));
+ }
+ else {
+ dma0_desc0->cmd = dma0_desc1->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize = dma0_desc1->offsize =0;
+ dma0_desc0->page_width = dma0_desc1->page_width = 0;
+ }
+
+ dma0_desc0->desc_size = dma0_desc1->desc_size = size;
+// = lcd_osd_info->fg0.h << 16 | lcd_osd_info->fg0.w;
+ REG_LCD_SIZE0 = size;
+// REG_LCD_SIZE0 = (lcd_osd_info->fg0.h << 16) | lcd_osd_info->fg0.w;
+
+ dma_cache_wback((unsigned int)(dma_desc_base), (DMA_DESC_NUM)*sizeof(struct jz4760_lcd_dma_desc));
+
+ jz4760fb_set_var(&cfb->fb0.var, 0, &cfb->fb0);
+ return 0;
+}
+
+/* Change Position of Foreground 1 */
+static int jz4760fb_foreground_move(struct jz4760lcd_osd_t *lcd_osd_info)
+{
+ int pos;
+ int j, count = 100000;
+ /*
+ * Foreground, only one of the following can be change at one time:
+ * 1. F0 size, 2. F0 position, 3. F1 size, 4. F1 position
+ *
+ * The rules of fg1 position:
+ * fg1.x + fg1.w <= panel.w;
+ * fg1.y + fg1.h <= panel.h;
+ *
+ * When output is LCD panel, fg.y can be odd number or even number.
+ * When output is TVE, as the TVE has odd frame and even frame,
+ * to simplified operation, fg.y should be even number always.
+ *
+ */
+
+ /* Foreground 0 */
+ if (lcd_osd_info->fg1.x + lcd_osd_info->fg1.w > jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg1.x = jz4760_lcd_info->panel.w - lcd_osd_info->fg1.w;
+ if (lcd_osd_info->fg1.y + lcd_osd_info->fg1.h > jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg1.y = jz4760_lcd_info->panel.h - lcd_osd_info->fg1.h;
+
+ if (lcd_osd_info->fg1.x >= jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg1.x = jz4760_lcd_info->panel.w - 1;
+ if (lcd_osd_info->fg1.y >= jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg1.y = jz4760_lcd_info->panel.h - 1;
+
+ pos = lcd_osd_info->fg1.y << 16 | lcd_osd_info->fg1.x;
+ if (REG_LCD_XYP1 == pos){
+ printk("FG1: same position\n");
+ return 0;
+ }
+
+ /*********************************************/
+ REG_LCD_XYP1 = pos;
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+ while(!(REG_LCD_OSDS & LCD_OSDS_READY));
+ j = count;
+ msleep(40);
+ while((REG_LCD_OSDCTRL & LCD_OSDCTRL_CHANGES) && j--);
+ if(j == 0) {
+ printk("Error FG1 Position: Wait change fail.\n");
+ return -EFAULT;
+
+ }
+ return 0;
+}
+
+/* Change window size of Foreground 1 */
+static int jz4760fb_foreground_resize(struct jz4760lcd_osd_t *lcd_osd_info)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+ int size, fg1_line_size, fg1_frm_size;
+// int desc_len = sizeof(struct jz4760_lcd_dma_desc);
+ /*
+ * NOTE:
+ * Foreground change sequence:
+ * 1. Change Position Registers -> LCD_OSDCTL.Change;
+ * 2. LCD_OSDCTRL.Change -> descripter->Size
+ * Foreground, only one of the following can be change at one time:
+ * 1. F0 size;
+ * 2. F0 position
+ * 3. F1 size
+ * 4. F1 position
+ */
+
+ /*
+ * The rules of f0, f1's position:
+ * f0.x + f0.w <= panel.w;
+ * f0.y + f0.h <= panel.h;
+ *
+ * When output is LCD panel, fg.y and fg.h can be odd number or even number.
+ * When output is TVE, as the TVE has odd frame and even frame,
+ * to simplified operation, fg.y and fg.h should be even number always.
+ *
+ */
+
+ /* Foreground 0 */
+ if (lcd_osd_info->fg1.x + lcd_osd_info->fg1.w > jz4760_lcd_info->panel.w)
+ lcd_osd_info->fg1.w = jz4760_lcd_info->panel.w - lcd_osd_info->fg1.x;
+ if (lcd_osd_info->fg1.y + lcd_osd_info->fg1.h > jz4760_lcd_info->panel.h)
+ lcd_osd_info->fg1.h = jz4760_lcd_info->panel.h - lcd_osd_info->fg1.y;
+// size = lcd_info->osd.fg1.h << 16|lcd_info->osd.fg1.w;
+ size = lcd_osd_info->fg1.h << 16|lcd_osd_info->fg1.w;
+ if (REG_LCD_SIZE1 == size) {
+ printk("FG1: same size\n");
+ return 0;// -EFAULT;
+ }
+
+// fg1_line_size = lcd_osd_info->fg1.w * ((lcd_osd_info->fg1.bpp + 7) / 8);
+ fg1_line_size = lcd_osd_info->fg1.w * lcd_osd_info->fg1.bpp / 8;
+ fg1_line_size = ((fg1_line_size + 3) >> 2) << 2; /* word aligned */
+ fg1_frm_size = fg1_line_size * lcd_osd_info->fg1.h;
+
+ /* set change bit */
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+ if ( jz4760_lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* output to TV */
+ dma1_desc0->cmd = dma1_desc1->cmd = (fg1_frm_size/4)/2;
+ dma1_desc0->offsize = dma1_desc1->offsize = fg1_line_size/4;
+ dma1_desc0->page_width = dma1_desc1->page_width = fg1_line_size/4;
+ dma1_desc1->databuf = virt_to_phys((void *)(lcd_frame + fg1_line_size));
+ }
+ else {
+ dma1_desc0->cmd = dma1_desc1->cmd = fg1_frm_size/4;
+ dma1_desc0->offsize = dma1_desc1->offsize = 0;
+ dma1_desc0->page_width = dma1_desc1->page_width = 0;
+ }
+
+ dma1_desc0->desc_size = dma1_desc1->desc_size = size;
+ REG_LCD_SIZE1 = size;
+
+ dma_cache_wback((unsigned int)(dma_desc_base), (DMA_DESC_NUM)*sizeof(struct jz4760_lcd_dma_desc));
+
+ jz4760fb_set_var(&cfb->fb.var, 1, &cfb->fb);
+ return 0;
+}
+
+
+
+/*
+ * Set lcd pixel clock
+ */
+static void jz4760fb_change_clock( struct jz4760lcd_info * lcd_info )
+{
+#if defined(CONFIG_FPGA) /* FPGA test, pixdiv */
+// REG_LCD_REV = 0x0000002;
+ REG_LCD_REV = 0x0000001;
+ printk("Fuwa test, pixclk divide REG_LCD_REV=0x%08x\n", REG_LCD_REV);
+ printk("Fuwa test, pixclk %d\n", JZ_EXTAL/(((REG_LCD_REV&0xFF)+1)*2));
+#else
+ unsigned int val = 0;
+ unsigned int pclk;
+ /* Timing setting */
+ __cpm_stop_lcd();
+
+ val = lcd_info->panel.fclk; /* frame clk */
+
+ if ( (lcd_info->panel.cfg & LCD_CFG_MODE_MASK) != LCD_CFG_MODE_SERIAL_TFT) {
+ pclk = val * (lcd_info->panel.w + lcd_info->panel.hsw + lcd_info->panel.elw + lcd_info->panel.blw) * (lcd_info->panel.h + lcd_info->panel.vsw + lcd_info->panel.efw + lcd_info->panel.bfw); /* Pixclk */
+ }
+ else {
+ /* serial mode: Hsync period = 3*Width_Pixel */
+ pclk = val * (lcd_info->panel.w*3 + lcd_info->panel.hsw + lcd_info->panel.elw + lcd_info->panel.blw) * (lcd_info->panel.h + lcd_info->panel.vsw + lcd_info->panel.efw + lcd_info->panel.bfw); /* Pixclk */
+ }
+
+ /********* In TVE mode PCLK = 27MHz ***********/
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* LCDC output to TVE */
+ pclk = 27000000;
+ __cpm_select_pixclk_tve();
+ }
+ else { /* LCDC output to LCD panel */
+ __cpm_select_pixclk_lcd();
+ }
+
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+ pclk = 30000000;
+ val = __cpm_get_pllout2() / pclk; /* pclk */
+#else
+ val = __cpm_get_pllout2() / pclk; /* pclk */
+#endif
+
+ val--;
+ dprintk("ratio: val = %d\n", val);
+ if ( val > 0x7ff ) {
+ printk("pixel clock divid is too large, set it to 0x7ff\n");
+ val = 0x7ff;
+ }
+
+
+ __cpm_set_pixdiv(val);
+// REG_CPM_LPCDR = 0x0000000e;
+ dprintk("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
+ __cpm_enable_pll_change();
+
+ dprintk("REG_CPM_LPCDR=0x%08x\n", REG_CPM_LPCDR);
+ dprintk("REG_CPM_CPCCR=0x%08x\n", REG_CPM_CPCCR);
+
+ jz_clocks.pixclk = __cpm_get_pixclk();
+ printk("LCDC: PixClock:%d\n", jz_clocks.pixclk);
+ __cpm_start_lcd();
+ udelay(1000);
+
+ /*
+ * set lcd device clock and lcd pixel clock.
+ * what about TVE mode???
+ *
+ */
+#endif
+
+}
+
+
+/*
+ * jz4760fb_deep_set_mode,
+ *
+ */
+static void jz4760fb_deep_set_mode( struct jz4760lcd_info * lcd_info )
+{
+ /* configurate sequence:
+ * 1. disable lcdc.
+ * 2. init frame descriptor.
+ * 3. set panel mode
+ * 4. set osd mode
+ * 5. start lcd clock in CPM
+ * 6. enable lcdc.
+ */
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+// __lcd_clr_ena(); /* Quick Disable */
+ lcd_info->osd.fg_change = FG_CHANGE_ALL; /* change FG0, FG1 size, postion??? */
+ jz4760fb_set_osd_mode(&lcd_info->osd);
+ jz4760fb_set_panel_mode(lcd_info);
+
+ jz4760fb_epd_descriptor_init(lcd_info);
+
+ jz4760fb_change_clock(lcd_info);
+if (use_fg0_only || use_2layer_Fg)
+ jz4760fb_set_var(&cfb->fb0.var, 0, &cfb->fb0);
+
+if (use_fg1_only || use_2layer_Fg)
+ jz4760fb_set_var(&cfb->fb.var, 1, &cfb->fb);
+
+// __lcd_set_ena(); /* enable lcdc */
+}
+
+
+static irqreturn_t jz4760fb_interrupt_handler(int irq, void *dev_id)
+{
+ unsigned int state;
+ static int irqcnt=0;
+ static int framecnt = 0;
+
+ state = REG_LCD_STATE;
+// printk("-------------In the lcd interrupt handler, state=0x%x--------\n", state);
+ if (state & EPD_STATE_PWRUP) {
+ REG_LCD_STATE = state & ~EPD_STATE_PWRUP;
+ mdelay(1);
+#if EPD_MODE_PAL
+ {
+ // REG_LCD_DA0 = virt_to_phys(dma0_desc_palette);
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_palette_epd[framecnt]);
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0);
+
+ //REG_SLCD_CTRL |= (1 << 1);
+ REG_SLCD_CTRL = 0;
+ __lcd_set_ena(); /* enalbe LCD Controller */
+ }
+#else
+ {
+ dma0_desc0->cmd = 0;
+ REG_SLCD_CTRL = 0;
+ __lcd_set_ena(); /* enalbe LCD Controller */
+ }
+
+#endif
+// printk("power on!");
+ REG_LCD_CTRL |= LCD_CTRL_PEDN;
+ REG_EPD_CTRL4 |= EPD_CTRL4_FEN;
+ }
+ if (state & EPD_STATE_PWRDN) {
+ REG_LCD_STATE = state & ~EPD_STATE_PWRDN;
+// printk("EPD Power Down interrupt\n");
+ }
+
+ if (state & EPD_STATE_FEND) {
+ REG_LCD_STATE = state & ~EPD_STATE_FEND;
+ /* IC only support 16 frames, in this situation epd works well,
+ but for more than 16 frames we should do sth
+ Added by Cynthia */
+
+ __lcd_clr_ena();
+
+ if( totally_time > (++framecnt)){
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_palette_epd[framecnt]);
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0);
+ REG_SLCD_CTRL |= SLCD_CTRL_DMA_START;
+ REG_EPD_CTRL4 |= EPD_CTRL4_FEN;
+ // printk("totally_time=%d , framecnt=%d \n",totally_time, framecnt);
+ }
+ else{
+
+ framecnt =0;
+ REG_EPD_CTRL4 &= ~EPD_CTRL4_FEN;
+ REG_EPD_CTRL2 |= EPD_CTRL2_PWROFF;
+ }
+
+
+ __lcd_set_ena();
+// printk("EPD Frame End interrupt state = 0x%x cnt= %d \n ", state,framecnt);
+
+/* ended by Cynthia */
+
+
+ }
+ if (state & LCD_STATE_EOF) /* End of frame */
+ {
+ REG_LCD_STATE = state & ~LCD_STATE_EOF;
+ // irqcnt++;
+ printk("======== End of frame = \n");
+
+ }
+ if (state & LCD_STATE_IFU0) {
+ // printk("%s, In FiFo0 underrun\n", __FUNCTION__);
+ REG_LCD_STATE = state & ~LCD_STATE_IFU0;
+
+ }
+
+ if (state & LCD_STATE_IFU1) {
+ REG_LCD_STATE = state & ~LCD_STATE_IFU1;
+// printk("%s, InFiFo1 underrun\n", __FUNCTION__);
+
+ }
+
+ if (state & LCD_STATE_OFU) { /* Out fifo underrun */
+ REG_LCD_STATE = state & ~LCD_STATE_OFU;
+ if ( irqcnt++ > 100 ) {
+ //__lcd_disable_ofu_intr();
+ //printk("disable Out FiFo underrun irq.\n");
+ }
+ printk("%s, Out FiFo underrun.\n", __FUNCTION__);
+ //
+// printk("REG_LCD_CMD0:\t0x%08x, REG_LCD_CMD1:\t0x%08x\n", REG_LCD_CMD0,REG_LCD_CMD1);
+ }
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * Suspend the LCDC.
+ */
+static int jz4760fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ __lcd_clr_ena(); /* Quick Disable */
+ __lcd_display_off();
+ __cpm_stop_lcd();
+
+ return 0;
+}
+
+/*
+ * Resume the LCDC.
+ */
+static int jz4760fb_resume(struct platform_device *pdev)
+{
+ __cpm_start_lcd();
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0);
+ __lcd_set_ena();
+ __lcd_display_on();
+
+return 0;
+}
+#else
+static int jz4760fb_suspend(struct device *dev, pm_message_t state) {return 0;}
+static int jz4760fb_resume(struct device *dev) {return 0;}
+#endif /* CONFIG_PM */
+
+/* The following routine is only for test */
+
+static void jz4760_lcd_gpio_init(void)
+{
+ /* gpio init __gpio_as_lcd */
+ if (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_TFT_16BIT)
+ __gpio_as_lcd_16bit();
+ else if (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_TFT_24BIT)
+ __gpio_as_lcd_24bit();
+ else
+ __gpio_as_lcd_18bit();
+
+ /* Configure SLCD module for setting smart lcd control registers */
+#if defined(CONFIG_FB_JZ4760_SLCD)
+ __lcd_as_smart_lcd();
+ __slcd_disable_dma();
+ __init_slcd_bus(); /* Note: modify this depend on you lcd */
+
+#endif
+ __lcd_display_pin_init();
+}
+
+static void jz4760_lcd_init_cfg(void)
+{
+ if (use_fg0_only || use_2layer_Fg)
+ jz4760_lcd_info->osd.osd_cfg |= LCD_OSDC_F0EN; /* only open fg0 */
+
+// jz4760_lcd_info->osd.osd_cfg |= LCD_OSDC_F1EN; /* only open fg1 */
+
+ /* In special mode, we only need init special pin,
+ * as general lcd pin has init in uboot */
+#if defined(CONFIG_SOC_JZ4760)
+ switch (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) {
+ case LCD_CFG_MODE_SPECIAL_TFT_1:
+ case LCD_CFG_MODE_SPECIAL_TFT_2:
+ case LCD_CFG_MODE_SPECIAL_TFT_3:
+ __gpio_as_lcd_special();
+ break;
+ default:
+ break;
+ }
+#endif
+}
+#ifdef CONFIG_LEDS_CLASS
+static void lcd_set_backlight_level(struct led_classdev *led_cdev, enum led_brightness value) {
+ __lcd_set_backlight_level((int)value);
+}
+
+static struct led_classdev lcd_backlight_led = {
+ .name = "lcd-backlight",
+ .brightness_set = lcd_set_backlight_level,
+};
+#endif
+
+
+static int __init jz4760fb_probe(struct platform_device *pdev)
+{
+ struct lcd_cfb_info *cfb;
+ int err = 0;
+ __lcd_close_backlight();
+ if (!pdev)
+ return -EINVAL;
+ jz4760_lcd_gpio_init(); /* gpio init */
+ __gpio_as_epd();
+ jz4760_lcd_init_cfg(); /* first config of lcd */
+
+ __lcd_clr_dis();
+ __lcd_clr_ena();
+
+ /* init clock */
+ __lcd_slcd_special_on();
+
+ cfb = jz4760fb_alloc_fb_info();
+ if (!cfb)
+ goto failed;
+
+ err = jz4760fb_map_smem(cfb);
+ if (err)
+ goto failed;
+
+ jz4760fb_deep_set_mode( jz4760_lcd_info );
+
+ /* registers frame buffer devices */
+
+ if (use_fg0_only || use_2layer_Fg)
+ { /* register fg0 */
+ err = register_framebuffer(&cfb->fb0);
+ if (err < 0) {
+ dprintk("jz4760fb_init(): register framebuffer err.\n");
+ goto failed;
+ }
+ printk("fb%d: %s frame buffer device, using %dK of video memory\n",
+ cfb->fb0.node, cfb->fb0.fix.id, cfb->fb0.fix.smem_len>>10);
+
+ }
+
+ if (use_fg1_only || use_2layer_Fg)
+ {/* register fg1 */
+ err = register_framebuffer(&cfb->fb);
+ if (err < 0) {
+ dprintk("jz4760fb_init(): register framebuffer err.\n");
+ goto failed;
+ }
+ printk("fb%d: %s frame buffer device, using %dK of video memory\n",
+ cfb->fb.node, cfb->fb.fix.id, cfb->fb.fix.smem_len>>10);
+ }
+
+
+ get_temp_sensor();
+ epd_gray_level = 8;
+ fill_init_palette();
+
+ if (request_irq(IRQ_LCD, jz4760fb_interrupt_handler, IRQF_DISABLED,
+ "lcd", 0)) {
+ err = -EBUSY;
+ goto failed;
+ }
+
+#ifdef CONFIG_LEDS_CLASS
+ err = led_classdev_register(&pdev->dev, &lcd_backlight_led);
+ if (err < 0)
+ goto failed;
+#endif
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+ init_epd_controller();
+ REG_SLCD_CTRL |= SLCD_CTRL_DMA_START;
+#endif
+
+#if defined(CONFIG_JZ4760_EPSON_EPD_DISPLAY)
+ REG_EPD_CTRL2 |= (EPD_CTRL2_PWRON);
+#else
+ __lcd_set_ena(); /* enalbe LCD Controller */
+ __lcd_display_on();
+#endif
+
+// print_lcdc_registers();
+ pm_set_vt_switch(0); /*disable VT switch during suspend/resume*/
+ return 0;
+
+failed:
+ print_dbg();
+ jz4760fb_unmap_smem(cfb);
+ jz4760fb_free_fb_info(cfb);
+
+ return err;
+}
+
+static int jz4760fb_remove(struct platform_device *pdev)
+{
+ struct lcd_cfb_info *cfb = platform_get_drvdata(pdev);
+
+ jz4760fb_unmap_smem(cfb);
+ jz4760fb_free_fb_info(cfb);
+ return 0;
+}
+
+
+
+static struct platform_driver jz_lcd_driver = {
+ .probe = jz4760fb_probe,
+ .remove = jz4760fb_remove,
+#ifdef CONFIG_PM
+ .suspend = jz4760fb_suspend,
+ .resume = jz4760fb_resume,
+#endif
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init jz4760fb_init(void)
+{
+ return platform_driver_register(&jz_lcd_driver);
+}
+
+static void __exit jz4760fb_cleanup(void)
+{
+ platform_driver_unregister(&jz_lcd_driver);
+}
+
+module_init(jz4760fb_init);
+module_exit(jz4760fb_cleanup);
diff --git a/drivers/video/jz4760_epd.h b/drivers/video/jz4760_epd.h
new file mode 100644
index 00000000000..0e8527ef4f7
--- /dev/null
+++ b/drivers/video/jz4760_epd.h
@@ -0,0 +1,252 @@
+/*
+ * linux/drivers/video/jz4760_lcd.h -- Ingenic Jz4760 On-Chip LCD frame buffer device
+ *
+ * Copyright (C) 2005-2008, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __JZ4760_LCD_H__
+#define __JZ4760_LCD_H__
+
+//#include <asm/io.h>
+
+
+#define NR_PALETTE 256
+#define PALETTE_SIZE (NR_PALETTE*2)
+
+/* use new descriptor(8 words) */
+struct jz4760_lcd_dma_desc {
+ unsigned int next_desc; /* LCDDAx */
+ unsigned int databuf; /* LCDSAx */
+ unsigned int frame_id; /* LCDFIDx */
+ unsigned int cmd; /* LCDCMDx */
+ unsigned int offsize; /* Stride Offsize(in word) */
+ unsigned int page_width; /* Stride Pagewidth(in word) */
+ unsigned int cmd_num; /* Command Number(for SLCD) */
+ unsigned int desc_size; /* Foreground Size */
+};
+
+struct jz4760_epd_dma_desc {
+ unsigned int next_desc; /* LCDDAx */
+ unsigned int databuf; /* LCDSAx */
+
+};
+
+
+struct jz4760lcd_panel_t {
+ unsigned int cfg; /* panel mode and pin usage etc. */
+ unsigned int slcd_cfg; /* Smart lcd configurations */
+ unsigned int ctrl; /* lcd controll register */
+ unsigned int w; /* Panel Width(in pixel) */
+ unsigned int h; /* Panel Height(in line) */
+ unsigned int fclk; /* frame clk */
+ unsigned int hsw; /* hsync width, in pclk */
+ unsigned int vsw; /* vsync width, in line count */
+ unsigned int elw; /* end of line, in pclk */
+ unsigned int blw; /* begin of line, in pclk */
+ unsigned int efw; /* end of frame, in line count */
+ unsigned int bfw; /* begin of frame, in line count */
+};
+
+
+struct jz4760lcd_fg_t {
+ int bpp; /* foreground bpp */
+ int x; /* foreground start position x */
+ int y; /* foreground start position y */
+ int w; /* foreground width */
+ int h; /* foreground height */
+};
+
+struct jz4760lcd_osd_t {
+ unsigned int osd_cfg; /* OSDEN, ALHPAEN, F0EN, F1EN, etc */
+ unsigned int osd_ctrl; /* IPUEN, OSDBPP, etc */
+ unsigned int rgb_ctrl; /* RGB Dummy, RGB sequence, RGB to YUV */
+ unsigned int bgcolor; /* background color(RGB888) */
+ unsigned int colorkey0; /* foreground0's Colorkey enable, Colorkey value */
+ unsigned int colorkey1; /* foreground1's Colorkey enable, Colorkey value */
+ unsigned int alpha; /* ALPHAEN, alpha value */
+ unsigned int ipu_restart; /* IPU Restart enable, ipu restart interval time */
+
+#define FG_NOCHANGE 0x0000
+#define FG0_CHANGE_SIZE 0x0001
+#define FG0_CHANGE_POSITION 0x0002
+#define FG1_CHANGE_SIZE 0x0010
+#define FG1_CHANGE_POSITION 0x0020
+#define FG_CHANGE_ALL ( FG0_CHANGE_SIZE | FG0_CHANGE_POSITION | \
+ FG1_CHANGE_SIZE | FG1_CHANGE_POSITION )
+ int fg_change;
+ struct jz4760lcd_fg_t fg0; /* foreground 0 */
+ struct jz4760lcd_fg_t fg1; /* foreground 1 */
+};
+
+struct jz4760lcd_info {
+ struct jz4760lcd_panel_t panel;
+ struct jz4760lcd_osd_t osd;
+};
+
+
+/* Jz LCDFB supported I/O controls. */
+#define FBIOSETBACKLIGHT 0x4688 /* set back light level */
+#define FBIODISPON 0x4689 /* display on */
+#define FBIODISPOFF 0x468a /* display off */
+#define FBIORESET 0x468b /* lcd reset */
+#define FBIOPRINT_REG 0x468c /* print lcd registers(debug) */
+#define FBIOROTATE 0x46a0 /* rotated fb */
+#define FBIOGETBUFADDRS 0x46a1 /* get buffers addresses */
+#define FBIO_GET_MODE 0x46a2 /* get lcd info */
+#define FBIO_SET_MODE 0x46a3 /* set osd mode */
+#define FBIO_DEEP_SET_MODE 0x46a4 /* set panel and osd mode */
+#define FBIO_MODE_SWITCH 0x46a5 /* switch mode between LCD and TVE */
+#define FBIO_GET_TVE_MODE 0x46a6 /* get tve info */
+#define FBIO_SET_TVE_MODE 0x46a7 /* set tve mode */
+#define FBIODISON_FG 0x46a8 /* FG display on */
+#define FBIODISOFF_FG 0x46a9 /* FG display on */
+#define FBIO_SET_LCD_TO_TVE 0x46b0 /* set lcd to tve mode */
+#define FBIO_SET_FRM_TO_LCD 0x46b1 /* set framebuffer to lcd */
+#define FBIO_SET_IPU_TO_LCD 0x46b2 /* set ipu to lcd directly */
+#define FBIO_CHANGE_SIZE 0x46b3 /* change FG size */
+#define FBIO_CHANGE_POSITION 0x46b4 /* change FG starts position */
+#define FBIO_SET_BG_COLOR 0x46b5 /* set background color */
+#define FBIO_SET_IPU_RESTART_VAL 0x46b6 /* set ipu restart value */
+#define FBIO_SET_IPU_RESTART_ON 0x46b7 /* set ipu restart on */
+#define FBIO_SET_IPU_RESTART_OFF 0x46b8 /* set ipu restart off */
+#define FBIO_ALPHA_ON 0x46b9 /* enable alpha */
+#define FBIO_ALPHA_OFF 0x46c0 /* disable alpha */
+#define FBIO_SET_ALPHA_VAL 0x46c1 /* set alpha value */
+
+
+#define GET_EPD_INFO 0x46d0
+#define START_EPD_TRANS 0x46d1
+
+
+/*
+ * LCD panel specific definition
+ */
+/* AUO */
+#if defined(CONFIG_JZ4760_LCD_AUO_A043FL01V2)
+#if defined(CONFIG_JZ4760_F4760) /* Jz4760 FPGA board */
+ #define LCD_RET (32*3+27) /*GPD29 LCD_DISP_N use for lcd reset*/
+#else
+#error "driver/video/Jzlcd.h, please define SPI pins on your board."
+#endif
+#define __lcd_special_pin_init() \
+ do { \
+ __gpio_as_output(LCD_RET); \
+ } while (0)
+#define __lcd_special_on() \
+ do { \
+ udelay(50); \
+ __gpio_clear_pin(LCD_RET); \
+ udelay(100); \
+ __gpio_set_pin(LCD_RET); \
+} while (0)
+
+ #define __lcd_special_off() \
+ do { \
+ __gpio_clear_pin(LCD_RET); \
+ } while (0)
+
+#endif /* CONFIG_JZLCD_AUO_A030FL01_V1 */
+
+#ifndef __lcd_special_pin_init
+#define __lcd_special_pin_init()
+#endif
+#ifndef __lcd_special_on
+#define __lcd_special_on()
+#endif
+#ifndef __lcd_special_off
+#define __lcd_special_off()
+#endif
+
+
+/*
+ * Platform specific definition
+ */
+#if defined(CONFIG_SOC_JZ4760) || defined(CONFIG_SOC_JZ4760D)
+
+#if defined(CONFIG_JZ4760_APUS) /* board apus */
+#define __lcd_display_pin_init() \
+do { \
+ __gpio_as_output(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_pin_init(); \
+} while (0)
+#define __lcd_display_on() \
+do { \
+ __gpio_clear_pin(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_on(); \
+ mdelay(200); \
+ __lcd_set_backlight_level(80); \
+} while (0)
+
+#define __lcd_display_off() \
+do { \
+ __lcd_close_backlight(); \
+ __lcd_special_off(); \
+} while (0)
+
+#elif defined(CONFIG_JZ4760D_CETUS)/* board apus */
+
+#define __lcd_display_pin_init() \
+do { \
+ __gpio_as_output(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_pin_init(); \
+} while (0)
+#define __lcd_display_on() \
+do { \
+ __gpio_set_pin(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_on(); \
+ __lcd_set_backlight_level(80); \
+} while (0)
+
+#define __lcd_display_off() \
+do { \
+ __lcd_close_backlight(); \
+ __lcd_special_off(); \
+} while (0)
+
+#else /* other boards */
+
+#define __lcd_display_pin_init() \
+do { \
+ __lcd_special_pin_init(); \
+} while (0)
+#define __lcd_display_on() \
+do { \
+ __lcd_special_on(); \
+ __lcd_set_backlight_level(80); \
+} while (0)
+
+#define __lcd_display_off() \
+do { \
+ __lcd_close_backlight(); \
+ __lcd_special_off(); \
+} while (0)
+#endif /* APUS */
+#endif /* CONFIG_SOC_JZ4760 */
+
+
+/*****************************************************************************
+ * LCD display pin dummy macros
+ *****************************************************************************/
+
+#ifndef __lcd_display_pin_init
+#define __lcd_display_pin_init()
+#endif
+#ifndef __lcd_slcd_special_on
+#define __lcd_slcd_special_on()
+#endif
+#ifndef __lcd_display_on
+#define __lcd_display_on()
+#endif
+#ifndef __lcd_display_off
+#define __lcd_display_off()
+#endif
+#ifndef __lcd_set_backlight_level
+#define __lcd_set_backlight_level(n)
+#endif
+
+#endif /* __JZ4760_LCD_H__ */
diff --git a/drivers/video/jz4760_lcd.c b/drivers/video/jz4760_lcd.c
new file mode 100644
index 00000000000..ba92933d193
--- /dev/null
+++ b/drivers/video/jz4760_lcd.c
@@ -0,0 +1,2454 @@
+/*
+ * linux/drivers/video/jz4760_lcd.c -- Ingenic Jz4760 LCD frame buffer device
+ *
+ * Copyright (C) 2005-2008, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * --------------------------------
+ * NOTE:
+ * This LCD driver support TFT16 TFT32 LCD, not support STN and Special TFT LCD
+ * now.
+ * It seems not necessory to support STN and Special TFT.
+ * If it's necessary, update this driver in the future.
+ * <Wolfgang Wang, Jun 10 2008>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/jzsoc.h>
+
+#include "console/fbcon.h"
+
+#include "jz4760_lcd.h"
+#include "jz4760_tve.h"
+
+#ifdef CONFIG_JZ4760_SLCD_KGM701A3_TFT_SPFD5420A
+#include "jz_kgm_spfd5420a.h"
+#endif
+
+MODULE_DESCRIPTION("Jz4760 LCD Controller driver");
+MODULE_AUTHOR("Wolfgang Wang, <lgwang@ingenic.cn>");
+MODULE_LICENSE("GPL");
+
+#define D(fmt, args...) \
+// printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
+
+#define E(fmt, args...) \
+ printk(KERN_ERR "%s(): "fmt"\n", __func__, ##args)
+
+#define JZ_FB_DEBUG 0
+static int lcd_backlight_level = 102;
+struct jz4760lcd_info jz4760_lcd_panel = {
+#if defined(CONFIG_JZ4760_LCD_SAMSUNG_LTP400WQF02)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_18BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 480, 272, 60, 41, 10, 2, 2, 2, 2,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 720, 573}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_AUO_A043FL01V2)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 480, 272, 60, 41, 10, 8, 4, 4, 2,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {16, 0, 0, 480, 272}, /* bpp, x, y, w, h */
+ .fg1 = {16, 0, 0, 720, 573}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_TOPPOLY_TD043MGEB1)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 800, 480, 60, 1, 1, 40, 215, 10, 34,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0xff, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 800, 480}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 800, 480}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_SLCD | /* Underrun recover*/
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SLCD, /* TFT Smart LCD panel */
+ .slcd_cfg = SLCD_CFG_DWIDTH_16BIT | SLCD_CFG_CWIDTH_16BIT | SLCD_CFG_CS_ACTIVE_LOW | SLCD_CFG_RS_CMD_LOW | SLCD_CFG_CLK_ACTIVE_FALLING | SLCD_CFG_TYPE_PARALLEL,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 240, 320, 60, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground0 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 240, 320}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 240, 320}, /* bpp, x, y, w, h */
+ },
+
+#elif defined(CONFIG_JZ4760_LCD_FOXCONN_PT035TN01)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+// LCD_CFG_MODE_TFT_18BIT | /* output 18bpp */
+ LCD_CFG_MODE_TFT_24BIT | /* output 24bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP | /* Vsync polarity: leading edge is falling edge */
+ LCD_CFG_PCP, /* Pix-CLK polarity: data translations at falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 320, 240, 80, 1, 1, 10, 50, 10, 13
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER | /* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SERIAL_TFT | /* Serial TFT panel */
+ LCD_CFG_MODE_TFT_18BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP | /* Vsync polarity: leading edge is falling edge */
+ LCD_CFG_PCP, /* Pix-CLK polarity: data translations at falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 320, 240, 60, 1, 1, 10, 50, 10, 13
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_SLCD_KGM701A3_TFT_SPFD5420A)
+ .panel = {
+// .cfg = LCD_CFG_LCDPIN_SLCD | LCD_CFG_RECOVER | /* Underrun recover*/
+ .cfg = LCD_CFG_LCDPIN_SLCD | /* Underrun recover*/
+// LCD_CFG_DITHER | /* dither */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_SLCD, /* TFT Smart LCD panel */
+ .slcd_cfg = SLCD_CFG_DWIDTH_18BIT | SLCD_CFG_CWIDTH_18BIT | SLCD_CFG_CS_ACTIVE_LOW | SLCD_CFG_RS_CMD_LOW | SLCD_CFG_CLK_ACTIVE_FALLING | SLCD_CFG_TYPE_PARALLEL,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+ 400, 240, 60, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_ALPHAMD | /* alpha blending mode */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+// .fg0 = {32, 0, 0, 400, 240}, /* bpp, x, y, w, h */
+ .fg0 = {32, 0, 0, 320, 240}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 400, 240}, /* bpp, x, y, w, h */
+ },
+#elif defined(CONFIG_JZ4760_VGA_DISPLAY)
+ .panel = {
+ .cfg = LCD_CFG_LCDPIN_LCD | LCD_CFG_RECOVER |/* Underrun recover */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_MODE_GENERIC_TFT | /* General TFT panel */
+ LCD_CFG_MODE_TFT_24BIT | /* output 18bpp */
+ LCD_CFG_HSP | /* Hsync polarity: active low */
+ LCD_CFG_VSP, /* Vsync polarity: leading edge is falling edge */
+ .slcd_cfg = 0,
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst, enable out FIFO underrun irq */
+// 800, 600, 60, 128, 4, 40, 88, 0, 23
+ 640, 480, 54, 96, 2, 16, 48, 10, 33
+// 1280, 720, 50, 152, 15, 22, 200, 14, 1
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+// LCD_OSDC_F1EN | /* enable Foreground1 */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = 0,
+ .bgcolor = 0x000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80001000, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32, 0, 0, 640, 480}, /* bpp, x, y, w, h */
+ .fg1 = {32, 0, 0, 640, 480}, /* bpp, x, y, w, h */
+ },
+#else
+#error "Select LCD panel first!!!"
+#endif
+};
+
+struct jz4760lcd_info jz4760_info_tve = {
+ .panel = {
+ .cfg = LCD_CFG_TVEN | /* output to tve */
+ LCD_CFG_NEWDES | /* 8words descriptor */
+ LCD_CFG_RECOVER | /* underrun protect */
+ LCD_CFG_MODE_INTER_CCIR656, /* Interlace CCIR656 mode */
+ .ctrl = LCD_CTRL_OFUM | LCD_CTRL_BST_16, /* 16words burst */
+ TVE_WIDTH_PAL, TVE_HEIGHT_PAL, TVE_FREQ_PAL, 0, 0, 0, 0, 0, 0,
+ },
+ .osd = {
+ .osd_cfg = LCD_OSDC_OSDEN | /* Use OSD mode */
+// LCD_OSDC_ALPHAEN | /* enable alpha */
+ LCD_OSDC_F0EN, /* enable Foreground0 */
+ .osd_ctrl = 0, /* disable ipu, */
+ .rgb_ctrl = LCD_RGBC_YCC, /* enable RGB => YUV */
+ .bgcolor = 0x00000000, /* set background color Black */
+ .colorkey0 = 0, /* disable colorkey */
+ .colorkey1 = 0, /* disable colorkey */
+ .alpha = 0xA0, /* alpha value */
+ .ipu_restart = 0x80000100, /* ipu restart */
+ .fg_change = FG_CHANGE_ALL, /* change all initially */
+ .fg0 = {32,}, /* */
+ .fg0 = {32,},
+ },
+};
+
+struct jz4760lcd_info *jz4760_lcd_info = &jz4760_lcd_panel; /* default output to lcd panel */
+
+#if 0//JZ_FB_DEBUG
+static void print_lcdc_registers(void) /* debug */
+{
+ /* LCD Controller Resgisters */
+ printk("REG_LCD_CFG:\t0x%08x\n", REG_LCD_CFG);
+ printk("REG_LCD_CTRL:\t0x%08x\n", REG_LCD_CTRL);
+ printk("REG_LCD_STATE:\t0x%08x\n", REG_LCD_STATE);
+ printk("REG_LCD_OSDC:\t0x%08x\n", REG_LCD_OSDC);
+ printk("REG_LCD_OSDCTRL:\t0x%08x\n", REG_LCD_OSDCTRL);
+ printk("REG_LCD_OSDS:\t0x%08x\n", REG_LCD_OSDS);
+ printk("REG_LCD_BGC:\t0x%08x\n", REG_LCD_BGC);
+ printk("REG_LCD_KEK0:\t0x%08x\n", REG_LCD_KEY0);
+ printk("REG_LCD_KEY1:\t0x%08x\n", REG_LCD_KEY1);
+ printk("REG_LCD_ALPHA:\t0x%08x\n", REG_LCD_ALPHA);
+ printk("REG_LCD_IPUR:\t0x%08x\n", REG_LCD_IPUR);
+ printk("REG_LCD_VAT:\t0x%08x\n", REG_LCD_VAT);
+ printk("REG_LCD_DAH:\t0x%08x\n", REG_LCD_DAH);
+ printk("REG_LCD_DAV:\t0x%08x\n", REG_LCD_DAV);
+ printk("REG_LCD_XYP0:\t0x%08x\n", REG_LCD_XYP0);
+ printk("REG_LCD_XYP1:\t0x%08x\n", REG_LCD_XYP1);
+ printk("REG_LCD_SIZE0:\t0x%08x\n", REG_LCD_SIZE0);
+ printk("REG_LCD_SIZE1:\t0x%08x\n", REG_LCD_SIZE1);
+ printk("REG_LCD_RGBC\t0x%08x\n", REG_LCD_RGBC);
+ printk("REG_LCD_VSYNC:\t0x%08x\n", REG_LCD_VSYNC);
+ printk("REG_LCD_HSYNC:\t0x%08x\n", REG_LCD_HSYNC);
+ printk("REG_LCD_PS:\t0x%08x\n", REG_LCD_PS);
+ printk("REG_LCD_CLS:\t0x%08x\n", REG_LCD_CLS);
+ printk("REG_LCD_SPL:\t0x%08x\n", REG_LCD_SPL);
+ printk("REG_LCD_REV:\t0x%08x\n", REG_LCD_REV);
+ printk("REG_LCD_IID:\t0x%08x\n", REG_LCD_IID);
+ printk("REG_LCD_DA0:\t0x%08x\n", REG_LCD_DA0);
+ printk("REG_LCD_SA0:\t0x%08x\n", REG_LCD_SA0);
+ printk("REG_LCD_FID0:\t0x%08x\n", REG_LCD_FID0);
+ printk("REG_LCD_CMD0:\t0x%08x\n", REG_LCD_CMD0);
+ printk("REG_LCD_OFFS0:\t0x%08x\n", REG_LCD_OFFS0);
+ printk("REG_LCD_PW0:\t0x%08x\n", REG_LCD_PW0);
+ printk("REG_LCD_CNUM0:\t0x%08x\n", REG_LCD_CNUM0);
+ printk("REG_LCD_DESSIZE0:\t0x%08x\n", REG_LCD_DESSIZE0);
+ printk("REG_LCD_DA1:\t0x%08x\n", REG_LCD_DA1);
+ printk("REG_LCD_SA1:\t0x%08x\n", REG_LCD_SA1);
+ printk("REG_LCD_FID1:\t0x%08x\n", REG_LCD_FID1);
+ printk("REG_LCD_CMD1:\t0x%08x\n", REG_LCD_CMD1);
+ printk("REG_LCD_OFFS1:\t0x%08x\n", REG_LCD_OFFS1);
+ printk("REG_LCD_PW1:\t0x%08x\n", REG_LCD_PW1);
+ printk("REG_LCD_CNUM1:\t0x%08x\n", REG_LCD_CNUM1);
+ printk("REG_LCD_DESSIZE1:\t0x%08x\n", REG_LCD_DESSIZE1);
+ printk("==================================\n");
+ printk("REG_LCD_VSYNC:\t%d:%d\n", REG_LCD_VSYNC>>16, REG_LCD_VSYNC&0xfff);
+ printk("REG_LCD_HSYNC:\t%d:%d\n", REG_LCD_HSYNC>>16, REG_LCD_HSYNC&0xfff);
+ printk("REG_LCD_VAT:\t%d:%d\n", REG_LCD_VAT>>16, REG_LCD_VAT&0xfff);
+ printk("REG_LCD_DAH:\t%d:%d\n", REG_LCD_DAH>>16, REG_LCD_DAH&0xfff);
+ printk("REG_LCD_DAV:\t%d:%d\n", REG_LCD_DAV>>16, REG_LCD_DAV&0xfff);
+ printk("==================================\n");
+
+ /* Smart LCD Controller Resgisters */
+ printk("REG_SLCD_CFG:\t0x%08x\n", REG_SLCD_CFG);
+ printk("REG_SLCD_CTRL:\t0x%08x\n", REG_SLCD_CTRL);
+ printk("REG_SLCD_STATE:\t0x%08x\n", REG_SLCD_STATE);
+ printk("==================================\n");
+
+ /* TVE Controller Resgisters */
+ printk("REG_TVE_CTRL:\t0x%08x\n", REG_TVE_CTRL);
+ printk("REG_TVE_FRCFG:\t0x%08x\n", REG_TVE_FRCFG);
+ printk("REG_TVE_SLCFG1:\t0x%08x\n", REG_TVE_SLCFG1);
+ printk("REG_TVE_SLCFG2:\t0x%08x\n", REG_TVE_SLCFG2);
+ printk("REG_TVE_SLCFG3:\t0x%08x\n", REG_TVE_SLCFG3);
+ printk("REG_TVE_LTCFG1:\t0x%08x\n", REG_TVE_LTCFG1);
+ printk("REG_TVE_LTCFG2:\t0x%08x\n", REG_TVE_LTCFG2);
+ printk("REG_TVE_CFREQ:\t0x%08x\n", REG_TVE_CFREQ);
+ printk("REG_TVE_CPHASE:\t0x%08x\n", REG_TVE_CPHASE);
+ printk("REG_TVE_CBCRCFG:\t0x%08x\n", REG_TVE_CBCRCFG);
+ printk("REG_TVE_WSSCR:\t0x%08x\n", REG_TVE_WSSCR);
+ printk("REG_TVE_WSSCFG1:\t0x%08x\n", REG_TVE_WSSCFG1);
+ printk("REG_TVE_WSSCFG2:\t0x%08x\n", REG_TVE_WSSCFG2);
+ printk("REG_TVE_WSSCFG3:\t0x%08x\n", REG_TVE_WSSCFG3);
+
+ printk("==================================\n");
+#if 0
+ if ( 0 ) {
+ unsigned int * pii = (unsigned int *)dma_desc_base;
+ int i, j;
+ for (j=0;j< DMA_DESC_NUM ; j++) {
+ printk("dma_desc%d(0x%08x):\n", j, (unsigned int)pii);
+ for (i =0; i<8; i++ ) {
+ printk("\t\t0x%08x\n", *pii++);
+ }
+ }
+ }
+#endif
+}
+#else
+#define print_lcdc_registers()
+#endif
+
+struct lcd_cfb_info {
+ struct fb_info fb;
+ struct {
+ u16 red, green, blue;
+ } palette[NR_PALETTE];
+
+ int b_lcd_display;
+ int b_lcd_pwm;
+ int backlight_level;
+};
+
+static struct lcd_cfb_info *jz4760fb_info;
+static struct jz4760_lcd_dma_desc *dma_desc_base;
+static struct jz4760_lcd_dma_desc *dma0_desc_palette, *dma0_desc0, *dma0_desc1, *dma1_desc0, *dma1_desc1;
+
+#define DMA_DESC_NUM 6
+
+static unsigned char *lcd_palette;
+static unsigned char *lcd_frame0;
+static unsigned char *lcd_frame1;
+
+static struct jz4760_lcd_dma_desc *dma0_desc_cmd0, *dma0_desc_cmd;
+static unsigned char *lcd_cmdbuf;
+
+static void jz4760fb_set_mode( struct jz4760lcd_info * lcd_info );
+static void jz4760fb_deep_set_mode( struct jz4760lcd_info * lcd_info );
+
+static int jz4760fb_set_backlight_level(int n);
+
+static int screen_on(void);
+static int screen_off(void);
+
+static void ctrl_enable(void)
+{
+ REG_LCD_STATE = 0; /* clear lcdc status */
+ __lcd_slcd_special_on();
+ __lcd_clr_dis();
+ __lcd_set_ena(); /* enable lcdc */
+
+ return;
+}
+
+static void ctrl_disable(void)
+{
+ if ( jz4760_lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD ||
+ jz4760_lcd_info->panel.cfg & LCD_CFG_TVEN ) /* */
+ __lcd_clr_ena(); /* Smart lcd and TVE mode only support quick disable */
+ else {
+ int cnt;
+ /* when CPU main freq is 336MHz,wait for 16ms */
+ cnt = 336000 * 16;
+ __lcd_set_dis(); /* regular disable */
+ //__lcd_clr_ena();
+ while(!__lcd_disable_done() && cnt) {
+ cnt--;
+ }
+ if (cnt == 0)
+ printk("LCD disable timeout! REG_LCD_STATE=0x%08xx\n",REG_LCD_STATE);
+ REG_LCD_STATE &= ~LCD_STATE_LDD;
+ }
+
+ return;
+}
+
+static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+static int jz4760fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ unsigned short *ptr, ctmp;
+
+// D("regno:%d,RGBt:(%d,%d,%d,%d)\t", regno, red, green, blue, transp);
+ if (regno >= NR_PALETTE)
+ return 1;
+
+ cfb->palette[regno].red = red ;
+ cfb->palette[regno].green = green;
+ cfb->palette[regno].blue = blue;
+ if (cfb->fb.var.bits_per_pixel <= 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+
+ red &= 0xff;
+ green &= 0xff;
+ blue &= 0xff;
+ }
+ switch (cfb->fb.var.bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (((jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_SINGLE_MSTN ) ||
+ ((jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) == LCD_CFG_MODE_DUAL_MSTN )) {
+ ctmp = (77L * red + 150L * green + 29L * blue) >> 8;
+ ctmp = ((ctmp >> 3) << 11) | ((ctmp >> 2) << 5) |
+ (ctmp >> 3);
+ } else {
+ /* RGB 565 */
+ if (((red >> 3) == 0) && ((red >> 2) != 0))
+ red = 1 << 3;
+ if (((blue >> 3) == 0) && ((blue >> 2) != 0))
+ blue = 1 << 3;
+ ctmp = ((red >> 3) << 11)
+ | ((green >> 2) << 5) | (blue >> 3);
+ }
+
+ ptr = (unsigned short *)lcd_palette;
+ ptr = (unsigned short *)(((u32)ptr)|0xa0000000);
+ ptr[regno] = ctmp;
+
+ break;
+
+ case 15:
+ if (regno < 16)
+ ((u32 *)cfb->fb.pseudo_palette)[regno] =
+ ((red >> 3) << 10) |
+ ((green >> 3) << 5) |
+ (blue >> 3);
+ break;
+ case 16:
+ if (regno < 16) {
+ ((u32 *)cfb->fb.pseudo_palette)[regno] =
+ ((red >> 3) << 11) |
+ ((green >> 2) << 5) |
+ (blue >> 3);
+ }
+ break;
+ case 17 ... 32:
+ if (regno < 16)
+ ((u32 *)cfb->fb.pseudo_palette)[regno] =
+ (red << 16) |
+ (green << 8) |
+ (blue << 0);
+
+/* if (regno < 16) {
+ unsigned val;
+ val = chan_to_field(red, &cfb->fb.var.red);
+ val |= chan_to_field(green, &cfb->fb.var.green);
+ val |= chan_to_field(blue, &cfb->fb.var.blue);
+ ((u32 *)cfb->fb.pseudo_palette)[regno] = val;
+ }
+*/
+
+ break;
+ }
+ return 0;
+}
+
+
+/*
+ * switch to tve mode from lcd mode
+ * mode:
+ * PANEL_MODE_TVE_PAL: switch to TVE_PAL mode
+ * PANEL_MODE_TVE_NTSC: switch to TVE_NTSC mode
+ */
+static void jz4760lcd_info_switch_to_TVE(int mode)
+{
+ struct jz4760lcd_info *info;
+ struct jz4760lcd_osd_t *osd_lcd;
+ int x, y, w, h;
+
+ info = jz4760_lcd_info = &jz4760_info_tve;
+ osd_lcd = &jz4760_lcd_panel.osd;
+
+ switch ( mode ) {
+ case PANEL_MODE_TVE_PAL:
+ info->panel.cfg |= LCD_CFG_TVEPEH; /* TVE PAL enable extra halfline signal */
+ info->panel.w = TVE_WIDTH_PAL;
+ info->panel.h = TVE_HEIGHT_PAL;
+ info->panel.fclk = TVE_FREQ_PAL;
+ w = ( osd_lcd->fg0.w < TVE_WIDTH_PAL )? osd_lcd->fg0.w:TVE_WIDTH_PAL;
+ h = ( osd_lcd->fg0.h < TVE_HEIGHT_PAL )?osd_lcd->fg0.h:TVE_HEIGHT_PAL;
+// x = ((TVE_WIDTH_PAL - w) >> 2) << 1;
+// y = ((TVE_HEIGHT_PAL - h) >> 2) << 1;
+ x = 0;
+ y = 0;
+
+ info->osd.fg0.bpp = osd_lcd->fg0.bpp;
+ info->osd.fg0.x = x;
+ info->osd.fg0.y = y;
+ info->osd.fg0.w = w;
+ info->osd.fg0.h = h;
+ w = ( osd_lcd->fg1.w < TVE_WIDTH_PAL )? osd_lcd->fg1.w:TVE_WIDTH_PAL;
+ h = ( osd_lcd->fg1.h < TVE_HEIGHT_PAL )?osd_lcd->fg1.h:TVE_HEIGHT_PAL;
+// x = ((TVE_WIDTH_PAL-w) >> 2) << 1;
+// y = ((TVE_HEIGHT_PAL-h) >> 2) << 1;
+ x = 0;
+ y = 0;
+
+ info->osd.fg1.bpp = 32; /* use RGB888 in TVE mode*/
+ info->osd.fg1.x = x;
+ info->osd.fg1.y = y;
+ info->osd.fg1.w = w;
+ info->osd.fg1.h = h;
+ break;
+ case PANEL_MODE_TVE_NTSC:
+ info->panel.cfg &= ~LCD_CFG_TVEPEH; /* TVE NTSC disable extra halfline signal */
+ info->panel.w = TVE_WIDTH_NTSC;
+ info->panel.h = TVE_HEIGHT_NTSC;
+ info->panel.fclk = TVE_FREQ_NTSC;
+ w = ( osd_lcd->fg0.w < TVE_WIDTH_NTSC )? osd_lcd->fg0.w:TVE_WIDTH_NTSC;
+ h = ( osd_lcd->fg0.h < TVE_HEIGHT_NTSC)?osd_lcd->fg0.h:TVE_HEIGHT_NTSC;
+ x = ((TVE_WIDTH_NTSC - w) >> 2) << 1;
+ y = ((TVE_HEIGHT_NTSC - h) >> 2) << 1;
+// x = 0;
+// y = 0;
+ info->osd.fg0.bpp = osd_lcd->fg0.bpp;
+ info->osd.fg0.x = x;
+ info->osd.fg0.y = y;
+ info->osd.fg0.w = w;
+ info->osd.fg0.h = h;
+ w = ( osd_lcd->fg1.w < TVE_WIDTH_NTSC )? osd_lcd->fg1.w:TVE_WIDTH_NTSC;
+ h = ( osd_lcd->fg1.h < TVE_HEIGHT_NTSC)?osd_lcd->fg1.h:TVE_HEIGHT_NTSC;
+ x = ((TVE_WIDTH_NTSC - w) >> 2) << 1;
+ y = ((TVE_HEIGHT_NTSC - h) >> 2) << 1;
+ info->osd.fg1.bpp = 32; /* use RGB888 int TVE mode */
+ info->osd.fg1.x = x;
+ info->osd.fg1.y = y;
+ info->osd.fg1.w = w;
+ info->osd.fg1.h = h;
+ break;
+ default:
+ printk("%s, %s: Unknown tve mode\n", __FILE__, __FUNCTION__);
+ }
+}
+
+static int jz4760fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+
+ void __user *argp = (void __user *)arg;
+
+ switch (cmd) {
+ case FBIOSETBACKLIGHT:
+ jz4760fb_set_backlight_level(arg);
+
+ break;
+
+ case FBIODISPON:
+ ctrl_enable();
+ screen_on();
+
+ break;
+
+ case FBIODISPOFF:
+ screen_off();
+ ctrl_disable();
+
+ break;
+
+ case FBIOPRINT_REG:
+ print_lcdc_registers();
+
+ break;
+
+ case FBIO_GET_MODE:
+ D("fbio get mode\n");
+
+ if (copy_to_user(argp, jz4760_lcd_info, sizeof(struct jz4760lcd_info)))
+ return -EFAULT;
+
+ break;
+
+ case FBIO_SET_MODE:
+ D("fbio set mode\n");
+
+ if (copy_from_user(jz4760_lcd_info, argp, sizeof(struct jz4760lcd_info)))
+ return -EFAULT;
+
+ /* set mode */
+ jz4760fb_set_mode(jz4760_lcd_info);
+
+ break;
+
+ case FBIO_DEEP_SET_MODE:
+ D("fbio deep set mode\n");
+
+ if (copy_from_user(jz4760_lcd_info, argp, sizeof(struct jz4760lcd_info)))
+ return -EFAULT;
+
+ jz4760fb_deep_set_mode(jz4760_lcd_info);
+
+ break;
+
+#ifdef CONFIG_FB_JZ4760_TVE
+ case FBIO_MODE_SWITCH:
+ D("FBIO_MODE_SWITCH");
+ switch (arg) {
+ case PANEL_MODE_TVE_PAL: /* switch to TVE_PAL mode */
+ case PANEL_MODE_TVE_NTSC: /* switch to TVE_NTSC mode */
+ jz4760lcd_info_switch_to_TVE(arg);
+ jz4760tve_init(arg); /* tve controller init */
+ udelay(100);
+ jz4760tve_enable_tve();
+ /* turn off lcd backlight */
+ screen_off();
+ break;
+ case PANEL_MODE_LCD_PANEL: /* switch to LCD mode */
+ default :
+ /* turn off TVE, turn off DACn... */
+ jz4760tve_disable_tve();
+ jz4760_lcd_info = &jz4760_lcd_panel;
+ /* turn on lcd backlight */
+ screen_on();
+ break;
+ }
+
+ jz4760fb_deep_set_mode(jz4760_lcd_info);
+
+ break;
+
+ case FBIO_GET_TVE_MODE:
+ D("fbio get TVE mode\n");
+ if (copy_to_user(argp, jz4760_tve_info, sizeof(struct jz4760tve_info)))
+ return -EFAULT;
+ break;
+ case FBIO_SET_TVE_MODE:
+ D("fbio set TVE mode\n");
+ if (copy_from_user(jz4760_tve_info, argp, sizeof(struct jz4760tve_info)))
+ return -EFAULT;
+ /* set tve mode */
+ jz4760tve_set_tve_mode(jz4760_tve_info);
+ break;
+#endif
+ default:
+ printk("%s, unknown command(0x%x)", __FILE__, cmd);
+ break;
+ }
+
+ return ret;
+}
+
+/* Use mmap /dev/fb can only get a non-cacheable Virtual Address. */
+static int jz4760fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ unsigned long start;
+ unsigned long off;
+ u32 len;
+ D("%s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
+ off = vma->vm_pgoff << PAGE_SHIFT;
+ //fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
+
+ /* frame buffer memory */
+ start = cfb->fb.fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK) + cfb->fb.fix.smem_len);
+ start &= PAGE_MASK;
+
+ if ((vma->vm_end - vma->vm_start + off) > len)
+ return -EINVAL;
+ off += start;
+
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ vma->vm_flags |= VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Uncacheable */
+
+#if 1
+ pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+ pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED; /* Uncacheable */
+// pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT; /* Write-Back */
+#endif
+
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+/* checks var and eventually tweaks it to something supported,
+ * DO NOT MODIFY PAR */
+static int jz4760fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ printk("jz4760fb_check_var, not implement\n");
+ return 0;
+}
+
+
+/*
+ * set the video mode according to info->var
+ */
+static int jz4760fb_set_par(struct fb_info *info)
+{
+ printk("jz4760fb_set_par, not implemented\n");
+ return 0;
+}
+
+
+/*
+ * (Un)Blank the display.
+ * Fix me: should we use VESA value?
+ */
+static int jz4760fb_blank(int blank_mode, struct fb_info *info)
+{
+ D("jz4760 fb_blank %d %p", blank_mode, info);
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ //case FB_BLANK_NORMAL:
+ /* Turn on panel */
+ __lcd_set_ena();
+ screen_on();
+
+ break;
+
+ case FB_BLANK_NORMAL:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_POWERDOWN:
+#if 0
+ /* Turn off panel */
+ __lcd_display_off();
+ __lcd_set_dis();
+#endif
+ break;
+ default:
+ break;
+
+ }
+ return 0;
+}
+
+/*
+ * pan display
+ */
+static int jz4760fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ int dy;
+
+ if (!var || !cfb) {
+ return -EINVAL;
+ }
+
+ if (var->xoffset - cfb->fb.var.xoffset) {
+ /* No support for X panning for now! */
+ return -EINVAL;
+ }
+
+ dy = var->yoffset;
+ D("var.yoffset: %d", dy);
+ if (dy) {
+ dma0_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame0 + (cfb->fb.fix.line_length * dy));
+ dma_cache_wback((unsigned int)(dma0_desc0), sizeof(struct jz4760_lcd_dma_desc));
+
+ }
+ else {
+ dma0_desc0->databuf = (unsigned int)virt_to_phys((void *)lcd_frame0);
+ dma_cache_wback((unsigned int)(dma0_desc0), sizeof(struct jz4760_lcd_dma_desc));
+ }
+
+ return 0;
+}
+
+
+/* use default function cfb_fillrect, cfb_copyarea, cfb_imageblit */
+static struct fb_ops jz4760fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = jz4760fb_setcolreg,
+ .fb_check_var = jz4760fb_check_var,
+ .fb_set_par = jz4760fb_set_par,
+ .fb_blank = jz4760fb_blank,
+ .fb_pan_display = jz4760fb_pan_display,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = jz4760fb_mmap,
+ .fb_ioctl = jz4760fb_ioctl,
+};
+
+static int jz4760fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;
+ struct jz4760lcd_info *lcd_info = jz4760_lcd_info;
+ int chgvar = 0;
+
+ var->height = lcd_info->osd.fg0.h; /* tve mode */
+ var->width = lcd_info->osd.fg0.w;
+ var->bits_per_pixel = lcd_info->osd.fg0.bpp;
+
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->activate = cfb->fb.var.activate;
+ var->xres = var->width;
+ var->yres = var->height;
+ var->xres_virtual = var->width;
+ var->yres_virtual = var->height;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->pixclock = 0;
+ var->left_margin = 0;
+ var->right_margin = 0;
+ var->upper_margin = 0;
+ var->lower_margin = 0;
+ var->hsync_len = 0;
+ var->vsync_len = 0;
+ var->sync = 0;
+ var->activate &= ~FB_ACTIVATE_TEST;
+
+ /*
+ * CONUPDATE and SMOOTH_XPAN are equal. However,
+ * SMOOTH_XPAN is only used internally by fbcon.
+ */
+ if (var->vmode & FB_VMODE_CONUPDATE) {
+ var->vmode |= FB_VMODE_YWRAP;
+ var->xoffset = cfb->fb.var.xoffset;
+ var->yoffset = cfb->fb.var.yoffset;
+ }
+
+ if (var->activate & FB_ACTIVATE_TEST)
+ return 0;
+
+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+ return -EINVAL;
+
+ if (cfb->fb.var.xres != var->xres)
+ chgvar = 1;
+ if (cfb->fb.var.yres != var->yres)
+ chgvar = 1;
+ if (cfb->fb.var.xres_virtual != var->xres_virtual)
+ chgvar = 1;
+ if (cfb->fb.var.yres_virtual != var->yres_virtual)
+ chgvar = 1;
+ if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel)
+ chgvar = 1;
+
+ //display = fb_display + con;
+
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+
+ switch(var->bits_per_pixel){
+ case 1: /* Mono */
+ cfb->fb.fix.visual = FB_VISUAL_MONO01;
+ cfb->fb.fix.line_length = (var->xres * var->bits_per_pixel) / 8;
+ break;
+ case 2: /* Mono */
+ var->red.offset = 0;
+ var->red.length = 2;
+ var->green.offset = 0;
+ var->green.length = 2;
+ var->blue.offset = 0;
+ var->blue.length = 2;
+
+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ cfb->fb.fix.line_length = (var->xres * var->bits_per_pixel) / 8;
+ break;
+ case 4: /* PSEUDOCOLOUR*/
+ var->red.offset = 0;
+ var->red.length = 4;
+ var->green.offset = 0;
+ var->green.length = 4;
+ var->blue.offset = 0;
+ var->blue.length = 4;
+
+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ cfb->fb.fix.line_length = var->xres / 2;
+ break;
+ case 8: /* PSEUDOCOLOUR, 256 */
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+
+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ cfb->fb.fix.line_length = var->xres ;
+ break;
+ case 15: /* DIRECTCOLOUR, 32k */
+ var->bits_per_pixel = 15;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
+ cfb->fb.fix.line_length = var->xres_virtual * 2;
+ break;
+ case 16: /* DIRECTCOLOUR, 64k */
+ var->bits_per_pixel = 16;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ cfb->fb.fix.line_length = var->xres_virtual * 2;
+ break;
+ case 17 ... 32:
+ /* DIRECTCOLOUR, 256 */
+ var->bits_per_pixel = 32;
+
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+
+ cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ cfb->fb.fix.line_length = var->xres_virtual * 4;
+ break;
+
+ default: /* in theory this should never happen */
+ printk(KERN_WARNING "%s: don't support for %dbpp\n",
+ cfb->fb.fix.id, var->bits_per_pixel);
+ break;
+ }
+
+ cfb->fb.var = *var;
+ cfb->fb.var.activate &= ~FB_ACTIVATE_ALL;
+
+ /*
+ * Update the old var. The fbcon drivers still use this.
+ * Once they are using cfb->fb.var, this can be dropped.
+ * --rmk
+ */
+ //display->var = cfb->fb.var;
+ /*
+ * If we are setting all the virtual consoles, also set the
+ * defaults used to create new consoles.
+ */
+ fb_set_cmap(&cfb->fb.cmap, &cfb->fb);
+
+ return 0;
+}
+
+static struct lcd_cfb_info * jz4760fb_alloc_fb_info(void)
+{
+ struct lcd_cfb_info *cfb;
+
+ cfb = kmalloc(sizeof(struct lcd_cfb_info) + sizeof(u32) * 16, GFP_KERNEL);
+
+ if (!cfb)
+ return NULL;
+
+ jz4760fb_info = cfb;
+
+ memset(cfb, 0, sizeof(struct lcd_cfb_info) );
+
+ cfb->backlight_level = LCD_DEFAULT_BACKLIGHT;
+
+ strcpy(cfb->fb.fix.id, "jz-lcd");
+ cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ cfb->fb.fix.type_aux = 0;
+ cfb->fb.fix.xpanstep = 1;
+ cfb->fb.fix.ypanstep = 1;
+ cfb->fb.fix.ywrapstep = 0;
+ cfb->fb.fix.accel = FB_ACCEL_NONE;
+
+ cfb->fb.var.nonstd = 0;
+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
+ cfb->fb.var.height = -1;
+ cfb->fb.var.width = -1;
+ cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
+
+ cfb->fb.fbops = &jz4760fb_ops;
+ cfb->fb.flags = FBINFO_FLAG_DEFAULT;
+
+ cfb->fb.pseudo_palette = (void *)(cfb + 1);
+
+ switch (jz4760_lcd_info->osd.fg0.bpp) {
+ case 1:
+ fb_alloc_cmap(&cfb->fb.cmap, 4, 0);
+ break;
+ case 2:
+ fb_alloc_cmap(&cfb->fb.cmap, 8, 0);
+ break;
+ case 4:
+ fb_alloc_cmap(&cfb->fb.cmap, 32, 0);
+ break;
+ case 8:
+
+ default:
+ fb_alloc_cmap(&cfb->fb.cmap, 256, 0);
+ break;
+ }
+ D("fb_alloc_cmap,fb.cmap.len:%d....\n", cfb->fb.cmap.len);
+
+ return cfb;
+}
+
+static int bpp_to_data_bpp(int bpp)
+{
+ switch (bpp) {
+ case 32:
+ case 16:
+ break;
+
+ case 15:
+ bpp = 16;
+ break;
+
+ default:
+ bpp = -EINVAL;
+ }
+
+ return bpp;
+}
+
+/*
+ * Map screen memory
+ */
+static int jz4760fb_map_smem(struct lcd_cfb_info *cfb)
+{
+ unsigned long page;
+ unsigned int page_shift, needroom, needroom1, bpp, w, h;
+
+ bpp = bpp_to_data_bpp(jz4760_lcd_info->osd.fg0.bpp);
+
+ D("FG0 BPP: %d, Data BPP: %d.", jz4760_lcd_info->osd.fg0.bpp, bpp);
+
+#ifndef CONFIG_FB_JZ4760_TVE
+ w = jz4760_lcd_info->osd.fg0.w;
+ h = jz4760_lcd_info->osd.fg0.h;
+#else
+ w = ( jz4760_lcd_info->osd.fg0.w > TVE_WIDTH_PAL )?jz4760_lcd_info->osd.fg0.w:TVE_WIDTH_PAL;
+ h = ( jz4760_lcd_info->osd.fg0.h > TVE_HEIGHT_PAL )?jz4760_lcd_info->osd.fg0.h:TVE_HEIGHT_PAL;
+#endif
+ needroom1 = needroom = ((w * bpp + 7) >> 3) * h;
+
+#if defined(CONFIG_FB_JZ4760_LCD_USE_2LAYER_FRAMEBUFFER)
+ bpp = bpp_to_data_bpp(jz4760_lcd_info->osd.fg1.bpp);
+
+ D("FG1 BPP: %d, Data BPP: %d.", jz4760_lcd_info->osd.fg1.bpp, bpp);
+
+#ifndef CONFIG_FB_JZ4760_TVE
+ w = jz4760_lcd_info->osd.fg1.w;
+ h = jz4760_lcd_info->osd.fg1.h;
+#else
+ w = ( jz4760_lcd_info->osd.fg1.w > TVE_WIDTH_PAL )?jz4760_lcd_info->osd.fg1.w:TVE_WIDTH_PAL;
+ h = ( jz4760_lcd_info->osd.fg1.h > TVE_HEIGHT_PAL )?jz4760_lcd_info->osd.fg1.h:TVE_HEIGHT_PAL;
+#endif
+ needroom += ((w * bpp + 7) >> 3) * h;
+#endif // two layer
+
+ for (page_shift = 0; page_shift < 12; page_shift++)
+ if ((PAGE_SIZE << page_shift) >= needroom)
+ break;
+ lcd_palette = (unsigned char *)__get_free_pages(GFP_KERNEL, 0);
+ lcd_frame0 = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);
+
+ if ((!lcd_palette) || (!lcd_frame0))
+ return -ENOMEM;
+ memset((void *)lcd_palette, 0, PAGE_SIZE);
+ memset((void *)lcd_frame0, 0, PAGE_SIZE << page_shift);
+
+ dma_desc_base = (struct jz4760_lcd_dma_desc *)((void*)lcd_palette + ((PALETTE_SIZE+3)/4)*4);
+
+#if defined(CONFIG_FB_JZ4760_SLCD)
+ lcd_cmdbuf = (unsigned char *)__get_free_pages(GFP_KERNEL, 0);
+ memset((void *)lcd_cmdbuf, 0, PAGE_SIZE);
+
+ { int data, i, *ptr;
+ ptr = (unsigned int *)lcd_cmdbuf;
+ data = WR_GRAM_CMD;
+ data = ((data & 0xff) << 1) | ((data & 0xff00) << 2);
+ for(i = 0; i < 3; i++){
+ ptr[i] = data;
+ }
+ }
+#endif
+
+#if defined(CONFIG_FB_JZ4760_LCD_USE_2LAYER_FRAMEBUFFER)
+ lcd_frame1 = lcd_frame0 + needroom1;
+#endif
+
+ /*
+ * Set page reserved so that mmap will work. This is necessary
+ * since we'll be remapping normal memory.
+ */
+ page = (unsigned long)lcd_palette;
+ SetPageReserved(virt_to_page((void*)page));
+
+ for (page = (unsigned long)lcd_frame0;
+ page < PAGE_ALIGN((unsigned long)lcd_frame0 + (PAGE_SIZE<<page_shift));
+ page += PAGE_SIZE) {
+ SetPageReserved(virt_to_page((void*)page));
+ }
+
+ cfb->fb.fix.smem_start = virt_to_phys((void *)lcd_frame0);
+ cfb->fb.fix.smem_len = (PAGE_SIZE << page_shift); /* page_shift/2 ??? */
+ cfb->fb.screen_base =
+ (unsigned char *)(((unsigned int)lcd_frame0&0x1fffffff) | 0xa0000000);
+
+ if (!cfb->fb.screen_base) {
+ printk("jz4760fb, %s: unable to map screen memory\n", cfb->fb.fix.id);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void jz4760fb_free_fb_info(struct lcd_cfb_info *cfb)
+{
+ if (cfb) {
+ fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
+ kfree(cfb);
+ }
+}
+
+static void jz4760fb_unmap_smem(struct lcd_cfb_info *cfb)
+{
+ struct page * map = NULL;
+ unsigned char *tmp;
+ unsigned int page_shift, needroom, bpp, w, h;
+
+ bpp = jz4760_lcd_info->osd.fg0.bpp;
+ if ( bpp == 18 || bpp == 24)
+ bpp = 32;
+ if ( bpp == 15 )
+ bpp = 16;
+ w = jz4760_lcd_info->osd.fg0.w;
+ h = jz4760_lcd_info->osd.fg0.h;
+ needroom = ((w * bpp + 7) >> 3) * h;
+#if defined(CONFIG_FB_JZ4760_LCD_USE_2LAYER_FRAMEBUFFER)
+ bpp = jz4760_lcd_info->osd.fg1.bpp;
+ if ( bpp == 18 || bpp == 24)
+ bpp = 32;
+ if ( bpp == 15 )
+ bpp = 16;
+ w = jz4760_lcd_info->osd.fg1.w;
+ h = jz4760_lcd_info->osd.fg1.h;
+ needroom += ((w * bpp + 7) >> 3) * h;
+#endif
+
+ for (page_shift = 0; page_shift < 12; page_shift++)
+ if ((PAGE_SIZE << page_shift) >= needroom)
+ break;
+
+ if (cfb && cfb->fb.screen_base) {
+ iounmap(cfb->fb.screen_base);
+ cfb->fb.screen_base = NULL;
+ release_mem_region(cfb->fb.fix.smem_start,
+ cfb->fb.fix.smem_len);
+ }
+
+ if (lcd_palette) {
+ map = virt_to_page(lcd_palette);
+ clear_bit(PG_reserved, &map->flags);
+ free_pages((int)lcd_palette, 0);
+ }
+
+ if (lcd_frame0) {
+ for (tmp=(unsigned char *)lcd_frame0;
+ tmp < lcd_frame0 + (PAGE_SIZE << page_shift);
+ tmp += PAGE_SIZE) {
+ map = virt_to_page(tmp);
+ clear_bit(PG_reserved, &map->flags);
+ }
+ free_pages((int)lcd_frame0, page_shift);
+ }
+}
+
+/* initial dma descriptors */
+static void jz4760fb_descriptor_init( struct jz4760lcd_info * lcd_info )
+{
+ unsigned int pal_size;
+
+ switch ( lcd_info->osd.fg0.bpp ) {
+ case 1:
+ pal_size = 4;
+ break;
+ case 2:
+ pal_size = 8;
+ break;
+ case 4:
+ pal_size = 32;
+ break;
+ case 8:
+ default:
+ pal_size = 512;
+ }
+
+ pal_size /= 4;
+
+ dma0_desc_palette = dma_desc_base + 0;
+ dma0_desc0 = dma_desc_base + 1;
+ dma0_desc1 = dma_desc_base + 2;
+ dma0_desc_cmd0 = dma_desc_base + 3; /* use only once */
+ dma0_desc_cmd = dma_desc_base + 4;
+ dma1_desc0 = dma_desc_base + 5;
+ dma1_desc1 = dma_desc_base + 6;
+
+ /*
+ * Normal TFT panel's DMA Chan0:
+ * TO LCD Panel:
+ * no palette: dma0_desc0 <<==>> dma0_desc0
+ * palette : dma0_desc_palette <<==>> dma0_desc0
+ * TO TV Encoder:
+ * no palette: dma0_desc0 <<==>> dma0_desc1
+ * palette: dma0_desc_palette --> dma0_desc0
+ * --> dma0_desc1 --> dma0_desc_palette --> ...
+ *
+ * SMART LCD TFT panel(dma0_desc_cmd)'s DMA Chan0:
+ * TO LCD Panel:
+ * no palette: dma0_desc_cmd <<==>> dma0_desc0
+ * palette : dma0_desc_palette --> dma0_desc_cmd
+ * --> dma0_desc0 --> dma0_desc_palette --> ...
+ * TO TV Encoder:
+ * no palette: dma0_desc_cmd --> dma0_desc0
+ * --> dma0_desc1 --> dma0_desc_cmd --> ...
+ * palette: dma0_desc_palette --> dma0_desc_cmd
+ * --> dma0_desc0 --> dma0_desc1
+ * --> dma0_desc_palette --> ...
+ * DMA Chan1:
+ * TO LCD Panel:
+ * dma1_desc0 <<==>> dma1_desc0
+ * TO TV Encoder:
+ * dma1_desc0 <<==>> dma1_desc1
+ */
+
+#if defined(CONFIG_FB_JZ4760_SLCD)
+ /* First CMD descriptors, use only once, cmd_num isn't 0 */
+ dma0_desc_cmd0->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc_cmd0->databuf = (unsigned int)virt_to_phys((void *)lcd_cmdbuf);
+ dma0_desc_cmd0->frame_id = (unsigned int)0x0da0cad0; /* dma0's cmd0 */
+ dma0_desc_cmd0->cmd = LCD_CMD_CMD | 3; /* command */
+ dma0_desc_cmd0->offsize = 0;
+ dma0_desc_cmd0->page_width = 0;
+ dma0_desc_cmd0->cmd_num = 3;
+
+ /* Dummy Command Descriptor, cmd_num is 0 */
+ dma0_desc_cmd->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc_cmd->databuf = 0;
+ dma0_desc_cmd->frame_id = (unsigned int)0x0da000cd; /* dma0's cmd0 */
+ dma0_desc_cmd->cmd = LCD_CMD_CMD | 0; /* dummy command */
+ dma0_desc_cmd->cmd_num = 0;
+ dma0_desc_cmd->offsize = 0;
+ dma0_desc_cmd->page_width = 0;
+
+ /* Palette Descriptor */
+ dma0_desc_palette->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd0);
+#else
+ /* Palette Descriptor */
+ dma0_desc_palette->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+#endif
+ dma0_desc_palette->databuf = (unsigned int)virt_to_phys((void *)lcd_palette);
+ dma0_desc_palette->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+
+ /* DMA0 Descriptor0 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) /* TVE mode */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc1);
+ else{ /* Normal TFT LCD */
+#if defined(CONFIG_FB_JZ4760_SLCD)
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd);
+#else
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+#endif
+ }
+
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+
+ /* DMA0 Descriptor1 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* TVE mode */
+
+
+ if (lcd_info->osd.fg0.bpp <= 8) /* load palette only once at setup */
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette);
+ else
+#if defined(CONFIG_FB_JZ4760_SLCD) /* for smatlcd */
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd);
+#else
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+#endif
+ dma0_desc1->frame_id = (unsigned int)0x0000da01; /* DMA0'1 */
+ }
+
+ if (lcd_info->osd.fg0.bpp <= 8) /* load palette only once at setup */
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_palette);
+ else {
+#if defined(CONFIG_FB_JZ4760_SLCD) /* for smartlcd */
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_cmd0); //smart lcd
+#else
+ REG_LCD_DA0 = virt_to_phys(dma0_desc0); //tft
+#endif
+ }
+
+ /* DMA1 Descriptor0 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) /* TVE mode */
+ dma1_desc0->next_desc = (unsigned int)virt_to_phys(dma1_desc1);
+ else /* Normal TFT LCD */
+ dma1_desc0->next_desc = (unsigned int)virt_to_phys(dma1_desc0);
+
+ dma1_desc0->databuf = virt_to_phys((void *)lcd_frame1);
+ dma1_desc0->frame_id = (unsigned int)0x0000da10; /* DMA1'0 */
+
+ /* DMA1 Descriptor1 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* TVE mode */
+ dma1_desc1->next_desc = (unsigned int)virt_to_phys(dma1_desc0);
+ dma1_desc1->frame_id = (unsigned int)0x0000da11; /* DMA1'1 */
+ }
+
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0); /* set Dma-chan1's Descripter Addrress */
+ dma_cache_wback_inv((unsigned int)(dma_desc_base), (DMA_DESC_NUM)*sizeof(struct jz4760_lcd_dma_desc));
+
+#if 0
+ /* Palette Descriptor */
+ if ( lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD )
+// dma0_desc_palette->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd);
+ dma0_desc_palette->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd1);
+ else
+ dma0_desc_palette->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc_palette->databuf = (unsigned int)virt_to_phys((void *)lcd_palette);
+ dma0_desc_palette->frame_id = (unsigned int)0xaaaaaaaa;
+ dma0_desc_palette->cmd = LCD_CMD_PAL | pal_size; /* Palette Descriptor */
+
+ /* Dummy Command Descriptor, cmd_num is 0 */
+ dma0_desc_cmd->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc_cmd->databuf = (unsigned int)virt_to_phys((void *)lcd_cmdbuf);
+ dma0_desc_cmd->frame_id = (unsigned int)0x0da0cad0; /* dma0's cmd0 */
+ dma0_desc_cmd->cmd = LCD_CMD_CMD | 3; /* dummy command */
+ dma0_desc_cmd->offsize = 0; /* dummy command */
+ dma0_desc_cmd->page_width = 0; /* dummy command */
+ dma0_desc_cmd->cmd_num = 3;
+
+//---------------------------------
+ dma0_desc_cmd1->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc_cmd1->databuf = 0;
+ dma0_desc_cmd1->frame_id = (unsigned int)0x0da0cad1; /* dma0's cmd0 */
+ dma0_desc_cmd1->cmd = LCD_CMD_CMD | 0; /* dummy command */
+ dma0_desc_cmd1->cmd_num = 0;
+ dma0_desc_cmd1->offsize = 0; /* dummy command */
+ dma0_desc_cmd1->page_width = 0; /* dummy command */
+//-----------------------------------
+ /* DMA0 Descriptor0 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) /* TVE mode */
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc1);
+ else{ /* Normal TFT LCD */
+ if (lcd_info->osd.fg0.bpp <= 8) /* load palette only once at setup?? */
+// dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette); //tft
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd); // smart lcd
+ else if ( lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD )
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd1);
+// dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd);
+ else
+ dma0_desc0->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ }
+
+ dma0_desc0->databuf = virt_to_phys((void *)lcd_frame0);
+ dma0_desc0->frame_id = (unsigned int)0x0000da00; /* DMA0'0 */
+
+ /* DMA0 Descriptor1 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* TVE mode */
+ if (lcd_info->osd.fg0.bpp <= 8) /* load palette only once at setup?? */
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc_palette);
+
+ else if ( lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD )
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc_cmd);
+ else
+ dma0_desc1->next_desc = (unsigned int)virt_to_phys(dma0_desc0);
+ dma0_desc1->frame_id = (unsigned int)0x0000da01; /* DMA0'1 */
+ }
+
+ /* DMA1 Descriptor0 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) /* TVE mode */
+ dma1_desc0->next_desc = (unsigned int)virt_to_phys(dma1_desc1);
+ else /* Normal TFT LCD */
+ dma1_desc0->next_desc = (unsigned int)virt_to_phys(dma1_desc0);
+
+ dma1_desc0->databuf = virt_to_phys((void *)lcd_frame1);
+ dma1_desc0->frame_id = (unsigned int)0x0000da10; /* DMA1'0 */
+
+ /* DMA1 Descriptor1 */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* TVE mode */
+ dma1_desc1->next_desc = (unsigned int)virt_to_phys(dma1_desc0);
+ dma1_desc1->frame_id = (unsigned int)0x0000da11; /* DMA1'1 */
+ }
+
+ if (lcd_info->osd.fg0.bpp <= 8) /* load palette only once at setup?? */
+ REG_LCD_DA0 = virt_to_phys(dma0_desc_palette);
+ else
+// REG_LCD_DA0 = virt_to_phys(dma0_desc_cmd); //smart lcd
+ REG_LCD_DA0 = virt_to_phys(dma0_desc0); //tft
+ REG_LCD_DA1 = virt_to_phys(dma1_desc0); /* set Dma-chan1's Descripter Addrress */
+ dma_cache_wback_inv((unsigned int)(dma_desc_base), (DMA_DESC_NUM)*sizeof(struct jz4760_lcd_dma_desc));
+#endif
+}
+
+static void jz4760fb_set_panel_mode( struct jz4760lcd_info * lcd_info )
+{
+ struct jz4760lcd_panel_t *panel = &lcd_info->panel;
+#ifdef CONFIG_JZ4760_VGA_DISPLAY
+ REG_TVE_CTRL |= TVE_CTRL_DAPD;
+ REG_TVE_CTRL &= ~( TVE_CTRL_DAPD1 | TVE_CTRL_DAPD2 | TVE_CTRL_DAPD3);
+#endif
+ /* set bpp */
+ lcd_info->panel.ctrl &= ~LCD_CTRL_BPP_MASK;
+ if ( lcd_info->osd.fg0.bpp == 1 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_1;
+ else if ( lcd_info->osd.fg0.bpp == 2 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_2;
+ else if ( lcd_info->osd.fg0.bpp == 4 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_4;
+ else if ( lcd_info->osd.fg0.bpp == 8 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_8;
+ else if ( lcd_info->osd.fg0.bpp == 15 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB555;
+ else if ( lcd_info->osd.fg0.bpp == 16 )
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_16 | LCD_CTRL_RGB565;
+ else if ( lcd_info->osd.fg0.bpp > 16 && lcd_info->osd.fg0.bpp < 32+1 ) {
+ lcd_info->osd.fg0.bpp = 32;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_18_24;
+ }
+ else {
+ printk("The BPP %d is not supported\n", lcd_info->osd.fg0.bpp);
+ lcd_info->osd.fg0.bpp = 32;
+ lcd_info->panel.ctrl |= LCD_CTRL_BPP_18_24;
+ }
+
+ lcd_info->panel.cfg |= LCD_CFG_NEWDES; /* use 8words descriptor always */
+
+ REG_LCD_CTRL = lcd_info->panel.ctrl; /* LCDC Controll Register */
+ REG_LCD_CFG = lcd_info->panel.cfg; /* LCDC Configure Register */
+ REG_SLCD_CFG = lcd_info->panel.slcd_cfg; /* Smart LCD Configure Register */
+
+ if ( lcd_info->panel.cfg & LCD_CFG_LCDPIN_SLCD ) /* enable Smart LCD DMA */
+ REG_SLCD_CTRL = SLCD_CTRL_DMA_EN;
+
+ switch ( lcd_info->panel.cfg & LCD_CFG_MODE_MASK ) {
+ case LCD_CFG_MODE_GENERIC_TFT:
+ case LCD_CFG_MODE_INTER_CCIR656:
+ case LCD_CFG_MODE_NONINTER_CCIR656:
+ case LCD_CFG_MODE_SLCD:
+ default: /* only support TFT16 TFT32, not support STN and Special TFT by now(10-06-2008)*/
+ REG_LCD_VAT = (((panel->blw + panel->w + panel->elw + panel->hsw)) << 16) | (panel->vsw + panel->bfw + panel->h + panel->efw);
+ REG_LCD_DAH = ((panel->hsw + panel->blw) << 16) | (panel->hsw + panel->blw + panel->w);
+ REG_LCD_DAV = ((panel->vsw + panel->bfw) << 16) | (panel->vsw + panel->bfw + panel->h);
+ REG_LCD_HSYNC = (0 << 16) | panel->hsw;
+ REG_LCD_VSYNC = (0 << 16) | panel->vsw;
+ break;
+ }
+}
+
+
+static void jz4760fb_set_osd_mode( struct jz4760lcd_info * lcd_info )
+{
+ D("%s, %d\n", __FILE__, __LINE__ );
+ lcd_info->osd.osd_ctrl &= ~(LCD_OSDCTRL_OSDBPP_MASK);
+ if ( lcd_info->osd.fg1.bpp == 15 )
+ lcd_info->osd.osd_ctrl |= LCD_OSDCTRL_OSDBPP_15_16|LCD_OSDCTRL_RGB555;
+ else if ( lcd_info->osd.fg1.bpp == 16 )
+ lcd_info->osd.osd_ctrl |= LCD_OSDCTRL_OSDBPP_15_16|LCD_OSDCTRL_RGB565;
+ else {
+ lcd_info->osd.fg1.bpp = 32;
+ lcd_info->osd.osd_ctrl |= LCD_OSDCTRL_OSDBPP_18_24;
+ }
+
+ REG_LCD_OSDC = lcd_info->osd.osd_cfg; /* F0, F1, alpha, */
+
+ REG_LCD_OSDCTRL = lcd_info->osd.osd_ctrl; /* IPUEN, bpp */
+ REG_LCD_RGBC = lcd_info->osd.rgb_ctrl;
+ REG_LCD_BGC = lcd_info->osd.bgcolor;
+ REG_LCD_KEY0 = lcd_info->osd.colorkey0;
+ REG_LCD_KEY1 = lcd_info->osd.colorkey1;
+ REG_LCD_ALPHA = lcd_info->osd.alpha;
+ REG_LCD_IPUR = lcd_info->osd.ipu_restart;
+}
+
+static void jz4760fb_foreground_resize( struct jz4760lcd_info * lcd_info )
+{
+ int fg0_line_size, fg0_frm_size, fg1_line_size, fg1_frm_size;
+ /*
+ * NOTE:
+ * Foreground change sequence:
+ * 1. Change Position Registers -> LCD_OSDCTL.Change;
+ * 2. LCD_OSDCTRL.Change -> descripter->Size
+ * Foreground, only one of the following can be change at one time:
+ * 1. F0 size;
+ * 2. F0 position
+ * 3. F1 size
+ * 4. F1 position
+ */
+
+ /*
+ * The rules of f0, f1's position:
+ * f0.x + f0.w <= panel.w;
+ * f0.y + f0.h <= panel.h;
+ *
+ * When output is LCD panel, fg.y and fg.h can be odd number or even number.
+ * When output is TVE, as the TVE has odd frame and even frame,
+ * to simplified operation, fg.y and fg.h should be even number always.
+ *
+ */
+
+ /* Foreground 0 */
+ if ( lcd_info->osd.fg0.x >= lcd_info->panel.w )
+ lcd_info->osd.fg0.x = lcd_info->panel.w;
+ if ( lcd_info->osd.fg0.y >= lcd_info->panel.h )
+ lcd_info->osd.fg0.y = lcd_info->panel.h;
+ if ( lcd_info->osd.fg0.x + lcd_info->osd.fg0.w > lcd_info->panel.w )
+ lcd_info->osd.fg0.w = lcd_info->panel.w - lcd_info->osd.fg0.x;
+ if ( lcd_info->osd.fg0.y + lcd_info->osd.fg0.h > lcd_info->panel.h )
+ lcd_info->osd.fg0.h = lcd_info->panel.h - lcd_info->osd.fg0.y;
+
+#if 0
+ /* Foreground 1 */
+ /* Case TVE ??? TVE 720x573 or 720x480*/
+ if ( lcd_info->osd.fg1.x >= lcd_info->panel.w )
+ lcd_info->osd.fg1.x = lcd_info->panel.w;
+ if ( lcd_info->osd.fg1.y >= lcd_info->panel.h )
+ lcd_info->osd.fg1.y = lcd_info->panel.h;
+ if ( lcd_info->osd.fg1.x + lcd_info->osd.fg1.w > lcd_info->panel.w )
+ lcd_info->osd.fg1.w = lcd_info->panel.w - lcd_info->osd.fg1.x;
+ if ( lcd_info->osd.fg1.y + lcd_info->osd.fg1.h > lcd_info->panel.h )
+ lcd_info->osd.fg1.h = lcd_info->panel.h - lcd_info->osd.fg1.y;
+#endif
+// fg0_line_size = lcd_info->osd.fg0.w*((lcd_info->osd.fg0.bpp+7)/8);
+ fg0_line_size = (lcd_info->osd.fg0.w*(lcd_info->osd.fg0.bpp)/8);
+ fg0_line_size = ((fg0_line_size+3)>>2)<<2; /* word aligned */
+ fg0_frm_size = fg0_line_size * lcd_info->osd.fg0.h;
+
+ fg1_line_size = lcd_info->osd.fg1.w*((lcd_info->osd.fg1.bpp+7)/8);
+ fg1_line_size = ((fg1_line_size+3)>>2)<<2; /* word aligned */
+ fg1_frm_size = fg1_line_size * lcd_info->osd.fg1.h;
+
+ if ( lcd_info->osd.fg_change ) {
+ if ( lcd_info->osd.fg_change & FG0_CHANGE_POSITION ) { /* F1 change position */
+ REG_LCD_XYP0 = lcd_info->osd.fg0.y << 16 | lcd_info->osd.fg0.x;
+ }
+ if ( lcd_info->osd.fg_change & FG1_CHANGE_POSITION ) { /* F1 change position */
+ REG_LCD_XYP1 = lcd_info->osd.fg1.y << 16 | lcd_info->osd.fg1.x;
+ }
+
+ /* set change */
+ if ( !(lcd_info->osd.osd_ctrl & LCD_OSDCTRL_IPU) &&
+ (lcd_info->osd.fg_change != FG_CHANGE_ALL) )
+ REG_LCD_OSDCTRL |= LCD_OSDCTRL_CHANGES;
+
+ /* wait change ready??? */
+// while ( REG_LCD_OSDS & LCD_OSDS_READY ) /* fix in the future, Wolfgang, 06-20-2008 */
+ D("wait LCD_OSDS_READY\n");
+
+ if ( lcd_info->osd.fg_change & FG0_CHANGE_SIZE ) { /* change FG0 size */
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* output to TV */
+ dma0_desc0->cmd = dma0_desc1->cmd = (fg0_frm_size/4)/2;
+ dma0_desc0->offsize = dma0_desc1->offsize
+ = fg0_line_size/4;
+ dma0_desc0->page_width = dma0_desc1->page_width
+ = fg0_line_size/4;
+ dma0_desc1->databuf = virt_to_phys((void *)(lcd_frame0 + fg0_line_size));
+ REG_LCD_DA0 = virt_to_phys(dma0_desc0); //tft
+ }
+ else {
+ dma0_desc0->cmd = dma0_desc1->cmd = fg0_frm_size/4;
+ dma0_desc0->offsize = dma0_desc1->offsize =0;
+ dma0_desc0->page_width = dma0_desc1->page_width = 0;
+ }
+
+ dma0_desc0->desc_size = dma0_desc1->desc_size
+ = lcd_info->osd.fg0.h << 16 | lcd_info->osd.fg0.w;
+ REG_LCD_SIZE0 = (lcd_info->osd.fg0.h<<16)|lcd_info->osd.fg0.w;
+
+ }
+
+ if ( lcd_info->osd.fg_change & FG1_CHANGE_SIZE ) { /* change FG1 size*/
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* output to TV */
+ dma1_desc0->cmd = dma1_desc1->cmd = (fg1_frm_size/4)/2;
+ dma1_desc0->offsize = dma1_desc1->offsize = fg1_line_size/4;
+ dma1_desc0->page_width = dma1_desc1->page_width = fg1_line_size/4;
+ dma1_desc1->databuf = virt_to_phys((void *)(lcd_frame1 + fg1_line_size));
+ REG_LCD_DA1 = virt_to_phys(dma0_desc1); //tft
+
+ }
+ else {
+ dma1_desc0->cmd = dma1_desc1->cmd = fg1_frm_size/4;
+ dma1_desc0->offsize = dma1_desc1->offsize = 0;
+ dma1_desc0->page_width = dma1_desc1->page_width = 0;
+ }
+
+ dma1_desc0->desc_size = dma1_desc1->desc_size
+ = lcd_info->osd.fg1.h << 16 | lcd_info->osd.fg1.w;
+ REG_LCD_SIZE1 = lcd_info->osd.fg1.h << 16|lcd_info->osd.fg1.w;
+ }
+
+ dma_cache_wback((unsigned int)(dma_desc_base), (DMA_DESC_NUM)*sizeof(struct jz4760_lcd_dma_desc));
+ lcd_info->osd.fg_change = FG_NOCHANGE; /* clear change flag */
+ }
+}
+
+static void jz4760fb_change_clock( struct jz4760lcd_info * lcd_info )
+{
+
+#if defined(CONFIG_FPGA)
+ REG_LCD_REV = 0x00000004;
+ printk("Fuwa test, pixclk divide REG_LCD_REV=0x%08x\n", REG_LCD_REV);
+ printk("Fuwa test, pixclk %d\n", JZ_EXTAL/(((REG_LCD_REV&0xFF)+1)*2));
+#else
+ unsigned int val = 0;
+ unsigned int pclk;
+ /* Timing setting */
+ __cpm_stop_lcd();
+
+ val = lcd_info->panel.fclk; /* frame clk */
+
+ if ( (lcd_info->panel.cfg & LCD_CFG_MODE_MASK) != LCD_CFG_MODE_SERIAL_TFT) {
+ pclk = val * (lcd_info->panel.w + lcd_info->panel.hsw + lcd_info->panel.elw + lcd_info->panel.blw) * (lcd_info->panel.h + lcd_info->panel.vsw + lcd_info->panel.efw + lcd_info->panel.bfw); /* Pixclk */
+ }
+ else {
+ /* serial mode: Hsync period = 3*Width_Pixel */
+ pclk = val * (lcd_info->panel.w*3 + lcd_info->panel.hsw + lcd_info->panel.elw + lcd_info->panel.blw) * (lcd_info->panel.h + lcd_info->panel.vsw + lcd_info->panel.efw + lcd_info->panel.bfw); /* Pixclk */
+ }
+
+ /********* In TVE mode PCLK = 27MHz ***********/
+ if ( lcd_info->panel.cfg & LCD_CFG_TVEN ) { /* LCDC output to TVE */
+ REG_CPM_LPCDR |= LPCDR_LTCS;
+ pclk = 27000000;
+ val = __cpm_get_pllout2() / pclk; /* pclk */
+ val--;
+ __cpm_set_pixdiv(val);
+
+
+ D("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
+#if 0
+#if defined(CONFIG_SOC_JZ4760) /* Jz4760D don't use LCLK */
+ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
+
+ val =(__cpm_get_pllout()) / val;
+ if ( val > 0x1f ) {
+ printk("lcd clock divide is too large, set it to 0x1f\n");
+ val = 0x1f;
+ }
+ __cpm_set_ldiv( val );
+#endif
+#endif
+ __cpm_select_pixclk_tve();
+
+ REG_CPM_CPCCR |= CPCCR_CE ; /* update divide */
+ }
+ else { /* LCDC output to LCD panel */
+ val = __cpm_get_pllout2() / pclk; /* pclk */
+ val--;
+ D("ratio: val = %d\n", val);
+ if ( val > 0x7ff ) {
+ printk("pixel clock divid is too large, set it to 0x7ff\n");
+ val = 0x7ff;
+ }
+
+ __cpm_set_pixdiv(val);
+ D("REG_CPM_LPCDR = 0x%08x\n", REG_CPM_LPCDR);
+#if 0
+#if defined(CONFIG_SOC_JZ4760) /* Jz4760D don't use LCLK */
+ val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
+ val =__cpm_get_pllout2() / val;
+ if ( val > 0x1f ) {
+ printk("lcd clock divide is too large, set it to 0x1f\n");
+ val = 0x1f;
+ }
+ __cpm_set_ldiv( val );
+#endif
+#endif
+ REG_CPM_CPCCR |= CPCCR_CE ; /* update divide */
+
+ }
+
+ D("REG_CPM_LPCDR=0x%08x\n", REG_CPM_LPCDR);
+ D("REG_CPM_CPCCR=0x%08x\n", REG_CPM_CPCCR);
+
+ jz_clocks.pixclk = __cpm_get_pixclk();
+ printk("LCDC: PixClock:%d\n", jz_clocks.pixclk);
+#if 0
+#if defined(CONFIG_SOC_JZ4760) /* Jz4760D don't use LCLK */
+ jz_clocks.lcdclk = __cpm_get_lcdclk();
+ printk("LCDC: LcdClock:%d\n", jz_clocks.lcdclk);
+#endif
+#endif
+ __cpm_start_lcd();
+ udelay(1000);
+ /*
+ * set lcd device clock and lcd pixel clock.
+ * what about TVE mode???
+ *
+ */
+#endif
+
+}
+
+/*
+ * jz4760fb_set_mode(), set osd configure, resize foreground
+ *
+ */
+static void jz4760fb_set_mode( struct jz4760lcd_info * lcd_info )
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ jz4760fb_set_osd_mode(lcd_info);
+ jz4760fb_foreground_resize(lcd_info);
+ jz4760fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+}
+
+/*
+ * jz4760fb_deep_set_mode,
+ *
+ */
+static void jz4760fb_deep_set_mode( struct jz4760lcd_info * lcd_info )
+{
+ /* configurate sequence:
+ * 1. disable lcdc.
+ * 2. init frame descriptor.
+ * 3. set panel mode
+ * 4. set osd mode
+ * 5. start lcd clock in CPM
+ * 6. enable lcdc.
+ */
+
+ __lcd_clr_ena(); /* Quick Disable */
+ lcd_info->osd.fg_change = FG_CHANGE_ALL; /* change FG0, FG1 size, postion??? */
+ jz4760fb_descriptor_init(lcd_info);
+ jz4760fb_set_panel_mode(lcd_info);
+ jz4760fb_set_mode(lcd_info);
+ jz4760fb_change_clock(lcd_info);
+ __lcd_set_ena(); /* enable lcdc */
+}
+
+
+static irqreturn_t jz4760fb_interrupt_handler(int irq, void *dev_id)
+{
+ unsigned int state;
+ static int irqcnt=0;
+
+ state = REG_LCD_STATE;
+ D("In the lcd interrupt handler, state=0x%x\n", state);
+
+ if (state & LCD_STATE_EOF) /* End of frame */
+ REG_LCD_STATE = state & ~LCD_STATE_EOF;
+
+ if (state & LCD_STATE_IFU0) {
+ printk("%s, InFiFo0 underrun\n", __FUNCTION__);
+ REG_LCD_STATE = state & ~LCD_STATE_IFU0;
+ }
+
+ if (state & LCD_STATE_IFU1) {
+ printk("%s, InFiFo1 underrun\n", __FUNCTION__);
+ REG_LCD_STATE = state & ~LCD_STATE_IFU1;
+ }
+
+ if (state & LCD_STATE_OFU) { /* Out fifo underrun */
+ REG_LCD_STATE = state & ~LCD_STATE_OFU;
+ if ( irqcnt++ > 100 ) {
+ __lcd_disable_ofu_intr();
+ printk("disable Out FiFo underrun irq.\n");
+ }
+ printk("%s, Out FiFo underrun.\n", __FUNCTION__);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * Suspend the LCDC.
+ */
+static int jz4760_fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ printk("%s(): called.\n", __func__);
+
+ screen_off();
+ ctrl_disable();
+
+ __cpm_stop_lcd();
+
+ return 0;
+}
+
+/*
+ * Resume the LCDC.
+ */
+static int jz4760_fb_resume(struct platform_device *pdev)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ printk("%s(): called.\n", __func__);
+
+ __cpm_start_lcd();
+
+ __gpio_set_pin(GPIO_DISP_OFF_N);
+ __lcd_special_on();
+ __lcd_set_ena();
+ mdelay(200);
+
+ __lcd_set_backlight_level(cfb->backlight_level);
+
+ return 0;
+}
+
+#else
+#define jzfb_suspend NULL
+#define jzfb_resume NULL
+#endif /* CONFIG_PM */
+
+/* The following routine is only for test */
+
+#if JZ_FB_DEBUG
+static void test_gpio(int gpio_num, int delay) {
+ __gpio_as_output(gpio_num);
+ while(1) {
+ __gpio_set_pin(gpio_num);
+ udelay(delay);
+ __gpio_clear_pin(gpio_num);
+ udelay(delay);
+ }
+}
+static void display_v_color_bar(int w, int h, int bpp) {
+ int i, j, wpl, data = 0;
+ int *ptr;
+ ptr = (int *)lcd_frame0;
+// ptr = (int *)lcd_frame1;
+ wpl = w*bpp/32;
+ if (!(bpp > 8))
+ switch(bpp){
+ case 1:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ *ptr++ = 0x00ff00ff;
+ }
+ break;
+ case 2:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ data = (i%4)*0x55555555;
+ *ptr++ = data;
+ }
+ break;
+ case 4:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ data = (i%16)*0x11111111;
+ *ptr++ = data;
+ }
+ break;
+ case 8:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i+=2) {
+ data = (i%(256))*0x01010101;
+ *ptr++ = data;
+ *ptr++ = data;
+ }
+ break;
+ }
+ else {
+ switch(bpp) {
+ case 16:
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/4)%8==0)
+ *ptr++ = 0xffffffff;
+ else if ((i/4)%8==1)
+ *ptr++ = 0xf800f800;
+ else if ((i/4)%8==2)
+ *ptr++ = 0xffe0ffe0;
+ else if ((i/4)%8==3)
+ *ptr++ = 0x07e007e0;
+ else if ((i/4)%8==4)
+ *ptr++ = 0x07ff07ff;
+ else if ((i/4)%8==5)
+ *ptr++ = 0x001f001f;
+ else if ((i/4)%8==6)
+ *ptr++ = 0xf81ff81f;
+ else if ((i/4)%8==7)
+ *ptr++ = 0x00000000;
+ }
+ break;
+ case 18:
+ case 24:
+ case 32:
+ default:
+#if 1
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/8)%8==7)
+ *ptr++ = 0xffffff;
+ else if ((i/8)%8==1)
+ *ptr++ = 0xff0000;
+ else if ((i/8)%8==2)
+ *ptr++ = 0xffff00;
+ else if ((i/8)%8==3)
+ *ptr++ = 0x00ff00;
+ else if ((i/8)%8==4)
+ *ptr++ = 0x00ffff;
+ else if ((i/8)%8==5)
+ *ptr++ = 0x0000ff;
+ else if ((i/8)%8==6)
+ *ptr++ = 0xff00ff;
+ else if ((i/8)%8==0)
+ *ptr++ = 0x000000;
+ }
+#else
+ for (j = 0;j < h; j++)
+ for (i = 0;i < wpl; i++) {
+ if((i/8)%8==7)
+ *ptr++ = 0x00ff0000;
+ else if ((i/8)%8==1)
+ *ptr++ = 0xffff0000;
+ else if ((i/8)%8==2)
+ *ptr++ = 0x20ff0000;
+ else if ((i/8)%8==3)
+ *ptr++ = 0x40ff0000;
+ else if ((i/8)%8==4)
+ *ptr++ = 0x60ff0000;
+ else if ((i/8)%8==5)
+ *ptr++ = 0x80ff0000;
+ else if ((i/8)%8==6)
+ *ptr++ = 0xa0ff0000;
+ else if ((i/8)%8==0)
+ *ptr++ = 0xc0ff0000;
+ }
+#endif
+ break;
+ }
+ }
+}
+static void display_h_color_bar(int w, int h, int bpp) {
+ int i, data = 0;
+ int *ptr;
+ int wpl; //word_per_line
+ ptr = (int *)lcd_frame0;
+// ptr = (int *)lcd_frame1;
+ wpl = w*bpp/32;
+ if (!(bpp > 8))
+ for (i = 0;i < wpl*h;i++) {
+ switch(bpp){
+ case 1:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%2)*0xffffffff;
+ *ptr++ = data;
+ break;
+ case 2:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%4)*0x55555555;
+ *ptr++ = data;
+ break;
+ case 4:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%16)*0x11111111;
+ *ptr++ = data;
+ break;
+ case 8:
+ if(i%(wpl*8)==0)
+ data = ((i/(wpl*8))%256)*0x01010101;
+ *ptr++ = data;
+ break;
+ }
+ }
+ else {
+
+ switch(bpp) {
+ case 15:
+ case 16:
+ for (i = 0;i < wpl*h;i++) {
+ if (((i/(wpl*8)) % 8) == 0)
+ *ptr++ = 0xffffffff;
+ else if (((i/(wpl*8)) % 8) == 1)
+ *ptr++ = 0xf800f800;
+ else if (((i/(wpl*8)) % 8) == 2)
+ *ptr++ = 0xffe0ffe0;
+ else if (((i/(wpl*8)) % 8) == 3)
+ *ptr++ = 0x07e007e0;
+ else if (((i/(wpl*8)) % 8) == 4)
+ *ptr++ = 0x07ff07ff;
+ else if (((i/(wpl*8)) % 8) == 5)
+ *ptr++ = 0x001f001f;
+ else if (((i/(wpl*8)) % 8) == 6)
+ *ptr++ = 0xf81ff81f;
+ else if (((i/(wpl*8)) % 8) == 7)
+ *ptr++ = 0x00000000;
+ }
+ break;
+ case 18:
+ case 24:
+ case 32:
+ default:
+ for (i = 0;i < wpl*h;i++) {
+ if (((i/(wpl*8)) % 8) == 7)
+ *ptr++ = 0xffffff;
+ else if (((i/(wpl*8)) % 8) == 2)
+ *ptr++ = 0xff0000;
+ else if (((i/(wpl*8)) % 8) == 4)
+ *ptr++ = 0xffff00;
+ else if (((i/(wpl*8)) % 8) == 6)
+ *ptr++ = 0x00ff00;
+ else if (((i/(wpl*8)) % 8) == 1)
+ *ptr++ = 0x00ffff;
+ else if (((i/(wpl*8)) % 8) == 3)
+ *ptr++ = 0x0000ff;
+ else if (((i/(wpl*8)) % 8) == 5)
+ *ptr++ = 0x000000;
+ else if (((i/(wpl*8)) % 8) == 0)
+ *ptr++ = 0xff00ff;
+ }
+ break;
+ }
+
+ }
+
+}
+#endif
+
+/* Backlight Control Interface via sysfs
+ *
+ * LCDC:
+ * Enabling LCDC when LCD backlight is off will only affects cfb->display.
+ *
+ * Backlight:
+ * Changing the value of LCD backlight when LCDC is off will only affect the cfb->backlight_level.
+ *
+ * - River.
+ */
+static int screen_off(void)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ __lcd_close_backlight();
+ __lcd_display_off();
+
+#ifdef HAVE_LCD_PWM_CONTROL
+ if (cfb->b_lcd_pwm) {
+ __lcd_pwm_stop();
+ cfb->b_lcd_pwm = 0;
+ }
+#endif
+
+ cfb->b_lcd_display = 0;
+
+ return 0;
+}
+
+static int screen_on(void)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ __lcd_display_on();
+
+ /* Really restore LCD backlight when LCD backlight is turned on. */
+ if (cfb->backlight_level) {
+#ifdef HAVE_LCD_PWM_CONTROL
+ if (!cfb->b_lcd_pwm) {
+ __lcd_pwm_start();
+ cfb->b_lcd_pwm = 1;
+ }
+#endif
+ __lcd_set_backlight_level(cfb->backlight_level);
+ }
+
+ cfb->b_lcd_display = 1;
+
+ return 0;
+}
+
+static int jz4760fb_set_backlight_level(int n)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ if (n) {
+ if (n > LCD_MAX_BACKLIGHT)
+ n = LCD_MAX_BACKLIGHT;
+
+ if (n < LCD_MIN_BACKLIGHT)
+ n = LCD_MIN_BACKLIGHT;
+
+ /* Really change the value of backlight when LCDC is enabled. */
+ if (cfb->b_lcd_display) {
+#ifdef HAVE_LCD_PWM_CONTROL
+ if (!cfb->b_lcd_pwm) {
+ __lcd_pwm_start();
+ cfb->b_lcd_pwm = 1;
+ }
+#endif
+ __lcd_set_backlight_level(n);
+ }
+ }else{
+ /* Turn off LCD backlight. */
+ __lcd_close_backlight();
+
+#ifdef HAVE_LCD_PWM_CONTROL
+ if (cfb->b_lcd_pwm) {
+ __lcd_pwm_stop();
+ cfb->b_lcd_pwm = 0;
+ }
+#endif
+ }
+
+ cfb->backlight_level = n;
+
+ return 0;
+}
+
+static ssize_t show_bl_level(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_cfb_info *cfb = jz4760fb_info;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", cfb->backlight_level);
+}
+
+static ssize_t store_bl_level(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int n;
+ char *ep;
+
+ n = simple_strtoul(buf, &ep, 0);
+ if (*ep && *ep != '\n')
+ return -EINVAL;
+
+ jz4760fb_set_backlight_level(n);
+
+ return count;
+}
+
+static struct device_attribute device_attrs[] = {
+ __ATTR(backlight_level, S_IRUGO | S_IWUSR, show_bl_level, store_bl_level),
+};
+
+static int jz4760fb_device_attr_register(struct fb_info *fb_info)
+{
+ int error = 0;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
+ error = device_create_file(fb_info->dev, &device_attrs[i]);
+
+ if (error)
+ break;
+ }
+
+ if (error) {
+ while (--i >= 0)
+ device_remove_file(fb_info->dev, &device_attrs[i]);
+ }
+
+ return 0;
+}
+
+static int jz4760fb_device_attr_unregister(struct fb_info *fb_info)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
+ device_remove_file(fb_info->dev, &device_attrs[i]);
+
+ return 0;
+}
+/* End */
+
+static void gpio_init(void)
+{
+ __lcd_display_pin_init();
+
+ /* gpio init __gpio_as_lcd */
+ if (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_TFT_16BIT)
+ __gpio_as_lcd_16bit();
+ else if (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_TFT_24BIT)
+ __gpio_as_lcd_24bit();
+ else
+ __gpio_as_lcd_18bit();
+
+ /* In special mode, we only need init special pin,
+ * as general lcd pin has init in uboot */
+#if defined(CONFIG_SOC_JZ4760)
+ switch (jz4760_lcd_info->panel.cfg & LCD_CFG_MODE_MASK) {
+ case LCD_CFG_MODE_SPECIAL_TFT_1:
+ case LCD_CFG_MODE_SPECIAL_TFT_2:
+ case LCD_CFG_MODE_SPECIAL_TFT_3:
+ __gpio_as_lcd_special();
+ break;
+ default:
+ ;
+ }
+#endif
+
+ return;
+}
+
+static void set_bpp_to_ctrl_bpp(void)
+{
+ switch (jz4760_lcd_info->osd.fg0.bpp) {
+ case 15:
+ case 16:
+ break;
+
+ case 17 ... 32:
+ jz4760_lcd_info->osd.fg0.bpp = 32;
+ break;
+
+ default:
+ E("FG0: BPP (%d) not support, Set BPP 32.\n",
+ jz4760_lcd_info->osd.fg0.bpp);
+
+ jz4760_lcd_info->osd.fg0.bpp = 32;
+ break;
+ }
+
+ switch (jz4760_lcd_info->osd.fg1.bpp) {
+ case 15:
+ case 16:
+ break;
+
+ case 17 ... 32:
+ jz4760_lcd_info->osd.fg1.bpp = 32;
+ break;
+
+ default:
+ E("FG1: BPP (%d) not support, Set BPP 32.\n",
+ jz4760_lcd_info->osd.fg1.bpp);
+
+ jz4760_lcd_info->osd.fg1.bpp = 32;
+ break;
+ }
+
+ return;
+}
+
+static void slcd_init(void)
+{
+ /* Configure SLCD module for setting smart lcd control registers */
+#if defined(CONFIG_FB_JZ4760_SLCD)
+ __lcd_as_smart_lcd();
+ __slcd_disable_dma();
+ __init_slcd_bus(); /* Note: modify this depend on you lcd */
+
+#endif
+ return;
+}
+
+static int __devinit jz4760_fb_probe(struct platform_device *dev)
+{
+ struct lcd_cfb_info *cfb;
+
+ int rv = 0;
+
+ cfb = jz4760fb_alloc_fb_info();
+ if (!cfb)
+ goto failed;
+
+ screen_off();
+ ctrl_disable();
+
+ gpio_init();
+ slcd_init();
+
+ set_bpp_to_ctrl_bpp();
+
+ /* init clk */
+ jz4760fb_change_clock(jz4760_lcd_info);
+
+ rv = jz4760fb_map_smem(cfb);
+ if (rv)
+ goto failed;
+
+ jz4760fb_deep_set_mode(jz4760_lcd_info);
+
+ rv = register_framebuffer(&cfb->fb);
+ if (rv < 0) {
+ D("Failed to register framebuffer device.");
+ goto failed;
+ }
+
+ printk("fb%d: %s frame buffer device, using %dK of video memory\n",
+ cfb->fb.node, cfb->fb.fix.id, cfb->fb.fix.smem_len>>10);
+
+ jz4760fb_device_attr_register(&cfb->fb);
+
+ if (request_irq(IRQ_LCD, jz4760fb_interrupt_handler, IRQF_DISABLED,
+ "lcd", 0)) {
+ D("Faield to request LCD IRQ.\n");
+ rv = -EBUSY;
+ goto failed;
+ }
+
+ ctrl_enable();
+ screen_on();
+
+#if JZ_FB_DEBUG
+ display_h_color_bar(jz4760_lcd_info->osd.fg0.w, jz4760_lcd_info->osd.fg0.h, jz4760_lcd_info->osd.fg0.bpp);
+
+ print_lcdc_registers();
+#endif
+
+ return 0;
+
+failed:
+ jz4760fb_unmap_smem(cfb);
+ jz4760fb_free_fb_info(cfb);
+
+ return rv;
+}
+
+static int __devexit jz4760_fb_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver jz4760_fb_driver = {
+ .probe = jz4760_fb_probe,
+ .remove = jz4760_fb_remove,
+ .suspend = jz4760_fb_suspend,
+ .resume = jz4760_fb_resume,
+ .driver = {
+ .name = "jz-lcd",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init jz4760_fb_init(void)
+{
+ return platform_driver_register(&jz4760_fb_driver);
+}
+
+static void __exit jz4760_fb_cleanup(void)
+{
+ platform_driver_unregister(&jz4760_fb_driver);
+}
+
+module_init(jz4760_fb_init);
+module_exit(jz4760_fb_cleanup);
diff --git a/drivers/video/jz4760_lcd.h b/drivers/video/jz4760_lcd.h
new file mode 100644
index 00000000000..f95e1345e32
--- /dev/null
+++ b/drivers/video/jz4760_lcd.h
@@ -0,0 +1,747 @@
+/*
+ * linux/drivers/video/jz4760_lcd.h -- Ingenic Jz4760 On-Chip LCD frame buffer device
+ *
+ * Copyright (C) 2005-2008, Ingenic Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __JZ4760_LCD_H__
+#define __JZ4760_LCD_H__
+
+//#include <asm/io.h>
+
+
+#define NR_PALETTE 256
+#define PALETTE_SIZE (NR_PALETTE*2)
+
+/* use new descriptor(8 words) */
+struct jz4760_lcd_dma_desc {
+ unsigned int next_desc; /* LCDDAx */
+ unsigned int databuf; /* LCDSAx */
+ unsigned int frame_id; /* LCDFIDx */
+ unsigned int cmd; /* LCDCMDx */
+ unsigned int offsize; /* Stride Offsize(in word) */
+ unsigned int page_width; /* Stride Pagewidth(in word) */
+ unsigned int cmd_num; /* Command Number(for SLCD) */
+ unsigned int desc_size; /* Foreground Size */
+};
+
+struct jz4760lcd_panel_t {
+ unsigned int cfg; /* panel mode and pin usage etc. */
+ unsigned int slcd_cfg; /* Smart lcd configurations */
+ unsigned int ctrl; /* lcd controll register */
+ unsigned int w; /* Panel Width(in pixel) */
+ unsigned int h; /* Panel Height(in line) */
+ unsigned int fclk; /* frame clk */
+ unsigned int hsw; /* hsync width, in pclk */
+ unsigned int vsw; /* vsync width, in line count */
+ unsigned int elw; /* end of line, in pclk */
+ unsigned int blw; /* begin of line, in pclk */
+ unsigned int efw; /* end of frame, in line count */
+ unsigned int bfw; /* begin of frame, in line count */
+};
+
+
+struct jz4760lcd_fg_t {
+ int bpp; /* foreground bpp */
+ int x; /* foreground start position x */
+ int y; /* foreground start position y */
+ int w; /* foreground width */
+ int h; /* foreground height */
+};
+
+struct jz4760lcd_osd_t {
+ unsigned int osd_cfg; /* OSDEN, ALHPAEN, F0EN, F1EN, etc */
+ unsigned int osd_ctrl; /* IPUEN, OSDBPP, etc */
+ unsigned int rgb_ctrl; /* RGB Dummy, RGB sequence, RGB to YUV */
+ unsigned int bgcolor; /* background color(RGB888) */
+ unsigned int colorkey0; /* foreground0's Colorkey enable, Colorkey value */
+ unsigned int colorkey1; /* foreground1's Colorkey enable, Colorkey value */
+ unsigned int alpha; /* ALPHAEN, alpha value */
+ unsigned int ipu_restart; /* IPU Restart enable, ipu restart interval time */
+
+#define FG_NOCHANGE 0x0000
+#define FG0_CHANGE_SIZE 0x0001
+#define FG0_CHANGE_POSITION 0x0002
+#define FG1_CHANGE_SIZE 0x0010
+#define FG1_CHANGE_POSITION 0x0020
+#define FG_CHANGE_ALL ( FG0_CHANGE_SIZE | FG0_CHANGE_POSITION | \
+ FG1_CHANGE_SIZE | FG1_CHANGE_POSITION )
+ int fg_change;
+ struct jz4760lcd_fg_t fg0; /* foreground 0 */
+ struct jz4760lcd_fg_t fg1; /* foreground 1 */
+};
+
+struct jz4760lcd_info {
+ struct jz4760lcd_panel_t panel;
+ struct jz4760lcd_osd_t osd;
+};
+
+
+/* Jz LCDFB supported I/O controls. */
+#define FBIOSETBACKLIGHT 0x4688 /* set back light level */
+#define FBIODISPON 0x4689 /* display on */
+#define FBIODISPOFF 0x468a /* display off */
+#define FBIORESET 0x468b /* lcd reset */
+#define FBIOPRINT_REG 0x468c /* print lcd registers(debug) */
+#define FBIOROTATE 0x46a0 /* rotated fb */
+#define FBIOGETBUFADDRS 0x46a1 /* get buffers addresses */
+#define FBIO_GET_MODE 0x46a2 /* get lcd info */
+#define FBIO_SET_MODE 0x46a3 /* set osd mode */
+#define FBIO_DEEP_SET_MODE 0x46a4 /* set panel and osd mode */
+#define FBIO_MODE_SWITCH 0x46a5 /* switch mode between LCD and TVE */
+#define FBIO_GET_TVE_MODE 0x46a6 /* get tve info */
+#define FBIO_SET_TVE_MODE 0x46a7 /* set tve mode */
+
+/*
+ * LCD panel specific definition
+ */
+/* AUO */
+#if defined(CONFIG_JZ4760_LCD_AUO_A043FL01V2)
+#if defined(CONFIG_JZ4760_LEPUS) /* board pavo */
+ #define SPEN (32*1+29) /*LCD_CS*/
+ #define SPCK (32*1+28) /*LCD_SCL*/
+ #define SPDA (32*1+21) /*LCD_SDA*/
+ #define LCD_RET (32*5+6) /*LCD_DISP_N use for lcd reset*/
+#else
+#error "driver/video/Jzlcd.h, please define SPI pins on your board."
+#endif
+
+#define __spi_write_reg(reg, val) \
+ do { \
+ unsigned char no; \
+ unsigned short value; \
+ unsigned char a=0; \
+ unsigned char b=0; \
+ __gpio_as_output(SPEN); /* use SPDA */ \
+ __gpio_as_output(SPCK); /* use SPCK */ \
+ __gpio_as_output(SPDA); /* use SPDA */ \
+ a=reg; \
+ b=val; \
+ __gpio_set_pin(SPEN); \
+ __gpio_clear_pin(SPCK); \
+ udelay(50); \
+ __gpio_clear_pin(SPDA); \
+ __gpio_clear_pin(SPEN); \
+ udelay(50); \
+ value=((a<<8)|(b&0xFF)); \
+ for(no=0;no<16;no++) \
+ { \
+ if((value&0x8000)==0x8000){ \
+ __gpio_set_pin(SPDA);} \
+ else{ \
+ __gpio_clear_pin(SPDA); } \
+ udelay(50); \
+ __gpio_set_pin(SPCK); \
+ value=(value<<1); \
+ udelay(50); \
+ __gpio_clear_pin(SPCK); \
+ } \
+ __gpio_set_pin(SPEN); \
+ udelay(400); \
+ } while (0)
+#define __spi_read_reg(reg,val) \
+ do{ \
+ unsigned char no; \
+ unsigned short value; \
+ __gpio_as_output(SPEN); /* use SPDA */ \
+ __gpio_as_output(SPCK); /* use SPCK */ \
+ __gpio_as_output(SPDA); /* use SPDA */ \
+ value = ((reg << 0) | (1 << 7)); \
+ val = 0; \
+ __gpio_as_output(SPDA); \
+ __gpio_set_pin(SPEN); \
+ __gpio_clear_pin(SPCK); \
+ udelay(50); \
+ __gpio_clear_pin(SPDA); \
+ __gpio_clear_pin(SPEN); \
+ udelay(50); \
+ for (no = 0; no < 16; no++ ) { \
+ udelay(50); \
+ if(no < 8) \
+ { \
+ if (value & 0x80) /* send data */ \
+ __gpio_set_pin(SPDA); \
+ else \
+ __gpio_clear_pin(SPDA); \
+ udelay(50); \
+ __gpio_set_pin(SPCK); \
+ value = (value << 1); \
+ udelay(50); \
+ __gpio_clear_pin(SPCK); \
+ if(no == 7) \
+ __gpio_as_input(SPDA); \
+ } \
+ else \
+ { \
+ udelay(100); \
+ __gpio_set_pin(SPCK); \
+ udelay(50); \
+ val = (val << 1); \
+ val |= __gpio_get_pin(SPDA); \
+ __gpio_clear_pin(SPCK); \
+ } \
+ } \
+ __gpio_as_output(SPDA); \
+ __gpio_set_pin(SPEN); \
+ udelay(400); \
+ } while(0)
+
+#define __lcd_special_pin_init() \
+ do { \
+ __gpio_as_output(SPEN); /* use SPDA */ \
+ __gpio_as_output(SPCK); /* use SPCK */ \
+ __gpio_as_output(SPDA); /* use SPDA */ \
+ __gpio_as_output(LCD_RET); \
+ udelay(50); \
+ __gpio_clear_pin(LCD_RET); \
+ udelay(100); \
+ __gpio_set_pin(LCD_RET); \
+ } while (0)
+#define __lcd_special_on() \
+ do { \
+ udelay(50); \
+ __gpio_clear_pin(LCD_RET); \
+ udelay(100); \
+ __gpio_set_pin(LCD_RET); \
+} while (0)
+
+ #define __lcd_special_off() \
+ do { \
+ __gpio_clear_pin(LCD_RET); \
+ } while (0)
+
+#endif /* CONFIG_JZLCD_AUO_A030FL01_V1 */
+
+/* TRULY_TFTG320240DTSW */
+#if defined(CONFIG_JZ4760_LCD_TRULY_TFTG320240DTSW_16BIT) || defined(CONFIG_JZ4760_LCD_TRULY_TFTG320240DTSW_18BIT)
+
+#if defined(CONFIG_JZ4760_LEPUS)
+#define LCD_RESET_PIN (32*5+10)// LCD_REV, GPF10
+#else
+#error "Define LCD_RESET_PIN on your board"
+#endif
+
+#define __lcd_special_on() \
+do { \
+ __gpio_as_output(32*3+30);\
+ __gpio_clear_pin(32*3+30);\
+ __gpio_as_output(LCD_RESET_PIN); \
+ __gpio_set_pin(LCD_RESET_PIN); \
+ udelay(100); \
+ __gpio_clear_pin(LCD_RESET_PIN); \
+ udelay(100); \
+ __gpio_set_pin(LCD_RESET_PIN); \
+} while (0)
+
+#endif /* CONFIG_JZ4760_LCD_TRULY_TFTG320240DTSW */
+
+// Wolfgang 2008.02.23
+#if defined(CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA) || defined(CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DUMMY)
+
+#if defined(CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA)
+#define PANEL_MODE 0x02 /* RGB Delta */
+#elif defined(CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DUMMY)
+#define PANEL_MODE 0x00 /* RGB Dummy */
+#endif
+
+#if defined(CONFIG_JZ4760_LEPUS) /* board LEPUS */
+ #define SPEN (32*2+29) //GPB29
+ #define SPCK (32*2+28) //GPB28
+ #define SPDA (32*2+21) //GPB21
+ #define LCD_RET (32*5+6) // GPF6 //use for lcd reset
+#else
+#error "please define SPI pins on your board."
+#endif
+
+ #define __spi_write_reg1(reg, val) \
+ do { \
+ unsigned char no;\
+ unsigned short value;\
+ unsigned char a=0;\
+ unsigned char b=0;\
+ a=reg;\
+ b=val;\
+ __gpio_set_pin(SPEN);\
+ udelay(100);\
+ __gpio_clear_pin(SPCK);\
+ __gpio_clear_pin(SPDA);\
+ __gpio_clear_pin(SPEN);\
+ udelay(25);\
+ value=((a<<8)|(b&0xFF));\
+ for(no=0;no<16;no++)\
+ {\
+ __gpio_clear_pin(SPCK);\
+ if((value&0x8000)==0x8000)\
+ __gpio_set_pin(SPDA);\
+ else\
+ __gpio_clear_pin(SPDA);\
+ udelay(25);\
+ __gpio_set_pin(SPCK);\
+ value=(value<<1); \
+ udelay(25);\
+ }\
+ __gpio_clear_pin(SPCK);\
+ __gpio_set_pin(SPEN);\
+ udelay(100);\
+ } while (0)
+
+ #define __spi_write_reg(reg, val) \
+ do {\
+ __spi_write_reg1((reg<<2), val); \
+ udelay(100); \
+ }while(0)
+
+ #define __lcd_special_pin_init() \
+ do { \
+ __gpio_as_output(SPEN); /* use SPDA */\
+ __gpio_as_output(SPCK); /* use SPCK */\
+ __gpio_as_output(SPDA); /* use SPDA */\
+ __gpio_as_output(SPDA); /* use reset */\
+ __gpio_as_output(LCD_RET); /* use reset */\
+ __gpio_set_pin(LCD_RET);\
+ mdelay(15);\
+ __gpio_clear_pin(LCD_RET);\
+ mdelay(15);\
+ __gpio_set_pin(LCD_RET);\
+ } while (0)
+
+ #define __lcd_special_on() \
+ do { \
+ mdelay(10); \
+ __spi_write_reg(0x00, 0x10); \
+ __spi_write_reg(0x01, 0xB1); \
+ __spi_write_reg(0x00, 0x10); \
+ __spi_write_reg(0x01, 0xB1); \
+ __spi_write_reg(0x02, PANEL_MODE); /* RGBD MODE */ \
+ __spi_write_reg(0x03, 0x01); /* Noninterlace*/ \
+ mdelay(10); \
+ } while (0)
+
+ #define __lcd_special_off() \
+ do { \
+ } while (0)
+
+#endif /* CONFIG_JZ4760_LCD_TOPPOLY_TD025THEA7_RGB_DELTA */
+
+
+#if defined(CONFIG_JZ4760_LCD_FOXCONN_PT035TN01) || defined(CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL)
+
+#if defined(CONFIG_JZ4760_LCD_FOXCONN_PT035TN01) /* board FUWA */
+#define MODE 0xcd /* 24bit parellel RGB */
+#endif
+#if defined(CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL)
+#define MODE 0xc9 /* 8bit serial RGB */
+#endif
+
+#if defined(CONFIG_JZ4760_LEPUS) /* board FuWa */
+
+ #define SPEN (32*2+29) /*LCD_CS*/
+ #define SPCK (32*2+28) /*LCD_SCL*/
+ #define SPDA (32*2+21) /*LCD_SDA*/
+ #define LCD_RET (32*5+6) /*LCD_DISP_N use for lcd reset*/
+
+#else
+#error "driver/video/Jzlcd.h, please define SPI pins on your board."
+#endif
+
+ #define __spi_write_reg1(reg, val) \
+ do { \
+ unsigned char no;\
+ unsigned short value;\
+ unsigned char a=0;\
+ unsigned char b=0;\
+ a=reg;\
+ b=val;\
+ __gpio_set_pin(SPEN);\
+ __gpio_set_pin(SPCK);\
+ __gpio_clear_pin(SPDA);\
+ __gpio_clear_pin(SPEN);\
+ udelay(25);\
+ value=((a<<8)|(b&0xFF));\
+ for(no=0;no<16;no++)\
+ {\
+ __gpio_clear_pin(SPCK);\
+ if((value&0x8000)==0x8000)\
+ __gpio_set_pin(SPDA);\
+ else\
+ __gpio_clear_pin(SPDA);\
+ udelay(25);\
+ __gpio_set_pin(SPCK);\
+ value=(value<<1); \
+ udelay(25);\
+ }\
+ __gpio_set_pin(SPEN);\
+ udelay(100);\
+ } while (0)
+
+ #define __spi_write_reg(reg, val) \
+ do {\
+ __spi_write_reg1((reg<<2|2), val); \
+ udelay(100); \
+ }while(0)
+
+ #define __lcd_special_pin_init() \
+ do { \
+ __gpio_as_output(SPEN); /* use SPDA */\
+ __gpio_as_output(SPCK); /* use SPCK */\
+ __gpio_as_output(SPDA); /* use SPDA */\
+ __gpio_as_output(LCD_RET);\
+ udelay(50);\
+ __gpio_clear_pin(LCD_RET);\
+ mdelay(150);\
+ __gpio_set_pin(LCD_RET);\
+ } while (0)
+
+ #define __lcd_special_on() \
+ do { \
+ udelay(50);\
+ __gpio_clear_pin(LCD_RET);\
+ mdelay(150);\
+ __gpio_set_pin(LCD_RET);\
+ mdelay(10);\
+ __spi_write_reg(0x00, 0x03); \
+ __spi_write_reg(0x01, 0x40); \
+ __spi_write_reg(0x02, 0x11); \
+ __spi_write_reg(0x03, MODE); /* mode */ \
+ __spi_write_reg(0x04, 0x32); \
+ __spi_write_reg(0x05, 0x0e); \
+ __spi_write_reg(0x07, 0x03); \
+ __spi_write_reg(0x08, 0x08); \
+ __spi_write_reg(0x09, 0x32); \
+ __spi_write_reg(0x0A, 0x88); \
+ __spi_write_reg(0x0B, 0xc6); \
+ __spi_write_reg(0x0C, 0x20); \
+ __spi_write_reg(0x0D, 0x20); \
+ } while (0) //reg 0x0a is control the display direction:DB0->horizontal level DB1->vertical level
+
+/* __spi_write_reg(0x02, 0x03); \
+ __spi_write_reg(0x06, 0x40); \
+ __spi_write_reg(0x0a, 0x11); \
+ __spi_write_reg(0x0e, 0xcd); \
+ __spi_write_reg(0x12, 0x32); \
+ __spi_write_reg(0x16, 0x0e); \
+ __spi_write_reg(0x1e, 0x03); \
+ __spi_write_reg(0x22, 0x08); \
+ __spi_write_reg(0x26, 0x40); \
+ __spi_write_reg(0x2a, 0x88); \
+ __spi_write_reg(0x2e, 0x88); \
+ __spi_write_reg(0x32, 0x20); \
+ __spi_write_reg(0x36, 0x20); \
+*/
+// } while (0) //reg 0x0a is control the display direction:DB0->horizontal level DB1->vertical level
+
+ #define __lcd_special_off() \
+ do { \
+ __spi_write_reg(0x00, 0x03); \
+ } while (0)
+
+#endif /* CONFIG_JZ4760_LCD_FOXCONN_PT035TN01 or CONFIG_JZ4760_LCD_INNOLUX_PT035TN01_SERIAL */
+
+#if defined(CONFIG_JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W)
+static inline void CmdWrite(unsigned int cmd)
+{
+ while (REG_SLCD_STATE & SLCD_STATE_BUSY); /* wait slcd ready */
+ udelay(30);
+ REG_SLCD_DATA = SLCD_DATA_RS_COMMAND | cmd;
+}
+
+static inline void DataWrite(unsigned int data)
+{
+ while (REG_SLCD_STATE & SLCD_STATE_BUSY); /* wait slcd ready */
+// udelay(30);
+ REG_SLCD_DATA = SLCD_DATA_RS_DATA | data;
+}
+
+
+static inline void delay(long delay_time)
+{
+ long cnt;
+
+// delay_time *= (384/8);
+ delay_time *= (43/8);
+
+ for (cnt=0;cnt<delay_time;cnt++)
+ {
+ asm("nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ );
+ }
+}
+
+
+/*---- LCD Initial ----*/
+static void SlcdInit(void)
+{
+ delay(10000);
+ CmdWrite(0x0301); //reset
+ delay(10000);
+ CmdWrite(0x0101);
+ CmdWrite(0x0301);
+ CmdWrite(0x0008);
+ CmdWrite(0x2201); //reset
+ CmdWrite(0x0000);
+ CmdWrite(0x0080); //0x0020
+ delay(10000);
+
+ CmdWrite(0x2809);
+ CmdWrite(0x1900);
+ CmdWrite(0x2110);
+ CmdWrite(0x1805);
+ CmdWrite(0x1E01);
+ CmdWrite(0x1847);
+ delay(1000);
+ CmdWrite(0x1867);
+ delay(10000);
+ CmdWrite(0x18F7);
+ delay(10000);
+ CmdWrite(0x2100);
+ CmdWrite(0x2809);
+ CmdWrite(0x1a05);
+ CmdWrite(0x1900);
+ CmdWrite(0x1f64);
+ CmdWrite(0x2070);
+ CmdWrite(0x1e81);
+ CmdWrite(0x1b01);
+
+ CmdWrite(0x0200);
+ CmdWrite(0x0504); //y address increcement
+ CmdWrite(0x0D00); //*240
+ CmdWrite(0x1D08);
+ CmdWrite(0x2300);
+ CmdWrite(0x2D01);
+ CmdWrite(0x337F);
+ CmdWrite(0x3400);
+ CmdWrite(0x3501);
+ CmdWrite(0x3700);
+ CmdWrite(0x42ef); //x start from 239
+ CmdWrite(0x4300);
+ CmdWrite(0x4400); //y start from 0
+ CmdWrite(0x4500);
+ CmdWrite(0x46EF);
+ CmdWrite(0x4700);
+ CmdWrite(0x4800);
+ CmdWrite(0x4901);
+ CmdWrite(0x4A3F);
+ CmdWrite(0x4B00);
+ CmdWrite(0x4C00);
+ CmdWrite(0x4D00);
+ CmdWrite(0x4E00);
+ CmdWrite(0x4F00);
+ CmdWrite(0x5000);
+ CmdWrite(0x7600);
+ CmdWrite(0x8600);
+ CmdWrite(0x8720);
+ CmdWrite(0x8802);
+ CmdWrite(0x8903);
+ CmdWrite(0x8D40);
+ CmdWrite(0x8F05);
+ CmdWrite(0x9005);
+ CmdWrite(0x9144);
+ CmdWrite(0x9244);
+ CmdWrite(0x9344);
+ CmdWrite(0x9433);
+ CmdWrite(0x9505);
+ CmdWrite(0x9605);
+ CmdWrite(0x9744);
+ CmdWrite(0x9844);
+ CmdWrite(0x9944);
+ CmdWrite(0x9A33);
+ CmdWrite(0x9B33);
+ CmdWrite(0x9C33);
+ //==> SETP 3
+ CmdWrite(0x0000);
+ CmdWrite(0x01A0);
+ CmdWrite(0x3B01);
+
+ CmdWrite(0x2809);
+ delay(1000);
+ CmdWrite(0x1900);
+ delay(1000);
+ CmdWrite(0x2110);
+ delay(1000);
+ CmdWrite(0x1805);
+ delay(1000);
+ CmdWrite(0x1E01);
+ delay(1000);
+ CmdWrite(0x1847);
+ delay(1000);
+ CmdWrite(0x1867);
+ delay(1000);
+ CmdWrite(0x18F7);
+ delay(1000);
+ CmdWrite(0x2100);
+ delay(1000);
+ CmdWrite(0x2809);
+ delay(1000);
+ CmdWrite(0x1A05);
+ delay(1000);
+ CmdWrite(0x19E8);
+ delay(1000);
+ CmdWrite(0x1F64);
+ delay(1000);
+ CmdWrite(0x2045);
+ delay(1000);
+ CmdWrite(0x1E81);
+ delay(1000);
+ CmdWrite(0x1B09);
+ delay(1000);
+ CmdWrite(0x0020);
+ delay(1000);
+ CmdWrite(0x0120);
+ delay(1000);
+
+ CmdWrite(0x3B01);
+ delay(1000);
+
+ /* Set Window(239,319), Set Cursor(239,319) */
+ CmdWrite(0x0510);
+ CmdWrite(0x01C0);
+ CmdWrite(0x4500);
+ CmdWrite(0x46EF);
+ CmdWrite(0x4800);
+ CmdWrite(0x4700);
+ CmdWrite(0x4A3F);
+ CmdWrite(0x4901);
+ CmdWrite(0x42EF);
+ CmdWrite(0x443F);
+ CmdWrite(0x4301);
+
+}
+
+#if defined(CONFIG_JZ4760_LEPUS)
+#define PIN_CS_N (32*1+29) /* a low voltage */
+#define PIN_RD_N (32*2+9) /* LCD_DE: GP C9, a high voltage */
+#define PIN_RESET_N (32*5+10) /* LCD_REV GP F10 */
+#else
+#error "Define special lcd pins for your platform."
+#endif
+
+#define __lcd_slcd_pin_init() \
+ do { \
+ __gpio_as_output(PIN_RD_N); /* RD#: LCD_REV */ \
+ __gpio_as_output(PIN_RESET_N); /* RESET#: LCD_SPL */ \
+ __gpio_set_pin(PIN_RD_N); /*set read signal high */ \
+ __gpio_set_pin(PIN_RESET_N); \
+ mdelay(100); \
+ __gpio_clear_pin(PIN_RESET_N); \
+ mdelay(100); \
+ __gpio_set_pin(PIN_RESET_N); \
+ /* Configure SLCD module */ \
+ REG_LCD_CTRL &= ~(LCD_CTRL_ENA|LCD_CTRL_DIS); /* disable lcdc */ \
+ REG_LCD_CFG = LCD_CFG_LCDPIN_SLCD | 0x0D; /* LCM */ \
+ REG_SLCD_CTRL &= ~SLCD_CTRL_DMA_EN; /* disable slcd dma */ \
+ REG_SLCD_CFG = SLCD_CFG_DWIDTH_16BIT | SLCD_CFG_CWIDTH_16BIT | SLCD_CFG_CS_ACTIVE_LOW | SLCD_CFG_RS_CMD_LOW | SLCD_CFG_CLK_ACTIVE_FALLING | SLCD_CFG_TYPE_PARALLEL; \
+ REG_LCD_REV = 0x04; /* lcd clock??? */ \
+ printk("Fuwa test, pixclk divide REG_LCD_REV=0x%08x\n", REG_LCD_REV); \
+}while (0)
+
+#define __lcd_slcd_special_on() \
+ do { \
+ __lcd_slcd_pin_init(); \
+ SlcdInit(); \
+ REG_SLCD_CTRL |= SLCD_CTRL_DMA_EN; /* slcdc dma enable */ \
+ } while (0)
+
+#endif /* #if CONFIG_JZ4760_LCD_TRULY_TFT_GG1P0319LTSW_W */
+
+#ifndef __lcd_special_pin_init
+#define __lcd_special_pin_init()
+#endif
+#ifndef __lcd_special_on
+#define __lcd_special_on()
+#endif
+#ifndef __lcd_special_off
+#define __lcd_special_off()
+#endif
+
+
+/*
+ * Platform specific definition
+ */
+#if defined(CONFIG_JZ4760_VGA_DISPLAY)
+#define __lcd_display_pin_init()
+#define __lcd_display_on()
+#define __lcd_display_off()
+#elif defined(CONFIG_JZ4760_LEPUS)/* board lepus */
+#define __lcd_display_pin_init() \
+do { \
+ __gpio_as_output(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_pin_init(); \
+} while (0)
+
+#define __lcd_display_on() \
+do { \
+ __gpio_set_pin(GPIO_LCD_VCC_EN_N); \
+ __lcd_special_on(); \
+} while (0)
+
+#define __lcd_display_off() \
+do { \
+ __lcd_special_off(); \
+} while (0)
+
+#else /* other boards */
+
+#define __lcd_display_pin_init() \
+do { \
+ __lcd_special_pin_init(); \
+} while (0)
+#define __lcd_display_on() \
+do { \
+ __lcd_special_on(); \
+ __lcd_set_backlight_level(80); \
+} while (0)
+
+#define __lcd_display_off() \
+do { \
+ __lcd_close_backlight(); \
+ __lcd_special_off(); \
+} while (0)
+#endif /* LEPUS */
+
+
+/*****************************************************************************
+ * LCD display pin dummy macros
+ *****************************************************************************/
+
+#ifndef __lcd_display_pin_init
+#define __lcd_display_pin_init()
+#endif
+#ifndef __lcd_slcd_special_on
+#define __lcd_slcd_special_on()
+#endif
+#ifndef __lcd_display_on
+#define __lcd_display_on()
+#endif
+#ifndef __lcd_display_off
+#define __lcd_display_off()
+#endif
+#ifndef __lcd_set_backlight_level
+#define __lcd_set_backlight_level(n)
+#endif
+
+#endif /* __JZ4760_LCD_H__ */
diff --git a/drivers/video/jz4760_tve.c b/drivers/video/jz4760_tve.c
new file mode 100644
index 00000000000..07864fa8b58
--- /dev/null
+++ b/drivers/video/jz4760_tve.c
@@ -0,0 +1,104 @@
+
+/*
+ * linux/drivers/video/jz4760_tve.c -- Ingenic Jz4760 TVE Controller operation
+ * interface.
+ * Copyright (C) 2005-2008, Ingenic Semiconductor Inc.
+ * Author: Wolfgang Wang, <lgwang@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.
+ *
+ * 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 <asm/jzsoc.h>
+#include "jz4760_tve.h"
+
+struct jz4760tve_info jz4760_tve_info_PAL = {
+ .ctrl = (4 << TVE_CTRL_YCDLY_BIT) | TVE_CTRL_SYNCT | TVE_CTRL_PAL | TVE_CTRL_SWRST, /* PAL, SVIDEO */
+ .frcfg = (23 << TVE_FRCFG_L1ST_BIT) | (625 << TVE_FRCFG_NLINE_BIT),
+ .slcfg1 = (800<<TVE_SLCFG1_WHITEL_BIT) | (282<<TVE_SLCFG1_BLACKL_BIT),
+ .slcfg2 = (296<<TVE_SLCFG2_VBLANKL_BIT) | (240<<TVE_SLCFG2_BLANKL_BIT),
+ .slcfg3 = (72 <<TVE_SLCFG3_SYNCL_BIT),
+ .ltcfg1 = (20<<TVE_LTCFG1_FRONTP_BIT) | (63<<TVE_LTCFG1_HSYNCW_BIT) | (78<<TVE_LTCFG1_BACKP_BIT),
+ .ltcfg2 = (1440 << TVE_LTCFG2_ACTLIN_BIT) | (24 << TVE_LTCFG2_PREBW_BIT) | (68 << TVE_LTCFG2_BURSTW_BIT),
+ .cfreq = 0x2a098acb,
+ .cphase = (0 << TVE_CPHASE_INITPH_BIT) | (0 << TVE_CPHASE_ACTPH_BIT) | (1 << TVE_CPHASE_CCRSTP_BIT),
+ .cbcrcfg = (32<<TVE_CBCRCFG_CBBA_BIT) | (59<<TVE_CBCRCFG_CRBA_BIT) | (137<<TVE_CBCRCFG_CBGAIN_BIT) | (137<<TVE_CBCRCFG_CRGAIN_BIT), /* CBGAIN CRGAIN??? */
+ .wsscr = 0x00000070, /* default value */
+ .wsscfg1 = 0x0,
+ .wsscfg2 = 0x0,
+ .wsscfg3 = 0x0,
+};
+
+struct jz4760tve_info jz4760_tve_info_NTSC = {
+ .ctrl = (4 << TVE_CTRL_YCDLY_BIT) | TVE_CTRL_SWRST, /* NTSC, SVIDEO */
+ .frcfg = (21 << TVE_FRCFG_L1ST_BIT) | (525 << TVE_FRCFG_NLINE_BIT),
+ .slcfg1 = (800<<TVE_SLCFG1_WHITEL_BIT) | (282<<TVE_SLCFG1_BLACKL_BIT),
+ .slcfg2 = (296<<TVE_SLCFG2_VBLANKL_BIT) | (240<<TVE_SLCFG2_BLANKL_BIT),
+ .slcfg3 = (72 <<TVE_SLCFG3_SYNCL_BIT),
+ .ltcfg1 = (16<<TVE_LTCFG1_FRONTP_BIT) | (63<<TVE_LTCFG1_HSYNCW_BIT) | (59<<TVE_LTCFG1_BACKP_BIT),
+ .ltcfg2 = (1440 << TVE_LTCFG2_ACTLIN_BIT) | (22 << TVE_LTCFG2_PREBW_BIT) | (68 << TVE_LTCFG2_BURSTW_BIT),
+ .cfreq = 0x21f07c1f,
+ .cphase = (0x17 << TVE_CPHASE_INITPH_BIT) | (0 << TVE_CPHASE_ACTPH_BIT) | (1 << TVE_CPHASE_CCRSTP_BIT),
+ .cbcrcfg = (59<<TVE_CBCRCFG_CBBA_BIT) | (0<<TVE_CBCRCFG_CRBA_BIT) | (137<<TVE_CBCRCFG_CBGAIN_BIT) | (137<<TVE_CBCRCFG_CRGAIN_BIT),
+ .wsscr = 0x00000070, /* default value */
+ .wsscfg1 = 0x0,
+ .wsscfg2 = 0x0,
+ .wsscfg3 = 0x0,
+};
+
+struct jz4760tve_info *jz4760_tve_info = &jz4760_tve_info_PAL; /* default as PAL mode */
+
+void jz4760tve_enable_tve(void)
+{
+ /* enable tve controller, enable DACn??? */
+ jz4760_tve_info->ctrl = (jz4760_tve_info->ctrl | TVE_CTRL_DAPD) & ( ~( TVE_CTRL_DAPD1 | TVE_CTRL_DAPD2));
+ jz4760_tve_info->ctrl &= ~TVE_CTRL_SWRST;
+ REG_TVE_CTRL = jz4760_tve_info->ctrl;
+}
+
+/* turn off TVE, turn off DACn... */
+void jz4760tve_disable_tve(void)
+{
+ jz4760_tve_info->ctrl &= ~TVE_CTRL_DAPD;/* DACn disabled??? */
+ jz4760_tve_info->ctrl |= TVE_CTRL_SWRST;/* DACn disabled??? */
+ REG_TVE_CTRL = jz4760_tve_info->ctrl;
+}
+
+void jz4760tve_set_tve_mode( struct jz4760tve_info *tve )
+{
+ REG_TVE_CTRL = tve->ctrl;
+ REG_TVE_FRCFG = tve->frcfg;
+ REG_TVE_SLCFG1 = tve->slcfg1;
+ REG_TVE_SLCFG2 = tve->slcfg2;
+ REG_TVE_SLCFG3 = tve->slcfg3;
+ REG_TVE_LTCFG1 = tve->ltcfg1;
+ REG_TVE_LTCFG2 = tve->ltcfg2;
+ REG_TVE_CFREQ = tve->cfreq;
+ REG_TVE_CPHASE = tve->cphase;
+ REG_TVE_CBCRCFG = tve->cbcrcfg;
+ REG_TVE_WSSCR = tve->wsscr;
+ REG_TVE_WSSCFG1 = tve->wsscfg1;
+ REG_TVE_WSSCFG2 = tve->wsscfg2;
+ REG_TVE_WSSCFG3 = tve->wsscfg3;
+}
+
+void jz4760tve_init( int tve_mode )
+{
+ switch ( tve_mode ) {
+ case PANEL_MODE_TVE_PAL:
+ jz4760_tve_info = &jz4760_tve_info_PAL;
+ break;
+ case PANEL_MODE_TVE_NTSC:
+ jz4760_tve_info = &jz4760_tve_info_NTSC;
+ break;
+ }
+
+ jz4760tve_set_tve_mode( jz4760_tve_info );
+// jz4760tve_enable_tve();
+}
diff --git a/drivers/video/jz4760_tve.h b/drivers/video/jz4760_tve.h
new file mode 100644
index 00000000000..ac89276bfcc
--- /dev/null
+++ b/drivers/video/jz4760_tve.h
@@ -0,0 +1,45 @@
+#ifndef __JZ4760_TVE_H__
+#define __JZ4760_TVE_H__
+
+
+#define PANEL_MODE_LCD_PANEL 0
+#define PANEL_MODE_TVE_PAL 1
+#define PANEL_MODE_TVE_NTSC 2
+
+/* TV parameter */
+#define TVE_WIDTH_PAL 720
+#define TVE_HEIGHT_PAL 573
+#define TVE_FREQ_PAL 50
+#define TVE_WIDTH_NTSC 720
+#define TVE_HEIGHT_NTSC 482
+#define TVE_FREQ_NTSC 60
+
+
+/* Structure for TVE */
+struct jz4760tve_info {
+ unsigned int ctrl;
+ unsigned int frcfg;
+ unsigned int slcfg1;
+ unsigned int slcfg2;
+ unsigned int slcfg3;
+ unsigned int ltcfg1;
+ unsigned int ltcfg2;
+ unsigned int cfreq;
+ unsigned int cphase;
+ unsigned int cbcrcfg;
+ unsigned int wsscr;
+ unsigned int wsscfg1;
+ unsigned int wsscfg2;
+ unsigned int wsscfg3;
+};
+
+extern struct jz4760tve_info *jz4760_tve_info;
+
+extern void jz4760tve_enable_tve(void);
+extern void jz4760tve_disable_tve(void);
+
+extern void jz4760tve_set_tve_mode( struct jz4760tve_info *tve );
+extern void jz4760tve_init( int tve_mode );
+
+
+#endif /* __JZ4760_TVE_H__ */
diff --git a/drivers/video/jzepd.c b/drivers/video/jzepd.c
new file mode 100644
index 00000000000..79ce8f31412
--- /dev/null
+++ b/drivers/video/jzepd.c
@@ -0,0 +1,2155 @@
+/*
+ * linux/drivers/video/jzepd.c -- Ingenic AUO-EPD frame buffer device
+ *
+ * This program is used to support Electronic Paper Display;
+ * you can redistribute it and/or modify it according to your own needs.
+ *
+ * This driver supports 4/8level waveform.
+ * The first writen by Cynthia <zhzhao@ingenic.cn>
+ */
+
+#include "jz4760_epd.h"
+
+//#define EPD_DEBUG
+
+#ifdef EPD_DEBUG
+#define D(fmt, arg...) printk(fmt, ##arg)
+#else
+#define D(fmt, arg...)
+#endif
+
+#define INVALID_TEMP -1
+#define VALID_TEMP 1
+
+#define MOD_INVALID -2
+#define MOD_VALID 2
+
+#define EPD_SUCCESS 0
+
+#define TEMP_NUM 4
+#define MOD_NUM 4
+
+int totally_time; // this is used to record multiple of 16 frames
+
+extern unsigned char *lcd_palette;
+
+enum epd_temperature_level
+{
+ TEMP_LOW_LEVEL = 0, //temp0
+ TEMP_HIGH_LEVEL , //temp1
+ TEMP_HIGHER_LEVEL , //temp2
+ TEMP_HIGHEST_LEVEL //temp3
+};
+enum epd_temperature_level epd_temp_level;
+
+
+enum epd_mod_level
+{
+ EPD_MOD_INIT = 0,
+ EPD_MOD_DU, // white/black level
+ EPD_MOD_GU, //gray level
+ EPD_MOD_GC //update all display with gray level
+};
+enum epd_mod_level epd_mod_level;
+
+enum epd_gray_level
+{
+ GRAY_LEVEL_4 = 4,
+ GRAY_LEVEL_8 = 8,
+ GRAY_LEVEL_16 = 16
+};
+enum epd_gray_level epd_gray_level;
+
+
+// waveform when temp = low level
+unsigned int waveform_temp0_init[]={
+};
+
+unsigned int waveform_temp0_du[]={
+};
+
+unsigned int waveform_temp0_gu[]={
+};
+
+unsigned int waveform_temp0_gc[]={
+};
+// waveform when temp = high level
+unsigned int waveform_temp1_init[]={
+};
+
+unsigned int waveform_temp1_du[]={
+};
+
+unsigned int waveform_temp1_gu[]={
+};
+
+unsigned int waveform_temp1_gc[]={
+};
+// waveform when temp = higher level
+unsigned int waveform_temp2_init[]={
+ 0x55555554, 0xAAAAAAA8, 0x01555555, 0x500AAAAA, 0xAA801555, 0x555500AA, 0xAAAAA855, 0x55555402,
+ 0xAAAAAAA0,
+};
+
+unsigned int waveform_temp2_du[]={
+ 0x01000080, 0x01000080, 0x05000080, 0x05000080, 0x05000080, 0x05000080, 0x15000080, 0x15000080,
+ 0x15000080, 0x150000A0, 0x150000A0, 0x150000A0, 0x150000A0, 0x150000A8, 0x150000A8, 0x00000000,
+};
+
+unsigned int waveform_temp2_gu[]={
+ 0x01010100, 0x01010100, 0x05050104, 0x05050104, 0x05050104, 0x05050104, 0x15051114, 0x15051114,
+ 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0,
+ 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8,
+ 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0,
+ 0x15455100, 0x15455100, 0x15450000, 0x15450000, 0x15450000, 0x15450000, 0x15000000, 0x15000000,
+ 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0,
+};
+
+unsigned int waveform_temp2_gc[]={
+};
+
+// waveform when temp = highest level
+unsigned int waveform_temp3_init[]={
+ 0x5555554A, 0xAAAAA855, 0x5555402A, 0xAAAAA005, 0x555554AA, 0xAAAA8555, 0x555402AA, 0xAAAA0000,
+};
+
+unsigned int waveform_temp3_du[]={
+ 0x01000080,0x01000080,0x05000080,0x05000080,0x05000080,0x15000080,0x15000080,0x15000080,
+ 0x150000A0,0x150000A0,0x150000A0,0x150000A8,0x150000A8,0x0,
+
+};
+
+unsigned int waveform_temp3_gu[]={
+ 0x01010100, 0x01010100, 0x05050104, 0x05050104, 0x05050104, 0x15051114, 0x15051114, 0x15051114,
+ 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0x15051114, 0, 0x2A8AA2A8, 0x2A8AA2A8,
+ 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8,
+ 0x2A8AA2A8, 0x2A8AA2A8, 0x2A8AA2A8, 0, 0x15455100, 0x15455100, 0x15450000, 0x15450000,
+ 0x15450000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000, 0x15000000,
+ 0x15000000, 0,
+
+};
+
+unsigned int waveform_temp3_gc[]={
+ 0x01010101,0x01010101,0x05050505,0x05050505,0x05050505,0x15151515,0x15151515,0x15151515,
+ 0x15151515,0x15151515,0x15151515,0x15151515,0x15151515,0x00000000,0xAAAAAAAA,0xAAAAAAAA,
+ 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,
+ 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0x00000000,0x55555500,0x55555500,0x55550000,0x55550000,
+ 0x55550000,0x55000000,0x55000000,0x55000000,0x55000000,0x55000000,0x55000000,0x55000000,
+ 0x55000000,0x00000000,
+};
+
+
+unsigned int waveform_handwriting[]={
+ 0x01000080,0x01000080,
+};
+
+
+/*========8 gray level waveform =======*/
+
+unsigned int waveform8_temp0_init[]={
+};
+
+unsigned int waveform8_temp0_du[]={
+};
+
+unsigned int waveform8_temp0_gu[]={
+};
+
+unsigned int waveform8_temp0_gc[]={
+};
+// waveform when temp = high level
+unsigned int waveform8_temp1_init[]={
+};
+
+unsigned int waveform8_temp1_du[]={
+};
+
+unsigned int waveform8_temp1_gu[]={
+};
+
+unsigned int waveform8_temp1_gc[]={
+};
+// waveform when temp = higher level
+unsigned int waveform8_temp2_init[]={
+};
+
+unsigned int waveform8_temp2_du[]={
+};
+
+unsigned int waveform8_temp2_gu[]={
+};
+
+unsigned int waveform8_temp2_gc[]={
+};
+// waveform when temp = highest level
+unsigned int waveform8_temp3_init[]={
+ 0x5555554A, 0xAAAAA955, 0x5555002A, 0xAAAAA001, 0x5555552A, 0xAAAAA555, 0x555400AA, 0xAAAA8000,
+};
+
+unsigned int waveform8_temp3_du[]={
+ 0x00100000,0x00000000,0x00000000,0x00008000,0x00050000,0x00000000,0x00000000,0x0000A000,
+ 0x00050000,0x00000000,0x00000000,0x0000A000,0x00150000,0x00000000,0x00000000,0x0000A800,
+ 0x00150000,0x00000000,0x00000000,0x0000A800,0x00550000,0x00000000,0x00000000,0x0000AA00,
+ 0x00550000,0x00000000,0x00000000,0x0000AA00,0x01550000,0x00000000,0x00000000,0x0000AA00,
+ 0x01550000,0x00000000,0x00000000,0x0000AA80,0x05550000,0x00000000,0x00000000,0x0000AAA0,
+ 0x05550000,0x00000000,0x00000000,0x0000AAA0,0x15550000,0x00000000,0x00000000,0x0000AAA8,
+ 0x15550000,0x00000000,0x00000000,0x0000AAA8,0, 0, 0, 0,
+
+};
+
+unsigned int waveform8_temp3_gu[]={
+
+ 0x00010001, 0x00010001, 0x00010001, 0x00010000, 0x00050005, 0x00050005, 0x00050005, 0x00010004,
+ 0x00050005, 0x00050005, 0x00050005, 0x00010004, 0x00150015, 0x00150015, 0x00150005, 0x00110014,
+ 0x00150015, 0x00150015, 0x00150005, 0x00110014, 0x00550055, 0x00550055, 0x00150045, 0x00510054,
+ 0x00550055, 0x00550055, 0x00150045, 0x00510054, 0x01550155, 0x01550055, 0x01150145, 0x01510154,
+ 0x01550155, 0x01550055, 0x01150145, 0x01510154, 0x05550555, 0x01550455, 0x05150545, 0x05510554,
+ 0x05550555, 0x01550455, 0x05150545, 0x05510554, 0x15550555, 0x11551455, 0x15151545, 0x15511554,
+ 0x15550555, 0x11551455, 0x15151545, 0x15511554, 0, 0, 0, 0,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8,
+ 0x2AAA8AAA, 0xa2aaa8aa, 0xaa2a2a8a, 0xaaa2aaa8, 0x15550000, 0, 0, 0,
+ 0x15554555, 0x51555455, 0x55155545, 0x55510000, 0x15554555, 0x51555455, 0x55155545, 0,
+ 0x15554555, 0x51555455, 0x55155545, 0, 0x15554555, 0x51555455, 0x55150000, 0,
+ 0x15554555, 0x51555455, 0x55150000, 0, 0x15554555, 0x51555455, 0, 0,
+ 0x15554555, 0x51555455, 0x00000000, 0, 0x15554555, 0x51550000, 0, 0,
+ 0x15554555, 0x51550000, 0x00000000, 0, 0x15554555, 0, 0, 0,
+ 0x15554555, 0, 0, 0, 0x15550000, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+unsigned int waveform8_temp3_gc[]={
+
+ 0x00010001, 0x00010001, 0x00010001, 0x00010001, 0x00050005, 0x00050005, 0x00050005, 0x00050005,
+ 0x00050005, 0x00050005, 0x00050005, 0x00050005, 0x00150015, 0x00150015, 0x00150015, 0x00150015,
+ 0x00150015, 0x00150015, 0x00150015, 0x00150015, 0x00550055, 0x00550055, 0x00550055, 0x00550055,
+ 0x00550055, 0x00550055, 0x00550055, 0x00550055, 0x01550155, 0x01550155, 0x01550155, 0x01550155,
+ 0x01550155, 0x01550155, 0x01550155, 0x01550155, 0x05550555, 0x05550555, 0x05550555, 0x05550555,
+ 0x05550555, 0x05550555, 0x05550555, 0x05550555, 0x15551555, 0x15551555, 0x15551555, 0x15551555,
+ 0x15551555, 0x15551555, 0x15551555, 0x15551555, 0, 0, 0, 0,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0x55550000, 0, 0, 0,
+ 0x55555555, 0x55555555, 0x55555555, 0x55550000, 0x55555555, 0x55555555, 0x55555555, 0,
+ 0x55555555, 0x55555555, 0x55555555, 0, 0x55555555, 0x55555555, 0x55550000, 0,
+ 0x55555555, 0x55555555, 0x55550000, 0, 0x55555555, 0x55555555, 0, 0,
+ 0x55555555, 0x55555555, 0x00000000, 0, 0x55555555, 0x55550000, 0x00000000, 0,
+ 0x55555555, 0x55550000, 0x00000000, 0, 0x55555555, 0, 0, 0,
+ 0x55555555, 0, 0, 0, 0x55550000, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+};
+
+/*========16 gray level waveform =======*/
+unsigned int waveform16_temp0_init[]={
+};
+
+unsigned int waveform16_temp0_du[]={
+};
+
+unsigned int waveform16_temp0_gu[]={
+};
+
+unsigned int waveform16_temp0_gc[]={
+};
+// waveform when temp = high level
+unsigned int waveform16_temp1_init[]={
+};
+
+unsigned int waveform16_temp1_du[]={
+};
+
+unsigned int waveform16_temp1_gu[]={
+};
+
+unsigned int waveform16_temp1_gc[]={
+};
+// waveform when temp = higher level
+unsigned int waveform16_temp2_init[]={
+};
+
+unsigned int waveform16_temp2_du[]={
+};
+
+unsigned int waveform16_temp2_gu[]={
+};
+
+unsigned int waveform16_temp2_gc[]={
+};
+
+// waveform when temp = highest level
+unsigned int waveform16_temp3_init[]={
+};
+
+unsigned int waveform16_temp3_du[]={
+};
+
+unsigned int waveform16_temp3_gu[]={
+};
+
+unsigned int waveform16_temp3_gc[]={
+};
+
+
+
+void printpalette(void *palette, int len)
+{
+ unsigned short *pal = (unsigned short *)palette;
+ int i;
+ printk("palette:\n");
+ for (i = 0; i < len; i++) {
+ if ((i*8)%256 == 0)
+ printk("\nfrm%d:\t", i*8/256);
+ if (i % 16 == 0)
+ printk("\n\t");
+ printk("%04x ", pal[i]);
+ }
+ printk("\n");
+}
+
+
+int get_temp_sensor(void)
+{
+ return 20;
+}
+
+/*identify different temperature zone*/
+int get_temp(void)
+{
+ int temp =0 ;
+
+ temp = get_temp_sensor();
+
+ if (temp <=5 && temp >= 0)
+ {
+ epd_temp_level = TEMP_LOW_LEVEL;
+ }
+ else if (temp <=12 && temp >= 6)
+ epd_temp_level = TEMP_HIGH_LEVEL;
+
+ else if (temp <=17 && temp >= 13)
+ epd_temp_level = TEMP_HIGHER_LEVEL;
+
+ else if (temp <=50 && temp >= 18)
+ epd_temp_level = TEMP_HIGHEST_LEVEL;
+
+ else
+ return INVALID_TEMP;
+
+ return VALID_TEMP;
+}
+
+
+void fill_init_palette(void)
+{
+ int i, j, offset, bit2;
+ int max_frm ;
+ int index_per_frame = (1 << 8);
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ int count=0, shift=0;
+ unsigned int *p;
+
+ memset(lcd_palette, 0x0, 4096*2);
+
+ get_temp();
+ D("%s: temp(%d) gray level=%d. \n",__func__,epd_temp_level,epd_gray_level);
+
+ if(epd_gray_level == GRAY_LEVEL_4){
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 179;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform_temp0_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ /*
+ (j * index_per_frame + i)*2(bit) = offset
+ but it alligned by word, so offset = offset/32;
+ */
+ offset = (j * index_per_frame + i)*2/32;
+ /*
+ store by word so shif 2 bit per 2 bit voltage until 32bit(a word)
+ from Lsb to Msb bit2 = 0,2,4,6,8,10...30
+ */
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ shift = 0;
+ count ++;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 143;
+
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform_temp1_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+
+ }
+
+ }
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 143;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform_temp2_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 ) // when shift(0~14),shift++, so shift tatally is 16
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 121;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform_temp3_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+
+ if (shift < 15 )
+ shift ++;// when shift(0~14),shift++, so shift tatally is 16
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+ }
+ if(epd_gray_level == GRAY_LEVEL_8){
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 179;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform8_temp0_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ /*
+ (j * index_per_frame + i)*2(bit) = offset
+ but it alligned by word, so offset = offset/32;
+ */
+ offset = (j * index_per_frame + i)*2/32;
+ /*
+ store by word so shif 2 bit per 2 bit voltage until 32bit(a word)
+ from Lsb to Msb bit2 = 0,2,4,6,8,10...30
+ */
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ shift = 0;
+ count ++;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 143;
+
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform8_temp1_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+
+ }
+
+ }
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 143;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform8_temp2_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 ) // when shift(0~14),shift++, so shift tatally is 16
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 122;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform8_temp3_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+
+ if (shift < 15 )
+ shift ++;// when shift(0~14),shift++, so shift tatally is 16
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+
+
+
+ }
+ if(epd_gray_level == GRAY_LEVEL_16){
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 179;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform16_temp0_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ /*
+ (j * index_per_frame + i)*2(bit) = offset
+ but it alligned by word, so offset = offset/32;
+ */
+ offset = (j * index_per_frame + i)*2/32;
+ /*
+ store by word so shif 2 bit per 2 bit voltage until 32bit(a word)
+ from Lsb to Msb bit2 = 0,2,4,6,8,10...30
+ */
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ shift = 0;
+ count ++;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 143;
+
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform16_temp1_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 )
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+
+ }
+
+ }
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 143;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform16_temp2_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+ if (shift <15 ) // when shift(0~14),shift++, so shift tatally is 16
+ shift ++;
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 122;
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ p = (unsigned int *)&waveform16_temp3_init; // give waveform_temp2_init to p
+ for (j = 0; j < max_frm; j++) {
+
+ for(i=0;i<index_per_frame;i++){
+
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ ptr[offset] |= ((*(p+count) >> (30-shift*2)) & 0x3) << bit2;
+
+ }
+
+ if (shift < 15 )
+ shift ++;// when shift(0~14),shift++, so shift tatally is 16
+ else {
+ count ++;
+ shift = 0;
+ }
+
+ }
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+
+
+
+ }
+
+ dma_cache_wback((unsigned int)(lcd_palette), 4096);
+// printpalette((unsigned short *)((unsigned int)lcd_palette | 0xa0000000), 4096);
+}
+
+void fill_du_4level_gray(int max_frm,unsigned int *p)
+{
+
+ int i,j,old,new,offset, bit2;
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ int index_per_frame = (1 << 8);
+ memset(lcd_palette, 0x0, 4096);
+ // record the totally multiple of 16frames
+
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+
+ for (j = 0; j < max_frm; j++) {
+ count = j;
+ for(i=0;i<index_per_frame;i++){
+
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(old == 0 && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-3*2)) & 0x3)<< bit2;
+
+ if(old == 0 && new == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-2*12)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-2*15)) & 0x3)<< bit2;
+
+ }
+
+
+ }
+
+}
+
+void fill_du_8level_gray(int max_frm,unsigned int *p)
+{
+
+ int i,j,old,new,offset, bit2;
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ int index_per_frame = (1 << 8);
+ memset(lcd_palette, 0x0, 4096);
+ // record the totally multiple of 16frames
+
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+
+ for (j = 0; j < max_frm; j++) {
+ count = 4*j;
+
+ for(i=0;i<index_per_frame;i++){
+
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(old == 0 && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-7*2)) & 0x3)<< bit2;
+
+
+
+ if(old == 0 && new == 0xf)
+ ptr[offset] |= ((*(p+count+3) >> (30-8*2)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0xf)
+ ptr[offset] |= ((*(p+count+3) >> (30-2*15)) & 0x3)<< bit2;
+
+
+ }
+
+
+ }
+
+}
+void fill_du_16level_gray(int max_frm,unsigned int *p)
+{
+
+ int i,j,old,new,offset, bit2;
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ int index_per_frame = (1 << 8);
+ memset(lcd_palette, 0x0, 4096);
+ // record the totally multiple of 16frames
+
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+
+ for (j = 0; j < max_frm; j++) {
+ count = 16*j;
+
+ for(i=0;i<index_per_frame;i++){
+
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(old == 0 && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-15*2)) & 0x3)<< bit2;
+
+
+
+ if(old == 0 && new == 0xf)
+ ptr[offset] |= ((*(p+count+15) >> (30-0*2)) & 0x3)<< bit2;
+ if(old == 0xf && new == 0xf)
+ ptr[offset] |= ((*(p+count+15) >> (30-2*15)) & 0x3)<< bit2;
+
+
+ }
+
+
+ }
+
+}
+
+void fill_du_palette(void)
+{
+
+ int max_frm ;
+ unsigned int *p;
+
+ get_temp();
+ D("%s: temp(%d) gray level=%d. \n",__func__,epd_temp_level,epd_gray_level);
+
+ if(epd_gray_level == GRAY_LEVEL_4)
+ {
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform_temp0_du; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform_temp1_du; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 14;
+ p = (unsigned int *)&waveform_temp2_du; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 14;
+ p = (unsigned int *)&waveform_temp3_du;
+
+
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_du_4level_gray(max_frm,p);
+ }
+
+ if(epd_gray_level == GRAY_LEVEL_8)
+ {
+
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform8_temp0_du; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform8_temp1_du; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 14;
+ p = (unsigned int *)&waveform8_temp2_du; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+ max_frm = 14;
+ p = (unsigned int *)&waveform8_temp3_du;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_du_8level_gray(max_frm,p);
+ }
+ if(epd_gray_level == GRAY_LEVEL_16)
+ {
+ // add 16level gray support
+
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform16_temp0_du; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 16;
+ p = (unsigned int *)&waveform16_temp1_du; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 14;
+ p = (unsigned int *)&waveform16_temp2_du; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+ max_frm = 14;
+ p = (unsigned int *)&waveform16_temp3_du;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_du_8level_gray(max_frm,p);
+
+
+
+ }
+ dma_cache_wback((unsigned int)(lcd_palette), 4096);
+// printpalette((unsigned short *)((unsigned int)lcd_palette | 0xa0000000), 2048);
+
+}
+
+
+void fill_16level_gray(int max_frm,unsigned int *p)
+{
+ int i,j,old,new,offset, bit2;
+ int index_per_frame = (1 << 8);
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ memset(lcd_palette, 0x0, 4096);
+
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ for (j = 0; j < max_frm; j++) {
+ count = 16*j;
+ for(i=0;i<index_per_frame;i++){
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(new == 0 && old == 0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x1)
+ ptr[offset] |= ((*(p+count) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x2)
+ ptr[offset] |= ((*(p+count) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x3)
+ ptr[offset] |= ((*(p+count) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x4)
+ ptr[offset] |= ((*(p+count) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x6)
+ ptr[offset] |= ((*(p+count) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x7)
+ ptr[offset] |= ((*(p+count) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0x8)
+ ptr[offset] |= ((*(p+count) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0x9)
+ ptr[offset] |= ((*(p+count) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xb)
+ ptr[offset] |= ((*(p+count) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xc)
+ ptr[offset] |= ((*(p+count) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xd)
+ ptr[offset] |= ((*(p+count) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xe)
+ ptr[offset] |= ((*(p+count) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x0 && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x1 && old == 0)
+ ptr[offset] |= ((*(p+count+1) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x1)
+ ptr[offset] |= ((*(p+count+1) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x2)
+ ptr[offset] |= ((*(p+count+1) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x3)
+ ptr[offset] |= ((*(p+count+1) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x4)
+ ptr[offset] |= ((*(p+count+1) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x5)
+ ptr[offset] |= ((*(p+count+1) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x6)
+ ptr[offset] |= ((*(p+count+1) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x7)
+ ptr[offset] |= ((*(p+count+1) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x8)
+ ptr[offset] |= ((*(p+count+1) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0x9)
+ ptr[offset] |= ((*(p+count+1) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xa)
+ ptr[offset] |= ((*(p+count+1) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xb)
+ ptr[offset] |= ((*(p+count+1) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xc)
+ ptr[offset] |= ((*(p+count+1) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xd)
+ ptr[offset] |= ((*(p+count+1) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xe)
+ ptr[offset] |= ((*(p+count+1) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x1 && old == 0xf)
+ ptr[offset] |= ((*(p+count+1) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x2 && old == 0)
+ ptr[offset] |= ((*(p+count+2) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x1)
+ ptr[offset] |= ((*(p+count+2) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x2)
+ ptr[offset] |= ((*(p+count+2) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x3)
+ ptr[offset] |= ((*(p+count+2) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x4)
+ ptr[offset] |= ((*(p+count+2) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x5)
+ ptr[offset] |= ((*(p+count+2) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x6)
+ ptr[offset] |= ((*(p+count+2) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x7)
+ ptr[offset] |= ((*(p+count+2) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x8)
+ ptr[offset] |= ((*(p+count+2) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x9)
+ ptr[offset] |= ((*(p+count+2) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xa)
+ ptr[offset] |= ((*(p+count+2) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xb)
+ ptr[offset] |= ((*(p+count+2) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xc)
+ ptr[offset] |= ((*(p+count+2) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xd)
+ ptr[offset] |= ((*(p+count+2) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xe)
+ ptr[offset] |= ((*(p+count+2) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xf)
+ ptr[offset] |= ((*(p+count+2) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0x3 && old == 0)
+ ptr[offset] |= ((*(p+count+3) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x1)
+ ptr[offset] |= ((*(p+count+3) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x2)
+ ptr[offset] |= ((*(p+count+3) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x3)
+ ptr[offset] |= ((*(p+count+3) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x4)
+ ptr[offset] |= ((*(p+count+3) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x5)
+ ptr[offset] |= ((*(p+count+3) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x6)
+ ptr[offset] |= ((*(p+count+3) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x7)
+ ptr[offset] |= ((*(p+count+3) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x8)
+ ptr[offset] |= ((*(p+count+3) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0x9)
+ ptr[offset] |= ((*(p+count+3) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xa)
+ ptr[offset] |= ((*(p+count+3) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xb)
+ ptr[offset] |= ((*(p+count+3) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xc)
+ ptr[offset] |= ((*(p+count+3) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xd)
+ ptr[offset] |= ((*(p+count+3) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xe)
+ ptr[offset] |= ((*(p+count+3) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x3 && old == 0xf)
+ ptr[offset] |= ((*(p+count+3) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x4 && old == 0)
+ ptr[offset] |= ((*(p+count+4) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x1)
+ ptr[offset] |= ((*(p+count+4) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x2)
+ ptr[offset] |= ((*(p+count+4) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x3)
+ ptr[offset] |= ((*(p+count+4) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x4)
+ ptr[offset] |= ((*(p+count+4) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x5)
+ ptr[offset] |= ((*(p+count+4) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x6)
+ ptr[offset] |= ((*(p+count+4) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x7)
+ ptr[offset] |= ((*(p+count+4) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x8)
+ ptr[offset] |= ((*(p+count+4) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0x9)
+ ptr[offset] |= ((*(p+count+4) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xa)
+ ptr[offset] |= ((*(p+count+4) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xb)
+ ptr[offset] |= ((*(p+count+4) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xc)
+ ptr[offset] |= ((*(p+count+4) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xd)
+ ptr[offset] |= ((*(p+count+4) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xe)
+ ptr[offset] |= ((*(p+count+4) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x4 && old == 0xf)
+ ptr[offset] |= ((*(p+count+4) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x5 && old == 0)
+ ptr[offset] |= ((*(p+count+5) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x1)
+ ptr[offset] |= ((*(p+count+5) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x2)
+ ptr[offset] |= ((*(p+count+5) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x3)
+ ptr[offset] |= ((*(p+count+5) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x4)
+ ptr[offset] |= ((*(p+count+5) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x5)
+ ptr[offset] |= ((*(p+count+5) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x6)
+ ptr[offset] |= ((*(p+count+5) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x7)
+ ptr[offset] |= ((*(p+count+5) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x8)
+ ptr[offset] |= ((*(p+count+5) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x9)
+ ptr[offset] |= ((*(p+count+5) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xa)
+ ptr[offset] |= ((*(p+count+5) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xb)
+ ptr[offset] |= ((*(p+count+5) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xc)
+ ptr[offset] |= ((*(p+count+5) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xd)
+ ptr[offset] |= ((*(p+count+5) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xe)
+ ptr[offset] |= ((*(p+count+5) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xf)
+ ptr[offset] |= ((*(p+count+5) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0x6 && old == 0)
+ ptr[offset] |= ((*(p+count+6) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x1)
+ ptr[offset] |= ((*(p+count+6) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x2)
+ ptr[offset] |= ((*(p+count+6) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x3)
+ ptr[offset] |= ((*(p+count+6) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x4)
+ ptr[offset] |= ((*(p+count+6) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x5)
+ ptr[offset] |= ((*(p+count+6) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x6)
+ ptr[offset] |= ((*(p+count+6) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x7)
+ ptr[offset] |= ((*(p+count+6) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x8)
+ ptr[offset] |= ((*(p+count+6) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0x9)
+ ptr[offset] |= ((*(p+count+6) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xa)
+ ptr[offset] |= ((*(p+count+6) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xb)
+ ptr[offset] |= ((*(p+count+6) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xc)
+ ptr[offset] |= ((*(p+count+6) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xd)
+ ptr[offset] |= ((*(p+count+6) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xe)
+ ptr[offset] |= ((*(p+count+6) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x6 && old == 0xf)
+ ptr[offset] |= ((*(p+count+6) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0x7 && old == 0)
+ ptr[offset] |= ((*(p+count+7) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x1)
+ ptr[offset] |= ((*(p+count+7) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x2)
+ ptr[offset] |= ((*(p+count+7) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x3)
+ ptr[offset] |= ((*(p+count+7) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x4)
+ ptr[offset] |= ((*(p+count+7) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x5)
+ ptr[offset] |= ((*(p+count+7) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x6)
+ ptr[offset] |= ((*(p+count+7) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x7)
+ ptr[offset] |= ((*(p+count+7) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x8)
+ ptr[offset] |= ((*(p+count+7) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x9)
+ ptr[offset] |= ((*(p+count+7) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xa)
+ ptr[offset] |= ((*(p+count+7) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xb)
+ ptr[offset] |= ((*(p+count+7) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xc)
+ ptr[offset] |= ((*(p+count+7) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xd)
+ ptr[offset] |= ((*(p+count+7) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xe)
+ ptr[offset] |= ((*(p+count+7) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xf)
+ ptr[offset] |= ((*(p+count+7) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0x8 && old == 0)
+ ptr[offset] |= ((*(p+count+8) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x1)
+ ptr[offset] |= ((*(p+count+8) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x2)
+ ptr[offset] |= ((*(p+count+8) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x3)
+ ptr[offset] |= ((*(p+count+8) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x4)
+ ptr[offset] |= ((*(p+count+8) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x5)
+ ptr[offset] |= ((*(p+count+8) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x6)
+ ptr[offset] |= ((*(p+count+8) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x7)
+ ptr[offset] |= ((*(p+count+8) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x8)
+ ptr[offset] |= ((*(p+count+8) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x9)
+ ptr[offset] |= ((*(p+count+8) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xa)
+ ptr[offset] |= ((*(p+count+8) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xb)
+ ptr[offset] |= ((*(p+count+8) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xc)
+ ptr[offset] |= ((*(p+count+8) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xd)
+ ptr[offset] |= ((*(p+count+8) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xe)
+ ptr[offset] |= ((*(p+count+8) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xf)
+ ptr[offset] |= ((*(p+count+8) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0x9 && old == 0)
+ ptr[offset] |= ((*(p+count+9) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x1)
+ ptr[offset] |= ((*(p+count+9) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x2)
+ ptr[offset] |= ((*(p+count+9) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x3)
+ ptr[offset] |= ((*(p+count+9) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x4)
+ ptr[offset] |= ((*(p+count+9) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x5)
+ ptr[offset] |= ((*(p+count+9) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x6)
+ ptr[offset] |= ((*(p+count+9) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x7)
+ ptr[offset] |= ((*(p+count+9) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x8)
+ ptr[offset] |= ((*(p+count+9) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0x9)
+ ptr[offset] |= ((*(p+count+9) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xa)
+ ptr[offset] |= ((*(p+count+9) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xb)
+ ptr[offset] |= ((*(p+count+9) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xc)
+ ptr[offset] |= ((*(p+count+9) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xd)
+ ptr[offset] |= ((*(p+count+9) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xe)
+ ptr[offset] |= ((*(p+count+9) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x9 && old == 0xf)
+ ptr[offset] |= ((*(p+count+9) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xa && old == 0)
+ ptr[offset] |= ((*(p+count+10) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x1)
+ ptr[offset] |= ((*(p+count+10) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x2)
+ ptr[offset] |= ((*(p+count+10) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x3)
+ ptr[offset] |= ((*(p+count+10) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x4)
+ ptr[offset] |= ((*(p+count+10) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x5)
+ ptr[offset] |= ((*(p+count+10) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x6)
+ ptr[offset] |= ((*(p+count+10) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x7)
+ ptr[offset] |= ((*(p+count+10) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x8)
+ ptr[offset] |= ((*(p+count+10) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x9)
+ ptr[offset] |= ((*(p+count+10) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xa)
+ ptr[offset] |= ((*(p+count+10) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xb)
+ ptr[offset] |= ((*(p+count+10) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xc)
+ ptr[offset] |= ((*(p+count+10) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xd)
+ ptr[offset] |= ((*(p+count+10) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xe)
+ ptr[offset] |= ((*(p+count+10) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xf)
+ ptr[offset] |= ((*(p+count+10) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xb && old == 0)
+ ptr[offset] |= ((*(p+count+11) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x1)
+ ptr[offset] |= ((*(p+count+11) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x2)
+ ptr[offset] |= ((*(p+count+11) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x3)
+ ptr[offset] |= ((*(p+count+11) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x4)
+ ptr[offset] |= ((*(p+count+11) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x5)
+ ptr[offset] |= ((*(p+count+11) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x6)
+ ptr[offset] |= ((*(p+count+11) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x7)
+ ptr[offset] |= ((*(p+count+11) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x8)
+ ptr[offset] |= ((*(p+count+11) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0x9)
+ ptr[offset] |= ((*(p+count+11) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xa)
+ ptr[offset] |= ((*(p+count+11) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xb)
+ ptr[offset] |= ((*(p+count+11) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xc)
+ ptr[offset] |= ((*(p+count+11) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xd)
+ ptr[offset] |= ((*(p+count+11) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xe)
+ ptr[offset] |= ((*(p+count+11) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xb && old == 0xf)
+ ptr[offset] |= ((*(p+count+11) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xc && old == 0)
+ ptr[offset] |= ((*(p+count+12) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x1)
+ ptr[offset] |= ((*(p+count+12) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x2)
+ ptr[offset] |= ((*(p+count+12) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x3)
+ ptr[offset] |= ((*(p+count+12) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x4)
+ ptr[offset] |= ((*(p+count+12) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x5)
+ ptr[offset] |= ((*(p+count+12) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x6)
+ ptr[offset] |= ((*(p+count+12) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x7)
+ ptr[offset] |= ((*(p+count+12) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x8)
+ ptr[offset] |= ((*(p+count+12) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x9)
+ ptr[offset] |= ((*(p+count+12) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xa)
+ ptr[offset] |= ((*(p+count+12) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xb)
+ ptr[offset] |= ((*(p+count+12) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xc)
+ ptr[offset] |= ((*(p+count+12) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xd)
+ ptr[offset] |= ((*(p+count+12) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xe)
+ ptr[offset] |= ((*(p+count+12) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xf)
+ ptr[offset] |= ((*(p+count+12) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xd && old == 0)
+ ptr[offset] |= ((*(p+count+13) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x1)
+ ptr[offset] |= ((*(p+count+13) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x2)
+ ptr[offset] |= ((*(p+count+13) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x3)
+ ptr[offset] |= ((*(p+count+13) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x4)
+ ptr[offset] |= ((*(p+count+13) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x5)
+ ptr[offset] |= ((*(p+count+13) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x6)
+ ptr[offset] |= ((*(p+count+13) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x7)
+ ptr[offset] |= ((*(p+count+13) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x8)
+ ptr[offset] |= ((*(p+count+13) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0x9)
+ ptr[offset] |= ((*(p+count+13) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xa)
+ ptr[offset] |= ((*(p+count+13) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xb)
+ ptr[offset] |= ((*(p+count+13) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xc)
+ ptr[offset] |= ((*(p+count+13) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xd)
+ ptr[offset] |= ((*(p+count+13) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xe)
+ ptr[offset] |= ((*(p+count+13) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xd && old == 0xf)
+ ptr[offset] |= ((*(p+count+13) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xe && old == 0)
+ ptr[offset] |= ((*(p+count+14) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x1)
+ ptr[offset] |= ((*(p+count+14) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x2)
+ ptr[offset] |= ((*(p+count+14) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x3)
+ ptr[offset] |= ((*(p+count+14) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x4)
+ ptr[offset] |= ((*(p+count+14) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x5)
+ ptr[offset] |= ((*(p+count+14) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x6)
+ ptr[offset] |= ((*(p+count+14) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x7)
+ ptr[offset] |= ((*(p+count+14) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x8)
+ ptr[offset] |= ((*(p+count+14) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0x9)
+ ptr[offset] |= ((*(p+count+14) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xa)
+ ptr[offset] |= ((*(p+count+14) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xb)
+ ptr[offset] |= ((*(p+count+14) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xc)
+ ptr[offset] |= ((*(p+count+14) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xd)
+ ptr[offset] |= ((*(p+count+14) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xe)
+ ptr[offset] |= ((*(p+count+14) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xe && old == 0xf)
+ ptr[offset] |= ((*(p+count+14) >> (30-15*2)) & 0x3) << bit2;
+
+ if(new == 0xf && old == 0)
+ ptr[offset] |= ((*(p+count+15) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x1)
+ ptr[offset] |= ((*(p+count+15) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x2)
+ ptr[offset] |= ((*(p+count+15) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x3)
+ ptr[offset] |= ((*(p+count+15) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x4)
+ ptr[offset] |= ((*(p+count+15) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x5)
+ ptr[offset] |= ((*(p+count+15) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x6)
+ ptr[offset] |= ((*(p+count+15) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x7)
+ ptr[offset] |= ((*(p+count+15) >> (30-7*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x8)
+ ptr[offset] |= ((*(p+count+15) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x9)
+ ptr[offset] |= ((*(p+count+15) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xa)
+ ptr[offset] |= ((*(p+count+15) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xb)
+ ptr[offset] |= ((*(p+count+15) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xc)
+ ptr[offset] |= ((*(p+count+15) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xd)
+ ptr[offset] |= ((*(p+count+15) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xe)
+ ptr[offset] |= ((*(p+count+15) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xf)
+ ptr[offset] |= ((*(p+count+15) >> (30-15*2)) & 0x3) << bit2;
+
+ }
+ }
+
+
+}
+
+
+void fill_8level_gray(int max_frm,unsigned int *p)
+{
+ int i,j,old,new,offset, bit2;
+ int index_per_frame = (1 << 8);
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ memset(lcd_palette, 0x0, 4096);
+
+ // record the totally multiple of 16frames
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+ for (j = 0; j < max_frm; j++) {
+ count = 4*j;
+ for(i=0;i<index_per_frame;i++){
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(new == 0 && old == 0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x2)
+ ptr[offset] |= ((*(p+count) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x7)
+ ptr[offset] |= ((*(p+count) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x8)
+ ptr[offset] |= ((*(p+count) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0xc)
+ ptr[offset] |= ((*(p+count) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-7*2)) & 0x3) << bit2;
+
+ if(new == 0x2 && old == 0)
+ ptr[offset] |= ((*(p+count) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x2)
+ ptr[offset] |= ((*(p+count) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x7)
+ ptr[offset] |= ((*(p+count) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0x8)
+ ptr[offset] |= ((*(p+count) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xc)
+ ptr[offset] |= ((*(p+count) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x2 && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x5 && old == 0)
+ ptr[offset] |= ((*(p+count+1) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x2)
+ ptr[offset] |= ((*(p+count+1) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x5)
+ ptr[offset] |= ((*(p+count+1) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x7)
+ ptr[offset] |= ((*(p+count+1) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x8)
+ ptr[offset] |= ((*(p+count+1) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xa)
+ ptr[offset] |= ((*(p+count+1) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xc)
+ ptr[offset] |= ((*(p+count+1) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xf)
+ ptr[offset] |= ((*(p+count+1) >> (30-7*2)) & 0x3) << bit2;
+
+ if(new == 0x7 && old == 0)
+ ptr[offset] |= ((*(p+count+1) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x2)
+ ptr[offset] |= ((*(p+count+1) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x5)
+ ptr[offset] |= ((*(p+count+1) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x7)
+ ptr[offset] |= ((*(p+count+1) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0x8)
+ ptr[offset] |= ((*(p+count+1) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xa)
+ ptr[offset] |= ((*(p+count+1) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xc)
+ ptr[offset] |= ((*(p+count+1) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0x7 && old == 0xf)
+ ptr[offset] |= ((*(p+count+1) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0x8 && old == 0)
+ ptr[offset] |= ((*(p+count+2) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x2)
+ ptr[offset] |= ((*(p+count+2) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x5)
+ ptr[offset] |= ((*(p+count+2) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x7)
+ ptr[offset] |= ((*(p+count+2) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0x8)
+ ptr[offset] |= ((*(p+count+2) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xa)
+ ptr[offset] |= ((*(p+count+2) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xc)
+ ptr[offset] |= ((*(p+count+2) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x8 && old == 0xf)
+ ptr[offset] |= ((*(p+count+2) >> (30-7*2)) & 0x3) << bit2;
+
+ if(new == 0xa && old == 0)
+ ptr[offset] |= ((*(p+count+2) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x2)
+ ptr[offset] |= ((*(p+count+2) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x5)
+ ptr[offset] |= ((*(p+count+2) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x7)
+ ptr[offset] |= ((*(p+count+2) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x8)
+ ptr[offset] |= ((*(p+count+2) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xa)
+ ptr[offset] |= ((*(p+count+2) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xc)
+ ptr[offset] |= ((*(p+count+2) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xf)
+ ptr[offset] |= ((*(p+count+2) >> (30-15*2)) & 0x3) << bit2;
+
+
+ if(new == 0xc && old == 0)
+ ptr[offset] |= ((*(p+count+3) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x2)
+ ptr[offset] |= ((*(p+count+3) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x5)
+ ptr[offset] |= ((*(p+count+3) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x7)
+ ptr[offset] |= ((*(p+count+3) >> (30-3*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0x8)
+ ptr[offset] |= ((*(p+count+3) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xa)
+ ptr[offset] |= ((*(p+count+3) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xc)
+ ptr[offset] |= ((*(p+count+3) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0xc && old == 0xf)
+ ptr[offset] |= ((*(p+count+3) >> (30-7*2)) & 0x3) << bit2;
+
+ if(new == 0xf && old == 0)
+ ptr[offset] |= ((*(p+count+3) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x2)
+ ptr[offset] |= ((*(p+count+3) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x5)
+ ptr[offset] |= ((*(p+count+3) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x7)
+ ptr[offset] |= ((*(p+count+3) >> (30-11*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x8)
+ ptr[offset] |= ((*(p+count+3) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xa)
+ ptr[offset] |= ((*(p+count+3) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xc)
+ ptr[offset] |= ((*(p+count+3) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xf)
+ ptr[offset] |= ((*(p+count+3) >> (30-15*2)) & 0x3) << bit2;
+
+
+
+ }
+ }
+
+
+}
+
+void fill_4level_gray(int max_frm,unsigned int *p)
+{
+
+ int i,j,old,new,offset, bit2;
+ int index_per_frame = (1 << 8);
+ int count; // count is offset of array
+ unsigned int *ptr = (unsigned int *)lcd_palette;
+ memset(lcd_palette, 0x0, 4096);
+ // record the totally multiple of 16frames
+
+ if( max_frm%16 != 0)
+ totally_time = (1+max_frm/16);
+ else
+ totally_time = max_frm/16;
+
+
+ for (j = 0; j < max_frm; j++) {
+ count = j;
+ for(i=0;i<index_per_frame;i++){
+ old = (i >> 4) & 0xf;
+ new = i & 0xf;
+ offset = (j * index_per_frame + i)*2/32;
+ bit2 = ((j * index_per_frame + i)%16)*2;
+
+ if(new == 0 && old == 0)
+ ptr[offset] |= ((*(p+count) >> (30-0*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-1*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-2*2)) & 0x3) << bit2;
+ if(new == 0 && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-3*2)) & 0x3) << bit2;
+
+ if(new == 0x5 && old == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-4*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-5*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-6*2)) & 0x3) << bit2;
+ if(new == 0x5 && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-7*2)) & 0x3) << bit2;
+
+
+ if(new == 0xa && old == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-8*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-9*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-10*2)) & 0x3) << bit2;
+ if(new == 0xa && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-11*2)) & 0x3) << bit2;
+
+
+ if(new == 0xf && old == 0x0)
+ ptr[offset] |= ((*(p+count) >> (30-12*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0x5)
+ ptr[offset] |= ((*(p+count) >> (30-13*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xa)
+ ptr[offset] |= ((*(p+count) >> (30-14*2)) & 0x3) << bit2;
+ if(new == 0xf && old == 0xf)
+ ptr[offset] |= ((*(p+count) >> (30-15*2)) & 0x3) << bit2;
+ }
+ }
+
+}
+
+
+
+void fill_gu_palette(void)
+{
+
+ int max_frm ;
+ unsigned int *p;
+
+ get_temp();
+ D("%s: temp(%d) gray level=%d. \n",__func__,epd_temp_level,epd_gray_level);
+
+ if(epd_gray_level == GRAY_LEVEL_4)
+ {
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp0_gu; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp1_gu; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp2_gu; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform_temp3_gu;
+
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_4level_gray(max_frm,p);
+ }
+
+ if(epd_gray_level == GRAY_LEVEL_8)
+ {
+
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp0_gu; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp1_gu; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp2_gu; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform8_temp3_gu;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_8level_gray(max_frm,p);
+ }
+ if(epd_gray_level == GRAY_LEVEL_16)
+ {
+ // add 16level gray support
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp0_gu; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp1_gu; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp2_gu; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform16_temp3_gu;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_16level_gray(max_frm,p);
+
+ }
+ dma_cache_wback((unsigned int)(lcd_palette), 4096);
+// printpalette((unsigned short *)((unsigned int)lcd_palette | 0xa0000000), 2048);
+
+}
+void fill_gc_palette(void)
+{
+
+ int max_frm ;
+ unsigned int *p;
+
+ get_temp();
+ D("%s: temp%d gray level=%d. \n",__func__,epd_temp_level,epd_gray_level);
+
+ if(epd_gray_level == GRAY_LEVEL_4)
+ {
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp0_gc; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp1_gc; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform_temp2_gc; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform_temp3_gc;
+
+
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_4level_gray(max_frm,p);
+ }
+
+ if(epd_gray_level == GRAY_LEVEL_8)
+ {
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp0_gc; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp1_gc; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform8_temp2_gc; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform8_temp3_gc;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_8level_gray(max_frm,p);
+ }
+ if(epd_gray_level == GRAY_LEVEL_16)
+ {
+ // add 16level gray support
+
+ if (epd_temp_level == TEMP_LOW_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp0_gc; // give waveform_temp2_Du to p
+
+
+ }
+ else if (epd_temp_level == TEMP_HIGH_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp1_gc; // give waveform_temp2_Du to p
+
+ }
+ else if (epd_temp_level == TEMP_HIGHER_LEVEL)
+ {
+
+ max_frm = 48;
+ p = (unsigned int *)&waveform16_temp2_gc; // give waveform_temp2_Du to p
+
+ }
+
+ else if (epd_temp_level == TEMP_HIGHEST_LEVEL)
+ {
+
+ max_frm = 42;
+ p = (unsigned int *)&waveform16_temp3_gc;
+ }
+ else{
+ printk("Invalid temperature level. \n");
+ return;
+ }
+
+ fill_16level_gray(max_frm,p);
+
+ }
+ dma_cache_wback((unsigned int)(lcd_palette), 4096);
+// printpalette((unsigned short *)((unsigned int)lcd_palette | 0xa0000000), 2048);
+
+
+}
+
+void handwriting_palette(void)
+{
+
+ int max_frm ;
+ unsigned int *p;
+ D("%s: temp(%d) gray level=%d. \n",__func__,epd_temp_level,epd_gray_level);
+ max_frm = 2;
+ p = (unsigned int *)&waveform_handwriting;
+ fill_du_4level_gray(max_frm,p);
+ dma_cache_wback((unsigned int)(lcd_palette), 4096);
+// printpalette((unsigned short *)((unsigned int)lcd_palette | 0xa0000000), 64);
+
+}
+
+int set_epd_mod(unsigned long arg)
+{
+
+ epd_mod_level = *(unsigned long *)arg;
+
+ if (epd_mod_level == EPD_MOD_INIT )
+ fill_init_palette();
+ else if (epd_mod_level == EPD_MOD_DU )
+ fill_du_palette();
+ else if (epd_mod_level == EPD_MOD_GU )
+ fill_gu_palette();
+ else if (epd_mod_level == EPD_MOD_GC )
+ fill_gc_palette();
+ else
+ return MOD_INVALID;
+ return EPD_SUCCESS;
+
+
+}
diff --git a/fs/yaffs2/devextras.h b/fs/yaffs2/devextras.h
index 9635c7a7381..a02c614da28 100644
--- a/fs/yaffs2/devextras.h
+++ b/fs/yaffs2/devextras.h
@@ -32,9 +32,13 @@
/* User space defines */
+#if 0
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned __u32;
+#else
+#include <mtd/types.h>
+#endif
/*
* Simple doubly linked list implementation.
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
index 606adb4795d..96a19f31483 100644
--- a/include/linux/i2c-dev.h
+++ b/include/linux/i2c-dev.h
@@ -53,6 +53,8 @@
#define I2C_SET_SUB_ADDRESS 0x0730
#define I2C_SET_CLOCK 0x0731
+extern void i2c_jz_setclk(struct i2c_client *client,unsigned long i2cclk);
+
/* This is the structure as used in the I2C_SMBUS ioctl call */
struct i2c_smbus_ioctl_data {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 58af5dc4fc2..8c2102d1720 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -50,6 +50,8 @@ struct i2c_board_info;
#define EEPROM_DEVICE_NUMBER 0x50 /*eeprom device number.20091027*/
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+
+extern void i2c_jz_setclk(struct i2c_client *client,unsigned long i2cclk);
/*
* The master routines are the ones normally used to transmit data to devices
* on a bus (or read from them). Apart from two basic transfer functions to
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 05211774462..413510d6a4d 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -30,6 +30,7 @@
#define HPET_MINOR 228
#define FUSE_MINOR 229
#define KVM_MINOR 232
+#define CIM_MINOR 234 /* JZ CIM for multimedia */
#define MISC_DYNAMIC_MINOR 255
struct device;
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index 1eac18bfffe..cdc46a3627f 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -5,7 +5,7 @@
#ifndef __MTD_ABI_H__
#define __MTD_ABI_H__
-#include <linux/types.h>
+#include <mtd/types.h>
#ifndef __KERNEL__
#define __user
diff --git a/include/mtd/types.h b/include/mtd/types.h
new file mode 100644
index 00000000000..2dd147f519d
--- /dev/null
+++ b/include/mtd/types.h
@@ -0,0 +1,100 @@
+/*
+ * 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) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#else
+
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#endif
+
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG _MIPS_SZLONG
+
+#ifndef __ASSEMBLY__
+
+
+typedef __signed char s8;
+typedef unsigned char u8;
+
+typedef __signed short s16;
+typedef unsigned short u16;
+
+typedef __signed int s32;
+typedef unsigned int u32;
+
+#if (_MIPS_SZLONG == 64)
+
+typedef __signed__ long s64;
+typedef unsigned long u64;
+
+#else
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+#endif
+
+#endif
+
+#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \
+ || defined(CONFIG_64BIT)
+typedef u64 dma_addr_t;
+#else
+typedef u32 dma_addr_t;
+#endif
+typedef u64 dma64_addr_t;
+
+/*
+ * Don't use phys_t. You've been warned.
+ */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+typedef unsigned long long phys_t;
+#else
+typedef unsigned long phys_t;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index cc4ecb0b2ec..0cb0cb100d0 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -17,7 +17,7 @@ config SOUND_JZ_I2S
depends on JZSOC
help
Say Y here if you have want to select the on-chip I2S driver
- on Jz4730/Jz4740/Jz5730.
+ on Jz4730/Jz4740/Jz5730/jz4760.
config SOUND_JZ_PCM
bool "Jz On-Chip PCM driver"
@@ -48,6 +48,12 @@ config I2S_DLV
help
Answer Y if you have an internal I2S codec on Jz4750 or Jz4750d, jz4750L.
+config I2S_DLV_4760
+ bool "Internal On-Chip codec on Jz4760"
+ depends on SOC_JZ4760
+ help
+ Answer Y if you have an internal I2S codec on Jz4760.
+
endchoice
choice
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 06bc7567b8a..b31f889fdbb 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SOUND_JZ_AC97) += jz_ac97.o ac97_codec.o
obj-$(CONFIG_I2S_AK4642EN) += ak4642en.o
obj-$(CONFIG_I2S_ICODEC) += jzcodec.o jz_i2s.o
obj-$(CONFIG_I2S_DLV) += jzdlv.o jz_i2s.o
+obj-$(CONFIG_I2S_DLV_4760) += jz4760_dlv.o jz4760_i2s.o
obj-$(CONFIG_SOUND_JZ_PCM) += jz_pcm_tlv320aic1106_dma.o
obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
diff --git a/sound/oss/jz4760_dlv.c b/sound/oss/jz4760_dlv.c
new file mode 100644
index 00000000000..a8b2b89bf85
--- /dev/null
+++ b/sound/oss/jz4760_dlv.c
@@ -0,0 +1,1009 @@
+/*
+ * Linux/sound/oss/jz_dlv.c
+ *
+ * DLV CODEC driver for Ingenic Jz4750 MIPS processor
+ *
+ * 2009-12-xx Steven <dsqiu@ingenic.cn>
+ * 2010-01-xx Jason <xwang@ingenic.cn>
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <linux/proc_fs.h>
+#include <linux/soundcard.h>
+#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <asm/hardirq.h>
+#include <asm/jzsoc.h>
+
+#include "sound_config.h"
+
+#include "jz_codec.h"
+#include "jz4760_dlv.h"
+#include "jz_i2s_dbg.h"
+
+#define HP_SENSE_DETECT 0
+#define REPLAY 1
+#define RECORD 2
+
+#define POWER_ON 0
+#define POWER_OFF 1
+
+#define switch_SB_DAC(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_DAC); \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_ADC); \
+} while (0)
+
+#define switch_SB_LINE_OUT(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_LOUT); \
+} while (0)
+
+#define switch_SB_OUT(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_HP); \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_LOUT); \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_BTL); \
+} while (0)
+
+#define switch_SB_MIX(pwrstat) \
+do { \
+ /* dlv_write_reg_bit(5, pwrstat, 5);*/ \
+} while (0)
+
+#define switch_SB_ADC(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR2, pwrstat, PMR2_SB_ADC); \
+} while (0)
+
+#define switch_SB_MIC1(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR1, pwrstat, PMR1_SB_MIC1); \
+ dlv_write_reg_bit(DLV_REG_PMR1, pwrstat, PMR1_SB_MIC2); \
+ dlv_write_reg_bit(DLV_REG_PMR1, pwrstat, PMR1_SB_MICBIAS);\
+ \
+} while (0)
+
+#define switch_SB_LINE_IN(pwrstat) \
+do { \
+ dlv_write_reg_bit(DLV_REG_PMR1, pwrstat, PMR1_SB_LINE); \
+ dlv_write_reg_bit(DLV_REG_PMR1, pwrstat, PMR1_SB_MICBIAS);\
+ \
+} while (0)
+
+/*
+#define ENTER() printk("Enter: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__)
+#define LEAVE() printk("Leave: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__)
+*/
+
+#ifdef IOC_DEBUG
+static dlv_print_ioc_cmd(int cmd)
+{
+ char *dlv_ioc_cmd[] = {
+ "CODEC_SET_MODE", "CODEC_CLEAR_MODE", "CODEC_SET_GPIO_PIN",
+ "CODEC_EACH_TIME_INIT", "CODEC_SET_STARTUP_PARAM", "CODEC_SET_VOLUME_TABLE",
+ "CODEC_SET_RECORD", "CODEC_SET_REPLAY", "CODEC_SET_REPLAY_RECORD",
+ "CODEC_TURN_ON", "CODEC_TURN_OFF", "CODEC_SET_REPLAY_SPEED",
+ "CODEC_RESET", "CODEC_GET_MIXER_OLD_INFO", "CODEC_GET_MIXER_INFO",
+ "CODEC_SET_BASS", "CODEC_SET_VOLUME", "CODEC_SET_MIC",
+ "CODEC_SET_LINE", "CODEC_I2S_RESUME", "CODEC_I2S_SUSPEND",
+ "CODEC_PIN_INIT", "CODEC_SET_SOME_FUNC", "CODEC_CLEAR_RECORD",
+ "CODEC_CLEAR_REPLAY", "CODEC_SET_REPLAY_HP_OR_SPKR", "CODEC_SET_DIRECT_MODE",
+ "CODEC_CLEAR_DIRECT_MODE", "CODEC_SET_LINEIN2HP", "CODEC_CLEAR_LINEIN2HP",
+ "CODEC_ANTI_POP", "CODEC_TURN_REPLAY", "CODEC_SET_REPLAY_CHANNEL",
+ "CODEC_SET_REPLAY_FORMAT", "CODEC_SET_RECORD_CHANNEL", "CODEC_SET_RECORD_FORMAT",
+ "CODEC_SET_RECORD_SPEED", "CODEC_DAC_MUTE"
+ };
+
+ if (cmd >= (sizeof(dlv_ioc_cmd) / sizeof(dlv_ioc_cmd[0]))) {
+ printk("%s: Unkown command !\n", __FUNCTION__);
+ } else {
+ printk("IOC CMD NAME = %s\n", dlv_ioc_cmd[cmd - 1]);
+ }
+}
+#endif
+
+/**
+ * CODEC read register
+ *
+ * addr: address of register
+ * return: value of register
+ */
+static inline int dlv_read_reg(int addr)
+{
+ volatile int reg;
+ while (__icdc_rgwr_ready()) {
+ ;//nothing...
+ }
+ __icdc_set_addr(addr);
+ reg = __icdc_get_value();
+ reg = __icdc_get_value();
+ reg = __icdc_get_value();
+ reg = __icdc_get_value();
+ reg = __icdc_get_value();
+ return __icdc_get_value();
+}
+
+/**
+ * CODEC write register
+ *
+ * addr: address of register
+ * val: value to set
+ */
+void dlv_write_reg(int addr, int val)
+{
+ volatile int reg;
+ while (__icdc_rgwr_ready()) {
+ ;//nothing...
+ }
+ REG_ICDC_RGADW = ((addr << ICDC_RGADW_RGADDR_BIT) | val);
+ __icdc_set_rgwr();
+ reg = __icdc_rgwr_ready();
+ reg = __icdc_rgwr_ready();
+ reg = __icdc_rgwr_ready();
+ reg = __icdc_rgwr_ready();
+ reg = __icdc_rgwr_ready();
+ reg = __icdc_rgwr_ready();
+ while (__icdc_rgwr_ready()) {
+ ;//nothing...
+ }
+}
+
+/**
+ * CODEC write a bit of a register
+ *
+ * addr: address of register
+ * bitval: bit value to modifiy
+ * mask_bit: indicate which bit will be modifiy
+ */
+static int dlv_write_reg_bit(int addr, int bitval, int mask_bit)
+{
+ int val = dlv_read_reg(addr);
+
+ if (bitval)
+ val |= (1 << mask_bit);
+ else
+ val &= ~(1 << mask_bit);
+ dlv_write_reg(addr, val);
+
+ return 1;
+}
+
+/*
+ * DLV CODEC operations routines
+ */
+
+static void dlv_each_time_init(void)
+{
+ ENTER();
+ __i2s_disable();
+ __i2s_as_slave();
+ __aic_internal_codec();
+ //__i2s_set_oss_sample_size(16);
+ //__i2s_set_iss_sample_size(16);
+ LEAVE();
+}
+
+static void dlv_set_mode(void)
+{
+ ENTER();
+
+ //dlv_write_reg(8, 0x2f);
+ //dlv_write_reg(9, 0xff);
+ dlv_write_reg(DLV_REG_ICR, 0x0f);
+ dlv_write_reg(DLV_REG_IFR, 0xff); // ???
+
+ schedule_timeout(2);
+
+ dlv_write_reg_bit(6, 0, 1);//PMR2.SB->0
+ dlv_write_reg_bit(6, 0, 0);//PMR2.SB->0
+
+// dlv_write_reg_bit(1, 0, 3);//PMR2.SB->0
+
+ dlv_write_reg_bit(5, 0, 4);//SB_ADC->1
+// set_record_mic_input_audio_with_audio_data_replay();
+// reset_dlv_codec();
+ LEAVE();
+}
+
+static void dlv_reset(void)
+{
+ ENTER();
+ /* reset DLV codec. from hibernate mode to sleep mode */
+ //dlv_write_reg(0, 0xf);
+ //dlv_write_reg_bit(6, 0, 0);
+ //dlv_write_reg_bit(6, 0, 1);
+
+ //2010-01-31 Jason add
+ //dlv_write_reg(22, 0x40);//mic 1
+
+ dlv_write_reg_bit(DLV_REG_AICR, 1, AICR_DAC_SERIAL);
+ dlv_write_reg_bit(DLV_REG_AICR, 1, AICR_ADC_SERIAL);
+
+ /* reset DLV codec. from hibernate mode to sleep mode */
+ dlv_write_reg(DLV_REG_AICR, 0xf);
+ dlv_write_reg_bit(DLV_REG_PMR1, 0, PMR1_SB);
+ dlv_write_reg_bit(DLV_REG_PMR1, 0, PMR1_SB_SLEEP);
+
+ schedule_timeout(30);
+
+
+
+ dlv_write_reg(DLV_REG_CR3, 1 << CR3_MICSTEREO);//mic 1
+
+ schedule_timeout(20);
+
+ dlv_write_reg_bit(DLV_REG_PMR1, 0, PMR1_SB_AIP);
+
+ //dlv_write_reg_bit(5, 0, 7);//PMR1.SB_DAC->0
+ //dlv_write_reg_bit(5, 0, 4);//PMR1.SB_ADC->0
+ dlv_write_reg_bit(DLV_REG_PMR2, 0, PMR2_SB_DAC);
+ dlv_write_reg_bit(DLV_REG_PMR2, 0, PMR2_SB_ADC);
+
+
+ schedule_timeout(2); ;//wait for stability
+ LEAVE();
+}
+
+static int dlv_set_startup_param(void)
+{
+ ENTER();
+ LEAVE();
+// __i2s_disable_transmit_intr();
+// __i2s_disable_receive_intr();
+ return 1;
+}
+
+/**
+ * Set audio replay
+ */
+static void dlv_set_replay(void)
+{
+ ENTER();
+
+// dump_dlv_regs("enter dlv_set_replay");
+
+ dlv_write_reg_bit(DLV_REG_CR1, 0, CR1_HP_MUTE);
+ dlv_write_reg_bit(DLV_REG_PMR1, 1, PMR1_SB_BYPASS);
+
+ // OUTSEL <-- 11b
+ dlv_write_reg_bit(DLV_REG_CR1, 1, CR1_OUTSEL0);
+ dlv_write_reg_bit(DLV_REG_CR1, 1, CR1_OUTSEL1);
+
+ // Disable mute
+ dlv_write_reg_bit(DLV_REG_CR2, 0, CR2_DAC_MUTE);
+ dlv_write_reg_bit(DLV_REG_CR1, 0, CR1_LINEOUT_MUTE);
+ dlv_write_reg_bit(DLV_REG_CR1, 0, CR1_BTL_MUTE);
+
+ // NOMAD
+ dlv_write_reg_bit(DLV_REG_CR2, 1, CR2_NOMAD);
+
+// dump_dlv_regs("leave dlv_set_replay");
+ LEAVE();
+}
+
+#if 0
+/* set Record MIC input audio with Audio data replay (full duplex) */
+static void set_record_mic_input_audio_with_audio_data_replay(void)
+{
+ ENTER();
+ printk("when run here ?????\n");
+ dlv_write_reg_bit(23, 0, 7);//AGC1.AGC_EN->0
+ dlv_write_reg(9, 0xff);
+ //dlv_write_reg(8, 0x30);
+ dlv_write_reg(8, 0x20);
+ dlv_write_reg_bit(1, 0, 4);//CR1.HP_DIS->0
+ dlv_write_reg_bit(5, 1, 3);//PMR1.SB_LIN->1
+ dlv_write_reg_bit(5, 1, 0);//PMR1.SB_IND->1
+
+ dlv_write_reg_bit(22, 0, 7);//CR3.SB_MIC->0
+
+ dlv_write_reg_bit(1, 0, 7);//CR1.SB_MICBIAS->0
+
+ dlv_write_reg_bit(1, 1, 3);//CR1.DACSEL->1
+ dlv_write_reg_bit(5, 0, 5);//PMR1.SB_MIX->0
+ LEAVE();
+}
+
+/* unset Record MIC input audio with Audio data replay (full duplex) */
+static void unset_record_mic_input_audio_with_audio_data_replay(void)
+{
+ ENTER();
+ /* ADC path */
+ printk("@@@ %s", __FUNCTION__);
+ dlv_write_reg_bit(5, 1, 4);//SB_ADC->1
+ dlv_write_reg_bit(1, 1, 7);//CR1.SB_MICBIAS->1
+ //dlv_write_reg_bit(1, 1, 6);//CR1.MONO->1
+ dlv_write_reg(22, 0xc0);//CR3.SB_MIC1->1
+// dlv_write_reg_bit(5, 1, 7);//SB_DAC->1
+ dlv_write_reg_bit(5, 1, 5);//SB_MIX->1
+
+ // 2009-01-20 Jason marked
+// dlv_write_reg_bit(6, 1, 0);//SB_SLEEP->1
+// dlv_write_reg_bit(6, 1, 1);//SB->1
+ LEAVE();
+}
+
+/* set Record LINE input audio with Audio data replay (full duplex for linein) */
+static void set_record_line_input_audio_with_audio_data_replay(void)
+{
+ ENTER();
+ dlv_write_reg(9, 0xff);
+ //dlv_write_reg(8, 0x30);
+ dlv_write_reg(8, 0x20);
+ dlv_write_reg_bit(1, 0, 4);//CR1.HP_DIS->0
+ dlv_write_reg_bit(5, 0, 3);//PMR1.SB_LIN->0
+ dlv_write_reg_bit(5, 1, 0);//PMR1.SB_IND->1
+ dlv_write_reg_bit(1, 1, 7);//CR1.SB_MICBIAS->1
+ //dlv_write_reg_bit(22, 1, 7);//CR3.SB_MIC->1
+ dlv_write_reg_bit(1, 1, 3);//CR1.DACSEL->1
+ dlv_write_reg_bit(5, 0, 5);//PMR1.SB_MIX->0
+
+ dlv_write_reg(22, 0xc6);//line in 1
+ dlv_write_reg_bit(23, 0, 7);//AGC1.AGC_EN->0
+ dlv_write_reg_bit(1, 0, 2);//CR1.BYPASS->0
+ dlv_write_reg_bit(5, 0, 5);//PMR1.SB_MIX->0
+ LEAVE();
+}
+
+//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+/* unset Record LINE input audio with Audio data replay (full duplex for linein) */
+static void unset_record_line_input_audio_with_audio_data_replay(void)
+{
+ ENTER();
+ /* ADC path */
+ printk("@@@ %s", __FUNCTION__);
+
+ dlv_write_reg_bit(5, 1, 4);//SB_ADC->1
+ dlv_write_reg_bit(1, 1, 7);//CR1.SB_MICBIAS->1
+ //dlv_write_reg_bit(1, 1, 6);//CR1.MONO->1
+ dlv_write_reg(22, 0xc0);//CR3.SB_MIC1->1
+// dlv_write_reg_bit(5, 1, 7);//SB_DAC->1
+ dlv_write_reg_bit(5, 1, 5);//SB_MIX->1
+
+ // 2010-01-20 Jason masked
+// dlv_write_reg_bit(6, 1, 0);//SB_SLEEP->1
+// dlv_write_reg_bit(6, 1, 1);//SB->1
+ LEAVE();
+}
+
+#endif
+
+static int dlv_set_replay_speed(int rate)
+{
+ int speed = 0, val;
+
+ int mrate[MAX_RATE_COUNT] = {
+ 96000, 48000, 44100, 32000, 24000,
+ 22050, 16000, 12000, 11025, 8000
+ };
+
+ for (val = 0; val < MAX_RATE_COUNT; val++) {
+ if (rate >= mrate[val]) {
+ speed = val;
+ break;
+ }
+ }
+ if (rate < mrate[MAX_RATE_COUNT - 1]) {
+ speed = MAX_RATE_COUNT - 1;
+ }
+ val = dlv_read_reg(DLV_REG_CCR2);
+ val &= 0xf;
+ val = (speed << 4) | val;
+ dlv_write_reg(DLV_REG_CCR2, val);
+ return mrate[speed];
+}
+
+static int dlv_set_record_speed(int rate)
+{
+ int speed = 0, val;
+
+ int mrate[MAX_RATE_COUNT] = {
+ 96000, 48000, 44100, 32000, 24000,
+ 22050, 16000, 12000, 11025, 8000
+ };
+
+ for (val = 0; val < MAX_RATE_COUNT; val++) {
+ if (rate >= mrate[val]) {
+ speed = val;
+ break;
+ }
+ }
+ if (rate < mrate[MAX_RATE_COUNT - 1]) {
+ speed = MAX_RATE_COUNT - 1;
+ }
+ val = dlv_read_reg(DLV_REG_CCR2);
+ val &= 0xf0;
+ val = speed | val;
+ dlv_write_reg(DLV_REG_CCR2, val);
+
+ return mrate[speed];
+}
+
+#if 0
+static void reset_jzcodec(void)
+{
+ ;
+}
+#endif
+
+static void dlv_get_mixer_old_info(mixer_info *info)
+{
+ strncpy(info->id, "JZDLV", sizeof(info->id));
+ strncpy(info->name, "Jz internal codec dlv on jz4750", sizeof(info->name));
+}
+
+static void dlv_get_mixer_info(mixer_info *old_info)
+{
+ strncpy(old_info->id, "JZDLV", sizeof(old_info->id));
+ strncpy(old_info->name, "Jz internal codec dlv on jz4750", sizeof(old_info->name));
+}
+
+static void dlv_set_mic(int val)
+{
+ int cur_vol;
+
+ ENTER();
+
+ printk("~~~~ dlv_set_mic\n");
+
+ /* set GIM */
+
+ /* set gain */
+ cur_vol = 31 * val / 100;
+ cur_vol = 0x80 | cur_vol;
+ dlv_write_reg(DLV_REG_GCR8, cur_vol);//GIL,GIR
+
+ LEAVE();
+}
+
+static void dlv_set_line(int val)
+{
+ int cur_vol;
+
+ ENTER();
+ /* set gain */
+ cur_vol = 31 * val / 100;
+ cur_vol &= 0x1f;
+ /* ???
+ dlv_write_reg(11, cur_vol);//GO1L
+ dlv_write_reg(12, cur_vol);//GO1R
+ */
+ LEAVE();
+}
+
+static void dlv_set_volume(int val)
+{
+ unsigned long cur_vol;
+
+ ENTER();
+
+ /* To protect circut and to avoid shutting down CODEC,
+ * valume must less then 60% of the max
+ */
+
+ if (val > 60) {
+ val = 60;
+ }
+
+
+ //val = 90;
+ cur_vol = 31 * (100 - val) / 100;
+
+ dlv_write_reg(DLV_REG_GCR1, 0x80 | cur_vol);
+
+ DPRINT_CODEC("$$$$$ val = %d, DLV_REG_CGR1 = 0x%02x\n",
+ val, dlv_read_reg(DLV_REG_GCR1));
+
+ LEAVE();
+}
+
+/*
+ * Base on set_record_mic_input_audio_without_playback()
+ */
+static void dlv_set_record(void)
+{
+ ENTER();
+
+// dump_dlv_regs("enter dlv_set_record");
+
+ /* ADC path for MIC IN */
+
+ dlv_write_reg_bit(DLV_REG_AGC1, 0, AGC1_AGCEN);//AGC1.AGC_EN->0
+
+ dlv_write_reg_bit(DLV_REG_PMR1, 0, PMR1_SB);
+ dlv_write_reg_bit(DLV_REG_PMR1, 0, PMR1_SB_SLEEP);
+
+ switch_SB_ADC(POWER_ON);
+
+ /* MIC 1*/
+ dlv_write_reg_bit(DLV_REG_PMR1, POWER_ON, PMR1_SB_MIC1);
+
+ /* MIC 2 */
+ //dlv_write_reg_bit(DLV_REG_PMR1, POWER_ON, PMR1_SB_MIC2);
+
+ dlv_write_reg_bit(DLV_REG_PMR1, POWER_ON, PMR1_SB_MICBIAS);
+
+ switch_SB_LINE_IN(POWER_OFF);
+
+ schedule_timeout(2);
+
+ // Record mono
+ dlv_write_reg(DLV_REG_CR3, 0);
+ dlv_write_reg_bit(DLV_REG_CR3, 1, CR3_MICDIFF);
+
+ /* MIC 1 */
+ dlv_write_reg_bit(DLV_REG_CR3, 0, CR3_INSEL1);
+ dlv_write_reg_bit(DLV_REG_CR3, 0, CR3_INSEL0);
+
+ /* MIC 2 */
+ //dlv_write_reg_bit(DLV_REG_CR3, 0, CR3_INSEL1);
+ //dlv_write_reg_bit(DLV_REG_CR3, 1, CR3_INSEL0);
+
+ dlv_write_reg_bit(DLV_REG_CR4, 0, 0);
+
+ dlv_write_reg_bit(DLV_REG_PMR1, 1, PMR1_SB_BYPASS);
+
+ // GIM
+// dlv_write_reg(DLV_REG_GCR7, 0x3f);
+ dlv_write_reg(DLV_REG_GCR7, 0x0);
+
+ // GIDR
+// dlv_write_reg(DLV_REG_GCR8, 0xff);
+ dlv_write_reg(DLV_REG_GCR8, 0x0);
+ // GID
+// dlv_write_reg(DLV_REG_GCR9, 0x1f);
+ dlv_write_reg(DLV_REG_GCR9, 0x0);
+
+
+
+// dump_dlv_regs("leave dlv_set_record");
+
+
+ LEAVE();
+}
+
+static void dlv_set_replay_recode(int val)
+{
+ ENTER();
+ if (val == USE_LINEIN) {
+ /* Record LINE input audio with Audio data replay (full duplex for linein) */
+ /* codec_test_line */
+ printk("use line in ???\n");
+// set_record_line_input_audio_with_audio_data_replay();
+ }
+ if (val == USE_MIC) {
+ /* Record MIC input audio with Audio data replay (full duplex) */
+ /* codec_test_mic */
+// set_record_mic_input_audio_with_audio_data_replay();
+ }
+ LEAVE();
+}
+
+static void dlv_anti_pop(int mode)
+{
+// dump_dlv_regs("++++++++++++++");
+ switch(mode) {
+ case CODEC_WRMODE:
+ //set SB_ADC or SB_DAC
+ //dlv_write_reg_bit(5, 0, 6);//PMR1.SB_OUT->0
+ switch_SB_OUT(POWER_ON);
+
+ //2010-01-31 Jason add
+ //dlv_write_reg(22, 0x40);//mic 1
+
+ //2010-01-31 Jason add
+ //dlv_write_reg(1, 0x04);
+
+ schedule_timeout(28); //280 ms
+ break;
+ case CODEC_RMODE:
+ printk("dlv_anti_pop CODEC_WMODE\n");
+ switch_SB_MIC1(POWER_ON);
+ break;
+ case CODEC_WMODE:
+ //dlv_write_reg_bit(5, 0, 6);//PMR1.SB_OUT->0
+ printk("dlv_anti_pop CODEC_WMODE\n");
+ switch_SB_OUT(POWER_ON);
+
+ schedule_timeout(28); //280 ms
+
+ // 2010-01-31 Jason marked
+ //dlv_write_reg_bit(5, 1, 4);//SB_ADC->1
+
+ //2010-01-31 Jason add
+ //dlv_write_reg(1, 0x04);
+
+ //dlv_write_reg_bit(5, 0, 7);//PMR1.SB_OUT->0
+ switch_SB_DAC(POWER_ON);
+
+ break;
+ }
+// dump_dlv_regs("--------------");
+}
+
+static void dlv_turn_replay(int mode)
+{
+ ENTER();
+ if (mode == USE_LINEIN) {
+ printk("use line in ?????????\n");
+ //unset_record_line_input_audio_with_audio_data_replay();
+ }
+ if (mode == USE_MIC) {
+ //unset_record_mic_input_audio_with_audio_data_replay();
+ }
+ LEAVE();
+}
+
+static void dlv_turn_off(int mode)
+{
+ ENTER();
+
+ if ((mode & REPLAY) && (mode & RECORD)) {
+ printk("Close DLV !!!\n");
+// dlv_write_reg_bit(1, 1, 5);//DAC_MUTE->1
+ schedule_timeout(20);
+
+ // 2010-01-31 Jason marked
+ //dlv_write_reg_bit(5, 1, 6);//SB_OUT->1
+
+ dlv_write_reg(9, 0xff);
+ dlv_write_reg(8, 0x2f);
+ } else if (mode & REPLAY) {
+ //nothing
+ } else if (mode & RECORD) {
+ printk("Close RECORD\n");
+// dlv_write_reg(4, 0x20);
+ }
+
+ LEAVE();
+}
+
+static int dlv_set_channel(int ch)
+{
+ if(ch > 2) ch = 2;
+ if(ch < 1) ch = 1;
+ switch (ch) {
+ case 1:
+ dlv_write_reg_bit(DLV_REG_CR2, 1, CR2_MONO);// MONO->1 for Mono
+ break;
+ case 2:
+ dlv_write_reg_bit(DLV_REG_CR2, 0, CR2_MONO);// MONO->0 for Stereo
+ break;
+ }
+ return ch;
+}
+
+static int dlv_set_data_width(unsigned int mode, unsigned int width)
+{
+ unsigned char cr2 = dlv_read_reg(DLV_REG_AICR);
+ unsigned char savecr2 = cr2;
+ int supported_width[4] = {16, 18, 20, 24};
+ int i;
+
+ for (i = 0; i < (sizeof(supported_width) / sizeof(supported_width[0])); i++) {
+ if (supported_width[i] <= width) {
+ break;
+ }
+ }
+
+ if (i == (sizeof(supported_width) / sizeof(supported_width[0]))) {
+ // For 8 bit width mode, handle it as 16 bit
+ if (width == 8) {
+ i = 0;
+ } else {
+ return -1;
+ }
+ }
+
+ //printk("mode = %d, width = %d, selected %d\n", mode, width, i);
+
+ switch (mode) {
+ case RECORD:
+ cr2 &= ~(3 << 4);
+ cr2 |= (i << 4);
+ break;
+ case REPLAY:
+ cr2 &= ~(3 << 6);
+ cr2 |= (i << 6);
+ break;
+ }
+
+ if (cr2 != savecr2) {
+ dlv_write_reg(DLV_REG_AICR, cr2);
+ }
+
+ printk("set cr2 = %x, %x\n", cr2, savecr2);
+
+ if (width == 8) {
+ return 8;
+ } else {
+ return supported_width[i];
+ }
+}
+
+static int dlv_mute(int val)
+{
+ return dlv_write_reg_bit(DLV_REG_CR2, val ? 1 : 0, CR2_DAC_MUTE);
+}
+
+void dump_dlv_regs(const char * str)
+{
+ unsigned int i;
+ unsigned char data;
+ printk("codec register dump, %s:\n", str);
+ for (i = 0; i < 32; i++) {
+ data = dlv_read_reg(i);
+ printk("address = 0x%02x, data = 0x%02x\n", i, data);
+ }
+}
+
+static int jzdlv_ioctl(void *context, unsigned int cmd, unsigned long arg)
+{
+ ENTER();
+ DUMP_CODEC_REGS(__FUNCTION__);
+ DPRINT_CODEC("[dlv IOCTL]++++++++++++++++++++++++++++\n");
+ DPRINT_CODEC("%s cmd = %d, arg = %lu\n", __FUNCTION__, cmd, arg);
+ DPRINT_DLV_IOC_CMD(cmd);
+ DPRINT_CODEC("[dlv IOCTL]----------------------------\n");
+
+ switch (cmd) {
+ case CODEC_SET_MODE:
+ dlv_set_mode();
+ break;
+
+ case CODEC_SET_STARTUP_PARAM:
+ dlv_set_startup_param();
+ break;
+
+ case CODEC_SET_REPLAY:
+ dlv_set_replay();
+ break;
+
+ case CODEC_SET_RECORD:
+ dlv_set_record();
+ break;
+
+ case CODEC_SET_REPLAY_RECORD:
+ dlv_set_replay_recode(arg);
+ break;
+
+ case CODEC_SET_VOLUME:
+ dlv_set_volume(arg);
+ break;
+
+ case CODEC_SET_MIC:
+ dlv_set_mic(arg);
+ break;
+
+ case CODEC_SET_LINE:
+ dlv_set_line(arg);
+ break;
+
+ case CODEC_EACH_TIME_INIT:
+ dlv_each_time_init();
+ break;
+
+ case CODEC_RESET:
+ dlv_reset();
+ break;
+
+ case CODEC_ANTI_POP:
+ dlv_anti_pop(arg);
+ break;
+
+ case CODEC_TURN_REPLAY:
+ dlv_turn_replay(arg);
+ break;
+
+ case CODEC_TURN_OFF:
+ dlv_turn_off(arg);
+ break;
+
+ case CODEC_GET_MIXER_INFO:
+ dlv_get_mixer_info((mixer_info *)arg);
+ break;
+
+ case CODEC_GET_MIXER_OLD_INFO:
+ dlv_get_mixer_old_info((mixer_info *)arg);
+ break;
+
+ case CODEC_SET_REPLAY_SPEED:
+ return dlv_set_replay_speed(arg);
+
+ case CODEC_SET_RECORD_SPEED:
+ return dlv_set_record_speed(arg);
+
+ case CODEC_SET_RECORD_CHANNEL:
+ return arg;
+
+ case CODEC_SET_REPLAY_CHANNEL:
+ return dlv_set_channel(arg);
+
+ case CODEC_SET_RECORD_DATA_WIDTH:
+ return dlv_set_data_width(RECORD, arg);
+
+ case CODEC_SET_REPLAY_DATA_WIDTH:
+ return dlv_set_data_width(REPLAY, arg);
+
+ case CODEC_DAC_MUTE:
+ return dlv_mute(arg);
+
+ default:
+ printk("%s:%d no support\n", __FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ LEAVE();
+ return 0;
+}
+
+static struct work_struct dlv_work;
+
+/*
+ * work handler
+ *
+ * Mission:
+ * Restart CODEC after shut down by short circurt protection
+ */
+static void dlv_work_handle(struct work_struct *work)
+{
+
+ printk("CODEC: short circurt detected!\n");
+
+// dump_dlv_regs("IRQ ---------");
+
+ /* Renable SB OUT */
+ switch_SB_OUT(POWER_OFF);
+ mdelay(300);
+
+ while (!(dlv_read_reg(DLV_REG_IFR) & (1 << IFR_RDO))) {
+ ;/* nothing */
+ }
+
+ while (dlv_read_reg(DLV_REG_IFR) & (1 << IFR_SCMC)) {
+ dlv_write_reg(DLV_REG_IFR, 1 << IFR_SCMC);
+ }
+ switch_SB_OUT(POWER_ON);
+ mdelay(300);
+
+ while (!(dlv_read_reg(DLV_REG_IFR) & (1 << IFR_RUP))) {
+ ;/* nothing */
+ }
+
+ /* Enable SCMC and JACK EVENT interrupt ... */
+ dlv_write_reg(DLV_REG_ICR, 0x0f);
+}
+
+static spinlock_t dlv_irq_lock;
+
+static irqreturn_t dlv_codec_irq(int irq, void *dev_id)
+{
+// unsigned char dlv_icr;
+ unsigned char dlv_ifr;
+
+ spin_lock(dlv_irq_lock);
+
+ /* Clear interrupt flag */
+ dlv_ifr = dlv_read_reg(DLV_REG_IFR);
+ dlv_write_reg(DLV_REG_IFR, dlv_ifr);
+
+ /* Mask SCMC and JACK EVENT temporarily */
+ dlv_write_reg(DLV_REG_ICR, 0x3f);
+
+ REG_AIC_SR = 0x78; //???
+
+ /*
+ * Start handler when output short circuit has been detected
+ */
+ if (dlv_ifr & (1 << IFR_SCMC)) {
+ schedule_work(&dlv_work);
+ } else {
+ printk("Jack event ???\n");
+// dump_dlv_regs("irq -- maybe jack event");
+ }
+
+#if HP_SENSE_DETECT
+ /* Jack event detected */
+ if (dlv_ifr & (1 << IFR_JACK_EVENT)) {
+
+ printk("Jack event ! dlv_ifr = 0x%08x\n", dlv_ifr);
+
+ /* IFR_JACK indicate the status of jack:
+ * 1. The jack is pluged: plug event
+ * 2. The jack is not pluged: unplug event
+ */
+ switch_set_state(&data->sdev, dlv_ifr & (1 << IFR_JACK));
+ }
+#endif
+ spin_unlock(dlv_irq_lock);
+ return IRQ_HANDLED;
+}
+
+#if HP_SENSE_DETECT
+/*
+ * HP_SENSE switch
+ */
+#define gpio_to_irq(gpio) (IRQ_GPIO_0 + (gpio))
+
+struct hp_switch_data {
+ struct switch_dev sdev;
+ unsigned int gpio;
+ const char *name_on;
+ const char *name_off;
+ const char *state_on;
+ const char *state_off;
+};
+
+static int __devexit hp_switch_remove(struct platform_device *pdev)
+{
+ struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);
+
+ switch_dev_unregister(&switch_data->sdev);
+ kfree(switch_data);
+
+ return 0;
+}
+
+static struct platform_driver hp_switch_driver = {
+ .probe = hp_switch_probe,
+ .remove = __devexit_p(hp_switch_remove),
+ .driver = {
+ .name = "switch-gpio",
+ .owner = THIS_MODULE,
+ },
+};
+/* HP_SENSE switch end */
+#endif
+
+static int __init init_dlv(void)
+{
+ int retval;
+
+ cpm_start_clock(CGM_AIC);
+
+ spin_lock_init(&dlv_irq_lock);
+ INIT_WORK(&dlv_work, dlv_work_handle);
+ register_jz_codecs((void *)jzdlv_ioctl);
+
+#if HP_SENSE_DETECT
+ retval = platform_driver_register(&hp_switch_driver);
+ if (retval) {
+ printk("Could net register headphone sense switch\n");
+ return retval;
+ }
+#endif
+
+ dlv_reset();
+
+ retval = request_irq(IRQ_AIC, dlv_codec_irq, IRQF_DISABLED, "dlv_codec_irq", NULL);
+ if (retval) {
+ printk("Could not get aic codec irq %d\n", IRQ_AIC);
+ return retval;
+ }
+
+ return 0;
+}
+
+static void __exit cleanup_dlv(void)
+{
+ free_irq(IRQ_AIC, NULL);
+#if HP_SENSE_DETECT
+ platform_driver_unregister(&hp_switch_driver);
+#endif
+}
+
+module_init(init_dlv);
+module_exit(cleanup_dlv);
diff --git a/sound/oss/jz4760_dlv.h b/sound/oss/jz4760_dlv.h
new file mode 100644
index 00000000000..99d0f0017de
--- /dev/null
+++ b/sound/oss/jz4760_dlv.h
@@ -0,0 +1,126 @@
+/*
+ * Linux/sound/oss/jz4760_dlv.h
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ4760_DLV_H__
+#define __JZ4760_DLV_H__
+
+#define MAX_RATE_COUNT 10
+
+/* JZ4760 DLV CODEC registers number */
+#define DLV_REG_SR 0
+
+#define DLV_REG_AICR 1
+ #define AICR_DAC_SERIAL 3
+ #define AICR_ADC_SERIAL 2
+ #define AICR_DAC_I2S 1
+ #define AICR_ADC_I2S 0
+
+#define DLV_REG_CR1 2
+ #define CR1_LOAD 7
+ #define CR1_HP_MUTE 5
+ #define CR1_LINEOUT_MUTE 4
+ #define CR1_BTL_MUTE 3
+ #define CR1_OUTSEL1 1
+ #define CR1_OUTSEL0 0
+ #define CR1_OUTSEL_MASK 0x3
+
+#define DLV_REG_CR2 3
+ #define CR2_MONO 7
+ #define CR2_DAC_MUTE 5
+ #define CR2_NOMAD 1
+ #define CR2_DAC_RIGHT_ONLY 0
+
+#define DLV_REG_CR3 4
+ #define CR3_INSEL1 3
+ #define CR3_INSEL0 2
+ #define CR3_MICSTEREO 1
+ #define CR3_MICDIFF 0
+
+#define DLV_REG_CR4 5
+
+#define DLV_REG_CCR1 6
+
+#define DLV_REG_CCR2 7
+
+#define DLV_REG_PMR1 8
+ #define PMR1_SB 7
+ #define PMR1_SB_SLEEP 6
+ #define PMR1_SB_AIP 5
+ #define PMR1_SB_LINE 4
+ #define PMR1_SB_MIC1 3
+ #define PMR1_SB_MIC2 2
+ #define PMR1_SB_BYPASS 1
+ #define PMR1_SB_MICBIAS 0
+
+#define DLV_REG_PMR2 9
+ #define PMR2_SB_ADC 4
+ #define PMR2_SB_HP 3
+ #define PMR2_SB_BTL 2
+ #define PMR2_SB_LOUT 1
+ #define PMR2_SB_DAC 0
+
+#define DLV_REG_ICR 10
+ #define ICR_JACK_MASK 5
+ #define ICR_SCMC_MASK 4
+ #define ICR_RUP_MASK 3
+ #define ICR_RDO_MASK 2
+ #define ICR_GUP_MASK 1
+ #define ICR_GDO_MASK 0
+
+#define DLV_REG_IFR 11
+ #define IFR_JACK 6
+ #define IFR_JACK_EVENT 5
+ #define IFR_SCMC 4
+ #define IFR_RUP 3
+ #define IFR_RDO 2
+ #define IFR_GUP 1
+ #define IFR_GDO 0
+
+#define DLV_REG_GCR1 12
+#define DLV_REG_GCR2 13
+#define DLV_REG_GCR3 14
+#define DLV_REG_GCR4 15
+#define DLV_REG_GCR5 16
+#define DLV_REG_GCR6 17
+#define DLV_REG_GCR7 18
+
+#define DLV_REG_GCR8 19
+#define DLV_REG_GCR9 20
+
+#define DLV_REG_AGC1 21
+ #define AGC1_AGCEN 7
+
+#define DLV_REG_AGC2 22
+#define DLV_REG_AGC3 23
+#define DLV_REG_AGC4 24
+#define DLV_REG_AGC5 25
+#define DLV_REG_MIX1 26
+#define DLV_REG_MIX2 27
+
+/*
+void write_codec_file(int addr, int val);
+int read_codec_file(int addr);
+void printk_codec_files(int aaa);
+int write_codec_file_bit(int addr, int bitval, int mask_bit);
+void set_audio_data_replay(void);
+void unset_audio_data_replay(void);
+void set_record_mic_input_audio_without_playback(void);
+void unset_record_mic_input_audio_without_playback(void);
+void set_record_line_input_audio_without_playback(void);
+void unset_record_line_input_audio_without_playback(void);
+void set_playback_line_input_audio_direct_only(void);
+void unset_playback_line_input_audio_direct_only(void);
+void set_record_mic_input_audio_with_direct_playback(void);
+void unset_record_mic_input_audio_with_direct_playback(void);
+void set_record_playing_audio_mixed_with_mic_input_audio(void);
+void unset_record_playing_audio_mixed_with_mic_input_audio(void);
+void set_record_mic_input_audio_with_audio_data_replay(void);
+void unset_record_mic_input_audio_with_audio_data_replay(void);
+void set_record_line_input_audio_with_audio_data_replay(void);
+void unset_record_line_input_audio_with_audio_data_replay(void);
+*/
+
+#endif // __JZ4760_DLV_H__
diff --git a/sound/oss/jz4760_i2s.c b/sound/oss/jz4760_i2s.c
new file mode 100644
index 00000000000..c2a72a2532b
--- /dev/null
+++ b/sound/oss/jz4760_i2s.c
@@ -0,0 +1,3068 @@
+/*
+ * Linux/sound/oss/jz_i2s.c
+ *
+ * Sound driver for Ingenic Jz4750 MIPS processor
+ *
+ * 2009-12-xx Steven <dsqiu@ingenic.cn>
+ * 2010-01-xx Jason <xwang@ingenic.cn>
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <linux/proc_fs.h>
+#include <linux/soundcard.h>
+#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <asm/hardirq.h>
+#include <asm/jzsoc.h>
+#include "sound_config.h"
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+//#include <linux/msm_audio.h>
+#include "jz_codec.h"
+#include "jz_i2s_dbg.h"
+
+#if defined CONFIG_PM
+#undef CONFIG_PM
+#endif
+
+#define DMA_ID_I2S_TX DMA_ID_AIC_TX
+#define DMA_ID_I2S_RX DMA_ID_AIC_RX
+
+// reference to dma.c
+#define DMA_TX_CHAN 6
+#define DMA_RX_CHAN 7
+
+#define NR_I2S 2
+
+#define JZCODEC_RW_BUFFER_SIZE 1
+#define JZCODEC_RW_BUFFER_TOTAL 4
+
+#define AUDIOBUF_STATE_FREE 0
+
+#define NOMAL_STOP 0
+#define FORCE_STOP 1
+#define PIPE_TRANS 1
+
+#define AUDIO_LOCK(lock, flags) spin_lock_irqsave(lock, flags)
+#define AUDIO_UNLOCK(lock, flags) spin_unlock_irqrestore(lock, flags)
+
+#define THIS_AUDIO_NODE(p) list_entry(p, audio_node, list)
+#define ALIGN_PAGE_SIZE(x) (((x) + PAGE_SIZE) / PAGE_SIZE * PAGE_SIZE)
+
+typedef struct {
+ struct list_head list;
+ unsigned int pBuf;
+#ifdef Q_DEBUG
+ unsigned int pBufID;
+#endif
+ unsigned int start;
+ unsigned int end;
+ unsigned int phyaddr;
+} audio_node;
+
+typedef struct {
+ unsigned int fact;
+ unsigned int datasize;
+ unsigned int listsize;
+ struct list_head free;
+ struct list_head use;
+} audio_head;
+
+typedef struct
+{
+ int ch;
+ int onetrans_bit;
+ int rw;
+ unsigned int *trans_addr;
+ unsigned int *trans_count;
+ unsigned int *trans_mode;
+ unsigned int *data_addr;
+} audio_dma_type;
+
+typedef struct __audio_pipe
+{
+ spinlock_t lock;
+ audio_dma_type dma;
+ unsigned int *mem;
+ audio_node *savenode;
+
+ int fragsize;
+ int fragstotal;
+ int is_non_block;
+ volatile int trans_state;
+
+ wait_queue_head_t q_full;
+ int avialable_couter;
+
+#ifdef WORK_QUEUE_MODE
+ struct work_struct work;
+#endif
+ void (*handle)(struct __audio_pipe *endpoint);
+ int (*filter)(void *buff, int cnt);
+} audio_pipe;
+
+struct i2s_codec
+{
+ /* I2S controller connected with */
+ void *private_data;
+ char *name;
+ int id;
+ int dev_mixer;
+
+ int use_mic_line_flag;
+ int audio_volume;
+ int mic_gain;
+ int bass_gain;
+
+ unsigned short record_audio_rate;
+ unsigned short replay_audio_rate;
+
+ short replay_codec_channel;
+ short record_codec_channel;
+
+ short replay_format;
+ short record_format;
+
+ int audiomute;
+ int user_need_mono;
+
+ struct semaphore i2s_sem;
+ int (*codecs_ioctrl)(void *context, unsigned int cmd, unsigned long arg);
+};
+
+struct jz_i2s_controller_info
+{
+ char *name;
+ audio_pipe *pout_endpoint;
+ audio_pipe *pin_endpoint;
+ int dev_audio;
+ unsigned int error; /* over / underrun */
+
+ struct i2s_codec *i2s_codec;
+
+#ifdef CONFIG_PM
+ struct pm_dev *pm;
+#endif
+};
+
+
+/*
+ * Global variates
+ */
+static audio_pipe out_endpoint = {
+ .mem = 0,
+ .savenode = 0,
+ .fragsize = 0,
+ .fragstotal = 0,
+ .trans_state = 0,
+};
+
+static audio_pipe in_endpoint= {
+ .mem = 0,
+ .savenode = 0,
+ .fragsize = 0,
+ .fragstotal = 0,
+ .trans_state = 0,
+};
+
+static struct i2s_codec the_codecs[NR_I2S];
+static struct jz_i2s_controller_info *the_i2s_controller = NULL;
+static int audio_mix_modcnt = 0;
+
+/*
+ * Debug functions
+ */
+#ifdef DMA_DEBUG
+void dump_dma(unsigned int dmanr, const char *str)
+{
+ printk("DMA%d Registers, %s:\n", dmanr, str);
+ printk("\tDMACR = 0x%08x\n", REG_DMAC_DMACR(dmanr/HALF_DMA_NUM));
+ printk("\tDSAR = 0x%08x\n", REG_DMAC_DSAR(dmanr));
+ printk("\tDTAR = 0x%08x\n", REG_DMAC_DTAR(dmanr));
+ printk("\tDTCR = 0x%08x\n", REG_DMAC_DTCR(dmanr));
+
+ *(unsigned int *)0xb342010c = 0x18;
+
+ printk("\tDRSR = 0x%08x, addr = 0x%08x\n", REG_DMAC_DRSR(dmanr), DMAC_DRSR(dmanr));
+ printk("\tDCCSR = 0x%08x\n", REG_DMAC_DCCSR(dmanr));
+ printk("\tDCMD = 0x%08x\n", REG_DMAC_DCMD(dmanr));
+ printk("\tDDA = 0x%08x\n", REG_DMAC_DDA(dmanr));
+ printk("\tDMADBR= 0x%08x\n", REG_DMAC_DMADBR(dmanr/HALF_DMA_NUM));
+ printk("\tCPCCR = 0x%08x\n", REG_CPM_CPCCR);
+ printk("\tCPPCR = 0x%08x\n", REG_CPM_CPPCR0);
+ printk("\tREG_CPM_CLKGR0 = 0x%08x\n", REG_CPM_CLKGR0);
+ printk("\tREG_CPM_CLKGR1 = 0x%08x\n", REG_CPM_CLKGR1);
+}
+#endif
+
+#ifdef IOC_DEBUG
+void dsp_print_ioc_cmd(int cmd)
+{
+ int i;
+ int cmd_arr[] = {
+ OSS_GETVERSION, SNDCTL_DSP_RESET, SNDCTL_DSP_SYNC,
+ SNDCTL_DSP_SPEED, SNDCTL_DSP_STEREO, SNDCTL_DSP_GETBLKSIZE,
+ SNDCTL_DSP_GETFMTS, SNDCTL_DSP_SETFMT, SNDCTL_DSP_CHANNELS,
+ SNDCTL_DSP_POST, SNDCTL_DSP_SUBDIVIDE, SNDCTL_DSP_SETFRAGMENT,
+ SNDCTL_DSP_GETCAPS, SNDCTL_DSP_NONBLOCK, SNDCTL_DSP_SETDUPLEX,
+ SNDCTL_DSP_GETOSPACE, SNDCTL_DSP_GETISPACE, SNDCTL_DSP_GETTRIGGER,
+ SNDCTL_DSP_SETTRIGGER, SNDCTL_DSP_GETIPTR, SNDCTL_DSP_GETOPTR,
+ SNDCTL_DSP_GETODELAY, SOUND_PCM_READ_RATE, SOUND_PCM_READ_CHANNELS,
+ SOUND_PCM_READ_BITS, SNDCTL_DSP_MAPINBUF, SNDCTL_DSP_MAPOUTBUF,
+ SNDCTL_DSP_SETSYNCRO, SOUND_PCM_READ_FILTER, SOUND_PCM_WRITE_FILTER,
+// AUDIO_GET_CONFIG, AUDIO_SET_CONFIG
+ };
+ char *cmd_str[] = {
+ "OSS_GETVERSION", "SNDCTL_DSP_RESET", "SNDCTL_DSP_SYNC",
+ "SNDCTL_DSP_SPEED", "SNDCTL_DSP_STEREO", "SNDCTL_DSP_GETBLKSIZE",
+ "SNDCTL_DSP_GETFMTS", "SNDCTL_DSP_SETFMT", "SNDCTL_DSP_CHANNELS",
+ "SNDCTL_DSP_POST", "SNDCTL_DSP_SUBDIVIDE", "SNDCTL_DSP_SETFRAGMENT",
+ "SNDCTL_DSP_GETCAPS", "SNDCTL_DSP_NONBLOCK", "SNDCTL_DSP_SETDUPLEX",
+ "SNDCTL_DSP_GETOSPACE", "SNDCTL_DSP_GETISPACE", "SNDCTL_DSP_GETTRIGGER",
+ "SNDCTL_DSP_SETTRIGGER","SNDCTL_DSP_GETIPTR", "SNDCTL_DSP_GETOPTR",
+ "SNDCTL_DSP_GETODELAY", "SOUND_PCM_READ_RATE", "SOUND_PCM_READ_CHANNELS",
+ "SOUND_PCM_READ_BITS", "SNDCTL_DSP_MAPINBUF", "SNDCTL_DSP_MAPOUTBUF",
+ "SNDCTL_DSP_SETSYNCRO", "SOUND_PCM_READ_FILTER","SOUND_PCM_WRITE_FILTER",
+// "AUDIO_GET_CONFIG", "AUDIO_SET_CONFIG"
+ };
+
+ for ( i = 0; i < sizeof(cmd_arr) / sizeof(int); i++) {
+ if (cmd_arr[i] == cmd) {
+ printk("Command name : %s\n", cmd_str[i]);
+ return;
+ }
+ }
+
+ if (i == sizeof(cmd_arr) / sizeof(int)) {
+ printk("Unknown command\n");
+ }
+}
+
+void mixer_print_ioc_cmd(int cmd)
+{
+ int i;
+ int cmd_arr[] = {
+ SOUND_MIXER_INFO, SOUND_OLD_MIXER_INFO, SOUND_MIXER_READ_STEREODEVS,
+ SOUND_MIXER_READ_CAPS, SOUND_MIXER_READ_DEVMASK, SOUND_MIXER_READ_RECMASK,
+ SOUND_MIXER_READ_RECSRC,SOUND_MIXER_WRITE_SPEAKER, SOUND_MIXER_WRITE_BASS,
+ SOUND_MIXER_READ_BASS, SOUND_MIXER_WRITE_VOLUME, SOUND_MIXER_READ_VOLUME,
+ SOUND_MIXER_WRITE_MIC, SOUND_MIXER_READ_MIC, SOUND_MIXER_WRITE_LINE,
+ SOUND_MIXER_READ_LINE, SOUND_MIXER_WRITE_MUTE, SOUND_MIXER_READ_MUTE,
+// SND_SET_DEVICE, SND_SET_VOLUME,
+// SND_GET_NUM_ENDPOINTS, SND_GET_ENDPOINT
+ };
+
+ char *cmd_str[] = {
+ "SOUND_MIXER_INFO", "SOUND_OLD_MIXER_INFO", "SOUND_MIXER_READ_STEREODEVS",
+ "SOUND_MIXER_READ_CAPS", "SOUND_MIXER_READ_DEVMASK", "SOUND_MIXER_READ_RECMASK",
+ "SOUND_MIXER_READ_RECSRC", "SOUND_MIXER_WRITE_SPEAKER", "SOUND_MIXER_WRITE_BASS",
+ "SOUND_MIXER_READ_BASS", "SOUND_MIXER_WRITE_VOLUME", "SOUND_MIXER_READ_VOLUME",
+ "SOUND_MIXER_WRITE_MIC", "SOUND_MIXER_READ_MIC", "SOUND_MIXER_WRITE_LINE",
+ "SOUND_MIXER_READ_LINE", "SOUND_MIXER_WRITE_MUTE", "SOUND_MIXER_READ_MUTE",
+// "SND_SET_DEVICE", "SND_SET_VOLUME",
+// "SND_GET_NUM_ENDPOINTS", "SND_GET_ENDPOINT"
+ };
+
+ for (i = 0; i < sizeof(cmd_arr) / sizeof(int); i++) {
+ if (cmd_arr[i] == cmd) {
+ printk("Command name : %s\n", cmd_str[i]);
+ return;
+ }
+ }
+
+ printk("Unknown command\n");
+}
+#endif
+
+//#ifdef REG_DEBUG
+void dump_aic_regs(const char *str)
+{
+ char *regname[] = {"aicfr","aiccr","aiccr1","aiccr2","i2scr","aicsr","acsr","i2ssr"};
+ int i;
+ unsigned int addr;
+
+ printk("AIC regs dump, %s\n", str);
+ for (i = 0; i < 0x1c; i += 4) {
+ addr = 0xb0020000 + i;
+ printk("%s\t0x%08x -> 0x%08x\n", regname[i/4], addr, *(unsigned int *)addr);
+ }
+}
+//#endif
+
+#ifdef BUF_DEBUG
+void dump_buf(char *buf, int dump_len, int bytes_in_line)
+{
+ int i;
+ printk("Buffer 0x%p:\n", buf);
+ for (i = 0; i < dump_len; i++) {
+ printk("%02x ", (unsigned char)buf[i]);
+ if ((i+1) % bytes_in_line == 0) {
+ printk("\n");
+ }
+ }
+ printk("\n");
+}
+#endif
+
+#ifdef Q_DEBUG
+void dump_node(audio_node *node, const char *str)
+{
+ if (!node || !str) {
+ printk("DUMP_NODE: detected argument is NULL\n");
+ return;
+ }
+
+ printk("%s: addr(0x%08x) id=%d, pBuf=0x%08x, start=0x%08x, end=0x%08x, phyaddr=0x%08x\n",
+ str, (unsigned int)node, node->pBufID, node->pBuf, node->start, node->end, node->phyaddr);
+}
+
+void dump_list(audio_head *head)
+{
+ audio_node *tmp;
+ struct list_head *p, *n;
+
+ BUG_ON(!head);
+
+ printk("--------\nAudio head info: fact = %d, datasize = %d, listsize = %d\n",
+ head->fact, head->datasize, head->listsize);
+
+ printk("free q:\n");
+ list_for_each_safe(p, n, &head->free) {
+ tmp = list_entry(p, audio_node, list);
+ DUMP_NODE(tmp, "fQ");
+ }
+ printk("use q:\n");
+ list_for_each_safe(p, n, &head->use) {
+ tmp = list_entry(p, audio_node, list);
+ DUMP_NODE(tmp, "uQ");
+ }
+ printk("--------\n");
+}
+#endif
+
+//----------------------------------------------------------------
+// audio node operater
+// int init_audio_node(unsigned int **memory, unsigned int pagesize, unsigned int count)
+// void deinit_audio_node(unsigned int **memory)
+// static inline audio_node *get_audio_freenode(unsigned int *mem)
+// static inline void put_audio_usenode(unsigned int *mem, audio_node *node)
+// static inline audio_node *get_audio_usenode(unsigned int *mem)
+// static inline void put_audio_freenode(unsigned int *mem, audio_node *node)
+// static inline int get_audio_freenodecount(unsigned int *mem)
+//
+//----------------------------------------------------------------
+
+void deinit_audio_node(unsigned int **memory)
+{
+ audio_head *phead;
+ unsigned int fact;
+
+ phead = (audio_head *)*memory;
+ fact = phead->fact;
+ free_pages((unsigned long)*memory, fact);
+ *memory = NULL;
+}
+
+int init_audio_node(unsigned int **memory, unsigned int pagesize, unsigned int count)
+{
+ unsigned int fact;
+ audio_node *pbuff;
+ audio_head *phead;
+ unsigned int *mem;
+ struct list_head *audio_wfree;
+ struct list_head *audio_wuse;
+ int memsize;
+ int datasize;
+ int headlistsize;
+ int i;
+
+ ENTER();
+
+ // Alloc memory first, to avail fail
+ datasize = ALIGN_PAGE_SIZE(pagesize * count);
+ headlistsize = ALIGN_PAGE_SIZE(count * sizeof(audio_node) + sizeof(audio_head));
+ memsize = headlistsize + datasize;
+ fact = get_order(memsize);
+
+ mem = (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA, fact);
+ if (mem == NULL) {
+ printk("JZ I2S: Memory allocation failed in function init_audio_node!\n");
+ return 0;
+ }
+
+ DPRINT("Mem alloc finish! memsize = %x, fact = %d, mem = 0x%08x\n",
+ memsize, fact, (unsigned int)mem);
+
+ // Free old buffer
+ if (*memory) {
+ phead = (audio_head *)*memory;
+ fact = phead->fact;
+ free_pages((unsigned long)*memory, fact);
+ *memory = NULL;
+ }
+ *memory = mem;
+
+/*
+ datasize = ALIGN_PAGE_SIZE(pagesize * count);
+ headlistsize = ALIGN_PAGE_SIZE(count * sizeof(audio_node) + sizeof(audio_head)); //8byte is save head data
+ memsize = headlistsize + datasize;
+
+ fact = get_order(memsize);
+*/
+
+ // Update list head
+ phead = (audio_head *)*memory;
+ phead->fact = fact;
+ phead->listsize = headlistsize;
+ phead->datasize = datasize;
+
+ audio_wuse = &(phead->use);
+ audio_wfree = &(phead->free);
+ INIT_LIST_HEAD(audio_wuse);
+ INIT_LIST_HEAD(audio_wfree);
+
+ pbuff = (audio_node *)((unsigned int)*memory + sizeof(audio_head));
+ for (i = 0; i < count; i++) {
+ pbuff->pBuf = (unsigned int)*memory + headlistsize + pagesize * i;
+ pbuff->phyaddr = (unsigned int)virt_to_phys((void *)pbuff->pBuf);
+ pbuff->start = 0;
+ pbuff->end = 0;
+#ifdef Q_DEBUG
+ pbuff->pBufID = i;
+#endif
+ DPRINT_Q("audio_note buffer[%d] = %x\n", i, (unsigned int)pbuff->pBuf);
+ list_add(&pbuff->list, audio_wfree);
+ pbuff++;
+ }
+
+ DUMP_LIST(phead);
+
+ LEAVE();
+ return 1;
+}
+
+#define is_null_free_audio_node(mem) \
+({ \
+ audio_head *phead = (audio_head *)(mem); \
+ struct list_head *pfree = &(phead->pfree); \
+ (pfree->next == pfree); \
+})
+
+#define is_null_use_audio_node(mem) \
+({ \
+ audio_head *phead = (audio_head *)mem; \
+ struct list_head *puse = &(phead->use); \
+ (puse->next == puse); \
+})
+
+//static unsigned int putid = 0, getid = 0;
+
+static inline audio_node *get_audio_freenode(unsigned int *mem)
+{
+ audio_head *phead;
+ audio_node *node = NULL;
+ struct list_head *pfree;
+ struct list_head *curnode;
+
+ phead = (audio_head *)mem;
+ pfree = &(phead->free);
+ curnode = pfree->next;
+
+ if (curnode != pfree) {
+ node = THIS_AUDIO_NODE(curnode);
+ node->start = 0;
+ node->end = 0;
+ list_del(curnode);
+ }
+ return node;
+}
+
+static inline void put_audio_usenode(unsigned int *mem, audio_node *node)
+{
+ audio_head *phead = (audio_head *)mem;
+ struct list_head *puse = &(phead->use);
+ struct list_head *curnode = &(node->list);
+
+ list_add_tail(curnode, puse);
+}
+
+static inline audio_node *get_audio_usenode(unsigned int *mem)
+{
+ audio_head *phead;
+ audio_node *node = NULL;
+ struct list_head *curnode;
+ struct list_head *puse;
+
+ phead = (audio_head *)mem;
+ puse = &(phead->use);
+ curnode = puse->next;
+
+ if (curnode != puse) {
+ node = THIS_AUDIO_NODE(curnode);
+ list_del(curnode);
+ }
+ return node;
+}
+
+static inline void put_audio_freenode(unsigned int *mem, audio_node *node)
+{
+ audio_head *phead = (audio_head *)mem;
+ struct list_head *pfree = &(phead->free);
+ struct list_head *curnode = &(node->list);
+
+ list_add_tail(curnode, pfree);
+}
+
+static inline int get_audio_freenodecount(unsigned int *mem)
+{
+ struct list_head *pfree;
+ struct list_head *plist;
+ audio_head *phead;
+ int count = 0;
+
+ phead = (audio_head *)mem;
+ pfree = &(phead->free);
+ plist = pfree;
+ while (plist->next != pfree) {
+ count++;
+ plist = plist->next;
+ }
+ return count;
+}
+
+//--------------------------------------------------------------------
+// end audio node operater
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+// static irqreturn_t jz_i2s_dma_irq (int irq, void *dev_id)
+// int init_audio_recorddma(audio_pipe *endpoint)
+// int init_audio_replaydma(audio_pipe *endpoint)
+// int init_audio_audiodma(audio_pipe *endpoint, int mode)
+// void config_dma_trans_mode(spinlock_t lock, audio_dma_type* dma, int mode)
+// static inline int audio_trystart_dma_node(audio_dma_type* dma, audio_node *node)
+// static inline int audio_trystart_dma_node(audio_dma_type* dma, audio_node *node)
+// static inline void audio_stop_dma_node(audio_dma_type* dma)
+
+static irqreturn_t jz_i2s_dma_irq (int irq, void *dev_id)
+{
+ audio_pipe * endpoint = (audio_pipe *) dev_id;
+ int dma_chan = endpoint->dma.ch;
+ int dma_state = REG_DMAC_DCCSR(dma_chan);
+ int err = 0;
+
+ ENTER();
+
+ REG_DMAC_DCCSR(dma_chan) = 0;
+
+ DPRINT_IRQ("!!!! endpoint direct = %s \n",(endpoint == &out_endpoint) ? "out" : "in");
+
+ if (dma_state & DMAC_DCCSR_HLT) {
+ err = 0;
+ DPRINT_IRQ("!!!! DMA HALT\n");
+ }
+ if (dma_state & DMAC_DCCSR_AR) {
+ err = 1;
+ DPRINT_IRQ("!!!! DMA ADDR ERROR\n");
+ }
+ if (dma_state & DMAC_DCCSR_INV) {
+ err = 1;
+ DPRINT_IRQ("!!!! DMA descriptor invalid\n");
+ }
+ if (dma_state & DMAC_DCCSR_CT) {
+ DPRINT_IRQ("!!!! DMA descriptor finish\n");
+ }
+ /*
+ if (dma_state & DMA_DCCSR_TT) {
+
+ }
+ */
+ if (err == 0) {
+ //printk("schedule_work++++ %x %x\n", endpoint,&(endpoint->work));
+ //schedule_work(&(endpoint->work));
+ //printk("schedule_work----\n");
+ endpoint->handle(endpoint);
+ } else {
+ DPRINT_IRQ("!!!! ??? unknown !!!\n");
+ }
+
+ LEAVE();
+
+ return IRQ_HANDLED;
+}
+
+static int jz_request_aic_dma(int dev_id, const char *dev_str,
+ irqreturn_t (*irqhandler)(int, void *),
+ unsigned long irqflags, void *irq_dev_id)
+{
+ struct jz_dma_chan *chan;
+ int i, ret;
+
+ if (dev_id == DMA_ID_AIC_TX) {
+ i = DMA_TX_CHAN;
+ if (jz_dma_table[i].dev_id != DMA_ID_AIC_TX) {
+ BUG_ON(1);
+ }
+ } else if (dev_id == DMA_ID_AIC_RX) {
+ i = DMA_RX_CHAN;
+ if (jz_dma_table[i].dev_id != DMA_ID_AIC_RX) {
+ BUG_ON(1);
+ }
+ } else {
+ BUG_ON(1);
+ }
+
+ /* we got channel */
+ chan = &jz_dma_table[i];
+
+ if (irqhandler) {
+ chan->irq = IRQ_DMA_0 + i;
+ chan->irq_dev = irq_dev_id;
+ if ((ret = request_irq(chan->irq, irqhandler, irqflags,
+ dev_str, chan->irq_dev))) {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ return ret;
+ }
+ } else {
+ chan->irq = -1;
+ chan->irq_dev = NULL;
+ }
+/*
+ printk("\n@@@@ %s:%d chan index = %d, chan.irq = %d\n\n",
+ __FUNCTION__, __LINE__, i, chan->irq);
+*/
+ chan->io = i;
+ chan->dev_id = dev_id;
+ chan->dev_str = dev_str;
+ chan->fifo_addr = CPHYSADDR(AIC_DR);
+
+ switch (dev_id) {
+ case DMA_ID_AIC_TX:
+ chan->mode = DMA_AIC_TX_CMD_UNPACK | DMA_MODE_WRITE;
+ chan->source = DMAC_DRSR_RS_AICOUT;
+ break;
+ case DMA_ID_AIC_RX:
+ chan->mode = DMA_32BIT_RX_CMD | DMA_MODE_READ;
+ chan->source = DMAC_DRSR_RS_AICIN;
+ break;
+ default:
+ printk("JZ AIC: %s:%d, need fix !!!\n", __FUNCTION__, __LINE__);
+ BUG_ON(1);
+ }
+
+ // Open AIC_TX and AIC_RX
+ REG_DMAC_DMACKE(1) = 1 << (DMA_RX_CHAN - HALF_DMA_NUM) | 1 << (DMA_TX_CHAN - HALF_DMA_NUM);
+
+ return i;
+}
+
+static int init_audio_recorddma(audio_pipe *endpoint)
+{
+ int ch = 0;
+
+ ENTER();
+ if ((ch = jz_request_aic_dma(DMA_ID_I2S_RX, "audio adc", jz_i2s_dma_irq, IRQF_DISABLED, endpoint)) < 0) {
+ printk(KERN_ERR "%s: can't reqeust DMA DAC channel.\n", __FUNCTION__);
+ return -1;
+ }
+ REG_DMAC_DMACR(ch / HALF_DMA_NUM) |= 1;
+ REG_DMAC_DCMD(ch) = DMAC_DCMD_DAI | DMAC_DCMD_SWDH_32 | DMAC_DCMD_TIE;
+ REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AICIN;
+ REG_DMAC_DSAR(ch) = (unsigned int)CPHYSADDR(AIC_DR);
+
+ endpoint->dma.ch = ch;
+ endpoint->dma.trans_addr = (unsigned int *)DMAC_DTAR(ch);
+ endpoint->dma.trans_count = (unsigned int *)DMAC_DTCR(ch);
+ endpoint->dma.trans_mode = (unsigned int *)DMAC_DCMD(ch);
+ endpoint->dma.data_addr = (unsigned int *)DMAC_DSAR(ch);
+
+ endpoint->dma.rw = 0;
+
+ LEAVE();
+ return ch;
+}
+
+static int init_audio_replaydma(audio_pipe *endpoint)
+{
+ int ch = 0;
+ if ((ch = jz_request_aic_dma(DMA_ID_I2S_TX,"audio dac", jz_i2s_dma_irq, IRQF_DISABLED, endpoint)) < 0) {
+ printk(KERN_ERR "%s: can't reqeust DMA DAC channel.\n", __FUNCTION__);
+ return -1;
+ }
+
+ REG_DMAC_DMACR(ch / HALF_DMA_NUM) |= 1;
+ REG_DMAC_DCMD(ch) = DMAC_DCMD_SAI | DMAC_DCMD_DWDH_32 | DMAC_DCMD_TIE;
+
+ //printk("$$$$ before set --- REG_DMAC_DRSR(ch) = 0x%08x\n", REG_DMAC_DRSR(ch));
+ REG_DMAC_DRSR(ch) = DMAC_DRSR_RS_AICOUT;
+
+ //printk("$$$$ ch = %d, DMAC_DRSR = 0x%08x, set 0x%08x, after set -- 0x%08x\n",
+ // ch, DMAC_DRSR(ch), DMAC_DRSR_RS_AICOUT, REG_DMAC_DRSR(ch));
+
+ *(unsigned int *)0xb342010c = 0x18;
+
+ //printk("$$$$ after force set --- REG_DMAC_DRSR(ch) = 0x%08x\n", REG_DMAC_DRSR(ch));
+
+ REG_DMAC_DTAR(ch) = (unsigned int)CPHYSADDR(AIC_DR);
+
+ endpoint->dma.ch = ch;
+ endpoint->dma.trans_addr = (unsigned int *)DMAC_DSAR(ch);
+ endpoint->dma.trans_count = (unsigned int *)DMAC_DTCR(ch);
+ endpoint->dma.trans_mode = (unsigned int *)DMAC_DCMD(ch);
+ endpoint->dma.data_addr = (unsigned int *)DMAC_DTAR(ch);
+ endpoint->dma.rw = 1;
+ return ch;
+}
+
+static int init_audio_audiodma(audio_pipe *endpoint, int mode)
+{
+ if (mode == CODEC_RMODE) {
+ return init_audio_recorddma(endpoint);
+ }
+
+ if (mode == CODEC_WMODE) {
+ return init_audio_replaydma(endpoint);
+ }
+
+ return -1;
+}
+
+static void config_dma_trans_mode(spinlock_t lock, audio_dma_type* dma, int sound_data_width)
+{
+ unsigned int curmode;
+ unsigned long flags;
+
+ ENTER();
+ AUDIO_LOCK(lock, flags);
+ curmode = *dma->trans_mode;
+
+ if (dma->rw) {
+ curmode &= ~(DMAC_DCMD_DWDH_MASK | DMAC_DCMD_DS_MASK);
+ switch(sound_data_width) {
+ case 8:
+ *dma->trans_mode = (curmode | DMAC_DCMD_DWDH_8 | DMAC_DCMD_DS_16BYTE);
+ dma->onetrans_bit = 16 * 8;
+ break;
+ case 16:
+ *dma->trans_mode = (curmode | DMAC_DCMD_DWDH_16 | DMAC_DCMD_DS_16BYTE);
+ dma->onetrans_bit = 16 * 8;
+ break;
+ case 17 ... 32:
+ *dma->trans_mode = (curmode | DMAC_DCMD_DWDH_32 | DMAC_DCMD_DS_32BYTE);
+ dma->onetrans_bit = 32 * 8;
+ break;
+ default:
+ printk("JZ I2S: Unkown DMA mode(sound data width) %d\n", sound_data_width);
+ break;
+ }
+ } else {
+ curmode &= ~(DMAC_DCMD_SWDH_MASK | DMAC_DCMD_DS_MASK);
+ switch(sound_data_width) {
+ case 8:
+ *dma->trans_mode = (curmode | DMAC_DCMD_SWDH_8 | DMAC_DCMD_DS_16BYTE);
+ dma->onetrans_bit = 16 * 8;
+ break;
+ case 16:
+ *dma->trans_mode = (curmode | DMAC_DCMD_SWDH_16 | DMAC_DCMD_DS_16BYTE);
+ dma->onetrans_bit = 16 * 8;
+ break;
+ case 17 ... 32:
+ *dma->trans_mode = (curmode | DMAC_DCMD_SWDH_32 | DMAC_DCMD_DS_32BYTE);
+ dma->onetrans_bit = 32 * 8;
+ break;
+ default:
+ printk("JZ I2S: Unkown DMA mode(sound data width) %d\n", sound_data_width);
+ break;
+ }
+ }
+
+ AUDIO_UNLOCK(lock, flags);
+ DUMP_DMA(dma->ch, __FUNCTION__);
+ DPRINT_DMA("dma_trans = %d\n", dma->onetrans_bit);
+ LEAVE();
+}
+
+#define aic_enable_transmit() \
+do { \
+ int dat = REG_AIC_CR; \
+ dat |= (AIC_CR_TDMS | AIC_CR_ERPL); \
+ REG_AIC_CR = dat; \
+} while (0)
+
+#define aic_disable_transmit() \
+do { \
+ int dat = REG_AIC_CR; \
+ dat &= ~(AIC_CR_TDMS | AIC_CR_ERPL); \
+ REG_AIC_CR = dat; \
+} while (0)
+
+static inline int audio_trystart_dma_node(audio_dma_type* dma, audio_node *node)
+{
+ int start = 0;
+
+ ENTER();
+
+ if ((REG_DMAC_DCCSR(dma->ch) & DMAC_DCCSR_EN) == 0) {
+ int count = node->end - node->start;
+ *(dma->trans_addr) = node->phyaddr;
+ *(dma->data_addr) = (unsigned int)CPHYSADDR(AIC_DR);
+ *(dma->trans_count) = count * 8 / dma->onetrans_bit;
+ REG_DMAC_DCCSR(dma->ch) = DMAC_DCCSR_NDES | DMAC_DCCSR_EN;
+ DPRINT_DMA("virt = 0x%08x phy = 0x%08x, dma->onetrans_bit = 0x%x\n",
+ node->pBuf, node->phyaddr, dma->onetrans_bit);
+
+ DUMP_CODEC_REGS(__FUNCTION__);
+ DUMP_AIC_REGS(__FUNCTION__);
+ start = 1;
+ }
+
+ DUMP_DMA(dma->ch, "audio_trystart_dma_node -----------");
+
+ LEAVE();
+ return start;
+}
+
+static inline void audio_stop_dma_node(audio_dma_type* dma)
+{
+ REG_DMAC_DCCSR(dma->ch) = 0;
+}
+
+/* Never be used, fix me ???
+static inline int recalculate_fifowidth(short channels, short fmt)
+{
+ int bit = 16;
+
+ if (fmt <= 8) {
+ bit = 8;
+ } else if (fmt > 16) {
+ bit = 32;
+ } else {
+ bit = 16;
+ }
+
+ return bit *= channels;
+}
+*/
+#define I2S_FIFO_DEPTH 32
+
+static inline void set_controller_triger(struct jz_i2s_controller_info *controller,
+ audio_pipe *endpoint, short channels, short format)
+{
+ int sound_data_width = 0;
+
+ ENTER();
+
+// printk("%%%% format = %d\n", format);
+
+ switch (format) {
+ case AFMT_U8:
+ case AFMT_S8:
+ sound_data_width = 8;
+ break;
+ case AFMT_S16_LE:
+ case AFMT_S16_BE:
+ sound_data_width = 16;
+ break;
+ default:
+ printk("JZ I2S: Unkown sound format %d\n", format);
+ return ;
+ }
+
+ config_dma_trans_mode(endpoint->lock,&(endpoint->dma), sound_data_width);
+ if (endpoint == &out_endpoint) {
+ if ((I2S_FIFO_DEPTH - endpoint->dma.onetrans_bit / sound_data_width) >= 30) {
+ __i2s_set_transmit_trigger(14);
+ } else {
+ __i2s_set_transmit_trigger((I2S_FIFO_DEPTH - endpoint->dma.onetrans_bit / sound_data_width) / 2);
+ }
+ }
+ if (endpoint == &in_endpoint) {
+ __i2s_set_receive_trigger((endpoint->dma.onetrans_bit / sound_data_width) / 2);
+ }
+
+ LEAVE();
+}
+
+//-------------------------------------------------------------------
+/*
+ int trystart_endpoint_out(audio_pipe *endpoint, audio_node *node);
+ int trystart_endpoint_in(audio_pipe *endpoint, audio_node *node);
+ note: this two function isn't protected;
+ */
+static inline int trystart_endpoint_out(struct jz_i2s_controller_info *controller, audio_node *node)
+{
+ audio_pipe *endpoint = controller->pout_endpoint;
+ int start = 0;
+
+ ENTER();
+
+ start = audio_trystart_dma_node(&(endpoint->dma), node);
+ if (start) {
+ endpoint->trans_state |= PIPE_TRANS;
+ endpoint->savenode = node;
+ aic_enable_transmit();
+ DUMP_AIC_REGS(__FUNCTION__);
+ DUMP_CODEC_REGS(__FUNCTION__);
+ }
+
+ LEAVE();
+ return start;
+}
+
+static inline int trystart_endpoint_in(struct jz_i2s_controller_info *controller, audio_node *node)
+{
+ audio_pipe *endpoint = controller->pin_endpoint;
+ int start = 0;
+
+ ENTER();
+ dma_cache_wback_inv((unsigned long)node->pBuf, endpoint->fragsize);
+ start = audio_trystart_dma_node(&(endpoint->dma), node);
+ if (start) {
+ endpoint->trans_state |= PIPE_TRANS;
+ endpoint->savenode = node;
+ __i2s_enable_receive_dma();
+ __i2s_enable_record();
+ DUMP_AIC_REGS(__FUNCTION__);
+ DUMP_CODEC_REGS(__FUNCTION__);
+ }
+ LEAVE();
+ return start;
+}
+
+int audio_get_endpoint_freesize(audio_pipe *endpoint, audio_buf_info *info)
+{
+ int count;
+ unsigned long flags;
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ count = get_audio_freenodecount(endpoint->mem);
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ info->fragments = count;
+ info->fragstotal = endpoint->fragstotal;
+ info->fragsize = endpoint->fragsize;
+ info->bytes = count * endpoint->fragsize;
+ return info->bytes;
+}
+
+void audio_clear_endpoint(audio_pipe *endpoint)
+{
+ audio_node *pusenode;
+ unsigned long flags;
+
+ ENTER();
+ AUDIO_LOCK(endpoint->lock, flags);
+ while (!is_null_use_audio_node(endpoint->mem)) {
+ pusenode = get_audio_usenode(endpoint->mem);
+ if (pusenode) {
+ put_audio_freenode(endpoint->mem, pusenode);
+ }
+ }
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ LEAVE();
+}
+
+void audio_sync_endpoint(audio_pipe *endpoint)
+{
+ int isnull = 1;
+ unsigned long flags;
+
+ ENTER();
+
+ do {
+ AUDIO_LOCK(endpoint->lock, flags);
+ isnull = is_null_use_audio_node(endpoint->mem);
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ if (!isnull) {
+ //printk("&&&& audio_sync_endpoint\n");
+ schedule_timeout(1);
+ }
+ } while (!isnull);
+
+ LEAVE();
+}
+
+void audio_close_endpoint(audio_pipe *endpoint, int mode)
+{
+ int is_use_list_null = 1, trans = 0;
+ unsigned long flags;
+
+ ENTER();
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ is_use_list_null = is_null_use_audio_node(endpoint->mem);
+ trans = endpoint->trans_state & PIPE_TRANS;
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ if (is_use_list_null) {
+ // Wait savenode trans complete
+ while (trans) {
+ AUDIO_LOCK(endpoint->lock, flags);
+ trans = endpoint->trans_state & PIPE_TRANS;
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ DPRINT("waiting savenode\n");
+ if (trans) {
+ schedule_timeout(10);
+ }
+ }
+
+ /* In replay mode, savenode must been put into free list after trans completed,
+ * so we don't care it in this condition.
+ * But in record mode, savenode must been put into use list after trans completed,
+ * so we have to ignore the incomming data and move it to free list forcely.
+ */
+ if (endpoint == &out_endpoint) {
+ goto _L_AUDIO_CLOSE_EP_RET;
+ }
+ }
+
+ // NOMAL_STOP routine of replay mode
+ if (mode == NOMAL_STOP) {
+ BUG_ON(endpoint != &out_endpoint);
+
+ // Wait use list free
+ audio_sync_endpoint(endpoint);
+ // wait savenode trans finish
+ while (trans) {
+ AUDIO_LOCK(endpoint->lock, flags);
+ trans = endpoint->trans_state & PIPE_TRANS;
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ //printk("waiting savenode\n");
+ if (trans) {
+ schedule_timeout(10);
+ }
+ }
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ } else {
+ // FORCE_STOP routine, both replay and record mode could run
+ audio_node *pusenode;
+
+ // Shutdown DMA immediately and clear lists forcely.
+ AUDIO_LOCK(endpoint->lock, flags);
+
+ endpoint->trans_state &= ~PIPE_TRANS;
+ audio_stop_dma_node(&endpoint->dma);
+
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ DPRINT_Q("---------------------------------\n");
+
+ while (!is_null_use_audio_node(endpoint->mem)) {
+ pusenode = get_audio_usenode(endpoint->mem);
+ if (pusenode) {
+ put_audio_freenode(endpoint->mem, pusenode);
+ }
+ }
+
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ DPRINT_Q("---------------------------------\n");
+
+ if (endpoint->savenode) {
+ DPRINT_Q("handle savenode : 0x%08x\n", (unsigned int)endpoint->savenode);
+ DUMP_NODE(endpoint->savenode, "SN");
+ put_audio_freenode(endpoint->mem, endpoint->savenode);
+
+ DPRINT_Q("savenode->list->next = 0x%08x, savenode->list->prev = 0x%08x\n",
+ (unsigned int)endpoint->savenode->list.next,
+ (unsigned int)endpoint->savenode->list.prev);
+
+ endpoint->savenode = NULL;
+ }
+
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ }
+
+_L_AUDIO_CLOSE_EP_RET:
+ LEAVE();
+}
+
+int audio_resizemem_endpoint(audio_pipe *endpoint, unsigned int pagesize, unsigned int count)
+{
+ int ret = init_audio_node(&endpoint->mem, pagesize, count);
+ if (ret) {
+ endpoint->fragsize = pagesize;
+ endpoint->fragstotal = count;
+ }
+ return ret;
+}
+
+static void handle_in_endpoint_work(audio_pipe *endpoint)
+{
+ audio_node *node;
+ unsigned long flags;
+
+ ENTER();
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ if (endpoint->savenode) {
+ DPRINT_Q("\nIIII RRRR QQQQ >>>>\n");
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "IRQSN");
+ DPRINT_Q("IIII RRRR QQQQ <<<<\n\n");
+
+ DPRINT_IRQ("%s endpoint->savenode = 0x%p\n", __FUNCTION__, endpoint->savenode);
+ put_audio_usenode(endpoint->mem, endpoint->savenode);
+
+ endpoint->savenode = NULL;
+ DUMP_BUF((char *)(endpoint->savenode->pBuf + endpoint->savenode->start), 64, 32);
+
+ if (!(endpoint->is_non_block)) {
+ endpoint->avialable_couter++;
+ wake_up_interruptible(&endpoint->q_full);
+ }
+ }
+
+ node = get_audio_freenode(endpoint->mem);
+ if (node) {
+ int start;
+ node->end = endpoint->fragsize;
+ dma_cache_wback_inv((unsigned long)node->pBuf, endpoint->fragsize);
+ start = audio_trystart_dma_node(&(endpoint->dma), node);
+ if (start == 0) {
+ put_audio_freenode(endpoint->mem, node);
+ } else {
+ endpoint->savenode = node;
+ }
+ } else {
+ endpoint->trans_state &= ~PIPE_TRANS;
+ __i2s_disable_receive_dma();
+ __i2s_disable_record();
+ DPRINT_IRQ("!!!! Stop AIC record !\n");
+ }
+
+ DPRINT_Q("\nIIII RRRR QQQQ >>>>\n");
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ DPRINT_Q("IIII RRRR QQQQ <<<<\n\n");
+
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ LEAVE();
+}
+
+/*
+static void audio_in_endpoint_work(struct work_struct *work)
+{
+ audio_pipe *endpoint = &in_endpoint;
+ handle_in_endpoint_work(endpoint);
+}
+*/
+
+static void handle_out_endpoint_work(audio_pipe *endpoint)
+{
+ audio_node *node;
+ unsigned long flags;
+
+ ENTER();
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ DPRINT_IRQ("%s endpoint->savenode = 0x%08x\n", __FUNCTION__, (unsigned int)endpoint->savenode);
+
+ if (endpoint->savenode) {
+ put_audio_freenode(endpoint->mem, endpoint->savenode);
+ DPRINT_IRQ("put_audio_freenode\n");
+ endpoint->savenode = NULL;
+
+ if (!(endpoint->is_non_block)) {
+ wake_up_interruptible(&endpoint->q_full);
+ endpoint->avialable_couter++;
+ }
+ }
+
+ node = get_audio_usenode(endpoint->mem);
+ if (node) {
+ int start;
+ start = audio_trystart_dma_node(&(endpoint->dma), node);
+ if (start == 0) {
+ printk("audio_out_endpoint_work audio_trystart_dma_node error!\n");
+ } else {
+ endpoint->savenode = node;
+ DPRINT_DMA("restart dma!\n");
+ }
+ } else {
+ endpoint->trans_state &= ~PIPE_TRANS;
+ aic_disable_transmit();
+ DPRINT_IRQ("!!!! Stop AIC !\n");
+ }
+
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ LEAVE();
+}
+
+/*
+static void audio_out_endpoint_work(struct work_struct *work)
+{
+ audio_pipe *endpoint = &out_endpoint;
+ handle_out_endpoint_work(endpoint);
+}
+*/
+
+void audio_init_endpoint(audio_pipe *endpoint, unsigned int pagesize, unsigned int count)
+{
+ audio_resizemem_endpoint(endpoint, pagesize, count);
+ spin_lock_init(&endpoint->lock);
+ init_waitqueue_head(&endpoint->q_full);
+ endpoint->avialable_couter = 0;
+ endpoint->filter = NULL;
+
+ if (endpoint == &in_endpoint) {
+ init_audio_audiodma(endpoint, CODEC_RMODE);
+ // INIT_WORK(&endpoint->work, audio_in_endpoint_work);
+ endpoint->handle = handle_in_endpoint_work;
+ }
+ if (endpoint == &out_endpoint) {
+ init_audio_audiodma(endpoint, CODEC_WMODE);
+ // INIT_WORK(&endpoint->work, audio_out_endpoint_work);
+ endpoint->handle = handle_out_endpoint_work;
+ }
+}
+
+void audio_deinit_endpoint(audio_pipe *endpoint)
+{
+ audio_close_endpoint(endpoint, FORCE_STOP);
+ deinit_audio_node(&endpoint->mem);
+}
+
+void register_jz_codecs(void *func)
+{
+ int i;
+
+ ENTER();
+
+ for (i = 0; i < NR_I2S; i++) {
+ if (the_codecs[i].codecs_ioctrl == 0) {
+ printk("register codec %x\n",(unsigned int)func);
+ the_codecs[i].id = i;
+ the_codecs[i].codecs_ioctrl = func;
+ init_MUTEX(&(the_codecs[i].i2s_sem));
+ break;
+ }
+ }
+
+ LEAVE();
+}
+
+#define codec_ioctrl(codec, cmd, args) ({ \
+ int result; \
+ down(&(codec)->i2s_sem); \
+ result = (codec)->codecs_ioctrl((codec), (cmd), (args));\
+ up(&(codec)->i2s_sem); \
+ result; \
+})
+
+static int jz_i2s_open_mixdev(struct inode *inode, struct file *file)
+{
+ int i;
+ int minor = MINOR(inode->i_rdev);
+
+ ENTER();
+
+ for (i = 0; i < NR_I2S; i++) {
+ if (the_codecs[i].dev_mixer == minor) {
+ goto match;
+ }
+ }
+match:
+ file->private_data = &the_codecs[i];
+
+ LEAVE();
+ return 0;
+}
+
+/*
+ * Debug entry for Android
+ */
+static int jz_i2s_write_mixdev(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct i2s_codec *codec = (struct i2s_codec *)file->private_data;
+ char buf_byte = 0;
+ char argument[16];
+ int val;
+
+ if (copy_from_user((void *)&buf_byte, buffer, 1)) {
+ printk("JZ MIX: copy_from_user failed !\n");
+ return -EFAULT;
+ }
+
+ switch (buf_byte) {
+ case '1':
+ dump_dlv_regs("jz_i2s_write_mixdev --- debug routine");
+ dump_aic_regs("");
+ break;
+ case '2':
+ printk("dlv_set_replay\n");
+ codec_ioctrl(codec, CODEC_SET_REPLAY, 0);
+ break;
+ case '3':
+ printk("dlv_set_record\n");
+ codec_ioctrl(codec, CODEC_SET_RECORD, 0);
+ break;
+ case '4':
+ if (codec_ioctrl(codec, CODEC_SET_RECORD_DATA_WIDTH, 16) >= 0) {
+ printk("Set data width : 16\n");
+ } else {
+ printk("Could not set data width\n");
+ }
+ break;
+ case '5':
+ if (copy_from_user((void *)&argument, buffer + 1, 3)) {
+ printk("JZ MIX: copy_from_user failed !\n");
+ return -EFAULT;
+ }
+ if (argument[0] >= '0' && argument[0] <= '9'
+ && argument [1] >= '0' && argument[1] <= '9'
+ && argument [2] >= '0' && argument[2] <= '9') {
+
+ val = (argument[0] - '0') * 100 + (argument[1] - '0') * 10 + argument[2] - '0';
+
+ printk("JZ MIX: set volume (%d)\n", val);
+ codec_ioctrl(codec, CODEC_SET_VOLUME, val);
+ } else {
+ printk("JZ MIX: invalid argument for set volume\n");
+ }
+ break;
+ }
+
+ return count;
+}
+
+/*
+ * Handle IOCTL request on /dev/mixer
+ *
+ * Support OSS IOCTL interfaces for /dev/mixer
+ * Support IOCTL interfaces for /dev/mixer defined in include/msm_audio.h
+ */
+static int jz_i2s_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct i2s_codec *codec = (struct i2s_codec *)file->private_data;
+ long val = 0;
+ int ret, rc = 0;
+
+ ENTER();
+
+ DPRINT_IOC("[mixer IOCTL]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+ DPRINT_IOC(" mixer IOCTL %s cmd = 0x%08x, arg = %lu\n", __FUNCTION__, cmd, arg);
+ DPRINT_MIXER_IOC_CMD(cmd);
+ DPRINT_IOC("[mixer IOCTL]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
+
+ // struct jz_i2s_controller_info *controller = (struct jz_i2s_controller_info *) file->private_data;
+
+ switch (cmd) {
+
+ /*
+ * OSS IOCTL commands for /dev/mixer
+ */
+ case SOUND_MIXER_INFO:
+ {
+ mixer_info info;
+ codec_ioctrl(codec, CODEC_GET_MIXER_INFO, (unsigned int)&info);
+ info.modify_counter = audio_mix_modcnt;
+ return copy_to_user((void *)arg, &info, sizeof(info));
+ }
+ case SOUND_OLD_MIXER_INFO:
+ {
+ _old_mixer_info info;
+ codec_ioctrl(codec, CODEC_GET_MIXER_OLD_INFO, (unsigned int)&info);
+ return copy_to_user((void *)arg, &info, sizeof(info));
+ }
+
+ case SOUND_MIXER_READ_STEREODEVS:
+ return put_user(0, (long *) arg);
+ case SOUND_MIXER_READ_CAPS:
+ return put_user(SOUND_CAP_EXCL_INPUT, (long *) arg);
+
+ case SOUND_MIXER_READ_DEVMASK:
+ break;
+ case SOUND_MIXER_READ_RECMASK:
+ break;
+ case SOUND_MIXER_READ_RECSRC:
+ break;
+
+ case SOUND_MIXER_WRITE_SPEAKER:
+ ret = get_user(val, (long *) arg);
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+ codec_ioctrl(codec, CODEC_SET_DIRECT_MODE, val);
+ break;
+
+ case SOUND_MIXER_WRITE_BASS:
+ ret = get_user(val, (long *) arg);
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+ codec->bass_gain = val;
+ codec_ioctrl(codec, CODEC_SET_BASS, val);
+ return 0;
+
+ case SOUND_MIXER_READ_BASS:
+ val = codec->bass_gain;
+ ret = val << 8;
+ val = val | ret;
+ return put_user(val, (long *) arg);
+
+ case SOUND_MIXER_WRITE_VOLUME:
+ ret = get_user(val, (long *) arg);
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+
+ DPRINT_IOC("SOUND_MIXER_WRITE_VOLUME <- %lu\n", val);
+
+ codec->audio_volume = val;
+ codec_ioctrl(codec, CODEC_SET_VOLUME, val);
+ return 0;
+
+ case SOUND_MIXER_READ_VOLUME:
+ val = codec->audio_volume;
+ ret = val << 8;
+ val = val | ret;
+ return put_user(val, (long *) arg);
+
+ case SOUND_MIXER_WRITE_MIC:
+ ret = get_user(val, (long *) arg);
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+ codec->mic_gain = val;
+ codec->use_mic_line_flag = USE_MIC;
+ codec_ioctrl(codec, CODEC_SET_MIC, val);
+ return 0;
+
+ case SOUND_MIXER_READ_MIC:
+ val = codec->mic_gain;
+ ret = val << 8;
+ val = val | ret;
+ return put_user(val, (long *) arg);
+
+ case SOUND_MIXER_WRITE_LINE:
+ ret = get_user(val, (long *) arg);
+ if (ret) {
+ return ret;
+ }
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+ codec->use_mic_line_flag = USE_LINEIN;
+ codec->mic_gain = val;
+ codec_ioctrl(codec, CODEC_SET_LINE, val);
+ return 0;
+
+ case SOUND_MIXER_READ_LINE:
+ val = codec->mic_gain;
+ ret = val << 8;
+ val = val | ret;
+ return put_user(val, (long *) arg);
+
+ case SOUND_MIXER_WRITE_MUTE:
+ get_user(codec->audiomute, (long *)arg);
+ //codec_ioctrl(codec, CODEC_DAC_MUTE, codec->audiomute);
+ break;
+
+ case SOUND_MIXER_READ_MUTE:
+ put_user(codec->audiomute, (long *) arg);
+ break;
+
+#if 0
+ /*
+ * MSM IOCTL commands for /dev/mixer
+ */
+ case SND_SET_DEVICE:
+ {
+ struct snd_device_config dev;
+ if (copy_from_user(&dev, (void *) arg, sizeof(dev))) {
+ rc = -EFAULT;
+ break;
+ }
+ break;
+ }
+
+ case SND_SET_VOLUME:
+ {
+ struct snd_volume_config vol;
+ if (copy_from_user(&vol, (void *) arg, sizeof(vol))) {
+ return -EFAULT;
+ }
+ val = vol.volume;
+ if ((val &= 0xff) >= 100) {
+ val = 100;
+ }
+ DPRINT_IOC("snd_set_volume %d %d %d\n", vol.device, vol.method, vol.volume);
+ codec->audio_volume = val;
+ codec_ioctrl(codec, CODEC_SET_MIC, (unsigned int)&val); ///??????????????????????????
+ //error
+ break;
+ }
+
+ case SND_GET_NUM_ENDPOINTS:
+ if (copy_to_user((void __user*) arg, &snd->snd_epts->num, sizeof(unsigned))) {
+ printk("%s: error get endpoint\n",__FUNCTION__);
+ rc = -EFAULT;
+ }
+ val = 2;
+ if (copy_to_user((void __user*) arg, &val, sizeof(unsigned))) {
+ printk("%s: error get endpoint\n",__FUNCTION__);
+ rc = -EFAULT;
+ }
+
+ break;
+ case SND_GET_ENDPOINT:
+ //rc = get_endpoint(snd, arg);
+ break;
+#endif
+
+ default:
+ printk("Mixer IOCTL error: %s:%d: known command: 0x%08x\n", __FUNCTION__, __LINE__, cmd);
+ return -ENOSYS;
+ }
+ audio_mix_modcnt++;
+
+ LEAVE();
+ return rc;
+}
+
+static struct file_operations jz_i2s_mixer_fops =
+{
+ owner: THIS_MODULE,
+ ioctl: jz_i2s_ioctl_mixdev,
+ open: jz_i2s_open_mixdev,
+ write: jz_i2s_write_mixdev,
+};
+
+int i2s_probe_codec(struct i2s_codec *codec)
+{
+ /* generic OSS to I2S wrapper */
+ return (codec->codecs_ioctrl) ? 1 : 0;
+}
+
+/* I2S codec initialisation. */
+static int __init jz_i2s_codec_init(struct jz_i2s_controller_info *controller)
+{
+ int i;
+
+ ENTER();
+
+ for (i = 0; i < NR_I2S; i++) {
+ the_codecs[i].private_data = controller;
+ if (i2s_probe_codec(&the_codecs[i]) == 0) {
+ break;
+ }
+ if ((the_codecs[i].dev_mixer = register_sound_mixer(&jz_i2s_mixer_fops, the_codecs[i].id)) < 0) {
+ printk(KERN_ERR "JZ I2S: couldn't register mixer!\n");
+ break;
+ }
+
+ }
+ controller->i2s_codec = &the_codecs[0];
+
+ LEAVE();
+ return i;
+}
+
+static void jz_i2s_reinit_hw(struct i2s_codec *codec, int mode)
+{
+ ENTER();
+
+ __i2s_disable();
+ schedule_timeout(5);
+ codec_ioctrl(codec, CODEC_EACH_TIME_INIT, 0);
+ __i2s_disable_record();
+ __i2s_disable_replay();
+ __i2s_disable_loopback();
+ __i2s_set_transmit_trigger(4);
+ __i2s_set_receive_trigger(3);
+
+ LEAVE();
+}
+
+static int jz_codec_set_speed(struct i2s_codec *codec, int rate, int mode)
+{
+ ENTER();
+
+ /* 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 ? */
+ if (mode & CODEC_RMODE) {
+ rate = codec_ioctrl(codec, CODEC_SET_RECORD_SPEED, rate);
+ if (rate > 0) {
+ codec->record_audio_rate = rate;
+ } else {
+ rate = codec->record_audio_rate;
+ }
+ }
+ if (mode & CODEC_WMODE) {
+ rate = codec_ioctrl(codec, CODEC_SET_REPLAY_SPEED, rate);
+ if (rate > 0) {
+ codec->replay_audio_rate = rate;
+ } else {
+ rate = codec->replay_audio_rate;
+ }
+ }
+
+ LEAVE();
+ return rate;
+}
+
+static short jz_codec_set_channels(struct i2s_codec *codec, short channels, int mode)
+{
+ ENTER();
+
+ DPRINT_IOC("%s mode = %x channels = %d\n", __FUNCTION__, mode, channels);
+ DPRINT_IOC("mode & CODEC_RMODE == %x", mode & CODEC_RMODE);
+
+ if (mode & CODEC_RMODE) {
+ channels = codec_ioctrl(codec, CODEC_SET_RECORD_CHANNEL, channels);
+ codec->record_codec_channel = channels;
+ }
+ if (mode & CODEC_WMODE) {
+ channels = codec_ioctrl(codec, CODEC_SET_REPLAY_CHANNEL, channels);
+ codec->replay_codec_channel = channels;
+ if (channels == 1) {
+ __aic_enable_mono2stereo();
+ } else {
+ __aic_disable_mono2stereo();
+ }
+ }
+
+ LEAVE();
+
+ return channels;
+}
+
+static void jz_codec_select_mode(struct i2s_codec *codec, int mode)
+{
+ ENTER();
+
+ switch (mode) {
+ case CODEC_WRMODE:
+ if (codec->use_mic_line_flag == USE_NONE) {
+ codec->use_mic_line_flag = USE_MIC;
+ }
+ codec_ioctrl(codec, CODEC_SET_REPLAY_RECORD, codec->use_mic_line_flag);
+ break;
+ case CODEC_RMODE:
+ if (codec->use_mic_line_flag == USE_NONE) {
+ codec->use_mic_line_flag = USE_MIC;
+ }
+ codec_ioctrl(codec, CODEC_SET_RECORD, codec->use_mic_line_flag);
+ break;
+ case CODEC_WMODE:
+ codec_ioctrl(codec, CODEC_SET_REPLAY, mode);
+ break;
+ }
+
+ LEAVE();
+}
+
+void jz_codec_anti_pop(struct i2s_codec *codec, int mode)
+{
+ ENTER();
+ codec_ioctrl(codec, CODEC_ANTI_POP, mode);
+ LEAVE();
+}
+
+void jz_codec_close(struct i2s_codec *codec, int mode)
+{
+ ENTER();
+ down(&codec->i2s_sem);
+ codec->codecs_ioctrl(codec, CODEC_TURN_OFF, mode);
+ up(&codec->i2s_sem);
+ LEAVE();
+}
+
+/***************************************************************
+ filter functions
+ ***************************************************************/
+
+/*
+ * Convert signed byte to unsiged byte
+ *
+ * Mapping:
+ * signed unsigned
+ * 0x00 (0) 0x80 (128)
+ * 0x01 (1) 0x81 (129)
+ * ...... ......
+ * 0x7f (127) 0xff (255)
+ * 0x80 (-128) 0x00 (0)
+ * 0x81 (-127) 0x01 (1)
+ * ...... ......
+ * 0xff (-1) 0x7f (127)
+ */
+static int convert_8bits_signed2unsigned(void *buffer, int counter)
+{
+ int i;
+ int counter_8align = counter & ~0x7;
+ unsigned char *ucsrc = buffer;
+ unsigned char *ucdst = buffer;
+
+ ENTER();
+
+ for (i = 0; i < counter_8align; i+=8) {
+ *(ucdst + i + 0) = *(ucsrc + i + 0) + 0x80;
+ *(ucdst + i + 1) = *(ucsrc + i + 1) + 0x80;
+ *(ucdst + i + 2) = *(ucsrc + i + 2) + 0x80;
+ *(ucdst + i + 3) = *(ucsrc + i + 3) + 0x80;
+ *(ucdst + i + 4) = *(ucsrc + i + 4) + 0x80;
+ *(ucdst + i + 5) = *(ucsrc + i + 5) + 0x80;
+ *(ucdst + i + 6) = *(ucsrc + i + 6) + 0x80;
+ *(ucdst + i + 7) = *(ucsrc + i + 7) + 0x80;
+ //printk("csrc + %d + 7 = %d, ucdst + %d + 7 = %d\n",
+ // i, *(csrc + i + 7), i, *(ucdst + i + 7));
+ }
+
+ BUG_ON(i != counter_8align);
+
+ for (i = counter_8align; i < counter; i++) {
+ *(ucdst + i) = *(ucsrc + i) + 0x80;
+ }
+
+ //printk("[dbg] src = 0x%02x (%d) --- dst = 0x%02x (%d), cnt = %d, cnt8a = %d\n",
+ // *csrc, *csrc, *ucdst, *ucdst, counter, counter_8align);
+ LEAVE();
+ return counter;
+}
+
+/*
+ * Convert stereo data to mono data, data width: 8 bits/channel
+ *
+ * buff: buffer address
+ * data_len: data length in kernel space, the length of stereo data
+ * calculated by "node->end - node->start"
+ */
+int convert_8bits_stereo2mono(void *buff, int data_len)
+{
+ /* stride = 16 bytes = 2 channels * 1 byte * 8 pipelines */
+ int data_len_16aligned = data_len & ~0xf;
+ int mono_cur, stereo_cur;
+ unsigned char *uc_buff = buff;
+
+ /* copy 8 times each loop */
+ for (stereo_cur = mono_cur = 0;
+ stereo_cur < data_len_16aligned;
+ stereo_cur += 16, mono_cur += 8) {
+
+ uc_buff[mono_cur + 0] = uc_buff[stereo_cur + 0];
+ uc_buff[mono_cur + 1] = uc_buff[stereo_cur + 2];
+ uc_buff[mono_cur + 2] = uc_buff[stereo_cur + 4];
+ uc_buff[mono_cur + 3] = uc_buff[stereo_cur + 6];
+ uc_buff[mono_cur + 4] = uc_buff[stereo_cur + 8];
+ uc_buff[mono_cur + 5] = uc_buff[stereo_cur + 10];
+ uc_buff[mono_cur + 6] = uc_buff[stereo_cur + 12];
+ uc_buff[mono_cur + 7] = uc_buff[stereo_cur + 14];
+ }
+
+ BUG_ON(stereo_cur != data_len_16aligned);
+
+ /* remaining data */
+ for (; stereo_cur < data_len; stereo_cur += 2, mono_cur++) {
+ uc_buff[mono_cur] = uc_buff[stereo_cur];
+ }
+
+ LEAVE();
+ return (data_len / 2);
+}
+
+/*
+ * Convert stereo data to mono data, and convert signed byte to unsigned byte.
+ *
+ * data width: 8 bits/channel
+ *
+ * buff: buffer address
+ * data_len: data length in kernel space, the length of stereo data
+ * calculated by "node->end - node->start"
+ */
+int convert_8bits_stereo2mono_signed2unsigned(void *buff, int data_len)
+{
+ /* stride = 16 bytes = 2 channels * 1 byte * 8 pipelines */
+ int data_len_16aligned = data_len & ~0xf;
+ int mono_cur, stereo_cur;
+ unsigned char *uc_buff = buff;
+
+ /* copy 8 times each loop */
+ for (stereo_cur = mono_cur = 0;
+ stereo_cur < data_len_16aligned;
+ stereo_cur += 16, mono_cur += 8) {
+
+ uc_buff[mono_cur + 0] = uc_buff[stereo_cur + 0] + 0x80;
+ uc_buff[mono_cur + 1] = uc_buff[stereo_cur + 2] + 0x80;
+ uc_buff[mono_cur + 2] = uc_buff[stereo_cur + 4] + 0x80;
+ uc_buff[mono_cur + 3] = uc_buff[stereo_cur + 6] + 0x80;
+ uc_buff[mono_cur + 4] = uc_buff[stereo_cur + 8] + 0x80;
+ uc_buff[mono_cur + 5] = uc_buff[stereo_cur + 10] + 0x80;
+ uc_buff[mono_cur + 6] = uc_buff[stereo_cur + 12] + 0x80;
+ uc_buff[mono_cur + 7] = uc_buff[stereo_cur + 14] + 0x80;
+ }
+
+ BUG_ON(stereo_cur != data_len_16aligned);
+
+ /* remaining data */
+ for (; stereo_cur < data_len; stereo_cur += 2, mono_cur++) {
+ uc_buff[mono_cur] = uc_buff[stereo_cur] + 0x80;
+ }
+
+ LEAVE();
+ return (data_len / 2);
+}
+
+/*
+ * Convert stereo data to mono data, data width: 16 bits/channel
+ *
+ * buff: buffer address
+ * data_len: data length in kernel space, the length of stereo data
+ * calculated by "node->end - node->start"
+ */
+int convert_16bits_stereo2mono(void *buff, int data_len)
+{
+ /* stride = 32 bytes = 2 channels * 2 byte * 8 pipelines */
+ int data_len_32aligned = data_len & ~0x1f;
+ int data_cnt_ushort = data_len_32aligned / 2;
+ int mono_cur, stereo_cur;
+ unsigned short *ushort_buff = (unsigned short *)buff;
+
+ /* copy 8 times each loop */
+ for (stereo_cur = mono_cur = 0;
+ stereo_cur < data_cnt_ushort;
+ stereo_cur += 16, mono_cur += 8) {
+
+ ushort_buff[mono_cur + 0] = ushort_buff[stereo_cur + 0];
+ ushort_buff[mono_cur + 1] = ushort_buff[stereo_cur + 2];
+ ushort_buff[mono_cur + 2] = ushort_buff[stereo_cur + 4];
+ ushort_buff[mono_cur + 3] = ushort_buff[stereo_cur + 6];
+ ushort_buff[mono_cur + 4] = ushort_buff[stereo_cur + 8];
+ ushort_buff[mono_cur + 5] = ushort_buff[stereo_cur + 10];
+ ushort_buff[mono_cur + 6] = ushort_buff[stereo_cur + 12];
+ ushort_buff[mono_cur + 7] = ushort_buff[stereo_cur + 14];
+ }
+
+ BUG_ON(stereo_cur != data_cnt_ushort);
+
+ /* remaining data */
+ for (; stereo_cur < data_cnt_ushort; stereo_cur += 2, mono_cur++) {
+ ushort_buff[mono_cur] = ushort_buff[stereo_cur];
+ }
+
+ LEAVE();
+ return (data_len / 2);
+}
+
+/*
+ * Set convert function for audio_pipe
+ *
+ * In AIC, we just use signed data for all ops as it is shared by
+ * replay and record. So, converting data for every non-compatible
+ * format is neccessary.
+ */
+static inline int endpoint_set_filter(audio_pipe *endpoint, int format, int channels)
+{
+ ENTER();
+
+ DPRINT("%s %d, endpoint = 0x%08x, format = %d, channels = %d\n",
+ __FUNCTION__, __LINE__, (unsigned int)endpoint, format, channels);
+
+ endpoint->filter = NULL;
+
+ switch (format) {
+ case AFMT_U8:
+ if (endpoint == &in_endpoint) {
+ if (channels == 2) {
+ endpoint->filter = convert_8bits_stereo2mono_signed2unsigned;
+ DPRINT("$$$$ set pin_endpoint->filter = convert_8bits_stereo_2_mono\n");
+ } else {
+ endpoint->filter = convert_8bits_signed2unsigned;
+ DPRINT("$$$$ set pin_endpoint->filter = convert_8bits_signed2unsigned\n");
+ }
+ }
+ break;
+ case AFMT_S16_LE:
+ if (endpoint == &in_endpoint) {
+ if (channels == 1) {
+ endpoint->filter = convert_16bits_stereo2mono;
+ DPRINT("$$$$ set pin_endpoint->filter = convert_16bits_stereo2mono\n");
+ } else {
+ endpoint->filter = NULL;
+ DPRINT("$$$$ set pin_endpoint->filter = NULL\n");
+ }
+ }
+ break;
+ default:
+ printk("JZ I2S endpoint_set_filter: unknown format\n");
+ endpoint->filter = NULL;
+ }
+
+ LEAVE();
+ return 0;
+}
+
+/*
+ * The "format" contains data width, signed/unsigned and LE/BE
+ *
+ * The AIC registers will not be modified !
+ *
+ * For CODEC set data_width
+ */
+static int jz_codec_set_format(struct i2s_codec *codec, unsigned int format, int mode)
+{
+ /* The value of format reference to soundcard.h:
+ *
+ * AFMT_MU_LAW 0x00000001
+ * AFMT_A_LAW 0x00000002
+ * AFMT_IMA_ADPCM 0x00000004
+ * AFMT_U8 0x00000008
+ * AFMT_S16_LE 0x00000010
+ * AFMT_S16_BE 0x00000020
+ * AFMT_S8 0x00000040
+ */
+ int data_width = 0;
+
+ ENTER();
+
+ DPRINT("$$$$ %s %d, format = %u, mode = %d\n", __FUNCTION__, __LINE__, format, mode);
+
+ down(&codec->i2s_sem);
+
+ /*
+ * It is dangerous to modify settings about signed bit, endian and M2S
+ * as record and replay shared the settings.
+ *
+ * Now we don't support unsigned format (AFMT_U8) and BE format (AFMT_S16_BE)
+ * To support such format, corresponding filter function must be implemented.
+ */
+ switch (format) {
+ case AFMT_U8:
+ data_width = 8;
+ if (mode & CODEC_RMODE) {
+ __i2s_set_iss_sample_size(8);
+ }
+ if (mode & CODEC_WMODE) {
+ __i2s_set_oss_sample_size(8);
+ }
+ break;
+ case AFMT_S8:
+ data_width = 8;
+ if (mode & CODEC_RMODE) {
+ __i2s_set_iss_sample_size(8);
+ }
+ if (mode & CODEC_WMODE) {
+ __i2s_set_oss_sample_size(8);
+ }
+ break;
+ case AFMT_S16_LE:
+ data_width = 16;
+ if (mode & CODEC_RMODE) {
+ __i2s_set_iss_sample_size(16);
+ }
+ if (mode & CODEC_WMODE) {
+ __i2s_set_oss_sample_size(16);
+ }
+ break;
+ case AFMT_S16_BE:
+ data_width = 16;
+ if (mode & CODEC_RMODE) {
+ __i2s_set_iss_sample_size(16);
+ }
+ if (mode & CODEC_WMODE) {
+ __i2s_set_oss_sample_size(16);
+ }
+ break;
+ default:
+ printk("JZ I2S: Unkown sound format %d\n", format);
+ goto _ERROR_SET_FORMAT;
+ }
+
+ if (mode & CODEC_RMODE) {
+ if (codec->codecs_ioctrl(codec, CODEC_SET_RECORD_DATA_WIDTH, data_width) < 0) {
+ printk("JZ I2S: CODEC ioctl error, command: CODEC_SET_RECORD_FORMAT");
+ goto _ERROR_SET_FORMAT;
+ }
+ codec->record_format = format;
+ }
+
+ if (mode & CODEC_WMODE) {
+ if (codec->codecs_ioctrl(codec, CODEC_SET_REPLAY_DATA_WIDTH, data_width) < 0) {
+ printk("JZ I2S: CODEC ioctl error, command: CODEC_SET_REPLAY_FORMAT");
+ goto _ERROR_SET_FORMAT;
+ }
+ codec->replay_format = format;
+ }
+
+ up(&codec->i2s_sem);
+ LEAVE();
+ return format;
+
+_ERROR_SET_FORMAT:
+ up(&codec->i2s_sem);
+ LEAVE();
+ return -1;
+}
+
+static int jz_audio_release(struct inode *inode, struct file *file)
+{
+ struct jz_i2s_controller_info *controller = (struct jz_i2s_controller_info *) file->private_data;
+ int mode = 0;
+
+ ENTER();
+
+ if (controller == NULL) {
+ printk("\nAudio device not ready!\n");
+ return -ENODEV;
+ }
+ if ((controller->pin_endpoint == NULL) && (controller->pout_endpoint == NULL) ) {
+ printk("\nAudio endpoint not open!\n");
+ return -ENODEV;
+ }
+ if ((file->f_mode & FMODE_READ) && controller->pin_endpoint) {
+ printk("Read mode, %s\n", __FUNCTION__);
+ mode |= CODEC_RMODE;
+ audio_close_endpoint(controller->pin_endpoint, FORCE_STOP);
+ controller->pin_endpoint = NULL;
+
+ __i2s_disable_receive_dma();
+ __i2s_disable_record();
+ }
+
+ if ((file->f_mode & FMODE_WRITE) && controller->pout_endpoint) {
+ printk("Write mode, %s\n", __FUNCTION__);
+ mode |= CODEC_WMODE;
+ audio_close_endpoint(controller->pout_endpoint, NOMAL_STOP);
+ controller->pout_endpoint = NULL;
+
+ __i2s_disable_transmit_dma();
+ __i2s_disable_replay();
+ }
+
+
+ if ((controller->pin_endpoint == NULL) && (controller->pout_endpoint == NULL) ) {
+ __i2s_disable();
+ }
+
+ jz_codec_close(controller->i2s_codec, mode);
+
+ LEAVE();
+ return 0;
+}
+
+static int jz_audio_open(struct inode *inode, struct file *file)
+{
+ struct jz_i2s_controller_info *controller = the_i2s_controller;
+ struct i2s_codec *codec = controller->i2s_codec;
+ int mode = 0;
+ int reset = 1;
+
+ ENTER();
+
+ if (controller == NULL) {
+ return -ENODEV;
+ }
+
+ if (controller->pin_endpoint || controller->pout_endpoint) {
+ reset = 0;
+ }
+
+ if ((file->f_mode & FMODE_READ) && (controller->pin_endpoint)) {
+ printk("\nAudio read device is busy!\n");
+ return -EBUSY;
+ }
+ if ((file->f_mode & FMODE_WRITE) && (controller->pout_endpoint)) {
+ printk("\nAudio write device is busy!\n");
+ return -EBUSY;
+ }
+
+ if (file->f_mode & FMODE_WRITE) {
+ controller->pout_endpoint = &out_endpoint;
+ controller->pout_endpoint->is_non_block = file->f_flags & O_NONBLOCK;
+ mode |= CODEC_WMODE;
+ }
+ if (file->f_mode & FMODE_READ) {
+ controller->pin_endpoint = &in_endpoint;
+ controller->pin_endpoint->is_non_block = file->f_flags & O_NONBLOCK;
+ mode |= CODEC_RMODE;
+ }
+ file->private_data = controller;
+
+ if (mode & CODEC_RMODE){
+/*
+ jz_codec_set_channels(codec, 2, CODEC_RMODE);
+ jz_codec_set_format(codec, 8, CODEC_RMODE);
+ jz_codec_set_speed(codec, 8000, CODEC_RMODE);
+*/
+ jz_codec_set_channels(codec, 2, CODEC_RMODE);
+ jz_codec_set_format(codec, 16, CODEC_RMODE);
+ jz_codec_set_speed(codec, 44100, CODEC_RMODE);
+ codec->user_need_mono = 0;
+
+ set_controller_triger(controller, &in_endpoint, codec->record_codec_channel, codec->record_format);
+ }
+ if (mode & CODEC_WMODE) {
+ jz_codec_set_channels(codec, 2, CODEC_WMODE);
+ jz_codec_set_format(codec, 16, CODEC_WMODE);
+ jz_codec_set_speed(codec, 44100, CODEC_WMODE);
+ set_controller_triger(controller, &out_endpoint, codec->replay_codec_channel, codec->replay_format);
+ }
+
+ DPRINT_IOC("============ default_codec record ===============\n"
+ "format = %d\n"
+ "channels = %d\n"
+ "rate = %d\n"
+ "dma one tran bit = %d\n",
+ codec->record_format, codec->record_codec_channel,
+ codec->record_audio_rate, in_endpoint.dma.onetrans_bit);
+
+ DPRINT_IOC("============ default_codec replay ===============\n"
+ "format = %d\n"
+ "channels = %d\n"
+ "rate = %d\n"
+ "dma one tran bit = %d\n",
+ codec->replay_format, codec->replay_codec_channel,
+ codec->replay_audio_rate, out_endpoint.dma.onetrans_bit);
+
+ jz_codec_select_mode(controller->i2s_codec, mode);
+
+ /* note: reset AIC protected REG_AIC_I2SCR.ECCLK is setting */
+ if (reset) {
+ down(&controller->i2s_codec->i2s_sem);
+ //__i2s_enable_transmit_dma();
+ //__i2s_enable_receive_dma();
+ //__i2s_enable_replay();
+ __i2s_enable();
+ up(&controller->i2s_codec->i2s_sem);
+ }
+ //reinit codec option
+
+ //DUMP_AIC_REGS();
+ DPRINT_TRC(".... jz_audio_open\n");
+
+ jz_codec_anti_pop(controller->i2s_codec, mode);
+
+ LEAVE();
+ return 0;
+}
+
+static int jz_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ long rc = -EINVAL;
+ int val = 0;
+ int mode = 0;
+
+ struct jz_i2s_controller_info *controller = (struct jz_i2s_controller_info *) file->private_data;
+ struct i2s_codec *codec = controller->i2s_codec;
+ audio_pipe *pin_endpoint = controller->pin_endpoint;
+ audio_pipe *pout_endpoint = controller->pout_endpoint;
+
+ ENTER();
+
+ DPRINT_IOC("[dsp IOCTL] --------------------------------\n");
+ DPRINT_IOC(" dsp IOCTL %s cmd = (0x%08x), arg = %lu\n", __FUNCTION__, cmd, arg);
+ DPRINT_DSP_IOC_CMD(cmd);
+ DPRINT_IOC("[dsp IOCTL] --------------------------------\n");
+
+ if (file->f_mode & FMODE_READ) {
+ mode |= CODEC_RMODE;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ mode |= CODEC_WMODE;
+ }
+
+ switch (cmd) {
+
+ case OSS_GETVERSION:
+ rc = put_user(SOUND_VERSION, (int *)arg);
+ break;
+ case SNDCTL_DSP_RESET:
+ break;
+
+ case SNDCTL_DSP_SYNC:
+ if (mode & CODEC_WMODE) {
+ if (pout_endpoint) {
+ audio_sync_endpoint(pout_endpoint);
+ }
+ }
+ rc = 1;
+ break;
+
+ case SNDCTL_DSP_SPEED:
+ /* set smaple rate */
+ if (get_user(val, (int *)arg)) {
+ rc = -EFAULT;
+ }
+ //printk("SNDCTL_DSP_SPEED ... set to %d\n", val);
+ val = jz_codec_set_speed(codec, val, mode);
+ rc = put_user(val, (int *)arg);
+ break;
+
+ case SNDCTL_DSP_STEREO:
+ /* set stereo or mono channel */
+ if (get_user(val, (int *)arg)) {
+ rc = -EFAULT;
+ }
+
+ jz_codec_set_channels(controller->i2s_codec, val ? 2 : 1, mode);
+
+ if (mode & CODEC_RMODE) {
+ set_controller_triger(controller, pin_endpoint,
+ codec->record_codec_channel, codec->record_format);
+ }
+
+ if (mode & CODEC_WMODE) {
+ set_controller_triger(controller, pout_endpoint,
+ codec->replay_codec_channel, codec->replay_format);
+ }
+
+ rc = 1;
+ break;
+
+ case SNDCTL_DSP_GETBLKSIZE:
+ {
+ // It seems that device could only be open with one mode (R or W)
+ int fragsize = 0;
+ if (mode & CODEC_RMODE) {
+ fragsize = pin_endpoint->fragsize;
+ }
+ if (mode & CODEC_WMODE) {
+ fragsize = pout_endpoint->fragsize;
+ }
+ rc = put_user(fragsize, (int *)arg);
+ break;
+ }
+
+ case SNDCTL_DSP_GETFMTS:
+ /* Returns a mask of supported sample format*/
+ rc = put_user(AFMT_U8 | AFMT_S16_LE, (int *)arg);
+ break;
+
+ case SNDCTL_DSP_SETFMT:
+ /* Select sample format */
+ if (get_user(val, (int *)arg)) {
+ rc = -EFAULT;
+ }
+
+ printk("\nSNDCTL_DSP_SETFMT ... set to %d\n", val);
+
+ if (val == AFMT_QUERY) {
+ if (mode & CODEC_RMODE) {
+ val = codec->record_format;
+ } else {
+ val = codec->replay_format;
+ }
+ } else {
+ val = jz_codec_set_format(codec, val, mode);
+ if (mode & CODEC_RMODE) {
+ if (codec->user_need_mono) {
+ endpoint_set_filter(pin_endpoint, val, 1);
+ } else {
+ endpoint_set_filter(pin_endpoint, val, 2);
+ }
+
+ set_controller_triger(controller, pin_endpoint,
+ codec->record_codec_channel, codec->record_format);
+ }
+ if (mode & CODEC_WMODE) {
+ set_controller_triger(controller, pout_endpoint,
+ codec->replay_codec_channel, codec->replay_format);
+ }
+ }
+
+ rc = put_user(val, (int *)arg);
+ break;
+
+ case SNDCTL_DSP_CHANNELS:
+ if (get_user(val, (int *)arg)) {
+ rc = -EFAULT;
+ }
+ //printk("\nSNDCTL_DSP_CHANNELS ... set to %d\n", val);
+
+ /* if mono, change to 2, and set 1 to codec->user_need_mono */
+ if (val == 1) {
+ val = 2;
+ codec->user_need_mono = 1;
+
+ } else {
+ codec->user_need_mono = 0;
+ }
+
+ /* Following lines could be marked as nothing will be changed */
+ jz_codec_set_channels(codec, val, mode);
+
+ if (mode & CODEC_RMODE) {
+ /* Set filter according to channel count */
+ if (codec->user_need_mono) {
+ endpoint_set_filter(pin_endpoint, codec->record_format, 1);
+ } else {
+ endpoint_set_filter(pin_endpoint, codec->record_format, 2);
+ }
+
+ set_controller_triger(controller, pin_endpoint,
+ codec->record_codec_channel, codec->record_format);
+ }
+ if (mode & CODEC_WMODE) {
+ set_controller_triger(controller, pout_endpoint,
+ codec->replay_codec_channel, codec->replay_format);
+ }
+
+ /* Restore for return value */
+ if (codec->user_need_mono) {
+ val = 1;
+ }
+
+ rc = put_user(val, (int *)arg);
+ break;
+
+ case SNDCTL_DSP_POST:
+ /* FIXME: the same as RESET ?? */
+ break;
+
+ case SNDCTL_DSP_SUBDIVIDE:
+ break;
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ rc = get_user(val, (long *) arg);
+ if (rc != -EINVAL) {
+ int newfragsize, newfragstotal;
+ newfragsize = 1 << (val & 0xFFFF);
+ if (newfragsize < 4 * PAGE_SIZE) {
+ newfragsize = 4 * PAGE_SIZE;
+ }
+ if (newfragsize > (16 * PAGE_SIZE)) {
+ newfragsize = 16 * PAGE_SIZE;
+ }
+
+ newfragstotal = (val >> 16) & 0x7FFF;
+ if (newfragstotal < 2) {
+ newfragstotal = 2;
+ }
+ if (newfragstotal > 32) {
+ newfragstotal = 32;
+ }
+
+ if (mode & CODEC_RMODE) {
+ rc = audio_resizemem_endpoint(controller->pin_endpoint, newfragsize, newfragstotal);
+ if (!rc) {
+ rc = -EINVAL;
+ }
+ }
+ if (mode & CODEC_WMODE) {
+ rc = audio_resizemem_endpoint(controller->pout_endpoint, newfragsize, newfragstotal);
+ if (!rc) {
+ rc = -EINVAL;
+ }
+ }
+ }
+ break;
+
+ case SNDCTL_DSP_GETCAPS:
+ rc = put_user(DSP_CAP_REALTIME | DSP_CAP_BATCH, (int *)arg);
+ break;
+
+ case SNDCTL_DSP_NONBLOCK:
+ file->f_flags |= O_NONBLOCK;
+ rc = 0;
+ break;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ rc = -EINVAL;
+ break;
+
+ case SNDCTL_DSP_GETOSPACE:
+ {
+ audio_buf_info abinfo;
+ if (!(mode & CODEC_WMODE)) {
+ return -EINVAL;
+ }
+ audio_get_endpoint_freesize(pout_endpoint, &abinfo);
+ rc = copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ break;
+ }
+
+ case SNDCTL_DSP_GETISPACE:
+ {
+ audio_buf_info abinfo;
+ if (!(mode & CODEC_RMODE)) {
+ return -EINVAL;
+ }
+ audio_get_endpoint_freesize(controller->pin_endpoint, &abinfo);
+ rc = copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+ break;
+ }
+
+ case SNDCTL_DSP_GETTRIGGER:
+ val = 0;
+ if ((mode & CODEC_RMODE) && controller->pin_endpoint) {
+ val |= PCM_ENABLE_INPUT;
+ }
+ if ((mode & CODEC_WMODE) && controller->pout_endpoint) {
+ val |= PCM_ENABLE_OUTPUT;
+ }
+ rc = put_user(val, (int *)arg);
+
+ break;
+
+ case SNDCTL_DSP_SETTRIGGER:
+ if (get_user(val, (int *)arg)) {
+ rc = -EFAULT;
+ }
+ break;
+
+ case SNDCTL_DSP_GETIPTR:
+ {
+ count_info cinfo;
+ if (!(mode & CODEC_RMODE)) {
+ rc = -EINVAL;
+ }
+ rc = copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+ break;
+ }
+
+ case SNDCTL_DSP_GETOPTR:
+ {
+ count_info cinfo;
+ if (!(mode & CODEC_WMODE)) {
+ rc = -EINVAL;
+ }
+ rc = copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+ break;
+ }
+
+ case SNDCTL_DSP_GETODELAY:
+ {
+ // fix me !!!
+ int unfinish = 0;
+ if (!(mode & CODEC_WMODE)) {
+ rc = -EINVAL;
+ }
+ rc = put_user(unfinish, (int *) arg);
+ break;
+ }
+
+ case SOUND_PCM_READ_RATE:
+ if (mode & CODEC_RMODE) {
+ //printk("\nSOUND_PCM_READ_RATE = %d\n", codec->record_audio_rate);
+ rc = put_user(codec->record_audio_rate, (int *)arg);
+ }
+ if (mode & CODEC_WMODE) {
+ //printk("\nSOUND_PCM_READ_RATE = %d\n", codec->replay_audio_rate);
+ rc = put_user(codec->replay_audio_rate, (int *)arg);
+ }
+ break;
+
+ case SOUND_PCM_READ_CHANNELS:
+ if (mode & CODEC_RMODE) {
+ //printk("\nSOUND_PCM_READ_RATE = %d\n", codec->record_codec_channel);
+ rc = put_user(codec->record_codec_channel, (int *)arg);
+ }
+ if (mode & CODEC_WMODE) {
+ //printk("\nSOUND_PCM_READ_RATE = %d\n", codec->replay_codec_channel);
+ rc = put_user(codec->replay_codec_channel, (int *)arg);
+ }
+ break;
+
+ case SOUND_PCM_READ_BITS:
+ if (mode & CODEC_RMODE) {
+ rc = put_user((codec->record_format & (AFMT_S8 | AFMT_U8)) ? 8 : 16, (int *)arg);
+ }
+ if (mode & CODEC_WMODE) {
+ rc = put_user((codec->record_format & (AFMT_S8 | AFMT_U8)) ? 8 : 16, (int *)arg);
+ }
+ break;
+
+ case SNDCTL_DSP_MAPINBUF:
+ case SNDCTL_DSP_MAPOUTBUF:
+ case SNDCTL_DSP_SETSYNCRO:
+ case SOUND_PCM_WRITE_FILTER:
+ case SOUND_PCM_READ_FILTER:
+ rc = -EINVAL;
+ break;
+#if 0
+ /* may be for msm only */
+ case AUDIO_GET_CONFIG:
+ break;
+
+ case AUDIO_SET_CONFIG:
+ break;
+#endif
+ default:
+ printk("%s[%s]:%d---no cmd\n",__FILE__,__FUNCTION__,__LINE__);
+ break;
+ }
+
+ LEAVE();
+
+ return rc;
+}
+
+static inline int endpoint_put_userdata(audio_pipe *endpoint, const char __user *buffer, size_t count)
+{
+ unsigned long flags;
+ audio_node *node;
+
+ ENTER();
+ DPRINT("<<<< put_userdata\n");
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ node = get_audio_freenode(endpoint->mem);
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ // For non-block mode
+ if (endpoint->is_non_block && !node) {
+ LEAVE();
+ return 0;
+ }
+
+ // For block mode, wait free node
+ while (!node) {
+ DPRINT("wait ----------\n");
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ // wait available node
+ wait_event_interruptible(endpoint->q_full, (endpoint->avialable_couter >= 1));
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ node = get_audio_freenode(endpoint->mem);
+ endpoint->avialable_couter = 0;
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ }
+
+ if (copy_from_user((void *)node->pBuf, buffer, count)) {
+ printk("JZ I2S: copy_from_user failed !\n");
+ return -EFAULT;
+ }
+ dma_cache_wback_inv((unsigned long)node->pBuf,(unsigned long)count);
+ node->start = 0;
+ node->end = count;
+ AUDIO_LOCK(endpoint->lock, flags);
+ put_audio_usenode(endpoint->mem, node);
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ LEAVE();
+
+ return count;
+}
+
+static ssize_t jz_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct jz_i2s_controller_info *controller = (struct jz_i2s_controller_info *)file->private_data;
+ audio_pipe *pout_endpoint = controller->pout_endpoint;
+ size_t usecount = 0;
+ int bat_cnt = -1;
+ int rem_cnt = 0;
+
+ ENTER();
+
+// dump_dlv_regs(__FUNCTION__);
+// dump_aic_regs(__FUNCTION__);
+
+ DPRINT("write data count = %d\n", count);
+
+ while (count >= pout_endpoint->fragsize) {
+
+ bat_cnt = endpoint_put_userdata(pout_endpoint,
+ &(buffer[usecount]),
+ pout_endpoint->fragsize);
+ // Prepare data success.
+ if (bat_cnt > 0) {
+ usecount += bat_cnt;
+ count -= bat_cnt;
+ DPRINT("bat_cnt = %d\n", bat_cnt);
+ }
+ // Perhaps non node is avialable.
+ else if (bat_cnt == 0) {
+ DPRINT("bat_cnt == 0\n");
+ break;
+ }
+ // Error occured.
+ else {
+ // break and handle prepared data.
+ if (usecount > 0) {
+ DPRINT("bat_cnt < 0, usecount > 0\n");
+ break;
+ }
+ // Has not prepared any data and return error when prepared data.
+ else {
+ DPRINT("bat_cnt < 0, usecount == 0\n");
+ return bat_cnt;
+ }
+ }
+ }
+
+ DPRINT("count = %d\n", count);
+
+ // Prepare few data or remain data after below code.
+ if (bat_cnt != 0 && count >= 32) {
+ DPRINT("check point 2 ... count = %d\n", count);
+ rem_cnt = endpoint_put_userdata(pout_endpoint, &buffer[usecount], count);
+ if (rem_cnt > 0) {
+ usecount += rem_cnt;
+ count -= rem_cnt;
+ DPRINT("check point 3 ... rem_cnt = %d\n", rem_cnt);
+ } else if (rem_cnt <= 0) {
+ // Not success... return Error.
+ if (usecount == 0) {
+ DPRINT("rem_cnt <= 0, usecount == 0\n");
+ return rem_cnt;
+ }
+ // Go on handle prepared data, ignore the error.
+ else {
+ DPRINT("rem_cnt <= 0, usecount != 0, usecount = %d\n", usecount);
+ }
+ }
+ }
+
+ // Handle prepared data.
+ if (usecount > 0) {
+ unsigned long flags;
+ audio_node *node;
+ AUDIO_LOCK(pout_endpoint->lock, flags);
+ if ((pout_endpoint->trans_state & PIPE_TRANS) == 0) {
+ node = get_audio_usenode(pout_endpoint->mem);
+ if (node) {
+ unsigned int start;
+ start = trystart_endpoint_out(controller, node);
+ if (start == 0) {
+ printk("JZ I2S: trystart_endpoint_out error\n");
+ }
+ }
+ }
+ AUDIO_UNLOCK(pout_endpoint->lock, flags);
+ }
+
+ DPRINT("----write data usecount = %d, count = %d\n", usecount, count);
+ BUG_ON(count < 0);
+ LEAVE();
+
+ return usecount + (count < 32 ? count : 0);
+}
+
+/**
+ * Copy recorded sound data from 'use' link list to userspace
+ */
+static inline int endpoint_get_userdata(audio_pipe *endpoint, const char __user *buffer, size_t count)
+{
+ unsigned long flags;
+ audio_node *node;
+ int ret;
+
+ /* counter for node buffer, raw data */
+ int node_buff_cnt = 0;
+ /* counter for node buffer after filte, fixed data */
+ int fixed_buff_cnt = 0;
+
+ ENTER();
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ node = get_audio_usenode(endpoint->mem);
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ DPRINT(">>>> %s mode\n", endpoint->is_non_block ? "non block" : "block");
+
+ // For non-block mode
+ if (endpoint->is_non_block && !node) {
+ return 0;
+ }
+
+ // For block mode, wait node which full filled data
+ while (!node) {
+ if ((endpoint->trans_state & PIPE_TRANS) == 0 ) {
+ DPRINT("DMA trans has not been started !\n");
+ return -1;
+ }
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ DUMP_LIST((audio_head *)endpoint->mem);
+ DUMP_NODE(endpoint->savenode, "SN");
+ AUDIO_UNLOCK(endpoint->lock, flags);
+
+ DPRINT("record stereo ... wait pipe_sem ----------\n");
+
+ // wait available node
+// interruptible_sleep_on(&endpoint->q_full);
+ wait_event_interruptible(endpoint->q_full, endpoint->avialable_couter >= 1);
+
+ AUDIO_LOCK(endpoint->lock, flags);
+ node = get_audio_usenode(endpoint->mem);
+ endpoint->avialable_couter = 0;
+ AUDIO_UNLOCK(endpoint->lock, flags);
+ }
+
+ if (node && (node_buff_cnt = node->end - node->start)) {
+ DPRINT("node_buff_cnt = %d, count = %d\n", node_buff_cnt, count);
+
+ if (endpoint->filter) {
+/*
+ printk("filter 3 ... %d\n", node_buff_cnt);
+ {
+ int i;
+ for (i = 100; i < 112; i++) {
+ printk("*(nod->pBuf + node_start + %d) = 0x%02x\n",
+ i, *(char *)(node->pBuf + node->start + i));
+ }
+ }
+*/
+ /* ret indicate that final data length when copy_to_user
+ * (node->end - node->start) may not equals to ret !
+ */
+ fixed_buff_cnt = endpoint->filter((void *)(node->pBuf + node->start), node_buff_cnt);
+/*
+ {
+ int i;
+ for (i = 100; i < 112; i++) {
+ printk("*(nod->pBuf + node_start + %d) = 0x%02x\n",
+ i, *(char *)(node->pBuf + node->start + i));
+ }
+ }
+*/
+ } else {
+ fixed_buff_cnt = node_buff_cnt;
+ }
+
+ if (count >= (size_t)fixed_buff_cnt) {
+ DPRINT(">>>> count >= fixed_buff_cnt, copy_to_user, fixed_buff_cnt = %d\n", fixed_buff_cnt);
+ ret = copy_to_user((void *)buffer, (void *)(node->pBuf + node->start), fixed_buff_cnt);
+ if (ret) {
+ printk("JZ I2S: copy_to_user failed, return %d\n", ret);
+ return -EFAULT;
+ }
+ put_audio_freenode(endpoint->mem, node);
+ } else {
+ DPRINT(">>>> count < fixed_buff_cnt, copy_to_user, fixed_buff_cnt = %d\n", fixed_buff_cnt);
+ ret = copy_to_user((void *)buffer,(void *)(node->pBuf + node->start), count);
+ if (ret) {
+ printk("JZ I2S: copy_to_user failed, return %d\n", ret);
+ return -EFAULT;
+ }
+ node->start += node_buff_cnt;
+ }
+ }
+
+ LEAVE();
+ return (fixed_buff_cnt < count ? fixed_buff_cnt : count);
+}
+
+static ssize_t jz_audio_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct jz_i2s_controller_info *controller = (struct jz_i2s_controller_info *)file->private_data;
+ audio_pipe *pin_endpoint = controller->pin_endpoint;
+ audio_node *node;
+ unsigned long flags;
+ int mcount, usecount = 0;
+
+ ENTER();
+
+// dump_dlv_regs(__FUNCTION__);
+// dump_aic_regs(__FUNCTION__);
+
+ if (count == 0) {
+ DPRINT("@@@@ jz_audio_read count == 0\n");
+ return 0;
+ }
+
+ AUDIO_LOCK(pin_endpoint->lock, flags);
+
+ DUMP_LIST((audio_head *)pin_endpoint->mem);
+ DUMP_NODE(pin_endpoint->savenode, "SN");
+
+ DPRINT("@@@@ jz_audio_read, pin_endpoint->trans_state = 0x%08x\n",
+ pin_endpoint->trans_state);
+
+ if ((pin_endpoint->trans_state & PIPE_TRANS) == 0) {
+ DPRINT("@@@@ jz_audio_read, PIPE_TRANS\n");
+ node = get_audio_freenode(pin_endpoint->mem);
+ if (node) {
+ unsigned int start;
+ DPRINT("@@@@ jz_audio_read, trystart_endpoint_in\n");
+// pin_endpoint->fragsize = count;
+ node->end = pin_endpoint->fragsize;
+
+ start = trystart_endpoint_in(controller, node);
+ if (start == 0) {
+ DPRINT("@@@@ Error ! jz_audio_read, start == 0\n");
+ put_audio_freenode(pin_endpoint->mem, node);
+ }
+ }
+ }
+ AUDIO_UNLOCK(pin_endpoint->lock, flags);
+
+ DUMP_AIC_REGS(__FUNCTION__);
+ DUMP_CODEC_REGS(__FUNCTION__);
+ //dump_dlv_regs(__FUNCTION__);
+ DPRINT("@@@@ count = %d\n", count);
+
+ do{
+ mcount = endpoint_get_userdata(pin_endpoint, &buffer[usecount], count);
+
+ DPRINT("@@@@ jz_audio_read, mcount = %d, usecount = %d\n", mcount, usecount);
+
+ if (mcount < 0) {
+ DPRINT("@@@@ jz_audio_read, mcount < 0, %d\n", mcount);
+ if (usecount > 0) {
+ break;
+ } else {
+ return mcount;
+ }
+ } else if (mcount == 0) {
+ DPRINT("@@@@ jz_audio_read, mcount == 0\n");
+ break;
+ } else {
+ usecount += mcount;
+ count -= mcount;
+ DPRINT("@@@@ jz_audio_read, mcount > 0, %d\n", mcount);
+ }
+ } while (count > 0);
+
+ DPRINT("@@@@ jz_audio_read, usecount = %d\n", usecount);
+
+ LEAVE();
+ return usecount;
+}
+
+/* static struct file_operations jz_i2s_audio_fops */
+static struct file_operations jz_i2s_audio_fops = {
+ owner: THIS_MODULE,
+ open: jz_audio_open,
+ release: jz_audio_release,
+ write: jz_audio_write,
+ read: jz_audio_read,
+ ioctl: jz_audio_ioctl
+};
+
+static void __init attach_jz_i2s(struct jz_i2s_controller_info *controller)
+{
+ char *name = NULL;
+ int adev = 0; /* No of Audio device. */
+
+ ENTER();
+
+ name = controller->name;
+
+ /* Initialize I2S CODEC and register /dev/mixer. */
+ if (jz_i2s_codec_init(controller) <= 0) {
+ goto mixer_failed;
+ }
+
+ /* Initialize AIC controller and reset it. */
+ jz_i2s_reinit_hw(controller->i2s_codec,1);
+ adev = register_sound_dsp(&jz_i2s_audio_fops, -1);
+ if (adev < 0) {
+ goto audio_failed;
+ }
+
+ controller->dev_audio = adev;
+
+ LEAVE();
+
+ return;
+mixer_failed:
+
+audio_failed:
+ unregister_sound_dsp(adev);
+
+ LEAVE();
+ return;
+}
+
+static void __exit unload_jz_i2s(struct jz_i2s_controller_info *controller)
+{
+ jz_i2s_reinit_hw(controller->i2s_codec,0);
+}
+
+//--------------------------------------------------------------------
+#ifdef CONFIG_PM
+static int jz_i2s_suspend(struct jz_i2s_controller_info *controller, int state)
+{
+ int i;
+ struct i2s_codec *codec;
+ for(i = 0;i < NR_I2S; i++){
+ codec = &the_codecs[i];
+ codec->codes_ioctrl(codec, I2S_SUSPEND_CODEC, 0);
+ }
+ printk("Aic and codec are suspended!\n");
+ return 0;
+}
+
+static int jz_i2s_resume(struct jz_i2s_controller_info *controller)
+{
+ int i;
+ struct i2s_codec *codec;
+ for(i = 0;i < NR_I2S; i++){
+ codec = &the_codecs[i];
+ codec->codes_ioctrl(codec, I2S_RESUME_CODEC,0);
+ }
+ return 0;
+}
+
+static int jz_i2s_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
+{
+ int ret;
+ struct jz_i2s_controller_info *controller = pm_dev->data;
+
+ if (!controller) return -EINVAL;
+
+ switch (req) {
+ case PM_SUSPEND:
+ ret = jz_i2s_suspend(controller, (int)data);
+ break;
+ case PM_RESUME:
+ ret = jz_i2s_resume(controller);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+#endif /* CONFIG_PM */
+
+static int __init probe_jz_i2s(struct jz_i2s_controller_info **controller)
+{
+ struct jz_i2s_controller_info *ctrl;
+
+ ENTER();
+ ctrl = kmalloc(sizeof(struct jz_i2s_controller_info), GFP_KERNEL);
+ if (ctrl == NULL) {
+ printk(KERN_ERR "Jz I2S Controller: out of memory.\n");
+ return -ENOMEM;
+ }
+ ctrl->name = "Jz I2S controller";
+ ctrl->pout_endpoint = 0;
+ ctrl->pin_endpoint = 0;
+ ctrl->error = 0;
+ //ctrl->i2s_codec->use_mic_line_flag = USE_NONE;
+
+ *controller = ctrl;
+
+ LEAVE();
+
+ return 0;
+}
+
+void i2s_controller_init(void)
+{
+ unsigned int aicfr;
+ unsigned int aiccr;
+ //init cpm clock, use ext clock;
+
+ ENTER();
+
+ REG_CPM_I2SCDR = 0;
+
+ __cpm_select_i2sclk_exclk();
+// __cpm_exclk_div2();
+ __cpm_enable_pll_change();
+
+ /* ??? legacy ???
+ printk("cpccr 0x%08x\n", *(unsigned int *)0xb0000000);
+ */
+
+ aicfr = (8 << 12) | (8 << 8) | (AIC_FR_ICDC | AIC_FR_LSMP | AIC_FR_AUSEL);
+ REG_AIC_FR = aicfr;
+
+ aiccr = REG_AIC_CR;
+ aiccr &= (~(AIC_CR_EREC | AIC_CR_ERPL | AIC_CR_TDMS | AIC_CR_RDMS));
+ REG_AIC_CR = aiccr;
+
+ LEAVE();
+}
+
+static int __init init_jz_i2s(struct platform_device *pdev)
+{
+ struct i2s_codec *default_codec = &(the_codecs[0]);
+ int errno;
+ int fragsize;
+ int fragstotal;
+
+ cpm_start_clock(CGM_AIC);
+
+ REG_AIC_I2SCR |= AIC_I2SCR_ESCLK;
+
+ i2s_controller_init();
+ if (default_codec->codecs_ioctrl == NULL) {
+ printk("default_codec: not ready!");
+ return -1;
+ }
+
+ default_codec->codecs_ioctrl(default_codec, CODEC_SET_MODE, 0);
+
+ if ((errno = probe_jz_i2s(&the_i2s_controller)) < 0) {
+ return errno;
+ }
+
+ /* May be external CODEC need it ...
+ * default_codec->codecs_ioctrl(default_codec, CODEC_SET_GPIO_PIN, 0);
+ */
+ attach_jz_i2s(the_i2s_controller);
+
+ /* Actually, the handler function of the command do nothing ...
+ * default_codec->codecs_ioctrl(default_codec, CODEC_SET_STARTUP_PARAM, 0);
+ * default_codec->codecs_ioctrl(default_codec, CODEC_SET_STARTUP_PARAM, 0);
+ */
+
+ /* Now the command is not supported by DLV CODEC ...
+ * default_codec->codecs_ioctrl(default_codec, CODEC_SET_VOLUME_TABLE, 0);
+ */
+ fragsize = JZCODEC_RW_BUFFER_SIZE * PAGE_SIZE;
+ fragstotal = JZCODEC_RW_BUFFER_TOTAL;
+
+ audio_init_endpoint(&out_endpoint, fragsize, fragstotal);
+ audio_init_endpoint(&in_endpoint, fragsize, fragstotal);
+
+#ifdef CONFIG_PM
+ the_i2s_controller->pm = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN,
+ jz_i2s_pm_callback);
+ if (the_i2s_controller->pm) {
+ the_i2s_controller->pm->data = i2s_controller;
+ }
+#endif
+ printk("JZ I2S OSS audio driver initialized\n");
+
+ LEAVE();
+
+ return 0;
+}
+
+static void __exit cleanup_jz_i2s(void)
+{
+#ifdef CONFIG_PM
+ /* pm_unregister(i2s_controller->pm); */
+#endif
+ struct i2s_codec *default_codec = &the_codecs[0];
+ unload_jz_i2s(the_i2s_controller);
+ the_i2s_controller = NULL;
+ audio_deinit_endpoint(&out_endpoint);
+ audio_deinit_endpoint(&in_endpoint);
+ default_codec->codecs_ioctrl(default_codec, CODEC_CLEAR_MODE, 0);
+}
+
+static struct platform_driver snd_plat_driver = {
+ .probe = init_jz_i2s,
+ .driver = {
+ .name = "mixer",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init snd_init(void)
+{
+ return platform_driver_register(&snd_plat_driver);
+}
+
+module_init(snd_init);
+module_exit(cleanup_jz_i2s);
diff --git a/sound/oss/jz_audio.h b/sound/oss/jz_audio.h
new file mode 100644
index 00000000000..f66b1616c06
--- /dev/null
+++ b/sound/oss/jz_audio.h
@@ -0,0 +1,136 @@
+/* sound/oss/jz_audio.h
+ *
+ * Copyright (C) 2010 Ingenic, Inc.
+ *
+ * 2010-03-30 Copy from include/linux/msm_audio.h which is write by Google.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __LINUX_JZ_AUDIO_H
+#define __LINUX_JZ_AUDIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+//#include <asm/sizes.h>
+
+/* PCM Audio */
+
+#define AUDIO_IOCTL_MAGIC 'a'
+
+#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
+#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
+#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
+#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
+#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
+#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
+#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
+#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
+#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
+#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
+#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
+#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
+#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
+#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
+#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
+#define AUDIO_WAIT_ADSP_DONE _IOR(AUDIO_IOCTL_MAGIC, 16, unsigned)
+#define AUDIO_ADSP_PAUSE _IOR(AUDIO_IOCTL_MAGIC, 17, unsigned)
+#define AUDIO_ADSP_RESUME _IOR(AUDIO_IOCTL_MAGIC, 18, unsigned)
+#define AUDIOIN_SET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 19, unsigned)
+
+struct jz_audio_config {
+ uint32_t buffer_size;
+ uint32_t buffer_count;
+ uint32_t channel_count;
+ uint32_t sample_rate;
+ uint32_t type;
+ uint32_t codec_format;
+ uint32_t unused[3];
+};
+
+struct jz_audio_stats {
+ uint32_t byte_count;
+ uint32_t sample_count;
+ uint32_t unused[2];
+};
+
+struct jz_audio_aac_config {
+ signed short format;
+ unsigned short audio_object;
+ unsigned short ep_config;
+ unsigned short aac_section_data_resilience_flag;
+ unsigned short aac_scalefactor_data_resilience_flag;
+ unsigned short aac_spectral_data_resilience_flag;
+ unsigned short sbr_on_flag;
+ unsigned short sbr_ps_on_flag;
+ unsigned short dual_mono_mode;
+ unsigned short channel_configuration;
+};
+
+
+////////////////////////////////////////////////////////////////////////
+
+#define SND_IOCTL_MAGIC 's'
+
+#define SND_MUTE_UNMUTED 0
+#define SND_MUTE_MUTED 1
+
+struct snd_device_config {
+ uint32_t device;
+ uint32_t ear_mute;
+ uint32_t mic_mute;
+};
+
+
+#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
+
+#define SND_METHOD_VOICE 0
+
+struct snd_volume_config {
+ uint32_t device;
+ uint32_t method;
+ uint32_t volume;
+};
+
+#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
+
+
+
+struct snd_endpoint {
+ int id;
+ char name[64];
+};
+
+struct jz_snd_endpoints {
+ struct snd_endpoint *endpoints;
+ int num;
+};
+
+
+#if 0
+struct snd_ctxt {
+ struct mutex lock;
+ int opened;
+
+ struct jz_rpc_endpoint *ept;
+ struct task_struct *task;
+ int inited;
+};
+#endif
+#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct jz_snd_endpoint *)
+
+
+//#define SND_GET_NUM_ENDPOINTS 101
+//#define SND_GET_ENDPOINT 102
+
+#endif
diff --git a/sound/oss/jz_codec.h b/sound/oss/jz_codec.h
new file mode 100644
index 00000000000..a6e789f5fd1
--- /dev/null
+++ b/sound/oss/jz_codec.h
@@ -0,0 +1,75 @@
+/* header file for JZ CODEC */
+#ifndef _JZ_CODEC_H_
+#define _JZ_CODEC_H_
+
+//-------------------------------------------------
+#define CODEC_SET_MODE 1
+#define CODEC_SET_STARTUP_PARAM 5
+#define CODEC_SET_VOLUME_TABLE 6
+
+#define CODEC_SET_RECORD 7
+#define CODEC_CLEAR_RECORD 24
+
+#define CODEC_SET_REPLAY 8
+#define CODEC_CLEAR_REPLAY 25
+
+#define CODEC_SET_REPLAY_RECORD 9
+
+#define CODEC_SET_REPLAY_SPEED 12
+#define CODEC_SET_RECORD_SPEED 37
+
+#define CODEC_SET_REPLAY_CHANNEL 33
+#define CODEC_SET_REPLAY_DATA_WIDTH 34
+
+#define CODEC_SET_RECORD_CHANNEL 35
+#define CODEC_SET_RECORD_DATA_WIDTH 36
+
+#define CODEC_SET_GPIO_PIN 3
+#define CODEC_SET_BASS 16
+#define CODEC_SET_VOLUME 17
+#define CODEC_SET_MIC 18
+#define CODEC_SET_LINE 19
+#define CODEC_SET_SOME_FUNC 23
+
+#define CODEC_CLEAR_MODE 2
+
+#define CODEC_EACH_TIME_INIT 4
+#define CODEC_TURN_ON 10
+#define CODEC_TURN_OFF 11
+
+#define CODEC_RESET 13
+#define CODEC_GET_MIXER_OLD_INFO 14
+#define CODEC_GET_MIXER_INFO 15
+#define CODEC_I2S_RESUME 20
+#define CODEC_I2S_SUSPEND 21
+#define CODEC_PIN_INIT 22
+
+#define CODEC_SET_REPLAY_HP_OR_SPKR 26
+#define CODEC_SET_DIRECT_MODE 27
+#define CODEC_CLEAR_DIRECT_MODE 28
+#define CODEC_SET_LINEIN2HP 29
+#define CODEC_CLEAR_LINEIN2HP 30
+
+//------------------------------------------------
+
+#define CODEC_ANTI_POP 31
+#define CODEC_TURN_REPLAY 32
+
+#define CODEC_DAC_MUTE 38
+
+//-------------------------------------------------
+
+void register_jz_codecs(void *func);
+void dump_dlv_regs(const char* str);
+void dlv_write_reg(int addr, int val);
+//-------------------------------------------------
+
+#define USE_NONE 1
+#define USE_MIC 2
+#define USE_LINEIN 3
+
+#define CODEC_WMODE (1 << 0)
+#define CODEC_RMODE (1 << 1)
+#define CODEC_WRMODE (CODEC_WMODE | CODEC_RMODE)
+
+#endif /* _JZ_CODEC_H_ */
diff --git a/sound/oss/jz_i2s.c b/sound/oss/jz_i2s.c
index 5bfbabcd2c8..f8fc5fce20d 100644
--- a/sound/oss/jz_i2s.c
+++ b/sound/oss/jz_i2s.c
@@ -49,6 +49,7 @@
#define USE_NONE 1
#define USE_MIC 2
#define USE_LINEIN 3
+#define USE_WAIT_EVENT
typedef struct hpvol_shift_s
{
@@ -108,8 +109,9 @@ static int codec_bass_gain;
static int audio_mix_modcnt;
static int jz_audio_dma_tran_count; /* bytes count of one DMA transfer */
#if defined(CONFIG_I2S_DLV)
-int jz_mic_only = 1;
-static int jz_codec_config = 0;
+int jz_dlv_vol_mute = 0; /* Added by River. */
+int jz_mic_only = 1;
+static int jz_codec_config = 0;
static unsigned long ramp_up_start;
static unsigned long ramp_up_end;
static unsigned long gain_up_start;
@@ -147,6 +149,8 @@ static DECLARE_WAIT_QUEUE_HEAD (tx_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD (drain_wait_queue);
static DECLARE_WAIT_QUEUE_HEAD (pop_wait_queue);
+static volatile int pop_wait_event;
+
struct jz_i2s_controller_info
{
int io_base;
@@ -422,8 +426,8 @@ static void jz_i2s_initHw(int set)
__i2s_disable_record();
__i2s_disable_replay();
__i2s_disable_loopback();
- __i2s_set_transmit_trigger(4);
- __i2s_set_receive_trigger(3);
+ __i2s_set_transmit_trigger(12);
+ __i2s_set_receive_trigger(4);
}
static int Init_In_Out_queue(int fragstotal,int fragsize)
@@ -1328,6 +1332,7 @@ static int __init probe_jz_i2s(struct jz_i2s_controller_info **controller)
printk(KERN_ERR "Jz I2S Controller: out of memory.\n");
return -ENOMEM;
}
+
(*controller)->name = "Jz I2S controller";
(*controller)->opened1 = 0;
(*controller)->opened2 = 0;
@@ -1338,6 +1343,7 @@ static int __init probe_jz_i2s(struct jz_i2s_controller_info **controller)
init_waitqueue_head(&tx_wait_queue);
init_waitqueue_head(&pop_wait_queue);
init_waitqueue_head(&drain_wait_queue);
+ pop_wait_event = 0;
return 0;
}
@@ -1512,8 +1518,10 @@ static irqreturn_t aic_codec_irq(int irq, void *dev_id)
gain_down_end = jiffies;
write_codec_file(9, file_9);
- if (file_9 & 0xf)
+ if (file_9 & 0xf) {
+ pop_wait_event = 1;
wake_up(&pop_wait_queue);
+ }
while (REG_ICDC_RGDATA & 0x100);
return IRQ_HANDLED;
@@ -1844,6 +1852,8 @@ static int drain_dac(struct jz_i2s_controller_info *ctrl, int nonblock)
static int jz_audio_release(struct inode *inode, struct file *file)
{
unsigned long flags;
+ unsigned int dacflag;
+ unsigned int timeout = 0xfff;
#if defined(CONFIG_I2S_DLV)
unsigned long tfl;
#endif
@@ -1855,17 +1865,21 @@ static int jz_audio_release(struct inode *inode, struct file *file)
return -ENODEV;
pop_dma_flag = 0;
-
+ pop_wait_event = 0;
+
if (controller->opened1 == 1 && controller->opened2 == 1) {
controller->opened1 = 0;
__i2s_enable_transmit_dma();
__i2s_enable_replay();
drain_dac(controller, file->f_flags & O_NONBLOCK);
#if defined(CONFIG_I2S_DLV)
+#if 0
/* wait for fifo empty */
write_codec_file_bit(1, 1, 5);//DAC_MUTE->1
gain_down_start = jiffies;
- sleep_on(&pop_wait_queue);
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+#endif
//gain_down_end = jiffies;
/*while (1) {
tfl = REG_AIC_SR & 0x00003f00;
@@ -1919,7 +1933,9 @@ static int jz_audio_release(struct inode *inode, struct file *file)
#if defined(CONFIG_I2S_DLV)
write_codec_file_bit(5, 1, 6);//SB_OUT->1
ramp_down_start = jiffies;
- sleep_on(&pop_wait_queue);
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+
//ramp_down_end = jiffies;
if (use_mic_line_flag == USE_LINEIN) {
unset_record_line_input_audio_with_audio_data_replay();
@@ -1948,14 +1964,31 @@ static int jz_audio_release(struct inode *inode, struct file *file)
//write_mute_to_dma_buffer(save_last_samples[last_dma_buffer_id].left,save_last_samples[last_dma_buffer_id].right);
#endif
#if defined(CONFIG_I2S_DLV)
+#if 0
write_codec_file_bit(1, 1, 5);//DAC_MUTE->1
gain_down_start = jiffies;
- sleep_on(&pop_wait_queue);
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+#endif
+ if (!jz_dlv_vol_mute) {
+ dacflag = read_codec_file(1);
+ if (!(dacflag & 0x20)) {
+ write_codec_file_bit(1, 1, 5);//DAC_MUTE->1
+ gain_down_start = jiffies;
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+ }
+ }else
+ mdelay(280);
+
//gain_down_end = jiffies;
while (1) {
+ timeout --;
tfl = REG_AIC_SR & 0x00003f00;
if (tfl == 0) {
+ break;
udelay(500);
+ } else if (!timeout){
break;
}
mdelay(2);
@@ -1969,7 +2002,7 @@ static int jz_audio_release(struct inode *inode, struct file *file)
if(clear_codec_replay)
clear_codec_replay();
#endif
-// __aic_flush_fifo();
+ __aic_flush_fifo();
spin_lock_irqsave(&controller->ioctllock, flags);
controller->total_bytes = 0;
@@ -1982,8 +2015,8 @@ static int jz_audio_release(struct inode *inode, struct file *file)
#if defined(CONFIG_I2S_DLV)
write_codec_file_bit(5, 1, 6);//SB_OUT->1
ramp_down_start = jiffies;
- sleep_on(&pop_wait_queue);
- //ramp_down_end = jiffies;
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
unset_audio_data_replay();
#endif
__i2s_disable();
@@ -2018,11 +2051,11 @@ static int jz_audio_release(struct inode *inode, struct file *file)
/* unset Record MIC input audio with direct playback */
unset_record_mic_input_audio_with_direct_playback();
#endif
-#if 0
+#if 1
/* unset Record MIC input audio without playback */
unset_record_mic_input_audio_without_playback();
#endif
-#if 1
+#if 0
unset_playback_line_input_audio_direct_only();
#endif
#if 0
@@ -2079,6 +2112,8 @@ static int jz_audio_open(struct inode *inode, struct file *file)
REG_DMAC_DMACKE(0) = 0x3f;
#endif
pop_dma_flag = 0;
+ pop_wait_event = 0;
+
if (controller->opened1 == 1 || controller->opened2 == 1 ) {
printk("\naudio is busy!\n");
return -EBUSY;
@@ -2225,11 +2260,11 @@ static int jz_audio_open(struct inode *inode, struct file *file)
set_record_mic_input_audio_with_direct_playback();
#endif
-#if 0
+#if 1
/* set Record MIC input audio without playback */
set_record_mic_input_audio_without_playback();
#endif
-#if 1
+#if 0
/* set Playback LINE input audio direct only */
set_playback_line_input_audio_direct_only();
#endif
@@ -2248,7 +2283,7 @@ static int jz_audio_open(struct inode *inode, struct file *file)
mdelay(10);
REG_AIC_I2SCR = 0x10;
mdelay(20);
-// __aic_flush_fifo();
+ __aic_flush_fifo();
#endif
__i2s_enable();
@@ -2262,19 +2297,15 @@ static int jz_audio_open(struct inode *inode, struct file *file)
__dmac_enable_module(0);
write_codec_file_bit(5, 0, 6);//PMR1.SB_OUT->0
ramp_up_start = jiffies;
- sleep_on(&pop_wait_queue);
- //ramp_up_end = jiffies;
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
#endif
} else if (file->f_mode & FMODE_WRITE) {
#if defined(CONFIG_I2S_DLV)
write_codec_file_bit(5, 0, 6);//PMR1.SB_OUT->0
ramp_up_start = jiffies;
- /*while (!(REG_RTC_RCR & RTC_RCR_WRDY));
- REG_RTC_RCR = 0x1;
- while (!(REG_RTC_RCR & RTC_RCR_WRDY));
- REG_RTC_RGR = 1;*/
- sleep_on(&pop_wait_queue);
- //ramp_up_end = jiffies;
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
write_codec_file_bit(5, 1, 4);//SB_ADC->1
#endif
} else if (file->f_mode & FMODE_READ) {
@@ -2741,9 +2772,19 @@ static ssize_t jz_audio_write(struct file *file, const char *buffer, size_t coun
last_dma_buffer_id = id;
#if defined(CONFIG_I2S_DLV)
if (jz_codec_config == 0) {
+#if 0
write_codec_file_bit(1, 0, 5);
gain_up_start = jiffies;
- sleep_on(&pop_wait_queue);
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+#endif
+ if (!jz_dlv_vol_mute) {
+ write_codec_file_bit(1, 0, 5);
+ gain_up_start = jiffies;
+ wait_event(pop_wait_queue, pop_wait_event);
+ pop_wait_event = 0;
+ }
+
//gain_up_end = jiffies;
jz_codec_config = 1;
//SB_ADC->1
diff --git a/sound/oss/jz_i2s_dbg.h b/sound/oss/jz_i2s_dbg.h
new file mode 100644
index 00000000000..a2088d2e6b3
--- /dev/null
+++ b/sound/oss/jz_i2s_dbg.h
@@ -0,0 +1,135 @@
+/*
+ * Linux/sound/oss/jz_i2s_dbg.h
+ *
+ * 2010-01-xx Jason <xwang@ingenic.cn>
+ *
+ * Copyright (c) Ingenic Semiconductor Co., Ltd.
+ */
+
+#ifndef __JZ_I2S_DBG_H__
+#define __JZ_I2S_DBG_H__
+
+
+/*
+ * Select debug level by define various value
+ *
+ * Detailedness level ( 2 > 1 > 0 > undefine)
+ *
+ * Depend on AIC_DEBUG_LEVELX
+ */
+#define AIC_DEBUG_LEVEL 3
+
+
+#if AIC_DEBUG_LEVEL == 2
+ #define AIC_DEBUG_LEVEL2 1
+#endif
+
+#if AIC_DEBUG_LEVEL == 1
+ #define AIC_DEBUG_LEVEL1 1
+#endif
+
+#if AIC_DEBUG_LEVEL == 0
+ #define AIC_DEBUG_LEVEL0 1
+#endif
+
+#ifdef AIC_DEBUG_LEVEL2
+ #define REG_DEBUG 1
+ #define DMA_DEBUG 1
+ #define BUF_DEBUG 1
+ #define Q_DEBUG 1
+ #define TRACE_DEBUG 1
+ #define IRQ_DEBUG 1
+ #define IOC_DEBUG 1
+ #define CODEC_DEBUG 1
+ #define OTHER_DEBUG 1
+#endif
+
+#ifdef AIC_DEBUG_LEVEL1
+ #define OTHER_DEBUG 1
+ #define IRQ_DEBUG 1
+ #define DMA_DEBUG 1
+ #define REG_DEBUG 1
+// #define IOC_DEBUG 1
+#endif
+
+#ifdef AIC_DEBUG_LEVEL0
+ #define IRQ_DEBUG 1
+ #define TRACE_DEBUG 1
+#endif
+
+#ifdef CODEC_DEBUG
+ #define DPRINT_CODEC(msg...) printk(msg)
+#else
+ #define DPRINT_CODEC(msg...) do{} while (0)
+#endif
+
+#ifdef REG_DEBUG
+ #define DUMP_AIC_REGS(msg...) dump_aic_regs(msg)
+ #define DUMP_CODEC_REGS(msg...) dump_dlv_regs(msg)
+#else
+ #define DUMP_AIC_REGS(msg...) do{} while (0)
+ #define DUMP_CODEC_REGS(msg...) do{} while (0)
+#endif
+
+#ifdef IOC_DEBUG
+ #define DPRINT_IOC(msg...) printk(msg)
+ #define DPRINT_DLV_IOC_CMD(msg...) dlv_print_ioc_cmd(msg)
+ #define DPRINT_MIXER_IOC_CMD(msg...) mixer_print_ioc_cmd(msg)
+ #define DPRINT_DSP_IOC_CMD(msg...) dsp_print_ioc_cmd(msg)
+#else
+ #define DPRINT_IOC(msg...) do{} while (0)
+ #define DPRINT_DLV_IOC_CMD(msg...) do{} while (0)
+ #define DPRINT_MIXER_IOC_CMD(msg...) do{} while (0)
+ #define DPRINT_DSP_IOC_CMD(msg...) do{} while (0)
+#endif
+
+#ifdef BUF_DEBUG
+ #define DUMP_BUF(msg...) dump_buf(msg)
+ #define DPRINT_BUF(msg...) printk(msg)
+#else
+ #define DUMP_BUF(msg...) do{} while (0)
+ #define DPRINT_BUF(msg...) do{} while (0)
+#endif
+
+#ifdef DMA_DEBUG
+ #define DUMP_DMA(arg...) dump_dma(arg)
+ #define DPRINT_DMA(msg...) printk(msg)
+#else
+ #define DUMP_DMA(arg...) do{} while (0)
+ #define DPRINT_DMA(msg...) do{} while (0)
+#endif
+
+#ifdef TRACE_DEBUG
+ #define ENTER() printk("Enter: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__)
+ #define LEAVE() printk("Leave: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__)
+ #define DPRINT_TRC(msg...) printk(msg)
+#else
+ #define ENTER() do{} while (0)
+ #define LEAVE() do{} while (0)
+ #define DPRINT_TRC(msg...) do{} while (0)
+#endif
+
+#ifdef IRQ_DEBUG
+ #define DPRINT_IRQ(msg...) printk(msg)
+#else
+ #define DPRINT_IRQ(msg...) do{} while (0)
+#endif
+
+#ifdef Q_DEBUG
+ #define DUMP_NODE(msg...) dump_node(msg)
+ #define DUMP_LIST(msg...) dump_list(msg)
+ #define DPRINT_Q(msg...) printk(msg)
+#else
+ #define DUMP_NODE(msg...) do{} while (0)
+ #define DUMP_LIST(msg...) do{} while (0)
+ #define DPRINT_Q(msg...) do{} while (0)
+#endif
+
+#ifdef OTHER_DEBUG
+ #define DPRINT(msg...) printk(msg)
+#else
+ #define DPRINT(msg...) do{} while (0)
+#endif
+
+
+#endif /*__JZ_I2S_DBG_H__*/
diff --git a/sound/oss/jzdlv.c b/sound/oss/jzdlv.c
index 0a61e4829dd..8061c36f508 100644
--- a/sound/oss/jzdlv.c
+++ b/sound/oss/jzdlv.c
@@ -28,6 +28,9 @@
#define USE_MIC 2
#define USE_LINEIN 3
+/* For volume control mute - Added by River. */
+extern int jz_dlv_vol_mute;
+
extern mixer_info info;
extern _old_mixer_info old_info;
extern int codec_volue_shift;
@@ -312,6 +315,7 @@ void set_playback_line_input_audio_direct_only(void)
write_codec_file_bit(1, 1, 2);//CR1.HP_BYPASS->1
write_codec_file_bit(1, 0, 4);//CR1.HP_DIS->0
write_codec_file_bit(1, 0, 3);//CR1.DACSEL->0
+ write_codec_file_bit(5, 1, 0);//PMR1.SB_IND->1
write_codec_file_bit(5, 0, 3);//PMR1.SB_LIN->0
write_codec_file_bit(5, 0, 5);//PMR1.SB_MIX->0
@@ -608,9 +612,24 @@ void set_dlv_line(int val)
void set_dlv_volume(int val)
{
unsigned long cur_vol;
- cur_vol = 31 * (100 - val) / 100;
- write_codec_file(17, cur_vol | 0xc0);
- write_codec_file(18, cur_vol);
+
+ /* 0 -> DAC Soft Mute - Modified by River. */
+ if (!val) {
+ if (!jz_dlv_vol_mute) {
+ write_codec_file_bit(1, 1, 5); /* DAC soft mute -> ON. */
+ jz_dlv_vol_mute = 1;
+ }
+ }else {
+ cur_vol = 31 * (100 - val) / 100;
+
+ if (jz_dlv_vol_mute) {
+ jz_dlv_vol_mute = 0;
+ write_codec_file_bit(1, 0, 5); /* DAC soft mute -> OFF. */
+ }
+
+ write_codec_file(17, cur_vol | 0xc0);
+ write_codec_file(18, cur_vol);
+ }
}
static int __init init_dlv(void)