Merge remote-tracking branch 'origin/develop-3.0-rk30' into develop-3.0
author黄涛 <huangtao@rock-chips.com>
Sun, 25 Mar 2012 07:55:20 +0000 (15:55 +0800)
committer黄涛 <huangtao@rock-chips.com>
Sun, 25 Mar 2012 07:55:20 +0000 (15:55 +0800)
101 files changed:
arch/arm/Makefile
arch/arm/configs/rk29_td8801_v2_defconfig
arch/arm/mach-rk29/Kconfig [changed mode: 0644->0755]
arch/arm/mach-rk29/Makefile [changed mode: 0644->0755]
arch/arm/mach-rk29/board-rk29-ddr3sdk.c
arch/arm/mach-rk29/board-rk29-k97.c
arch/arm/mach-rk29/board-rk29-td8801_v2-rfkill.c [changed mode: 0644->0755]
arch/arm/mach-rk29/board-rk29-td8801_v2.c
arch/arm/mach-rk29/board-rk29phonepadsdk.c
arch/arm/mach-rk29/i2c_sram.c [new file with mode: 0755]
arch/arm/mach-rk29/include/mach/board.h
arch/arm/mach-rk29/include/mach/pm-vol.h [changed mode: 0644->0755]
arch/arm/mach-rk29/include/mach/rk29_camera.h
arch/arm/mach-rk29/include/mach/rk29_iomap.h
arch/arm/mach-rk29/include/mach/vpu_mem.h
arch/arm/mach-rk29/io.c [changed mode: 0644->0755]
arch/arm/mach-rk29/memcpy_dma.c
arch/arm/mach-rk29/pm.c
arch/arm/mach-rk29/rk29_charge_lowpower.c [new file with mode: 0755]
arch/arm/mach-rk29/verifyID.c [new file with mode: 0644]
arch/arm/mach-rk29/verifyID.h [new file with mode: 0644]
arch/arm/mach-rk29/vpu_mem.c
drivers/cmmb/cmmb_class.c
drivers/gpu/ion/ion.c
drivers/gpu/ion/ion_carveout_heap.c
drivers/gpu/ion/ion_priv.h
drivers/i2c/busses/i2c-rk29.c
drivers/input/gsensor/bma023.c
drivers/input/touchscreen/ili2102_ts.c
drivers/input/touchscreen/pixcir_i2c_ts.c
drivers/input/touchscreen/rk29_i2c_goodix.c
drivers/media/video/Kconfig
drivers/media/video/gc0307.c
drivers/media/video/gc0308.c
drivers/media/video/gc0309.c
drivers/media/video/gc0309_for_td8801.c [changed mode: 0755->0644]
drivers/media/video/gc2015.c
drivers/media/video/gt2005.c
drivers/media/video/hi253.c
drivers/media/video/hi704.c
drivers/media/video/mt9d112.c
drivers/media/video/mt9d113.c
drivers/media/video/mt9p111.c [changed mode: 0755->0644]
drivers/media/video/mt9t111.c
drivers/media/video/nt99250.c
drivers/media/video/ov2640.c [changed mode: 0755->0644]
drivers/media/video/ov2640_rk.c
drivers/media/video/ov2655.c
drivers/media/video/ov2659.c
drivers/media/video/ov3640.c [changed mode: 0755->0644]
drivers/media/video/ov5640.c
drivers/media/video/ov5640_for_td8801.c [changed mode: 0755->0644]
drivers/media/video/ov5642.c
drivers/media/video/ov7675.c
drivers/media/video/ov7690.c [changed mode: 0755->0644]
drivers/media/video/rk29_camera.c
drivers/media/video/rk29_camera_oneframe.c
drivers/media/video/s5k6aa.c [changed mode: 0755->0644]
drivers/media/video/sid130B.c [changed mode: 0644->0755]
drivers/media/video/siv120b.c
drivers/media/video/soc_camera.c
drivers/media/video/uvc/uvc_queue.c
drivers/mfd/wm831x-i2c.c
drivers/mfd/wm8994-core.c
drivers/misc/mu509.c
drivers/mmc/host/rk29_sdmmc.c
drivers/net/usb/dm9620.c
drivers/net/usb/sr9700.c
drivers/net/wireless/rtl8192c/core/rtw_ioctl_set.uu
drivers/net/wireless/rtl8192c/core/rtw_wlan_util.c
drivers/net/wireless/rtl8192c/os_dep/linux/ioctl_linux.uu
drivers/net/wireless/rtl8192c/os_dep/linux/wifi_version.h
drivers/net/wireless/wifi_sys/rkwifi_sys_iface.c
drivers/power/rk29_adc_battery.c
drivers/power/wm831x_power.c
drivers/regulator/wm8994-regulator.c
drivers/staging/rk29/vivante/hal/inc/gc_hal_options.h
drivers/staging/rk29/vivante/hal/kernel/gc_hal_kernel_mmu.c
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/staging/rk29/vivante/hal/os/linux/kernel/gc_hal_kernel_os.c
drivers/usb/gadget/android.c
drivers/usb/gadget/storage_common.c [changed mode: 0644->0755]
drivers/usb/serial/option.c
drivers/usb/serial/usb-serial.c [changed mode: 0644->0755]
drivers/video/Makefile
drivers/video/fb.uu [new file with mode: 0644]
drivers/video/hdmi/hdmi-sysfs.c
include/linux/ion.h [changed mode: 0644->0755]
include/linux/mfd/wm8994/pdata.h
include/linux/mu509.h
include/sound/soc.h
mkkrnlimg
pack-kernel.sh
sound/soc/codecs/rt5625.c
sound/soc/codecs/rt5625.h
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8994.h
sound/soc/codecs/wm_hubs.c
sound/soc/rk29/Kconfig
sound/soc/rk29/rk29_rt5625.c
sound/soc/soc-core.c

index cd2b4f5343746fad52f6071aa2089b5e12068589..83aa4bd2c5a7650ab85fb92f18fab1bc59ee6845 100644 (file)
@@ -293,9 +293,16 @@ bp:;       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
 i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
 
 PHONY += kernel.img zkernel.img
+
+ifdef CONFIG_MACH_RK29_2906
+kernel.img: Image FORCE
+       $(Q)$(srctree)/mkkrnlimg $(obj)/arch/arm/boot/Image $(obj)/kernel.img RK2906
+       @echo '  RK2906 Image:  $@ is ready'
+else
 kernel.img: Image FORCE
        $(Q)$(srctree)/mkkrnlimg $(obj)/arch/arm/boot/Image $(obj)/kernel.img
        @echo '  Image:  $@ is ready'
+endif
 
 zkernel.img: zImage FORCE
        $(Q)$(srctree)/mkkrnlimg $(obj)/arch/arm/boot/zImage $(obj)/kernel.img
index c87882b4354cf71088948442621c633bb2cfd26e..5d6bfebc19ec30ec19b54a37e7e8f43d5f34b7da 100755 (executable)
@@ -317,8 +317,10 @@ CONFIG_RK29_LAST_LOG=y
 # CONFIG_RK29_WORKING_POWER_MANAGEMENT is not set
 CONFIG_RK29_CLK_SWITCH_TO_32K=y
 CONFIG_RK29_GPIO_SUSPEND=y
-# CONFIG_RK29_NEON_POWERDOMAIN_SET is not set
+CONFIG_RK29_NEON_POWERDOMAIN_SET=y
 # CONFIG_RK29_SPI_INSRAM is not set
+CONFIG_RK29_I2C_INSRAM=y
+# CONFIG_RK29_CHARGE_EARLYSUSPEND is not set
 
 #
 # System MMU
@@ -1012,7 +1014,7 @@ CONFIG_ANDROID_PMEM=y
 # CONFIG_SENSORS_AK8975 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
-# CONFIG_UID_STAT is not set
+CONFIG_UID_STAT=y
 # CONFIG_BMP085 is not set
 # CONFIG_WL127X_RFKILL is not set
 CONFIG_APANIC=y
@@ -1197,10 +1199,10 @@ CONFIG_PPP_ASYNC=y
 CONFIG_PPP_SYNC_TTY=y
 CONFIG_PPP_DEFLATE=y
 CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOLAC is not set
-# CONFIG_PPPOPNS is not set
+CONFIG_PPP_MPPE=y
+#CONFIG_PPPOE is not set
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
 # CONFIG_SLIP is not set
 CONFIG_SLHC=y
 # CONFIG_NETCONSOLE is not set
@@ -1309,7 +1311,7 @@ CONFIG_TOUCHSCREEN_PIXCIR=y
 CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_LPSENSOR_ISL29028 is not set
 # CONFIG_INPUT_LPSENSOR_CM3602 is not set
-CONFIG_INPUT_LPSENSOR_AL3006=y
+# CONFIG_INPUT_LPSENSOR_AL3006 is not set
 # CONFIG_INPUT_AD714X is not set
 # CONFIG_INPUT_ATI_REMOTE is not set
 # CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -1562,7 +1564,7 @@ CONFIG_POWER_SUPPLY=y
 # CONFIG_PDA_POWER is not set
 CONFIG_WM831X_BACKUP=y
 CONFIG_WM831X_POWER=y
-CONFIG_WM831X_CHARGER_DISPLAY=y
+# CONFIG_WM831X_CHARGER_DISPLAY is not set
 # CONFIG_WM831X_WITH_BATTERY is not set
 # CONFIG_TEST_POWER is not set
 # CONFIG_BATTERY_DS2780 is not set
@@ -1578,7 +1580,7 @@ CONFIG_WM831X_CHARGER_DISPLAY=y
 # CONFIG_CHARGER_MAX8903 is not set
 # CONFIG_CHARGER_GPIO is not set
 # CONFIG_BATTERY_RK29_ADC is not set
-# CONFIG_POWER_ON_CHARGER_DISPLAY is not set
+CONFIG_POWER_ON_CHARGER_DISPLAY=y
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
@@ -1770,6 +1772,7 @@ CONFIG_SOC_CAMERA=y
 # CONFIG_SOC_CAMERA_OV2659 is not set
 # CONFIG_SOC_CAMERA_OV7690 is not set
 # CONFIG_SOC_CAMERA_OV9650 is not set
+# CONFIG_SOC_CAMERA_OV2640_RK is not set
 # CONFIG_SOC_CAMERA_OV3640 is not set
 # CONFIG_SOC_CAMERA_OV5642 is not set
 # CONFIG_SOC_CAMERA_OV5640 is not set
@@ -2029,6 +2032,7 @@ CONFIG_SND_RK29_SOC_WM8994=y
 # CONFIG_SND_RK29_CODEC_SOC_MASTER is not set
 CONFIG_SND_RK29_CODEC_SOC_SLAVE=y
 # CONFIG_ADJUST_VOL_BY_CODEC is not set
+CONFIG_PHONE_INCALL_IS_SUSPEND=y
 CONFIG_SND_SOC_I2C_AND_SPI=y
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_WM_HUBS=y
old mode 100644 (file)
new mode 100755 (executable)
index 6c3e86d..c85df82
@@ -1,5 +1,8 @@
 if ARCH_RK29
 
+config MACH_RK29_2906
+       bool "ROCKCHIP RK2906 Feature"
+
 choice
        prompt "Select Board Type"
        depends on ARCH_RK29
@@ -108,11 +111,14 @@ config RK29_NEON_POWERDOMAIN_SET
 config RK29_SPI_INSRAM
        tristate "Support spi control interface"
        depends on REGULATOR_WM831X
-       default ns
+       default n
 config RK29_I2C_INSRAM
        tristate "Support i2c control interface"
-       depends on REGULATOR_ACT8891
-       default ns
+       depends on REGULATOR_WM831X
+       default n
+config RK29_CHARGE_EARLYSUSPEND
+       bool "Support charge in low power"
+       default n
 config RK29_PWM_INSRAM
        tristate "Support pwm control interface"
        depends on RK29_PWM_REGULATOR
old mode 100644 (file)
new mode 100755 (executable)
index 4809e2d..89009d8
@@ -1,4 +1,4 @@
-obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o ddr.o memcpy_dma.o reset.o
+obj-y += timer.o io.o devices.o verifyID.o iomux.o clock.o rk29-pl330.o dma.o ddr.o memcpy_dma.o reset.o
 obj-y += tests.o memtester.o
 obj-$(CONFIG_PM) += pm.o
 obj-$(CONFIG_CPU_FREQ) += cpufreq.o
@@ -15,5 +15,6 @@ obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-
 obj-$(CONFIG_MACH_RK29_TD8801_V2) += board-rk29-td8801_v2.o board-rk29-td8801_v2-key.o board-rk29-td8801_v2-rfkill.o
 obj-$(CONFIG_MACH_RK29_PHONEPADSDK) += board-rk29phonepadsdk.o board-rk29phonepadsdk-key.o board-rk29phonepadsdk-rfkill.o board-rk29phonepadsdk-power.o
 obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-newton-rfkill.o board-rk29sdk-power.o
+obj-$(CONFIG_RK29_CHARGE_EARLYSUSPEND) += rk29_charge_lowpower.o
 obj-$(CONFIG_MACH_RK29_K97) += board-rk29-k97.o board-rk29k97-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
 obj-$(CONFIG_MACH_RK29_PHONE_Z5) += board-rk29-z5.o board-rk29-z5-key.o board-rk29-z5-rfkill.o
index 1efc7f82f460fe4a0e7e21af18b9ff5cf8439fed..6f8d695a0314ce2b866d1ec60bf14008b6f61d20 100755 (executable)
@@ -69,7 +69,7 @@
 #ifdef CONFIG_VIDEO_RK29
 /*---------------- Camera Sensor Macro Define Begin  ------------------------*/
 /*---------------- Camera Sensor Configuration Macro Begin ------------------------*/
-#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642                      /* back camera sensor */
+#define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642                      /* back camera sensor */
 #define CONFIG_SENSOR_IIC_ADDR_0           0x78
 #define CONFIG_SENSOR_IIC_ADAPTER_ID_0    1
 #define CONFIG_SENSOR_ORIENTATION_0       90
@@ -83,6 +83,7 @@
 #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L
 
 #define CONFIG_SENSOR_QCIF_FPS_FIXED_0      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_0   15000
 #define CONFIG_SENSOR_QVGA_FPS_FIXED_0      15000
 #define CONFIG_SENSOR_CIF_FPS_FIXED_0       15000
 #define CONFIG_SENSOR_VGA_FPS_FIXED_0       15000
 #define CONFIG_SENSOR_SVGA_FPS_FIXED_0      15000
 #define CONFIG_SENSOR_720P_FPS_FIXED_0      30000
 
-#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659                      /* front camera sensor */
+#define CONFIG_SENSOR_01  RK29_CAM_SENSOR_OV5642                   /* back camera sensor 1 */
+#define CONFIG_SENSOR_IIC_ADDR_01          0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_01    1
+#define CONFIG_SENSOR_ORIENTATION_01       90
+#define CONFIG_SENSOR_POWER_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_01       RK29_PIN6_PB7
+#define CONFIG_SENSOR_FALSH_PIN_01         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_01 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_01 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_01 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_01 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_01   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_01       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_01       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_01      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_01     30000
+
+#define CONFIG_SENSOR_02 RK29_CAM_SENSOR_OV5640                      /* back camera sensor 2 */
+#define CONFIG_SENSOR_IIC_ADDR_02          0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_02    1
+#define CONFIG_SENSOR_ORIENTATION_02       90
+#define CONFIG_SENSOR_POWER_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_02       RK29_PIN6_PB7
+#define CONFIG_SENSOR_FALSH_PIN_02         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_02 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_02 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_02 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_02 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_02   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_02       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_02       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_02      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_02      30000
+
+#define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659                      /* front camera sensor 0 */
 #define CONFIG_SENSOR_IIC_ADDR_1           0x60
 #define CONFIG_SENSOR_IIC_ADAPTER_ID_1    1
 #define CONFIG_SENSOR_ORIENTATION_1       270
 #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
 
 #define CONFIG_SENSOR_QCIF_FPS_FIXED_1      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_1   15000
 #define CONFIG_SENSOR_QVGA_FPS_FIXED_1      15000
 #define CONFIG_SENSOR_CIF_FPS_FIXED_1       15000
 #define CONFIG_SENSOR_VGA_FPS_FIXED_1       15000
 #define CONFIG_SENSOR_SVGA_FPS_FIXED_1      15000
 #define CONFIG_SENSOR_720P_FPS_FIXED_1      30000
 
+#define CONFIG_SENSOR_11 RK29_CAM_SENSOR_OV2659                      /* front camera sensor 1 */
+#define CONFIG_SENSOR_IIC_ADDR_11          0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_11    1
+#define CONFIG_SENSOR_ORIENTATION_11       270
+#define CONFIG_SENSOR_POWER_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_11       RK29_PIN5_PD7
+#define CONFIG_SENSOR_FALSH_PIN_11         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_11 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_11 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_11 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_11 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_11   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_11       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_11       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_11      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_11      30000
+
+#define CONFIG_SENSOR_12 RK29_CAM_SENSOR_OV2655                      /* front camera sensor 2 */
+#define CONFIG_SENSOR_IIC_ADDR_12          0x00
+#define CONFIG_SENSOR_IIC_ADAPTER_ID_12    1
+#define CONFIG_SENSOR_ORIENTATION_12       270
+#define CONFIG_SENSOR_POWER_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_RESET_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_POWERDN_PIN_12       RK29_PIN5_PD7
+#define CONFIG_SENSOR_FALSH_PIN_12         INVALID_GPIO
+#define CONFIG_SENSOR_POWERACTIVE_LEVEL_12 RK29_CAM_POWERACTIVE_L
+#define CONFIG_SENSOR_RESETACTIVE_LEVEL_12 RK29_CAM_RESETACTIVE_L
+#define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_12 RK29_CAM_POWERDNACTIVE_H
+#define CONFIG_SENSOR_FLASHACTIVE_LEVEL_12 RK29_CAM_FLASHACTIVE_L
+
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_240X160_FPS_FIXED_12   15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_12       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_12       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_12      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_12      30000
+
+
 #endif  //#ifdef CONFIG_VIDEO_RK29
 /*---------------- Camera Sensor Configuration Macro End------------------------*/
 #include "../../../drivers/media/video/rk29_camera.c"
@@ -2724,8 +2815,12 @@ static struct platform_device *devices[] __initdata = {
        #if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)
        &rk29_soc_camera_pdrv_0,
        #endif
+    #if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)
        &rk29_soc_camera_pdrv_1,
+       #endif
+    #if (PMEM_CAM_SIZE > 0)
        &android_pmem_cam_device,
+       #endif
 #endif
 #if PMEM_SKYPE_SIZE > 0
        &android_pmem_skype_device,
index 6e9f58684b649d2fab4b623d6c681ca0653f3dd3..ab32e956dc62809929304d2991a25abc8262a8bc 100755 (executable)
 #endif
 
 #define CONFIG_SENSOR_QCIF_FPS_FIXED_0      12504
+#define CONFIG_SENSOR_240X160_FPS_FIXED_0      12504
 #define CONFIG_SENSOR_QVGA_FPS_FIXED_0      12504
 #define CONFIG_SENSOR_CIF_FPS_FIXED_0       12504
 #define CONFIG_SENSOR_VGA_FPS_FIXED_0       12504
 #define CONFIG_SENSOR_480P_FPS_FIXED_0      12504
 #define CONFIG_SENSOR_SVGA_FPS_FIXED_0      12504
-#define CONFIG_SENSOR_720P_FPS_FIXED_0      6256
+#define CONFIG_SENSOR_720P_FPS_FIXED_0      12504
 #ifdef CONFIG_SOC_CAMERA_OV9665
 #define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV9665                      /* front camera sensor */
 #define CONFIG_SENSOR_IIC_ADDR_1            0x60
 #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
 
 #define CONFIG_SENSOR_QCIF_FPS_FIXED_1      12504
+#define CONFIG_SENSOR_240X160_FPS_FIXED_1      12504
 #define CONFIG_SENSOR_QVGA_FPS_FIXED_1      12504
 #define CONFIG_SENSOR_CIF_FPS_FIXED_1       12504
 #define CONFIG_SENSOR_VGA_FPS_FIXED_1       12504
 #define CONFIG_SENSOR_480P_FPS_FIXED_1      12504
 #define CONFIG_SENSOR_SVGA_FPS_FIXED_1      12504
-#define CONFIG_SENSOR_720P_FPS_FIXED_1      6256
+#define CONFIG_SENSOR_720P_FPS_FIXED_1      12504
 #endif  //#ifdef CONFIG_VIDEO_RK29
 /*---------------- Camera Sensor Configuration Macro End------------------------*/
 #include "../../../drivers/media/video/rk29_camera.c"
 #define SDRAM_SIZE          SZ_512M
 #endif
 #define PMEM_GPU_SIZE       SZ_128M
-#define PMEM_UI_SIZE        (48 * SZ_1M) /* 1280x800: 64M 1024x768: 48M ... */
+#define PMEM_UI_SIZE        (68 * SZ_1M) /* 1280x800: 64M 1024x768: 48M ... */
 #define PMEM_VPU_SIZE       SZ_64M
 #define PMEM_SKYPE_SIZE     0
 #define PMEM_CAM_SIZE       PMEM_CAM_NECESSARY
@@ -1021,7 +1023,7 @@ static struct mma8452_platform_data mma8452_info = {
   .model= 8452,
   .swap_xyz= 1,
   .swap_xy=0,
-  .orientation ={1,0,0,0,0,1,0,-1,0},
+  .orientation ={1,0,0,0,0,-1,0,-1,0},
   .init_platform_hw= mma8452_init_platform_hw,
 
 };
@@ -2781,8 +2783,13 @@ static struct platform_device *devices[] __initdata = {
        #if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)
        &rk29_soc_camera_pdrv_0,
        #endif
+    #if (CONFIG_SENSOR_IIC_ADDR_1 != 0x00)
        &rk29_soc_camera_pdrv_1,
+       #endif   
+
+    #if (PMEM_CAM_SIZE > 0)
        &android_pmem_cam_device,
+       #endif
 #endif
 #if PMEM_SKYPE_SIZE > 0
        &android_pmem_skype_device,
old mode 100644 (file)
new mode 100755 (executable)
index a0a9893..6e52d2f
@@ -47,8 +47,8 @@ struct bt_ctrl
 #define IOMUX_BT_GPIO_POWER     rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
 #define BT_GPIO_RESET                  RK29_PIN6_PC7
 #define BT_GPIO_WAKE_UP         RK29_PIN6_PD0
-#define BT_GPIO_WAKE_UP_HOST    RK29_PIN4_PD4
-#define IOMUX_BT_GPIO_WAKE_UP_HOST() rk29_mux_api_set(GPIO4D4_CPUTRACECLK_NAME,GPIO4H_GPIO4D4);
+#define BT_GPIO_WAKE_UP_HOST    RK29_PIN4_PA2
+//#define IOMUX_BT_GPIO_WAKE_UP_HOST() rk29_mux_api_set(GPIO4D4_CPUTRACECLK_NAME,GPIO4H_GPIO4D4);
 
 //bt cts paired to uart rts
 #define UART_RTS                RK29_PIN2_PA7
@@ -241,7 +241,7 @@ static int __devinit bcm4329_rfkill_probe(struct platform_device *pdev)
                printk("%s:failed to request RAHO_BT_WAKE_UP_HOST\n",__FUNCTION__);
        }
 
-       IOMUX_BT_GPIO_WAKE_UP_HOST();
+       //IOMUX_BT_GPIO_WAKE_UP_HOST();
        gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
        rc = request_irq(gpio_to_irq(BT_GPIO_WAKE_UP_HOST),bcm4329_wake_host_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
        if(rc)
index f10841e968346a0732c3cffbac494a05e687d1b5..3c3c4be1b1f64236d1f693399b5cd154af2d8ed8 100755 (executable)
@@ -1,4 +1,4 @@
-/* arch/arm/mach-rk29/board-rk29-phonesdk.c
+/* arch/arm/mach-rk29/board-rk29-td8801.c
  *
  * Copyright (C) 2010 ROCKCHIP, Inc.
  *
@@ -702,8 +702,8 @@ static struct akm8975_platform_data akm8975_info =
        .m_layout = 
        {
                {
-                       {-1, 0, 0 },
-                       {0, -1, 0 },
+                       {1, 0, 0 },
+                       {0, 1, 0 },
                        {0,     0, 1 },
                },
 
@@ -2419,6 +2419,14 @@ struct platform_device rk29_device_tdsc8800 = {
     };
 #endif
 
+#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+#define SDMMC0_WRITE_PROTECT_PIN               RK29_PIN2_PA3 //According to your own project to set the value of write-protect-pin.
+#endif
+
+#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
+#define SDMMC1_WRITE_PROTECT_PIN               RK29_PIN1_PC1 //According to your own project to set the value of write-protect-pin.
+#endif
+
 
 /*****************************************************************************************
  * SDMMC devices
@@ -2655,22 +2663,38 @@ static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width)
 #ifdef CONFIG_SDMMC0_RK29
 static int rk29_sdmmc0_cfg_gpio(void)
 {
+#ifdef CONFIG_SDMMC_RK29_OLD   
        rk29_mux_api_set(GPIO1D1_SDMMC0CMD_NAME, GPIO1H_SDMMC0_CMD);
        rk29_mux_api_set(GPIO1D0_SDMMC0CLKOUT_NAME, GPIO1H_SDMMC0_CLKOUT);
        rk29_mux_api_set(GPIO1D2_SDMMC0DATA0_NAME, GPIO1H_SDMMC0_DATA0);
        rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
        rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
        rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
-#ifdef CONFIG_SDMMC_RK29_OLD
+       
        rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2);
-#else
-  rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
-#endif
+
        rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5);   ///GPIO5H_SDMMC0_PWR_EN);  ///GPIO5H_GPIO5D5);
        gpio_request(RK29_PIN5_PD5,"sdmmc");
+#if 0
        gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH);
        mdelay(100);
        gpio_set_value(RK29_PIN5_PD5,GPIO_LOW);
+#else
+       gpio_direction_output(RK29_PIN5_PD5,GPIO_LOW);
+#endif
+
+#else
+    rk29_sdmmc_set_iomux(0, 0xFFFF);
+    
+       rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
+
+       #if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+    gpio_request(SDMMC0_WRITE_PROTECT_PIN,"sdmmc-wp");
+    gpio_direction_input(SDMMC0_WRITE_PROTECT_PIN);        
+    #endif
+
+#endif
+
        return 0;
 }
 
@@ -2681,25 +2705,32 @@ struct rk29_sdmmc_platform_data default_sdmmc0_data = {
                                           MMC_VDD_33_34|MMC_VDD_34_35| MMC_VDD_35_36),
        .host_caps      = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
        .io_init = rk29_sdmmc0_cfg_gpio,
+
+#if !defined(CONFIG_SDMMC_RK29_OLD)            
+       .set_iomux = rk29_sdmmc_set_iomux,
+#endif
+
        .dma_name = "sd_mmc",
 #ifdef CONFIG_SDMMC0_USE_DMA
        .use_dma  = 1,
 #else
        .use_dma = 0,
 #endif
-#if !defined(CONFIG_SDMMC_RK29_OLD)
-  .set_iomux = rk29_sdmmc_set_iomux,
-#endif
-
-//     .detect_irq = RK29_PIN2_PA2, // INVALID_GPIO
        .detect_irq = INVALID_GPIO,
        .enable_sd_wakeup = 0,
+
+#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT)
+    .write_prt = SDMMC0_WRITE_PROTECT_PIN,
+#else
+    .write_prt = INVALID_GPIO,
+#endif
 };
 #endif
 #ifdef CONFIG_SDMMC1_RK29
 #define CONFIG_SDMMC1_USE_DMA
 static int rk29_sdmmc1_cfg_gpio(void)
 {
+#if defined(CONFIG_SDMMC_RK29_OLD)
        rk29_mux_api_set(GPIO1C2_SDMMC1CMD_NAME, GPIO1H_SDMMC1_CMD);
        rk29_mux_api_set(GPIO1C7_SDMMC1CLKOUT_NAME, GPIO1H_SDMMC1_CLKOUT);
        rk29_mux_api_set(GPIO1C3_SDMMC1DATA0_NAME, GPIO1H_SDMMC1_DATA0);
@@ -2707,6 +2738,16 @@ static int rk29_sdmmc1_cfg_gpio(void)
        rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_SDMMC1_DATA2);
        rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_SDMMC1_DATA3);
        //rk29_mux_api_set(GPIO1C0_UART0CTSN_SDMMC1DETECTN_NAME, GPIO1H_SDMMC1_DETECT_N);
+
+#else
+
+#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
+    gpio_request(SDMMC1_WRITE_PROTECT_PIN,"sdio-wp");
+    gpio_direction_input(SDMMC1_WRITE_PROTECT_PIN);        
+#endif
+
+#endif
+
        return 0;
 }
 
@@ -2721,15 +2762,27 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
        .host_ocr_avail = (MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28|MMC_VDD_28_29|
                                           MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32|
                                           MMC_VDD_32_33|MMC_VDD_33_34),
+
+#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)                                    
        .host_caps      = (MMC_CAP_4_BIT_DATA|MMC_CAP_SDIO_IRQ|
                                   MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
+#else
+    .host_caps         = (MMC_CAP_4_BIT_DATA|MMC_CAP_MMC_HIGHSPEED|MMC_CAP_SD_HIGHSPEED),
+#endif
+
        .io_init = rk29_sdmmc1_cfg_gpio,
+
+#if !defined(CONFIG_SDMMC_RK29_OLD)            
+       .set_iomux = rk29_sdmmc_set_iomux,
+#endif 
        .dma_name = "sdio",
 #ifdef CONFIG_SDMMC1_USE_DMA
        .use_dma  = 1,
 #else
        .use_dma = 0,
 #endif
+       
+#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD)
 #ifdef CONFIG_WIFI_CONTROL_FUNC
         .status = rk29sdk_wifi_status,
         .register_status_notify = rk29sdk_wifi_status_register,
@@ -2737,11 +2790,23 @@ struct rk29_sdmmc_platform_data default_sdmmc1_data = {
 #if 0
         .detect_irq = RK29SDK_WIFI_SDIO_CARD_DETECT_N,
 #endif
-#if !defined(CONFIG_SDMMC_RK29_OLD)
-    .set_iomux = rk29_sdmmc_set_iomux,
+
+#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
+    .write_prt = SDMMC1_WRITE_PROTECT_PIN,
+#else
+    .write_prt = INVALID_GPIO, 
+#endif  
+
+#else
+//for wifi develop board
+    .detect_irq = INVALID_GPIO,
+    .enable_sd_wakeup = 0,
 #endif
+
 };
-#endif
+#endif ////endif--#ifdef CONFIG_SDMMC1_RK29
+
+
 
 #ifdef CONFIG_WIFI_CONTROL_FUNC
 #define RK29SDK_WIFI_BT_GPIO_POWER_N       RK29_PIN5_PD6
@@ -2791,6 +2856,22 @@ static int rk29sdk_wifi_bt_gpio_control_init(void)
     gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N,    GPIO_LOW);
     gpio_direction_output(RK29SDK_BT_GPIO_RESET_N,      GPIO_LOW);
 
+    #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
+    
+    rk29_mux_api_set(GPIO1C4_SDMMC1DATA1_NAME, GPIO1H_GPIO1C4);
+    gpio_request(RK29_PIN1_PC4, "mmc1-data1");
+    gpio_direction_output(RK29_PIN1_PC4,GPIO_LOW);//set mmc1-data1 to low.
+
+    rk29_mux_api_set(GPIO1C5_SDMMC1DATA2_NAME, GPIO1H_GPIO1C5);
+    gpio_request(RK29_PIN1_PC5, "mmc1-data2");
+    gpio_direction_output(RK29_PIN1_PC5,GPIO_LOW);//set mmc1-data2 to low.
+
+    rk29_mux_api_set(GPIO1C6_SDMMC1DATA3_NAME, GPIO1H_GPIO1C6);
+    gpio_request(RK29_PIN1_PC6, "mmc1-data3");
+    gpio_direction_output(RK29_PIN1_PC6,GPIO_LOW);//set mmc1-data3 to low.
+    
+    rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
+    #endif    
     pr_info("%s: init finished\n",__func__);
 
     return 0;
@@ -2801,12 +2882,22 @@ static int rk29sdk_wifi_power(int on)
         pr_info("%s: %d\n", __func__, on);
         if (on){
                 gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH);
+               
+               #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+                rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13
+                #endif
+
                 gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH);
                 mdelay(100);
                 pr_info("wifi turn on power\n");
         }else{
                 if (!rk29sdk_bt_power_state){
                         gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
+                       
+                       #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)      
+                        rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13
+                        #endif
+
                         mdelay(100);
                         pr_info("wifi shut off power\n");
                 }else
index 4df7bbeb5fda61d99d2784f2b8d45d6e89c0fee7..b6c7b3fdb11b5cfd8fa092de50df0e92a92d43bc 100755 (executable)
 #define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H
 #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_L
 
-#define CONFIG_SENSOR_QCIF_FPS_FIXED_0      15
-#define CONFIG_SENSOR_QVGA_FPS_FIXED_0      15
-#define CONFIG_SENSOR_CIF_FPS_FIXED_0       15
-#define CONFIG_SENSOR_VGA_FPS_FIXED_0       15
-#define CONFIG_SENSOR_480P_FPS_FIXED_0      15
-#define CONFIG_SENSOR_SVGA_FPS_FIXED_0      15
-#define CONFIG_SENSOR_720P_FPS_FIXED_0      30
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_0      15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_0      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_0       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_0       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_0      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_0      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_0      30000
 
 #define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659                      /* front camera sensor */
 #define CONFIG_SENSOR_IIC_ADDR_1           0x60
 #define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H
 #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L
 
-#define CONFIG_SENSOR_QCIF_FPS_FIXED_1      15
-#define CONFIG_SENSOR_QVGA_FPS_FIXED_1      15
-#define CONFIG_SENSOR_CIF_FPS_FIXED_1       15
-#define CONFIG_SENSOR_VGA_FPS_FIXED_1       15
-#define CONFIG_SENSOR_480P_FPS_FIXED_1      15
-#define CONFIG_SENSOR_SVGA_FPS_FIXED_1      15
-#define CONFIG_SENSOR_720P_FPS_FIXED_1      30
+#define CONFIG_SENSOR_QCIF_FPS_FIXED_1      15000
+#define CONFIG_SENSOR_QVGA_FPS_FIXED_1      15000
+#define CONFIG_SENSOR_CIF_FPS_FIXED_1       15000
+#define CONFIG_SENSOR_VGA_FPS_FIXED_1       15000
+#define CONFIG_SENSOR_480P_FPS_FIXED_1      15000
+#define CONFIG_SENSOR_SVGA_FPS_FIXED_1      15000
+#define CONFIG_SENSOR_720P_FPS_FIXED_1      30000
 
 #endif  //#ifdef CONFIG_VIDEO_RK29
 /*---------------- Camera Sensor Configuration Macro End------------------------*/
 #else
 #define SDRAM_SIZE          SZ_512M
 #endif
+
 #define PMEM_GPU_SIZE       SZ_64M
-#define PMEM_UI_SIZE        SZ_32M
+/*1280*800 : (32+64)M ,1024*768 : (26+48)M, 800*600 : (16+32)M, 800*480 : (12+32)M,*/
+#define PMEM_UI_SIZE        (48 * SZ_1M)
 #define PMEM_VPU_SIZE       SZ_64M
 #define PMEM_SKYPE_SIZE     0
 #define PMEM_CAM_SIZE       PMEM_CAM_NECESSARY
@@ -903,11 +905,26 @@ static struct wm8994_pdata wm8994_platform_data = {
 
        .micdet_irq = 0,
        .irq_base = 0,
+       .lineout1_diff = 1,
        .PA_control_pin=RK29_PIN6_PB6,
        
 };
 #endif 
 
+#if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_SPKOUT) || defined (CONFIG_SND_SOC_RT5625_SPK_FORM_HPOUT)
+
+//please define level value of power amp control
+#define POWER_AMP_ON 0
+#define POWER_AMP_OFF 1
+#define RT5625_POWER_AMP_PIN INVALID_GPIO  //RK29_PIN6_PB6
+
+struct rt5625_platform_data rt5625_platform_data = {
+       .spk_ctr_pin = RT5625_POWER_AMP_PIN,
+       .spk_ctr_on = POWER_AMP_ON,
+       .spk_ctr_off = POWER_AMP_OFF,
+};
+#endif
+
 #ifdef CONFIG_RK_HEADSET_DET
 
 struct rk_headset_pdata rk_headset_info = {
@@ -1101,11 +1118,14 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
         },
 #endif
 
-#if defined (CONFIG_SND_SOC_RT5625)
+//note: rt5625 support two hardware connect, select the right config
+
+#if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_SPKOUT) || defined (CONFIG_SND_SOC_RT5625_SPK_FORM_HPOUT)
        {
                .type                   = "rt5625",
                .addr                   = 0x1e,         //need check A1 pin,A1 pin is low,addr=0x1e,A1 pin is high,addr=0x1f.
                .flags                  = 0,
+               .platform_data  = &rt5625_platform_data,
        },
 #endif
 
@@ -1828,6 +1848,7 @@ static int mu509_io_deinit(void)
 struct rk29_mu509_data rk29_mu509_info = {
        .io_init = mu509_io_init,
        .io_deinit = mu509_io_deinit,
+       .modem_power_en = RK29_PIN6_PC2,
        .bp_power = RK29_PIN6_PB1,//RK29_PIN0_PB4,
        .bp_power_active_low = 1,
        .bp_reset = RK29_PIN6_PC7,//RK29_PIN0_PB3,
diff --git a/arch/arm/mach-rk29/i2c_sram.c b/arch/arm/mach-rk29/i2c_sram.c
new file mode 100755 (executable)
index 0000000..aa4a3ad
--- /dev/null
@@ -0,0 +1,527 @@
+#include <mach/rk29_iomap.h>
+#include <mach/board.h>
+#include <mach/sram.h>
+#include <mach/iomux.h>
+#include <mach/cru.h>
+#include <asm/io.h>
+#include <mach/gpio.h>
+
+#if defined(CONFIG_RK29_I2C_INSRAM)
+
+#define I2C_SPEED 200
+
+#if defined(CONFIG_MACH_RK29_TD8801_V2)
+/******************need set when you use i2c*************************/
+#define I2C_SADDR               (0x34)        /* slave address ,wm8310 addr is 0x34*/
+#define SRAM_I2C_CH 1  //CH==0, i2c0,CH==1, i2c1,CH==2, i2c2,CH==3, i2c3
+#define SRAM_I2C_ADDRBASE RK29_I2C1_BASE //RK29_I2C0_BASE\RK29_I2C2_BASE\RK29_I2C3_BASE
+#define I2C_SLAVE_ADDR_LEN 1  // 2:slav addr is 10bit ,1:slav addr is 7bit
+#define I2C_SLAVE_REG_LEN 2   // 2:slav reg addr is 16 bit ,1:is 8 bit
+#define SRAM_I2C_DATA_BYTE 2  //i2c transmission data is 1bit(8wei) or 2bit(16wei)
+#define GRF_GPIO_IOMUX GRF_GPIO1L_IOMUX
+/*ch=0:GRF_GPIO2L_IOMUX,ch=1:GRF_GPIO1L_IOMUX,ch=2:GRF_GPIO5H_IOMUX,ch=3:GRF_GPIO2L_IOMUX*/
+#define I2C_GRF_GPIO_IOMUX (~(0x03<<14))&(~(0x03<<12))|(0x01<<14)|(0x01<<12)
+/*CH=0:(~(0x03<<30))&(~(0x03<<28))|(0x01<<30)|(0x01<<28),CH=1:(~(0x03<<14))&(~(0x03<<12))|(0x01<<14)|(0x01<<12),
+CH=2:(~(0x03<<24))&(~(0x03<<22))|(0x01<<24)|(0x01<<22),CH=3:(~(0x03<<26))&(~(0x03<<24))|(0x02<<26)|(0x02<<24)*/
+/***************************************/
+#if defined(SRAM_I2C_CH)
+#define CRU_CLKGATE_ADDR  CRU_CLKGATE2_CON
+#define  CRU_CLKGATE_BIT SRAM_I2C_CH+11
+#else
+#define CRU_CLKGATE_ADDR  CRU_CLKGATE0_CON
+#define  CRU_CLKGATE_BIT 26
+#endif
+//#define SRAM_I2C_ADDRBASE (RK29_I2C##SRAM_I2C_CH##_BASE      )
+
+#define I2C_SLAVE_TYPE (((I2C_SLAVE_ADDR_LEN-1)<<4)|((I2C_SLAVE_REG_LEN-1)))
+
+#define uint8 unsigned char
+#define uint16 unsigned short
+#define uint32 unsigned int
+uint32 __sramdata data[5];
+
+#define CRU_CLKGATE0_CON       0x54
+#define CRU_CLKGATE2_CON       0x64
+#define CRU_CLKGATE1_CON       0x60
+
+#define CRU_CLKSEL0_CON                0x14
+#define GRF_GPIO5H_IOMUX       0x74
+#define GRF_GPIO2L_IOMUX       0x58
+#define GRF_GPIO1L_IOMUX       0x50
+
+#define I2C_ARBITR_LOSE_STATUS   (1<<7)        // Arbitration lose STATUS
+#define I2C_RECE_INT_MACKP       (1<<1)        // Master ACK period interrupt status bit
+#define I2C_RECE_INT_MACK        (1)           // Master receives ACK interrupt status bit
+
+#define I2C_MTXR                (0x0000)               /* master transmit */
+#define I2C_MRXR                (0x0004)        /* master receive */
+
+#define I2C_IER                 (0x0014)        /* interrupt enable control */
+#define I2C_ISR                 (0x0018)        /* interrupt status, write 0 to clear */
+#define I2C_LCMR                (0x001c)        /* stop/start/resume command, write 1 to set */
+#define I2C_LSR                 (0x0020)        /* i2c core status */
+#define I2C_CONR                (0x0024)        /* i2c config */
+#define I2C_OPR                 (0x0028)        /* i2c core config */
+#define I2C_MASTER_TRAN_MODE    (1<<3)
+#define I2C_MASTER_PORT_ENABLE  (1<<2)
+#define I2C_CON_NACK           (1 << 4)
+#define I2C_CON_ACK            (0)
+#define I2C_LCMR_RESUME         (1<<2)
+#define I2C_LCMR_STOP           (1<<1)
+#define I2C_LCMR_START          (1<<0)
+#define SRAM_I2C_WRITE                 (0x0ul)
+#define SRAM_I2C_READ          (0x1ul)
+#define I2C_MASTER_RECE_MODE   (0)
+#define I2C_CORE_ENABLE         (1<<6)
+#define I2C_CORE_DISABLE        (0)
+
+#define SRAM_I2C_CLK_ENABLE()  writel((~0x000000085), RK29_CRU_BASE + CRU_CLKGATE1_CON);
+#define SRAM_I2C_CLK_DISABLE() writel(~0, RK29_CRU_BASE + CRU_CLKGATE1_CON);
+#define sram_i2c_set_mode() do{ writel(0x0,SRAM_I2C_ADDRBASE + I2C_ISR);writel(0x0, SRAM_I2C_ADDRBASE + I2C_IER);writel((readl(SRAM_I2C_ADDRBASE + I2C_CONR)&(~(0x1ul<<4)))|I2C_MASTER_TRAN_MODE|I2C_MASTER_PORT_ENABLE, SRAM_I2C_ADDRBASE + I2C_CONR);}while(0)
+#define sram_udelay(usecs,a) LOOP((usecs)*LOOPS_PER_USEC)
+
+void __sramfunc sram_i2c_start(void);
+void __sramfunc sram_i2c_stop(void);
+uint8 __sramfunc sram_i2c_wait_event(void);
+uint8 __sramfunc sram_i2c_send_data(uint8 buf, uint8 startbit);
+uint8 __sramfunc sram_i2c_read_data(uint8 *buf);
+uint8 __sramfunc sram_i2c_slaveAdr(uint16 I2CSlaveAddr, uint8 addressBit, uint8 read_or_write);
+
+void __sramfunc sram_printch(char byte);
+void __sramfunc print_Hex(unsigned int hex);
+
+
+void  i2c_interface_ctr_reg_pread()
+{
+    readl(SRAM_I2C_ADDRBASE);
+    readl(RK29_CRU_BASE);
+    readl(RK29_GRF_BASE);
+       readl(RK29_GPIO0_BASE);
+       readl(RK29_GPIO1_BASE);
+       readl(RK29_GPIO2_BASE);
+       readl(RK29_GPIO3_BASE);
+       readl(RK29_GPIO4_BASE);
+       readl(RK29_GPIO5_BASE);
+       readl(RK29_GPIO6_BASE);
+}
+
+void __sramfunc sram_i2c_delay(int delay_time)
+{
+    int n = 100 * delay_time;
+    while(n--)
+    {
+        __asm__ __volatile__("");
+    }
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_init
+Desc      : initialize the necessary registers
+Params    : channel-determine which I2C bus we used
+Return    : none
+------------------------------------------------------------------------------------------------------*/
+void __sramfunc sram_i2c_init()
+{
+
+    //enable cru_clkgate1 clock
+    data[0] = readl(RK29_CRU_BASE + CRU_CLKGATE1_CON);
+    writel(data[0]&(~0x00000085), RK29_CRU_BASE + CRU_CLKGATE1_CON);
+    //set the pclk
+    data[1] = readl(RK29_CRU_BASE + CRU_CLKSEL0_CON);
+    writel(data[1]&(~(0x07 << 5))&(~(0x03 << 10)) | (0x03 << 10), RK29_CRU_BASE + CRU_CLKSEL0_CON);
+    data[2] = readl(RK29_CRU_BASE + CRU_CLKGATE_ADDR);
+    writel(data[2]&(~(0x01 << CRU_CLKGATE_BIT)), RK29_CRU_BASE + CRU_CLKGATE_ADDR);
+    data[3] = readl(RK29_GRF_BASE + GRF_GPIO_IOMUX);
+    writel(data[3]&I2C_GRF_GPIO_IOMUX, RK29_GRF_BASE + GRF_GPIO_IOMUX);
+
+
+    //reset I2c-reg base
+    data[4] = readl(SRAM_I2C_ADDRBASE + I2C_OPR);
+    writel(data[4] | (0x1ul << 7), SRAM_I2C_ADDRBASE + I2C_OPR);
+    sram_i2c_delay(10);
+    writel(data[4]&(~(0x1ul << 7)), SRAM_I2C_ADDRBASE + I2C_OPR);
+    writel(0x0, SRAM_I2C_ADDRBASE + I2C_LCMR);
+    //disable arq
+    writel(0x0, SRAM_I2C_ADDRBASE + I2C_IER);
+    writel(data[4]&(~0x03f), SRAM_I2C_ADDRBASE + I2C_OPR);
+    //enable i2c core
+    writel(data[4] | I2C_CORE_ENABLE ,  SRAM_I2C_ADDRBASE  + I2C_OPR);
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_deinit
+Desc      : de-initialize the necessary registers
+Params    : noe
+Return    : none
+------------------------------------------------------------------------------------------------------*/
+void __sramfunc sram_i2c_deinit(void)
+{
+    SRAM_I2C_CLK_ENABLE();
+    //restore i2c opr reg
+    writel(data[4], SRAM_I2C_ADDRBASE + I2C_OPR);
+
+    //restore iomux reg
+    writel(data[3], RK29_GRF_BASE + GRF_GPIO_IOMUX);
+
+    //restore cru gate2
+    writel(data[2], RK29_CRU_BASE + CRU_CLKGATE_ADDR);
+
+    //restore scu clock reg
+    writel(data[1], RK29_CRU_BASE + CRU_CLKSEL0_CON);
+
+    //restore cru gate1
+    writel(data[0], RK29_CRU_BASE + CRU_CLKGATE1_CON);
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_start
+Desc      : start i2c
+Params    : none
+Return    : none
+------------------------------------------------------------------------------------------------------*/
+void __sramfunc sram_i2c_start(void)
+{
+    writel(I2C_LCMR_START | I2C_LCMR_RESUME, SRAM_I2C_ADDRBASE + I2C_LCMR);
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_stop
+Desc      : stop i2c
+Params    : none
+Return    : none
+------------------------------------------------------------------------------------------------------*/
+void __sramfunc sram_i2c_stop(void)
+{
+    writel(I2C_LCMR_STOP | I2C_LCMR_RESUME, SRAM_I2C_ADDRBASE + I2C_LCMR);
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_wait_event
+Desc      : wait the ack
+Params    : none
+Return    : success: return 0; fail: return 1
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_wait_event(void)
+{
+    unsigned int isr, waiteSendDelay = 3;
+
+    isr = readl(SRAM_I2C_ADDRBASE + I2C_ISR);
+
+    while (waiteSendDelay > 0)
+    {
+        if ((isr & I2C_ARBITR_LOSE_STATUS) != 0)
+        {
+            writel(0x0, SRAM_I2C_ADDRBASE + I2C_ISR);
+            return 1;
+        }
+        if ((isr & I2C_RECE_INT_MACK) != 0)
+        {
+            break;
+        }
+        sram_i2c_delay(1);
+        waiteSendDelay--;
+    }
+    writel(isr & (~0x1ul) , SRAM_I2C_ADDRBASE + I2C_ISR);
+    return 0;
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_send_data
+Desc      : send a byte data
+Params    : buf: the data we need to send;
+            startbit: startbit=1, send a start signal
+                      startbit=0, do not send a start signal
+Return    : success: return 0; fail: return 1
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_send_data(uint8 buf, uint8 startbit)
+{
+    writel(buf, SRAM_I2C_ADDRBASE + I2C_MTXR);
+    readl(SRAM_I2C_ADDRBASE + I2C_LCMR);
+    if(startbit)
+    {
+        writel(I2C_LCMR_START | I2C_LCMR_RESUME, SRAM_I2C_ADDRBASE + I2C_LCMR);
+        sram_i2c_delay(50);
+    }
+    else
+    {
+        writel(I2C_LCMR_RESUME, SRAM_I2C_ADDRBASE + I2C_LCMR);
+        sram_i2c_delay(50);
+    }
+
+    if(sram_i2c_wait_event() != 0)
+        return 1;
+
+    return 0;
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_send_data
+Desc      : receive a byte data
+Params    : buf: save the data we received
+Return    : success: return 0; fail: return 1
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_read_data(uint8 *buf)
+{
+    unsigned int ret;
+    uint8 waitDelay = 3;
+
+    ret = readl(SRAM_I2C_ADDRBASE + I2C_LCMR);
+    writel(ret | I2C_LCMR_RESUME, SRAM_I2C_ADDRBASE + I2C_LCMR);
+
+    while(waitDelay > 0)
+    {
+        ret = readl(SRAM_I2C_ADDRBASE + I2C_ISR);
+        if((ret & I2C_ARBITR_LOSE_STATUS) != 0)
+            return 1;
+
+        if((ret & I2C_RECE_INT_MACKP) != 0)
+            break;
+
+        waitDelay--;
+    }
+
+    sram_i2c_delay(50);
+    *buf = (uint8)readl(SRAM_I2C_ADDRBASE + I2C_MRXR);
+    ret = readl(SRAM_I2C_ADDRBASE + I2C_ISR);
+    writel(ret & (~(0x1 << 1)), SRAM_I2C_ADDRBASE + I2C_ISR);
+    return 0;
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_slaveAdr
+Desc      : send the slaveAddr in 10bit mode or in 7bit mode
+Params    : I2CSlaveAddr: slave address
+            addressbit: high 4bits determine 7 bits or 10 bits slave address锛沴ow 4bits determine 8 bits or 16 bits regAddress
+            high 4bits==7, slave address is 7 bits
+            high 4bits==10,slave address is 10 bits
+            low 4bits==0, slave address is 8 bits
+            low 4bits==1, slave address is 16 bits
+            read_or_write: read a data or write a data from salve
+Return    : sucess return 0, fail return 0
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_slaveAdr(uint16 I2CSlaveAddr, uint8 addressBit, uint8 read_or_write)
+{
+    uint8 retv = 1;
+
+    if((addressBit & 0xf0) == 0x10)               //10bit slave address
+    {
+        if(sram_i2c_send_data((I2CSlaveAddr >> 7) & 0x06 | 0xf0 | read_or_write, 1) != 0)
+            goto STOP;
+
+        sram_i2c_delay(50);
+        if(sram_i2c_send_data((I2CSlaveAddr) & 0xff | read_or_write, 0) != 0)
+            goto STOP;
+    }
+    else                //7bit slave address
+    {
+        if(sram_i2c_send_data((I2CSlaveAddr << 1) | read_or_write, 1) != 0)
+            goto STOP;
+    }
+
+    retv = 0;
+
+STOP:
+    //sram_i2c_stop();
+    return retv;
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_wirte
+Desc      : conduct wirte operation
+Params    : I2CSlaveAddr: slave address
+            regAddr: slave register address
+            *pdataBuff: data we want to write
+            size: number of bytes
+            addressbit: high 4bits determine 7 bits or 10 bits slave address锛沴ow 4bits determine 8 bits or 16 bits regAddress
+            high 4bits==7, slave address is 7 bits
+            high 4bits==10,slave address is 10 bits
+            low 4bits==0, slave address is 8 bits
+            low 4bits==1, slave address is 16 bits
+Return    : success: return 0; fail: return 1
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_write(uint16 I2CSlaveAddr, uint16 regAddr, void *pdataBuff, uint16 size, uint8 addressBit)
+{
+    unsigned int ret;
+    uint8 *pdata;
+    uint8 bit_if16 = (addressBit & 0x0f) ? 0x2 : 0x1; 
+    uint8 retv = 1;
+
+    pdata = (uint8 *) pdataBuff;
+
+    sram_i2c_set_mode();
+
+    sram_i2c_delay(50);
+    if((retv = sram_i2c_slaveAdr(I2CSlaveAddr, addressBit, SRAM_I2C_WRITE)) != 0)
+        goto STOP;
+    sram_i2c_delay(50);
+
+    do
+    {
+       bit_if16--;
+        if (sram_i2c_send_data((regAddr >> (bit_if16 ? 8 : 0)) & 0xff, 0) != 0)
+            goto STOP;
+               
+    }
+    while(bit_if16);
+       
+    sram_i2c_delay(50);
+
+    do
+    {
+        if (sram_i2c_send_data(*pdata, 0) != 0)
+            goto STOP;
+        sram_i2c_delay(50);
+        pdata++;
+        size--;
+    }
+    while (size);
+
+    retv = 0;
+    ret = readl( SRAM_I2C_ADDRBASE + I2C_CONR);
+    writel(ret | I2C_CON_NACK, SRAM_I2C_ADDRBASE + I2C_CONR);
+
+STOP:
+    sram_i2c_stop();
+    return retv;
+}
+
+
+/*-------------------------------------------------------------------------------------------------------
+Name      : sram_i2c_read
+Desc      : conduct read operation
+Params    : I2CSlaveAddr: slave address
+            regAddr: slave register address
+            *pdataBuff: save the data master received
+            size: number of bytes
+            addressbit: high 4bits determine 7 bits or 10 bits slave address锛沴ow 4bits determine 8 bits or 16 bits regAddress
+            high 4bits==7, slave address is 7 bits
+            high 4bits==10,slave address is 10 bits
+            low 4bits==0, slave address is 8 bits
+            low 4bits==1, slave address is 16 bits
+            mode: mode=0, NORMALMODE
+                  mode=1, DIRECTMODE
+Return    : success: return 0; fail: return 1
+------------------------------------------------------------------------------------------------------*/
+uint8 __sramfunc sram_i2c_read(uint16 I2CSlaveAddr, uint16 regAddr, void *pdataBuff, uint16 size, uint8 addressBit)
+{
+    uint8 *pdata;
+    unsigned int ret;
+    uint8 bit_if16 = (addressBit & 0x0f) ? 0x2 : 0x1;
+    uint8 retv = 1;
+
+    pdata = (uint8 *)pdataBuff;
+    sram_i2c_set_mode();
+    //sram_i2c_delay(50);
+
+    if((retv = sram_i2c_slaveAdr(I2CSlaveAddr, addressBit, SRAM_I2C_WRITE)) != 0)
+        goto STOP;
+    //sram_i2c_delay(50);
+
+    do
+    {
+       bit_if16--;
+        if (sram_i2c_send_data((regAddr >> (bit_if16 ? 8 : 0)) & 0xff, 0) != 0)
+            goto STOP;
+    }
+    while(bit_if16);
+
+    sram_i2c_delay(50);
+
+    if((retv = sram_i2c_slaveAdr(I2CSlaveAddr, addressBit, SRAM_I2C_READ)) != 0)
+        goto STOP;
+
+    writel((ret&(~(0x1 << 3))) | I2C_MASTER_RECE_MODE | I2C_MASTER_PORT_ENABLE, SRAM_I2C_ADDRBASE + I2C_CONR);
+    do
+    {
+        ret = readl(SRAM_I2C_ADDRBASE + I2C_CONR);
+        if(size == 1)
+        {
+            if((sram_i2c_read_data(pdata)) != 0)
+                goto STOP;
+            writel(ret | I2C_CON_NACK, SRAM_I2C_ADDRBASE + I2C_CONR);
+        }
+        else
+        {
+            if((sram_i2c_read_data(pdata)) != 0)
+                goto STOP;
+            writel(ret & (~(0x1ul << 4)) | I2C_CON_ACK, SRAM_I2C_ADDRBASE + I2C_CONR);
+        }
+        //sram_i2c_delay(50);
+        pdata++;
+        size--;
+    }
+    while (size);
+
+    retv = 0;
+
+STOP:
+    sram_i2c_stop();
+    return retv;
+}
+unsigned int __sramfunc rk29_suspend_voltage_set(unsigned int vol)
+{
+    uint8 slaveaddr;
+    uint16 slavereg;
+    unsigned int ret, mask, addr;
+    uint8 data[2];
+
+    sram_i2c_init();  //init i2c device
+    slaveaddr = I2C_SADDR;            //slave device addr
+    slavereg = 0x4003;            // reg addr
+
+    data[0] = 0x00;       //clear i2c when read
+    data[1] = 0x00;
+    ret = sram_i2c_read(slaveaddr, slavereg, data, SRAM_I2C_DATA_BYTE, I2C_SLAVE_TYPE);  
+   // print_Hex(data[0]); //read data saved in data
+   // print_Hex(data[1]); //read data saved in data
+    //sram_printch('\n');
+       
+    data[0] |= (0x1<<6);        //write data
+    sram_i2c_write(slaveaddr, slavereg, data, SRAM_I2C_DATA_BYTE, I2C_SLAVE_TYPE);//wm831x enter sleep mode    
+    sram_i2c_delay(50);
+
+    sram_i2c_deinit();  //deinit i2c device
+
+}
+
+void __sramfunc rk29_suspend_voltage_resume(unsigned int vol)
+{
+    uint8 slaveaddr;
+    uint16 slavereg;
+    unsigned int ret, mask, addr;
+    uint8 data[2];
+
+    sram_i2c_init();  //init i2c device
+    slaveaddr = I2C_SADDR;            //slave device addr
+    slavereg = 0x4003;            // reg addr
+  
+    data[0] = 0x00;       //clear i2c when read
+    data[1] = 0x00;  
+    ret = sram_i2c_read(slaveaddr, slavereg, data, SRAM_I2C_DATA_BYTE, I2C_SLAVE_TYPE);
+   // print_Hex(data[0]); //read data saved in data
+   // print_Hex(data[1]); //read data saved in data
+   // sram_printch('\n');
+
+    data[0] &= ~(0x1<<6);        //write data   
+    sram_i2c_write(slaveaddr, slavereg, data, SRAM_I2C_DATA_BYTE, I2C_SLAVE_TYPE);//wm831x exit sleep mode
+    sram_i2c_delay(50);
+
+    sram_i2c_deinit();  //deinit i2c device
+    // To make the system time correct after resume from suspend
+    sram_udelay(100000, 24); 
+
+}
+
+#endif
+#endif
+
+
index 9099b888f6a76917f8390e58598eed72a2d4c23b..515b09c7f06209baf94a9812b063ecf809ba7f8b 100755 (executable)
@@ -226,6 +226,12 @@ struct cs42l52_platform_data {
     void    (*exit_platform_hw)(void);
 };
 
+struct rt5625_platform_data {
+    int spk_ctr_pin;
+       int spk_ctr_on;
+       int spk_ctr_off;
+};
+
 //tcl miaozh add
 /*nas touch */
 struct nas_platform_data {
old mode 100644 (file)
new mode 100755 (executable)
index 70d78c7..7aa76c0
@@ -2,15 +2,17 @@
 #define PM_VOL_H\r
 \r
 \r
-#if defined(CONFIG_RK29_SPI_INSRAM)||defined(CONFIG_RK29_PWM_INSRAM)\r
+#if defined(CONFIG_RK29_SPI_INSRAM)||defined(CONFIG_RK29_PWM_INSRAM)||defined(CONFIG_RK29_I2C_INSRAM)\r
 \r
 void interface_ctr_reg_pread(void);\r
+void i2c_interface_ctr_reg_pread(void);\r
 unsigned int __sramfunc rk29_suspend_voltage_set(unsigned int vol);\r
 void __sramfunc rk29_suspend_voltage_resume(unsigned int vol);\r
 \r
 #else\r
 \r
 #define interface_ctr_reg_pread()\r
+#define i2c_interface_ctr_reg_pread()\r
 static unsigned int __sramfunc rk29_suspend_voltage_set(unsigned int vol) { return 0; }\r
 #define rk29_suspend_voltage_resume(a)\r
 \r
index 45fbc3bd11e7753c0dff16abc89695f1f12fd3ed..c1cbc3289921e3989192f5f394a778f0a8363ba9 100755 (executable)
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <plat/rk_camera.h>
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#include <linux/videodev2.h>
+
+#define RK29_CAM_DRV_NAME "rk29xx-camera"
+#define RK29_CAM_PLATFORM_DEV_ID 33
+
+#define INVALID_GPIO -1
+
+#define RK29_CAM_IO_SUCCESS 0
+#define RK29_CAM_EIO_INVALID -1
+#define RK29_CAM_EIO_REQUESTFAIL -2
+
+#define RK29_CAM_SUPPORT_NUMS   6
+
+/*---------------- Camera Sensor Must Define Macro Begin  ------------------------*/
+#define RK29_CAM_SENSOR_OV7675 ov7675
+#define RK29_CAM_SENSOR_OV9650 ov9650
+#define RK29_CAM_SENSOR_OV2640 ov2640
+#define RK29_CAM_SENSOR_OV2655 ov2655
+#define RK29_CAM_SENSOR_OV2659 ov2659
+#define RK29_CAM_SENSOR_OV7690 ov7690
+#define RK29_CAM_SENSOR_OV3640 ov3640
+#define RK29_CAM_SENSOR_OV5640 ov5640
+#define RK29_CAM_SENSOR_OV5642 ov5642
+#define RK29_CAM_SENSOR_S5K6AA s5k6aa
+#define RK29_CAM_SENSOR_MT9D112 mt9d112
+#define RK29_CAM_SENSOR_MT9D113 mt9d113
+#define RK29_CAM_SENSOR_MT9P111 mt9p111
+#define RK29_CAM_SENSOR_MT9T111 mt9t111
+#define RK29_CAM_SENSOR_GT2005  gt2005
+#define RK29_CAM_SENSOR_GC0307  gc0307
+#define RK29_CAM_SENSOR_GC0308  gc0308
+#define RK29_CAM_SENSOR_GC0309  gc0309
+#define RK29_CAM_SENSOR_GC2015  gc2015
+#define RK29_CAM_SENSOR_SIV120B  siv120b
+#define RK29_CAM_SENSOR_SID130B  sid130B
+#define RK29_CAM_SENSOR_HI253  hi253
+#define RK29_CAM_SENSOR_HI704  hi704
+#define RK29_CAM_SENSOR_NT99250 nt99250
+
+#define RK29_CAM_SENSOR_NAME_OV7675 "ov7675"
+#define RK29_CAM_SENSOR_NAME_OV9650 "ov9650"
+#define RK29_CAM_SENSOR_NAME_OV2640 "ov2640"
+#define RK29_CAM_SENSOR_NAME_OV2655 "ov2655"
+#define RK29_CAM_SENSOR_NAME_OV2659 "ov2659"
+#define RK29_CAM_SENSOR_NAME_OV7690 "ov7690"
+#define RK29_CAM_SENSOR_NAME_OV3640 "ov3640"
+#define RK29_CAM_SENSOR_NAME_OV5640 "ov5640"
+#define RK29_CAM_SENSOR_NAME_OV5642 "ov5642"
+#define RK29_CAM_SENSOR_NAME_S5K6AA "s5k6aa"
+#define RK29_CAM_SENSOR_NAME_MT9D112 "mt9d112"
+#define RK29_CAM_SENSOR_NAME_MT9D113 "mt9d113"
+#define RK29_CAM_SENSOR_NAME_MT9P111 "mt9p111"
+#define RK29_CAM_SENSOR_NAME_MT9T111 "mt9t111"
+#define RK29_CAM_SENSOR_NAME_GT2005  "gt2005"
+#define RK29_CAM_SENSOR_NAME_GC0307  "gc0307"
+#define RK29_CAM_SENSOR_NAME_GC0308  "gc0308"
+#define RK29_CAM_SENSOR_NAME_GC0309  "gc0309"
+#define RK29_CAM_SENSOR_NAME_GC2015  "gc2015"
+#define RK29_CAM_SENSOR_NAME_SIV120B "siv120b"
+#define RK29_CAM_SENSOR_NAME_SID130B "sid130B"
+#define RK29_CAM_SENSOR_NAME_HI253  "hi253"
+#define RK29_CAM_SENSOR_NAME_HI704  "hi704"
+#define RK29_CAM_SENSOR_NAME_NT99250 "nt99250"
+
+#define ov7675_FULL_RESOLUTION     0x30000            // 0.3 megapixel
+#define ov9650_FULL_RESOLUTION     0x130000           // 1.3 megapixel   
+#define ov2640_FULL_RESOLUTION     0x200000           // 2 megapixel
+#define ov2655_FULL_RESOLUTION     0x200000           // 2 megapixel
+#define ov2659_FULL_RESOLUTION     0x200000           // 2 megapixel
+#define ov7690_FULL_RESOLUTION     0x300000           // 2 megapixel
+#define ov3640_FULL_RESOLUTION     0x300000           // 3 megapixel
+#define ov5640_FULL_RESOLUTION     0x500000           // 5 megapixel
+#define ov5642_FULL_RESOLUTION     0x500000           // 5 megapixel
+#define s5k6aa_FULL_RESOLUTION     0x130000           // 1.3 megapixel
+#define mt9d112_FULL_RESOLUTION    0x200000           // 2 megapixel
+#define mt9d113_FULL_RESOLUTION    0x200000           // 2 megapixel
+#define mt9t111_FULL_RESOLUTION    0x300000           // 3 megapixel
+#define mt9p111_FULL_RESOLUTION    0x500000           // 5 megapixel
+#define gt2005_FULL_RESOLUTION     0x200000           // 2 megapixel
+#define gc0308_FULL_RESOLUTION     0x30000            // 0.3 megapixel
+#define gc0309_FULL_RESOLUTION     0x30000            // 0.3 megapixel
+#define gc2015_FULL_RESOLUTION     0x200000           // 2 megapixel
+#define siv120b_FULL_RESOLUTION     0x30000            // 0.3 megapixel
+#define sid130B_FULL_RESOLUTION     0x200000           // 2 megapixel    
+#define hi253_FULL_RESOLUTION       0x200000           // 2 megapixel
+#define hi704_FULL_RESOLUTION       0x30000            // 0.3 megapixel
+#define nt99250_FULL_RESOLUTION     0x200000           // 2 megapixel
+/*---------------- Camera Sensor Must Define Macro End  ------------------------*/
+
+
+#define RK29_CAM_POWERACTIVE_BITPOS    0x00
+#define RK29_CAM_POWERACTIVE_MASK      (1<<RK29_CAM_POWERACTIVE_BITPOS)
+#define RK29_CAM_POWERACTIVE_H (0x01<<RK29_CAM_POWERACTIVE_BITPOS)
+#define RK29_CAM_POWERACTIVE_L (0x00<<RK29_CAM_POWERACTIVE_BITPOS)
+
+#define RK29_CAM_RESETACTIVE_BITPOS    0x01
+#define RK29_CAM_RESETACTIVE_MASK      (1<<RK29_CAM_RESETACTIVE_BITPOS)
+#define RK29_CAM_RESETACTIVE_H (0x01<<RK29_CAM_RESETACTIVE_BITPOS)
+#define RK29_CAM_RESETACTIVE_L  (0x00<<RK29_CAM_RESETACTIVE_BITPOS)
+
+#define RK29_CAM_POWERDNACTIVE_BITPOS  0x02
+#define RK29_CAM_POWERDNACTIVE_MASK    (1<<RK29_CAM_POWERDNACTIVE_BITPOS)
+#define RK29_CAM_POWERDNACTIVE_H       (0x01<<RK29_CAM_POWERDNACTIVE_BITPOS)
+#define RK29_CAM_POWERDNACTIVE_L       (0x00<<RK29_CAM_POWERDNACTIVE_BITPOS)
+
+#define RK29_CAM_FLASHACTIVE_BITPOS    0x03
+#define RK29_CAM_FLASHACTIVE_MASK      (1<<RK29_CAM_FLASHACTIVE_BITPOS)
+#define RK29_CAM_FLASHACTIVE_H (0x01<<RK29_CAM_FLASHACTIVE_BITPOS)
+#define RK29_CAM_FLASHACTIVE_L  (0x00<<RK29_CAM_FLASHACTIVE_BITPOS)
+
+/* v4l2_subdev_core_ops.ioctl  ioctl_cmd macro */
+#define RK29_CAM_SUBDEV_ACTIVATE            0x00
+#define RK29_CAM_SUBDEV_DEACTIVATE          0x01
+#define RK29_CAM_SUBDEV_IOREQUEST                      0x02
+#define RK29_CAM_SUBDEV_CB_REGISTER         0x03
+
+enum rk29camera_ioctrl_cmd
+{
+       Cam_Power,
+       Cam_Reset,
+       Cam_PowerDown,
+       Cam_Flash
+};
+
+enum rk29sensor_power_cmd
+{
+       Sensor_Reset,
+       Sensor_PowerDown,
+       Sensor_Flash
+};
+
+enum rk29camera_flash_cmd
+{
+    Flash_Off,
+    Flash_On,
+    Flash_Torch
+};
+
+struct rk29camera_gpio_res {
+    unsigned int gpio_reset;
+    unsigned int gpio_power;
+       unsigned int gpio_powerdown;
+       unsigned int gpio_flash;
+    unsigned int gpio_flag;
+       unsigned int gpio_init;
+    
+    const char *dev_name;
+};
+
+struct rk29camera_mem_res {
+       const char *name;
+       unsigned int start;
+       unsigned int size;
+};
+struct rk29camera_info {
+    const char *dev_name;
+    unsigned int orientation;
+    struct v4l2_frmivalenum fival[10];
+};
+struct rk29camera_platform_data {
+    int (*io_init)(void);
+    int (*io_deinit)(int sensor);
+       int (*sensor_ioctrl)(struct device *dev,enum rk29camera_ioctrl_cmd cmd,int on);
+    struct rk29camera_gpio_res gpio_res[RK29_CAM_SUPPORT_NUMS];
+       struct rk29camera_mem_res meminfo;
+    struct rk29camera_info info[RK29_CAM_SUPPORT_NUMS];
+};
+
+struct rk29camera_platform_ioctl_cb {
+    int (*sensor_power_cb)(struct rk29camera_gpio_res *res, int on);
+    int (*sensor_reset_cb)(struct rk29camera_gpio_res *res, int on);
+    int (*sensor_powerdown_cb)(struct rk29camera_gpio_res *res, int on);
+    int (*sensor_flash_cb)(struct rk29camera_gpio_res *res, int on);    
+};
+
+typedef struct rk29_camera_sensor_cb {
+    int (*sensor_cb)(void *arg); 
+}rk29_camera_sensor_cb_s;
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
+
index eb7cbb9a6361e9538490e9dff741de0e635cfd38..3cbe5b5477a1b4b56323883ed3db7e250c407e19 100755 (executable)
 #define RK29_DEBUG_PHYS             0x20024000
 #define RK29_DEBUG_SIZE             SZ_16K
 #define RK29_I2C0_PHYS              0x2002C000
+#define RK29_I2C0_BASE             (RK29_ADDR_BASE1+0x2C000)
 #define RK29_I2C0_SIZE              SZ_16K
 #define RK29_UART0_PHYS             0x20030000
 #define RK29_UART0_SIZE             SZ_4K
index 7d4c5279ef7be091f943fe8356ba1de19eaaabb9..40faef3c368d958eb1d2efcfa7560d31f1835d5f 100644 (file)
@@ -28,7 +28,9 @@
 #define VPU_MEM_LINK            _IOW(VPU_MEM_IOCTL_MAGIC, 7, unsigned int)
 #define VPU_MEM_CACHE_CLEAN     _IOW(VPU_MEM_IOCTL_MAGIC, 8, unsigned int)
 #define VPU_MEM_CACHE_INVALID   _IOW(VPU_MEM_IOCTL_MAGIC, 9, unsigned int)
-
+#define VPU_MEM_POOL_SET        _IOW(VPU_MEM_IOCTL_MAGIC, 10, unsigned int)
+#define VPU_MEM_POOL_UNSET      _IOW(VPU_MEM_IOCTL_MAGIC, 11, unsigned int)
+#define VPU_MEM_POOL_CHECK      _IOW(VPU_MEM_IOCTL_MAGIC, 12, unsigned int)
 
 struct vpu_mem_platform_data
 {
old mode 100644 (file)
new mode 100755 (executable)
index 122d8c6..e606909
@@ -52,11 +52,12 @@ static struct map_desc rk29_io_desc[] __initdata = {
        RK29_DEVICE(NANDC),
        RK29_DEVICE(SPI0),
        RK29_DEVICE(SPI1),
+       RK29_DEVICE(I2C0),
        RK29_DEVICE(I2C1),
        RK29_DEVICE(I2C2),
        RK29_DEVICE(I2C3),
-#ifdef CONFIG_DDR_RECONFIG
        RK29_DEVICE(LCDC),
+#ifdef CONFIG_DDR_RECONFIG
        RK29_DEVICE(GPU),
        RK29_DEVICE(VCODEC),
        RK29_DEVICE(VIP),
index f7d4dc0964af0c04e3742f07c186858daf6cc08c..23b303714a6a40545617f568d92dfd2872ef6fc1 100755 (executable)
@@ -57,7 +57,7 @@ static ssize_t memcpy_dma_write(struct device *device, struct device_attribute *
     return 0;\r
 }\r
 \r
-static DEVICE_ATTR(dmamemcpy,  S_IRUGO|S_IALLUGO, memcpy_dma_read, memcpy_dma_write);\r
+static DEVICE_ATTR(dmamemcpy,  S_IRUGO|S_IXUGO, memcpy_dma_read, memcpy_dma_write);\r
 \r
 \r
 static int __devinit dma_memcpy_probe(struct platform_device *pdev)\r
index 656c6d99173fe2cc27630e629921e97d8ed151af..4040573f8ddfc2ae7ce642a4b3d8f25a292c1995 100755 (executable)
@@ -406,7 +406,12 @@ static int rk29_pm_enter(suspend_state_t state)
 
        sram_printch('0');
        flush_tlb_all();
+       #if defined(CONFIG_RK29_SPI_INSRAM) || defined(CONFIG_RK29_PWM_INSRAM)
        interface_ctr_reg_pread();
+       #endif
+       #if defined(CONFIG_RK29_I2C_INSRAM)
+       i2c_interface_ctr_reg_pread();
+       #endif
 
        /* disable clock */
        clkgate[0] = cru_readl(CRU_CLKGATE0_CON);
@@ -433,6 +438,15 @@ static int rk29_pm_enter(suspend_state_t state)
                   | (1 << CLK_GATE_TPIU)
 #endif
                   ) | clkgate[0], CRU_CLKGATE0_CON);
+
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+#if defined(CONFIG_SND_RK29_SOC_I2S_8CH)
+       cru_writel(clkgate[0]&(~(1<<CLK_GATE_I2S0)),CRU_CLKGATE0_CON);
+#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
+       cru_writel(clkgate[0]&(~(1<<CLK_GATE_I2S1)),CRU_CLKGATE0_CON);
+#endif
+#endif 
+
        cru_writel(~0, CRU_CLKGATE1_CON);
        cru_writel(~((1 << CLK_GATE_GPIO1 % 32)
                   | (1 << CLK_GATE_GPIO2 % 32)
@@ -479,9 +493,9 @@ static int rk29_pm_enter(suspend_state_t state)
        cru_writel(clksel0 & ~0x7FC000, CRU_CLKSEL0_CON);
 
        sram_printch('4');
-       
+       pm_gpio_suspend();
        rk29_suspend();
-       
+       pm_gpio_resume();
        sram_printch('4');
        
        /* resume general pll */
diff --git a/arch/arm/mach-rk29/rk29_charge_lowpower.c b/arch/arm/mach-rk29/rk29_charge_lowpower.c
new file mode 100755 (executable)
index 0000000..8f4c28a
--- /dev/null
@@ -0,0 +1,171 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/suspend.h>
+#include <linux/power_supply.h>
+#include <linux/earlysuspend.h>
+#include <mach/rk29_iomap.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+
+
+
+#define CHARGE_EARLYSUSPEND 0
+#define CHARGE_EARLYRESUME  1
+
+/******************************************************************/
+#ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
+
+static DEFINE_MUTEX(power_suspend_lock);
+
+static struct early_suspend charge_lowerpower = {
+
+       .level = -0xff,
+       .suspend = NULL,
+       .resume = NULL,
+};
+
+
+void charge_earlysuspend_enter(int status) //xsf
+{
+
+#ifdef CONFIG_HAS_EARLYSUSPEND  
+
+       struct early_suspend *pos;
+       struct early_suspend *earlysuspend_temp;
+       struct list_head *list_head;
+       struct list_head *list_temp;
+
+
+       mutex_lock(&power_suspend_lock);
+
+       earlysuspend_temp = &charge_lowerpower;
+       list_head =  earlysuspend_temp->link.prev;
+
+       if(status == 0)
+       {
+               list_for_each_entry(pos, list_head, link)
+               {
+//                     printk("earlysuspend-level = %d --\n", pos->level);
+                       if (pos->suspend != NULL)
+                               pos->suspend(pos);
+               }       
+       }
+       
+       if(status == 1)
+       {
+               list_for_each_entry_reverse(pos, list_head, link)
+               {
+//                     printk("earlysuspend-level = %d --\n", pos->level);
+                       if (pos->resume != NULL)
+                               pos->resume(pos);
+               }       
+       }
+
+       mutex_unlock(&power_suspend_lock);
+#endif
+
+}
+int  rk29_charge_judge(void)
+{
+       return readl(RK29_GPIO4_BASE + GPIO_INT_STATUS);
+
+}
+extern int rk29_pm_enter(suspend_state_t state);
+
+int charger_suspend(void)
+{
+
+#ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
+
+       charge_earlysuspend_enter(0); 
+       while(1)
+       {
+               local_irq_disable();
+               rk29_pm_enter(PM_SUSPEND_MEM);
+
+               if((rk29_charge_judge() &&(0x01000000)))
+               {       
+                       local_irq_enable();
+                       break;
+               }
+               else
+                       local_irq_enable();
+       }
+       charge_earlysuspend_enter(1); //xsf
+       return 0;
+#endif
+}
+
+
+
+static int __devinit charge_lowerpower_probe(struct platform_device *pdev)
+{
+
+
+       printk("%s\n",__FUNCTION__);
+#ifdef CONFIG_HAS_EARLYSUSPEND  
+       register_early_suspend(&charge_lowerpower);//xsf
+#endif
+
+}
+
+static struct platform_driver charge_lowerpower_driver = {
+       .probe          = charge_lowerpower_probe,
+       .driver         = {
+               .name   = "charge_lowerpower",
+               .owner  = THIS_MODULE,
+       },
+};
+static int __init charge_lowerpower_init(void)
+{
+       return platform_driver_register(&charge_lowerpower_driver);
+}
+module_init(charge_lowerpower_init);
+
+static void __exit charge_lowerpower_exit(void)
+{
+       platform_driver_unregister(&charge_lowerpower_driver);
+}
+module_exit(charge_lowerpower_exit);
+
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("xsf<xsf@rock-chips.com>");
+MODULE_DESCRIPTION("charger lowerpower");
+
+
+#endif
+/***************************************************************/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/arch/arm/mach-rk29/verifyID.c b/arch/arm/mach-rk29/verifyID.c
new file mode 100644 (file)
index 0000000..db1a4ec
--- /dev/null
@@ -0,0 +1,106 @@
+#include <linux/module.h>\r
+#include <linux/file.h>\r
+#include <linux/fs.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/uaccess.h>\r
+#include "verifyID.h"\r
+\r
+\r
+\r
+static int verifyid_open(struct inode *inode, struct file *file)\r
+{\r
+       int ret;\r
+       ret = generic_file_open(inode, file);\r
+       if (unlikely(ret))\r
+               return ret;\r
+       return 0;\r
+}\r
+\r
+static int verifyid_release(struct inode *ignored, struct file *file)\r
+{\r
+\r
+       return 0;\r
+}\r
+\r
+static int GetChipTag(void)\r
+{\r
+    unsigned long i;\r
+    unsigned long value; \r
+    value = read_XDATA32(RK29_GPIO6_BASE+0x4);\r
+       printk("read gpio6+4 = 0x%x\n",value);\r
+    write_XDATA32((RK29_GPIO6_BASE+0x4), (read_XDATA32(RK29_GPIO6_BASE+0x4)&(~(0x7ul<<28)))); // portD 4:6 input\r
+    value = read_XDATA32(RK29_GPIO6_BASE+0x50); \r
+       printk("read gpio6+0x50 = 0x%x\n",value);\r
+    value = (value>>28)&0x07; \r
+       \r
+    return value;\r
+}\r
+static long verifyid_ioctl(struct file *file, unsigned int cmd, unsigned long arg)\r
+{\r
+       long ret = -ENOTTY;\r
+\r
+       switch (cmd) {\r
+       case VERIFYID_GETID:\r
+               ret=GetChipTag();\r
+               *((unsigned long *)arg) = 1;\r
+               break;\r
+       }\r
+\r
+       return ret;\r
+}\r
+\r
+static ssize_t verifyid_read(struct file *file, char __user *buf,\r
+                          size_t len, loff_t *pos)\r
+{\r
+       long ret = GetChipTag();\r
+       char *kb = {0x11,0x22,0x33,0x44};\r
+       if(ret>0)\r
+               //*buf = 0xf8;\r
+               copy_to_user(buf,kb,1);\r
+       return ret;\r
+}\r
+\r
+static struct file_operations verifyid_fops = {\r
+       .owner = THIS_MODULE,\r
+       .open = verifyid_open,\r
+       .read = verifyid_read,\r
+       .release = verifyid_release,\r
+       .unlocked_ioctl = verifyid_ioctl,\r
+       .compat_ioctl = verifyid_ioctl,\r
+};\r
+\r
+static struct miscdevice verifyid_misc = {\r
+       .minor = MISC_DYNAMIC_MINOR,\r
+       .name = "verifyid",\r
+       .fops = &verifyid_fops,\r
+};\r
+\r
+static int __init verifyid_init(void)\r
+{\r
+       int ret;\r
+       ret = misc_register(&verifyid_misc);\r
+       if (unlikely(ret)) {\r
+               printk(KERN_ERR "verifyid: failed to register misc device!\n");\r
+               return ret;\r
+       }\r
+       printk(KERN_INFO "verifyid: initialized\n");\r
+\r
+       return 0;\r
+}\r
+\r
+static void __exit verifyid_exit(void)\r
+{\r
+       int ret;\r
+\r
+       ret = misc_deregister(&verifyid_misc);\r
+       if (unlikely(ret))\r
+               printk(KERN_ERR "verifyid: failed to unregister misc device!\n");\r
+\r
+       printk(KERN_INFO "verifyid: unloaded\n");\r
+}\r
+\r
+module_init(verifyid_init);\r
+module_exit(verifyid_exit);\r
+\r
+MODULE_LICENSE("GPL");\r
+\r
diff --git a/arch/arm/mach-rk29/verifyID.h b/arch/arm/mach-rk29/verifyID.h
new file mode 100644 (file)
index 0000000..253da5a
--- /dev/null
@@ -0,0 +1,14 @@
+/*\r
+ */\r
+\r
+#ifndef _LINUX_VERIFYID_H\r
+#define _LINUX_VERIFYID_H\r
+#include <mach/rk29_iomap.h>\r
+\r
+\r
+#define VERIFYID_GETID 0x29\r
+#define     write_XDATA32(address, value)   (*((unsigned long volatile*)(address)) = value)\r
+#define     read_XDATA32(address)           (*((unsigned long  volatile*)(address)))\r
+\r
+#endif /* _LINUX_VERIFYID_H */\r
+\r
index bc05e6842ea4600295909caf20e46a626d9f46a6..898dee3d6fbb960d112ed48142e7f6d0455554f4 100644 (file)
  * @author ChenHengming (2011-4-11)\r
  */\r
 typedef struct vpu_mem_session {\r
-    /* a list of memory region used posted by current process */\r
-    struct list_head list_used;\r
-    struct list_head list_post;\r
-    /* a linked list of data so we can access them for debugging */\r
-    struct list_head list_session;\r
+       /* a list of memory region used posted by current process */\r
+       struct list_head list_used;\r
+       struct list_head list_post;\r
+       /* a linked list of data so we can access them for debugging */\r
+       struct list_head list_session;\r
+       /* a linked list of memory pool on current session */\r
+       struct list_head list_pool;\r
        /* process id of teh mapping process */\r
        pid_t pid;\r
 } vdm_session;\r
 \r
+/**\r
+ * session memory pool info\r
+ */\r
+typedef struct vpu_mem_pool_info {\r
+       struct list_head session_link;      /* link to session use for search */\r
+       struct list_head list_used;         /* a linked list for used memory in the pool */\r
+       vdm_session *session;\r
+       int count_current;\r
+       int count_target;\r
+       int pfn;\r
+} vdm_pool;\r
+\r
+/**\r
+ * session memory pool config input\r
+ */\r
+typedef struct vpu_mem_pool_config {\r
+       int size;\r
+       unsigned int count;\r
+} vdm_pool_config;\r
+\r
 /**\r
  * global region info\r
  */\r
 typedef struct vpu_mem_region_info {\r
-    struct list_head index_list;        /* link to index list use for search */\r
-    int used;\r
-    int post;\r
-    int index;\r
-    int pfn;\r
+       struct list_head index_list;        /* link to index list use for search */\r
+       int used;\r
+       int post;\r
+       int index;\r
+       int pfn;\r
 } vdm_region;\r
 \r
 /**\r
@@ -76,13 +98,19 @@ typedef struct vpu_mem_region_info {
  * this struct should be modified with bitmap lock\r
  */\r
 typedef struct vpu_mem_link_info {\r
-    struct list_head session_link;      /* link to vpu_mem_session list */\r
-    struct list_head status_link;       /* link to vdm_info.status list use for search */\r
-    vdm_region *region;\r
-    int link_post;\r
-    int link_used;\r
-    int index;\r
-    int pfn;\r
+       struct list_head session_link;      /* link to vpu_mem_session list */\r
+       struct list_head status_link;       /* link to vdm_info.status list use for search */\r
+       struct list_head pool_link;         /* link to vpu_mem_session pool list for search */\r
+       vdm_region *region;\r
+       vdm_pool *pool;\r
+       union {\r
+               int post;\r
+               int used;\r
+               int count;\r
+       } ref;\r
+       int *ref_ptr;\r
+       int index;\r
+       int pfn;\r
 } vdm_link;\r
 \r
 /**\r
@@ -106,11 +134,11 @@ typedef struct vpu_mem_info {
        /*\r
         * vdm_session init only store the free region but use a vdm_session for convenience\r
         */\r
-    vdm_session status;\r
+       vdm_session status;\r
        struct list_head list_index;        /* sort by index */\r
-    struct list_head list_free;         /* free region list */\r
-    struct list_head list_session;      /* session list */\r
-    struct rw_semaphore rw_sem;\r
+       struct list_head list_free;         /* free region list */\r
+       struct list_head list_session;      /* session list */\r
+       struct rw_semaphore rw_sem;\r
 } vdm_info;\r
 \r
 static vdm_info vpu_mem;\r
@@ -133,47 +161,52 @@ static int vpu_mem_over = 0;
  */\r
 static void dump_status(void)\r
 {\r
-    vdm_link    *link, *tmp_link;\r
-    vdm_region  *region, *tmp_region;\r
-    vdm_session *session, *tmp_session;\r
-\r
-    printk("vpu mem status dump :\n\n");\r
-\r
-    // °´ index ´òÓ¡È«²¿ region\r
-    printk("region:\n");\r
-    list_for_each_entry_safe(region, tmp_region, &vdm_index, index_list) {\r
-        printk("        idx %6d pfn %6d used %3d post %3d\n",\r
-            region->index, region->pfn, region->used, region->post);\r
-    }\r
-    printk("free  :\n");\r
-    list_for_each_entry_safe(link, tmp_link, &vdm_free, status_link) {\r
-        printk("        idx %6d pfn %6d used %3d post %3d\n",\r
-            link->index, link->pfn, link->link_used, link->link_post);\r
-    }\r
-    printk("used  :\n");\r
-    list_for_each_entry_safe(link, tmp_link, &vdm_used, status_link) {\r
-        printk("        idx %6d pfn %6d used %3d post %3d\n",\r
-            link->index, link->pfn, link->link_used, link->link_post);\r
-    }\r
-    printk("post  :\n");\r
-    list_for_each_entry_safe(link, tmp_link, &vdm_post, status_link) {\r
-        printk("        idx %6d pfn %6d used %3d post %3d\n",\r
-            link->index, link->pfn, link->link_used, link->link_post);\r
-    }\r
+       vdm_link    *link, *tmp_link;\r
+       vdm_pool    *pool, *tmp_pool;\r
+       vdm_region  *region, *tmp_region;\r
+       vdm_session *session, *tmp_session;\r
+\r
+       printk("vpu mem status dump :\n\n");\r
+\r
+       // °´ index ´òÓ¡È«²¿ region\r
+       printk("region:\n");\r
+       list_for_each_entry_safe(region, tmp_region, &vdm_index, index_list) {\r
+               printk("        idx %6d pfn %6d used %3d post %3d\n",\r
+                       region->index, region->pfn, region->used, region->post);\r
+       }\r
+       printk("free  :\n");\r
+       list_for_each_entry_safe(link, tmp_link, &vdm_free, status_link) {\r
+               printk("        idx %6d pfn %6d ref %3d\n",\r
+                       link->index, link->pfn, link->ref.used);\r
+       }\r
+       printk("used  :\n");\r
+       list_for_each_entry_safe(link, tmp_link, &vdm_used, status_link) {\r
+               printk("        idx %6d pfn %6d used %3d\n",\r
+                       link->index, link->pfn, link->ref.used);\r
+       }\r
+       printk("post  :\n");\r
+       list_for_each_entry_safe(link, tmp_link, &vdm_post, status_link) {\r
+               printk("        idx %6d pfn %6d post %3d\n",\r
+                       link->index, link->pfn, link->ref.post);\r
+       }\r
 \r
-    // ´òÓ¡ vpu_mem_info ÖеÄÈ«²¿ session µÄ region Õ¼ÓÃÇé¿ö\r
-    list_for_each_entry_safe(session, tmp_session, &vdm_proc, list_session) {\r
-        printk("pid: %d\n", session->pid);\r
+       // ´òÓ¡ vpu_mem_info ÖеÄÈ«²¿ session µÄ region Õ¼ÓÃÇé¿ö\r
+       list_for_each_entry_safe(session, tmp_session, &vdm_proc, list_session) {\r
+               printk("pid: %d\n", session->pid);\r
 \r
-        list_for_each_entry_safe(link, tmp_link, &session->list_used, session_link) {\r
-            printk("used: idx %6d pfn %6d used %3d\n",\r
-                link->index, link->pfn, link->link_used);\r
-        }\r
-        list_for_each_entry_safe(link, tmp_link, &session->list_post, session_link) {\r
-            printk("post: idx %6d pfn %6d post %3d\n",\r
-                link->index, link->pfn, link->link_post);\r
-        }\r
-    }\r
+               list_for_each_entry_safe(pool, tmp_pool, &session->list_pool, session_link) {\r
+                       printk("pool: pfn %6d target %3d current %2d\n",\r
+                               pool->pfn, pool->count_current, pool->count_target);\r
+               }\r
+               list_for_each_entry_safe(link, tmp_link, &session->list_used, session_link) {\r
+                       printk("used: idx %6d pfn %6d used %3d\n",\r
+                               link->index, link->pfn, link->ref.used);\r
+               }\r
+               list_for_each_entry_safe(link, tmp_link, &session->list_post, session_link) {\r
+                       printk("post: idx %6d pfn %6d post %3d\n",\r
+                               link->index, link->pfn, link->ref.post);\r
+               }\r
+       }\r
 }\r
 \r
 /**\r
@@ -188,16 +221,16 @@ static void dump_status(void)
  */\r
 static vdm_link *find_used_link(vdm_session *session, int index)\r
 {\r
-    vdm_link *pos, *n;\r
+       vdm_link *pos, *n;\r
 \r
-    list_for_each_entry_safe(pos, n, &session->list_used, session_link) {\r
-        if (index == pos->index) {\r
-            DLOG("found index %d ptr %x\n", index, pos);\r
-            return pos;\r
-        }\r
-    }\r
+       list_for_each_entry_safe(pos, n, &session->list_used, session_link) {\r
+               if (index == pos->index) {\r
+                       DLOG("found index %d ptr %p\n", index, pos);\r
+                       return pos;\r
+               }\r
+       }\r
 \r
-    return NULL;\r
+       return NULL;\r
 }\r
 \r
 /**\r
@@ -211,15 +244,15 @@ static vdm_link *find_used_link(vdm_session *session, int index)
  */\r
 static vdm_link *find_post_link(int index)\r
 {\r
-    vdm_link *pos, *n;\r
+       vdm_link *pos, *n;\r
 \r
-    list_for_each_entry_safe(pos, n, &vdm_post, status_link) {\r
-        if (index == pos->index) {\r
-            return pos;\r
-        }\r
-    }\r
+       list_for_each_entry_safe(pos, n, &vdm_post, status_link) {\r
+               if (index == pos->index) {\r
+                       return pos;\r
+               }\r
+       }\r
 \r
-    return NULL;\r
+       return NULL;\r
 }\r
 \r
 /**\r
@@ -233,16 +266,61 @@ static vdm_link *find_post_link(int index)
  */\r
 static vdm_link *find_free_link(int index)\r
 {\r
-    vdm_link *pos, *n;\r
+       vdm_link *pos, *n;\r
 \r
-    list_for_each_entry_safe(pos, n, &vdm_free, status_link) {\r
-        if (index == pos->index) {\r
-            return pos;\r
-        }\r
-    }\r
+       list_for_each_entry_safe(pos, n, &vdm_free, status_link) {\r
+               if (index == pos->index) {\r
+                       return pos;\r
+               }\r
+       }\r
 \r
-    return NULL;\r
+       return NULL;\r
 }\r
+\r
+static vdm_pool *find_pool_by_pfn(vdm_session *session, unsigned int pfn)\r
+{\r
+       vdm_pool *pos, *n;\r
+\r
+       list_for_each_entry_safe(pos, n, &session->list_pool, session_link) {\r
+               if (pfn == pos->pfn) {\r
+                       return pos;\r
+               }\r
+       }\r
+\r
+       return NULL;\r
+}\r
+\r
+static void vpu_mem_pool_add_link(vdm_pool *pool, vdm_link *link)\r
+{\r
+       link->pool = pool;\r
+       list_add_tail(&link->pool_link, &pool->list_used);\r
+       pool->count_current++;\r
+}\r
+\r
+static void vpu_mem_pool_del_link(vdm_link *link)\r
+{\r
+       vdm_pool *pool = link->pool;\r
+       link->pool = NULL;\r
+       list_del_init(&link->pool_link);\r
+       pool->count_current--;\r
+}\r
+\r
+static void link_ref_inc(vdm_link *link)\r
+{\r
+       link->ref.count++;\r
+       if (link->ref_ptr) {\r
+               *link->ref_ptr += 1;\r
+       }\r
+}\r
+\r
+static void link_ref_dec(vdm_link *link)\r
+{\r
+       link->ref.count--;\r
+       if (link->ref_ptr) {\r
+               *link->ref_ptr -= 1;\r
+       }\r
+}\r
+\r
 /**\r
  * insert a region into the index list for search\r
  *\r
@@ -267,7 +345,7 @@ static int _insert_region_index(vdm_region *region)
 \r
     list_for_each_entry_safe(tmp, n, &vdm_index, index_list) {\r
         next = tmp->index;\r
-        DLOG("insert index %d pfn %d last %d next %d ptr %x\n", index, region->pfn, last, next, tmp);\r
+        DLOG("insert index %d pfn %d last %d next %d ptr %p\n", index, region->pfn, last, next, tmp);\r
         if ((last < index) && (index < next))  {\r
             DLOG("Done\n");\r
             list_add_tail(&region->index_list, &tmp->index_list);\r
@@ -304,14 +382,14 @@ static void _insert_link_status_free(vdm_link *link)
     list_for_each_entry_safe(tmp, n, &vdm_free, status_link) {\r
         next = tmp->index;\r
         if ((last < index) && (index < next))  {\r
-            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %x\n", index, link->pfn, last, next, tmp);\r
+            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %p\n", index, link->pfn, last, next, tmp);\r
             list_add_tail(&link->status_link, &tmp->status_link);\r
             return ;\r
         }\r
         last = next;\r
     }\r
     list_add_tail(&link->status_link, &tmp->status_link);\r
-    DLOG("list_add index %d pfn %d last %d ptr %x\n", index, link->pfn, last, tmp);\r
+    DLOG("list_add index %d pfn %d last %d ptr %p\n", index, link->pfn, last, tmp);\r
     return ;\r
 }\r
 \r
@@ -331,7 +409,7 @@ static void _insert_link_status_post(vdm_link *link)
     list_for_each_entry_safe(tmp, n, &vdm_post, status_link) {\r
         next = tmp->index;\r
         if ((last < index) && (index < next))  {\r
-            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %x\n", index, link->pfn, last, next, tmp);\r
+            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %p\n", index, link->pfn, last, next, tmp);\r
             list_add_tail(&link->status_link, &tmp->status_link);\r
             return ;\r
         }\r
@@ -339,7 +417,7 @@ static void _insert_link_status_post(vdm_link *link)
     }\r
 \r
     list_add_tail(&link->status_link, &tmp->status_link);\r
-    DLOG("list_add index %d pfn %d last %d ptr %x\n", index, link->pfn, last, tmp);\r
+    DLOG("list_add index %d pfn %d last %d ptr %p\n", index, link->pfn, last, tmp);\r
     return ;\r
 }\r
 \r
@@ -359,7 +437,7 @@ static void _insert_link_status_used(vdm_link *link)
     list_for_each_entry_safe(tmp, n, &vdm_used, status_link) {\r
         next = tmp->index;\r
         if ((last < index) && (index < next))  {\r
-            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %x\n", index, link->pfn, last, next, tmp);\r
+            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %p\n", index, link->pfn, last, next, tmp);\r
             list_add_tail(&link->status_link, &tmp->status_link);\r
             return ;\r
         }\r
@@ -367,7 +445,7 @@ static void _insert_link_status_used(vdm_link *link)
     }\r
 \r
     list_add_tail(&link->status_link, &tmp->status_link);\r
-    DLOG("list_add index %d pfn %d last %d ptr %x\n", index, link->pfn, last, tmp);\r
+    DLOG("list_add index %d pfn %d last %d ptr %p\n", index, link->pfn, last, tmp);\r
     return ;\r
 }\r
 \r
@@ -388,115 +466,130 @@ static void _insert_link_session_used(vdm_link *link, vdm_session *session)
         next = tmp->index;\r
         if ((last < index) && (index < next))  {\r
             list_add_tail(&link->session_link, &tmp->session_link);\r
-            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %x\n", index, link->pfn, last, next, tmp);\r
+            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %p\n", index, link->pfn, last, next, tmp);\r
             return ;\r
         }\r
         last = next;\r
     }\r
 \r
     list_add_tail(&link->session_link, &tmp->session_link);\r
-    DLOG("list_add index %d pfn %d last %d ptr %x\n", index, link->pfn, last, tmp);\r
+    DLOG("list_add index %d pfn %d last %d ptr %p\n", index, link->pfn, last, tmp);\r
     return ;\r
 }\r
 \r
 static void _insert_link_session_post(vdm_link *link, vdm_session *session)\r
 {\r
-    int index = link->index;\r
-    int last = -1;\r
-    int next;\r
-    vdm_link *tmp, *n;\r
-\r
-    if (list_empty(&session->list_post)) {\r
-        DLOG("session post list is empty, list_add_tail first region\n");\r
-        list_add_tail(&link->session_link, &session->list_post);\r
-        return ;\r
-    }\r
+       int index = link->index;\r
+       int last = -1;\r
+       int next;\r
+       vdm_link *tmp, *n;\r
+\r
+       if (list_empty(&session->list_post)) {\r
+               DLOG("session post list is empty, list_add_tail first region\n");\r
+               list_add_tail(&link->session_link, &session->list_post);\r
+               return ;\r
+       }\r
 \r
-    list_for_each_entry_safe(tmp, n, &session->list_post, session_link) {\r
-        next = tmp->index;\r
-        if ((last < index) && (index < next))  {\r
-            list_add_tail(&link->session_link, &tmp->session_link);\r
-            DLOG("list_add_tail index %d pfn %d last %d next %d ptr %x\n", index, link->pfn, last, next, tmp);\r
-            return ;\r
-        }\r
-        last = next;\r
-    }\r
+       list_for_each_entry_safe(tmp, n, &session->list_post, session_link) {\r
+               next = tmp->index;\r
+               if ((last < index) && (index < next))  {\r
+                       list_add_tail(&link->session_link, &tmp->session_link);\r
+                       DLOG("list_add_tail index %d pfn %d last %d next %d ptr %p\n", index, link->pfn, last, next, tmp);\r
+                       return ;\r
+               }\r
+               last = next;\r
+       }\r
 \r
-    list_add_tail(&link->session_link, &tmp->session_link);\r
-    DLOG("list_add index %d pfn %d last %d ptr %x\n", index, link->pfn, last, tmp);\r
-    return ;\r
+       list_add_tail(&link->session_link, &tmp->session_link);\r
+       DLOG("list_add index %d pfn %d last %d ptr %p\n", index, link->pfn, last, tmp);\r
+       return ;\r
 }\r
 \r
 static void _remove_free_region(vdm_region *region)\r
 {\r
-    list_del_init(&region->index_list);\r
-    kfree(region);\r
+       list_del_init(&region->index_list);\r
+       kfree(region);\r
 }\r
 \r
 static void _remove_free_link(vdm_link *link)\r
 {\r
-    list_del_init(&link->session_link);\r
-    list_del_init(&link->status_link);\r
-    kfree(link);\r
+       list_del_init(&link->session_link);\r
+       list_del_init(&link->status_link);\r
+       kfree(link);\r
 }\r
 \r
 static void _merge_two_region(vdm_region *dst, vdm_region *src)\r
 {\r
-    vdm_link *dst_link = find_free_link(dst->index);\r
-    vdm_link *src_link = find_free_link(src->index);\r
-    dst->pfn        += src->pfn;\r
-    dst_link->pfn   += src_link->pfn;\r
-    _remove_free_link(src_link);\r
-    _remove_free_region(src);\r
+       vdm_link *dst_link = find_free_link(dst->index);\r
+       vdm_link *src_link = find_free_link(src->index);\r
+       dst->pfn        += src->pfn;\r
+       dst_link->pfn   += src_link->pfn;\r
+       _remove_free_link(src_link);\r
+       _remove_free_region(src);\r
 }\r
 \r
 static void merge_free_region_and_link(vdm_region *region)\r
 {\r
-    if (region->used || region->post) {\r
-        printk(KERN_ALERT "try to merge unfree region!\n");\r
-        return ;\r
-    } else {\r
-        vdm_region *neighbor;\r
-        struct list_head *tmp = region->index_list.next;\r
-        if (tmp != &vdm_index) {\r
-            neighbor = (vdm_region *)list_entry(tmp, vdm_region, index_list);\r
-            if (is_free_region(neighbor)) {\r
-                DLOG("merge next\n");\r
-                _merge_two_region(region, neighbor);\r
-            }\r
-        }\r
-        tmp = region->index_list.prev;\r
-        if (tmp != &vdm_index) {\r
-            neighbor = (vdm_region *)list_entry(tmp, vdm_region, index_list);\r
-            if (is_free_region(neighbor)) {\r
-                DLOG("merge prev\n");\r
-                _merge_two_region(neighbor, region);\r
-            }\r
-        }\r
-    }\r
+       if (region->used || region->post) {\r
+               printk(KERN_ALERT "try to merge unfree region!\n");\r
+               return ;\r
+       } else {\r
+               vdm_region *neighbor;\r
+               struct list_head *tmp = region->index_list.next;\r
+               if (tmp != &vdm_index) {\r
+                       neighbor = (vdm_region *)list_entry(tmp, vdm_region, index_list);\r
+                       if (is_free_region(neighbor)) {\r
+                               DLOG("merge next\n");\r
+                               _merge_two_region(region, neighbor);\r
+                       }\r
+               }\r
+               tmp = region->index_list.prev;\r
+               if (tmp != &vdm_index) {\r
+                       neighbor = (vdm_region *)list_entry(tmp, vdm_region, index_list);\r
+                       if (is_free_region(neighbor)) {\r
+                               DLOG("merge prev\n");\r
+                               _merge_two_region(neighbor, region);\r
+                       }\r
+               }\r
+       }\r
 }\r
 \r
 static void put_free_link(vdm_link *link)\r
 {\r
-    list_del_init(&link->session_link);\r
-    list_del_init(&link->status_link);\r
-    _insert_link_status_free(link);\r
+       if (link->pool) {\r
+               vpu_mem_pool_del_link(link);\r
+       }\r
+       list_del_init(&link->session_link);\r
+       list_del_init(&link->status_link);\r
+       _insert_link_status_free(link);\r
 }\r
 \r
 static void put_used_link(vdm_link *link, vdm_session *session)\r
 {\r
-    list_del_init(&link->session_link);\r
-    list_del_init(&link->status_link);\r
-    _insert_link_status_used(link);\r
-    _insert_link_session_used(link, session);\r
+       list_del_init(&link->session_link);\r
+       list_del_init(&link->status_link);\r
+       _insert_link_status_used(link);\r
+       _insert_link_session_used(link, session);\r
+       if (NULL == link->pool) {\r
+               vdm_pool *pool = find_pool_by_pfn(session, link->pfn);\r
+               if (pool) {\r
+                       vpu_mem_pool_add_link(pool, link);\r
+               }\r
+       }\r
 }\r
 \r
 static void put_post_link(vdm_link *link, vdm_session *session)\r
 {\r
-    list_del_init(&link->session_link);\r
-    list_del_init(&link->status_link);\r
-    _insert_link_status_post(link);\r
-    _insert_link_session_post(link, session);\r
+       list_del_init(&link->session_link);\r
+       list_del_init(&link->status_link);\r
+       _insert_link_status_post(link);\r
+       _insert_link_session_post(link, session);\r
+       if (NULL == link->pool) {\r
+               vdm_pool *pool = find_pool_by_pfn(session, link->pfn);\r
+               if (pool) {\r
+                       vpu_mem_pool_add_link(pool, link);\r
+               }\r
+       }\r
 }\r
 \r
 /**\r
@@ -512,36 +605,38 @@ static void put_post_link(vdm_link *link, vdm_session *session)
  */\r
 static vdm_link *new_link_by_index(int index, int pfn)\r
 {\r
-    vdm_region *region = (vdm_region *)kmalloc(sizeof(vdm_region), GFP_KERNEL);\r
-    vdm_link   *link   = (vdm_link   *)kmalloc(sizeof(vdm_link  ), GFP_KERNEL);\r
+       vdm_region *region = (vdm_region *)kmalloc(sizeof(vdm_region), GFP_KERNEL);\r
+       vdm_link   *link   = (vdm_link   *)kmalloc(sizeof(vdm_link  ), GFP_KERNEL);\r
 \r
-    if ((NULL == region) || (NULL == link)) {\r
-        printk(KERN_ALERT "can not kmalloc vdm_region and vdm_link in %s", __FUNCTION__);\r
-        if (region) {\r
-            kfree(region);\r
-        }\r
-        if (link) {\r
-            kfree(link);\r
-        }\r
-        return NULL;\r
-    }\r
+       if ((NULL == region) || (NULL == link)) {\r
+               printk(KERN_ALERT "can not kmalloc vdm_region and vdm_link in %s", __FUNCTION__);\r
+               if (region) {\r
+                       kfree(region);\r
+               }\r
+               if (link) {\r
+                       kfree(link);\r
+               }\r
+               return NULL;\r
+       }\r
 \r
-    region->post    = 0;\r
-    region->used    = 0;\r
-    region->index   = index;\r
-    region->pfn     = pfn;\r
+       region->post    = 0;\r
+       region->used    = 0;\r
+       region->index   = index;\r
+       region->pfn     = pfn;\r
 \r
-    INIT_LIST_HEAD(&region->index_list);\r
+       INIT_LIST_HEAD(&region->index_list);\r
 \r
-    link->link_post = 0;\r
-    link->link_used = 0;\r
-    link->region    = region;\r
-    link->index     = region->index;\r
-    link->pfn       = region->pfn;\r
-    INIT_LIST_HEAD(&link->session_link);\r
-    INIT_LIST_HEAD(&link->status_link);\r
+       link->ref.count = 0;\r
+       link->ref_ptr   = NULL;\r
+       link->region    = region;\r
+       link->index     = region->index;\r
+       link->pfn       = region->pfn;\r
+       INIT_LIST_HEAD(&link->session_link);\r
+       INIT_LIST_HEAD(&link->status_link);\r
+       INIT_LIST_HEAD(&link->pool_link);\r
+       link->pool      = NULL;\r
 \r
-    return link;\r
+       return link;\r
 }\r
 \r
 /**\r
@@ -556,21 +651,23 @@ static vdm_link *new_link_by_index(int index, int pfn)
  */\r
 static vdm_link *new_link_by_region(vdm_region *region)\r
 {\r
-    vdm_link *link = (vdm_link *)kmalloc(sizeof(vdm_link), GFP_KERNEL);\r
-    if (NULL == link) {\r
-        printk(KERN_ALERT "can not kmalloc vdm_region and vdm_link in %s", __FUNCTION__);\r
-        return NULL;\r
-    }\r
-\r
-    link->link_post = 0;\r
-    link->link_used = 0;\r
-    link->region    = region;\r
-    link->index     = region->index;\r
-    link->pfn       = region->pfn;\r
-    INIT_LIST_HEAD(&link->session_link);\r
-    INIT_LIST_HEAD(&link->status_link);\r
+       vdm_link *link = (vdm_link *)kmalloc(sizeof(vdm_link), GFP_KERNEL);\r
+       if (NULL == link) {\r
+               printk(KERN_ALERT "can not kmalloc vdm_region and vdm_link in %s", __FUNCTION__);\r
+               return NULL;\r
+       }\r
 \r
-    return link;\r
+       link->ref.count = 0;\r
+       link->ref_ptr   = NULL;\r
+       link->region    = region;\r
+       link->index     = region->index;\r
+       link->pfn       = region->pfn;\r
+       INIT_LIST_HEAD(&link->session_link);\r
+       INIT_LIST_HEAD(&link->status_link);\r
+       INIT_LIST_HEAD(&link->pool_link);\r
+       link->pool      = NULL;\r
+\r
+       return link;\r
 }\r
 \r
 /**\r
@@ -582,9 +679,17 @@ static vdm_link *new_link_by_region(vdm_region *region)
  */\r
 static void link_del(vdm_link *link)\r
 {\r
-    list_del_init(&link->session_link);\r
-    list_del_init(&link->status_link);\r
-    kfree(link);\r
+       if (link->pool) {\r
+               vpu_mem_pool_del_link(link);\r
+       }\r
+       list_del_init(&link->session_link);\r
+       list_del_init(&link->status_link);\r
+       if (is_free_region(link->region) && NULL == find_free_link(link->index)) {\r
+               put_free_link(link);\r
+               merge_free_region_and_link(link->region);\r
+       } else {\r
+               kfree(link);\r
+       }\r
 }\r
 \r
 /**\r
@@ -601,56 +706,46 @@ static void link_del(vdm_link *link)
  */\r
 static vdm_link *get_used_link_from_free_link(vdm_link *link, vdm_session *session, int pfn)\r
 {\r
-    if (pfn > link->pfn) {\r
-        return NULL;\r
-    }\r
-    if (pfn == link->pfn) {\r
-        DLOG("pfn == link->pfn %d\n", pfn);\r
-        link->link_used     = 1;\r
-        link->region->used  = 1;\r
-        put_used_link(link, session);\r
-        return link;\r
-    } else {\r
-        vdm_link *used = new_link_by_index(link->index, pfn);\r
-        if (NULL == used)\r
-            return NULL;\r
-\r
-        link->index         += pfn;\r
-        link->pfn           -= pfn;\r
-        link->region->index += pfn;\r
-        link->region->pfn   -= pfn;\r
-        used->link_used      = 1;\r
-        used->region->used   = 1;\r
-\r
-        DLOG("used: index %d pfn %d ptr %x\n", used->index, used->pfn, used->region);\r
-        if (_insert_region_index(used->region)) {\r
-            printk(KERN_ALERT "fail to insert allocated region index %d pfn %d\n", used->index, used->pfn);\r
-            link_del(used);\r
-            link->index         -= pfn;\r
-            link->pfn           += pfn;\r
-            link->region->index -= pfn;\r
-            link->region->pfn   += pfn;\r
-            _remove_free_region(used->region);\r
-            _remove_free_link(used);\r
-            return NULL;\r
-        }\r
-        put_used_link(used, session);\r
-        return used;\r
-    }\r
+       if (pfn > link->pfn) {\r
+               return NULL;\r
+       }\r
+       if (pfn == link->pfn) {\r
+               DLOG("pfn == link->pfn %d\n", pfn);\r
+               link->ref.used      = 1;\r
+               link->region->used  = 1;\r
+               link->ref_ptr       = &link->region->used;\r
+               put_used_link(link, session);\r
+               return link;\r
+       } else {\r
+               vdm_link *used = new_link_by_index(link->index, pfn);\r
+               if (NULL == used)\r
+                       return NULL;\r
+\r
+               link->index         += pfn;\r
+               link->pfn           -= pfn;\r
+               link->region->index += pfn;\r
+               link->region->pfn   -= pfn;\r
+               used->ref.used      = 1;\r
+               used->region->used  = 1;\r
+               used->ref_ptr       = &used->region->used;\r
+\r
+               DLOG("used: index %d pfn %d ptr %p\n", used->index, used->pfn, used->region);\r
+               if (_insert_region_index(used->region)) {\r
+                       printk(KERN_ALERT "fail to insert allocated region index %d pfn %d\n", used->index, used->pfn);\r
+                       link_del(used);\r
+                       link->index         -= pfn;\r
+                       link->pfn           += pfn;\r
+                       link->region->index -= pfn;\r
+                       link->region->pfn   += pfn;\r
+                       _remove_free_region(used->region);\r
+                       _remove_free_link(used);\r
+                       return NULL;\r
+               }\r
+               put_used_link(used, session);\r
+               return used;\r
+       }\r
 }\r
 \r
-static int vpu_mem_release(struct inode *, struct file *);\r
-static int vpu_mem_mmap(struct file *, struct vm_area_struct *);\r
-static int vpu_mem_open(struct inode *, struct file *);\r
-static long vpu_mem_ioctl(struct file *, unsigned int, unsigned long);\r
-\r
-struct file_operations vpu_mem_fops = {\r
-       .open = vpu_mem_open,\r
-    .mmap = vpu_mem_mmap,\r
-    .unlocked_ioctl = vpu_mem_ioctl,\r
-       .release = vpu_mem_release,\r
-};\r
-\r
 int is_vpu_mem_file(struct file *file)\r
 {\r
        if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode))\r
@@ -663,145 +758,221 @@ int is_vpu_mem_file(struct file *file)
 \r
 static long vpu_mem_allocate(struct file *file, unsigned int len)\r
 {\r
-    vdm_link *free, *n;\r
+       vdm_link *free, *n;\r
        unsigned int pfn = (len + VPU_MEM_MIN_ALLOC - 1)/VPU_MEM_MIN_ALLOC;\r
-    vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
 \r
-    if (!is_vpu_mem_file(file)) {\r
-        printk(KERN_INFO "allocate vpu_mem session from invalid file\n");\r
-        return -ENODEV;\r
-    }\r
+       if (!is_vpu_mem_file(file)) {\r
+               printk(KERN_INFO "allocate vpu_mem session from invalid file\n");\r
+               return -ENODEV;\r
+       }\r
 \r
-    list_for_each_entry_safe(free, n, &vdm_free, status_link) {\r
-        /* find match free buffer use it first */\r
-        vdm_link *used = get_used_link_from_free_link(free, session, pfn);\r
-        DLOG("search free buffer at index %d pfn %d for len %d\n", free->index, free->pfn, pfn);\r
-        if (NULL == used) {\r
-            continue;\r
-        } else {\r
-            DLOG("found buffer at index %d pfn %d for ptr %x\n", used->index, used->pfn, used);\r
-            return used->index;\r
-        }\r
-    }\r
+       list_for_each_entry_safe(free, n, &vdm_free, status_link) {\r
+               /* find match free buffer use it first */\r
+               vdm_link *used = get_used_link_from_free_link(free, session, pfn);\r
+               DLOG("search free buffer at index %d pfn %d for len %d\n", free->index, free->pfn, pfn);\r
+               if (NULL == used) {\r
+                       continue;\r
+               } else {\r
+                       DLOG("found buffer at index %d pfn %d for ptr %p\n", used->index, used->pfn, used);\r
+                       return used->index;\r
+               }\r
+       }\r
 \r
        if (!vpu_mem_over) {\r
-        printk(KERN_INFO "vpu_mem: no space left to allocate!\n");\r
-        dump_status();\r
-        vpu_mem_over = 1;\r
-    }\r
-    return -1;\r
+               printk(KERN_INFO "vpu_mem: no space left to allocate!\n");\r
+               dump_status();\r
+               vpu_mem_over = 1;\r
+       }\r
+       return -1;\r
 }\r
 \r
 static int vpu_mem_free(struct file *file, int index)\r
 {\r
-    vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
 \r
-    if (!is_vpu_mem_file(file)) {\r
-        printk(KERN_INFO "free vpu_mem session from invalid file.\n");\r
-        return -ENODEV;\r
-    }\r
+       if (!is_vpu_mem_file(file)) {\r
+               printk(KERN_INFO "free vpu_mem session from invalid file.\n");\r
+               return -ENODEV;\r
+       }\r
 \r
        DLOG("searching for index %d\n", index);\r
-    {\r
-        vdm_link *link = find_used_link(session, index);\r
-        if (NULL == link) {\r
-            DLOG("no link of index %d searched\n", index);\r
-            return -1;\r
-        }\r
-        link->link_used--;\r
-        link->region->used--;\r
-        if (0 == link->link_used) {\r
-            if (is_free_region(link->region)) {\r
-                put_free_link(link);\r
-                merge_free_region_and_link(link->region);\r
-            } else {\r
-                link_del(link);\r
-            }\r
-        }\r
+       {\r
+               vdm_link *link = find_used_link(session, index);\r
+               if (NULL == link) {\r
+                       DLOG("no link of index %d searched\n", index);\r
+                       return -1;\r
+               }\r
+               link_ref_dec(link);\r
+               if (0 == link->ref.used) {\r
+                       link_del(link);\r
+               }\r
        }\r
-    return 0;\r
+       return 0;\r
 }\r
 \r
 static int vpu_mem_duplicate(struct file *file, int index)\r
 {\r
-    vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
        /* caller should hold the write lock on vpu_mem_sem! */\r
-    if (!is_vpu_mem_file(file)) {\r
-        printk(KERN_INFO "duplicate vpu_mem session from invalid file.\n");\r
-        return -ENODEV;\r
-    }\r
+       if (!is_vpu_mem_file(file)) {\r
+               printk(KERN_INFO "duplicate vpu_mem session from invalid file.\n");\r
+               return -ENODEV;\r
+       }\r
 \r
        DLOG("duplicate index %d\n", index);\r
-    {\r
-        vdm_link *post = find_post_link(index);\r
-        if (NULL == post) {\r
-            vdm_link *used = find_used_link(session, index);\r
-            if (NULL == used) {\r
-                printk(KERN_ERR "try to duplicate unknown index %d\n", index);\r
-                dump_status();\r
-                return -1;\r
-            }\r
-            post = new_link_by_region(used->region);\r
-            post->link_post = 1;\r
-            post->region->post++;\r
-            put_post_link(post, session);\r
-        } else {\r
-            DLOG("duplicate posted index %d\n", index);\r
-            post->link_post++;\r
-            post->region->post++;\r
-        }\r
-    }\r
+       {\r
+               vdm_link *post = find_post_link(index);\r
+               if (NULL == post) {\r
+                       vdm_link *used = find_used_link(session, index);\r
+                       if (NULL == used) {\r
+                               printk(KERN_ERR "try to duplicate unknown index %d\n", index);\r
+                               dump_status();\r
+                               return -1;\r
+                       }\r
+                       post = new_link_by_region(used->region);\r
+                       post->ref_ptr  = &post->region->post;\r
+                       link_ref_inc(post);\r
+                       put_post_link(post, session);\r
+               } else {\r
+                       DLOG("duplicate posted index %d\n", index);\r
+                       link_ref_inc(post);\r
+               }\r
+       }\r
 \r
        return 0;\r
 }\r
 \r
 static int vpu_mem_link(struct file *file, int index)\r
 {\r
-    vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
 \r
        if (!is_vpu_mem_file(file)) {\r
-        printk(KERN_INFO "link vpu_mem session from invalid file.\n");\r
-        return -ENODEV;\r
+               printk(KERN_INFO "link vpu_mem session from invalid file.\n");\r
+               return -ENODEV;\r
        }\r
 \r
-    DLOG("link index %d\n", index);\r
-    {\r
-        vdm_link *post = find_post_link(index);\r
-        if (NULL == post) {\r
-            printk(KERN_ERR "try to link unknown index %d\n", index);\r
-            dump_status();\r
-            return -1;\r
-        } else {\r
-            vdm_link *used = find_used_link(session, index);\r
-            post->link_post--;\r
-            post->region->post--;\r
-            if (0 == post->link_post) {\r
-                if (NULL == used) {\r
-                    post->link_used++;\r
-                    post->region->used++;\r
-                    put_used_link(post, session);\r
-                } else {\r
-                    used->link_used++;\r
-                    used->region->used++;\r
-                    link_del(post);\r
-                }\r
-            } else {\r
-                if (NULL == used) {\r
-                    used = new_link_by_region(post->region);\r
-                    used->link_used++;\r
-                    used->region->used++;\r
-                    put_used_link(used, session);\r
-                } else {\r
-                    used->link_used++;\r
-                    used->region->used++;\r
-                }\r
-            }\r
-        }\r
-    }\r
+       DLOG("link index %d\n", index);\r
+       {\r
+               vdm_link *post = find_post_link(index);\r
+               if (NULL == post) {\r
+                       printk(KERN_ERR "try to link unknown index %d\n", index);\r
+                       dump_status();\r
+                       return -1;\r
+               } else {\r
+                       vdm_link *used = find_used_link(session, index);\r
+                       link_ref_dec(post);\r
+\r
+                       if (used) {\r
+                               if (0 == post->ref.post) {\r
+                                       link_del(post);\r
+                                       post = NULL;\r
+                               }\r
+                       } else {\r
+                               if (post->ref.post) {\r
+                                       used = new_link_by_region(post->region);\r
+                               } else {\r
+                                       used = post;\r
+                                       post = NULL;\r
+                               }\r
+                               used->ref_ptr = &used->region->used;\r
+                               put_used_link(used, session);\r
+                       }\r
+                       link_ref_inc(used);\r
+               }\r
+       }\r
 \r
        return 0;\r
 }\r
 \r
+static int vpu_mem_pool_add(vdm_session *session, unsigned int pfn, unsigned int count)\r
+{\r
+       vdm_link *link, *n;\r
+       vdm_pool *pool = kmalloc(sizeof(vdm_pool), GFP_KERNEL);\r
+       DLOG("vpu_mem_pool_add %p pfn %d count %d\n", pool, pfn, count);\r
+       if (NULL == pool) {\r
+               printk(KERN_ALERT "vpu_mem: unable to allocate memory for vpu_mem pool.");\r
+               return -1;\r
+       }\r
+       INIT_LIST_HEAD(&pool->session_link);\r
+       INIT_LIST_HEAD(&pool->list_used);\r
+       pool->session = session;\r
+       pool->pfn = pfn;\r
+       pool->count_target = count;\r
+       pool->count_current = 0;\r
+\r
+       list_for_each_entry_safe(link, n, &session->list_used, session_link) {\r
+               if (pfn == link->pfn && NULL == link->pool) {\r
+                       vpu_mem_pool_add_link(pool, link);\r
+               }\r
+       }\r
+\r
+       list_add_tail(&pool->session_link, &session->list_pool);\r
+\r
+       return 0;\r
+}\r
+\r
+static void vpu_mem_pool_del(vdm_pool *pool)\r
+{\r
+       vdm_link *link, *n;\r
+       DLOG("vpu_mem_pool_del %p\n", pool);\r
+       list_for_each_entry_safe(link, n, &pool->list_used, pool_link) {\r
+               vpu_mem_pool_del_link(link);\r
+       }\r
+       if (pool->count_current) {\r
+               printk(KERN_ALERT "vpu_mem pool deleted by still %d link left.\n", pool->count_current);\r
+       }\r
+       list_del_init(&pool->session_link);\r
+       pool->session = NULL;\r
+       kfree(pool);\r
+       return ;\r
+}\r
+\r
+static int vpu_mem_pool_set(struct file *file, unsigned int pfn, unsigned int count)\r
+{\r
+       int ret = 0;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_pool *pool = find_pool_by_pfn(session, pfn);\r
+       if (NULL == pool) {\r
+               // no pool build pool first\r
+               ret = vpu_mem_pool_add(session, pfn, count);\r
+       } else {\r
+               pool->count_target += count;\r
+       }\r
+       return ret;\r
+}\r
+\r
+static int vpu_mem_pool_unset(struct file *file, unsigned int pfn, unsigned int count)\r
+{\r
+       int ret = 0;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_pool *pool = find_pool_by_pfn(session, pfn);\r
+       if (pool) {\r
+               pool->count_target -= count;\r
+               if (pool->count_target <= 0) {\r
+                       if (pool->count_target) {\r
+                               printk(KERN_ALERT "vpu_mem pool unpaired set and unset with %d differ.", pool->count_target);\r
+                       }\r
+                       vpu_mem_pool_del(pool);\r
+               }\r
+       }\r
+       return ret;\r
+}\r
+\r
+static int vpu_mem_pool_check(struct file *file, unsigned int pfn)\r
+{\r
+       int ret = 0;\r
+       vdm_session *session = (vdm_session *)file->private_data;\r
+       vdm_pool *pool = find_pool_by_pfn(session, pfn);\r
+       if (pool) {\r
+               if (pool->count_current >= pool->count_target) {\r
+                       ret = 1;\r
+               }\r
+               DLOG("vpu_mem_pool_check pfn %u current %d target %d ret %d\n", pfn, pool->count_current, pool->count_target, ret);\r
+       }\r
+       return ret;\r
+}\r
+\r
 void vpu_mem_cache_opt(struct file *file, long index, unsigned int cmd)\r
 {\r
        vdm_session *session = (vdm_session *)file->private_data;\r
@@ -815,32 +986,32 @@ void vpu_mem_cache_opt(struct file *file, long index, unsigned int cmd)
                return;\r
 \r
        down_read(&vdm_rwsem);\r
-    do {\r
-        vdm_link *link = find_used_link(session, index);\r
-        if (NULL == link) {\r
-            pr_err("vpu_mem_cache_opt on non-exsist index %ld\n", index);\r
-            break;\r
-        }\r
-        start = vpu_mem.vbase + index * VPU_MEM_MIN_ALLOC;\r
-        end   = start + link->pfn * VPU_MEM_MIN_ALLOC;;\r
-        switch (cmd) {\r
-        case VPU_MEM_CACHE_FLUSH : {\r
-            dmac_flush_range(start, end);\r
-            break;\r
-        }\r
-        case VPU_MEM_CACHE_CLEAN : {\r
-            dmac_clean_range(start, end);\r
-            break;\r
-        }\r
-        case VPU_MEM_CACHE_INVALID : {\r
-            dmac_inv_range(start, end);\r
-            break;\r
-        }\r
-        default :\r
-            break;\r
-        }\r
-    } while (0);\r
-    up_read(&vdm_rwsem);\r
+       do {\r
+               vdm_link *link = find_used_link(session, index);\r
+               if (NULL == link) {\r
+                       pr_err("vpu_mem_cache_opt on non-exsist index %ld\n", index);\r
+                       break;\r
+               }\r
+               start = vpu_mem.vbase + index * VPU_MEM_MIN_ALLOC;\r
+               end   = start + link->pfn * VPU_MEM_MIN_ALLOC;;\r
+               switch (cmd) {\r
+               case VPU_MEM_CACHE_FLUSH : {\r
+                       dmac_flush_range(start, end);\r
+                       break;\r
+               }\r
+               case VPU_MEM_CACHE_CLEAN : {\r
+                       dmac_clean_range(start, end);\r
+                       break;\r
+               }\r
+               case VPU_MEM_CACHE_INVALID : {\r
+                       dmac_inv_range(start, end);\r
+                       break;\r
+               }\r
+               default :\r
+               break;\r
+               }\r
+       } while (0);\r
+       up_read(&vdm_rwsem);\r
 }\r
 \r
 static pgprot_t vpu_mem_phys_mem_access_prot(struct file *file, pgprot_t vma_prot)\r
@@ -872,34 +1043,35 @@ static int vpu_mem_map_pfn_range(struct vm_area_struct *vma, unsigned long len)
 \r
 static int vpu_mem_open(struct inode *inode, struct file *file)\r
 {\r
-    vdm_session *session;\r
-    int ret = 0;\r
-\r
-    DLOG("current %u file %p(%d)\n", current->pid, file, (int)file_count(file));\r
-    /* setup file->private_data to indicate its unmapped */\r
-    /*  you can only open a vpu_mem device one time */\r
-    if (file->private_data != NULL && file->private_data != &vpu_mem.dev)\r
-            return -1;\r
-    session = kmalloc(sizeof(vdm_session), GFP_KERNEL);\r
-    if (!session) {\r
-        printk(KERN_ALERT "vpu_mem: unable to allocate memory for vpu_mem metadata.");\r
-        return -1;\r
-    }\r
-    session->pid = current->pid;\r
-    INIT_LIST_HEAD(&session->list_post);\r
-    INIT_LIST_HEAD(&session->list_used);\r
+       vdm_session *session;\r
+       int ret = 0;\r
 \r
-    file->private_data = session;\r
+       DLOG("current %u file %p(%d)\n", current->pid, file, (int)file_count(file));\r
+       /* setup file->private_data to indicate its unmapped */\r
+       /*  you can only open a vpu_mem device one time */\r
+       if (file->private_data != NULL && file->private_data != &vpu_mem.dev)\r
+               return -1;\r
+       session = kmalloc(sizeof(vdm_session), GFP_KERNEL);\r
+       if (!session) {\r
+               printk(KERN_ALERT "vpu_mem: unable to allocate memory for vpu_mem metadata.");\r
+               return -1;\r
+       }\r
+       session->pid = current->pid;\r
+       INIT_LIST_HEAD(&session->list_post);\r
+       INIT_LIST_HEAD(&session->list_used);\r
+       INIT_LIST_HEAD(&session->list_pool);\r
 \r
-    down_write(&vdm_rwsem);\r
-    list_add_tail(&session->list_session, &vdm_proc);\r
-    up_write(&vdm_rwsem);\r
-    return ret;\r
+       file->private_data = session;\r
+\r
+       down_write(&vdm_rwsem);\r
+       list_add_tail(&session->list_session, &vdm_proc);\r
+       up_write(&vdm_rwsem);\r
+       return ret;\r
 }\r
 \r
 static int vpu_mem_mmap(struct file *file, struct vm_area_struct *vma)\r
 {\r
-    vdm_session *session;\r
+       vdm_session *session;\r
        unsigned long vma_size =  vma->vm_end - vma->vm_start;\r
        int ret = 0;\r
 \r
@@ -911,7 +1083,7 @@ static int vpu_mem_mmap(struct file *file, struct vm_area_struct *vma)
 \r
        session = (vdm_session *)file->private_data;\r
 \r
-    /* assert: vma_size must be the total size of the vpu_mem */\r
+       /* assert: vma_size must be the total size of the vpu_mem */\r
        if (vpu_mem.size != vma_size) {\r
                printk(KERN_WARNING "vpu_mem: mmap size [%lu] does not match"\r
                       "size of backing region [%lu].\n", vma_size, vpu_mem.size);\r
@@ -938,128 +1110,150 @@ static int vpu_mem_release(struct inode *inode, struct file *file)
 {\r
        vdm_session *session = (vdm_session *)file->private_data;\r
 \r
-    down_write(&vdm_rwsem);\r
-    {\r
-        vdm_link *link, *tmp_link;\r
-        //unsigned long flags = current->flags;\r
-        //printk("current->flags: %lx\n", flags);\r
-        list_del(&session->list_session);\r
-        file->private_data = NULL;\r
-\r
-        list_for_each_entry_safe(link, tmp_link, &session->list_post, session_link) {\r
-            do {\r
-                link->link_post--;\r
-                link->region->post--;\r
-            } while (link->link_post);\r
-            if (find_free_link(link->index)) {\r
-                link_del(link);\r
-            } else {\r
-                put_free_link(link);\r
-            }\r
-            if (is_free_region(link->region)) {\r
-                merge_free_region_and_link(link->region);\r
-            }\r
-        }\r
-        list_for_each_entry_safe(link, tmp_link, &session->list_used, session_link) {\r
-            do {\r
-                link->link_used--;\r
-                link->region->used--;\r
-            } while (link->link_used);\r
-            if (find_free_link(link->index)) {\r
-                link_del(link);\r
-            } else {\r
-                put_free_link(link);\r
-            }\r
-            if (is_free_region(link->region)) {\r
-                merge_free_region_and_link(link->region);\r
-            }\r
-        }\r
-    }\r
-    up_write(&vdm_rwsem);\r
-    kfree(session);\r
+       down_write(&vdm_rwsem);\r
+       {\r
+               vdm_link *link, *tmp_link;\r
+               vdm_pool *pool, *tmp_pool;\r
+               //unsigned long flags = current->flags;\r
+               //printk("current->flags: %lx\n", flags);\r
+               list_del(&session->list_session);\r
+               file->private_data = NULL;\r
+\r
+               list_for_each_entry_safe(pool, tmp_pool, &session->list_pool, session_link) {\r
+                       vpu_mem_pool_del(pool);\r
+               }\r
 \r
-    return 0;\r
+               list_for_each_entry_safe(link, tmp_link, &session->list_post, session_link) {\r
+                       do {\r
+                               link_ref_dec(link);\r
+                       } while (link->ref.post);\r
+                       link_del(link);\r
+               }\r
+               list_for_each_entry_safe(link, tmp_link, &session->list_used, session_link) {\r
+                       do {\r
+                               link_ref_dec(link);\r
+                       } while (link->ref.used);\r
+                       link_del(link);\r
+               }\r
+       }\r
+       up_write(&vdm_rwsem);\r
+       kfree(session);\r
+\r
+       return 0;\r
 }\r
 \r
 static long vpu_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)\r
 {\r
-    long index, ret = 0;\r
+       long index, ret = 0;\r
 \r
        switch (cmd) {\r
-       case VPU_MEM_GET_PHYS:\r
+       case VPU_MEM_GET_PHYS: {\r
                DLOG("get_phys\n");\r
                printk(KERN_INFO "vpu_mem: request for physical address of vpu_mem region "\r
                                "from process %d.\n", current->pid);\r
                if (copy_to_user((void __user *)arg, &vpu_mem.base, sizeof(vpu_mem.base)))\r
-                       return -EFAULT;\r
-               break;\r
-       case VPU_MEM_GET_TOTAL_SIZE:\r
+               return -EFAULT;\r
+       } break;\r
+       case VPU_MEM_GET_TOTAL_SIZE: {\r
                DLOG("get total size\n");\r
                if (copy_to_user((void __user *)arg, &vpu_mem.size, sizeof(vpu_mem.size)))\r
                        return -EFAULT;\r
-               break;\r
-    case VPU_MEM_ALLOCATE:\r
+       } break;\r
+       case VPU_MEM_ALLOCATE: {\r
+               unsigned int size;\r
                DLOG("allocate\n");\r
-        {\r
-            unsigned int size;\r
-            if (copy_from_user(&size, (void __user *)arg, sizeof(size)))\r
-                return -EFAULT;\r
-            down_write(&vdm_rwsem);\r
-            ret = vpu_mem_allocate(file, size);\r
-            up_write(&vdm_rwsem);\r
-            DLOG("allocate at index %ld\n", ret);\r
-            break;\r
-        }\r
-    case VPU_MEM_FREE:\r
-        DLOG("mem free\n");\r
-        {\r
-            if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
-                return -EFAULT;\r
-            if (index >= vpu_mem.size)\r
-                return -EACCES;\r
-            down_write(&vdm_rwsem);\r
-            ret = vpu_mem_free(file, index);\r
-            up_write(&vdm_rwsem);\r
-            break;\r
-        }\r
+               if (copy_from_user(&size, (void __user *)arg, sizeof(size)))\r
+               return -EFAULT;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_allocate(file, size);\r
+               up_write(&vdm_rwsem);\r
+               DLOG("allocate at index %ld\n", ret);\r
+       } break;\r
+       case VPU_MEM_FREE: {\r
+               DLOG("mem free\n");\r
+               if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
+                       return -EFAULT;\r
+               if (index >= vpu_mem.size)\r
+                       return -EACCES;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_free(file, index);\r
+               up_write(&vdm_rwsem);\r
+       } break;\r
+\r
        case VPU_MEM_CACHE_FLUSH:\r
-    case VPU_MEM_CACHE_CLEAN:\r
-    case VPU_MEM_CACHE_INVALID:\r
-        DLOG("flush\n");\r
-               {\r
-                       if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
-                               return -EFAULT;\r
-            if (index < 0)\r
-                return -EINVAL;\r
-                       vpu_mem_cache_opt(file, index, cmd);\r
-                       break;\r
-               }\r
-       case VPU_MEM_DUPLICATE:\r
-        DLOG("duplicate\n");\r
-               {\r
-                       if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
-                               return -EFAULT;\r
-            down_write(&vdm_rwsem);\r
-                       ret = vpu_mem_duplicate(file, index);\r
-            up_write(&vdm_rwsem);\r
-                       break;\r
-               }\r
-       case VPU_MEM_LINK:\r
-        DLOG("link\n");\r
-               {\r
-                       if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
-                               return -EFAULT;\r
-            down_write(&vdm_rwsem);\r
-                       ret = vpu_mem_link(file, index);\r
-            up_write(&vdm_rwsem);\r
-                       break;\r
-               }\r
+       case VPU_MEM_CACHE_CLEAN:\r
+       case VPU_MEM_CACHE_INVALID: {\r
+               DLOG("flush\n");\r
+               if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
+                       return -EFAULT;\r
+               if (index < 0)\r
+                       return -EINVAL;\r
+               vpu_mem_cache_opt(file, index, cmd);\r
+       } break;\r
+       case VPU_MEM_DUPLICATE: {\r
+               DLOG("duplicate\n");\r
+               if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
+                       return -EFAULT;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_duplicate(file, index);\r
+               up_write(&vdm_rwsem);\r
+       } break;\r
+\r
+       case VPU_MEM_LINK: {\r
+               DLOG("link\n");\r
+               if (copy_from_user(&index, (void __user *)arg, sizeof(index)))\r
+                       return -EFAULT;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_link(file, index);\r
+               up_write(&vdm_rwsem);\r
+       } break;\r
+\r
+       case VPU_MEM_POOL_SET: {\r
+               struct vpu_mem_pool_config config;\r
+               DLOG("pool set\n");\r
+               if (copy_from_user(&config, (void __user *)arg, sizeof(config)))\r
+                       return -EFAULT;\r
+               config.size = (config.size + VPU_MEM_MIN_ALLOC - 1)/VPU_MEM_MIN_ALLOC;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_pool_set(file, config.size, config.count);\r
+               up_write(&vdm_rwsem);\r
+       } break;\r
+\r
+       case VPU_MEM_POOL_UNSET: {\r
+               struct vpu_mem_pool_config config;\r
+               DLOG("pool unset\n");\r
+               if (copy_from_user(&config, (void __user *)arg, sizeof(config)))\r
+                       return -EFAULT;\r
+               config.size = (config.size + VPU_MEM_MIN_ALLOC - 1)/VPU_MEM_MIN_ALLOC;\r
+               down_write(&vdm_rwsem);\r
+               ret = vpu_mem_pool_unset(file, config.size, config.count);\r
+               up_write(&vdm_rwsem);\r
+       } break;\r
+\r
+       case VPU_MEM_POOL_CHECK: {\r
+               int pfn;\r
+               if (copy_from_user(&pfn, (void __user *)arg, sizeof(int)))\r
+                       return -EFAULT;\r
+               pfn = (pfn + VPU_MEM_MIN_ALLOC - 1)/VPU_MEM_MIN_ALLOC;\r
+               DLOG("pool check\n");\r
+               down_read(&vdm_rwsem);\r
+               ret = vpu_mem_pool_check(file, pfn);\r
+               up_read(&vdm_rwsem);\r
+       } break;\r
+\r
        default:\r
                return -EINVAL;\r
        }\r
        return ret;\r
 }\r
 \r
+struct file_operations vpu_mem_fops = {\r
+       .open = vpu_mem_open,\r
+       .mmap = vpu_mem_mmap,\r
+       .unlocked_ioctl = vpu_mem_ioctl,\r
+       .release = vpu_mem_release,\r
+};\r
+\r
 #if VPU_MEM_DEBUG\r
 static ssize_t debug_open(struct inode *inode, struct file *file)\r
 {\r
@@ -1079,10 +1273,10 @@ static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
        n = scnprintf(buffer, debug_bufmax,\r
                      "pid #: mapped regions (offset, len, used, post) ...\n");\r
        down_read(&vdm_rwsem);\r
-    list_for_each_entry_safe(region, tmp_region, &vdm_index, index_list) {\r
-        n += scnprintf(buffer + n, debug_bufmax - n,\r
-                "(%d,%d,%d,%d) ",\r
-                region->index, region->pfn, region->used, region->post);\r
+       list_for_each_entry_safe(region, tmp_region, &vdm_index, index_list) {\r
+               n += scnprintf(buffer + n, debug_bufmax - n,\r
+                       "(%d,%d,%d,%d) ",\r
+                       region->index, region->pfn, region->used, region->post);\r
        }\r
        up_read(&vdm_rwsem);\r
        n++;\r
@@ -1230,6 +1424,7 @@ static int proc_vpu_mem_show(struct seq_file *s, void *v)
     down_read(&vdm_rwsem);\r
     {\r
         vdm_link    *link, *tmp_link;\r
+        vdm_pool    *pool, *tmp_pool;\r
         vdm_region  *region, *tmp_region;\r
         vdm_session *session, *tmp_session;\r
         // °´ index ´òÓ¡È«²¿ region\r
@@ -1244,7 +1439,7 @@ static int proc_vpu_mem_show(struct seq_file *s, void *v)
             seq_printf(s, "free :\n");\r
             list_for_each_entry_safe(link, tmp_link, &vdm_free, status_link) {\r
                 seq_printf(s, "       idx %6d pfn %6d used %3d post %3d\n",\r
-                    link->index, link->pfn, link->link_used, link->link_post);\r
+                    link->index, link->pfn, link->ref.used, link->ref.post);\r
             }\r
         }\r
         if (list_empty(&vdm_used)) {\r
@@ -1253,7 +1448,7 @@ static int proc_vpu_mem_show(struct seq_file *s, void *v)
             seq_printf(s, "used :\n");\r
             list_for_each_entry_safe(link, tmp_link, &vdm_used, status_link) {\r
                 seq_printf(s, "       idx %6d pfn %6d used %3d post %3d\n",\r
-                    link->index, link->pfn, link->link_used, link->link_post);\r
+                    link->index, link->pfn, link->ref.used, link->ref.post);\r
             }\r
         }\r
         if (list_empty(&vdm_post)) {\r
@@ -1262,20 +1457,29 @@ static int proc_vpu_mem_show(struct seq_file *s, void *v)
             seq_printf(s, "post :\n");\r
             list_for_each_entry_safe(link, tmp_link, &vdm_post, status_link) {\r
                 seq_printf(s, "       idx %6d pfn %6d used %3d post %3d\n",\r
-                    link->index, link->pfn, link->link_used, link->link_post);\r
+                    link->index, link->pfn, link->ref.used, link->ref.post);\r
             }\r
         }\r
 \r
         // ´òÓ¡ vpu_mem_info ÖеÄÈ«²¿ session µÄ region Õ¼ÓÃÇé¿ö\r
         list_for_each_entry_safe(session, tmp_session, &vdm_proc, list_session) {\r
             seq_printf(s, "\npid: %d\n", session->pid);\r
+            if (list_empty(&session->list_pool)) {\r
+                seq_printf(s, "pool : empty\n");\r
+            } else {\r
+                seq_printf(s, "pool :\n");\r
+                list_for_each_entry_safe(pool, tmp_pool, &session->list_pool, session_link) {\r
+                    seq_printf(s, "       pfn %6d target %3d current %2d\n",\r
+                        pool->pfn, pool->count_target, pool->count_current);\r
+                }\r
+            }\r
             if (list_empty(&session->list_used)) {\r
                 seq_printf(s, "used : empty\n");\r
             } else {\r
                 seq_printf(s, "used :\n");\r
                 list_for_each_entry_safe(link, tmp_link, &session->list_used, session_link) {\r
                     seq_printf(s, "       idx %6d pfn %6d used %3d\n",\r
-                        link->index, link->pfn, link->link_used);\r
+                        link->index, link->pfn, link->ref.used);\r
                 }\r
             }\r
             if (list_empty(&session->list_post)) {\r
@@ -1284,7 +1488,7 @@ static int proc_vpu_mem_show(struct seq_file *s, void *v)
                 seq_printf(s, "post :\n");\r
                 list_for_each_entry_safe(link, tmp_link, &session->list_post, session_link) {\r
                     seq_printf(s, "       idx %6d pfn %6d post %3d\n",\r
-                        link->index, link->pfn, link->link_post);\r
+                        link->index, link->pfn, link->ref.post);\r
                 }\r
             }\r
         }\r
index 794db94004d4daa3cfcae86d19a5841ac329886f..b9d99a05f137a8cf7f016d9e795cae27c49e4109 100755 (executable)
@@ -186,7 +186,7 @@ ssize_t cmmb_class_show_name(struct class * class, char * buf, size_t count, lof
        \r
 }  \r
 \r
-static CLASS_ATTR(name, 0777, cmmb_class_show_name, NULL);\r
+static CLASS_ATTR(name, 0660, cmmb_class_show_name, NULL);
 \r
 static int __init init_cmmbclass(void)\r
 {\r
index 6a1c59ae965086df7eba62dd2b08adc085025b5f..90316b5613aa0be32331ca38399c115feb477474 100755 (executable)
@@ -303,7 +303,6 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
                /* if the client doesn't support this heap type */
                if (!((1 << heap->type) & client->heap_mask))
                        continue;
-               
                /* if the caller didn't specify this heap type */
                if (!((1 << heap->id) & flags))
                        continue;
@@ -911,7 +910,7 @@ err:
 static long ion_share_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct ion_buffer *buffer = filp->private_data;
-       
+
        switch (cmd) {
        case PMEM_GET_PHYS:
        {
@@ -930,6 +929,9 @@ static long ion_share_ioctl(struct file *filp, unsigned int cmd, unsigned long a
                if (copy_from_user(&region, (void __user *)arg,
                                sizeof(struct pmem_region)))
                        return -EFAULT;
+                if(!(region.offset & 0xf0000000))
+                        region.offset = buffer->vm_start;
+
                dmac_flush_range((void *)region.offset, (void *)(region.offset + region.len));
 
                break;
@@ -963,7 +965,7 @@ static int ion_ioctl_share(struct file *parent, struct ion_client *client,
 
        if (parent->f_flags & O_DSYNC)
                file->f_flags |= O_DSYNC;
-       
+
        ion_buffer_get(handle->buffer);
        fd_install(fd, file);
 
@@ -982,15 +984,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        case ION_IOC_ALLOC:
        {
                struct ion_allocation_data data;
+
                if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
                        return -EFAULT;
-
                data.handle = ion_alloc(client, data.len, data.align,
                                             data.flags);
                if (IS_ERR_OR_NULL(data.handle)) {
                        printk("%s: alloc 0x%x bytes failed\n", __func__, data.len);
-            return -ENOMEM;
-               } 
+                       return -ENOMEM;
+               }
                if (copy_to_user((void __user *)arg, &data, sizeof(data)))
                        return -EFAULT;
                break;
@@ -1101,13 +1103,47 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                        return err;
                }
 
-               err = data.handle->buffer->heap->ops->cache_op(buffer->heap, buffer, 
+               err = data.handle->buffer->heap->ops->cache_op(buffer->heap, buffer,
                        data.virt, data.size, cmd);
                mutex_unlock(&client->lock);
                if(err < 0)
                        return err;
                break;
        }
+        case ION_GET_CLIENT:
+        {
+                struct ion_handle *handle;
+               struct ion_client_data data;
+                struct rb_node *n;
+
+               if (copy_from_user(&data, (void __user *)arg,
+                                  sizeof(struct ion_client_data)))
+                       return -EFAULT;
+
+               mutex_lock(&client->lock);
+                switch (data.type) {
+                        case ION_TYPE_GET_TOTAL_SIZE:
+                                data.total_size = 0;
+                               for (n = rb_first(&client->handles); n; n = rb_next(n)) {
+                                       handle = rb_entry(n, struct ion_handle, node);
+                                        data.total_size += handle->buffer->size;
+                                }
+                                break;
+                        case ION_TYPE_SIZE_GET_COUNT:
+                                data.count = 0;
+                               for (n = rb_first(&client->handles); n; n = rb_next(n)) {
+                                       handle = rb_entry(n, struct ion_handle, node);
+                                        if(handle->buffer->size == data.size)
+                                                data.count++;
+                                }
+                                break;
+                }
+               mutex_unlock(&client->lock);
+               if (copy_to_user((void __user *)arg, &data,
+                                sizeof(struct ion_client_data)))
+                       return -EFAULT;
+                break;
+        }
        default:
                return -ENOTTY;
        }
@@ -1315,6 +1351,7 @@ static const struct file_operations debug_leak_fops = {
        .llseek = seq_lseek,
        .release = single_release,
 };
+
 struct ion_device *ion_device_create(long (*custom_ioctl)
                                     (struct ion_client *client,
                                      unsigned int cmd,
index ec355c7da546adea8726bb697c432800dbf28953..38080f12aee52fba593b12e4075f1f42afb42225 100755 (executable)
@@ -13,8 +13,8 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/spinlock.h>
 
- #include <linux/spinlock.h>
 #include <linux/err.h>
 #include <linux/genalloc.h>
 #include <linux/io.h>
 #include <linux/vmalloc.h>
 #include <linux/iommu.h>
 #include <linux/seq_file.h>
-#include <asm/mach/map.h>
 #include <linux/dma-mapping.h>
 #include <asm/cacheflush.h>
-
 #include "ion_priv.h"
 
-#define ION_CACHED
+#include <asm/mach/map.h>
+
 #define RESERVED_SIZE(total)   ((total)/10)
+
 struct ion_carveout_heap {
        struct ion_heap heap;
        struct gen_pool *pool;
        ion_phys_addr_t base;
-
        unsigned long allocated_bytes;
        unsigned long vpu_allocated_bytes;
        unsigned long max_allocated;
@@ -45,6 +44,7 @@ struct ion_carveout_heap {
        unsigned long bit_nr;
        unsigned long *bits;
 };
+
 ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
                                      unsigned long size,
                                      unsigned long align,
@@ -52,12 +52,12 @@ ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
 {
        struct ion_carveout_heap *carveout_heap =
                container_of(heap, struct ion_carveout_heap, heap);
-       unsigned long offset; 
+       unsigned long offset;
        unsigned long free_size = carveout_heap->total_size - carveout_heap->allocated_bytes;
 
-       if((flags & (1<<ION_VPU_ID)) && 
-               (free_size < RESERVED_SIZE(carveout_heap->total_size))){
-               printk("%s: heap %s has not enough memory for vpu: vpu allocated(%luM)\n", 
+       if ((flags & (1<<ION_VPU_ID)) &&
+               (free_size < RESERVED_SIZE(carveout_heap->total_size))) {
+               printk("%s: heap %s has not enough memory for vpu: vpu allocated(%luM)\n",
                        __func__, heap->name, carveout_heap->vpu_allocated_bytes/SZ_1M);
                return ION_CARVEOUT_ALLOCATE_FAIL;
        }
@@ -70,13 +70,13 @@ ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
                                " the allocation of size %lu pages still failed."
                                " Memory is probably fragmented.\n",
                                __func__, heap->name,
-                               (carveout_heap->total_size - carveout_heap->allocated_bytes)/SZ_1K, 
+                               (carveout_heap->total_size - carveout_heap->allocated_bytes)/SZ_1K,
                                size/SZ_1K);
                else
                        printk("%s: heap %s has not enough memory(%luK)"
                                "the alloction of size is %luK.\n",
                                __func__, heap->name,
-                               (carveout_heap->total_size - carveout_heap->allocated_bytes)/SZ_1K, 
+                               (carveout_heap->total_size - carveout_heap->allocated_bytes)/SZ_1K,
                                size/SZ_1K);
                return ION_CARVEOUT_ALLOCATE_FAIL;
        }
@@ -88,7 +88,7 @@ ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
        if((offset + size - carveout_heap->base) > carveout_heap->max_allocated)
                carveout_heap->max_allocated = offset + size - carveout_heap->base;
 
-       bitmap_set(carveout_heap->bits, 
+       bitmap_set(carveout_heap->bits,
                (offset - carveout_heap->base)/PAGE_SIZE , size/PAGE_SIZE);
        return offset;
 }
@@ -105,7 +105,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
        if(flags & (1<<ION_VPU_ID))
                carveout_heap->vpu_allocated_bytes -= size;
        carveout_heap->allocated_bytes -= size;
-       bitmap_clear(carveout_heap->bits, 
+       bitmap_clear(carveout_heap->bits,
                (addr - carveout_heap->base)/PAGE_SIZE, size/PAGE_SIZE);
 }
 
@@ -177,8 +177,10 @@ int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
                                        vma->vm_end - vma->vm_start,
                                        pgprot_noncached(vma->vm_page_prot));
 
+        buffer->vm_start = vma->vm_start;
        return err;
 }
+
 int ion_carveout_cache_op(struct ion_heap *heap, struct ion_buffer *buffer,
                        void *virt, size_t size, unsigned int cmd)
 {
@@ -189,20 +191,20 @@ int ion_carveout_cache_op(struct ion_heap *heap, struct ion_buffer *buffer,
        switch(cmd) {
                case ION_CACHE_FLUSH:
                        dmac_flush_range((void *)start, (void *)end);
-                       outer_flush_range(buffer->priv_phys,buffer->priv_phys + size); 
+                       outer_flush_range(buffer->priv_phys,buffer->priv_phys + size);
                        break;
                case ION_CACHE_CLEAN:
-            /* When cleaning, always clean the innermost (L1) cache first 
+            /* When cleaning, always clean the innermost (L1) cache first
              * and then clean the outer cache(s).
              */
                        dmac_clean_range((void *)start, (void *)end);
-                       outer_clean_range(buffer->priv_phys,buffer->priv_phys + size); 
+                       outer_clean_range(buffer->priv_phys,buffer->priv_phys + size);
                        break;
                case ION_CACHE_INVALID:
-            /* When invalidating, always invalidate the outermost cache first 
+            /* When invalidating, always invalidate the outermost cache first
              * and the L1 cache last.
              */
-                       outer_inv_range(buffer->priv_phys,buffer->priv_phys + size); 
+                       outer_inv_range(buffer->priv_phys,buffer->priv_phys + size);
                        dmac_inv_range((void *)start, (void *)end);
                        break;
                default:
@@ -218,7 +220,7 @@ static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s)
                container_of(heap, struct ion_carveout_heap, heap);
 
        for(i = carveout_heap->bit_nr/8 - 1; i>= 0; i--){
-               seq_printf(s, "%.3uM> Bits[%.3d - %.3d]: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", 
+               seq_printf(s, "%.3uM> Bits[%.3d - %.3d]: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
                                i+1, i*8 + 7, i*8,
                                carveout_heap->bits[i*8 + 7],
                                carveout_heap->bits[i*8 + 6],
@@ -235,10 +237,11 @@ static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s)
                carveout_heap->allocated_bytes/SZ_1M);
        seq_printf(s, "max_allocated: %luM\n",
                carveout_heap->max_allocated/SZ_1M);
-       seq_printf(s, "Heap size: %luM, heap base: 0x%lx\n", 
+       seq_printf(s, "Heap size: %luM, heap base: 0x%lx\n",
                carveout_heap->total_size/SZ_1M, carveout_heap->base);
        return 0;
 }
+
 static struct ion_heap_ops carveout_heap_ops = {
        .allocate = ion_carveout_heap_allocate,
        .free = ion_carveout_heap_free,
@@ -273,7 +276,7 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
        carveout_heap->max_allocated = 0;
        carveout_heap->total_size = heap_data->size;
        carveout_heap->bit_nr = heap_data->size/(PAGE_SIZE * sizeof(unsigned long) * 8);
-       carveout_heap->bits = 
+       carveout_heap->bits =
                (unsigned long *)kzalloc(carveout_heap->bit_nr * sizeof(unsigned long), GFP_KERNEL);
 
        return &carveout_heap->heap;
index f954d2d90058c9c886d206acc73d19734b3ed537..75b1e753628e7684891dcb8b3d6d3aace85ad5d7 100755 (executable)
@@ -75,7 +75,7 @@ struct ion_buffer {
        void *vaddr;
        int dmap_cnt;
        struct scatterlist *sglist;
-
+       unsigned long vm_start;
        int marked;
 };
 
index 06aea18ad670f7403e156a44be431c4eb35224a0..69af912074c81e9d0de6b4050ee15eea341fffad 100755 (executable)
@@ -398,7 +398,7 @@ static int rk29_send_address(struct rk29_i2c_data *i2c,
        if((lsr & I2C_LSR_RCV_NAK) && !(msg->flags & I2C_M_IGNORE_NAK))
        {
                dev_info(i2c->dev, "addr: 0x%x receive no ack\n", msg->addr);
-               return -EINVAL;
+               return -EAGAIN;
        }
        if(start && (msg->flags & I2C_M_TEN))
                ret = rk29_send_2nd_addr(i2c, msg, start);
@@ -722,6 +722,9 @@ static int rk29_i2c_probe(struct platform_device *pdev)
        i2c->adap.algo          = &rk29_i2c_algorithm;
        i2c->adap.class         = I2C_CLASS_HWMON;
        i2c->adap.nr            = pdata->bus_num;
+    i2c->adap.retries   = 3;
+    i2c->adap.timeout   = msecs_to_jiffies(500);
+
        spin_lock_init(&i2c->cmd_lock);
 
        i2c->dev = &pdev->dev;
index 4fe4f4979d607a9304e782a774ce86df49b95d0b..4c2aa91efe9bece6ce2fd807fa9645e4b28c1460 100755 (executable)
@@ -672,17 +672,17 @@ static ssize_t bma150_enable_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(range, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+static DEVICE_ATTR(range, S_IRUGO,
                bma150_range_show, bma150_range_store);
-static DEVICE_ATTR(bandwidth, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+static DEVICE_ATTR(bandwidth, S_IRUGO,
                bma150_bandwidth_show, bma150_bandwidth_store);
-static DEVICE_ATTR(mode, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+static DEVICE_ATTR(mode, S_IRUGO,
                bma150_mode_show, bma150_mode_store);
-static DEVICE_ATTR(value, S_IRUGO|S_IWUSR|S_IWGRP,
+static DEVICE_ATTR(value, S_IRUGO,
                bma150_value_show, NULL);
-static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+static DEVICE_ATTR(delay, S_IRUGO,
                bma150_delay_show, bma150_delay_store);
-static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP|S_IWOTH,
+static DEVICE_ATTR(enable, S_IRUGO,
                bma150_enable_show, bma150_enable_store);
 
 static struct attribute *bma150_attributes[] = {
index e043d1b5f34899646cfcc1fc7e9ab5be1aac30b2..fd64405c3e622a20541e79068748664f518e2b48 100755 (executable)
@@ -399,6 +399,11 @@ static void ili2102_ts_work_func(struct work_struct *work)
                                        x = g_x[i];
                                        y = g_y[i];
                                }
+                               #ifdef CONFIG_MACH_RK29_TD8801_V2
+                               if( y >=80 ) y-=80;
+                               if( x >= 50 ) x-=50;
+                               #endif
+
                                g_x[i] = x;
                                g_y[i] = y;     
                                
index db2e66f90c6acfdac05befe587cf62f2dd8fae91..39faff42b3746d0523e90dcaa6d318a9717b1b0a 100644 (file)
@@ -70,13 +70,14 @@ struct point_data{
        unsigned char   id;    //finger ID
        int     posx;
        int     posy;
+       int     lastx;
+       int     lasty;
        unsigned char active;
        unsigned char pre_active;
 };
 
 static struct point_data point[MAX_SUPPORT_POINT];
 
-
 struct i2c_dev
 {
        struct list_head list;
@@ -272,12 +273,17 @@ static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data)
                        input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, false);
                }
 
-               if (point[i].active) {
+               if (point[i].active && (
+                       abs(point[i].posx - point[i].lastx) > 2 ||
+                       abs(point[i].posy - point[i].lasty) > 2
+                       )) {
                        input_mt_slot(tsdata->input, point[i].id);
                        input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER, true);
                        input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 1);
                        input_report_abs(tsdata->input, ABS_MT_POSITION_X, point[i].posy);
                        input_report_abs(tsdata->input, ABS_MT_POSITION_Y, point[i].posx);
+                       point[i].lastx = point[i].posx;
+                       point[i].lasty = point[i].posy;
                }
 
                DBG("%d[id = %d] = %2d active= %d pre_active = %d x = %5d y = %5d \n",
@@ -296,7 +302,7 @@ static void pixcir_ts_work_func(struct work_struct *work)
        while (!tsdata->exiting) {
        
                pixcir_ts_poscheck(tsdata);
-               /*if (attb_read_val()){
+               if (attb_read_val()){
                        DBG("%s:  >>>>>touch release\n\n",__FUNCTION__);
                        for (i = 0; i < MAX_SUPPORT_POINT; i++) {
                                point[i].pre_active = point[i].active;
@@ -309,7 +315,7 @@ static void pixcir_ts_work_func(struct work_struct *work)
                        input_sync(tsdata->input);
                        enable_irq(tsdata->client->irq);
                        break;
-               }*/
+               }
 
                msleep(1);
        }
index b4a43e71f9e0af65a388e3883191bc59beec432e..f5469ed2bde7635f0b54dd94f9adb11a841f9527 100755 (executable)
@@ -1637,7 +1637,7 @@ static ssize_t dbg_mode_store(struct class *cls,struct class_attribute *attr, co
       \r
     return _count;\r
 }\r
-static CLASS_ATTR(debug, 0666, dbg_mode_show, dbg_mode_store);\r
+static CLASS_ATTR(debug, 0664, dbg_mode_show, dbg_mode_store);\r
 \r
 static int dbg_sys_init(void)\r
 {\r
index e574c8de607b67a055ec11179a674b27fc4c10a7..aba638bf97ca08242c31f6be40be305dc38bc5d2 100755 (executable)
@@ -1185,6 +1185,19 @@ config VIDEO_RK29_DIGITALZOOM_IPP_OFF
        bool "Digital zoom with IPP off"
 endchoice
 
+choice
+       prompt "RK29XX camera memory "
+       depends on VIDEO_RK29 
+       default VIDEO_RK29_CAMMEM_PMEM
+       ---help---
+               where camera memory which is used for preview/raw/jpeg in android camera hal is alloced 
+config VIDEO_RK29_CAMMEM_PMEM
+       bool "Camera memory from pmem"
+
+config VIDEO_RK29_CAMMEM_ION
+       bool "Camera memory from ion"
+endchoice
+
 config VIDEO_MX2_HOSTSUPPORT
        bool
 
index 3a6a9e293d8ee264436dbcb307ab14b09d1628b0..baff822d39d79120bc68893dd3eca9a6cbfdb398 100755 (executable)
@@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -51,11 +51,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480//144
 #define SENSOR_MAX_WIDTH    800//1600
 #define SENSOR_MAX_HEIGHT   600//1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -75,6 +74,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1610,13 +1613,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
@@ -1625,63 +1621,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1702,7 +1644,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     mdelay(5); */ //delay 5 microseconds
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2094,7 +2036,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2113,6 +2055,52 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg!=0xff)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg!=0xff)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg!=0xff)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg!=0xff)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg!=0xff)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg!=0xff)
+    {
+        set_w = 1280;
+        set_h = 720;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg!=0xff)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+    }    
+
+    mf->width = set_w;
+    mf->height = set_h;    
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2880,22 +2868,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index b131adcc38c58fbcde9bb6018f907f6fc7b2ec66..033f533780dce659c6e126a9ad0fcbaf6aea26da 100755 (executable)
@@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -51,11 +51,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480//144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -75,6 +74,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1485,13 +1488,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
@@ -1500,63 +1496,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1577,7 +1518,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     mdelay(5); */ //delay 5 microseconds
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -1942,7 +1883,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -1961,6 +1902,48 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
+    }
+
+    mf->width = set_w;
+    mf->height = set_h; 
+    
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2723,22 +2706,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index d30e026ceb8e7d3790db5229fb1c7581e48fd440..0ee641e8c7cf4354f54c8deff4487f5e5ef6ba3e 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640             /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -97,7 +100,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init SVGA preview */
 static struct reginfo sensor_init_data[] =
 {
          /*init registers code.*/
@@ -1442,13 +1445,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1457,63 +1453,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
-    SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
+    int ret;
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
                ret = -ENODEV;
@@ -1548,7 +1488,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -1897,7 +1837,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -1916,6 +1856,37 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+    }    
+    mf->width = set_w;
+    mf->height = set_h; 
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2677,23 +2648,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
-
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index 2b88daa..f23c4d8
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640             /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
 
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
@@ -1443,13 +1445,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1458,62 +1453,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-       int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-       sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
                ret = -ENODEV;
@@ -1548,7 +1488,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2678,22 +2618,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 55ca4c19e6dbe2d63e728dc999d2b53789061092..b31ed13207be8e77ddb3eead0c1affca6306d630 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800//1024                       /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600//768
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -97,7 +100,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init SVGA preview */
 static struct reginfo sensor_init_data[] =
 
 {
@@ -1594,13 +1597,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1609,62 +1605,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1711,7 +1653,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2098,7 +2040,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2117,6 +2059,56 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800-32;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {          
+        set_w = 1024;
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {    
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600-32;
+        set_h = 1200;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;    
+    }
+    mf->width = set_w;
+    mf->height = set_h;     
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2888,22 +2880,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index c89758cd7212b4fe1265a8a5802de321420bf6db..6ecc115b6b1fba579aaf24559842fd1efeab3a60 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -97,7 +100,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init 352X288 SVGA */
 static struct reginfo sensor_init_data[] =
 {
     {0x0101 , 0x00},
@@ -2240,13 +2243,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
@@ -2256,62 +2252,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -2358,7 +2300,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2737,7 +2679,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2756,6 +2698,52 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+    }
+
+       mf->width = set_w;
+    mf->height = set_h;
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -3527,22 +3515,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index c096707e5c18497398563c4db759c7ab9bc41a74..343a22c73c98e38cf9bc5e4084d009a2c33914ac 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      1600                    /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  1200
+#define SENSOR_INIT_WINSEQADR sensor_uxga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -98,7 +101,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init SVGA preview */
 static struct reginfo sensor_init_data[] =
 {
 //     {0x01, 0xf9}, 
@@ -2152,14 +2155,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 1600;
-static s32 sensor_init_height = 1200;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -2168,62 +2163,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;    
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_uxga;
-       sensor_init_width = 1600;
-       sensor_init_height = 1200;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -2262,7 +2203,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 #endif
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -3429,22 +3370,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index d2e9cbe8c22506cbe1cc585b8eb5fa323c521529..6c2c2659cd3680e7eb49f1c9dad145e97061f9a9 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -98,7 +101,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init SVGA preview */
 static struct reginfo sensor_init_data[] =
 {
            //PAGE 0
@@ -1630,13 +1633,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1645,62 +1641,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1739,7 +1681,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 #endif
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2882,22 +2824,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 9e5064a33cd3b5250e28d0595b05eb353323d592..997657e0d71e26dfba3d36fdb4cd34608995f235 100755 (executable)
@@ -19,8 +19,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "mt9d112.h"
 
 static int debug;
@@ -54,11 +53,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   240
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -79,6 +77,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1765,13 +1768,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1779,66 +1775,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-       int ret,i = 0,j=0;
+    int ret;
 #if (SENSOR_ID_REG != SEQUENCE_END)    
     u16 pid = 0;
 #endif
-   struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
-
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -1883,7 +1823,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2245,7 +2185,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2264,6 +2204,72 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+       if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END))
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=SEQUENCE_END))
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && (sensor_vga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && (sensor_xga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 1024;
+        set_h = 768;
+    }
+       else if (((set_w <= 1280) && (set_h <= 720)) && (sensor_720p[0].reg!=SEQUENCE_END))
+    {
+        set_w = 1280;
+        set_h = 720;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else if (((set_w <= 1920) && (set_h <= 1080)) && (sensor_1080p[0].reg!=SEQUENCE_END))
+    {
+        set_w = 1920;
+        set_h = 1080;
+    }
+       else if (((set_w <= 2048) && (set_h <= 1536)) && (sensor_qxga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 2048;
+        set_h = 1536;
+    }
+       else if (((set_w <= 2592) && (set_h <= 1944)) && (sensor_qsxga[0].reg!=SEQUENCE_END))
+    {
+        set_w = 2592;
+        set_h = 1944;
+    }
+
+       mf->width = set_w;
+       mf->height = set_h;
+    
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -3179,22 +3185,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index b497ec31cb05522981366799795def203debc99b..191482da4d28609012dd7b7ee26ef02de312faf6 100755 (executable)
@@ -20,8 +20,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "mt9d113.h"
 
 static int debug;
@@ -57,11 +56,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   600
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_init_data
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -81,6 +79,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   1
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_FALLING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8 |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1560,13 +1562,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1574,63 +1569,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+    u16 pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1684,7 +1625,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2992,22 +2933,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index ba535af..b5bf570
@@ -22,8 +22,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "mt9p111.h"
 
 static int debug;
@@ -58,11 +57,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2592
 #define SENSOR_MAX_HEIGHT   1944
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT  V4L2_MBUS_FMT_UYVY8_2X8
 #define YUV420_BUFFER_MAX_SIZE  7558272     /* 2592*1944*1.5*/ 
 
 #define CONFIG_SENSOR_WhiteBalance     1
@@ -86,6 +84,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN    6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -114,7 +117,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_AF_MODE_CLOSE       5
 #endif
 
-/* init 800*600 SVGA */
+/* init 640X480 VGA */
 static struct reginfo sensor_init_data[] =
 {
 //[Step2-PLL_Timing]
@@ -2856,14 +2859,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -2873,66 +2868,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
 #endif
     const struct sensor_datafmt *fmt;
-    int ret,pid = 0,i = 0 ,j = 0;
+    int ret,pid = 0;
     int index  =0 ;
 #if (SENSOR_RESET_REG != SEQUENCE_END)
     struct reginfo reg_info;
 #endif
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -2983,7 +2923,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     
     SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING());
  
-    ret =sensor_write_init_data(client, sensor_init_data_p);
+    ret =sensor_write_init_data(client, sensor_init_data);
     if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
@@ -3762,7 +3702,10 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
         mf->width = SENSOR_MAX_WIDTH;
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
-
+    if (sensor_fmt_catch(mf->width, mf->height, &mf->width, &mf->height) == NULL) {
+               mf->width = 0;
+               mf->height = 0;
+       }
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -4698,22 +4641,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index b7b0e6cbc6aa32ee549959726d5d731861caf52f..ce2575e0f327ebb9e805090bab00699d6555a074 100755 (executable)
@@ -20,8 +20,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "mt9t111.h"
 
 static int debug;
@@ -56,11 +55,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2048
 #define SENSOR_MAX_HEIGHT   1536
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -84,6 +82,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH|\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN    6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -110,7 +113,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_AF_MODE_CLOSE       5
 #endif
 
-/* init 800*600 SVGA */
+/* init 640X480 VGA */
 static struct reginfo sensor_init_data[] =
 {
 //[Step2-PLL_Timing]
@@ -6689,14 +6692,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -6704,65 +6699,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    int ret,pid = 0,i = 0 , j = 0;
+    int ret,pid = 0;
 #if (SENSOR_RESET_REG != SEQUENCE_END)
     struct reginfo reg_info;
 #endif
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
                ret = -ENODEV;
@@ -6807,7 +6747,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
        
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -8326,22 +8266,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 53825acd43cfcb826ec17f1c8f3da8ea6e60b1d0..4aaaecee8aff4a840b11b6b6ab032c4c31b67a93 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -97,7 +100,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init 352X288 SVGA */
 static struct reginfo sensor_init_data[] =
 {
 {0x3024,0x02}, //TG   //0x02     
@@ -1441,14 +1444,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1457,62 +1452,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1562,7 +1503,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
        #endif
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2771,22 +2712,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index a1dbbd3..9b2ac56
+/*
+<<<<<<< HEAD
+ * ov2640 Camera Driver
+ *
+ * Copyright (C) 2010 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *
+ * Based on ov772x, ov9640 drivers and previous non merged implementations.
+ *
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2006, OmniVision
+=======
+o* Driver for MT9M001 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+>>>>>>> parent of 15f7fab... temp revert rk change
+ *
+ * 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.
+ */
+
+<<<<<<< HEAD
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-subdev.h>
+#include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+
+#define VAL_SET(x, mask, rshift, lshift)  \
+               ((((x) >> rshift) & mask) << lshift)
+/*
+ * DSP registers
+ * register offset for BANK_SEL == BANK_SEL_DSP
+ */
+#define R_BYPASS    0x05 /* Bypass DSP */
+#define   R_BYPASS_DSP_BYPAS    0x01 /* Bypass DSP, sensor out directly */
+#define   R_BYPASS_USE_DSP      0x00 /* Use the internal DSP */
+#define QS          0x44 /* Quantization Scale Factor */
+#define CTRLI       0x50
+#define   CTRLI_LP_DP           0x80
+#define   CTRLI_ROUND           0x40
+#define   CTRLI_V_DIV_SET(x)    VAL_SET(x, 0x3, 0, 3)
+#define   CTRLI_H_DIV_SET(x)    VAL_SET(x, 0x3, 0, 0)
+#define HSIZE       0x51 /* H_SIZE[7:0] (real/4) */
+#define   HSIZE_SET(x)          VAL_SET(x, 0xFF, 2, 0)
+#define VSIZE       0x52 /* V_SIZE[7:0] (real/4) */
+#define   VSIZE_SET(x)          VAL_SET(x, 0xFF, 2, 0)
+#define XOFFL       0x53 /* OFFSET_X[7:0] */
+#define   XOFFL_SET(x)          VAL_SET(x, 0xFF, 0, 0)
+#define YOFFL       0x54 /* OFFSET_Y[7:0] */
+#define   YOFFL_SET(x)          VAL_SET(x, 0xFF, 0, 0)
+#define VHYX        0x55 /* Offset and size completion */
+#define   VHYX_VSIZE_SET(x)     VAL_SET(x, 0x1, (8+2), 7)
+#define   VHYX_HSIZE_SET(x)     VAL_SET(x, 0x1, (8+2), 3)
+#define   VHYX_YOFF_SET(x)      VAL_SET(x, 0x3, 8, 4)
+#define   VHYX_XOFF_SET(x)      VAL_SET(x, 0x3, 8, 0)
+#define DPRP        0x56
+#define TEST        0x57 /* Horizontal size completion */
+#define   TEST_HSIZE_SET(x)     VAL_SET(x, 0x1, (9+2), 7)
+#define ZMOW        0x5A /* Zoom: Out Width  OUTW[7:0] (real/4) */
+#define   ZMOW_OUTW_SET(x)      VAL_SET(x, 0xFF, 2, 0)
+#define ZMOH        0x5B /* Zoom: Out Height OUTH[7:0] (real/4) */
+#define   ZMOH_OUTH_SET(x)      VAL_SET(x, 0xFF, 2, 0)
+#define ZMHH        0x5C /* Zoom: Speed and H&W completion */
+#define   ZMHH_ZSPEED_SET(x)    VAL_SET(x, 0x0F, 0, 4)
+#define   ZMHH_OUTH_SET(x)      VAL_SET(x, 0x1, (8+2), 2)
+#define   ZMHH_OUTW_SET(x)      VAL_SET(x, 0x3, (8+2), 0)
+#define BPADDR      0x7C /* SDE Indirect Register Access: Address */
+#define BPDATA      0x7D /* SDE Indirect Register Access: Data */
+#define CTRL2       0x86 /* DSP Module enable 2 */
+#define   CTRL2_DCW_EN          0x20
+#define   CTRL2_SDE_EN          0x10
+#define   CTRL2_UV_ADJ_EN       0x08
+#define   CTRL2_UV_AVG_EN       0x04
+#define   CTRL2_CMX_EN          0x01
+#define CTRL3       0x87 /* DSP Module enable 3 */
+#define   CTRL3_BPC_EN          0x80
+#define   CTRL3_WPC_EN          0x40
+#define SIZEL       0x8C /* Image Size Completion */
+#define   SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6)
+#define   SIZEL_HSIZE8_SET(x)    VAL_SET(x, 0x7, 0, 3)
+#define   SIZEL_VSIZE8_SET(x)    VAL_SET(x, 0x7, 0, 0)
+#define HSIZE8      0xC0 /* Image Horizontal Size HSIZE[10:3] */
+#define   HSIZE8_SET(x)         VAL_SET(x, 0xFF, 3, 0)
+#define VSIZE8      0xC1 /* Image Vertical Size VSIZE[10:3] */
+#define   VSIZE8_SET(x)         VAL_SET(x, 0xFF, 3, 0)
+#define CTRL0       0xC2 /* DSP Module enable 0 */
+#define   CTRL0_AEC_EN       0x80
+#define   CTRL0_AEC_SEL      0x40
+#define   CTRL0_STAT_SEL     0x20
+#define   CTRL0_VFIRST       0x10
+#define   CTRL0_YUV422       0x08
+#define   CTRL0_YUV_EN       0x04
+#define   CTRL0_RGB_EN       0x02
+#define   CTRL0_RAW_EN       0x01
+#define CTRL1       0xC3 /* DSP Module enable 1 */
+#define   CTRL1_CIP          0x80
+#define   CTRL1_DMY          0x40
+#define   CTRL1_RAW_GMA      0x20
+#define   CTRL1_DG           0x10
+#define   CTRL1_AWB          0x08
+#define   CTRL1_AWB_GAIN     0x04
+#define   CTRL1_LENC         0x02
+#define   CTRL1_PRE          0x01
+#define R_DVP_SP    0xD3 /* DVP output speed control */
+#define   R_DVP_SP_AUTO_MODE 0x80
+#define   R_DVP_SP_DVP_MASK  0x3F /* DVP PCLK = sysclk (48)/[6:0] (YUV0);
+                                  *          = sysclk (48)/(2*[6:0]) (RAW);*/
+#define IMAGE_MODE  0xDA /* Image Output Format Select */
+#define   IMAGE_MODE_Y8_DVP_EN   0x40
+#define   IMAGE_MODE_JPEG_EN     0x10
+#define   IMAGE_MODE_YUV422      0x00
+#define   IMAGE_MODE_RAW10       0x04 /* (DVP) */
+#define   IMAGE_MODE_RGB565      0x08
+#define   IMAGE_MODE_HREF_VSYNC  0x02 /* HREF timing select in DVP JPEG output
+                                      * mode (0 for HREF is same as sensor) */
+#define   IMAGE_MODE_LBYTE_FIRST 0x01 /* Byte swap enable for DVP
+                                      *    1: Low byte first UYVY (C2[4] =0)
+                                      *        VYUY (C2[4] =1)
+                                      *    0: High byte first YUYV (C2[4]=0)
+                                      *        YVYU (C2[4] = 1) */
+#define RESET       0xE0 /* Reset */
+#define   RESET_MICROC       0x40
+#define   RESET_SCCB         0x20
+#define   RESET_JPEG         0x10
+#define   RESET_DVP          0x04
+#define   RESET_IPU          0x02
+#define   RESET_CIF          0x01
+#define REGED       0xED /* Register ED */
+#define   REGED_CLK_OUT_DIS  0x10
+#define MS_SP       0xF0 /* SCCB Master Speed */
+#define SS_ID       0xF7 /* SCCB Slave ID */
+#define SS_CTRL     0xF8 /* SCCB Slave Control */
+#define   SS_CTRL_ADD_AUTO_INC  0x20
+#define   SS_CTRL_EN            0x08
+#define   SS_CTRL_DELAY_CLK     0x04
+#define   SS_CTRL_ACC_EN        0x02
+#define   SS_CTRL_SEN_PASS_THR  0x01
+#define MC_BIST     0xF9 /* Microcontroller misc register */
+#define   MC_BIST_RESET           0x80 /* Microcontroller Reset */
+#define   MC_BIST_BOOT_ROM_SEL    0x40
+#define   MC_BIST_12KB_SEL        0x20
+#define   MC_BIST_12KB_MASK       0x30
+#define   MC_BIST_512KB_SEL       0x08
+#define   MC_BIST_512KB_MASK      0x0C
+#define   MC_BIST_BUSY_BIT_R      0x02
+#define   MC_BIST_MC_RES_ONE_SH_W 0x02
+#define   MC_BIST_LAUNCH          0x01
+#define BANK_SEL    0xFF /* Register Bank Select */
+#define   BANK_SEL_DSP     0x00
+#define   BANK_SEL_SENS    0x01
+
+/*
+ * Sensor registers
+ * register offset for BANK_SEL == BANK_SEL_SENS
+ */
+#define GAIN        0x00 /* AGC - Gain control gain setting */
+#define COM1        0x03 /* Common control 1 */
+#define   COM1_1_DUMMY_FR          0x40
+#define   COM1_3_DUMMY_FR          0x80
+#define   COM1_7_DUMMY_FR          0xC0
+#define   COM1_VWIN_LSB_UXGA       0x0F
+#define   COM1_VWIN_LSB_SVGA       0x0A
+#define   COM1_VWIN_LSB_CIF        0x06
+#define REG04       0x04 /* Register 04 */
+#define   REG04_DEF             0x20 /* Always set */
+#define   REG04_HFLIP_IMG       0x80 /* Horizontal mirror image ON/OFF */
+#define   REG04_VFLIP_IMG       0x40 /* Vertical flip image ON/OFF */
+#define   REG04_VREF_EN         0x10
+#define   REG04_HREF_EN         0x08
+#define   REG04_AEC_SET(x)      VAL_SET(x, 0x3, 0, 0)
+#define REG08       0x08 /* Frame Exposure One-pin Control Pre-charge Row Num */
+#define COM2        0x09 /* Common control 2 */
+#define   COM2_SOFT_SLEEP_MODE  0x10 /* Soft sleep mode */
+                                    /* Output drive capability */
+#define   COM2_OCAP_Nx_SET(N)   (((N) - 1) & 0x03) /* N = [1x .. 4x] */
+#define PID         0x0A /* Product ID Number MSB */
+#define VER         0x0B /* Product ID Number LSB */
+#define COM3        0x0C /* Common control 3 */
+#define   COM3_BAND_50H        0x04 /* 0 For Banding at 60H */
+#define   COM3_BAND_AUTO       0x02 /* Auto Banding */
+#define   COM3_SING_FR_SNAPSH  0x01 /* 0 For enable live video output after the
+                                    * snapshot sequence*/
+#define AEC         0x10 /* AEC[9:2] Exposure Value */
+#define CLKRC       0x11 /* Internal clock */
+#define   CLKRC_EN             0x80
+#define   CLKRC_DIV_SET(x)     (((x) - 1) & 0x1F) /* CLK = XVCLK/(x) */
+#define COM7        0x12 /* Common control 7 */
+#define   COM7_SRST            0x80 /* Initiates system reset. All registers are
+                                    * set to factory default values after which
+                                    * the chip resumes normal operation */
+#define   COM7_RES_UXGA        0x00 /* Resolution selectors for UXGA */
+#define   COM7_RES_SVGA        0x40 /* SVGA */
+#define   COM7_RES_CIF         0x20 /* CIF */
+#define   COM7_ZOOM_EN         0x04 /* Enable Zoom mode */
+#define   COM7_COLOR_BAR_TEST  0x02 /* Enable Color Bar Test Pattern */
+#define COM8        0x13 /* Common control 8 */
+#define   COM8_DEF             0xC0 /* Banding filter ON/OFF */
+#define   COM8_BNDF_EN         0x20 /* Banding filter ON/OFF */
+#define   COM8_AGC_EN          0x04 /* AGC Auto/Manual control selection */
+#define   COM8_AEC_EN          0x01 /* Auto/Manual Exposure control */
+#define COM9        0x14 /* Common control 9
+                         * Automatic gain ceiling - maximum AGC value [7:5]*/
+#define   COM9_AGC_GAIN_2x     0x00 /* 000 :   2x */
+#define   COM9_AGC_GAIN_4x     0x20 /* 001 :   4x */
+#define   COM9_AGC_GAIN_8x     0x40 /* 010 :   8x */
+#define   COM9_AGC_GAIN_16x    0x60 /* 011 :  16x */
+#define   COM9_AGC_GAIN_32x    0x80 /* 100 :  32x */
+#define   COM9_AGC_GAIN_64x    0xA0 /* 101 :  64x */
+#define   COM9_AGC_GAIN_128x   0xC0 /* 110 : 128x */
+#define COM10       0x15 /* Common control 10 */
+#define   COM10_PCLK_HREF      0x20 /* PCLK output qualified by HREF */
+#define   COM10_PCLK_RISE      0x10 /* Data is updated at the rising edge of
+                                    * PCLK (user can latch data at the next
+                                    * falling edge of PCLK).
+                                    * 0 otherwise. */
+#define   COM10_HREF_INV       0x08 /* Invert HREF polarity:
+                                    * HREF negative for valid data*/
+#define   COM10_VSINC_INV      0x02 /* Invert VSYNC polarity */
+#define HSTART      0x17 /* Horizontal Window start MSB 8 bit */
+#define HEND        0x18 /* Horizontal Window end MSB 8 bit */
+#define VSTART      0x19 /* Vertical Window start MSB 8 bit */
+#define VEND        0x1A /* Vertical Window end MSB 8 bit */
+#define MIDH        0x1C /* Manufacturer ID byte - high */
+#define MIDL        0x1D /* Manufacturer ID byte - low  */
+#define AEW         0x24 /* AGC/AEC - Stable operating region (upper limit) */
+#define AEB         0x25 /* AGC/AEC - Stable operating region (lower limit) */
+#define VV          0x26 /* AGC/AEC Fast mode operating region */
+#define   VV_HIGH_TH_SET(x)      VAL_SET(x, 0xF, 0, 4)
+#define   VV_LOW_TH_SET(x)       VAL_SET(x, 0xF, 0, 0)
+#define REG2A       0x2A /* Dummy pixel insert MSB */
+#define FRARL       0x2B /* Dummy pixel insert LSB */
+#define ADDVFL      0x2D /* LSB of insert dummy lines in Vertical direction */
+#define ADDVFH      0x2E /* MSB of insert dummy lines in Vertical direction */
+#define YAVG        0x2F /* Y/G Channel Average value */
+#define REG32       0x32 /* Common Control 32 */
+#define   REG32_PCLK_DIV_2    0x80 /* PCLK freq divided by 2 */
+#define   REG32_PCLK_DIV_4    0xC0 /* PCLK freq divided by 4 */
+#define ARCOM2      0x34 /* Zoom: Horizontal start point */
+#define REG45       0x45 /* Register 45 */
+#define FLL         0x46 /* Frame Length Adjustment LSBs */
+#define FLH         0x47 /* Frame Length Adjustment MSBs */
+#define COM19       0x48 /* Zoom: Vertical start point */
+#define ZOOMS       0x49 /* Zoom: Vertical start point */
+#define COM22       0x4B /* Flash light control */
+#define COM25       0x4E /* For Banding operations */
+#define BD50        0x4F /* 50Hz Banding AEC 8 LSBs */
+#define BD60        0x50 /* 60Hz Banding AEC 8 LSBs */
+#define REG5D       0x5D /* AVGsel[7:0],   16-zone average weight option */
+#define REG5E       0x5E /* AVGsel[15:8],  16-zone average weight option */
+#define REG5F       0x5F /* AVGsel[23:16], 16-zone average weight option */
+#define REG60       0x60 /* AVGsel[31:24], 16-zone average weight option */
+#define HISTO_LOW   0x61 /* Histogram Algorithm Low Level */
+#define HISTO_HIGH  0x62 /* Histogram Algorithm High Level */
+
+/*
+ * ID
+ */
+#define MANUFACTURER_ID        0x7FA2
+#define PID_OV2640     0x2642
+#define VERSION(pid, ver) ((pid << 8) | (ver & 0xFF))
+
+/*
+ * Struct
+ */
+struct regval_list {
+       u8 reg_num;
+       u8 value;
+};
+
+/* Supported resolutions */
+enum ov2640_width {
+       W_QCIF  = 176,
+       W_QVGA  = 320,
+       W_CIF   = 352,
+       W_VGA   = 640,
+       W_SVGA  = 800,
+       W_XGA   = 1024,
+       W_SXGA  = 1280,
+       W_UXGA  = 1600,
+};
+
+enum ov2640_height {
+       H_QCIF  = 144,
+       H_QVGA  = 240,
+       H_CIF   = 288,
+       H_VGA   = 480,
+       H_SVGA  = 600,
+       H_XGA   = 768,
+       H_SXGA  = 1024,
+       H_UXGA  = 1200,
+};
+
+struct ov2640_win_size {
+       char                            *name;
+       enum ov2640_width               width;
+       enum ov2640_height              height;
+       const struct regval_list        *regs;
+};
+
+
+struct ov2640_priv {
+       struct v4l2_subdev              subdev;
+       struct ov2640_camera_info       *info;
+       enum v4l2_mbus_pixelcode        cfmt_code;
+       const struct ov2640_win_size    *win;
+       int                             model;
+       u16                             flag_vflip:1;
+       u16                             flag_hflip:1;
+};
+
+/*
+ * Registers settings
+ */
+
+#define ENDMARKER { 0xff, 0xff }
+
+static const struct regval_list ov2640_init_regs[] = {
+       { BANK_SEL, BANK_SEL_DSP },
+       { 0x2c,   0xff },
+       { 0x2e,   0xdf },
+       { BANK_SEL, BANK_SEL_SENS },
+       { 0x3c,   0x32 },
+       { CLKRC, CLKRC_DIV_SET(1) },
+       { COM2, COM2_OCAP_Nx_SET(3) },
+       { REG04, REG04_DEF | REG04_HREF_EN },
+       { COM8,  COM8_DEF | COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN },
+       { COM9, COM9_AGC_GAIN_8x | 0x08},
+       { 0x2c,   0x0c },
+       { 0x33,   0x78 },
+       { 0x3a,   0x33 },
+       { 0x3b,   0xfb },
+       { 0x3e,   0x00 },
+       { 0x43,   0x11 },
+       { 0x16,   0x10 },
+       { 0x39,   0x02 },
+       { 0x35,   0x88 },
+       { 0x22,   0x0a },
+       { 0x37,   0x40 },
+       { 0x23,   0x00 },
+       { ARCOM2, 0xa0 },
+       { 0x06,   0x02 },
+       { 0x06,   0x88 },
+       { 0x07,   0xc0 },
+       { 0x0d,   0xb7 },
+       { 0x0e,   0x01 },
+       { 0x4c,   0x00 },
+       { 0x4a,   0x81 },
+       { 0x21,   0x99 },
+       { AEW,    0x40 },
+       { AEB,    0x38 },
+       { VV,     VV_HIGH_TH_SET(0x08) | VV_LOW_TH_SET(0x02) },
+       { 0x5c,   0x00 },
+       { 0x63,   0x00 },
+       { FLL,    0x22 },
+       { COM3,   0x38 | COM3_BAND_AUTO },
+       { REG5D,  0x55 },
+       { REG5E,  0x7d },
+       { REG5F,  0x7d },
+       { REG60,  0x55 },
+       { HISTO_LOW,   0x70 },
+       { HISTO_HIGH,  0x80 },
+       { 0x7c,   0x05 },
+       { 0x20,   0x80 },
+       { 0x28,   0x30 },
+       { 0x6c,   0x00 },
+       { 0x6d,   0x80 },
+       { 0x6e,   0x00 },
+       { 0x70,   0x02 },
+       { 0x71,   0x94 },
+       { 0x73,   0xc1 },
+       { 0x3d,   0x34 },
+       { COM7, COM7_RES_UXGA | COM7_ZOOM_EN },
+       { 0x5a,   0x57 },
+       { BD50,   0xbb },
+       { BD60,   0x9c },
+       { BANK_SEL, BANK_SEL_DSP },
+       { 0xe5,   0x7f },
+       { MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL },
+       { 0x41,   0x24 },
+       { RESET, RESET_JPEG | RESET_DVP },
+       { 0x76,   0xff },
+       { 0x33,   0xa0 },
+       { 0x42,   0x20 },
+       { 0x43,   0x18 },
+       { 0x4c,   0x00 },
+       { CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10 },
+       { 0x88,   0x3f },
+       { 0xd7,   0x03 },
+       { 0xd9,   0x10 },
+       { R_DVP_SP , R_DVP_SP_AUTO_MODE | 0x2 },
+       { 0xc8,   0x08 },
+       { 0xc9,   0x80 },
+       { BPADDR, 0x00 },
+       { BPDATA, 0x00 },
+       { BPADDR, 0x03 },
+       { BPDATA, 0x48 },
+       { BPDATA, 0x48 },
+       { BPADDR, 0x08 },
+       { BPDATA, 0x20 },
+       { BPDATA, 0x10 },
+       { BPDATA, 0x0e },
+       { 0x90,   0x00 },
+       { 0x91,   0x0e },
+       { 0x91,   0x1a },
+       { 0x91,   0x31 },
+       { 0x91,   0x5a },
+       { 0x91,   0x69 },
+       { 0x91,   0x75 },
+       { 0x91,   0x7e },
+       { 0x91,   0x88 },
+       { 0x91,   0x8f },
+       { 0x91,   0x96 },
+       { 0x91,   0xa3 },
+       { 0x91,   0xaf },
+       { 0x91,   0xc4 },
+       { 0x91,   0xd7 },
+       { 0x91,   0xe8 },
+       { 0x91,   0x20 },
+       { 0x92,   0x00 },
+       { 0x93,   0x06 },
+       { 0x93,   0xe3 },
+       { 0x93,   0x03 },
+       { 0x93,   0x03 },
+       { 0x93,   0x00 },
+       { 0x93,   0x02 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x93,   0x00 },
+       { 0x96,   0x00 },
+       { 0x97,   0x08 },
+       { 0x97,   0x19 },
+       { 0x97,   0x02 },
+       { 0x97,   0x0c },
+       { 0x97,   0x24 },
+       { 0x97,   0x30 },
+       { 0x97,   0x28 },
+       { 0x97,   0x26 },
+       { 0x97,   0x02 },
+       { 0x97,   0x98 },
+       { 0x97,   0x80 },
+       { 0x97,   0x00 },
+       { 0x97,   0x00 },
+       { 0xa4,   0x00 },
+       { 0xa8,   0x00 },
+       { 0xc5,   0x11 },
+       { 0xc6,   0x51 },
+       { 0xbf,   0x80 },
+       { 0xc7,   0x10 },
+       { 0xb6,   0x66 },
+       { 0xb8,   0xA5 },
+       { 0xb7,   0x64 },
+       { 0xb9,   0x7C },
+       { 0xb3,   0xaf },
+       { 0xb4,   0x97 },
+       { 0xb5,   0xFF },
+       { 0xb0,   0xC5 },
+       { 0xb1,   0x94 },
+       { 0xb2,   0x0f },
+       { 0xc4,   0x5c },
+       { 0xa6,   0x00 },
+       { 0xa7,   0x20 },
+       { 0xa7,   0xd8 },
+       { 0xa7,   0x1b },
+       { 0xa7,   0x31 },
+       { 0xa7,   0x00 },
+       { 0xa7,   0x18 },
+       { 0xa7,   0x20 },
+       { 0xa7,   0xd8 },
+       { 0xa7,   0x19 },
+       { 0xa7,   0x31 },
+       { 0xa7,   0x00 },
+       { 0xa7,   0x18 },
+       { 0xa7,   0x20 },
+       { 0xa7,   0xd8 },
+       { 0xa7,   0x19 },
+       { 0xa7,   0x31 },
+       { 0xa7,   0x00 },
+       { 0xa7,   0x18 },
+       { 0x7f,   0x00 },
+       { 0xe5,   0x1f },
+       { 0xe1,   0x77 },
+       { 0xdd,   0x7f },
+       { CTRL0,  CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN },
+       ENDMARKER,
+};
+
+/*
+ * Register settings for window size
+ * The preamble, setup the internal DSP to input an UXGA (1600x1200) image.
+ * Then the different zooming configurations will setup the output image size.
+ */
+static const struct regval_list ov2640_size_change_preamble_regs[] = {
+       { BANK_SEL, BANK_SEL_DSP },
+       { RESET, RESET_DVP },
+       { HSIZE8, HSIZE8_SET(W_UXGA) },
+       { VSIZE8, VSIZE8_SET(H_UXGA) },
+       { CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN |
+                CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN },
+       { HSIZE, HSIZE_SET(W_UXGA) },
+       { VSIZE, VSIZE_SET(H_UXGA) },
+       { XOFFL, XOFFL_SET(0) },
+       { YOFFL, YOFFL_SET(0) },
+       { VHYX, VHYX_HSIZE_SET(W_UXGA) | VHYX_VSIZE_SET(H_UXGA) |
+               VHYX_XOFF_SET(0) | VHYX_YOFF_SET(0)},
+       { TEST, TEST_HSIZE_SET(W_UXGA) },
+       ENDMARKER,
+};
+
+#define PER_SIZE_REG_SEQ(x, y, v_div, h_div, pclk_div) \
+       { CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(v_div) | \
+                CTRLI_H_DIV_SET(h_div)},               \
+       { ZMOW, ZMOW_OUTW_SET(x) },                     \
+       { ZMOH, ZMOH_OUTH_SET(y) },                     \
+       { ZMHH, ZMHH_OUTW_SET(x) | ZMHH_OUTH_SET(y) },  \
+       { R_DVP_SP, pclk_div },                         \
+       { RESET, 0x00}
+
+static const struct regval_list ov2640_qcif_regs[] = {
+       PER_SIZE_REG_SEQ(W_QCIF, H_QCIF, 3, 3, 4),
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_qvga_regs[] = {
+       PER_SIZE_REG_SEQ(W_QVGA, H_QVGA, 2, 2, 4),
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_cif_regs[] = {
+       PER_SIZE_REG_SEQ(W_CIF, H_CIF, 2, 2, 8),
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_vga_regs[] = {
+       PER_SIZE_REG_SEQ(W_VGA, H_VGA, 0, 0, 2),
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_svga_regs[] = {
+       PER_SIZE_REG_SEQ(W_SVGA, H_SVGA, 1, 1, 2),
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_xga_regs[] = {
+       PER_SIZE_REG_SEQ(W_XGA, H_XGA, 0, 0, 2),
+       { CTRLI,    0x00},
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_sxga_regs[] = {
+       PER_SIZE_REG_SEQ(W_SXGA, H_SXGA, 0, 0, 2),
+       { CTRLI,    0x00},
+       { R_DVP_SP, 2 | R_DVP_SP_AUTO_MODE },
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_uxga_regs[] = {
+       PER_SIZE_REG_SEQ(W_UXGA, H_UXGA, 0, 0, 0),
+       { CTRLI,    0x00},
+       { R_DVP_SP, 0 | R_DVP_SP_AUTO_MODE },
+       ENDMARKER,
+};
+
+#define OV2640_SIZE(n, w, h, r) \
+       {.name = n, .width = w , .height = h, .regs = r }
+
+static const struct ov2640_win_size ov2640_supported_win_sizes[] = {
+       OV2640_SIZE("QCIF", W_QCIF, H_QCIF, ov2640_qcif_regs),
+       OV2640_SIZE("QVGA", W_QVGA, H_QVGA, ov2640_qvga_regs),
+       OV2640_SIZE("CIF", W_CIF, H_CIF, ov2640_cif_regs),
+       OV2640_SIZE("VGA", W_VGA, H_VGA, ov2640_vga_regs),
+       OV2640_SIZE("SVGA", W_SVGA, H_SVGA, ov2640_svga_regs),
+       OV2640_SIZE("XGA", W_XGA, H_XGA, ov2640_xga_regs),
+       OV2640_SIZE("SXGA", W_SXGA, H_SXGA, ov2640_sxga_regs),
+       OV2640_SIZE("UXGA", W_UXGA, H_UXGA, ov2640_uxga_regs),
+};
+
+/*
+ * Register settings for pixel formats
+ */
+static const struct regval_list ov2640_format_change_preamble_regs[] = {
+       { BANK_SEL, BANK_SEL_DSP },
+       { R_BYPASS, R_BYPASS_USE_DSP },
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_yuv422_regs[] = {
+       { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_YUV422 },
+       { 0xD7, 0x01 },
+       { 0x33, 0xa0 },
+       { 0xe1, 0x67 },
+       { RESET,  0x00 },
+       { R_BYPASS, R_BYPASS_USE_DSP },
+       ENDMARKER,
+};
+
+static const struct regval_list ov2640_rgb565_regs[] = {
+       { IMAGE_MODE, IMAGE_MODE_LBYTE_FIRST | IMAGE_MODE_RGB565 },
+       { 0xd7, 0x03 },
+       { RESET,  0x00 },
+       { R_BYPASS, R_BYPASS_USE_DSP },
+       ENDMARKER,
+};
+
+static enum v4l2_mbus_pixelcode ov2640_codes[] = {
+       V4L2_MBUS_FMT_UYVY8_2X8,
+       V4L2_MBUS_FMT_RGB565_2X8_LE,
+};
+
+/*
+ * Supported controls
+ */
+static const struct v4l2_queryctrl ov2640_controls[] = {
+       {
+               .id             = V4L2_CID_VFLIP,
+               .type           = V4L2_CTRL_TYPE_BOOLEAN,
+               .name           = "Flip Vertically",
+               .minimum        = 0,
+               .maximum        = 1,
+               .step           = 1,
+               .default_value  = 0,
+       }, {
+               .id             = V4L2_CID_HFLIP,
+               .type           = V4L2_CTRL_TYPE_BOOLEAN,
+               .name           = "Flip Horizontally",
+               .minimum        = 0,
+               .maximum        = 1,
+               .step           = 1,
+               .default_value  = 0,
+       },
+};
+
+/*
+ * General functions
+ */
+static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
+{
+       return container_of(i2c_get_clientdata(client), struct ov2640_priv,
+                           subdev);
+}
+
+static int ov2640_write_array(struct i2c_client *client,
+                             const struct regval_list *vals)
+{
+       int ret;
+
+       while ((vals->reg_num != 0xff) || (vals->value != 0xff)) {
+               ret = i2c_smbus_write_byte_data(client,
+                                               vals->reg_num, vals->value);
+               dev_vdbg(&client->dev, "array: 0x%02x, 0x%02x",
+                        vals->reg_num, vals->value);
+
+               if (ret < 0)
+                       return ret;
+               vals++;
+       }
+       return 0;
+}
+
+static int ov2640_mask_set(struct i2c_client *client,
+                          u8  reg, u8  mask, u8  set)
+{
+       s32 val = i2c_smbus_read_byte_data(client, reg);
+       if (val < 0)
+               return val;
+
+       val &= ~mask;
+       val |= set & mask;
+
+       dev_vdbg(&client->dev, "masks: 0x%02x, 0x%02x", reg, val);
+
+       return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int ov2640_reset(struct i2c_client *client)
+{
+       int ret;
+       const struct regval_list reset_seq[] = {
+               {BANK_SEL, BANK_SEL_SENS},
+               {COM7, COM7_SRST},
+               ENDMARKER,
+       };
+
+       ret = ov2640_write_array(client, reset_seq);
+       if (ret)
+               goto err;
+
+       msleep(5);
+err:
+       dev_dbg(&client->dev, "%s: (ret %d)", __func__, ret);
+       return ret;
+}
+
+/*
+ * soc_camera_ops functions
+ */
+static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
+{
+       return 0;
+}
+
+static int ov2640_set_bus_param(struct soc_camera_device *icd,
+                               unsigned long flags)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
+
+       /* Only one width bit may be set */
+       if (!is_power_of_2(width_flag))
+               return -EINVAL;
+
+       if (icl->set_bus_param)
+               return icl->set_bus_param(icl, width_flag);
+
+       /*
+        * Without board specific bus width settings we support only the
+        * sensors native bus width witch are tested working
+        */
+       if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8))
+               return 0;
+
+       return 0;
+}
+
+static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd)
+{
+       struct soc_camera_link *icl = to_soc_camera_link(icd);
+       unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
+               SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
+               SOCAM_DATA_ACTIVE_HIGH;
+
+       if (icl->query_bus_param)
+               flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
+       else
+               flags |= SOCAM_DATAWIDTH_10;
+
+       return soc_camera_apply_sensor_flags(icl, flags);
+}
+
+static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+       struct i2c_client  *client = v4l2_get_subdevdata(sd);
+       struct ov2640_priv *priv = to_ov2640(client);
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               ctrl->value = priv->flag_vflip;
+               break;
+       case V4L2_CID_HFLIP:
+               ctrl->value = priv->flag_hflip;
+               break;
+       }
+       return 0;
+}
+
+static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+       struct i2c_client  *client = v4l2_get_subdevdata(sd);
+       struct ov2640_priv *priv = to_ov2640(client);
+       int ret = 0;
+       u8 val;
+
+       switch (ctrl->id) {
+       case V4L2_CID_VFLIP:
+               val = ctrl->value ? REG04_VFLIP_IMG : 0x00;
+               priv->flag_vflip = ctrl->value ? 1 : 0;
+               ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
+               break;
+       case V4L2_CID_HFLIP:
+               val = ctrl->value ? REG04_HFLIP_IMG : 0x00;
+               priv->flag_hflip = ctrl->value ? 1 : 0;
+               ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
+               break;
+       }
+
+       return ret;
+}
+
+static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
+                              struct v4l2_dbg_chip_ident *id)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct ov2640_priv *priv = to_ov2640(client);
+
+       id->ident    = priv->model;
+       id->revision = 0;
+
+       return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov2640_g_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+       reg->size = 1;
+       if (reg->reg > 0xff)
+               return -EINVAL;
+
+       ret = i2c_smbus_read_byte_data(client, reg->reg);
+       if (ret < 0)
+               return ret;
+
+       reg->val = ret;
+
+       return 0;
+}
+
+static int ov2640_s_register(struct v4l2_subdev *sd,
+                            struct v4l2_dbg_register *reg)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (reg->reg > 0xff ||
+           reg->val > 0xff)
+               return -EINVAL;
+
+       return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
+}
+#endif
+
+/* Select the nearest higher resolution for capture */
+static const struct ov2640_win_size *ov2640_select_win(u32 *width, u32 *height)
+{
+       int i, default_size = ARRAY_SIZE(ov2640_supported_win_sizes) - 1;
+
+       for (i = 0; i < ARRAY_SIZE(ov2640_supported_win_sizes); i++) {
+               if (ov2640_supported_win_sizes[i].width  >= *width &&
+                   ov2640_supported_win_sizes[i].height >= *height) {
+                       *width = ov2640_supported_win_sizes[i].width;
+                       *height = ov2640_supported_win_sizes[i].height;
+                       return &ov2640_supported_win_sizes[i];
+               }
+       }
+
+       *width = ov2640_supported_win_sizes[default_size].width;
+       *height = ov2640_supported_win_sizes[default_size].height;
+       return &ov2640_supported_win_sizes[default_size];
+}
+
+static int ov2640_set_params(struct i2c_client *client, u32 *width, u32 *height,
+                            enum v4l2_mbus_pixelcode code)
+{
+       struct ov2640_priv       *priv = to_ov2640(client);
+       const struct regval_list *selected_cfmt_regs;
+       int ret;
+
+       /* select win */
+       priv->win = ov2640_select_win(width, height);
+
+       /* select format */
+       priv->cfmt_code = 0;
+       switch (code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_LE:
+               dev_dbg(&client->dev, "%s: Selected cfmt RGB565", __func__);
+               selected_cfmt_regs = ov2640_rgb565_regs;
+               break;
+       default:
+       case V4L2_MBUS_FMT_UYVY8_2X8:
+               dev_dbg(&client->dev, "%s: Selected cfmt YUV422", __func__);
+               selected_cfmt_regs = ov2640_yuv422_regs;
+       }
+
+       /* reset hardware */
+       ov2640_reset(client);
+
+       /* initialize the sensor with default data */
+       dev_dbg(&client->dev, "%s: Init default", __func__);
+       ret = ov2640_write_array(client, ov2640_init_regs);
+       if (ret < 0)
+               goto err;
+
+       /* select preamble */
+       dev_dbg(&client->dev, "%s: Set size to %s", __func__, priv->win->name);
+       ret = ov2640_write_array(client, ov2640_size_change_preamble_regs);
+       if (ret < 0)
+               goto err;
+
+       /* set size win */
+       ret = ov2640_write_array(client, priv->win->regs);
+       if (ret < 0)
+               goto err;
+
+       /* cfmt preamble */
+       dev_dbg(&client->dev, "%s: Set cfmt", __func__);
+       ret = ov2640_write_array(client, ov2640_format_change_preamble_regs);
+       if (ret < 0)
+               goto err;
+
+       /* set cfmt */
+       ret = ov2640_write_array(client, selected_cfmt_regs);
+       if (ret < 0)
+               goto err;
+
+       priv->cfmt_code = code;
+       *width = priv->win->width;
+       *height = priv->win->height;
+
+       return 0;
+
+err:
+       dev_err(&client->dev, "%s: Error %d", __func__, ret);
+       ov2640_reset(client);
+       priv->win = NULL;
+
+       return ret;
+}
+
+static int ov2640_g_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client  *client = v4l2_get_subdevdata(sd);
+       struct ov2640_priv *priv = to_ov2640(client);
+
+       if (!priv->win) {
+               u32 width = W_SVGA, height = H_SVGA;
+               int ret = ov2640_set_params(client, &width, &height,
+                                           V4L2_MBUS_FMT_UYVY8_2X8);
+               if (ret < 0)
+                       return ret;
+       }
+
+       mf->width       = priv->win->width;
+       mf->height      = priv->win->height;
+       mf->code        = priv->cfmt_code;
+
+       switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_LE:
+               mf->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       default:
+       case V4L2_MBUS_FMT_UYVY8_2X8:
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+       }
+       mf->field       = V4L2_FIELD_NONE;
+
+       return 0;
+}
+
+static int ov2640_s_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *mf)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int ret;
+
+
+       switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_LE:
+               mf->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       default:
+               mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+       case V4L2_MBUS_FMT_UYVY8_2X8:
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+       }
+
+       ret = ov2640_set_params(client, &mf->width, &mf->height, mf->code);
+
+       return ret;
+}
+
+static int ov2640_try_fmt(struct v4l2_subdev *sd,
+                         struct v4l2_mbus_framefmt *mf)
+{
+       const struct ov2640_win_size *win;
+
+       /*
+        * select suitable win
+        */
+       win = ov2640_select_win(&mf->width, &mf->height);
+
+       mf->field       = V4L2_FIELD_NONE;
+
+       switch (mf->code) {
+       case V4L2_MBUS_FMT_RGB565_2X8_LE:
+               mf->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       default:
+               mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
+       case V4L2_MBUS_FMT_UYVY8_2X8:
+               mf->colorspace = V4L2_COLORSPACE_JPEG;
+       }
+
+       return 0;
+}
+
+static int ov2640_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
+                          enum v4l2_mbus_pixelcode *code)
+{
+       if (index >= ARRAY_SIZE(ov2640_codes))
+               return -EINVAL;
+
+       *code = ov2640_codes[index];
+       return 0;
+}
+
+static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+       a->c.left       = 0;
+       a->c.top        = 0;
+       a->c.width      = W_UXGA;
+       a->c.height     = H_UXGA;
+       a->type         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+       return 0;
+}
+
+static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+       a->bounds.left                  = 0;
+       a->bounds.top                   = 0;
+       a->bounds.width                 = W_UXGA;
+       a->bounds.height                = H_UXGA;
+       a->defrect                      = a->bounds;
+       a->type                         = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       a->pixelaspect.numerator        = 1;
+       a->pixelaspect.denominator      = 1;
+
+       return 0;
+}
+
+static int ov2640_video_probe(struct soc_camera_device *icd,
+                             struct i2c_client *client)
+{
+       struct ov2640_priv *priv = to_ov2640(client);
+       u8 pid, ver, midh, midl;
+       const char *devname;
+       int ret;
+
+       /*
+        * we must have a parent by now. And it cannot be a wrong one.
+        * So this entire test is completely redundant.
+        */
+       if (!icd->dev.parent ||
+           to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
+               dev_err(&client->dev, "Parent missing or invalid!\n");
+               ret = -ENODEV;
+               goto err;
+       }
+
+       /*
+        * check and show product ID and manufacturer ID
+        */
+       i2c_smbus_write_byte_data(client, BANK_SEL, BANK_SEL_SENS);
+       pid  = i2c_smbus_read_byte_data(client, PID);
+       ver  = i2c_smbus_read_byte_data(client, VER);
+       midh = i2c_smbus_read_byte_data(client, MIDH);
+       midl = i2c_smbus_read_byte_data(client, MIDL);
+
+       switch (VERSION(pid, ver)) {
+       case PID_OV2640:
+               devname     = "ov2640";
+               priv->model = V4L2_IDENT_OV2640;
+               break;
+       default:
+               dev_err(&client->dev,
+                       "Product ID error %x:%x\n", pid, ver);
+               ret = -ENODEV;
+               goto err;
+       }
+
+       dev_info(&client->dev,
+                "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
+                devname, pid, ver, midh, midl);
+
+       return 0;
+
+err:
+       return ret;
+}
+
+static struct soc_camera_ops ov2640_ops = {
+       .set_bus_param          = ov2640_set_bus_param,
+       .query_bus_param        = ov2640_query_bus_param,
+       .controls               = ov2640_controls,
+       .num_controls           = ARRAY_SIZE(ov2640_controls),
+};
+
+static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
+       .g_ctrl         = ov2640_g_ctrl,
+       .s_ctrl         = ov2640_s_ctrl,
+       .g_chip_ident   = ov2640_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .g_register     = ov2640_g_register,
+       .s_register     = ov2640_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
+       .s_stream       = ov2640_s_stream,
+       .g_mbus_fmt     = ov2640_g_fmt,
+       .s_mbus_fmt     = ov2640_s_fmt,
+       .try_mbus_fmt   = ov2640_try_fmt,
+       .cropcap        = ov2640_cropcap,
+       .g_crop         = ov2640_g_crop,
+       .enum_mbus_fmt  = ov2640_enum_fmt,
+};
+
+static struct v4l2_subdev_ops ov2640_subdev_ops = {
+       .core   = &ov2640_subdev_core_ops,
+       .video  = &ov2640_subdev_video_ops,
+};
+
+/*
+ * i2c_driver functions
+ */
+static int ov2640_probe(struct i2c_client *client,
+                       const struct i2c_device_id *did)
+{
+       struct ov2640_priv        *priv;
+       struct soc_camera_device  *icd = client->dev.platform_data;
+       struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
+       struct soc_camera_link    *icl;
+       int                        ret;
+
+       if (!icd) {
+               dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n");
+               return -EINVAL;
+       }
+
+       icl = to_soc_camera_link(icd);
+       if (!icl) {
+               dev_err(&adapter->dev,
+                       "OV2640: Missing platform_data for driver\n");
+               return -EINVAL;
+       }
+
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+               dev_err(&adapter->dev,
+                       "OV2640: I2C-Adapter doesn't support SMBUS\n");
+               return -EIO;
+       }
+
+       priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(&adapter->dev,
+                       "Failed to allocate memory for private data!\n");
+               return -ENOMEM;
+       }
+
+       priv->info = icl->priv;
+
+       v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
+
+       icd->ops = &ov2640_ops;
+
+       ret = ov2640_video_probe(icd, client);
+       if (ret) {
+               icd->ops = NULL;
+               kfree(priv);
+       } else {
+               dev_info(&adapter->dev, "OV2640 Probed\n");
+       }
+
+       return ret;
+}
+
+static int ov2640_remove(struct i2c_client *client)
+{
+       struct ov2640_priv       *priv = to_ov2640(client);
+       struct soc_camera_device *icd = client->dev.platform_data;
+
+       icd->ops = NULL;
+       kfree(priv);
+       return 0;
+}
+
+static const struct i2c_device_id ov2640_id[] = {
+       { "ov2640", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, ov2640_id);
+
+static struct i2c_driver ov2640_i2c_driver = {
+       .driver = {
+               .name = "ov2640",
+       },
+       .probe    = ov2640_probe,
+       .remove   = ov2640_remove,
+       .id_table = ov2640_id,
+};
+
+/*
+ * Module functions
+ */
+static int __init ov2640_module_init(void)
+{
+       return i2c_add_driver(&ov2640_i2c_driver);
+}
+
+static void __exit ov2640_module_exit(void)
+{
+       i2c_del_driver(&ov2640_i2c_driver);
+}
+
+module_init(ov2640_module_init);
+module_exit(ov2640_module_exit);
+
+MODULE_DESCRIPTION("SoC Camera driver for Omni Vision 2640 sensor");
+MODULE_AUTHOR("Alberto Panizzo");
+MODULE_LICENSE("GPL v2");
+=======
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -41,11 +1254,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       1
@@ -65,6 +1277,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1550,13 +2766,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -1565,62 +2774,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1669,7 +2824,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2843,22 +3998,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 4b77bc0282e7fc0c282ed6c2fc56edcf60a9e5d0..d964b6d0e4aa6c7e2a7413503edab59b149a4cff 100755 (executable)
@@ -1,4 +1,4 @@
-#include <linux/videodev2.h>
+#include <linux/videodev2.h>\r
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
@@ -9,8 +9,8 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -25,7 +25,6 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define _CONS(a,b) a##b
 #define CONS(a,b) _CONS(a,b)
 
-
 #define __STR(x) #x
 #define _STR(x) __STR(x)
 #define STR(x) _STR(x)
@@ -42,11 +41,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       1
@@ -66,6 +64,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
 
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
@@ -1552,78 +1553,15 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = sensor_init_data;
-static struct reginfo* sensor_init_winseq_p = sensor_svga;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-       int ret,pid = 0,i = 0,j=0;
-       //if val ==1,mean that sensor need to be reinit
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-       sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -1673,7 +1611,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -1828,7 +1766,7 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd)
 
 static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct soc_camera_device *icd = client->dev.platform_data;
     struct sensor *sensor = to_sensor(client);
 
@@ -1877,7 +1815,7 @@ static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefm
 }
 static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
        const struct v4l2_queryctrl *qctrl;
@@ -2057,10 +1995,10 @@ sensor_s_fmt_end:
 
 static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;\r
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2078,14 +2016,66 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
         mf->width = SENSOR_MAX_WIDTH;
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
+\r
+    set_w = mf->width;
+    set_h = mf->height;
 
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;\r
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;\r
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;\r
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;\r
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;\r
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {
+        set_w = 1024;\r
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;\r
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600;\r
+        set_h = 1200;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;\r
+        set_h = SENSOR_INIT_HEIGHT;
+    }\r
+
+    mf->width = set_w;
+    mf->height = set_h;\r
+\r
     mf->colorspace = fmt->colorspace;
     
     return ret;
 }
  static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
 
     if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
         return -EINVAL;
@@ -2369,7 +2359,7 @@ static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_que
 
 static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct sensor *sensor = to_sensor(client);
     const struct v4l2_queryctrl *qctrl;
 
@@ -2428,7 +2418,7 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 
 static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct sensor *sensor = to_sensor(client);
     struct soc_camera_device *icd = client->dev.platform_data;
     const struct v4l2_queryctrl *qctrl;
@@ -2718,7 +2708,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
 
 static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct soc_camera_device *icd = client->dev.platform_data;
     int i, error_cnt=0, error_idx=-1;
 
@@ -2743,7 +2733,7 @@ static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control
 
 static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl)
 {
-    struct i2c_client *client = v4l2_get_subdevdata(sd);
+    struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct soc_camera_device *icd = client->dev.platform_data;
     int i, error_cnt=0, error_idx=-1;
 
@@ -2831,7 +2821,7 @@ sensor_video_probe_err:
 
 static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 {
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct soc_camera_device *icd = client->dev.platform_data;  
     struct sensor *sensor = to_sensor(client);
     int ret = 0;
@@ -2847,22 +2837,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           \r
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }\r
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
@@ -3017,4 +3010,4 @@ module_exit(sensor_mod_exit);
 
 MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));
 MODULE_AUTHOR("ddl <kernel@rock-chips>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL");\r
index 3e03bddaac98199ad1452776607f536a79332f12..bca088c1c4ac39e4b51aeff9746ecacb2e22ee36 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   1
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -94,7 +97,7 @@ struct reginfo
     u8 val;
 };
 
-/* init 800*600 SVGA */
+/* init 352X288 SVGA */
 static struct reginfo sensor_init_data[] =
 {
     {0x308c, 0x80},
@@ -369,7 +372,7 @@ static struct reginfo sensor_uxga[] =
 static struct reginfo sensor_sxga[] =
 {
     {0x300E, 0x34},
-    {0x3011, 0x01},
+    {0x3011, 0x00},
     {0x3012, 0x00},
     {0x302a, 0x05},
     {0x302b, 0xCB},
@@ -1681,14 +1684,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
-
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1697,62 +1692,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1803,7 +1744,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2188,7 +2129,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2207,6 +2148,52 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {
+        set_w = 1024;
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600;
+        set_h = 1200;
+    }
+
+    mf->width = set_w;
+    mf->height = set_h;
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2974,22 +2961,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+            sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 02259502ecc526c513631428f166d32677c1710d..b1830bb9fe684507d01fe993dd6203a284e8ea89 100755 (executable)
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   600
 #define SENSOR_MAX_WIDTH    1600
 #define SENSOR_MAX_HEIGHT   1200
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1458,8 +1461,7 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 {
        struct soc_camera_link *icl = to_soc_camera_link(icd);
        int ret = 0;
-       //for fpga debug ,not control io
-       //return 0;
+
     SENSOR_DG("%s %s  cmd(%d) on(%d)\n",SENSOR_NAME_STRING(),__FUNCTION__,cmd,on);
        switch (cmd)
        {
@@ -1499,13 +1501,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = sensor_init_data;
-static struct reginfo* sensor_init_winseq_p = sensor_svga;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1514,63 +1509,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       //if val ==1,mean that sensor need to be reinit
-    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1618,7 +1558,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2010,7 +1950,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2029,6 +1969,62 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg)
+    {
+        set_w = 1280;
+        set_h = 720;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {
+        set_w = 1024;
+        set_h = 768;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else
+    {              /* ddl@rock-chips.com : Sensor output smallest size if  isn't support app  */
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
+    }
+
+    mf->width = set_w;
+    mf->height = set_h;
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2835,21 +2831,23 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                {
                        sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
             if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                           (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                           sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-               }
-                       
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index 0024ece..3665166
@@ -19,9 +19,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "ov3640.h"
 
 static int debug;
@@ -52,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2048
 #define SENSOR_MAX_HEIGHT   1536
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_init_data
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -81,6 +78,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -2540,13 +2542,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = sd->priv;
@@ -2555,62 +2550,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;    
     char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -2659,7 +2600,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -4044,22 +3985,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 30f9ec75279db75e68d5585792f239ea6673cdb8..e71f9e7337d34613c531e0368753b3f54461f872 100755 (executable)
@@ -19,9 +19,9 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
+#include <mach/rk29_camera.h>
 #include "ov5640.h"
-#include <linux/vmalloc.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2592
 #define SENSOR_MAX_HEIGHT   1944
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -82,6 +81,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_WRITE_REGS  1
 #define WRITE_REGS_NUM 100
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
 
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
@@ -1995,6 +1997,11 @@ static void sensor_af_workqueue(struct work_struct *work)
     SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd);
     
     mutex_lock(&sensor->wq_lock);
+    if((sensor_work->cmd != WqCmd_af_init) && (sensor->info_priv.auto_focus != SENSOR_AF_MODE_AUTO))
+        {
+        SENSOR_TR("auto focus status is wrong ,do nothing !");
+        goto set_end;
+        }
     switch (sensor_work->cmd) 
     {
         case WqCmd_af_init:
@@ -2069,7 +2076,7 @@ static void sensor_af_workqueue(struct work_struct *work)
             SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING());
             break;
     } 
-
+set_end:
     if (sensor_work->wait == false) {
         kfree((void*)sensor_work);
     } else {
@@ -2361,13 +2368,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = sensor_init_data;
-static struct reginfo* sensor_init_winseq_p = sensor_svga;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -2376,63 +2376,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-       int ret,pid = 0,i = 0,j=0;
-       //if val ==1,mean that sensor need to be reinit
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-       sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -2480,7 +2424,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
@@ -3762,10 +3706,10 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
                }
                #endif
        } else if (enable == 0) {
-               sensor->info_priv.enable = 0;
                #if CONFIG_SENSOR_Focus 
         flush_workqueue(sensor->sensor_wq);
                #endif
+               sensor->info_priv.enable = 0;
        }
        return 0;
 }
@@ -3847,22 +3791,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+            sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index f9f71e3..2c97f4d
@@ -19,9 +19,9 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
+#include <mach/rk29_camera.h>
 #include "ov5640.h"
-#include <linux/vmalloc.h>
+
 static int debug = 1;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2592
 #define SENSOR_MAX_HEIGHT   1944
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -63,7 +62,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_Effect        1
 #define CONFIG_SENSOR_Scene         1
 #define CONFIG_SENSOR_DigitalZoom   0
-#define CONFIG_SENSOR_Exposure      0
+#define CONFIG_SENSOR_Exposure      1
 #define CONFIG_SENSOR_Flash         1
 #define CONFIG_SENSOR_Mirror        0
 #define CONFIG_SENSOR_Flip          0
@@ -82,6 +81,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_WRITE_REGS  1
 #define WRITE_REGS_NUM 100
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
 
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
@@ -959,31 +961,73 @@ static struct reginfo *sensor_EffectSeqe[] = {sensor_Effect_Normal, sensor_Effec
 #if CONFIG_SENSOR_Exposure
 static  struct reginfo sensor_Exposure0[]=
 {
+       {0x3a0f, 0x10},
+       {0x3a10, 0x08},
+       {0x3a1b, 0x10},
+       {0x3a1e, 0x08},
+       {0x3a11, 0x20},
+       {0x3a1f, 0x10},
        {SEQUENCE_END, 0x00}
 };
 static  struct reginfo sensor_Exposure1[]=
 {
+       {0x3a0f, 0x20},
+       {0x3a10, 0x18},
+       {0x3a11, 0x41},
+       {0x3a1b, 0x20},
+       {0x3a1e, 0x18},
+       {0x3a1f, 0x10},
        {SEQUENCE_END, 0x00}
 };
 static  struct reginfo sensor_Exposure2[]=
 {
+       {0x3a0f, 0x30},
+       {0x3a10, 0x28},
+       {0x3a11, 0x61},
+       {0x3a1b, 0x30},
+       {0x3a1e, 0x28},
+       {0x3a1f, 0x10},
        {SEQUENCE_END, 0x00}
 };
 
 static  struct reginfo sensor_Exposure3[]=
 {
+       {0x3a0f, 0x38},
+       {0x3a10, 0x30},
+       {0x3a11, 0x61},
+       {0x3a1b, 0x38},
+       {0x3a1e, 0x30},
+       {0x3a1f, 0x10},
        {SEQUENCE_END, 0x00}
 };
 static  struct reginfo sensor_Exposure4[]=
 {
+       {0x3a0f, 0x40},
+       {0x3a10, 0x38},
+       {0x3a11, 0x71},
+       {0x3a1b, 0x40},
+       {0x3a1e, 0x38},
+       {0x3a1f, 0x10},
        {SEQUENCE_END, 0x00}
 };
 static  struct reginfo sensor_Exposure5[]=
 {
+       {0x3a0f, 0x50},
+       {0x3a10, 0x48},
+       {0x3a11, 0x90},
+       {0x3a1b, 0x50},
+       {0x3a1e, 0x48},
+       {0x3a1f, 0x20},
        {SEQUENCE_END, 0x00}
 };
 static  struct reginfo sensor_Exposure6[]=
 {
+       {0x3a0f, 0x60},
+       {0x3a10, 0x58},
+       {0x3a11, 0xa0},
+       {0x3a1b, 0x60},
+       {0x3a1e, 0x58},
+       {0x3a1f, 0x20},
        {SEQUENCE_END, 0x00}
 };
 static struct reginfo *sensor_ExposureSeqe[] = {sensor_Exposure0, sensor_Exposure1, sensor_Exposure2, sensor_Exposure3,
@@ -1191,8 +1235,8 @@ static const struct v4l2_queryctrl sensor_controls[] =
         .id            = V4L2_CID_EXPOSURE,
         .type          = V4L2_CTRL_TYPE_INTEGER,
         .name          = "Exposure Control",
-        .minimum       = 0,
-        .maximum       = 6,
+        .minimum       = -3,
+        .maximum       = 3,
         .step          = 1,
         .default_value = 0,
     },
@@ -2361,13 +2405,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = sensor_init_data;
-static struct reginfo* sensor_init_winseq_p = sensor_svga;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -2376,63 +2413,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-       int ret,pid = 0,i = 0,j=0;
-       //if val ==1,mean that sensor need to be reinit
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-       sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -2480,7 +2461,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
@@ -3847,22 +3828,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 701558c2f606aa772988fbd7bb8934fc83bf3948..c238e393d2e71760b713df3752dac5e9a2cf4246 100755 (executable)
@@ -19,8 +19,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include "ov5642.h"
 
 static int debug;
@@ -51,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    2592
 #define SENSOR_MAX_HEIGHT   1944
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      800                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  600
+#define SENSOR_INIT_WINSEQADR sensor_svga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -80,6 +78,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -161,6 +164,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define StepFocus_Nearest_Tag    0x04
 #define StepFocus_Spec_Tag       0x10
 #endif
+
 /* init 800X600 SVGA */
 static struct reginfo sensor_init_data[] =
 {
@@ -3921,6 +3925,11 @@ static void sensor_af_workqueue(struct work_struct *work)
     SENSOR_DG("%s %s Enter, cmd:0x%x \n",SENSOR_NAME_STRING(), __FUNCTION__,sensor_work->cmd);
     
     mutex_lock(&sensor->wq_lock);
+    if((sensor_work->cmd != WqCmd_af_init) && (sensor->info_priv.auto_focus != SENSOR_AF_MODE_AUTO))
+        {
+        SENSOR_TR("auto focus status is wrong ,do nothing !");
+        goto set_end;
+        }
     switch (sensor_work->cmd) 
     {
         case WqCmd_af_init:
@@ -3995,7 +4004,7 @@ static void sensor_af_workqueue(struct work_struct *work)
             SENSOR_TR("Unknow command(%d) in %s af workqueue!",sensor_work->cmd,SENSOR_NAME_STRING());
             break;
     } 
-
+set_end:
     if (sensor_work->wait == false) {
         kfree((void*)sensor_work);
     } else {
@@ -4239,14 +4248,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -4255,62 +4256,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
     char value;
-    int ret,pid = 0,i = 0,j=0;
-    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && (i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret,pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -4357,7 +4304,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0) {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
         goto sensor_INIT_ERR;
@@ -4800,7 +4747,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -4819,6 +4766,78 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
 
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+       else if (((set_w <= 1024) && (set_h <= 768)) && sensor_xga[0].reg)
+    {
+        set_w = 1024;
+        set_h = 768;
+    }
+       else if (((set_w <= 1280) && (set_h <= 720)) && sensor_720p[0].reg)
+    {
+        set_w = 1280;
+        set_h = 720;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else if (((set_w <= 1600) && (set_h <= 1200)) && sensor_uxga[0].reg)
+    {
+        set_w = 1600;
+        set_h = 1200;
+    }
+    else if (((set_w <= 1920) && (set_h <= 1080)) && sensor_1080p[0].reg)
+    {
+        set_w = 1920;
+        set_h = 1080;
+    }
+       else if (((set_w <= 2048) && (set_h <= 1536)) && sensor_qxga[0].reg)
+    {
+        set_w = 2048;
+        set_h = 1536;
+    }
+       else if (((set_w <= 2592) && (set_h <= 1944)) && sensor_qsxga[0].reg)
+    {
+        set_w = 2592;
+        set_h = 1944;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;
+    }
+
+    mf->width = set_w;
+    mf->height = set_h;
+    
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -5675,10 +5694,10 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable)
                }
                #endif
        } else if (enable == 0) {
-               sensor->info_priv.enable = 0;
                #if CONFIG_SENSOR_Focus 
         flush_workqueue(sensor->sensor_wq);
                #endif
+               sensor->info_priv.enable = 0;
        }
        return 0;
 }
@@ -5760,24 +5779,26 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                        break;
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
-               {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;    
-            
+               {           
+            sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
             if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-            } 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
index 814299f64cc631e13f534727dffbfe4d294c7e23..a94b2d1f8da45f11d6b5eb867e841242c914ad9c 100755 (executable)
@@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -51,11 +51,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480//144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -75,6 +74,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -92,7 +95,8 @@ struct reginfo
     u8 reg;
     u8 val;
 };
-/* init 800*600 SVGA */
+
+/* init 640X480 VGA */
 static struct reginfo sensor_init_data[] =
 {
        {0x12, 0x80},
@@ -1379,13 +1383,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 800;
-static s32 sensor_init_height = 600;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1393,62 +1390,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-       int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_svga;
-       sensor_init_width = 800;
-       sensor_init_height = 600;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
 
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
@@ -1470,7 +1412,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
 
     mdelay(5);  //delay 5 microseconds
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -1850,7 +1792,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -1868,7 +1810,48 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
         mf->width = SENSOR_MAX_WIDTH;
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
+    
+    set_w = mf->width;
+    set_h = mf->height;
+
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else if (((set_w <= 800) && (set_h <= 600)) && sensor_svga[0].reg)
+    {
+        set_w = 800;
+        set_h = 600;
+    }
+    else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg)
+    {
+        set_w = 1280;
+        set_h = 1024;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
+    }
 
+    mf->width = set_w;
+    mf->height = set_h;
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2628,21 +2611,24 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
                        sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100755 (executable)
new mode 100644 (file)
index d197720..3e9884e
@@ -19,8 +19,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -50,11 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     1
 #define CONFIG_SENSOR_Brightness       0
@@ -74,6 +73,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -91,8 +94,7 @@ struct reginfo
     u8 reg;
     u8 val;
 };
-
-/* init 640*480 VGA */
+/* init 640X480 VGA */
 static struct reginfo sensor_init_data[] =
 {
        {0x12, 0x80},
@@ -1177,13 +1179,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1191,62 +1186,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    int ret,pid = 0,i = 0,j=0;
-    struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1266,7 +1207,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     }
     mdelay(5);  //delay 5 microseconds
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -2445,22 +2386,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index e5efd4a76731038cc7b189e171bdc03461da42e0..9fbd3037d1641f958d47401d2e5be05aa294bf4a 100755 (executable)
 #define PMEM_CAMIPP_NECESSARY    0x800000\r
 #elif (PMEM_CAM_FULL_RESOLUTION == 0x300000)\r
 #define PMEM_CAM_NECESSARY   0xe00000        /* 1280*720*1.5*4(preview) + 4.5M(capture raw) + 3M(jpeg encode output) */\r
-#define PMEM_CAMIPP_NECESSARY    0x500000\r
+#define PMEM_CAMIPP_NECESSARY    0x600000\r
 #elif (PMEM_CAM_FULL_RESOLUTION == 0x200000) /* 1280*720*1.5*4(preview) + 3M(capture raw) + 3M(jpeg encode output) */\r
 #define PMEM_CAM_NECESSARY   0xc00000\r
-#define PMEM_CAMIPP_NECESSARY    0x400000\r
+#define PMEM_CAMIPP_NECESSARY    0x600000\r
 #elif ((PMEM_CAM_FULL_RESOLUTION == 0x100000) || (PMEM_CAM_FULL_RESOLUTION == 0x130000))\r
 #define PMEM_CAM_NECESSARY   0x800000        /* 800*600*1.5*4(preview) + 2M(capture raw) + 2M(jpeg encode output) */\r
 #define PMEM_CAMIPP_NECESSARY    0x400000\r
 #define PMEM_CAM_NECESSARY   0x1200000\r
 #define PMEM_CAMIPP_NECESSARY    0x800000\r
 #endif\r
+\r
+#ifdef CONFIG_VIDEO_RK29_CAMMEM_ION\r
+#undef PMEM_CAM_NECESSARY\r
+#define PMEM_CAM_NECESSARY   0x00000000\r
+#endif\r
+\r
 /*---------------- Camera Sensor Fixed Macro End  ------------------------*/\r
 #else   //#ifdef CONFIG_VIDEO_RK29 \r
 #define PMEM_CAM_NECESSARY   0x00000000\r
@@ -68,7 +74,7 @@
  *****************************************************************************************/\r
 #ifdef CONFIG_VIDEO_RK29 \r
 static int camera_debug;\r
-module_param(camera_debug, int, S_IRUGO|S_IWUSR);\r
+module_param(camera_debug, int, S_IRUGO|S_IWUSR|S_IWGRP);\r
 \r
 #define ddprintk(level, fmt, arg...) do {                      \\r
        if (camera_debug >= level)                                      \\r
@@ -76,10 +82,27 @@ module_param(camera_debug, int, S_IRUGO|S_IWUSR);
 \r
 #define dprintk(format, ...) ddprintk(1, format, ## __VA_ARGS__)    \r
 \r
-#define SENSOR_NAME_0 STR(CONFIG_SENSOR_0)                     /* back camera sensor */\r
-#define SENSOR_NAME_1 STR(CONFIG_SENSOR_1)                     /* front camera sensor */\r
+#define SENSOR_NAME_0 STR(CONFIG_SENSOR_0)                     /* back camera sensor 0 */\r
 #define SENSOR_DEVICE_NAME_0  STR(CONS(CONFIG_SENSOR_0, _back))\r
+#ifdef CONFIG_SENSOR_01\r
+#define SENSOR_NAME_01 STR(CONFIG_SENSOR_01)                   /* back camera sensor 1 */\r
+#define SENSOR_DEVICE_NAME_01  STR(CONS(CONFIG_SENSOR_01, _back_1))\r
+#endif\r
+#ifdef CONFIG_SENSOR_02\r
+#define SENSOR_NAME_02 STR(CONFIG_SENSOR_02)                   /* back camera sensor 2 */\r
+#define SENSOR_DEVICE_NAME_02  STR(CONS(CONFIG_SENSOR_02, _back_2))\r
+#endif\r
+#define SENSOR_NAME_1 STR(CONFIG_SENSOR_1)                     /* front camera sensor 0 */\r
 #define SENSOR_DEVICE_NAME_1  STR(CONS(CONFIG_SENSOR_1, _front))\r
+#ifdef CONFIG_SENSOR_11\r
+#define SENSOR_NAME_11 STR(CONFIG_SENSOR_11)                   /* front camera sensor 1 */\r
+#define SENSOR_DEVICE_NAME_11  STR(CONS(CONFIG_SENSOR_11, _front_1))\r
+#endif\r
+#ifdef CONFIG_SENSOR_12\r
+#define SENSOR_NAME_12 STR(CONFIG_SENSOR_12)                   /* front camera sensor 2 */\r
+#define SENSOR_DEVICE_NAME_12  STR(CONS(CONFIG_SENSOR_12, _front_2))\r
+#endif\r
+\r
 \r
 static int rk29_sensor_io_init(void);\r
 static int rk29_sensor_io_deinit(int sensor);\r
@@ -97,7 +120,43 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
             .gpio_flash = CONFIG_SENSOR_FALSH_PIN_0,\r
             .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_0|CONFIG_SENSOR_RESETACTIVE_LEVEL_0|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0|CONFIG_SENSOR_FLASHACTIVE_LEVEL_0),\r
             .gpio_init = 0,            \r
-            .dev_name = SENSOR_DEVICE_NAME_0,\r
+            .dev_name = SENSOR_DEVICE_NAME_0,        \r
+        }, {\r
+        #ifdef CONFIG_SENSOR_01\r
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_01,\r
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_01,\r
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_01,\r
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_01,\r
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_01|CONFIG_SENSOR_RESETACTIVE_LEVEL_01|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_01|CONFIG_SENSOR_FLASHACTIVE_LEVEL_01),\r
+            .gpio_init = 0,            \r
+            .dev_name = SENSOR_DEVICE_NAME_01,\r
+        #else\r
+            .gpio_reset = INVALID_GPIO,\r
+            .gpio_power = INVALID_GPIO,\r
+            .gpio_powerdown = INVALID_GPIO,\r
+            .gpio_flash = INVALID_GPIO,\r
+            .gpio_flag = 0,\r
+            .gpio_init = 0,            \r
+            .dev_name = NULL,\r
+        #endif\r
+        }, {\r
+        #ifdef CONFIG_SENSOR_02\r
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_02,\r
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_02,\r
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_02,\r
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_02,\r
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_02|CONFIG_SENSOR_RESETACTIVE_LEVEL_02|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_02|CONFIG_SENSOR_FLASHACTIVE_LEVEL_02),\r
+            .gpio_init = 0,            \r
+            .dev_name = SENSOR_DEVICE_NAME_02, \r
+        #else\r
+            .gpio_reset = INVALID_GPIO,\r
+            .gpio_power = INVALID_GPIO,\r
+            .gpio_powerdown = INVALID_GPIO,\r
+            .gpio_flash = INVALID_GPIO,\r
+            .gpio_flag = 0,\r
+            .gpio_init = 0,            \r
+            .dev_name = NULL,\r
+        #endif\r
         }, {\r
             .gpio_reset = CONFIG_SENSOR_RESET_PIN_1,\r
             .gpio_power = CONFIG_SENSOR_POWER_PIN_1,\r
@@ -106,6 +165,42 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
             .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_1|CONFIG_SENSOR_RESETACTIVE_LEVEL_1|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1|CONFIG_SENSOR_FLASHACTIVE_LEVEL_1),\r
             .gpio_init = 0,\r
             .dev_name = SENSOR_DEVICE_NAME_1,\r
+        },{\r
+        #ifdef CONFIG_SENSOR_11\r
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_11,\r
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_11,\r
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_11,\r
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_11,\r
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_11|CONFIG_SENSOR_RESETACTIVE_LEVEL_11|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_11|CONFIG_SENSOR_FLASHACTIVE_LEVEL_11),\r
+            .gpio_init = 0,\r
+            .dev_name = SENSOR_DEVICE_NAME_11,\r
+        #else\r
+            .gpio_reset = INVALID_GPIO,\r
+            .gpio_power = INVALID_GPIO,\r
+            .gpio_powerdown = INVALID_GPIO,\r
+            .gpio_flash = INVALID_GPIO,\r
+            .gpio_flag = 0,\r
+            .gpio_init = 0,            \r
+            .dev_name = NULL,\r
+        #endif        \r
+        }, {\r
+        #ifdef CONFIG_SENSOR_12\r
+            .gpio_reset = CONFIG_SENSOR_RESET_PIN_12,\r
+            .gpio_power = CONFIG_SENSOR_POWER_PIN_12,\r
+            .gpio_powerdown = CONFIG_SENSOR_POWERDN_PIN_12,\r
+            .gpio_flash = CONFIG_SENSOR_FALSH_PIN_12,\r
+            .gpio_flag = (CONFIG_SENSOR_POWERACTIVE_LEVEL_12|CONFIG_SENSOR_RESETACTIVE_LEVEL_12|CONFIG_SENSOR_POWERDNACTIVE_LEVEL_12|CONFIG_SENSOR_FLASHACTIVE_LEVEL_12),\r
+            .gpio_init = 0,\r
+            .dev_name = SENSOR_DEVICE_NAME_12,\r
+        #else\r
+            .gpio_reset = INVALID_GPIO,\r
+            .gpio_power = INVALID_GPIO,\r
+            .gpio_powerdown = INVALID_GPIO,\r
+            .gpio_flash = INVALID_GPIO,\r
+            .gpio_flag = 0,\r
+            .gpio_init = 0,            \r
+            .dev_name = NULL,\r
+        #endif\r
         }\r
     },\r
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP\r
@@ -118,11 +213,47 @@ static struct rk29camera_platform_data rk29_camera_platform_data = {
     .info = {\r
         {\r
             .dev_name = SENSOR_DEVICE_NAME_0,\r
-            .orientation = CONFIG_SENSOR_ORIENTATION_0, \r
+            .orientation = CONFIG_SENSOR_ORIENTATION_0,  \r
+        #ifdef CONFIG_SENSOR_01\r
            },{\r
+               .dev_name = SENSOR_DEVICE_NAME_01,\r
+            .orientation = CONFIG_SENSOR_ORIENTATION_01, \r
+        #else\r
+        },{\r
+               .dev_name = NULL,\r
+            .orientation = 0x00, \r
+        #endif\r
+        #ifdef CONFIG_SENSOR_02\r
+           },{\r
+               .dev_name = SENSOR_DEVICE_NAME_02,\r
+            .orientation = CONFIG_SENSOR_ORIENTATION_02, \r
+        #else\r
+        },{\r
+               .dev_name = NULL,\r
+            .orientation = 0x00, \r
+        #endif\r
+        },{\r
             .dev_name = SENSOR_DEVICE_NAME_1,\r
             .orientation = CONFIG_SENSOR_ORIENTATION_1,\r
-        }\r
+        #ifdef CONFIG_SENSOR_11 \r
+        },{\r
+            .dev_name = SENSOR_DEVICE_NAME_11,\r
+            .orientation = CONFIG_SENSOR_ORIENTATION_11, \r
+        #else\r
+        },{\r
+               .dev_name = NULL,\r
+            .orientation = 0x00, \r
+        #endif\r
+        #ifdef CONFIG_SENSOR_12\r
+           },{\r
+               .dev_name = SENSOR_DEVICE_NAME_12,\r
+            .orientation = CONFIG_SENSOR_ORIENTATION_12, \r
+        #else\r
+        },{\r
+               .dev_name = NULL,\r
+            .orientation = 0x00, \r
+        #endif\r
+           }\r
        }\r
 };\r
 \r
@@ -1099,7 +1230,7 @@ static int sensor_power_default_cb (struct rk29camera_gpio_res *res, int on)
     int ret = 0;\r
     \r
     if (camera_power != INVALID_GPIO)  {\r
-                    if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {\r
+               if (camera_io_init & RK29_CAM_POWERACTIVE_MASK) {\r
             if (on) {\r
                gpio_set_value(camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
                        dprintk("%s..%s..PowerPin=%d ..PinLevel = %x   \n",__FUNCTION__,res->dev_name, camera_power, ((camera_ioflag&RK29_CAM_POWERACTIVE_MASK)>>RK29_CAM_POWERACTIVE_BITPOS));\r
@@ -1221,7 +1352,149 @@ static int sensor_flash_default_cb (struct rk29camera_gpio_res *res, int on)
     return ret;\r
 }\r
 \r
-\r
+static void rk29_sensor_fps_get(int idx, unsigned int *val, int w, int h)\r
+{\r
+    switch (idx)\r
+    {\r
+        case 0:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_0;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_0\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_0;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_0;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_0;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_0;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_0;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_0;\r
+            }\r
+            break;\r
+        }\r
+        #ifdef CONFIG_SENSOR_01\r
+        case 1:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_01;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_01\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_01;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_01;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_01;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_01;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_01;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_01;\r
+            }\r
+            break;\r
+        }\r
+        #endif\r
+        #ifdef CONFIG_SENSOR_02\r
+        case 2:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_02;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_02\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_02;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_02;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_02;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_02;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_02;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_02;\r
+            }\r
+            break;\r
+        }\r
+        #endif\r
+        \r
+        case 3:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_1;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_1\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_1;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_1;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_1;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_1;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_1;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_1;\r
+            }\r
+            break;\r
+        }\r
+        #ifdef CONFIG_SENSOR_11\r
+        case 4:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_11;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_11\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_11;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_11;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_11;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_11;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_11;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_11;\r
+            }\r
+            break;\r
+        }\r
+        #endif\r
+        #ifdef CONFIG_SENSOR_12\r
+        case 5:\r
+        {\r
+            if ((w==176) && (h==144)) {\r
+                *val = CONFIG_SENSOR_QCIF_FPS_FIXED_12;\r
+            #ifdef CONFIG_SENSOR_240X160_FPS_FIXED_12\r
+            } else if ((w==240) && (h==160)) {\r
+                *val = CONFIG_SENSOR_240X160_FPS_FIXED_12;\r
+            #endif\r
+            } else if ((w==320) && (h==240)) {\r
+                *val = CONFIG_SENSOR_QVGA_FPS_FIXED_12;\r
+            } else if ((w==352) && (h==288)) {\r
+                *val = CONFIG_SENSOR_CIF_FPS_FIXED_12;\r
+            } else if ((w==640) && (h==480)) {\r
+                *val = CONFIG_SENSOR_VGA_FPS_FIXED_12;\r
+            } else if ((w==720) && (h==480)) {\r
+                *val = CONFIG_SENSOR_480P_FPS_FIXED_12;\r
+            } else if ((w==1280) && (h==720)) {\r
+                *val = CONFIG_SENSOR_720P_FPS_FIXED_12;\r
+            }\r
+            break;\r
+        }\r
+        #endif\r
+        default:\r
+            printk(KERN_ERR"rk29_cam_io: sensor-%d have not been define in board file!",idx);\r
+    }\r
+}\r
 static int rk29_sensor_io_init(void)\r
 {\r
     int ret = 0, i,j;\r
@@ -1238,7 +1511,10 @@ static int rk29_sensor_io_init(void)
     if (sensor_ioctl_cb.sensor_flash_cb == NULL)\r
         sensor_ioctl_cb.sensor_flash_cb = sensor_flash_default_cb;\r
     \r
-    for (i=0; i<2; i++) {\r
+    for (i=0; i<RK29_CAM_SUPPORT_NUMS; i++) {\r
+        if (rk29_camera_platform_data.gpio_res[i].dev_name == NULL)\r
+            continue;\r
+        \r
         camera_reset = rk29_camera_platform_data.gpio_res[i].gpio_reset;\r
         camera_power = rk29_camera_platform_data.gpio_res[i].gpio_power;\r
                camera_powerdown = rk29_camera_platform_data.gpio_res[i].gpio_powerdown;\r
@@ -1253,7 +1529,11 @@ static int rk29_sensor_io_init(void)
                     printk("%s..%s..power pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_power);\r
                                    goto sensor_io_int_loop_end;\r
                 } else {\r
-                    if (camera_power != rk29_camera_platform_data.gpio_res[0].gpio_power) {\r
+                    for (j=0; j<i; j++) {\r
+                        if (camera_power == rk29_camera_platform_data.gpio_res[j].gpio_power)\r
+                            break;\r
+                    }\r
+                    if (i==j) {\r
                         printk("%s..%s..power pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_power);\r
                         goto sensor_io_int_loop_end;\r
                     }\r
@@ -1276,8 +1556,34 @@ static int rk29_sensor_io_init(void)
         if (camera_reset != INVALID_GPIO) {\r
             ret = gpio_request(camera_reset, "camera reset");\r
             if (ret) {\r
-                printk("%s..%s..reset pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_reset);\r
-                goto sensor_io_int_loop_end;\r
+                if (i==1) {\r
+                    if ((camera_reset == rk29_camera_platform_data.gpio_res[0].gpio_reset) \r
+                        || (camera_reset == rk29_camera_platform_data.gpio_res[2].gpio_reset)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==2) {\r
+                    if ((camera_reset == rk29_camera_platform_data.gpio_res[0].gpio_reset) \r
+                        || (camera_reset == rk29_camera_platform_data.gpio_res[1].gpio_reset)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==4) {\r
+                    if ((camera_reset == rk29_camera_platform_data.gpio_res[3].gpio_reset) \r
+                        || (camera_reset == rk29_camera_platform_data.gpio_res[5].gpio_reset)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==5) {\r
+                    if ((camera_reset == rk29_camera_platform_data.gpio_res[3].gpio_reset) \r
+                        || (camera_reset == rk29_camera_platform_data.gpio_res[4].gpio_reset)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (ret) {\r
+                    printk("%s..%s..reset pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_reset);\r
+                    goto sensor_io_int_loop_end;\r
+                }\r
             }\r
 \r
             if (rk29_sensor_iomux(camera_reset) < 0) {\r
@@ -1296,8 +1602,34 @@ static int rk29_sensor_io_init(void)
                if (camera_powerdown != INVALID_GPIO) {\r
             ret = gpio_request(camera_powerdown, "camera powerdown");\r
             if (ret) {\r
-                printk("%s..%s..powerdown pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_powerdown);\r
-                goto sensor_io_int_loop_end;\r
+                if (i==1) {\r
+                    if ((camera_powerdown == rk29_camera_platform_data.gpio_res[0].gpio_powerdown) \r
+                        || (camera_powerdown == rk29_camera_platform_data.gpio_res[2].gpio_powerdown)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==2) {\r
+                    if ((camera_powerdown == rk29_camera_platform_data.gpio_res[0].gpio_powerdown) \r
+                        || (camera_powerdown == rk29_camera_platform_data.gpio_res[1].gpio_powerdown)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==4) {\r
+                    if ((camera_powerdown == rk29_camera_platform_data.gpio_res[3].gpio_powerdown) \r
+                        || (camera_powerdown == rk29_camera_platform_data.gpio_res[5].gpio_powerdown)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==5) {\r
+                    if ((camera_powerdown == rk29_camera_platform_data.gpio_res[3].gpio_powerdown) \r
+                        || (camera_powerdown == rk29_camera_platform_data.gpio_res[4].gpio_powerdown)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (ret) {\r
+                    printk("%s..%s..powerdown pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_powerdown);\r
+                    goto sensor_io_int_loop_end;\r
+                }\r
             }\r
 \r
             if (rk29_sensor_iomux(camera_powerdown) < 0) {\r
@@ -1316,8 +1648,34 @@ static int rk29_sensor_io_init(void)
                if (camera_flash != INVALID_GPIO) {\r
             ret = gpio_request(camera_flash, "camera flash");\r
             if (ret) {\r
-                printk("%s..%s..flash pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_flash);\r
-                               goto sensor_io_int_loop_end;\r
+                if (i==1) {\r
+                    if ((camera_flash == rk29_camera_platform_data.gpio_res[0].gpio_flash) \r
+                        || (camera_flash == rk29_camera_platform_data.gpio_res[2].gpio_flash)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==2) {\r
+                    if ((camera_flash == rk29_camera_platform_data.gpio_res[0].gpio_flash) \r
+                        || (camera_flash == rk29_camera_platform_data.gpio_res[1].gpio_flash)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==4) {\r
+                    if ((camera_flash == rk29_camera_platform_data.gpio_res[3].gpio_flash) \r
+                        || (camera_flash == rk29_camera_platform_data.gpio_res[5].gpio_flash)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (i==5) {\r
+                    if ((camera_flash == rk29_camera_platform_data.gpio_res[3].gpio_flash) \r
+                        || (camera_flash == rk29_camera_platform_data.gpio_res[4].gpio_flash)) {\r
+                        ret = 0;\r
+                    }\r
+                }\r
+                if (ret) {\r
+                    printk("%s..%s..flash pin(%d) init failed\n",__FUNCTION__,rk29_camera_platform_data.gpio_res[i].dev_name,camera_flash);\r
+                               goto sensor_io_int_loop_end;\r
+                }\r
             }\r
 \r
             if (rk29_sensor_iomux(camera_flash) < 0) {\r
@@ -1335,164 +1693,37 @@ static int rk29_sensor_io_init(void)
         \r
         for (j=0; j<10; j++) {\r
             memset(&rk29_camera_platform_data.info[i].fival[j],0x00,sizeof(struct v4l2_frmivalenum));\r
-        }\r
-        j=0;\r
-        if (strstr(rk29_camera_platform_data.info[i].dev_name,"_back")) {\r
-            \r
-            #if CONFIG_SENSOR_QCIF_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QCIF_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 176;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 144;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_QVGA_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QVGA_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 320;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 240;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_CIF_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_CIF_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 352;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 288;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_VGA_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_VGA_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 640;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 480;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_480P_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_480P_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 720;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 480;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif            \r
-\r
-            #if CONFIG_SENSOR_SVGA_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_SVGA_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 800;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 600;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_720P_FPS_FIXED_0\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_720P_FPS_FIXED_0;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 1280;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 720;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-        } else {\r
-            #if CONFIG_SENSOR_QCIF_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QCIF_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 176;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 144;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_QVGA_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_QVGA_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 320;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 240;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_CIF_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_CIF_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 352;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 288;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
 \r
-            #if CONFIG_SENSOR_VGA_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_VGA_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 640;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 480;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_480P_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_480P_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 720;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 480;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif \r
-\r
-            #if CONFIG_SENSOR_SVGA_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_SVGA_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 800;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 600;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
-\r
-            #if CONFIG_SENSOR_720P_FPS_FIXED_1\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.denominator = CONFIG_SENSOR_720P_FPS_FIXED_1;\r
-            rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
-            rk29_camera_platform_data.info[i].fival[j].index = 0;\r
-            rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
-            rk29_camera_platform_data.info[i].fival[j].width = 1280;\r
-            rk29_camera_platform_data.info[i].fival[j].height = 720;\r
-            rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
-            j++;\r
-            #endif\r
+            if (j==0) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 176;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 144;\r
+            } else if (j==1) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 320;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 240;\r
+            } else if (j==2) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 352;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 288;\r
+            } else if (j==3) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 640;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 480;\r
+            } else if (j==4) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 720;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 480;\r
+            } else if (j==5) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 1280;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 720;\r
+            } else if (j==6) {\r
+                rk29_camera_platform_data.info[i].fival[j].width = 240;\r
+                rk29_camera_platform_data.info[i].fival[j].height = 160;\r
+            }\r
+            if (rk29_camera_platform_data.info[i].fival[j].width && rk29_camera_platform_data.info[i].fival[j].height) {\r
+                rk29_sensor_fps_get(i,&rk29_camera_platform_data.info[i].fival[j].discrete.denominator,\r
+                    rk29_camera_platform_data.info[i].fival[j].width,rk29_camera_platform_data.info[i].fival[j].height);\r
+                rk29_camera_platform_data.info[i].fival[j].discrete.numerator= 1000;\r
+                rk29_camera_platform_data.info[i].fival[j].index = 0;\r
+                rk29_camera_platform_data.info[i].fival[j].pixel_format = V4L2_PIX_FMT_NV12;\r
+                rk29_camera_platform_data.info[i].fival[j].type = V4L2_FRMIVAL_TYPE_DISCRETE;\r
+            }\r
         }\r
         \r
                continue;\r
@@ -1550,16 +1781,19 @@ static int rk29_sensor_io_deinit(int sensor)
 static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd, int on)\r
 {\r
     struct rk29camera_gpio_res *res = NULL;    \r
-       int ret = RK29_CAM_IO_SUCCESS;\r
-    if(rk29_camera_platform_data.gpio_res[0].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[0].dev_name, dev_name(dev)) == 0)) {\r
-               res = (struct rk29camera_gpio_res *)&rk29_camera_platform_data.gpio_res[0];\r
-    } else if (rk29_camera_platform_data.gpio_res[1].dev_name && (strcmp(rk29_camera_platform_data.gpio_res[1].dev_name, dev_name(dev)) == 0)) {\r
-       res = (struct rk29camera_gpio_res *)&rk29_camera_platform_data.gpio_res[1];\r
-    } else {\r
+       int ret = RK29_CAM_IO_SUCCESS,i;\r
+\r
+    for (i=0; i<RK29_CAM_SUPPORT_NUMS; i++) {\r
+        if(rk29_camera_platform_data.gpio_res[i].dev_name &&  (strcmp(rk29_camera_platform_data.gpio_res[i].dev_name, dev_name(dev)) == 0)) {\r
+               res = (struct rk29camera_gpio_res *)&rk29_camera_platform_data.gpio_res[i];\r
+        } \r
+    }\r
+    if (res == NULL) {\r
         printk(KERN_ERR "%s is not regisiterd in rk29_camera_platform_data!!\n",dev_name(dev));\r
         ret = RK29_CAM_EIO_INVALID;\r
         goto rk29_sensor_ioctrl_end;\r
     }\r
+\r
        switch (cmd)\r
        {\r
                case Cam_Power:\r
@@ -1613,12 +1847,18 @@ static int rk29_sensor_ioctrl(struct device *dev,enum rk29camera_ioctrl_cmd cmd,
 rk29_sensor_ioctrl_end:\r
     return ret;\r
 }\r
+\r
+static int rk29_sensor_powerdown(struct device *dev, int on)\r
+{\r
+       return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);\r
+}\r
 static int rk29_sensor_power(struct device *dev, int on)\r
 {\r
-       rk29_sensor_ioctrl(dev,Cam_Power,on);\r
+    if (!on)                        /* ddl@rock-chips.com : Ensure sensor enter standby or power off */\r
+        rk29_sensor_powerdown(dev,1);\r
+       rk29_sensor_ioctrl(dev,Cam_Power,on);    \r
     return 0;\r
 }\r
-#if (CONFIG_SENSOR_RESET_PIN_0 != INVALID_GPIO) || (CONFIG_SENSOR_RESET_PIN_1 != INVALID_GPIO)\r
 static int rk29_sensor_reset(struct device *dev)\r
 {\r
        rk29_sensor_ioctrl(dev,Cam_Reset,1);\r
@@ -1626,11 +1866,7 @@ static int rk29_sensor_reset(struct device *dev)
        rk29_sensor_ioctrl(dev,Cam_Reset,0);\r
        return 0;\r
 }\r
-#endif\r
-static int rk29_sensor_powerdown(struct device *dev, int on)\r
-{\r
-       return rk29_sensor_ioctrl(dev,Cam_PowerDown,on);\r
-}\r
+\r
 #if (CONFIG_SENSOR_IIC_ADDR_0 != 0x00)\r
 static struct i2c_board_info rk29_i2c_cam_info_0[] = {\r
        {\r
@@ -1689,6 +1925,130 @@ static struct platform_device rk29_soc_camera_pdrv_1 = {
        },\r
 };\r
 #endif\r
+#ifdef CONFIG_SENSOR_01\r
+#if (CONFIG_SENSOR_IIC_ADDR_01 != 0x00)\r
+static struct i2c_board_info rk29_i2c_cam_info_01[] = {\r
+       {\r
+               I2C_BOARD_INFO(SENSOR_NAME_01, CONFIG_SENSOR_IIC_ADDR_01>>1)\r
+       },\r
+};\r
+\r
+static struct soc_camera_link rk29_iclink_01 = {\r
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
+       .power          = rk29_sensor_power,\r
+#if (CONFIG_SENSOR_RESET_PIN_01 != INVALID_GPIO)\r
+    .reset      = rk29_sensor_reset,\r
+#endif    \r
+       .powerdown  = rk29_sensor_powerdown,\r
+       .board_info     = &rk29_i2c_cam_info_01[0],\r
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_01,\r
+       .module_name    = SENSOR_NAME_01,\r
+};\r
+\r
+/*platform_device : soc-camera need  */\r
+static struct platform_device rk29_soc_camera_pdrv_01 = {\r
+       .name   = "soc-camera-pdrv",\r
+       .id     = 8,\r
+       .dev    = {\r
+               .init_name = SENSOR_DEVICE_NAME_01,\r
+               .platform_data = &rk29_iclink_01,\r
+       },\r
+};\r
+#endif\r
+#endif\r
+#ifdef CONFIG_SENSOR_02\r
+#if (CONFIG_SENSOR_IIC_ADDR_02 != 0x00)\r
+static struct i2c_board_info rk29_i2c_cam_info_02[] = {\r
+       {\r
+               I2C_BOARD_INFO(SENSOR_NAME_02, CONFIG_SENSOR_IIC_ADDR_02>>1)\r
+       },\r
+};\r
+\r
+static struct soc_camera_link rk29_iclink_02 = {\r
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
+       .power          = rk29_sensor_power,\r
+#if (CONFIG_SENSOR_RESET_PIN_02 != INVALID_GPIO)\r
+    .reset      = rk29_sensor_reset,\r
+#endif    \r
+       .powerdown  = rk29_sensor_powerdown,\r
+       .board_info     = &rk29_i2c_cam_info_02[0],\r
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_02,\r
+       .module_name    = SENSOR_NAME_02,\r
+};\r
+\r
+/*platform_device : soc-camera need  */\r
+static struct platform_device rk29_soc_camera_pdrv_02 = {\r
+       .name   = "soc-camera-pdrv",\r
+       .id     = 3,\r
+       .dev    = {\r
+               .init_name = SENSOR_DEVICE_NAME_02,\r
+               .platform_data = &rk29_iclink_02,\r
+       },\r
+};\r
+#endif\r
+#endif\r
+#ifdef CONFIG_SENSOR_11\r
+#if (CONFIG_SENSOR_IIC_ADDR_11 != 0x00)\r
+static struct i2c_board_info rk29_i2c_cam_info_11[] = {\r
+       {\r
+               I2C_BOARD_INFO(SENSOR_NAME_11, CONFIG_SENSOR_IIC_ADDR_11>>1)\r
+       },\r
+};\r
+\r
+static struct soc_camera_link rk29_iclink_11 = {\r
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
+       .power          = rk29_sensor_power,\r
+#if (CONFIG_SENSOR_RESET_PIN_11 != INVALID_GPIO)\r
+    .reset      = rk29_sensor_reset,\r
+#endif         \r
+       .powerdown  = rk29_sensor_powerdown,\r
+       .board_info     = &rk29_i2c_cam_info_11[0],\r
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_11,\r
+       .module_name    = SENSOR_NAME_11,\r
+};\r
+\r
+/*platform_device : soc-camera need  */\r
+static struct platform_device rk29_soc_camera_pdrv_11 = {\r
+       .name   = "soc-camera-pdrv",\r
+       .id     = 4,\r
+       .dev    = {\r
+               .init_name = SENSOR_DEVICE_NAME_11,\r
+               .platform_data = &rk29_iclink_11,\r
+       },\r
+};\r
+#endif\r
+#endif\r
+#ifdef CONFIG_SENSOR_12\r
+#if (CONFIG_SENSOR_IIC_ADDR_12 != 0x00)\r
+static struct i2c_board_info rk29_i2c_cam_info_12[] = {\r
+       {\r
+               I2C_BOARD_INFO(SENSOR_NAME_12, CONFIG_SENSOR_IIC_ADDR_12>>1)\r
+       },\r
+};\r
+\r
+static struct soc_camera_link rk29_iclink_12 = {\r
+       .bus_id         = RK29_CAM_PLATFORM_DEV_ID,\r
+       .power          = rk29_sensor_power,\r
+#if (CONFIG_SENSOR_RESET_PIN_12 != INVALID_GPIO)\r
+    .reset      = rk29_sensor_reset,\r
+#endif         \r
+       .powerdown  = rk29_sensor_powerdown,\r
+       .board_info     = &rk29_i2c_cam_info_12[0],\r
+       .i2c_adapter_id = CONFIG_SENSOR_IIC_ADAPTER_ID_12,\r
+       .module_name    = SENSOR_NAME_12,\r
+};\r
+\r
+/*platform_device : soc-camera need  */\r
+static struct platform_device rk29_soc_camera_pdrv_12 = {\r
+       .name   = "soc-camera-pdrv",\r
+       .id     = 5,\r
+       .dev    = {\r
+               .init_name = SENSOR_DEVICE_NAME_12,\r
+               .platform_data = &rk29_iclink_12,\r
+       },\r
+};\r
+#endif\r
+#endif\r
 \r
 static u64 rockchip_device_camera_dmamask = 0xffffffffUL;\r
 static struct resource rk29_camera_resource[] = {\r
@@ -1716,7 +2076,7 @@ static struct platform_device rk29_device_camera = {
                .platform_data  = &rk29_camera_platform_data,\r
        }\r
 };\r
-\r
+#if (PMEM_CAM_SIZE > 0)\r
 static struct android_pmem_platform_data android_pmem_cam_pdata = {\r
        .name           = "pmem_cam",\r
        .start          = PMEM_CAM_BASE,\r
@@ -1732,6 +2092,38 @@ static struct platform_device android_pmem_cam_device = {
                .platform_data = &android_pmem_cam_pdata,\r
        },\r
 };\r
+#endif\r
+\r
+static int rk_register_camera_devices(void)\r
+{   \r
+#ifdef CONFIG_SENSOR_IIC_ADDR_01\r
+#if CONFIG_SENSOR_IIC_ADDR_01\r
+    platform_device_register(&rk29_soc_camera_pdrv_01);\r
+#endif\r
+#endif\r
+\r
+#ifdef CONFIG_SENSOR_IIC_ADDR_02\r
+#if CONFIG_SENSOR_IIC_ADDR_02\r
+    platform_device_register(&rk29_soc_camera_pdrv_02);\r
+#endif\r
+#endif\r
+\r
+#ifdef CONFIG_SENSOR_IIC_ADDR_11\r
+#if CONFIG_SENSOR_IIC_ADDR_11\r
+    platform_device_register(&rk29_soc_camera_pdrv_11);\r
+#endif\r
+#endif\r
+\r
+#ifdef CONFIG_SENSOR_IIC_ADDR_12\r
+#if CONFIG_SENSOR_IIC_ADDR_12\r
+    platform_device_register(&rk29_soc_camera_pdrv_12);\r
+#endif\r
+#endif\r
+       return 0;\r
+}\r
+\r
+module_init(rk_register_camera_devices);\r
+\r
 \r
 #endif\r
 \r
index 80b98127b6e7c464989e09b67ff0f0cf46320428..dd7cd4534bd8020313c77e7a53be232714c750e0 100755 (executable)
@@ -9,7 +9,7 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
-#if CONFIG_ARCH_RK29
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/io.h>
@@ -41,7 +41,7 @@
 
 
 static int debug;
-module_param(debug, int, S_IRUGO|S_IWUSR);
+module_param(debug, int, S_IRUGO|S_IWUSR|S_IWGRP);
 
 #define dprintk(level, fmt, arg...) do {                       \
        if (debug >= level)                                     \
@@ -148,8 +148,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 *v0.x.4 : this driver support digital zoom;
 *v0.x.5 : this driver support test framerate and query framerate from board file configuration;
 *v0.x.6 : this driver improve test framerate method;
+*v0.x.7 : this driver product resolution by IPP crop and scale, which user request but sensor can't support;
+*         note: this version is only provide yifang client, which is not official version;
+*v0.x.8 : this driver and rk29_camera.c support upto 3 back-sensors and upto 3 front-sensors;
 */
-#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 6)
+#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 8)
 
 /* limit to rk29 hardware capabilities */
 #define RK29_CAM_BUS_PARAM   (SOCAM_MASTER |\
@@ -316,6 +319,8 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
     struct rk29_camera_dev *pcdev = ici->priv;
     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
                                                icd->current_fmt->host_fmt);
+    int bytes_per_line_host = soc_mbus_bytes_per_line(pcdev->host_width,
+                                               icd->current_fmt->host_fmt);
 
     dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
 
@@ -324,7 +329,7 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 
        /* planar capture requires Y, U and V buffers to be page aligned */
        *size = PAGE_ALIGN(bytes_per_line*icd->user_height);       /* Y pages UV pages, yuv422*/
-       pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line * pcdev->host_height);
+       pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
 
 
        if (CAM_WORKQUEUE_IS_EN()) {
@@ -553,6 +558,7 @@ static void rk29_camera_capture_process(struct work_struct *work)
     vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
     src_y_size = pcdev->host_width*pcdev->host_height;
     dst_y_size = pcdev->icd->user_width*pcdev->icd->user_height;
+    
     for (h=0; h<scale_times; h++) {
         for (w=0; w<scale_times; w++) {
             
@@ -574,17 +580,17 @@ static void rk29_camera_capture_process(struct work_struct *work)
                        vb->state = VIDEOBUF_ERROR;
                        spin_unlock_irqrestore(&pcdev->lock, flags);
 
-                printk("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
-                printk("widx:%d hidx:%d ",w,h);
-                printk("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
-               printk("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
-               printk("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
-               printk("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
-               printk("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
-               printk("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
-               printk("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
-               printk("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
-               printk("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
+                RK29CAMERA_TR("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
+                RK29CAMERA_TR("widx:%d hidx:%d ",w,h);
+                RK29CAMERA_TR("%dx%d@(%d,%d)->%dx%d\n",pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height,pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,pcdev->icd->user_width,pcdev->icd->user_height);
+               RK29CAMERA_TR("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
+               RK29CAMERA_TR("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
+               RK29CAMERA_TR("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
+               RK29CAMERA_TR("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
+               RK29CAMERA_TR("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
+               RK29CAMERA_TR("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
+               RK29CAMERA_TR("ipp_req.src_vir_w:0x%x ipp_req.dst_vir_w :0x%x\n",ipp_req.src_vir_w ,ipp_req.dst_vir_w);
+               RK29CAMERA_TR("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
                 
                        goto do_ipp_err;
                }
@@ -859,9 +865,8 @@ static int rk29_camera_add_device(struct soc_camera_device *icd)
         goto ebusy;
     }
 
-    dev_info(&icd->dev, "RK29 Camera driver attached to camera%d(%s)\n",
-             icd->devnum,dev_name(icd->pdev));
-
+    RK29CAMERA_DG("RK29 Camera driver attached to %s\n",dev_name(icd->pdev));
+    
        pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT;
     pcdev->active = NULL;
     pcdev->icd = NULL;
@@ -927,8 +932,7 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd)
        mutex_lock(&camera_lock);
     BUG_ON(icd != pcdev->icd);
 
-    dev_info(&icd->dev, "RK29 Camera driver detached from camera%d(%s)\n",
-             icd->devnum,dev_name(icd->pdev));
+    RK29CAMERA_DG("RK29 Camera driver detached from %s\n",dev_name(icd->pdev));
 
        /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
           stream may be turn on again before close device, if suspend and resume happened. */
@@ -1316,25 +1320,50 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
                ret = -EINVAL;
             goto RK29_CAMERA_SET_FMT_END;
        }
-               mf.width = usr_w;
-               mf.height = usr_h;
        }
        #endif
     icd->sense = NULL;
 
     if (!ret) {
-        rect.left = 0;
-        rect.top = 0;
-        rect.width = mf.width;
-        rect.height = mf.height;
+
+        if (mf.width*usr_h == mf.height*usr_w) {
+            rect.width = mf.width;
+            rect.height = mf.height;
+        } else {
+            int ratio;
+            if (usr_w > usr_h) {
+                if (mf.width > usr_w) {
+                    ratio = mf.width*10/usr_w;
+                    rect.width = usr_w*ratio/10;
+                    rect.height = usr_h*ratio/10;                    
+                } else {
+                    ratio = usr_w*10/mf.width + 1;
+                    rect.width = usr_w*10/ratio;
+                    rect.height = usr_h*10/ratio;
+                }                
+            } else {
+                if (mf.height > usr_h) {
+                    ratio = mf.height*10/usr_h;
+                    rect.width = usr_w*ratio/10;
+                    rect.height = usr_h*ratio/10;                    
+                } else {
+                    ratio = usr_h*10/mf.height + 1;
+                    rect.width = usr_w*10/ratio;
+                    rect.height = usr_h*10/ratio;
+                }
+            }
+        }
+
+        rect.left = (mf.width - rect.width)/2;
+        rect.top = (mf.height - rect.height)/2;
 
         down(&pcdev->zoominfo.sem);        
         pcdev->zoominfo.a.c.width = rect.width*100/pcdev->zoominfo.zoom_rate;
                pcdev->zoominfo.a.c.width &= ~0x03;
                pcdev->zoominfo.a.c.height = rect.height*100/pcdev->zoominfo.zoom_rate;
                pcdev->zoominfo.a.c.height &= ~0x03;
-               pcdev->zoominfo.a.c.left = ((rect.width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
-               pcdev->zoominfo.a.c.top = ((rect.height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
+               pcdev->zoominfo.a.c.left = ((rect.width - pcdev->zoominfo.a.c.width)/2 + rect.left)&(~0x01);
+               pcdev->zoominfo.a.c.top = ((rect.height - pcdev->zoominfo.a.c.height)/2 + rect.top)&(~0x01);
         up(&pcdev->zoominfo.sem);
 
         /* ddl@rock-chips.com: IPP work limit check */
@@ -1354,9 +1383,17 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
             }
         }
         
-        RK29CAMERA_DG("%s..%s icd width:%d  host width:%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
-                                  rect.width, pix->width, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
+        /* ddl@rock-chips.com: Crop is doing by IPP, not by VIP in rk2918 */
+        rect.left = 0;
+        rect.top = 0;
+        rect.width = mf.width;
+        rect.height = mf.height;
+        
+        RK29CAMERA_DG("%s..%s Sensor output:%dx%d  VIP output:%dx%d (zoom: %dx%d@(%d,%d)->%dx%d)\n",__FUNCTION__,xlate->host_fmt->name,
+                                  mf.width, mf.height,rect.width,rect.height, pcdev->zoominfo.a.c.width,pcdev->zoominfo.a.c.height, pcdev->zoominfo.a.c.left,pcdev->zoominfo.a.c.top,
                                   pix->width, pix->height);
+
+                
         rk29_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
         
                if (CAM_IPPWORK_IS_EN()) {
@@ -1365,8 +1402,8 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd,
         pcdev->icd_width = icd_width;
         pcdev->icd_height = icd_height;
 
-        pix->width = mf.width;
-       pix->height = mf.height;
+        pix->width = usr_w;
+       pix->height = usr_h;
        pix->field = mf.field;
        pix->colorspace = mf.colorspace;
        icd->current_fmt = xlate;        
@@ -1376,7 +1413,7 @@ RK29_CAMERA_SET_FMT_END:
     if (stream_on & ENABLE_CAPTURE)
         write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL) | ENABLE_CAPTURE));
        if (ret)
-       RK29CAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
+       RK29CAMERA_TR("\n%s: Driver isn't support %dx%d resolution which user request!\n",__FUNCTION__,usr_w,usr_h);
     return ret;
 }
 static bool rk29_camera_fmt_capturechk(struct v4l2_format *f)
@@ -1412,7 +1449,8 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
        bool is_capture = rk29_camera_fmt_capturechk(f);
        bool vipmem_is_overflow = false;
     struct v4l2_mbus_framefmt mf;
-
+    int bytes_per_line_host;
+    
        usr_w = pix->width;
        usr_h = pix->height;
        RK29CAMERA_DG("%s enter width:%d  height:%d\n",__FUNCTION__,usr_w,usr_h);
@@ -1453,13 +1491,14 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
                goto RK29_CAMERA_TRY_FMT_END;
     RK29CAMERA_DG("%s mf.width:%d  mf.height:%d\n",__FUNCTION__,mf.width,mf.height);
        #ifdef CONFIG_VIDEO_RK29_WORK_IPP       
-       if ((mf.width > usr_w) && (mf.height > usr_h)) {
+       if ((mf.width != usr_w) || (mf.height != usr_h)) {
+        bytes_per_line_host = soc_mbus_bytes_per_line(mf.width,icd->current_fmt->host_fmt); 
                if (is_capture) {
-                       vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
+                       vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height) > pcdev->vipmem_size);
                } else {
                        /* Assume preview buffer minimum is 4 */
-                       vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
-               }
+                       vipmem_is_overflow = (PAGE_ALIGN(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
+               }        
                if (vipmem_is_overflow == false) {
                        pix->width = usr_w;
                        pix->height = usr_h;
@@ -1468,26 +1507,14 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
             pix->width = mf.width;
             pix->height = mf.height;            
                }
-       } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
-               if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) {
-                       if (is_capture) {
-                               vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size);
-                       } else {
-                               vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size);
-                       }
-                       if (vipmem_is_overflow == false) {
-                               pix->width = usr_w;
-                               pix->height = usr_h;
-                       } else {
-                               RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
+        
+        if ((mf.width < usr_w) || (mf.height < usr_h)) {
+            if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
+                RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
                 pix->width = mf.width;
                 pix->height = mf.height;
-                       }
-               } else {
-                       RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
-            pix->width = mf.width;
-            pix->height = mf.height;
-               }
+            }
+        }        
        }
        #else
     pix->width = mf.width;
@@ -1496,15 +1523,15 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd,
     pix->colorspace    = mf.colorspace;    
 
     switch (mf.field) {
-       case V4L2_FIELD_ANY:
-       case V4L2_FIELD_NONE:
-               pix->field      = V4L2_FIELD_NONE;
-               break;
-       default:
-               /* TODO: support interlaced at least in pass-through mode */
-               dev_err(icd->dev.parent, "Field type %d unsupported.\n",
-                       mf.field);
-               goto RK29_CAMERA_TRY_FMT_END;
+       case V4L2_FIELD_ANY:
+       case V4L2_FIELD_NONE:
+               pix->field      = V4L2_FIELD_NONE;
+               break;
+       default:
+               /* TODO: support interlaced at least in pass-through mode */
+               dev_err(icd->dev.parent, "Field type %d unsupported.\n",
+                       mf.field);
+               goto RK29_CAMERA_TRY_FMT_END;
        }
 
 RK29_CAMERA_TRY_FMT_END:
@@ -1554,14 +1581,27 @@ static int rk29_camera_querycap(struct soc_camera_host *ici,
 {
     struct rk29_camera_dev *pcdev = ici->priv;
     char orientation[5];
+    int i;
 
-    strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));    
-    if (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[0].dev_name) == 0) {
-        sprintf(orientation,"-%d",pcdev->pdata->info[0].orientation);
+    strlcpy(cap->card, dev_name(pcdev->icd->pdev), sizeof(cap->card));
+
+    memset(orientation,0x00,sizeof(orientation));
+    for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+        if ((pcdev->pdata->info[i].dev_name!=NULL) && (strcmp(dev_name(pcdev->icd->pdev), pcdev->pdata->info[i].dev_name) == 0)) {
+            sprintf(orientation,"-%d",pcdev->pdata->info[i].orientation);
+        }
+    }
+    
+    if (orientation[0] != '-') {
+        RK29CAMERA_TR("%s: %s is not registered in rk29_camera_platform_data, orientation apply default value",__FUNCTION__,dev_name(pcdev->icd->pdev));
+        if (strstr(dev_name(pcdev->icd->pdev),"front")) 
+            strcat(cap->card,"-270");
+        else 
+            strcat(cap->card,"-90");
     } else {
-        sprintf(orientation,"-%d",pcdev->pdata->info[1].orientation);
+        strcat(cap->card,orientation); 
     }
-    strcat(cap->card,orientation); 
+    
     cap->version = RK29_CAM_VERSION_CODE;
     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 
@@ -1772,7 +1812,7 @@ int rk29_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_f
     struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
     struct rk29_camera_dev *pcdev = ici->priv;
     struct rk29_camera_frmivalenum *fival_list = NULL;
-    struct v4l2_frmivalenum *fival_head;
+    struct v4l2_frmivalenum *fival_head=NULL;
     int i,ret = 0,index;
     
     index = fival->index & 0x00ffffff;
@@ -1805,12 +1845,20 @@ int rk29_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_f
             RK29CAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
             ret = -EINVAL;
         }
-    } else {
-        if (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[0].dev_name) == 0) {
-            fival_head = pcdev->pdata->info[0].fival;
-        } else {
-            fival_head = pcdev->pdata->info[1].fival;
+    } else {  
+
+        for (i=0; i<RK29_CAM_SUPPORT_NUMS; i++) {
+            if (pcdev->pdata->info[i].dev_name && (strcmp(dev_name(pcdev->icd->pdev),pcdev->pdata->info[i].dev_name) == 0)) {
+                fival_head = pcdev->pdata->info[i].fival;
+            }
+        }
+        
+        if (fival_head == NULL) {
+            RK29CAMERA_TR("%s: %s is not registered in rk29_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
+            ret = -EINVAL;
+            goto rk29_camera_enum_frameintervals_end;
         }
+        
         i = 0;
         while (fival_head->width && fival_head->height) {
             if ((fival->pixel_format == fival_head->pixel_format)
@@ -1826,20 +1874,20 @@ int rk29_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_f
 
         if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
             memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
-            RK29CAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(&rk29_camdev_info_ptr->icd->dev),
+            RK29CAMERA_DG("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(rk29_camdev_info_ptr->icd->pdev),
                 fival->width, fival->height,
                 fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
                             fival->discrete.denominator,fival->discrete.numerator);                        
         } else {
             if (index == 0)
-                RK29CAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(&rk29_camdev_info_ptr->icd->dev),
+                RK29CAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(rk29_camdev_info_ptr->icd->pdev),
                     fival->width,fival->height, 
                     fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
                            index);
             else
-                RK29CAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(&rk29_camdev_info_ptr->icd->dev),
+                RK29CAMERA_DG("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(rk29_camdev_info_ptr->icd->pdev),
                     fival->width,fival->height, 
                     fival->pixel_format & 0xFF, (fival->pixel_format >> 8) & 0xFF,
                            (fival->pixel_format >> 16) & 0xFF, (fival->pixel_format >> 24),
@@ -1847,7 +1895,7 @@ int rk29_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_f
             ret = -EINVAL;
         }
     }
-
+rk29_camera_enum_frameintervals_end:
     return ret;
 }
 
@@ -1968,7 +2016,9 @@ static int rk29_camera_probe(struct platform_device *pdev)
     int irq,i;
     int err = 0;
 
-    RK29CAMERA_DG("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
+    RK29CAMERA_TR("RK29 Camera driver version: v%d.%d.%d\n",(RK29_CAM_VERSION_CODE&0xff0000)>>16,
+        (RK29_CAM_VERSION_CODE&0xff00)>>8,RK29_CAM_VERSION_CODE&0xff);
+    
     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
     irq = platform_get_irq(pdev, 0);
     if (!res || irq < 0) {
@@ -2230,4 +2280,3 @@ module_exit(rk29_camera_exit);
 MODULE_DESCRIPTION("RK29 Soc Camera Host driver");
 MODULE_AUTHOR("ddl <ddl@rock-chips>");
 MODULE_LICENSE("GPL");
-#endif
old mode 100755 (executable)
new mode 100644 (file)
index 44dc74e..cfe412a
@@ -19,8 +19,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
 #include <linux/delay.h>
 #include "s5k6aa.h"
 static int debug;
@@ -55,11 +54,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480
 #define SENSOR_MAX_WIDTH    1280
 #define SENSOR_MAX_HEIGHT   1024
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -81,6 +79,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -107,7 +110,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_AF_MODE_CLOSE       5
 #endif
 
-/* init 800*600 SVGA */
+/* init 640X480 SVGA */
 static struct reginfo sensor_init_data[] =
 {
        {0x0010,0x0001},        // Reset
@@ -3307,13 +3310,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
 
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
@@ -3322,63 +3318,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret;
+    u16 pid = 0;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        sensor_ioctrl(icd,Sensor_Reset, 1);
@@ -3426,7 +3368,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;
     }
 
-    ret = sensor_write_array(client, sensor_init_data_p);
+    ret = sensor_write_array(client, sensor_init_data);
     if (ret != 0)
     {
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());
@@ -4663,22 +4605,20 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
                }
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                if (sensor->sensor_io_request->gpio_res[0].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[0].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[0];
+                } else if (sensor->sensor_io_request->gpio_res[1].dev_name && 
+                    (strcmp(sensor->sensor_io_request->gpio_res[1].dev_name, dev_name(icd->pdev)) == 0)) {
+                    sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[1];
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
old mode 100644 (file)
new mode 100755 (executable)
index e354db5..0827afe
@@ -19,9 +19,7 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>\r
 #include <media/v4l2-chip-ident.h>\r
 #include <media/soc_camera.h>\r
-#include <plat/rk_camera.h>\r
-#include <linux/vmalloc.h>\r
-\r
+#include <mach/rk29_camera.h>\r
 \r
 static int debug;\r
 module_param(debug, int, S_IRUGO|S_IWUSR);\r
@@ -52,12 +50,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   144\r
 #define SENSOR_MAX_WIDTH    1600\r
 #define SENSOR_MAX_HEIGHT   1200\r
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */\r
-#define SENSOR_INIT_HEIGHT     sensor_init_height\r
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p\r
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode\r
-#define SENSOR_BUS_PARAM  sensor_init_busparam\r
-\r
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */\r
+#define SENSOR_INIT_HEIGHT  480\r
+#define SENSOR_INIT_WINSEQADR sensor_vga\r
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8\r
 \r
 #define CONFIG_SENSOR_WhiteBalance 1\r
 #define CONFIG_SENSOR_Brightness       0\r
@@ -77,6 +73,9 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0\r
 #define CONFIG_SENSOR_I2C_RDWRCHK   0\r
 \r
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\\r
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW|\\r
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)\r
 \r
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500\r
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000\r
@@ -1675,13 +1674,6 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:\r
        return ret;\r
 }\r
-static s32 sensor_init_width = 640;\r
-static s32 sensor_init_height = 480;\r
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);\r
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;\r
-static struct reginfo* sensor_init_data_p = NULL;\r
-static struct reginfo* sensor_init_winseq_p = NULL;\r
-static struct reginfo* sensor_init_winseq_board = NULL;\r
 static int sensor_init(struct v4l2_subdev *sd, u32 val)\r
 {\r
     struct i2c_client *client = v4l2_get_subdevdata(sd);\r
@@ -1689,62 +1681,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);\r
        const struct v4l2_queryctrl *qctrl;\r
     const struct sensor_datafmt *fmt;\r
-    int ret,pid = 0,i = 0,j=0;\r
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;\r
-    sensor_init_data_p = sensor_init_data;\r
-       sensor_init_winseq_p = sensor_vga;\r
-       sensor_init_width = 640;\r
-       sensor_init_height = 480;\r
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { \r
-               for(i = 0;i < RK_CAM_NUM;i++){\r
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&\r
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))\r
-                                       break;\r
-                       }\r
-               }\r
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){\r
-       //user has defined the init data\r
-               //init reg\r
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){\r
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){\r
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;\r
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;\r
-                               }\r
-                       sensor_init_data_p = sensor_init_data;\r
-                       }\r
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){\r
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);\r
-                       }\r
-               //init winseq\r
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){\r
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;\r
-                       if(sensor_init_winseq_board)\r
-                               {\r
-                               vfree(sensor_init_winseq_board);\r
-                               sensor_init_winseq_board = NULL;\r
-                               }\r
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);\r
-                       if(!sensor_init_winseq_board)\r
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);\r
-                       for(j = 0;j< tmp_winseq_size;j++){\r
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;\r
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;\r
-                               }\r
-                       sensor_init_winseq_p = sensor_init_winseq_board;\r
-                       }\r
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){\r
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);\r
-                       }\r
-               //init width,height,bus,pixelcode\r
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)\r
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;\r
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)\r
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;\r
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)\r
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;\r
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)\r
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;\r
-       }\r
+    int ret;\r
 \r
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);\r
 \r
@@ -1805,7 +1742,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
         goto sensor_INIT_ERR;\r
     }\r
 #endif\r
-    ret = sensor_write_array(client, sensor_init_data_p);\r
+    ret = sensor_write_array(client, sensor_init_data);\r
     if (ret != 0)\r
     {\r
         SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING());\r
@@ -2193,7 +2130,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);\r
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;\r
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -2211,7 +2148,57 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
         mf->width = SENSOR_MAX_WIDTH;
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
-
+\r
+    set_w = mf->width;
+    set_h = mf->height;
+\r
+       if (((set_w <= 176) && (set_h <= 144)) &&( sensor_qcif[0].reg!=0xff))\r
+       {\r
+        set_w = 176;\r
+        set_h = 144;\r
+       }\r
+       else if (((set_w <= 320) && (set_h <= 240)) && (sensor_qvga[0].reg!=0xff))\r
+    {\r
+        set_w = 320;\r
+        set_h = 240;\r
+    }\r
+    else if (((set_w <= 352) && (set_h<= 288)) && (sensor_cif[0].reg!=0xff))\r
+    {\r
+        set_w = 352;\r
+        set_h = 288;\r
+    }\r
+    else if (((set_w <= 640) && (set_h <= 480)) &&( sensor_vga[0].reg!=0xff))\r
+    {\r
+        set_w =640;\r
+        set_h = 480;\r
+    }\r
+    else if (((set_w <= 800) && (set_h <= 600)) && (sensor_svga[0].reg!=0xff))\r
+    {\r
+        set_w = 800;\r
+        set_h = 600;\r
+    }\r
+       else if (((set_w <= 1024) && (set_h <= 768)) &&( sensor_xga[0].reg!=0xff))\r
+    {\r
+        set_w = 1024;\r
+        set_h = 768;\r
+    }\r
+    else if (((set_w <= 1280) && (set_h <= 1024)) && (sensor_sxga[0].reg!=0xff))\r
+    {\r
+        set_w = 1280;\r
+        set_h = 1024;\r
+    }\r
+    else if (((set_w <= 1600) && (set_h <= 1200)) && (sensor_uxga[0].reg!=0xff))\r
+    {\r
+        set_w = 1600;\r
+        set_h = 1200;\r
+    }\r
+    else\r
+    {\r
+        set_w = SENSOR_INIT_WIDTH;\r
+        set_h = SENSOR_INIT_HEIGHT;            \r
+    }\r
+    mf->width = set_w;
+    mf->height = set_h;  \r
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2982,22 +2969,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 \r
                case RK29_CAM_SUBDEV_IOREQUEST:\r
                {\r
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       \r
-                       if (sensor->sensor_io_request != NULL) { \r
-                       int j = 0;\r
-                       for(j = 0;j < RK_CAM_NUM;j++){\r
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && \r
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {\r
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];\r
-                               break;\r
-                                         } \r
-                       }\r
-                       if(j == RK_CAM_NUM){\r
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);\r
-                               ret = -EINVAL;\r
-                               goto sensor_ioctl_end;\r
-                               }\r
-                               }\r
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           \r
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }\r
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control \r
                for this project */\r
             #if CONFIG_SENSOR_Flash    \r
@@ -3151,4 +3141,4 @@ module_exit(sensor_mod_exit);
 \r
 MODULE_DESCRIPTION(SENSOR_NAME_STRING(Camera sensor driver));\r
 MODULE_AUTHOR("ddl <kernel@rock-chips>");\r
-MODULE_LICENSE("GPL");
\ No newline at end of file
+MODULE_LICENSE("GPL");\r
index 13bd16538e470a618d4139fcb08c64ea447f74b4..bfea1e0d6827bddf747f09872a71fadbb682acb7 100755 (executable)
@@ -20,8 +20,8 @@ o* Driver for MT9M001 CMOS Image Sensor from Micron
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
-#include <plat/rk_camera.h>
-#include <linux/vmalloc.h>
+#include <mach/rk29_camera.h>
+
 static int debug;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
@@ -51,11 +51,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define SENSOR_MIN_HEIGHT   480//144
 #define SENSOR_MAX_WIDTH    640
 #define SENSOR_MAX_HEIGHT   480
-#define SENSOR_INIT_WIDTH      sensor_init_width                       /* Sensor pixel size for sensor_init_data array */
-#define SENSOR_INIT_HEIGHT     sensor_init_height
-#define SENSOR_INIT_WINSEQADR  sensor_init_winseq_p
-#define SENSOR_INIT_PIXFMT sensor_init_pixelcode
-#define SENSOR_BUS_PARAM  sensor_init_busparam
+#define SENSOR_INIT_WIDTH      640                     /* Sensor pixel size for sensor_init_data array */
+#define SENSOR_INIT_HEIGHT  480
+#define SENSOR_INIT_WINSEQADR sensor_vga
+#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8
 
 #define CONFIG_SENSOR_WhiteBalance     0
 #define CONFIG_SENSOR_Brightness       0
@@ -75,6 +74,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CONFIG_SENSOR_I2C_NOSCHED   0
 #define CONFIG_SENSOR_I2C_RDWRCHK   0
 
+#define SENSOR_BUS_PARAM  (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |\
+                          SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |\
+                          SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ)
+
 #define COLOR_TEMPERATURE_CLOUDY_DN  6500
 #define COLOR_TEMPERATURE_CLOUDY_UP    8000
 #define COLOR_TEMPERATURE_CLEARDAY_DN  5000
@@ -1454,13 +1457,7 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd
 sensor_power_end:
        return ret;
 }
-static s32 sensor_init_width = 640;
-static s32 sensor_init_height = 480;
-static unsigned long sensor_init_busparam = (SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING|SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8  |SOCAM_MCLK_24MHZ);
-static enum v4l2_mbus_pixelcode sensor_init_pixelcode = V4L2_MBUS_FMT_YUYV8_2X8;
-static struct reginfo* sensor_init_data_p = NULL;
-static struct reginfo* sensor_init_winseq_p = NULL;
-static struct reginfo* sensor_init_winseq_board = NULL;
+
 static int sensor_init(struct v4l2_subdev *sd, u32 val)
 {
     struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -1468,63 +1465,8 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
     struct sensor *sensor = to_sensor(client);
        const struct v4l2_queryctrl *qctrl;
     const struct sensor_datafmt *fmt;
-    char value;
-    int ret,pid = 0,i = 0,j=0;
-       struct rk29camera_platform_data* tmp_plat_data =(struct rk29camera_platform_data*)val;
-    sensor_init_data_p = sensor_init_data;
-       sensor_init_winseq_p = sensor_vga;
-       sensor_init_width = 640;
-       sensor_init_height = 480;
-       if (tmp_plat_data != NULL && (u32)tmp_plat_data != 1) { 
-               for(i = 0;i < RK_CAM_NUM;i++){
-                       if ((tmp_plat_data->sensor_init_data[i])&& tmp_plat_data->info[i].dev_name &&
-                               (strcmp(tmp_plat_data->info[i].dev_name, dev_name(icd->pdev)) == 0))
-                                       break;
-                       }
-               }
-       if(tmp_plat_data  && ((u32)tmp_plat_data != 1) &&(i < RK_CAM_NUM) && tmp_plat_data->sensor_init_data[i]){
-       //user has defined the init data
-               //init reg
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       for(j = 0;j< sizeof(sensor_init_data)/sizeof(struct reginfo);j++){
-                               sensor_init_data[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].reg;
-                               sensor_init_data[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data[j].val;
-                               }
-                       sensor_init_data_p = sensor_init_data;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data){
-                       sensor_init_data_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_data);
-                       }
-               //init winseq
-               if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq && (sizeof(struct reginfo) != sizeof(struct reginfo_t))){
-                       int tmp_winseq_size = tmp_plat_data->sensor_init_data[i]->rk_sensor_winseq_size;
-                       if(sensor_init_winseq_board)
-                               {
-                               vfree(sensor_init_winseq_board);
-                               sensor_init_winseq_board = NULL;
-                               }
-                       sensor_init_winseq_board = (struct reginfo*)vmalloc(tmp_winseq_size);
-                       if(!sensor_init_winseq_board)
-                               SENSOR_TR("%s :vmalloc erro !",__FUNCTION__);
-                       for(j = 0;j< tmp_winseq_size;j++){
-                               sensor_init_winseq_board[j].reg = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].reg;
-                               sensor_init_winseq_board[j].val = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq[j].val;
-                               }
-                       sensor_init_winseq_p = sensor_init_winseq_board;
-                       }
-               else if(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq){
-                       sensor_init_winseq_p = (struct reginfo*)(tmp_plat_data->sensor_init_data[i]->rk_sensor_init_winseq);
-                       }
-               //init width,height,bus,pixelcode
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width != INVALID_VALUE)
-                       sensor_init_width = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_width;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height != INVALID_VALUE)
-                       sensor_init_height = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_height;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param != INVALID_VALUE)
-                       sensor_init_busparam = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_bus_param;
-               if(tmp_plat_data->sensor_init_data[i] && tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode != INVALID_VALUE)
-                       sensor_init_pixelcode = tmp_plat_data->sensor_init_data[i]->rk_sensor_init_pixelcode;
-       }
+    int ret, i;
+
     SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
 
        if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
@@ -1549,7 +1491,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
                
     // ret = sensor_write(client, sensor_init_data + i*2, sensor_init_data + i*2 + 1);
     // printk("write to reg[0x%x] 0x%x\n",sensor_init_data[i].reg,sensor_init_data[i].val);
-       ret = sensor_write(client, sensor_init_data_p[i].reg, sensor_init_data_p[i].val);
+       ret = sensor_write(client, sensor_init_data[i].reg, sensor_init_data[i].val);
     //ret = sensor_write_array(client, sensor_init_data);
        if (ret != 0)
        {
@@ -1872,7 +1814,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
     struct i2c_client *client = v4l2_get_subdevdata(sd);
     struct sensor *sensor = to_sensor(client);
     const struct sensor_datafmt *fmt;
-    int ret = 0;
+    int ret = 0,set_w,set_h;
    
        fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
                                   ARRAY_SIZE(sensor_colour_fmts));
@@ -1890,7 +1832,37 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
         mf->width = SENSOR_MAX_WIDTH;
     else if (mf->width < SENSOR_MIN_WIDTH)
         mf->width = SENSOR_MIN_WIDTH;
+    
+    set_w = mf->width;
+    set_h = mf->height;
 
+       if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg)
+       {
+        set_w = 176;
+        set_h = 144;
+       }
+       else if (((set_w <= 320) && (set_h <= 240)) && sensor_qvga[0].reg)
+    {
+        set_w = 320;
+        set_h = 240;
+    }
+    else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[0].reg)
+    {
+        set_w = 352;
+        set_h = 288;
+    }
+    else if (((set_w <= 640) && (set_h <= 480)) && sensor_vga[0].reg)
+    {
+        set_w = 640;
+        set_h = 480;
+    }
+    else
+    {
+        set_w = SENSOR_INIT_WIDTH;
+        set_h = SENSOR_INIT_HEIGHT;            
+    }
+    mf->width = set_w;
+    mf->height = set_h;  
     mf->colorspace = fmt->colorspace;
     
     return ret;
@@ -2665,23 +2637,25 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 
                case RK29_CAM_SUBDEV_IOREQUEST:
                {
-                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;                       
-                       if (sensor->sensor_io_request != NULL) { 
-                       int j = 0;
-                       for(j = 0;j < RK_CAM_NUM;j++){
-                                       if (sensor->sensor_io_request->gpio_res[j].dev_name && 
-                                               (strcmp(sensor->sensor_io_request->gpio_res[j].dev_name, dev_name(icd->pdev)) == 0)) {
-                                               sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[j];
-                               break;
-                                         } 
-                       }
-                       if(j == RK_CAM_NUM){
-                               SENSOR_TR("%s %s RK_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
-                               ret = -EINVAL;
-                               goto sensor_ioctl_end;
-                               }
-                               }
-                       
+                       sensor->sensor_io_request = (struct rk29camera_platform_data*)arg;           
+            if (sensor->sensor_io_request != NULL) { 
+                sensor->sensor_gpio_res = NULL;
+                for (i=0; i<RK29_CAM_SUPPORT_NUMS;i++) {
+                    if (sensor->sensor_io_request->gpio_res[i].dev_name && 
+                        (strcmp(sensor->sensor_io_request->gpio_res[i].dev_name, dev_name(icd->pdev)) == 0)) {
+                        sensor->sensor_gpio_res = (struct rk29camera_gpio_res*)&sensor->sensor_io_request->gpio_res[i];
+                    }
+                }
+                if (sensor->sensor_gpio_res == NULL) {
+                    SENSOR_TR("%s %s obtain gpio resource failed when RK29_CAM_SUBDEV_IOREQUEST \n",SENSOR_NAME_STRING(),__FUNCTION__);
+                    ret = -EINVAL;
+                    goto sensor_ioctl_end;
+                }
+            } else {
+                SENSOR_TR("%s %s RK29_CAM_SUBDEV_IOREQUEST fail\n",SENSOR_NAME_STRING(),__FUNCTION__);
+                ret = -EINVAL;
+                goto sensor_ioctl_end;
+            }
             /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control 
                for this project */
             #if CONFIG_SENSOR_Flash    
index 86ab89524d0609437370e19b3332bb702b0e49a2..8e7219337450f67f97a3e4e75ae960713d2c4866 100755 (executable)
@@ -1109,8 +1109,8 @@ static void scan_add_host(struct soc_camera_host *ici)
                if (icd->iface == ici->nr) {
                        int ret;
                        icd->dev.parent = ici->v4l2_dev.dev;
-                       dev_set_name(&icd->dev, "%u-%u", icd->iface,
-                                    icd->devnum);
+                       dev_set_name(&icd->dev, "%u-%u-%s", icd->iface,
+                                    icd->devnum,dev_name(icd->pdev));
                        ret = device_register(&icd->dev);
                        if (ret < 0) {
                                icd->dev.parent = NULL;
@@ -1185,8 +1185,6 @@ static int soc_camera_probe(struct device *dev)
        struct v4l2_mbus_framefmt mf;
        int ret;
 
-       dev_info(dev, "Probing %s\n", dev_name(dev));
-
        ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
                                 icl->regulators);
        if (ret < 0)
@@ -1278,7 +1276,7 @@ static int soc_camera_probe(struct device *dev)
        soc_camera_power_set(icd, icl, 0);
 
        mutex_unlock(&icd->video_lock);
-
+    dev_info(dev, "Probe %s success\n", dev_name(icd->pdev));
        return 0;
 
 evidstart:
@@ -1301,6 +1299,7 @@ eadd:
 epower:
        regulator_bulk_free(icl->num_regulators, icl->regulators);
 ereg:
+    dev_err(dev, "Probe %s failed\n", dev_name(icd->pdev));
        return ret;
 }
 
index ace5f99bbc4d9995f7bcadc4d9f002d4e91292fc..21280925452759decad512f22d0e260e1f160f18 100644 (file)
@@ -371,7 +371,7 @@ checks:
                                ((!list_empty(&queue->mainqueue)) || (!(queue->flags & UVC_QUEUE_STREAMING))));
                        mutex_lock(&queue->mutex);
 
-                       if (ret)
+                       if (ret || (!(queue->flags & UVC_QUEUE_STREAMING)))
                                goto done;
 
                        goto checks;
index 1c9a5163616773b5f07b5dad53701115967db39e..3e75d9c1d2f093be36c4a91bf85e980a137515ca 100755 (executable)
@@ -140,8 +140,8 @@ static int wm831x_i2c_resume(struct device *dev)
 void wm831x_i2c_shutdown(struct i2c_client *i2c)
 {
        struct wm831x *wm831x = i2c_get_clientdata(i2c);
-       printk("%s\n", __FUNCTION__);
-       wm831x_device_shutdown(wm831x);
+//     printk("%s\n", __FUNCTION__);
+//     wm831x_device_shutdown(wm831x);
 }
 
 static const struct i2c_device_id wm831x_i2c_id[] = {
index 1005847fbb14e9dd6eeae8ea8c42872fdfd9cae5..1dce22260ded57f8d68769f7b1a37ebe4ff4a26e 100755 (executable)
 #include <mach/gpio.h>
 #include <mach/iomux.h>
 
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+#include <sound/soc.h>
+#endif
+
 #if 0
 #define DBG(x...) printk(KERN_DEBUG x)
 #else
@@ -275,10 +279,16 @@ static const char *wm8958_main_supplies[] = {
 #ifdef CONFIG_PM
 static int wm8994_suspend(struct device *dev)
 {
-       struct wm8994 *wm8994 = dev_get_drvdata(dev);
+       struct wm8994 *wm8994 = dev_get_drvdata(dev);   
        int ret;
-       
-//     printk("on wm8994-core.c wm8994_suspend\n");
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND  
+       printk("on wm8994-core.c wm8994_suspend\n");
+       if(snd_soc_incall_status(0,0))
+       {
+               DBG("incalling  cannot suspend\n");
+               return 0;
+       }
+#endif
        /* Don't actually go through with the suspend if the CODEC is
         * still active (eg, for audio passthrough from CP. */
        ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
@@ -323,10 +333,16 @@ static int wm8994_suspend(struct device *dev)
 
 static int wm8994_resume(struct device *dev)
 {
-       struct wm8994 *wm8994 = dev_get_drvdata(dev);
+       struct wm8994 *wm8994 = dev_get_drvdata(dev);           
        int ret;
-       
-//     printk("on wm8994-core.c wm8994_resume\n");
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND  
+       printk("on wm8994-core.c wm8994_resume\n");
+       if(snd_soc_incall_status(0,0))
+       {
+               DBG("incalling cannot resume\n");
+               return 0;
+       }
+#endif
        /* We may have lied to the PM core about suspending */
        if (!wm8994->suspended)
                return 0;
index 6a613c29e0d156937eee8e8674b62902eb7c94f8..7391fa636e8a435ae193c1526baa0da44dcf2f67 100755 (executable)
@@ -21,6 +21,7 @@
 #include <linux/workqueue.h>
 #include <linux/mu509.h>
 #include <linux/slab.h>
+#include <linux/earlysuspend.h>
 
 MODULE_LICENSE("GPL");
 
@@ -43,7 +44,8 @@ struct rk29_mu509_data *gpdata = NULL;
 struct class *modem_class = NULL; 
 static int do_wakeup_irq = 0;
 static int modem_status;
-
+static int online = 0;
+int suspend_int =0;
 static void ap_wakeup_bp(struct platform_device *pdev, int wake)
 {
        struct rk29_mu509_data *pdata = pdev->dev.platform_data;
@@ -55,8 +57,12 @@ extern void rk28_send_wakeup_key(void);
 
 static void do_wakeup(struct work_struct *work)
 {
-//    MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
-    //rk28_send_wakeup_key();
+      if(suspend_int)
+         {
+             gpio_set_value(gpdata->ap_wakeup_bp, 0);
+             suspend_int = 0;
+         }
+
 }
 
 static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
@@ -67,7 +73,7 @@ static irqreturn_t detect_irq_handler(int irq, void *dev_id)
         do_wakeup_irq = 0;
   //      MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
         wake_lock_timeout(&modem_wakelock, 10 * HZ);
-        schedule_delayed_work(&wakeup_work, HZ / 10);
+        schedule_delayed_work(&wakeup_work, 2*HZ);
     }
     return IRQ_HANDLED;
 }
@@ -77,6 +83,9 @@ int modem_poweron_off(int on_off)
   if(on_off)
   {
                MODEMDBG("------------modem_poweron\n");
+               gpio_set_value(pdata->bp_reset, GPIO_HIGH);
+               msleep(100);
+               gpio_set_value(pdata->bp_reset, GPIO_LOW);
                gpio_set_value(pdata->bp_power, GPIO_LOW);
                msleep(1000);
                gpio_set_value(pdata->bp_power, GPIO_HIGH);
@@ -89,9 +98,8 @@ int modem_poweron_off(int on_off)
   {
                MODEMDBG("------------modem_poweroff\n");
                gpio_set_value(pdata->bp_power, GPIO_LOW);
-               mdelay(2500);
                gpio_set_value(pdata->bp_power, GPIO_HIGH);
-               mdelay(2500);
+               msleep(2500);
                gpio_set_value(pdata->bp_power, GPIO_LOW);
   }
   return 0;
@@ -111,7 +119,7 @@ static int mu509_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int mu509_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long mu509_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct rk29_mu509_data *pdata = gpdata;
        //MODEMDBG("-------------%s\n",__FUNCTION__);
@@ -119,9 +127,9 @@ static int mu509_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        {
                case MU509_RESET:                                       
                        gpio_set_value(pdata->bp_reset, GPIO_HIGH);
-                       mdelay(100);
+                       msleep(100);
                        gpio_set_value(pdata->bp_reset, GPIO_LOW);
-                       mdelay(100);
+                       msleep(100);
                        gpio_set_value(pdata->bp_power, GPIO_LOW);
                        msleep(1000);
                        gpio_set_value(pdata->bp_power, GPIO_HIGH);
@@ -154,30 +162,30 @@ static struct miscdevice mu509_misc = {
        .name = MODEM_NAME,
        .fops = &mu509_fops
 };
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static ssize_t modem_status_read(struct class *cls, struct class_attribute *attr, char *_buf)
+#else
 static ssize_t modem_status_read(struct class *cls, char *_buf)
+#endif
 {
 
        return sprintf(_buf, "%d\n", modem_status);
        
 }
-
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static ssize_t modem_status_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
+#else
 static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _count)
+#endif
 {
-
-    printk("Read data from Android: %s\n", _buf);
-   struct rk29_mu509_data *pdata = gpdata;
-   int new_state = simple_strtoul(_buf, NULL, 16);
+    int new_state = simple_strtoul(_buf, NULL, 16);
    if(new_state == modem_status) return _count;
    if (new_state == 1){
      printk("%s, c(%d), open modem \n", __FUNCTION__, new_state);
-        //gpio_set_value(pdata->bp_power, GPIO_HIGH);
-           gpio_set_value(pdata->bp_reset, GPIO_HIGH);
-           mdelay(100);
-           gpio_set_value(pdata->bp_reset, GPIO_LOW);
-           modem_poweron_off(1);
+        modem_poweron_off(1);
    }else if(new_state == 0){
      printk("%s, c(%d), close modem \n", __FUNCTION__, new_state);
-     gpio_set_value(pdata->bp_power, GPIO_LOW);
+        modem_poweron_off(0);
    }else{
      printk("%s, invalid parameter \n", __FUNCTION__);
    }
@@ -185,6 +193,47 @@ static ssize_t modem_status_write(struct class *cls, const char *_buf, size_t _c
     return _count; 
 }
 static CLASS_ATTR(modem_status, 0777, modem_status_read, modem_status_write);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static ssize_t online_read(struct class *cls, struct class_attribute *attr, char *_buf)
+#else
+static ssize_t online_read(struct class *cls, char *_buf)
+#endif
+{
+       return sprintf(_buf, "%d\n", online);
+       
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
+static ssize_t online_write(struct class *cls, struct class_attribute *attr, const char *_buf, size_t _count)
+#else
+static ssize_t online_write(struct class *cls, const char *_buf, size_t _count)
+#endif
+{
+   int new_value = simple_strtoul(_buf, NULL, 16);
+   if(new_value == online) return _count;
+       online = new_value;
+    return _count; 
+}
+static CLASS_ATTR(online, 0777, online_read, online_write);
+static void rk29_early_suspend(struct early_suspend *h)
+{
+        printk("*********************509____suspend\n");
+                
+}
+static void rk29_early_resume(struct early_suspend *h)
+{
+        if(suspend_int)
+       {
+         printk("***************509____resume\n");
+        gpio_set_value(gpdata->ap_wakeup_bp, 0);
+        suspend_int = 0;
+       }
+}
+
+static struct early_suspend mu509_early_suspend = {
+                .suspend = rk29_early_suspend,
+                 .resume = rk29_early_resume,
+                 .level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1,
+         };
 static int mu509_probe(struct platform_device *pdev)
 {
        struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data;
@@ -195,12 +244,12 @@ static int mu509_probe(struct platform_device *pdev)
        pdata->dev = &pdev->dev;
        if(pdata->io_init)
                pdata->io_init();
-       gpio_set_value(pdata->bp_reset, GPIO_HIGH);
-       mdelay(100);
-       gpio_set_value(pdata->bp_reset, GPIO_LOW);
+       gpio_set_value(pdata->modem_power_en, GPIO_HIGH);
+       msleep(1000);
        modem_poweron_off(1);
        modem_status = 1;
        
+       register_early_suspend(&mu509_early_suspend);
        mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
        if(mu509_data == NULL)
        {
@@ -251,10 +300,12 @@ err2:
        return 0;
 }
 
-int mu509_suspend(struct platform_device *pdev)
+int mu509_suspend(struct platform_device *pdev, pm_message_t state)
 {
+       suspend_int = 1;
        do_wakeup_irq = 1;
        //MODEMDBG("-------------%s\n",__FUNCTION__);
+       if(!online)
        ap_wakeup_bp(pdev, 1);
        rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_GPIO1C1);
        //gpio_direction_output(RK29_PIN1_PC1, 1);
@@ -264,12 +315,16 @@ int mu509_suspend(struct platform_device *pdev)
 int mu509_resume(struct platform_device *pdev)
 {
        //MODEMDBG("-------------%s\n",__FUNCTION__);
-       ap_wakeup_bp(pdev, 0);
+       //ap_wakeup_bp(pdev, 0);
        rk29_mux_api_set(GPIO1C1_UART0RTSN_SDMMC1WRITEPRT_NAME, GPIO1H_UART0_RTS_N);
+       if(gpio_get_value(gpdata->bp_wakeup_ap))
+       {
+               schedule_delayed_work(&wakeup_work, 2*HZ);
+       }
        return 0;
 }
 
-void mu509_shutdown(struct platform_device *pdev, pm_message_t state)
+void mu509_shutdown(struct platform_device *pdev)
 {
        struct rk29_mu509_data *pdata = pdev->dev.platform_data;
        struct modem_dev *mu509_data = platform_get_drvdata(pdev);
@@ -280,6 +335,7 @@ void mu509_shutdown(struct platform_device *pdev, pm_message_t state)
        if(pdata->io_deinit)
                pdata->io_deinit();
        cancel_work_sync(&mu509_data->work);
+       gpio_free(pdata->modem_power_en);
        gpio_free(pdata->bp_power);
        gpio_free(pdata->bp_reset);
        gpio_free(pdata->ap_wakeup_bp);
@@ -306,6 +362,7 @@ static int __init mu509_init(void)
        
        modem_class = class_create(THIS_MODULE, "rk291x_modem");
        ret =  class_create_file(modem_class, &class_attr_modem_status);
+       ret =  class_create_file(modem_class, &class_attr_online);
        if (ret)
        {
                printk("Fail to class rk291x_modem.\n");
@@ -318,6 +375,7 @@ static void __exit mu509_exit(void)
        //MODEMDBG("-------------%s\n",__FUNCTION__);
        platform_driver_unregister(&mu509_driver);
        class_remove_file(modem_class, &class_attr_modem_status);
+       class_remove_file(modem_class, &class_attr_online);
 }
 
 module_init(mu509_init);
index 785f092e1c4d5320a5f9003cd8a3dd8352eef5a1..625973bcce534cd52ee2cb6f1799a6a2a7175868 100755 (executable)
@@ -79,7 +79,7 @@ int debug_level = 5;
 #define RK29_SDMMC_WAIT_DTO_INTERNVAL   4500  //The time interval from the CMD_DONE_INT to DTO_INT
 #define RK29_SDMMC_REMOVAL_DELAY        2000  //The time interval from the CD_INT to detect_timer react.
 
-#define RK29_SDMMC_VERSION "Ver.3.03 The last modify date is 2012-03-23,modifyed by XBW." 
+#define RK29_SDMMC_VERSION "Ver.3.03 The last modify date is 2012-03-23,modifyed by XBW."
 
 #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) 
 #define RK29_CTRL_SDMMC_ID   0  //mainly used by SDMMC
index 2f5a8fa1f6c5709fa6995cd54fe8975d36f8d68a..9df1e01d47d6688c9f23b071c74fac9dcb0ac846 100755 (executable)
@@ -19,9 +19,9 @@
  * V1.5 - Support RK2818 (Debug the Register Function) 
  */
 
-#define DEBUG
+//#define DEBUG
 
-//#define RK2818
+#define RK2818
 
 
 #include <linux/module.h>
@@ -622,7 +622,7 @@ static int dm9620_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->hard_header_len += DM_TX_OVERHEAD;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
 #ifdef RK2818   //harris 2010.12.27
-       dev->rx_urb_size = 8912; // ftp fail fixed
+       dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD+1;
 #else
        dev->rx_urb_size = 2048;//dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD+1; // ftp fail fixed
 #endif
index cd16b97f0d77099fa38540a6ca3e1867392fd40f..11281802b52524ab117fab3fc3b0410d094dfc91 100755 (executable)
@@ -421,7 +421,7 @@ static int sr9700_android_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &sr9700_android_ethtool_ops;
        dev->net->hard_header_len += QF_TX_OVERHEAD;
        dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
-       dev->rx_urb_size =4096;// dev->net->mtu + ETH_HLEN + QF_RX_OVERHEAD;
+       dev->rx_urb_size = dev->net->mtu + ETH_HLEN + QF_RX_OVERHEAD;
 
        dev->mii.dev = dev->net;
        dev->mii.mdio_read = sr9700_android_mdio_read;
index 81116da3988a26a8b77d4fe122bf02b3e613fcfb..2c635546475d5b4feb79576257642fac3fe6adb9 100644 (file)
 begin 644 core/rtw_ioctl_set.o
-M?T5,1@$!`0````````````$`*``!``````````````!4$```````!30`````
-M`"@`$``-``1`+>4`()#E(`!2XQ0``(H``%+C%```"@0PT.4@,$/B<S#OYEX`
-M4^,`0*"3!!"@DP8``)H*``#J!#"`X`$PT^<@,$/B<S#OYEX`4^,$``"*`4"$
-MXG1`[^8$`%+A]?__B@$``.H`0*#C````Z@%`H.,$`*#A$`"]Z![_+^$00"WI
-M`#"@X00@D>4-$=+C$P``&@$#$N,'```:!CN`XAPP@^(#(`+B`@*#X``0H.,0
-M(*#C_O__ZPD``.I7#8#B*`"`XN`0@^+^___K`$!0X@,```H1#H3B`!"@XQ`@
-MH./^___K`0"@XQ"`O>AP0"WI`4"@X0%@H.$`4*#A`0!PX@``H#.A#Y#A%0``
-M&@,`4>,3``"*7PV%X@0`@.(!`H#@`!"@XQ`@H./^___K!0"@X5X=A>(X$('B
-M!""@X0`PH./^___K!DR$X@11A>`$4(7B`#"@XP`PA>4#0%#@`4"@$P```.H`
-M0*#C!`"@X7"`O>AP0"WI`$"@X0%0H.$$8)'E`V'&XP0`5N,`0*##(```R@@P
-MD>4%`%/C`2"@`[PW`0,#((0'!@``"@T`4^,`(*`3O#<!$P,@A!<%(*`#O#<!
-M`P,@A`=?#X;B``*$X`0`@.(,$(7B"""5Y?[__^L&/(;B`S&$X`@@E>4$((/E
-M7SV@XP-@A.<$`*#A7AV$XC@0@>(&(*#A`3"@X_[__^L`0%#B`4"@$P0`H.%P
-M@+WH\$<MZ0C03>(`0*#A`5"@X00PD>4``%/C`@``N@$!$^,N```*00$`Z@$!
-M$^,K```*5PV`XB@`@.+@$(3B_O__ZP!@4.($```*N#<!XP,PE.<"`%/C[&"6
-M!0$```J\-P'C`V"4YP0PU>4``%/C+P$`&@PPE>4!`'/C,`$`&K`AU>'_/P_C
-M`P!2X2P!`!HG`0#J"#"5Y2``4^,D`0`:3```Z@0`5N,)```:"#"5Y1``4^,&
-M```*(`!3XQP!`!H0,*#C"#"%Y0!PH.,'@*#A1```Z@4`5N,!`%83%`$`"CP`
-M`.H@.P'C`S"4YP,`4^,3``"*%#@!XP,PE.<``%/C#P``&@@PE>4%`%/C`2"@
-M`[PW`0,#((0'!@``"@T`4^,`(*`3O#<!$P,@A!<%(*`#O#<!`P,@A`>\-P'C
-M`V"4YP$``.H4.`'C`V"4YVPPE.4@`!/C!@``"@PPE>4!`'/C\P``&K`AU>'_
-M/P_C`P!2X>\``!H"`%;C`P``&@@PE>4@`%/CZ@``&@@``.H$`%;C!@``&@@P
-ME>40`%/C(`!3$^,``!H@`%/C$#"@`P@PA04$<)7EUWW@YVPPE.4@`!/C!P``
-M"@$`$^,!<*`3!X"@$0,```H#``#J`'"@XP>`H.$```#J`8"@X[@W`>,#,)3G
-M`@!3XR0```H%`%;C`0!6$R$``!H(()7E("""XJ`^`>,#((3G!&"5Y0)AQN.D
-M/@'C`V"$YP@@E>6H/@'C`R"$YR!PA>)ZC83B+`"(X@<0H.$(()7E_O__ZU\/
-MAN(``H3@!`"`X@<0H.$(()7E_O__ZP8\AN(#,83@"""5Y00@@^5?/:#C`V"$
-MYP0`H.$@$(CB_O__ZP%`H..J``#J!#"5Y0("$^,;```*`0!8XPP``!K8`<7A
-M`"#@X_\_#^,`(`+@`3`#X`@0C>+X(&'A8PV$XB@`@.(-$*#A"""@X_[__^L.
-M``#JV`'%X0`@X./_/P_C`"`"X`$P`^`($(WB^"!AX6,-A.(@`(#B#1"@X0@@
-MH./^___K4```Z@$`6.-.```:`0!7XP0@U048.`$#`R"$!P0PE>4#`!/C@0``
-M"@9KA.(<8(;B`S`#X@,"AN``$*#C$""@X_[__^MA?83B''"'X@0`U>4#``#B
-M``*'X``0H.,0(*#C_O__ZV*-A.(<@(CB!`#5Y0,``.(``HC@`!"@XQ`@H./^
-M___K!#"5Y0$"$^,+```*`S`#X@,"A^`P$(7B"""@X_[__^L$`-7E`P``X@`"
-MB.`X$(7B"""@X_[__^L*``#J`S`#X@,"A^`X$(7B"""@X_[__^L$`-7E`P``
-MX@`"B.`P$(7B"""@X_[__^L$`-7E`P``X@`"AN`@$(7B"""5Y?[__^L$,)7E
-M`S`#X@0PA>4!,*#C$"L!XP(PQ.<`$*#C$BL!XP(0Q.<$`*#A7AV$XC@0@>($
-M()7E_O__ZP!`4.(!0*`3.@``ZE<-A.(H`(#BX!"$XO[__^L`@%#B`4"@`S,`
-M``H1KHCB"@"@X0`0H.,0(*#C_O__ZR"0A>(*`*#A"1"@X1`@H./^___K`@!6
-MXQ8``!H`(*#C$3L!XP,@Q.<$,)7E`0(3XP@```KP`(CB$!")X@@@H./^___K
-M`0R(XA@0B>(((*#C_O__ZP<``.KP`(CB&!")X@@@H./^___K`0R(XA`0B>((
-M(*#C_O__ZP``5^,%```*!`"@X0@0H.$`(*#C_O__ZP!`H.$$``#J!`"@X0@0
-MH.$!(*#C_O__ZP!`H.$`0%3B`4"@$P```.H`0*#C!`"@X0C0C>+PA[WH`@!6
-MX]7^_QK0_O_J$$`MZ5Y-@.(X0(3B(#L!XP,0@.<#`%'C`B"@@[@W`8,#(("'
-M!!"@X?[__^L!`%#C``"@$P$`H`,0@+WH<$`MZ2C03>(`0%#B'@``"ITU`^,#
-M,-3G``!3XQH```IL,)3E(@T3XQD``!H4-=3E`0!3XQ8```K^___K#3"@X7]M
-MP^,_8,;C!#"6Y0$P@^($,(;E!%"-X@4`H.$`$*#C)""@X_[__^L$`*#A!1"@
-MX?[__^L`0*#A!#"6Y0$P0^($,(;E_O__ZP(``.H`0*#C````Z@%`H.,$`*#A
-M*-"-XG"`O>@00"WI`$"@X?[__^L-(*#A?SW"XS\PP^,$()/E`2""X@0@@^5L
-M,)3E`0`3XP4```H$`*#A_O__ZP0`H.'^___K!`"@X?[__^L-(*#A?SW"XS\P
-MP^,$()/E`2!"X@0@@^7^___K`0"@XQ"`O>AP0"WI`$"@X0%0H.$X,9#E`0!3
-MX3X```K^___K#2"@X7\]PN,_,,/C!""3Y0$@@N($((/E;#"4Y0$`$^,"```:
-M."&4Y0``4N,$```:!`"@X?[__^ML,)3E`0`3XP$``!I``!/C!```"@0`H.'^
-M___K;#"4Y0$`$^,$```:.#&4Y0$`4^,!```*``!3XP$``!H$`*#A_O__ZS@Q
-ME.4$`%/C`P``&@`PX./8,(3E!`"@X?[__^LX483E;#"4Y7@PP^-L,(3E`0!5
-MXP@P@P-L,(0%"```"B`P@S-L,(0U!0``.@0`5>,#```:$#"#XVPPA.4$`*#A
-M_O__ZPT@H.%_/<+C/S##XP0@D^4!($+B!""#Y?[__^L!`*#C<("]Z'!`+>D`
-M0*#AA%"0Y0$PX./8,(#E;#"0Y8`P@^-L,(#E>%"`Y0$PH.-P,,#EA`"`XO[_
-M_^L!`%#C#0``&FPPE.6`,,/C;#"$Y10UU.4``%/C`@``"G$PU.4``%/C/```
-M"@0`H.&4$(3B_O__ZP!`H.$X``#J;`"$XO[__^L!`%#C"P``&@`PH.-P,,3E
-M`#``XP`P0.,`$)/E10Z$X@@`@.*B'X'B`A"!XO[__^L!0*#C*```ZFPPE.4@
-M`!/C%P``"D`PH.-L,(3EJ6V$XCU0AN(%`*#A`!"@XR0@H./^___K!0"@X900
-MA.(D(*#C_O__ZP0`H.'^___K-0"&XO[__^L$`*#A_O__ZP$`4.,`0*`3`#"@
-M`W`PQ`4!0*`##0``ZH`PP^-L,(3E%#74Y0``4^,"```*<3#4Y0``4^,$```*
-M!`"@X900A.+^___K`$"@X0```.H!0*#C!`"@X7"`O>CP02WI`%"@X0%PH.&=
-M-0/C`S#0YP``4^,`0*`#;P``"FPPD.6``!/C`4"@$VL``!H""Q/C:P``&A``
-M`.IL,)7E`@L3XP4```H&`*#A_O__ZP%`1.(!`'3C]___&@$``.H``%3C!0``
-MRHP!G^6,$9_E_O__ZVQ`E>740^#G4```ZO[__^L-(*#A?SW"XS\PP^,$()/E
-M`2""X@0@@^5L,)7E00`3XS,```J4()7E`#"7Y0,`4N$A```:F`"%X@00A^+^
-M___K`0!0XQP``!IL,)7E"``3XQ0``!H%`*#AP!"%XO[__^L``%#C`4"@$S0`
-M`!H%`*#A_O__ZVPPE>4!`!/C`0``"@4`H.'^___K!0"@X?[__^ML,)7E0``3
-MXT`PPQ,@,(,3;#"%%1(``.H%`*#A`1"@XP$@H.'^___K#0``Z@4`H.'^___K
-M;#"5Y0$`$^,!```*!0"@X?[__^L%`*#A_O__ZVPPE>5``!/C0###$R`P@Q-L
-M,(45&#8"XP,PU><!`%/C#0``"@<`H.'^___K``!0XPD```J4`(7B!Q"@X20@
-MH./^___K`#"@XXPTA>4%`*#A_O__ZP!`H.$```#J`$"@XPT@H.%_/<+C/S##
-MXP0@D^4!($+B!""#Y?[__^L$`*#A\(&]Z&0`H./^___K,$"@XV1@H../___J
-M``````````!P0"WI`$"@X0%0H.$`,-'E``!3XP\``!H!(-'E``!2XPP``!H"
-M,-'E``!3XQH``!H#,-'E``!3XQ<``!H$,-'E``!3XQ0``!H%,-'E``!3XQ$`
-M`!I'``#J_P!3XPX``!H!,-7E_P!3XPL``!H",-7E_P!3XP@``!H#,-7E_P!3
-MXP4``!H$,-7E_P!3XP(``!H%,-7E_P!3XS8```K^___K#2"@X7\]PN,_,,/C
-M!""3Y0$@@N($((/E;#"4Y2(-$^/30^`7(P``&D$`$^,8```*X`"$X@40H.$&
-M(*#C_O__ZP$`4.,$```:;#"4Y0@`$^,!0*`#%P``"@T``.H$`*#A_O__ZVPP
-ME.4!`!/C`0``"@0`H.'^___K!`"@X?[__^ML,)3E0``3XT`PPQ,@,(,3;#"$
-M%;@`A.(%$*#A!B"@X_[__^L!,*#CC#2$Y00`H.'^___K`$"@X0T@H.%_/<+C
-M/S##XP0@D^4!($+B!""#Y?[__^L```#J`$"@XP0`H.%P@+WH`````+"PH(!\
-M````L+"H@.@```"PL*J`;`$``+"PJH`8`@``L*X!@&0'``"PL*B`H`<``+"J
-M"8!$"```L+"H@+`(``"PL*J`S`D``+"PJH`L"P``L+"L@#`-``"PL*J`<G1W
-M7W-E=%\X,#)?,3%?<W-I9``E<SH@4V5T(%-3240@:7,@;F]T(&%L;&]W960@
-M=6YD97(@<W5R=F5Y:6YG"@``````1T-#.B`H1TY5*2`T+C0N,`!!*@```&%E
-M86)I``$@````!3<M00`&"@=!"`$2!!0!%0$7`Q@!&0$:`AX!`"YS>6UT86(`
-M+G-T<G1A8@`N<VAS=')T86(`+G)E;"YT97AT`"YD871A`"YB<W,`+D%232YE
-M>'1A8@`N<F5L+D%232YE>&ED>``N<F]D871A`"YR;V1A=&$N<W1R,2XT`"YC
-M;VUM96YT`"YN;W1E+D=.52US=&%C:P`N05)-+F%T=')I8G5T97,`````````
-M```````````````````````````````````````````````?`````0````8`
-M````````-````+0.``````````````0`````````&P````D`````````````
-M``@:``"X`@``#@````$````$````"````"4````!`````P````````#H#@``
-M`````````````````0`````````K````"`````,`````````Z`X`````````
-M``````````$`````````,`````$````"`````````.@.````````````````
-M```!`````````#\````!``!P@@````````#H#@``8`````$`````````!```
-M```````[````"0``````````````P!P``&@````.````!@````0````(````
-M2@````$````"`````````$@/```4```````````````$`````````%(````!
-M````,@````````!<#P``,```````````````!`````$```!A`````0``````
-M````````C`\``!(```````````````$`````````:@````$`````````````
-M`)X/```````````````````!`````````'H````#``!P``````````">#P``
-M*P```````````````0`````````1`````P``````````````R0\``(H`````
-M``````````$``````````0````(``````````````-02```0!```#P```!H`
-M```$````$`````D````#``````````````#D%@``(P,``````````````0``
-M`````````````````````````````0``````````````!`#Q_P``````````
-M``````,``0`````````````````#``,``````````````````P`$`!$`````
-M`````````````0`````````````````#``4``````````````````P`&`!$`
-M``!\`````````````0`1````Z`````````````$`$0```&P!```````````!
-M`!$````8`@```````````0`1````9`<```````````$`$0```*`'````````
-M```!`!$```!$"````````````0`1````L`@```````````$`$0```,P)````
-M```````!`!$````L"P```````````0`4````*`T```````````$`$0```#`-
-M```````````!``````````````````,`"``7`````````!0````!``@`````
-M`````````````P`)``````````````````,`"P`````````````````#``H`
-M`````````````````P`,`"8`````````?````!(``0`X```````````````0
-M````3P```'P```!L````$@`!`&D``````````````!````!U````````````
-M```0````A0```.@```"$````$@`!`)\``````````````!````"K````;`$`
-M`*P````2``$`P@``````````````$````,X````8`@``3`4``!(``0#E````
-M```````````0````]P```&0'```\````$@`!`!H!`````````````!`````G
-M`0``H`<``*0````2``$`1@$`````````````$````%<!`````````````!``
-M``!J`0`````````````0````>@$``$0(``!L````$@`!`)8!````````````
-M`!````"G`0`````````````0````OP$`````````````$````-@!``"P"```
-M'`$``!(``0#[`0`````````````0````"`(`````````````$````!8"``#,
-M"0``8`$``!(``0`B`@`````````````0````,P(`````````````$````%H"
-M`````````````!````!B`@`````````````0````;`(`````````````$```
-M`)`"`````````````!````"I`@`````````````0````NP(``"P+```$`@``
-M$@`!`,\"`````````````!````#6`@`````````````0````W0(`````````
-M````$````.D"`````````````!````#Z`@`````````````0````#@,``#`-
-M``"$`0``$@`!``!R='=?:6]C=&Q?<V5T+F,`)&$`)&0`7U]F=6YC7U\N,SDP
-M-34`<G1W7W9A;&ED871E7W-S:60`7U]A96%B:5]U;G=I;F1?8W!P7W!R,`!R
-M='=?<V5T7S@P,E\Q,5]R96UO=F5?:V5Y`%]R='=?;65M<V5T`')T=U]G971?
-M<W1A:6YF;P!R='=?<V5T7S@P,E\Q,5]R96UO=F5?=V5P`')T=U]S971?:V5Y
-M`')T=U]S971?.#`R7S$Q7V%D9%]W97``7W)T=U]M96UC<'D`<G1W7W-E=%\X
-M,#)?,3%?861D7VME>0!R='=?<V5T<W1A:V5Y7V-M9`!R='=?<V5T7S@P,E\Q
-M,5]A=71H96YT:6-A=&EO;E]M;V1E`')T=U]S971?875T:`!R='=?<V5T7S@P
-M,E\Q,5]B<W-I9%]L:7-T7W-C86X`;&]C86Q?8FA?9&ES86)L90!R='=?<VET
-M97-U<G9E>5]C;60`;&]C86Q?8FA?96YA8FQE`')T=U]S971?.#`R7S$Q7V1I
-M<V%S<V]C:6%T90!R='=?9&ES87-S;V-?8VUD`')T=U]I;F1I8V%T95]D:7-C
-M;VYN96-T`')T=U]F<F5E7V%S<V]C7W)E<V]U<F-E<P!R='=?<V5T7S@P,E\Q
-M,5]I;F9R87-T<G5C='5R95]M;V1E`'-T;W!?87!?;6]D90!S=&%R=%]A<%]M
-M;V1E`')T=U]D;U]J;VEN`%]R='=?<75E=65?96UP='D`<G1W7W-E;&5C=%]A
-M;F1?:F]I;E]F<F]M7W-C86YN961?<75E=64`:FEF9FEE<P!M;V1?=&EM97(`
-M<G1W7W5P9&%T95]R96=I<W1R>7!R:79?9&5V7VYE='=O<FL`<G1W7V=E;F5R
-M871E7W)A;F1O;5]I8G-S`')T=U]C<F5A=&5B<W-?8VUD`')T=U]S971?.#`R
-M7S$Q7W-S:60`;7-L965P`'!R:6YT:P!?<G1W7VUE;6-M<`!R='=?:7-?<V%M
-M95]I8G-S`')T=U]L<'-?8W1R;%]W:U]C;60`<G1W7W-E=%\X,#)?,3%?8G-S
-M:60``+`````<'0``Q````!P>``#<````'!T``"0!```<'0``/`$``!P@``#4
-M`0``'"(```0"```<(```5`(``!P>``!8!```'"(``'`$```<(@``E`0``!PA
-M``#@!```'"(``!0%```<(@``6`4``!P=``!X!0``'!T``)@%```<'0``N`4`
-M`!PB``#0!0``'"(``.@%```<(@````8``!PB```8!@``'"(``%`&```<(```
-M;`8``!P>``",!@``'!T``*`&```<(@``T`8``!PB``#@!@``'"(``/0&```<
-M(@``!`<``!PB```<!P``'"0``#0'```<)```C`<``!PF``#8!P``'"@```0(
-M```<'0``$`@``!PI```D"```'"H``$P(```<*```>`@``!PL``"`"```'"T`
-M`(@(```<+@``I`@``!PJ``#("```'"@````)```<+```'`D``!PN``!$"0``
-M'"T``&`)```<,```I`D``!PQ``#`"0``'"H``/P)```<,P``-`H``!PI``!$
-M"@``'#0``%@*```K-0``7`H``"PU``!T"@``'#8``*@*```<'0``N`H``!PB
-M``#`"@``'#<``,@*```<.```T`H``!PY```4"P``'"D``'@+```<.P``G`L`
-M`!P\``"L"P``'"@``.P+```</0``#`P``!P^```@#```'"P``#0,```<+0``
-M/`P``!PN``!D#```'#\``'`,```<+```A`P``!PM``",#```'"X``+@,```<
-M&@``T`P``!PB``#@#```'#(```@-```<*@``&`T``!P[```H#0```A8``"P-
-M```"%```S`T``!PH```,#@``'#T``#`.```<+```1`X``!PM``!,#@``'"X`
-M`'`.```<(@``@`X``!PR``"@#@``'"H````````J`@`````````;```(````
-M*@(``!`````J`@``&````"H"```@````*@(``"@````J`@``,````"H"```X
-G````*@(``$`````J`@``2````"H"``!0````*@(``%@````J`@``
+M?T5,1@$!`0````````````$`*``!```````````````H$```````!30`````
+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
+M___K!0"@X900A.(D(*#C_O__ZP0`H.'^___K-0"&XO[__^L$`*#A_O__ZP$`
+M4.,``*`3`#"@`W`PQ`4!`*`#<("]Z(`PP^-L,(3E%#74Y0``4^,"```*<3#4
+MY0``4^,#```*!`"@X900A.+^___K<("]Z`$`H.-P@+WH\$$MZ0!0H.$!<*#A
+MG34#XP,PT.<``%/C`$"@`V\```IL,)#E@``3XP%`H!-K```:`@L3XVL``!H0
+M``#J;#"5Y0(+$^,%```*!@"@X?[__^L!0$3B`0!TX_?__QH!``#J``!4XP4`
+M`,J,`9_EC!&?Y?[__^ML0)7EU$/@YU```.K^___K#2"@X7\]PN,_,,/C!""3
+MY0$@@N($((/E;#"5Y4$`$^,S```*E""5Y0`PE^4#`%+A(0``&I@`A>($$(?B
+M_O__ZP$`4.,<```:;#"5Y0@`$^,4```:!0"@X<`0A>+^___K``!0XP%`H!,T
+M```:!0"@X?[__^ML,)7E`0`3XP$```H%`*#A_O__ZP4`H.'^___K;#"5Y4``
+M$^-`,,,3(#"#$VPPA142``#J!0"@X0$0H.,!(*#A_O__ZPT``.H%`*#A_O__
+MZVPPE>4!`!/C`0``"@4`H.'^___K!0"@X?[__^ML,)7E0``3XT`PPQ,@,(,3
+M;#"%%1@V`N,#,-7G`0!3XPT```H'`*#A_O__ZP``4.,)```*E`"%X@<0H.$D
+M(*#C_O__ZP`PH..,-(7E!0"@X?[__^L`0*#A````Z@!`H.,-(*#A?SW"XS\P
+MP^,$()/E`2!"X@0@@^7^___K!`"@X?"!O>AD`*#C_O__ZS!`H.-D8*#CC___
+MZ@``````````<$`MZ0!`H.$!4*#A`##1Y0``4^,/```:`2#1Y0``4N,,```:
+M`C#1Y0``4^,:```:`S#1Y0``4^,7```:!##1Y0``4^,4```:!3#1Y0``4^,1
+M```:1P``ZO\`4^,.```:`3#5Y?\`4^,+```:`C#5Y?\`4^,(```:`S#5Y?\`
+M4^,%```:!##5Y?\`4^,"```:!3#5Y?\`4^,V```*_O__ZPT@H.%_/<+C/S##
+MXP0@D^4!((+B!""#Y6PPE.4B#1/CTT/@%R,``!I!`!/C&```"N``A.(%$*#A
+M!B"@X_[__^L!`%#C!```&FPPE.4(`!/C`4"@`Q<```H-``#J!`"@X?[__^ML
+M,)3E`0`3XP$```H$`*#A_O__ZP0`H.'^___K;#"4Y4``$^-`,,,3(#"#$VPP
+MA!6X`(3B!1"@X08@H./^___K`3"@XXPTA.4$`*#A_O__ZP!`H.$-(*#A?SW"
+MXS\PP^,$()/E`2!"X@0@@^7^___K````Z@!`H.,$`*#A<("]Z`````"PL+"`
+M<````+"PJ(#<````L+"J@%P!``"PL*J`!`(``+"N`8!$!P``L+"H@(`'``"P
+MJ@F`)`@``+"PJ("0"```L+"J@*P)``"PL*J```L``+"PK(`$#0``L+"J@')T
+M=U]S971?.#`R7S$Q7W-S:60`)7,Z(%-E="!34TE$(&ES(&YO="!A;&QO=V5D
+M('5N9&5R('-U<G9E>6EN9PH``````$=#0SH@*$=.52D@-"XT+C``02H```!A
+M96%B:0`!(`````4W+4$`!@H'00@!$@04`14!%P,8`1D!&@(>`0`N<WEM=&%B
+M`"YS=')T86(`+G-H<W1R=&%B`"YR96PN=&5X=``N9&%T80`N8G-S`"Y!4DTN
+M97AT86(`+G)E;"Y!4DTN97AI9'@`+G)O9&%T80`N<F]D871A+G-T<C$N-``N
+M8V]M;65N=``N;F]T92Y'3E4M<W1A8VL`+D%232YA='1R:6)U=&5S````````
+M````````````````````````````````````````````````'P````$````&
+M`````````#0```"(#@`````````````$`````````!L````)````````````
+M``#<&0``N`(```X````!````!`````@````E`````0````,`````````O`X`
+M``````````````````$`````````*P````@````#`````````+P.````````
+M```````````!`````````#`````!`````@````````"\#@``````````````
+M`````0`````````_`````0``<((`````````O`X``&`````!``````````0`
+M````````.P````D``````````````)0<``!H````#@````8````$````"```
+M`$H````!`````@`````````<#P``%```````````````!`````````!2````
+M`0```#(`````````,`\``#````````````````0````!````80````$`````
+M`````````&`/```2```````````````!`````````&H````!````````````
+M``!R#P```````````````````0````````!Z`````P``<```````````<@\`
+M`"L```````````````$`````````$0````,``````````````)T/``"*````
+M```````````!``````````$````"``````````````"H$@``$`0```\````:
+M````!````!`````)`````P``````````````N!8``",#``````````````$`
+M``````````````````````````````$```````````````0`\?\`````````
+M```````#``$``````````````````P`#``````````````````,`!``1````
+M``````````````$``````````````````P`%``````````````````,`!@`1
+M````<`````````````$`$0```-P````````````!`!$```!<`0``````````
+M`0`1````!`(```````````$`$0```$0'```````````!`!$```"`!P``````
+M`````0`1````)`@```````````$`$0```)`(```````````!`!$```"L"0``
+M`````````0`1``````L```````````$`%````/P,```````````!`!$````$
+M#0```````````0`````````````````#``@`%P`````````4`````0`(````
+M``````````````,`"0`````````````````#``L``````````````````P`*
+M``````````````````,`#``F`````````'`````2``$`.```````````````
+M$````$\```!P````;````!(``0!I```````````````0````=0``````````
+M````$````(4```#<````@````!(``0"?```````````````0````JP```%P!
+M``"H````$@`!`,(``````````````!````#.````!`(``$`%```2``$`Y0``
+M````````````$````/<```!$!P``/````!(``0`:`0`````````````0````
+M)P$``(`'``"D````$@`!`$8!`````````````!````!7`0`````````````0
+M````:@$`````````````$````'H!```D"```;````!(``0"6`0``````````
+M```0````IP$`````````````$````+\!`````````````!````#8`0``D`@`
+M`!P!```2``$`^P$`````````````$`````@"`````````````!`````6`@``
+MK`D``%0!```2``$`(@(`````````````$````#,"`````````````!````!:
+M`@`````````````0````8@(`````````````$````&P"`````````````!``
+M``"0`@`````````````0````J0(`````````````$````+L"````"P``!`(`
+M`!(``0#/`@`````````````0````U@(`````````````$````-T"````````
+M`````!````#I`@`````````````0````^@(`````````````$`````X#```$
+M#0``A`$``!(``0``<G1W7VEO8W1L7W-E="YC`"1A`"1D`%]?9G5N8U]?+C,Y
+M,#8W`')T=U]V86QI9&%T95]S<VED`%]?865A8FE?=6YW:6YD7V-P<%]P<C``
+M<G1W7W-E=%\X,#)?,3%?<F5M;W9E7VME>0!?<G1W7VUE;7-E=`!R='=?9V5T
+M7W-T86EN9F\`<G1W7W-E=%\X,#)?,3%?<F5M;W9E7W=E<`!R='=?<V5T7VME
+M>0!R='=?<V5T7S@P,E\Q,5]A9&1?=V5P`%]R='=?;65M8W!Y`')T=U]S971?
+M.#`R7S$Q7V%D9%]K97D`<G1W7W-E='-T86ME>5]C;60`<G1W7W-E=%\X,#)?
+M,3%?875T:&5N=&EC871I;VY?;6]D90!R='=?<V5T7V%U=&@`<G1W7W-E=%\X
+M,#)?,3%?8G-S:61?;&ES=%]S8V%N`&QO8V%L7V)H7V1I<V%B;&4`<G1W7W-I
+M=&5S=7)V97E?8VUD`&QO8V%L7V)H7V5N86)L90!R='=?<V5T7S@P,E\Q,5]D
+M:7-A<W-O8VEA=&4`<G1W7V1I<V%S<V]C7V-M9`!R='=?:6YD:6-A=&5?9&ES
+M8V]N;F5C=`!R='=?9G)E95]A<W-O8U]R97-O=7)C97,`<G1W7W-E=%\X,#)?
+M,3%?:6YF<F%S=')U8W1U<F5?;6]D90!S=&]P7V%P7VUO9&4`<W1A<G1?87!?
+M;6]D90!R='=?9&]?:F]I;@!?<G1W7W%U975E7V5M<'1Y`')T=U]S96QE8W1?
+M86YD7VIO:6Y?9G)O;5]S8V%N;F5D7W%U975E`&II9F9I97,`;6]D7W1I;65R
+M`')T=U]U<&1A=&5?<F5G:7-T<GEP<FEV7V1E=E]N971W;W)K`')T=U]G96YE
+M<F%T95]R86YD;VU?:6)S<P!R='=?8W)E871E8G-S7V-M9`!R='=?<V5T7S@P
+M,E\Q,5]S<VED`&US;&5E<`!P<FEN=&L`7W)T=U]M96UC;7``<G1W7VES7W-A
+M;65?:6)S<P!R='=?;'!S7V-T<FQ?=VM?8VUD`')T=U]S971?.#`R7S$Q7V)S
+M<VED``"D````'!T``+@````<'@``T````!P=```8`0``'!T``#`!```<(```
+MQ`$``!PB``#T`0``'"```$`"```<'@``1`0``!PB``!<!```'"(``(`$```<
+M(0``S`0``!PB````!0``'"(``$0%```<'0``9`4``!P=``"$!0``'!T``*0%
+M```<(@``O`4``!PB``#4!0``'"(``.P%```<(@``!`8``!PB```\!@``'"``
+M`%@&```<'@``>`8``!P=``",!@``'"(``+P&```<(@``S`8``!PB``#@!@``
+M'"(``/`&```<(@``"`<``!PD```<!P``'"0``&P'```<)@``N`<``!PH``#D
+M!P``'!T``/`'```<*0``!`@``!PJ```L"```'"@``%@(```<+```8`@``!PM
+M``!H"```'"X``(0(```<*@``J`@``!PH``#@"```'"P``/P(```<+@``)`D`
+M`!PM``!`"0``'#```(0)```<,0``H`D``!PJ``#<"0``'#,``!0*```<*0``
+M(`H``!PT```T"@``*S4``#@*```L-0``4`H``!PV``"$"@``'!T``)0*```<
+M(@``G`H``!PW``"D"@``'#@``*P*```<.0``\`H``!PI``!,"P``'#L``'`+
+M```</```@`L``!PH``#`"P``'#T``.`+```</@``]`L``!PL```(#```'"T`
+M`!`,```<+@``.`P``!P_``!$#```'"P``%@,```<+0``8`P``!PN``",#```
+M'!H``*0,```<(@``M`P``!PR``#<#```'"H``.P,```<.P``_`P```(6````
+M#0```A0``*`-```<*```X`T``!P]```$#@``'"P``!@.```<+0``(`X``!PN
+M``!$#@``'"(``%0.```<,@``=`X``!PJ````````*@(`````````&P``"```
+M`"H"```0````*@(``!@````J`@``(````"H"```H````*@(``#`````J`@``
+H.````"H"``!`````*@(``$@````J`@``4````"H"``!8````*@(`````
 `
 end
index c1e0cb4792a1326e4f44202af6d6b90250e207f3..056ba49c786c5c4df922f75cc075989ec313d65e 100755 (executable)
@@ -1611,6 +1611,8 @@ void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr)
                DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __FUNCTION__, __LINE__,
                        preorder_ctrl->indicate_seq, start_seq);
                #endif
+               #else
+               preorder_ctrl->indicate_seq = 0xffff;
                #endif
                
                preorder_ctrl->enable =(pmlmeinfo->bAcceptAddbaReq == _TRUE)? _TRUE :_FALSE;
index 1a60a338e1b8d433c9d27e73310847fe64888d70..73baefce51218b0634f6a8b9fd4e25acbf5e074f 100644 (file)
 begin 644 os_dep/linux/ioctl_linux.o
-M?T5,1@$!`0````````````$`*``!```````````````L:@``````!30`````
+M?T5,1@$!`0````````````$`*``!``````````````!@:0``````!30`````
 M`"@`$0`.`#`P0.)S,._F"0!3XS``0)(>_R^183!`XG,P[^8%`%/C5P!`DA[_
-M+Y%!,$#B<S#OY@4`4^,``."#-P!`DA[_+^$$0"WE@$.0Y0,P`>(#`%/C"@``
-M&@`PH.,D*P'C`C"$YP(0H.,@*P'C`A"$YP,0H..X)P'C`A"$YP-`H.$<``#J
-M`@`1XPD```H`,*#C)"L!XP(PA.<!(*#C(!L!XP$@A.>X%P'C`2"$YP-`H.$0
-M``#J`0`1XPH```H@.P'C`S"4YP,`4^,)``"*`#"@XR`K`>,",(3GN"<!XP(P
-MA.<#0*#A`P``Z@0`$>,50.`#````"@!`H.,$`*#A$`"]Z![_+^$``*#C'O\O
-MX8`SD.5L,)/E"``3XP(PH!,`,((5"P``&D``$^,!```:(``3XP(```H!,*#C
-M`#""Y00``.H0`!/C`S"@$P`P@A4`,*`#`#""!0``H.,>_R_A!$`MY8!#D.5L
-M,)3E`0`3XP8```J*-0'CTS"4X0`P8^(`,(+E`#"@XP0PPN4$``#J`#"@XP`P
-M@N4$,,+E`3"@XP4PPN4``*#C$`"]Z![_+^$`,-#E``!3XP@```H!`%/A`P``
-M&@@``.H,`(#B`0!3X04```H,,-#E``!3X_G__QH``%/B`0"@$Q[_+^$!`*#C
-M'O\OX8`3D.58.@+CLS"1X0`P@N4``*#C!`#"Y1[_+^$$0"WE@$.0Y04PTN4`
-M`%/C!```"BHI`.,<-`'C`R"$YP``H.,(``#J`#"2Y0$<0^(J*`#C`@!1X14`
-MX(,!,,.3'"0!DP(PA)<``*"3$`"]Z![_+^&`$Y#E'#0!XP,PD><`,(+E``"@
-MXP0`PN4>_R_A!S"@XP`P@N4``*#C!`#"Y0$PH.,%,,+E'O\OX0``H.,``(+E
-M!`#"Y0$PH.,%,,+E'O\OX1!`+>D(T$WB@$.0Y0X`D^@`,(WE!`"@X?\_#^,/
-M,$#C:,4#XP_@H.$,\)3G``"@XPC0C>(0@+WH``#@XQ[_+^$``.#C'O\OX0``
-MH.,>_R_A``"@XQ[_+^$``*#C'O\OX0``H.,>_R_A<``MZ8!#D.4"8*#AB#4#
-MXP,0E.<!,'+B`#"@,P``4>,!,(,3``!3XQ5`X!,*```:`%"2Y0(`5>,`0*"#
-M!4&$D`0PMI4$,(25`#``DP`P0),`():5!2&#EP!`H),$`*#A<`"]Z![_+^$`
-M`*#C'O\OX0``H.,>_R_A``"@XQ[_+^$>_R_A'O\OX?!'+>D(T$WB`%"@X1,0
-MH.,'((WB,#4#XP_@H.$#\)#G!S#=Y0,`4^,``%,3`:"@`P*@H!,`8*#C!I"@
-MX61U`^,`@.#C"P``Z@4`H.$&$*#A!""@X0@PH.$/X*#A!_"5YP%`A.(!#%3C
-M]O__&@%@AN(*`%;A`0``J@E`H.'Q___J"-"-XO"'O>@``*#C'O\OX01`+>6`
-M0Y#E;#"4Y0$`$^,'```:`#"@XRHF`^,",,3G*R8#XP(PQ.<L)@/C`C#$YPL`
-M`.J,-0'C`Q#4YXXU`>,#(-3GBC4!X],`E.$K-@/C`P#$YRHV`^,#$,3G+#8#
-MXP,@Q.</(*#C+38#XP,@Q.<V#(3B*`"`XA``O>@>_R_A<$`MZ0-`H.&`4Y#E
-M!0"@X08`D^C_/P_C#S!`XV3%`^,/X*#A#/"5YP!0H.$$`*#A`!``XP`00.,%
-M(*#A_O__ZP``H.-P@+WH\$\MZ:G?3>("D*#A`V"@X8"SD.5J/0_C_S]/XP!`
-MH.,J+HWBLT""X6@]#^/_/T_CLT""X2(.C>($$*#A@""@X_[__^L@`(WB!!"@
-MX0(LH./^___K`!"9Y;1PV>$-P*#A?SW,XS\PP^,(4)/E!T"1X`5`U#``4*`S
-M``!5XP4``!H&`*#A!R"@X?[__^L``%#C<0$`&@8``.H``%?C!```"@8`H.$'
-M$*#A_O__ZPT`X.-L`0#J`$"@XPQ`C>400(WE%$"-Y1Q@C>4<<(WB`(``XP"`
-M0.,,H(WB!%"@X0,``.H,`%7C!@``"@5`BN<$4(7B!P"@X0@0H.'^___K`$!0
-MXO;__QH,0)WE!`"@X0`0`.,`$$#C_O__ZP``4.,\```:"P"@X0`0H..`(*#C
-M(CZ-XO[__^L!`%#C1P$`&@8`H.$`$*#C!""@X_[__^L&`*#A&!6?Y08@H.'^
-M___K`*"@XPRUG^4`@`#C`(!`XP8`H.$+$*#A!B"@X0HPH.'^___K(BZ-X@I0
-M@N`%<*#A`$"@XP8`H.$($*#A!B"@X0$PU^3^___K`4"$X@@`5./W__\:!@"@
-MX;P4G^4&(*#A_O__ZP8`H.$($*#A!B"@X0@PU>7^___K`4"$X@%0A>(0`%3C
-M]O__&@8`H.&,%)_E!B"@X?[__^L0H(KB@`!:X]K__QH&`*#A_O__Z[0`R>$`
-M`*#C%`$`Z@0`H.$`$`#C`!!`X_[__^L``%#C00``&A``G>4``%#C"@$`"A1`
-MG>4``%3C!P$`"AA0C>(%$*#A$""@X_[__^L`<*#A!`"@X040H.$*(*#C_O__
-MZW!0_^8``%7C^P``"G=P_^9J30_C_T]/XP`0H.,`$(WE"P"@X0,@H.,JSHWB
-M!#",X/[__^L%@*#A!S"%X"HNC>*T0)+A!`!3X>D``,H+`*#A!Q"@X04@H.$B
-M/HWB_O__ZP8`H.$`$*#C!""@X_[__^L`0*#CG%.?Y2)^C>*8HY_E"0``Z@8`
-MH.$%$*#A!B"@X00PU^?^___K!@"@X0H0H.$&(*#A_O__ZP%`A.((`%3A\___
-MN@8`H.'^___K`0"`XK0`R>$``*#CS```Z@0`H.$`$`#C`!!`X_[__^L``%#C
-M,```&B`PC>(`,(WE"P"@X0`0H.,!(*#A`CR@X_[__^L``%#CN@``"@8`H.$`
-M$*#C!""@X_[__^L`0*#C`%``XP!00.,@<(WB`*``XP"@0.,`@`#C`(!`XP8`
-MH.$%$*#A!B"@X00PU^?^___K#S`$X@\`4^,$```:!@"@X0@0H.$&(*#A_O__
-MZP8``.H',`3B!P!3XP,``!H&`*#A"A"@X08@H.'^___K`4"$X@(,5./H__\:
-M!@"@X?[__^NT`,GA``"@XY4``.H$`*#A`!``XP`00./^___K``!0XS```!H0
-M0)WE``!4XXL```H40)WE``!4XX@```IJ30_C_T]/XP`0H.,`$(WE"P"@X0,@
-MH.,JSHWB!#",X/[__^LJ+HWBM$"2X14`5.-Y``#:"P"@X180H.,&(*#C(CZ-
-MXO[__^L&`*#A`!"@XP0@H./^___K`%"@X]QQG^4B3HWBV(&?Y08`H.$'$*#A
-M!B"@X04PU.?^___K!@"@X0@0H.$&(*#A_O__ZP%0A>(&`%7C\___&@8`H.'^
-M___KM`#)X0``H.->``#J!`"@X0`0`.,`$$#C_O__ZP``4.,P```:$$"=Y0``
-M5.-4```*%$"=Y0``5.-1```*:DT/X_]/3^,`$*#C`!"-Y0L`H.$#(*#C*LZ-
-MX@0PC.#^___K*BZ-XK1`DN$)`%3C0@``V@L`H.$*$*#C!""@XR(^C>+^___K
-M!@"@X0`0H.,$(*#C_O__ZP!0H.,`<9_E(DZ-XOR`G^4&`*#A!Q"@X08@H.$%
-M,-3G_O__ZP8`H.$($*#A!B"@X?[__^L!4(7B!`!5X_/__QH&`*#A_O__Z[0`
-MR>$``*#C)P``Z@0`H.$`$`#C`!!`X_[__^L``%#C%```&FA-#^/_3T_C"P"@
-MX2H^C>($$(/@_O__ZPL`H.'^___K*LZ-XK1`G.$`,&3@!@"@X0`0`.,`$$#C
-M!B"@X?[__^L&`*#A_O__Z[0`R>$``*#C#```Z@8`H.$`$`#C`!!`XP8@H.'^
-M___K!@"@X?[__^NT`,GA``"@XP(``.H-`.#C````ZA4`X..IWXWB\(^]Z!0`
-M```<````,````#0```!`````3````/!!+>D(T$WB`X"@X8!SD.4"8*#A`#"@
-MXP0PC>4`$)+E#2"@X7\]PN,_,,/C"$"3Y010D>($4-4P`$"@,P``5.,#```:
-M!`"-X@0@H./^___K`@``Z@0`C>($$*#C_O__ZX@U`^,#,)?G`6!VX@!@H#,`
-M`%/C`6"&$P``5N,50.`3)@``&@1`G>4``%3C`##8!00PC04$,)WE`0!3XP@`
-M`!K$-`/C`S"7YP``4^,:```*!P"@X0D0H.,S_R_A`$"@XQ8``.H"`%/C"```
-M&L0T`^,#,)?G``!3XP\```H'`*#A"A"@XS/_+^$`0*#C"P``Z@,`4^,(```:
-MQ#0#XP,PE^<``%/C!```"@<`H.$,$*#C,_\OX0!`H.,```#J`$"@XP0`H.$(
-MT(WB\(&]Z/!%+>FIWTWB@*.0Y0!`H.,,0(WE$$"-Y11`C>5J+0_C_R]/XRH>
-MC>*R0('A'#"-Y1Q@C>(`<`#C`'!`XPR`C>(#``#J#`!4XP8```H$4(CG!$"$
-MX@8`H.$'$*#A_O__ZP!04.+V__\:#$"=Y00`H.$`$`#C`!!`X_[__^L``%#C
-M+P``&A``G>4``%#CO0``"A10G>4``%7CN@``"A@0C>(0(*#C_O__ZP"`H.$%
-M`*#A_O__ZZ!PL.$`8*`3(DZ-$K0```H$``#J`@!5Y0$05>7^___K!@#$YP%@
-MAN("4(7B!P!6X??__SIX4._F:DT/X_]/3^,`$*#C`!"-Y0H`H.$#(*#C*LZ-
-MX@0PC.#^___K!S"%X"H>C>*T0)'A!`!3X9P``(H*`*#A!1"@X7<@_^8B/HWB
-M_O__ZP``4..5```*D@``Z@0`H.$`$`#C`!!`X_[__^L``%#C(@``&A``G>4`
-M`%#CAP``"A10G>4``%7CA```"A@0C>(0(*#C_O__ZP"`H.$%`*#A_O__ZZ!P
-ML.$`8*`3($"-$GX```H$``#J`@!5Y0$05>7^___K!@#$YP%@AN("4(7B!P!6
-MX??__SH@,(WB`#"-Y0H`H.$!$*#C>"#OYG<P_^;^___K``!0XVP```II``#J
-M!`"@X0`0`.,`$$#C_O__ZP``4.,L```:$%"=Y0``5>->```*%$"=Y0``5.-;
-M```*!0"@X?[__^N@<+#A6P``"@8`5^,`8*"3(DZ-DE<``(H$``#J`@!5Y0$0
-M5>7^___K!@#$YP%@AN("4(7B!P!6X??__SIJ30_C_T]/XP`0H.,`$(WE"@"@
-MX0,@H.,JSHWB!#",X/[__^L6,(?B*AZ-XK1`D>$$`%/A0```B@H`H.$6$*#C
-M=R#_YB(^C>+^___K``!0XSD```HV``#J!`"@X0`0`.,`$$#C_O__ZP``4.,J
-M```:$$"=Y0``5.,K```*%%"=Y0``5>,H```*!`"@X?[__^N@<+#A*```"@10
-MH.$`8*#C(DZ-X@``U>4!$-7E_O__ZP8`Q.<!8(;B`E"%X@8`5^'W__^*:DT/
-MX_]/3^,`$*#C`!"-Y0H`H.$#(*#C*LZ-X@0PC.#^___K"C"'XBH>C>*T0)'A
-M!`!3X0\``(H*`*#A"A"@XW<@_^8B/HWB_O__ZP``4.,(```*!0``ZB0`G^7^
-M___K``"@XP0``.H5`.#C`@``Z@``H.,```#J#0#@XZG?C>+PA;WHQ````/!`
-M+>D4T$WB`D"@X8!CD.4`,`#C`#!`XP!0T^4``%7C"```&@-0H.$`,`#C`#!`
-MXP4`H.$`$)/E$""@X_[__^L`,*#C#S#%Y;0PU.$0`%/C4@``B@`0E.4-(*#A
-M?SW"XS\PP^,(4)/E$$"1X@5`U#``4*`S``!5XP4``!H-`*#A$""@X_[__^L`
-M`%#C!0``"D(``.H-`*#A$!"@X_[__^L-0.#C/@``Z@8`H.$-$*#A_O__ZP!`
-M4.(Y```:````XP``0.,`$`#C`!!`XPD@H./^___K`0!0XP@``!K,4)_E$'#5
-MY=,]H.,#<,;G!@"@X?[__^L14-7E83(#XP-0QN<`4`#C`%!`XPUPH.$%`*#A
-M#1"@X1`@H./^___K`#"@XP\PQ>4-`*#A`!``XP`00.,)(*#C_O__ZP$`4.,8
-M```:!@"@X0$0H./^___KQ#0#XP,PEN<``%/C`@``"@8`H.$'$*#C,_\OX0!0
-M`.,`4$#CTSV@XP,@UN<0(,7E`'"@XP-PQN<&`*#A_O__ZV$R`^,#(-;G$2#%
-MY0-PQN<```#J#4#@XP0`H.$4T(WB\("]Z``````00"WI<#(#XP,PD.?_-,/C
-M_S##XP$(4^,F```*9#(#XP,PT.<``%/C)```"G$R`^,#,-#G`0!3XP,``!I,
-M-@/C`S"0YP$`4^,:```*;#"0Y0$`$^,9```:N#(#XP,PD.<"`%/C%0``"K`R
-M`^,#,)#G``!3XQ$``!H`,`#C`#!`XP`PD^6H(@/C`B"0YV00H..1`@'@TRT$
-MXV(@0>.2P8'@R0V`XC0`@.(A$X/@_O__ZP%`H.,"``#J`$"@XP```.H!0*#C
-M!`"@X1"`O>CP02WI"-!-X@!@H.$"4*#A`T"@X0,`H.$`$`#C`!!`XP0@H./^
-M___K``!0XR<```JT(-7A!"!"XG(@_^:T(,7A!#"$XH"#EN4!($+B`0!2XP,`
-M``H"`%+C`'"@$P@``!H#``#J`'#3Y3!P1^)W<._F`P``Z@``T^4!$-/E_O__
-MZP!PH.$*`%?C$```BF0R`^,#,-CG!P!3X0P```H``%?C`B"@$V,R`Q,#(,@7
-M`0``&@@`H.'^___K9#(#XP-PR.<`<%?B`7"@$V(R`^,#<,CG!`"@X0`0`.,`
-M$$#C!""@X_[__^L``%#C*0``"K0PU>$$,$/BM##%X8!3EN4(((WB`#"@XP0P
-M(N4$`(3B`!``XP`00./^___K!#"=Y0$`4^,3``"*82(#XP(PQ><!(*#C9#(#
-MXP,@Q><`,`#C`#!`XP`PD^6H(@/C`B"5YV00H..1`@'@TRT$XV(@0>.2`8'@
-MR0V%XC0`@.(A$X/@_O__ZP<``.H"`%/C!0``&@4`H.'^___K``!0XP`@H!-D
-M,@,3`R#%%P``H.,(T(WB\(&]Z!!`+>F``Y#E!@"3Z/[__^L``*#C$("]Z/!!
-M+>D0T$WB@&.0Y0!`DN5T</_F5%CGYP0PDN4,,(WE)$R@X7%`1.(.`%3C!/&?
-ME\8``.KX%```V!<``$P5``#8%P``:!4``(P5``#8%P``V!<``-@7``#8%P``
-MV!<``-@7``#8%P``V!<``,P5```"`%7C"```"@0`5>,+```*`0!5X[$``!H&
-M`*#A!Q"@X7,@[^;^___KK```Z@8`H.$'$*#A<R#_YO[__^NG``#J!@"@X0<0
-MH.$#(*#A_O__ZZ(``.H&`*#A!Q"@X0`@X.-@Q0/C#^"@X0SPEN>;``#J`#"-
-MY08`H.$%$*#A!R"@X0`PX.-HQ0/C#^"@X0SPEN>2``#J``!5XP`@H`.(-0$#
-M`R#&!XT```H!`%7CBP``&@$@H..(-0'C`R#&YPQ`G>5D`%3C9$"@(XDU`>,#
-M0,;G@@``Z@P`5>-(```*!@``B@8`5>,4```*"0!5XR(```H%`%7C>0``&@H`
-M`.K=`%7C2```"@(``(H1`%7C<P``&D$``.KN`%7C40``"OT`5>-N```:9```
-MZE<-AN(H`(#BX!"&XO[__^MH``#J"T"-X@8`H.$4$*#C!""@X3`U`^,/X*#A
-M`_"6YP]P!^(+<,WE!@"@X100H.,$(*#A+#4#XP_@H.$#\);G6```ZO[__^L-
-M(*#A?SW"XS\PP^,$()/E`2""X@0@@^57C8;B.("(X@!PH..O7X?B`U"%XH51
-MAN``0)CE````Z@!`E.4%`*#A!!"@X?[__^L``%#C^?__"@%PA^((@(CB(`!7
-MX_#__QH-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^7^___K-P``Z@8`H.$&$*#C
-M#""-XC@U`^,/X*#A`_"6YS```.I3)@/C`C#&YRT``.H``%/C`@``&@8`H.'^
-M___K*```Z@$`4^,"```:!@"@X?[__^LC``#J`@!3XR$``!H&`*#A_O__ZQX`
-M`.H/`%/C!@``&@8`H.$'$*#C"R"-XC0U`^,/X*#A`_"6YQ4``.H&`*#A!Q"@
-MXPP@C>(X-0/C#^"@X0/PEN<&`*#A!Q"@XPL@C>(T-0/C#^"@X0/PEN<(``#J
-M=W#OY@8`H.'%'J#C!R"@X?[__^L&`*#A6!P`XP<@H.'^___K``"@XQ#0C>+P
-M@;WH$$`MZ8!#D.4`$-+E417$Y00`H.'^___K`0!0XP``X!,``*`#$("]Z/!/
-M+>D\T$WB@%.0Y8@U`^,#,)7G`I"@X0$@<N(`(*`S``!3XP(PH`$!,((3``!3
-MXP!`H`,>8*`#!0``"HL``.H&`*#A_O__ZP%`A.)E`%3C`@``"FPPE>4B#1/C
-M]___&@`@H..V(,GAM##9X1\`4^-^``":`!"9Y0T@H.%_/<+C/S##XPA@D^4@
-M0)'B!D#4,`!@H#,``%;C!0``&@P`C>(@(*#C_O__ZP``4.,%```*;@``Z@P`
-MC>(@$*#C_O__ZQ5`X.-L``#J_O__ZPT@H.%_/<+C/S##XP0@D^4!((+B!""#
-MY81`A>*$H)7E`+"@XRR`C>(``XWH!)"@X0D`H.$*$*#A_O__ZP$`4.,\```*
-M"T"@X0Q0C>(``-7EM/G_ZP!P4.(0``"Z`0#UY;#Y_^L`8%#B#```N@%0A>('
-M8H;A!&#(YP0`5.,#``#*`##5Y3H`4^,$```:`5"%X@%`A.(&`%3CZ___&D8`
-M`.H-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^7^___K%4#@XSH``.J@8(7BD""5
-MY08`H.$T$(WB#"!"XO[__^L``%#C!0``"C1`G>4``%3C!)"=%0$PH!.V,,D1
-M#P``&I`@E>4&`*#A-!"-X@P@0N+^___K``!0XP4```HT0)WE``!4XP20G14"
-M(*`3MB#)$0(``!H`H)KEO?__Z@20G>4-(*#A?SW"XS\PP^,$()/E`2!"X@0@
-M@^7^___KM##9X2$`4^,1``":``"9Y2``@.(-(*#A?SW"XS\PP^,(4)/E`4"0
-MX@5`U#``4*`S``!5XP0``!H&$(GB`2"@X_[__^L``%#C`0``"A5`X.,```#J
-M`$"@XP0`H.$\T(WB\(^]Z`I0H.$``)WE(!"*X@8@H./^___K`0!0X]7__QJY
-M___J\$<MZ0C03>("0*#A@&.0Y;10TN$``%7CC0``"@`PDN4``%/CB@``"K:0
-MTN$%<*#A!0"@X?[__^L`@%#B"T#@`X0```H`$)3E#2"@X7\]PN,_,,/C"*"3
-MY0=0D>`*4-4P`*"@,P``6N,%```:"`"@X0<@H.'^___K``!0XW@``!H&``#J
-M``!7XP0```H(`*#A!Q"@X?[__^L-0.#C<P``Z@A0H.$`,)CE(@!3XQ5`X(-N
-M``"*"%"(X@8`4^,V```*!```B@(`4^,'```*`P!3XTH``!H:``#J!P!3XS<`
-M``H?`%/C10``&CX``.H$,)7E`@!3XP@```H$`%/C"P``"@$`4^,]```:!@"@
-MX0`0E>7^___K"`"%Y3@``.H&`*#A`!"5Y?[__^L(`(7E,P``Z@8`H.$`$)7E
-M_O__ZP@`A>4N``#J!#"5Y0(`4^,(```*!`!3XPL```H!`%/C)P``&@8`H.$`
-M$)7E""#5Y?[__^LB``#J!@"@X0`0E>6X(-7A_O__ZQT``.H&`*#A`!"5Y0@@
-ME>7^___K&```Z@8`H.$`$-7E!"#5Y0`PX.-DQ0/C#^"@X0SPEN<(`(7E#P``
-MZ@`0U>4$(-7E"#"5Y0`PC>4&`*#A`##@XVC%`^,/X*#A#/"6YP4``.H&`*#A
-M*!"@XP`@H.,L-0/C#^"@X0/PEN=YD._F``!9XQ<``!H``)3E#2"@X7\]PN,_
-M,,/C"%"3Y0=`D.`%0-0P`%"@,P``5>,'0*`1`P``&@@0H.$'(*#A_O__ZP!`
-MH.$``%3C!@``"@,``.H50.#C!`"@X0C0C>+PA[WH#4#@XP```.H`0*#C"`"@
-MX0<0H.'^___K]?__ZG!`+>D#0*#A@`.0Y0`0D^7^___K`%"@X00`H.$`$`#C
-M`!!`XP4@H.'^___K``"@XW"`O>CP1RWI$-!-XH!3D.4#8*#A`#"@XP@PC>6\
-M,,WA`#"-Y;0PS>$-`*#A!A"&X@8@H./^___K`#"6Y0$`4^,K```:#0"@X0@0
-MC>(&(*#C_O__ZP$`4.-1```*`$"@XPUPH.$&@*#C=)#OY@2@H.$$`X7@)@R`
-MXB$`@.(-$*#A"""@X?[__^L!`%#C#P``&@2CH.$*`(7@)@R`XB<`@.(4$(;B
-M$""@X_[__^L*H(7@)JR*XB"@BN(!0*#C`$#*Y020B>`@.@+C`Y#%YS<``.H!
-M0(3B$`!4X^+__QHV``#J`""@XR`Z`N,#(,7G`4"@XRX``.H"`%/C'0``&@!`
-MH.,-8*#A!G"@XP2`H.$$`X7@)@R`XB$`@.(-$*#A!R"@X?[__^L!`%#C#0``
-M&@2#H.$(`(7@)@R`XB$`@.(`$*#C!B"@X_[__^L(4(7@)ER%XB!0A>(`,*#C
-M`##%Y0%`H.,2``#J`4"$XA``5./E__\:#0``Z@,`4^,)```:)@R%XB``@.(`
-M$*#C`2N@X_[__^L`(*#C(#H"XP,@Q><!0*#C`@``Z@!`H.,```#J`4"@XP0`
-MH.$0T(WB\(>]Z"!*`N,$`-7G``.%X"8,@.(A`(#B#1"@X08@H./^___K!`#5
-MYP`#A>`F#(#B)P"`XA00AN(0(*#C_O__ZP0PU><#,X7@)CR#XB`P@^(!(*#C
-M`"##Y00PU><",(/@<S#OY@0PQ><0`%/CX/__&JS__^IP0"WI`D"@X8!CD.5L
-M();E`0`2XP<``!I``!+C!0``&@``H..T`,3AMC#4X0(Y@^.V,,3A<("]Z`90
-MU.4``%7C!```"@0`5>,5`."#`5!%D@(``)IP@+WH7RV@XP)0EN<!$(7B<1#_
-MYK80Q.$D*P'C`B"6YP8`4N,"\9^7,P``ZD`@```L(```X"```"P@``#((```
-MX"```,@@`````*#CM`#$X0(9@>.V$,3A<("]Z`8LA>("(8;@M"#2X;0@Q.$`
-M`%+C%@``"E\?A>(!$H;@!ER%X@51AN`#`*#A!!"!X@0@E>7^___KMB#4X;8@
-MQ.$@.P'C`S"6YP``4^,"*H(#MB#$`0``H`-P@+T(`0!3XP``H!,!*8(#MB#$
-M`0``H`-P@+WH``"@X[0`Q.$"&8'CMA#$X7"`O>@0,*#CM##$X0H;@>.V$,3A
-M``"@XW"`O>@``*#CM`#$X0(9@>.V$,3A<("]Z!!`+>D``%/B!P``"@[`H..T
-MP,+A`3"@X[8PPN$`$`#C`!!`XPP@H.'^___K``"@XQ"`O>AP0"WI`E"@X8!#
-MD.5L()3E`0`2XP(``!I``!+C`$#@`P@```KH8)3EM&#%X0,`H.'L$(3B!B"@
-MX?[__^L!,*#CMC#%X0!`H.,$`*#A<("]Z'!`+>F`4Y#E`D"@X0$PH..R,,3@
-M!`"@X0`0H.,&(*#C_O__ZVPPE>4!`!/C`P``&D``$^,!```:$``3XP0```H$
-M`*#AX!"%X@8@H./^___K`P``Z@0`H.$`$*#C!B"@X_[__^L``*#C<("]Z/!!
-M+>D@T$WB`F"@X0-PH.&`0Y#E!`"-X@`0H.,<(*#C_O__Z[8PUN$""1/C#0``
-M"@$@H.,D.P'C`R"$YP`PH..\)P'C`C"$YQ0H`>,",(3GN"<!XP(PA.<@*P'C
-M`C"$YP-`H.%M``#J_U`3X@4```H$`%7C%0#@@P%019(!@*"3`P``FF8``.I?
-M+:#C`E"4YP"`H.,""A/C"P``"@`PH.,D*P'C`C"$Y[@G`>,",(3GO"<!XP(P
-MA.<4*`'C`C"$YR`K`>,",(3G&0``Z@$)$^,,```*`""@XR0[`>,#((3G`3"@
-MX[@G`>,",(3GO"<!XP(PA.<4*`'C`C"$YR`K`>,",(3G"@``Z@`PH.,D*P'C
-M`C"$Y[@G`>,",(3GO"<!XP(PA.<4*`'C`C"$YR`K`>,",(3G"%"-Y;0PUN$`
-M`%/C!@``"@4`4^,%,*"3#3"@@PPPC>4,,(/B!#"-Y1P``.H`,*#C##"-Y0$`
-M6.,8```:7SV@XP-0A.<&7(7B!5&$X`0PE>4%`%/C`@``"@T`4^,*```:!```
-MZ@$@H..\-P'C`R"$YP!`H.,<``#J!2"@X[PW`>,#((3G`$"@XQ<``.H`,*#C
-MO"<!XP(PA.<#0*#A$@``Z@@PG>4",8/C"#"-Y010C>(,`(7B!Q"@X0P@G>7^
-M___K!`"@X040H.'^___K``!0XP0``!JX,@/C`S"4YP``4^->0.`#````"@!`
-MH.,$`*#A(-"-XO"!O>CP1RWI`4"@X8!CD.4`,*#C(#"!Y1LPP>6^,M'A,#"#
-MX@(`4^'-``"*!#"1Y0$`<^/*```:N"#1X?\_#^,#`%+AQ@``&B0PT>4#`%/C
-MPP``BEY]AN(X<(?B#%"!X@4`H.$`$`#C`!!`X_[__^L``%#C10``&@`@H.,D
-M.P'C`R"&YP$PH..\)P'C`C"&YU@@@N(",(;G)(#4Y;Y2U.$$`%CC%4#@@[``
-M`(H``%7CJP``"@4`5>,%H*"3#:"@@PR0BN()`*#A_O__ZP!04.*E```*!0"@
-MX0`0H.,<(*#C_O__ZPB@A>4`D(7E#0!:XP4PH`.\)P$#`C"&!U@@@@(",(8'
-M`C&(XP0PA>4,H(7B"@"@X3`0A.((()7E_O__ZQPPU.4``%/C!0``"@8`H.$%
-M$*#A_O__ZP``4../```*C```Z@,`6..,``"*7P^(X@`"AN`$`(#B"A"@X0@@
-ME>7^___K!CR(X@,QAN`(()7E!""#Y08`H.$'$*#A"""@X0`PH./^___K`$"@
-MXWP``.JX-P'C`S"6YP(`4^-R```:;""6Y0@P`.,!,$#C`S`"X```4^-L```*
-M5PV&XB@`@.+@$(;B_O__ZP"`4.)0```*!0"@X;@1G^7^___K``!0XP`PH!/H
-M,(@5)#L!XP,PEN<&`%/C!`!3$[PW`0,#,)8'[#"(!1PPU.4!`%/C&P``&C!P
-MA.*^(M3A$0Z(X@<0H.$0`%+C$""@(_[__^L%`*#A8!&?Y?[__^L``%#C"@``
-M&O``B.(0$(?B"""@X_[__^L!#(CB&!"'X@@@H./^___K`""@XQ$[`>,#(,;G
-M!@"@X0@0H.$!(*#C_O__ZR0``.HD`-3E``*&X#"`A.*^(M3A!@N`XAP`@.((
-M$*#A$`!2XQ`@H"/^___K)`#4Y0H`@.*XIP'C``**X```AN`$`(#B$!"(X@@@
-MH./^___K)`#4Y0X`@.(``HK@``"&X`0`@.(8$(CB"""@X_[__^L!,*#C$"L!
-MXP(PQN<D$-3EOB]"X@(0AN<&`*#A!Q"@X20@U.7^___K!@"@X?[__^L`0%#B
-M$0``"@4`H.%D$)_E_O__ZP``4.,`,*`3Z#"$%20[`>,#,);G!@!3XP0`4Q,&
-M```:O#<!XP,PEN?L,(3E`$"@XP(``.H50.#C````Z@!`H.,$`*#A\(>]Z`!`
-MH.,```#J7D#@XP4`H.$)$*#A_O__Z_;__^H4`0``'`$``/!'+>D`D*#A`J"@
-MX0-@H.&V<M/A0'"'X@<`H.'^___K`$"@X0"`H.$``%#C0@``"@`0H.,'(*#A
-M_O__ZP0`H.$#,*#C!#"`Y/\0H.,&(*#C_O__Z[0RUN$#`%/C`_&?ES4``.HH
-M*```'"@``#0H``!`*````%``XP!00.,'``#J`%``XP!00.,$``#J`%``XP!0
-M0.,!``#J`%``XP!00.,,`(CB!1"@X1`@H./^___K`#"6Y00`$^,`,*`3'##(
-M%0`PEN4(`!/C`3"@$QPPR!4&,-KE`3!#XB0PR.4`,);E`@`3XP,```HE`(CB
-M#!"&X@@@H./^___KMC+6X0``4^,$```*OC+(X3``B.(H$(;BMB+6X?[__^L)
-M`*#A"!"@X0<@H.'/_O_K`%"@X00`H.$'$*#A_O__ZP```.H`4.#C!0"@X?"'
-MO>AP0"WI`%"@X0)`H.&`8Y#EMC#2X0,ZH.$C.J#A"@!3XP/QGY<*``#J_"D`
-M`/PI``#\*0``_"D``$PI``!T*0``Q"D``/PI``#\*0``1"D``/PI``!>0.#C
-M+```Z@`PDN4``%/C`2"@$Q@V`A,#(,87`$"@$P!`H`,8-@(#`T#&!R(``.HD
-M.P'C`S"6YP``4^,=```*`#"2Y0``4^,:```*`2"@XR0[`>,#((;G`$"@X[PW
-M`>,#0(;G%#@!XP-`AN>X-P'C`T"&YR`[`>,#0(;G#@``ZFPPEN4!`!/C!0``
-M"@8`H.'^___K!@"@X?[__^L&`*#A_O__ZP4`H.$`$)3EDO7_ZP!`H.$```#J
-M`$"@XP0`H.%P@+WH\$\MZ1303>(`8*#A`D"@X0`PH.,,,(WE"#"-Y0%0H.$#
-M`%'A`!"@$P$0H`.``%+C`3"@D0$P@8,``%/C!@``"@`@H.,(.0'C`R#`YP(`
-M4>$"0*`1%4#@`\8``.H``%+C`$"@`\,```H$L*#A!`"@X?[__^L`<%#B"T#@
-M`[T```H'`*#A!1"@X0L@H.'^___K`P!4XP!`X)/#``":!%"@X0<`H.$$$*#A
-M#""-X@@PC>+^___K`0!0XP4``!H"(*#CN#<!XP,@AN<$(*#C(#L!XP,@AN<'
-M`*#A!1"@X0P@C>((,(WB_O__ZP$`4.,%```:`B"@X[@W`>,#((;G!R"@XR`[
-M`>,#((;G#%"=Y0%01>(/`%7C!?&?ES$``.ID*P``@"L``.PK``#4*P``["L`
-M`.PK``#L*P``G"L``.PK``#L*P``["L``.PK``#L*P``["L``.PK``"X*P``
-M`""@XQ0X`>,#((;G`2"@XR0[`>,#((;G&@``Z@$@H.,4.`'C`R"&YP`@H.,D
-M.P'C`R"&YQ,``.H"(*#C%#@!XP,@AN<$(*#C)#L!XP,@AN<,``#J!""@XQ0X
-M`>,#((;G!B"@XR0[`>,#((;G!0``Z@4@H.,4.`'C`R"&YP`@H.,D.P'C`R"&
-MYPA0G>4!4$7B#P!5XP7QGY<R``#J0"P``%PL``#,+```L"P``,PL``#,+```
-MS"P``'@L``#,+```S"P``,PL``#,+```S"P``,PL``#,+```E"P````@H..\
-M-P'C`R"&YP$@H.,D.P'C`R"&YTL``.H!(*#CO#<!XP,@AN<`(*#C)#L!XP,@
-MAN=$``#J`B"@X[PW`>,#((;G!""@XR0[`>,#((;G/0``Z@0@H..\-P'C`R"&
-MYP8@H.,D.P'C`R"&YS8``.H%(*#CO#<!XP,@AN<`(*#C)#L!XP,@AN<O``#J
-M`""@XP@Y`>,#(,;G`#``XP`P0.,`,)/E!#"-Y2X``.H%@*#A!:"'X``PVN7=
-M`%/C%@``&@(`A>(``(?@!!"-X@0@H./^___K`0!0XP\``!H!0*#C"H"@X00@
-MVN<"((+B`@Q2XP(LH*,,.P'C`R"&YQD,AN()`(#B"A"@X?[__^L(.0'C`T#&
-MYP!`H.,5``#J"("'X`DPV.<",(/B`U"%X'50_^8%`%3AW/__B@!`H.,,``#J
-M!`"@X130C>+PC[WH`""@XP@Y`>,#(,;G`#``XP`P0.,`,)/E!#"-Y0!0H.,!
-MD*#CS?__Z@<`H.$+$*#A_O__Z^[__^H00"WI@`.0Y0,0H.&T(-+A"___ZQ"`
-MO>CP12WI#-!-X@)0H.$`,*#C!#"-Y8!CD.6R,,WA`3#-Y6PPEN4!`!/C`@``
-M&D``$^,``.`#60``"E`QEN46#H;B+1"@XP0@C>(,,$/B_O__ZP!P4.(0```*
-M!$"=Y0``5.,-```*!T"@X0(`C>(%$(?B`B"@X_[__^L",/3E`2#4Y0(T@^'3
-MH.#G8``3XP!PH`,!<*`3`8"@XP(``.H`<*#C!Z"@X0>`H.$\,=;E`2!#XG(@
-M[^;]`%+C`$"@@PP``(H&(*#A`$"@XP0`H.%_,`/B!`!3X0-`H"$$`,7E/3'2
-MY0$@@N(!$$/B<1#OYOT`4>/U__^:`0!8XR,``!H&`*#A$Q"@XP$@C>(P-0/C
-M#^"@X0/PEN<!0-WE`P!4XPD``!H``%KC`P``"@``5^.6<*`3AW"@`PT``.H`
-M`%?C2'"@$T%PH`,)``#J``!:XP0```H.,0#C``!7XP-PH`%+?Z`3`@``Z@``
-M5^.0<*`3@G"@`X=PH.$@,0KC!S!`XY,'`^``,(7E``"@XP0``.H@,0KC!S!`
-MXY,$`^``,(7E``"@XPS0C>+PA;WH<$`MZ2#03>*`8Y#E`$"2Y03@TN4-P*#A
-M,#&?Y0\`D^@'`*SH`##,Y0$`=.,P```*I$*@X<4Z!>-\.D#CDR2#X*,SH.%N
-M`%/C!5"@`RD```H/``"*-P!3XP)0H`,E```*!0``B@H`4^,`4*`#(0``"A0`
-M4^,>```:%0``ZCP`4^,#4*`#&P``"EH`4^,8```:$0``ZO``4^,(4*`#%0``
-M"@4``(IX`%/C!E"@`Q$```JT`%/C#@``&@D``.I:#U/C"5"@`PL```H>#E/C
-M"```&@4``.H!4*#C!@``Z@10H.,$``#J!U"@XP(``.H*4*#C````Z@M0H.,`
-M0*#C#0"@X1`0C>(`P.#C!##0YP4`4^$$P,$7`@``&@0PP><``%[C`@``"@%`
-MA.(-`%3C]?__&@8`H.$0$(WB_O__ZP$`4.,``*`#``#@$R#0C>)P@+WH!```
-M`/!%+>DLT$WB`E"@X0-@H.&`0Y#E!`"@X?[__^L``%#C2```"L@U`^,#,)3G
-M``!3XT0```JT@-7A(`!8XP9`X(-#``"*;#"4Y1``$^,]```:(#L!XP.@E.>V
-M,-7A``!3XSH```H``%CC.```"B``6.,@@*`C!%"-X@4`H.$`$*#C)""@X_[_
-M_^LH<(WB)(`GY00`A>(&$*#A"""@X?[__^N$8(3BA#"4Y7@PA.4$<(?B!@"@
-MX7@0E.7^___K`0!0XQ@```IX4)3E!0"@X2PPD.1X,(3E!Q"@X00@G>7^___K
-M`0!0X_'__QHH()7E!#"=Y0,`4N'M__\:;#"4Y2``$^,#```*>""5Y3@QE.4#
-M`%+AYO__&@0`H.%X$)7E_O__ZP``4.,'```*!`"@X0H0H.'^___K!`"@X000
-MC>+^___K``!0XP$``!H`0.#C````Z@!`H.,$`*#A+-"-XO"%O>CP0"WI#-!-
-MX@)@H.&`0Y#E`#"@XP0PC>5L,)3E00`3XT\```I0,93E%@Z$XBT0H.,$((WB
-M##!#XO[__^L``%#C`'"@`P(```H$4)WE`'!5X@%PH!-/7X3B!0"@X?[__^L!
-M`%#C#0``&@$`5^,%```:!@"@X1`0H.,`(`#C`"!`X_[__^L[``#J!@"@X1`0
-MH.,`(`#C`"!`X_[__^LU``#J!0"@X?[__^L!`%#C#0``&@$`5^,%```:!@"@
-MX1`0H.,`(`#C`"!`X_[__^LI``#J!@"@X1`0H.,`(`#C`"!`X_[__^LC``#J
-M)#&4Y0X`4^,-``":`0!7XP4``!H&`*#A$!"@XP`@`.,`($#C_O__ZQ@``.H&
-M`*#A$!"@XP`@`.,`($#C_O__ZQ(``.H!`%?C!0``&@8`H.$0$*#C`"``XP`@
-M0./^___K"@``Z@8`H.$0$*#C`"``XP`@0./^___K!```Z@(`H.$0$*#C`"``
-MXP`@0./^___K``"@XPS0C>+P@+WH^$\MZ0-PH.&`0Y#ECC^@X[0PPN$'`*#A
-M`!"@XP,@H.'^___K0#L$XTPP0.,`,(?E9#"@XRPPQ^4M,,?E+C#'Y0<PH.,O
-M,,?E7""@XS`@Q^5-(.#C,2#'Y0!0H.,R4,?E,S#'Y00PH.,T,,?E`#``XP`P
-M0.,`8)/E.&"'Y01@D^4\8(?E"&"3Y4!@A^4,8)/E1&"'Y0$\H./`,(?E*CD`
-MX\0PA^6\7<?A%C"@XQ@QQ^40,*#C&3''Y05@H.$*H*#C!)"@XZ"V".,!L$#C
-MK#?4Y0``4^,*```*)H"&XHB!A^`*,,CGK`?4Y?[__^N;``#@"0"(YP$PH..X
-M,,CA`6"&XG9@_^8@`%;C`P``"@%0A>(,0(3B)@!5X^O__QH3/J#CLV"'X3)A
-MQ^4/,*#C-#*'Y3\PH.,/,,?E``"@X_B/O>AP0"WI`E"@X8!#D.5L,)3E`0`3
-MXPH```HD`93E_O__ZZ`V".,!,$#CDP`#X``PA>4!,*#CM##%X20QE.4&,,7E
-M"0``ZJ8'U.7^___KH#8(XP$P0..3``/@`#"%Y0$PH..T,,7AIC?4Y08PQ>4`
-M`*#C<("]Z/!/+>G%WTWB`K"@X0-0H.$`,*#C]#*-Y0(LC>*R.\+A%3L(X_\_
-M3^.^/\+A`3"@XP,LC>*P,,+A`PR-X@(`@.(@$(OB!B"@X_[__^L48(7B.#.=
-MY08`4^$+``":,4Z-XA0@H..T(63A!0"@X000H.$$(*#C_O__ZP0`A>($$(3B
-M$""@X_[__^L&4*#A*`"+XO[__^L``%#C(```"AL["./_/T_C`BR-XKX_PN$!
-M,*#C`RR-XK8PPN&X<MOA(`!7XR!PH".T<,+A"'"'X@=`A>`X,YWE!`!3X1``
-M`)HQ;HWBM'%FX01PH.,%`*#A!A"@X0<@H.'^___K!P"%X`@0AN('(*#A_O__
-MZP@`A>(L$(OB`SR-XK0@T^'^___K````Z@5`H.&@((OB"""-Y9`PF^4"`*#A
-M+1"@X[TOC>(,,$/B_O__ZP!@4.(4```*]%*=Y0``5>,1```*!E"@X2L.C>("
-M`(#B!1"&X@(@H./^___K`C#UY0$@U>4"-(/ATR#@YR0@C>5@`!/C`#"@`P$P
-MH!,4,(WE`2"@XQ`@C>4#``#J`#"@XQ0PC>4D,(WE$#"-Y0$["./_/T_C`BR-
-MXKX_PN%\4(OB!0"@X?[__^L!`%#C#@``&A`PG>4!`%/C!0``&@,,C>(0$*#C
-M`"``XP`@0./^___K.```Z@,,C>(0$*#C`"``XP`@0./^___K,@``Z@4`H.'^
-M___K`0!0XPX``!H0()WE`0!2XP4``!H##(WB$!"@XP`@`.,`($#C_O__ZR4`
-M`.H##(WB$!"@XP`@`.,`($#C_O__ZQ\``.ID,)OE#@!3XPX``)H0,)WE`0!3
-MXP4``!H##(WB$!"@XP`@`.,`($#C_O__ZQ,``.H##(WB$!"@XP`@`.,`($#C
-M_O__ZPT``.H0()WE`0!2XP4``!H##(WB$!"@XP`@`.,`($#C_O__ZP0``.H#
-M#(WB$!"@XP`@`.,`($#C_O__ZQ1@A.(X,YWE!@!3X0L``)HQ7HWB%""@X[0A
-M9>$$`*#A!1"@X00@H./^___K!`"$X@00A>(0(*#C_O__ZP9`H.$'.PCC_S]/
-MXP(LC>*^/\+AE#"+X@PPC>4#`*#A_O__ZP`0H.&^#XWB`@"`X@(@H./^___K
-M`BR-XKH_TN$#`!/C%0``"@$`$^,#,*`3`#.-%0$PH`,`,XT%")"$XC@SG>4)
-M`%/A#```FC%>C>(((*#CM"%EX01@H.,$`*#A!1"@X08@H.'^___K!@"$X`80
-MA>`&(*#A_O__ZP```.H$D*#A9#";Y0``4^,!,*`#9#"+!04["./_/T_C`BR-
-MXKX_PN%D`)OE_O__ZZ`V".,!,$#CDP`#X``SC>4!,*#C`RR-XK0PPN%D,)OE
-M!C/-Y0Q0B>(X,YWE!0!3X0L``)HQ3HWB#""@X[0A9.$)`*#A!!"@X00@H./^
-M___K!`")X@00A.(((*#C_O__ZP60H.$K.PCC_S]/XP(LC>*^/\+AND_2X1``
-M%.,".Z`3`RR-$K8PPA$".:`#`RR-`K8PP@$`,*#C`RR-XK0PPN$(4(GB.#.=
-MY04`4^$1``":,4Z-X@@@H..T(63A!&"@XPD`H.$$$*#A!B"@X?[__^L&`(G@
-M"!"$X@8@H.'^___K!0"@X2P0B^(#/(WBM"#3X?[__^L%D*#AK8^-X@@`H.%`
-M$*#C`"``XP`@0./^___K?"#;Y0``4N,`<*`#(P``"JU/C>(`0(3@"U"@X0!P
-MH.-`@(CB`#``XP`P0.,8,(WE`#``XP-@H.$`8$#C`*``XP"@0.,<D(WE(+"-
-MY1BPG>4&D*#A?V`"X@<`5N$&<*`A"!!DX*8PH.$!`!+C"2"@`0L@H!$`((WE
-M!`"@X0H@H.'^___K?2#5Y0%0A>(``%+C`$"$$.[__QH<D)WE(+"=Y1`@G>4!
-M`%+C+P``&@(LC>*R.]+A`@D3XPP```HD,)WE``!3XP0```H.<0#C%""=Y0``
-M4N-+?Z`3(@``ZA0PG>4``%/CD'"@$X)PH`,=``#J@``3XPH```HD()WE``!2
-MXP,```H4,)WE``!3XQ0``!H/``#J%""=Y0``4N,.```:"0``ZB0PG>4``%/C
-M`P``"A0@G>4``%+C"0``&@0``.H4,)WE``!3XP,``!I!<*#C!```ZH=PH.,"
-M``#J2'"@XP```.J6<*#CAW"@X2$["./_/T_C`BR-XKX_PN$`,*#C!3/-Y00S
-MS>4@,0KC!S!`XY,'`^``,XWE#%")XC@SG>4%`%/A"P``FC%.C>(,(*#CM"%D
-MX0D`H.$$$*#A!""@X_[__^L$`(GB!!"$X@@@H./^___K!9"@X0`PH.,"+(WB
-ML#O"X;PZPN&0$)OE2S^-X@`PC>4K/HWB!#"-Y0P`G>4L((WBJS^-XO[__^L"
-M/(WBL$O3X0``5.-A```*BT^-X@0`H.$`$*#C@""@X_[__^L`,`#C`#!`XP,`
-MD^@#`(3H`BR-XK!+TN$``%3C$```"B-NC>(#8(;B`$"@XP!P`.,`<$#C2X^-
-MX@10H.$&`*#A!Q"@X04@V.?^___K`&"&X`%0A>("/(WBL$O3X04`5.'U__^*
-MOP^-X@`0H.,4(*#C_O__ZP(\"./_/T_C`BR-XKX_PN&+#XWB_O__ZW``_^8#
-M/(WBM`##X0A0@.(%8(G@.".=Y08`4N$0``":,4Z-XK119.$$4*#C"0"@X000
-MH.$%(*#A_O__ZP4`B>`($(3B!2"@X?[__^L(`(GBBQ^-X@,\C>*T(-/A_O__
-MZP:0H.&_#XWB`!"@XQ0@H./^___K!3P(X_\_3^,"+(WBOC_"X;!;TN$#/(WB
-MM%##X0A0A>(%8(G@.".=Y08`4N$0``":,4Z-XK119.$$4*#C"0"@X000H.$%
-M(*#A_O__ZP4`B>`($(3B!2"@X?[__^L(`(GB2Q^-X@,\C>*T(-/A_O__ZP:0
-MH.$"+(WBO$K2X0``5.-A```*BT^-X@0`H.$`$*#C@""@X_[__^L`,`#C`#!`
-MXP,`D^@#`(3H`CR-XKQ*T^$``%3C$```"B-NC>(#8(;B`$"@XP!P`.,`<$#C
-M+("-X@10H.$&`*#A!Q"@X04@V.?^___K`&"&X`%0A>("+(WBO$K2X04`5.'U
-M__^*OP^-X@`0H.,4(*#C_O__ZP(\"./_/T_C`BR-XKX_PN&+#XWB_O__ZW``
-M_^8#/(WBM`##X0A0@.(%8(G@.".=Y08`4N$0``":,4Z-XK119.$$4*#C"0"@
-MX000H.$%(*#A_O__ZP4`B>`($(3B!2"@X?[__^L(`(GBBQ^-X@,\C>*T(-/A
-M_O__ZP:0H.&_#XWB`!"@XQ0@H./^___K!3P(X_\_3^,"+(WBOC_"X;Q:TN$#
-M/(WBM%##X0A0A>(%8(G@.".=Y08`4N$0``":,4Z-XK119.$$4*#C"0"@X000
-MH.$%(*#A_O__ZP4`B>`($(3B!2"@X?[__^L(`(GB+!"-X@,\C>*T(-/A_O__
-MZP:0H.$`,*#CK#*-Y9"`F^4,@$CB`P!8X0`PH-,!,*##"""=Y0``4N,``%@3
-M.P``V@``4^,Y```*`$"@XZNOC>(%/`CC_S]/XPPPC>6_+XWB""""XA`@C>4$
-M4*#A%+"-Y0BPH.$(@)WE!7"@X05@B.`&`*#A"A"@X?[__^L``%#C'P``"JQ"
-MG>4"`%3C'```F@PPG>4"+(WBOC_"X;PZTN$#+(WBM##"X0@P@^((,(WE`T")
-MX#@SG>4$`%/A$```F@@@G>4"/(WBO"_#X0D`H.&_'XWB!""@X_[__^L$`(GB
-M$!"=Y00@H./^___K"`")X@80H.$#/(WBM"#3X?[__^L$D*#A!W"(X`$PU^4"
-M,(/B`U"%X`4`6^'2___*%+"=Y0$\"./_/T_C`BR-XKX_PN%+,*#C`S/-Y5`P
-MF^4!,\WEC##;Y0`SS>5C,.#C`C/-Y0A@B>(X,YWE!@!3X0P``)HQ3HWB"""@
-MX[0A9.$$4*#C"0"@X000H.$%(*#A_O__ZP4`B>`%$(3@!2"@X?[__^L&D*#A
-M"0"@X<7?C>+PC[WH\$\MZ1S03>(4$(WE#""-Y1`PC>6`DY#EM'#2X0=P@^#$
-M,@/C`S#9YP``4^,$```*B#4#XP,PF><``%/C%4#@$S8``!K^___K#2"@X7\]
-MPN,_,,/C!""3Y0$@@N($((/EA(")XH1`F>5ZOHGB#+"+XA!@G>7_H@#C"`"@
-MX000H.'^___K`0!0XQ8```H',&;@"@!3X09`X-,3``#:!%"@X2@PE.4``%/C
-M`$"4!?'__PH+`*#A9!"5Y?[__^L!`%#C!@``&@!PC>4)`*#A%!"=Y04@H.$&
-M,*#AU?S_ZP!@H.$`0)3EX___Z@!`H.,-(*#A?SW"XS\PP^,$()/E`2!"X@0@
-M@^7^___K$#"=Y09@8^`,()WEM&#"X0`PH..V,,+A!`"@X1S0C>+PC[WH<$`M
-MZ8!3D.4`0%/B#P``"K`PU.$``%/C`P``"@$`4^->0.`3#```&@0``.H%`*#A
-M_O__ZP``4.,$```*!0``Z@4`H.'^___K``!0XP$``!H`0.#C````Z@!`H.,$
-M`*#A<("]Z/!'+>D"8*#A@$.0Y00`H.'^___K``!0XP0``!KP`)_E\!"?Y?[_
-M_^L`0.#C-@``ZL@U`^,#,)3G``!3XR\```JP,-;A`0!3XP0```K(`)_EP!"?
-MY?[__^L50.#C*@``ZB`[`>,#H)3GA'"$XH0PE.5X,(3E`F"&X@:`H.,'`*#A
-M>!"4Y?[__^L!`%#C!0``&@0`H.$&$*#A_O__ZP``4.,6```*%P``ZGA0E.4%
-M`*#A(#"0Y'@PA.4&$*#A"""@X?[__^L!`%#CZ___&@0`H.%X$)7E_O__ZP``
-M4.,'```*!`"@X0H0H.'^___K!`"@X080H.'^___K``!0XP$``!H`0.#C````
-MZ@!`H.,$`*#A\(>]Z/0!```4````$`(``#!`+>D4T$WB`%"@X0U`H.$-`*#A
-M`!"@XQ`@H./^___K`3"@X[`PS>$"`(WB`!"@XP8@H./^___KUSV@XP,`E><5
-M&PCC#2"@X0`PH./^___K%-"-XC"`O>@P0"WI%-!-X@!0H.$-0*#A#0"@X0`0
-MH.,0(*#C_O__ZP$PH..P,,WA`@"-XN`0A>(&(*#C_O__Z]<]H.,#`)7G%1L(
-MXPT@H.$`,*#C_O__ZQ30C>(P@+WH,$`MZ1303>(`4*#A#4"@X0T`H.$`$*#C
-M$""@X_[__^O7/:#C`P"5YQD;".,-(*#A`#"@X_[__^L4T(WB,("]Z/!/+>DL
-MT$WB`F"@X0-0H.&`0Y#E!`"@X?[__^L``%#C@@``"H@U`^,#,)3G``!3XWX`
-M`!K(-0/C`S"4YP``4^-Z```*G34#XP,PU.<``%/C=@``"A0UU.4!`%/C`P``
-M&@0`H.'^___K`$"@XW```.IL,)3E(@T3XP,```H$`*#A_O__ZP!`H.-I``#J
-MM##6X4\/4^,?```:MC#6X0(`$^-B```*`6#5Y2``5N,@8*"C!'"-X@<`H.$`
-M$*#C)""@X_[__^L$`(?B%!"%X@8@H.'^___K!&"-Y?[__^L-,*#A?UW#XS]0
-MQ>,$,)7E`3"#X@0PA>4$`*#A!Q"@X?[__^L`0*#A!#"5Y0$P0^($,(7E_O__
-MZT(``.H+`%/C/0``F@4`H.$4$9_E#""@X_[__^L!`%#C-P``&K1PUN$,<$?B
-M#&"%X@0`C>(`$*#C)""@X_[__^OH@)_E`Z"-X@*0C>((L(WB&0``Z@8`H.$(
-M$*#A"B"@X?[__^L#4-WE4P!5XQ0``!H!8(;B`7!'XL=?Q^$&`*#A"!"@X0D@
-MH.'^___K`6"&X@%01>("(-WE`@!5X0,``+H$((WE"P"@X080H.'^___K`G#=
-MY0=@AN`%<&?@``!7X^/__\K^___K#3"@X7]=P^,_4,7C!#"5Y0$P@^($,(7E
-M!`"@X000C>+^___K`$"@X00PE>4!,$/B!#"%Y?[__^L"``#J!`"@X?[__^L`
-M0*#A``!4XP!`H!,````:`$#@XP0`H.$LT(WB\(^]Z"0````X`@``\$\MZ5G?
-M3>(`L*#A$!"-Y0*`H.$4,(WE@).0Y;1@TN$&H*#A!@"@X?[__^L`4%#B"T#@
-M`X,!``H`$)CE#0"@X7\]P.,_,,/C"'"3Y09`D>`'0-0P`'"@,P``5^,%```:
-M!0"@X08@H.'^___K``!0XPH```H$``#J``!6XP<```H%`*#A!A"@X?[__^L%
-M`*#A"A"@X?[__^L-0.#C:0$`ZK8@V.%F-PCC`P!2X0`PH!,!,*`#"`!6XP`P
-MH-,``%/C%@``"@`P`.,`,$#C-#"3Y3PPC>4`,-7EW0!3XU4!`!H"`(7B/!"-
-MX@0@H./^___K`0!0XT\!`!H"#%;C`FR@HU4.B>(#`(#B!1"@X08@H.'^___K
-M5&>)Y0!`H.-&`0#J"P!6XP,``,H``%;C`$"@PPT``,H5``#J!0"@X1`5G^4,
-M(*#C_O__ZP$`4./U__\:"P"@X1`0G>4((*#A!3"@X13__^L`0*#A,P$`Z@0P
-MU>=A($/B<B#OYAD`4N,@,$.2!##%EP%`A.($`%;A]O__R@!`H..\9)_E!'&6
-MYP<`H.'^___K`""@X04`H.$'$*#A_O__ZP``4.,#```*`4"$X@D`5./S__\:
-M_```Z@@`5.,$\9^7^0``ZB!)``#H20``=$H``+1*````2P``0$L``&!+``"`
-M2P``@$P``````.,``$#C_O__ZP`P`.,`,$#C%$"3Y0$`5.,$```:`T"@X1@`
-M@^+^___K`C"@XQ0PA.4`,`#C`#!`XP!`D^4``%3C"0``&A!TG^5]GZ#C#&2?
-MY0<`H.'^___K"0"@X?[__^L`0);E``!4X_C__PI<,(WB`"``XP`@0.,#`)+H
-M`R"@X00`@N2P$,+A\"X/X_\O3^,%$*#C%@Z-XK(0@.$+`*#A`AP(XTP@C>+^
-M___K!0"@X0`0`.,`$$#C`R"@X_[__^O#``#J````XP``0./^___K7#"-X@`@
-M`.,`($#C`P"2Z`,@H.$$`(+D`!#"Y?`N#^/_+T_C!!"@XQ8.C>*R$(#A"P"@
-MX0(<".-,((WB_O__ZP4`H.$`$`#C`!!`XP,@H./^___K`#``XP`P0.,40)/E
-M`@!4XZ8``!H#0*#A&`"#XO[__^L!,*#C%#"$Y:```.IL,)GE`0`3XP8```H%
-M`*#A`!``XP`00..*-0'CTR"9X?[__^N6``#J!0"@X0`0`.,`$$#C`R"@X_[_
-M_^N0``#J"P"@X1`0G>4L((WB%#"=Y<3X_^L``%#C`$"@$RP@G06#/@T#&S-$
-M`Y,2PP#"+Z`!0TEB``4`H.$`$`#C`!!`XP0@H.'^___K?0``ZG01F^4`(-'E
-M`3#1Y0(`T>4``(WE`P#1Y00`C>4$`-'E"`"-Y040T>4,$(WE!0"@X0`0`.,`
-M$$#C_O__ZVT``.H!,*#C4C7)Y04`H.$`$`#C`!!`XP,@H./^___K90``Z@`P
-MH.-2-<GE!0"@X0`0`.,`$$#C`R"@X_[__^M=``#J`C"@XT@PC>4\0(WB!0"@
-MX0`0`.,`$$#C!""@X?[__^L$`*#A`!``XP`00./^___K``!0XP`PH`-(,(T%
-M%@``"CP`C>(`$`#C`!!`X_[__^L``%#C`C"@`T@PC04.```*/`"-X@`0`.,`
-M$$#C_O__ZP``4.,%,*`#2#"-!08```H\`(WB`!``XP`00./^___K``!0XP(P
-MH`-(,(T%````XP``0.,\$(WB2""=Y?[__^L`,`#C`#!`XTA`G>4`0,/E'$"-
-MX@0`H.%($(WB!""@X_[__^L+`*#A$!"=Y00@H.$4,)WEWO+_ZP4`H.$`$`#C
-M`!!`XP,@H./^___K'0``Z@`P`.,`,$#C`##3Y0``4^,%```*`@!3XPU`H`,#
-M```*!0!3XPY`H`,````*"T"@XP4`H.$`$`#C`!!`XP0@H.'^___K`#``XP`P
-M0.,```#C``!`XP00H.$`(-/E_O__ZP0``.H%`*#A`!``XP`00.,#(*#C_O__
-MZP"0F.6T0-CA!0"@X?[__^L!<(#B=W#_Y@<`5.$$<*`Q#2"@X7\]PN,_,,/C
-M"&"3Y0=`F>`&0-0P`&"@,P``5N,$```:"0"@X040H.$'(*#A_O__ZP!PH.$`
-M`%?C#4#@$P```!H`0*#C!0"@X0H0H.'^___K!`"@X5G?C>+PC[WH)````#``
-M``!@`@```````'!`+>D"4*#A@$.0Y00`H.'^___K``!0XP!`H`,?```*G34#
-MXP,PU.<``%/C&@``"@`PE>4#`%/C`_&?EP,``.KH30``X$T``/A-``#P30``
-M%4#@XQ$``.H`4*#C!```Z@)0H.,"``#J!%"@XP```.H!4*#C!`"@X040H.'^
-M___K``!0XP0```H$`*#A!1"@X?[__^L`0*#C````Z@!`X.,$`*#A<("]Z/!'
-M+>D`D*#A`:"@X0)PH.$#@*#A'`"@X_[__^L`4*#A`$"@X0``4.,`0*`#*@``
-M"A0`H./^___K`&!0X@0``!H%`*#A'!"@X_[__^L`0*#C(0``Z@8`H.$`$*#C
-M%""@X_[__^L!@,;E`'#&Y0$PH.,#,,;E`7!'XG=P[^8$`%?C$%"@@P`P`),`
-M,$"3!W"#D#A0UY4$`(;B"A"@X04@H.'^___K%#"@X[`PQ.$$8(3E"#"$Y0`P
-MH.,,,(3E$#"$Y10`A.+^___K2PV)XA@`@.($$*#A_O__ZP!`H.$$`*#A\(>]
-MZ!!`+>D%($+B<B#OY@@`4N,`0*"#`,``DP#`0),"((R00$#2E00@H.&[___K
-M$("]Z/!/+>D4T$WB`&"@X0%0H.'\.PCC`P!2X9L```K^.PCC`P!2X5Y`X!.J
-M`P`:M`'1X3\`4..1``":$#"1Y0``4^..```*_O__ZP"`H.$`H*#A``!0XPM@
-MX`.)```*$!"5Y;21U>$-(*#A?SW"XS\PP^,(<)/E"4"1X`=`U#``<*`S``!7
-MXP0``!H)(*#A_O__ZP``4.,)```*`P``Z@``6>,&```*"1"@X?[__^L(`*#A
-MM!'5X?[__^L-8.#C<```Z@`PFN4!,$/B`P!3XP/QGY<#``#J,%```.A0````
-M40``&%$``%Y@X.--``#J$!":Y8!#EN4,,-KE!P!3XP@``(K<,-KA`2"@XQ(S
-MH.'<`!/C(0``&B``$^,;```:`@`3XP$``!I>8.#C/0``Z@(@H..X-P'C`R"$
-MY_\0`>(!`%'C`@``"@(`4>$3```:!@``Z@0PH.,@*P'C`C"$YR0K`>,",(3G
-M`&"@XRT``.H'(*#C(#L!XP,@A.<&(*#C)#L!XP,@A.<`8*#C)0``Z@8`H.'9
-MZ__K`&"@X2$``.H`8*#C'P``ZH`#EN4P$(KBO"#:X4/V_^L`8*#A&0``Z@8`
-MH.$*$*#AM"'5X;_T_^L`8*#A$P``ZH!#EN4,,)KE`0!3XP,```H"`%/C7F#@
-M$PP``!H$``#J!`"@X?[__^L``%#C!```&@4``.H$`*#A_O__ZP``4.,!```*
-M`&"@XP```.H`8.#C``!6XQ```!H0`)7EM)'5X0T@H.%_/<+C/S##XPAPD^4)
-M0)#@!T#4,`!PH#,``%?C`P``&@H0H.$)(*#A_O__ZP"0H.$``%GC#6#@$P@`
-MH.&T$=7A_O__ZP```.H58.#C!D"@X1(#`.J`([;EG34#XP,PTN<``%/C`$#@
-M`PP#``H0,)'E``!3XQ5`X`,(`P`*M`'1X?[__^L`L*#A`'"@X0``4.,+0.`#
-M`0,`"A`0E>6T@=7A#2"@X7\]PN,_,,/C"*"3Y0A`D>`*0-0P`*"@,P``6N,$
-M```:"""@X?[__^L``%#C"0``"@,``.H``%CC!@``"@@0H.'^___K"P"@X;01
-MU>'^___K#4#@X^@"`.H`,)?E`3!#XA(`4^,#\9^7$@``ZN!2``#\4@``V%,`
-M`-A2``"P6P``I%0``-A2``#84@``V%(``-A2``#84@``V%(``-A2``#84@``
-MV%(``#Q4``!`7```X%P``%1=``!>0.#CN`(`Z@!`EN4$`*#A_O__ZP0`H.'^
-M___K`$"@X;$"`.H`8);E;#"6Y1$`$^,P```*!#"7Y0$`<^,#```:N"#7X0$X
-M@^(#`%+A*0``"E<-AN(H`(#B!!"'XO[__^L`0%#B"T#@`Y\"``H0@)?EO##7
-MX=0PA.43#H3B%!"'XA`@H./^___K`@P8XP$PH!/<,(05`#"@`]PPA`7(-);E
-M``!3X]PPA`4""QCC`#"@`UPVA`4'```*`3"@XUPVA.7<,(3E9PZ$X@4`@.(D
-M$(?B&B"@X_[__^O4-);E``!3XUPVA`4&`*#A!!"@X?[__^L`0*#C?`(`ZA5`
-MX.-Z`@#J`&"6Y6PPEN41`!/C$@``"@0PE^4!`'/C`P``&K@@U^$!.(/B`P!2
-MX0L```I7#8;B*`"`X@00A^+^___K`$!0X@!`H`-H`@`*!@"@X000H.'^___K
-M`$"@XV,"`.H50.#C80(`ZK2!U>$`8);E;#"6Y1``$^,2```*L$<!XP0`AN`,
-M$(?B`B"@X_[__^NT,);A`3!#XG,P_^8?`%/C!#"@@2`@H(.S((:!!@"@X0X0
-MA^(.($CB_O__ZP$`4.,`0*`#20(`"A5`X.-'`@#JM"'5X0!@EN4`,*#C(#"'
-MY1LPQ^6^,M?A0#"#X@,`4N%A`@`:!#"7Y0$`<^,'```:N"#7X0$X@^(#`%+A
-M`P``&B0PU^4#`%/C5P(`B@8``.I7#8;B*`"`X@00A^+^___K`(!0XD8"`!I-
-M`@#J#$"'X@0`H.$X&9_E_O__ZP``4.-'`@`*!`"@X2@9G^7^___K`0!PX@``
-MH#,``%#C`("@`P$PH`-2```*)(#7Y;ZBU^$!,'KB`#"@,P,`6.,!,(.#``!3
-MXS@"`!H``%KC`$"@`PT```H%`%KC!:"@DPV@H(,,D(KB"0"@X?[__^L`0%#B
-M*P(`"@0`H.$`$*#C'""@X_[__^L(H(3E`)"$Y02`A.4,D(3B"0"@X3`0A^((
-M()3E_O__ZQPPU^4``%/C(```"@`@H.,D.P'C`R"&YP$PH..\)P'C`C"&YU@@
-M@N(",(;G"#"4Y0T`4^,%,*`#6"!"`@(PA@=8((("`C"&!U\]H.,#@(;G7P^(
-MX@`"AN`$`(#B"1"@X0@@E.7^___K!CR(X@,QAN`(()3E!""#Y08`H.$,$(3B
-M""#4Y0@PH.$O_O_K3@$`ZE\/B.(``H;@!`"`X@D0H.$(()3E_O__ZP8\B.(#
-M,8;@"""4Y00@@^4&`*#A#!"$X@@@U.4(,*#A'_[_ZSX!`.H``%/C;@``"FPP
-MEN40`!/C:P``"APPU^4!`%/CXP$`&@``4.,1```*)`#7Y0`"AN"^(M?A!@N`
-MXAP`@.(P$(?B$`!2XQ`@H"/^___K`2"@XQ0X`>,#((;GOC+7X0T`4^,$((("
-M%#@!`P,@A@<[``#J!`"@X4P7G^7^___K``!0XR$``!H"(*#C%#@!XP,@AN<D
-M`-?E``*&X#!`A^*^(M?A!@N`XAP`@.($$*#A$`!2XQ`@H"/^___K)`#7Y0H`
-M@.*XAP'C``*(X```AN`$`(#B$!"$X@@@H./^___K)`#7Y0X`@.(``HC@``"&
-MX`0`@.(8$(3B"""@X_[__^L!(*#C$3L!XP,@QN<4``#J!`"@X;06G^7^___K
-M``!0XPP``!H$(*#C%#@!XP,@AN<D`-?E``*&X+XBU^$&"X#B'`"`XC`0A^(0
-M`%+C$""@(_[__^L"``#J`""@XQ0X`>,#((;G)"#7Y1@X`>,#((;G`2"@X[X_
-M@^(#(,;GOS]#X@,@EN=8,$/B`R"&YP8`H.$P$(?B<B#OYB0PU^5^_?_K!@"@
-MX?[__^L`@%#B@`$`"@!`H./H0(CE%#@!XP,PEN?L,(CE60$`ZK@W`>,#,);G
-M`@!3XP`PH!,!,*`#``!8XP`PH`,``%/C<0$`"FPPEN40`!/C;@$`"APPU^4!
-M`%/C50``&C"@A^*^(M?A$0Z(X@H0H.$0`%+C$""@(_[__^L$`*#AG!6?Y?[_
-M_^L``%#C!@``&@$PH./L,(CEOC+7X0T`4^,%,*`#[#"(!1H``.H$`*#A<!6?
-MY?[__^L``%#C#0``&@(PH./L,(CE\`"(XA`0BN(((*#C_O__ZP$,B.(8$(KB
-M"""@X_[__^L!(*#C$3L!XP,@QN<'``#J!`"@X2@5G^7^___K``!0XP0PH`/L
-M,(@%`#"@$^PPB!4<`*#C_O__ZP"0H.$``%#C'P``"A<`H./^___K`*!0X@,`
-M`!H)`*#A'!"@X_[__^L7``#J%`")XO[__^L5,*#CL##)X02@B>47,*#C"#")
-MY0`PH.,,,(GE$#")Y>PPF.4&,,KE"@"@X>`0B.(&(*#C_O__ZP<`BN(1'HCB
-M$""@X_[__^M+#8;B&`"`X@D0H.'^___K`$"@X^A`B.7T``#J``!0XQ$```HD
-M`-?E``*&X+XBU^$&"X#B'`"`XC`0A^(0`%+C$""@(_[__^L!(*#C%#@!XP,@
-MAN>^,M?A#0!3XP0@@@(4.`$#`R"&!SL``.H$`*#A%!2?Y?[__^L``%#C(0``
-M&@(@H.,4.`'C`R"&YR0`U^4``H;@,$"'XKXBU^$&"X#B'`"`X@00H.$0`%+C
-M$""@(_[__^LD`-?E"@"`XKB'`>,``HC@``"&X`0`@.(0$(3B"""@X_[__^LD
-M`-?E#@"`X@`"B.```(;@!`"`XA@0A.(((*#C_O__ZP$@H.,1.P'C`R#&YQ0`
-M`.H$`*#A?!.?Y?[__^L``%#C#```&@0@H.,4.`'C`R"&YR0`U^4``H;@OB+7
-MX08+@.(<`(#B,!"'XA``4N,0(*`C_O__ZP(``.H`(*#C%#@!XP,@AN<D(-?E
-M&#@!XP,@AN<!(*#COC^#X@,@QN>_/T/B`R"6YU@P0^(#((;G!@"@X3`0A^)R
-M(._F)##7Y;#\_^L&`*#A_O__ZP"`4.*R```*`$"@X^A`B.44.`'C`S"6Y^PP
-MB.6+``#J``!4XXD```H$`*#A#!"*XO[__^L`0*#CA```Z@!`EN5L,)3E$0`3
-MXQT```H$,)?E`0!SXP,``!JX(-?A`3B#X@,`4N$6```*5PV$XB@`@.($$(?B
-M_O__ZP!`4.(`0.`#<@``"DPWU.7=`%/C,`!3$P!`H!-M```:32?4Y0(@@N(@
-M`%+C(""@(PP@A^40`(?B'1V$X@P0@>+^___K`$"@XV(``.H50.#C8```ZK0Q
-MU>$<(I_E3""2Y0P@C>4`0);E;""4Y1``$N,=```*#F!#XG@'E.4``%#C`P``
-M"H07E.7^___K`#"@XW@WA.4``%;C`$"@TTT``-H&`*#A_O__ZW@'A.6$9X3E
-M``!0XPP```H.$(?B!B"@X?[__^L$`*#AW1"@XPP@C>(!,*#C_O__ZP$@H./0
-M,@'C`R#$YP!`H.,Z``#J%4#@XS@``.JT,=7A`$"6Y6P@E.40`!+C%0``"@Y@
-M0^)\!Y3E``!0XP,```J(%Y3E_O__ZP`PH.-\-X3E``!6XP!`H-,H``#:!@"@
-MX?[__^M\!X3EB&>$Y0``4.,$```*#A"'X@8@H.'^___K`$"@XQT``.H50.#C
-M&P``ZK0QU>$`0);E;""4Y1``$N,5```*#F!#XH`'E.4``%#C`P``"HP7E.7^
-M___K`#"@XX`WA.4``%;C`$"@TPL``-H&`*#A_O__ZX`'A.6,9X3E``!0XP0`
-M``H.$(?B!B"@X?[__^L`0*#C````ZA5`X.,``%3C$```&A``E>6T8=7A#2"@
-MX7\]PN,_,,/C"("3Y08PD.`(,-,P`("@,P``6.,#```:!Q"@X08@H.'^___K
-M`&"@X0``5N,-0.`3"P"@X;01U>'^___K!`"@X130C>+PC[WH#$"'X@0`H.$D
-M$)_E_O__ZP$`<.(``*`S`#"@XQ/^_^H`0*#CW/__ZA5`X./:___J%`$``!`!
-M```<`0``)`$````````00"WI`$``XP!`0.,`,*#C%#"$Y60`H./^___K%$"4
-MY0(`5.,!```:#`"?Y?[__^L$`)_E_O__ZQ"`O>@8````<$`MZ0!``.,`0$#C
-M&%"$X@4`H.$`$*#C`"``XP`@0./^___K!0"@X?[__^L",*#C%#"$Y7"`O>A`
-M0@\`@(0>`&#L4P#`V*<`@(U;`$!4B0``&[<`@*@2`0`V;@$`424"`&S<`H#Y
-M-P.(`@``N`(``*0#``"L`P``N`,``,`#``#,`P``W`,``.0#``!L````.``<
-M`!4```!,`0``4```````````````````````````````````````````````
+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
+M_^LJSHWBM#"<X0`P8^`%`*#A`!``XP`00.,%(*#A_O__ZP4`H.'^___KM`#(
+MX0``H.,,``#J!0"@X0`0`.,`$$#C!2"@X?[__^L%`*#A_O__Z[0`R.$``*#C
+M`@``Z@T`X.,```#J%0#@XZG?C>+PC[WH%````!P````P````-````$````!,
+M````<$`MZ0C03>(#8*#A@%.0Y0)`H.$`,*#C!#"-Y0`0DN4-(*#A?SW"XS\P
+MP^,(,)/E!""1X@,@TC``,*`S``!3XP,``!H$`(WB!""@X_[__^L"``#J!`"-
+MX@00H./^___KB#4#XP,PE><!0'3B`$"@,P``4^,!0(03``!4XQ4`X!,F```:
+M!#"=Y0``4^,`,-8%!#"-!00PG>4!`%/C"```&L0T`^,#,)7G``!3XQH```H%
+M`*#A"1"@XS/_+^$``*#C%@``Z@(`4^,(```:Q#0#XP,PE><``%/C#P``"@4`
+MH.$*$*#C,_\OX0``H.,+``#J`P!3XP@``!K$-`/C`S"5YP``4^,$```*!0"@
+MX0P0H.,S_R_A``"@XP```.H``*#C"-"-XG"`O>CP12WIJ=]-XH"#D.4`0*#C
+M#$"-Y1!`C>440(WE:BT/X_\O3^,J'HWBLD"!X1PPC>4<4(WB`&``XP!@0.,,
+M<(WB`P``Z@P`5.,&```*!`"'YP1`A.(%`*#A!A"@X?[__^L``%#C]O__&@Q`
+MG>4$`*#A`!``XP`00./^___K``!0XR\``!H0`)WE``!0X[P```H44)WE``!5
+MX[D```H8$(WB$""@X_[__^L`H*#A!0"@X?[__^N@<+#A`&"@$R).C1*S```*
+M!```Z@(`5>4!$%7E_O__ZP8`Q.<!8(;B`E"%X@<`5N'W__\Z>E#OYFI-#^/_
+M3T_C`!"@XP`0C>4(`*#A`R"@XRK.C>($,(S@_O__ZP<@A>`J'HWBM#"1X0,`
+M4N&;``"*"`"@X040H.%W(/_F(CZ-XO[__^L``%#CE```"I$``.H$`*#A`!``
+MXP`00./^___K``!0XR(``!H0`)WE``!0XX8```H44)WE``!5XX,```H8$(WB
+M$""@X_[__^L`H*#A!0"@X?[__^N@<+#A`&"@$R!`C1)]```*!```Z@(`5>4!
+M$%7E_O__ZP8`Q.<!8(;B`E"%X@<`5N'W__\Z(#"-X@`PC>4(`*#A`1"@XWH@
+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
+M``"T`P``O`,``,@#``#8`P``X`,``&P````X`!P`%0```$P!``!0````````
 M````````````````````````````````````````````````````````````
 M````````````````````````````````````````````````````````````
 M````````````````````````````````````````````````````````````
 M````````````````````````````````````````````````````````````
 M````````````````````````````````````````````````````````````
 M````````````````````````````````````````````````````````````
-M````````````````````````````````````````````````````````*+(!
-M@;"P7X0``````````+"PL(!`````L+"@@``!``"PL+"`"`$``+"PL(!8`0``
-ML+"@@*@!``"PL+"`[`$``+"PL(`(`@``L+"@@%P"``"PL+"`>`(``+"PL("4
-M`@``L+"P@*P"``"PJ`&`Y`(``+"PL(#L`@``L+"P@/0"``"PL+"`_`(``+"P
-ML(`$`P``L+"P@`P#``"PL+"`%`,``+"PHH!\`P``L+"P@(0#``"PL+"`C`,`
-M`+"PL("4`P``L+"P@)@#``"PL+"`G`,``+"N`8`D!```L+"P@"P$``"PL*"`
-MK`0``+"PJH#T!```KRBR@'P+``"PK`&`J`P```````!0$```L*L$@`02``"P
-ML*B`T!(``+"L`8!P%```L+"H@(@4``"PK`.`Y!<``+"PJ(`,&```L*\.@+0:
-M``"PK@&`-!T``+"PJH!H'0``L*X#@)`?``"PL*J`]"```+"PJ(`H(0``L+"J
-M@'@A``"PL*J`Y"$``+"L!X`0)```L+"N@*@G``"PL*Z`\"@``+"PJH`(*@``
-ML*\$@,0M``"PL*B`W"T``%^$`H"$+P``L*H'@-@P``!?A`J`.#(``+"K`H"\
-M,P``KPBQ@/PT``"PL*J`<#4``*]$LH`\00``L*\&@&A"``"PL*J`S$(``+"P
-MKH#L0P``L*D$@$1$``"PJ02`G$0``+"I!(#<1```L*\*@"1'``"O/QB`B$T`
-M`+"PJH`P3@``L+"N@!1/``"PL*B`1$\``+"O!(!L7@``L+"H@*Q>``"PL*J`
-M`%#R!`L*"0@'!@4$`P(!`/\```!R='=?=WA?<V5T7W=A<```0U-#04X@4P$`
-M`%,```````!0\@0%$!`0#0````$`````````!0````!0\@3@BP```D@``')T
-M=U]W<FET93,R``````#ABP```4@0*')T=U]R96%D,S(```````#BBP``````
-M`&1R:79E<E]E>'0```````#CBP````````````````````````````#DBP``
-M`4@``&%P:6YF;P````````````#EBP```D@``'-E='!I9`````````````#F
-MBP```4@``'=P<U]S=&%R=`````````#GBP```4@``&=E=%]S96YS:71I=FET
-M>0#HBP```4@``'=P<U]P<F]B7W)E<5]I90#IBP```4@``'=P<U]A<W-O8U]R
-M97%?:67JBP```4@``&-H86YN96Q?<&QA;@````#KBP```D@``&1B9P``````
-M``````````#LBP```T@``')F=P````````````````#MBP```D@0*')F<@``
-M``````````````#PBP``0"```'`R<%]S970```````````#QBP``0"!`*'`R
-M<%]G970```````````#RBP``0"`0('`R<%]G970R``````````#VBP``0"``
-M`'!M7W-E=`````````````#XBP``$"```')E<F5G7VYD7VYA;64```#ZBP``
-M@"```&5F=7-E7W-E=`````````#[BP``@"``+V5F=7-E7V=E=``````````P
-M>"4P-7@``"P```!R96%L;6%P`"5S(`H`````)7,@"3!X)3`R>`D`)7,@)3`R
-M6``E<PD`)7,*`')M87``````)7,@,'@E,#)8````)7,@`')E86QR87<`)7,@
-M)3`R>``E<PH)`````&UA8P!V:61P:60``&%B;&5R87<`)7,@.B!;(&%V86EL
-M86)L92!R87<@<VEZ95T@/2`E9``E<R`Z($-O;6UA;F0@;F]T(&9O=6YD"@!W
-M;6%P`````'=R87<`````0V]M;6%N9"!N;W0@9F]U;F0*``!D:7-A8FQE)60`
-M``!L<',]`````&EP<ST`````)74``#!X)3`X>```/%=)1DE`4D5!3%1%2SX`
-M`%=%4`!N;VYE`````%1+25``````0T--4`````!)145%(#@P,BXQ,6)N````
-M245%12`X,#(N,3%B`````$E%144@.#`R+C$Q8F=N``!)145%(#@P,BXQ,6)G
-M````245%12`X,#(N,3%A;@```$E%144@.#`R+C$Q80````!)145%(#@P,BXQ
-M,6=N````245%12`X,#(N,3%G`````'5N87-S;V-I871E9``````@4F%T97,@
-M*$UB+W,I.B```````"XU```E9"5S(````'=P85]I93T`)3`R>`````!R<VY?
-M:64]`"5S.B!R9G!W<G-T871E7V-H96-K(&9A:6PN"@`E<SH@=&5M<"T^<V%?
-M9F%M:6QY("$]($%24$A21%]%5$A%4BX*````)6,``$%.1%)/241?5TE&25]#
-M341?4U1!4E0N+BXN+BXN+BXN"@```'=A:71I;F<@9F]R('=I9FD@9')I=F5R
-M('1O(&)E(')E861Y+BXN"@!35$%25````$]+``!!3D123TE$7U=)1DE?0TU$
-M7U-43U`N+BXN+BXN+BXN"@````!35$]0`````%=)1DD@<G-S:2`E9`````!,
-M24Y+4U!%140@)60`````34%#041$4B`]("4P,G@Z)3`R>#HE,#)X.B4P,G@Z
-M)3`R>#HE,#)X`"4J<R`E<P``55,``$55``!*4```0TX``&-O=6YT<GD@8V]D
-M93H@)7,L('-E="!C:&%N;F5L('!L86XZ("5D"@!38V%N+4-H86YN96QS(#T@
-M)60``$=E="!#:&%N;F5L<R!R971U<FX@)60@*&EN:71?8VAA;FYE;%]P;&%N
-M/25D*0H``')T;#@Q.#A?=VEF:5]W86ME;&]C:P```%)34TD`````3$E.2U-0
-M145$````34%#041$4@!30T%.+4%#5$E610!30T%.+5!!4U-)5D4`````0T]5
-M3E1260!30T%.+4-(04Y.14Q3`````$=#0SH@*$=.52D@-"XT+C``02H```!A
-M96%B:0`!(`````4W+4$`!@H'00@!$@04`14!%P,8`1D!&@(>`0`N<WEM=&%B
-M`"YS=')T86(`+G-H<W1R=&%B`"YR96PN=&5X=``N<F5L+F1A=&$`+F)S<P`N
-M05)-+F5X=&%B`"YR96PN05)-+F5X:61X`"YR;V1A=&$`+G)O9&%T82YS='(Q
-M+C0`+F-O;6UE;G0`+FYO=&4N1TY5+7-T86-K`"Y!4DTN871T<FEB=71E<P``
-M`````````````````````````````````````````````````````!\````!
-M````!@`````````T````Y%X`````````````!``````````;````"0``````
-M````````-)$``'@8```/`````0````0````(````*0````$````#````````
-M`!A?``"\`0`````````````$`````````"4````)``````````````"LJ0``
-MB`(```\````#````!`````@````O````"`````,`````````V&```&``````
-M``````````@`````````-`````$````"`````````-A@```,````````````
-M```$`````````$,````!``!P@@````````#D8```0`(```$`````````!```
-M```````_````"0``````````````-*P``%@"```/````!P````0````(````
-M3@````$````"`````````"1C``!(`@`````````````$`````````%8````!
-M````,@````````!L90``]`,`````````````!`````$```!E`````0``````
-M````````8&D``!(```````````````$`````````;@````$`````````````
-M`')I```````````````````!`````````'X````#``!P``````````!R:0``
-M*P```````````````0`````````1`````P``````````````G6D``(X`````
-M``````````$``````````0````(``````````````-1L``#@%@``$````/X`
-M```$````$`````D````#``````````````"T@P``?0T``````````````0``
-M`````````````````````````````0``````````````!`#Q_P``````````
-M``````,``0`````````````````#``,``````````````````P`%``\`````
-M````0`````(``0`9``````````````````$``````````````````P`&````
-M``````````````,`!P`<````0````,`````"``$`&0```$`````````````!
-M`"X``````0``"`````(``0`9``````$```````````$`/@````@!``!0````
-M`@`!`!D````(`0```````````0!.````6`$``%`````"``$`&0```%@!````
-M```````!`!D```"H`0```````````0!>````[`$``!P````"``$`&0```.P!
-M```````````!`&T````(`@``5`````(``0`9````"`(```````````$`?0``
-M`%P"```<`````@`!`!D```!<`@```````````0"-````>`(``!P````"``$`
-M&0```'@"```````````!`)X```"4`@``&`````(``0`9````E`(`````````
-M``$`KP```*P"```X`````@`!`!D```"L`@```````````0"_````Y`(```@`
-M```"``$`&0```.0"```````````!`-````#L`@``"`````(``0`9````[`(`
-M``````````$`U@```/0"```(`````@`!`!D```#T`@```````````0#R````
-M_`(```@````"``$`&0```/P"```````````!``D!```$`P``"`````(``0`9
-M````!`,```````````$`'P$```P#```(`````@`!`!D````,`P``````````
-M`0`N`0``%`,``&@````"``$`&0```!0#```````````!`#H!``!\`P``"```
-M``(``0`9````?`,```````````$`1@$``(0#```(`````@`!`!D```"$`P``
-M`````````0!2`0``C`,```@````"``$`&0```(P#```````````!`!D```"4
-M`P```````````0`9````F`,```````````$`&0```)P#```````````!`%\!
-M```D!```"`````(``0`9````)`0```````````$`:`$``"P$``"``````@`!
-M`!D````L!````````````0!_`0``K`0``$@````"``$`&0```*P$````````
-M```!`(X!````````````````"@"3`0``]`0``(@&```"``$`&0```/0$````
-M```````!`*0!```(````````````"@"I`0``#`````````````H`K@$``"@`
-M```````````*`+,!```X````````````"@"X`0``4`````````````H`O@$`
-M`%@````````````*`,0!```P````````````"@#)`0``8`````````````H`
-MSP$``&@````````````*`-4!``!L````````````"@#;`0``=```````````
-M``H`X0$``'P````````````*`.<!``"<````````````"@#M`0``9`L`````
-M``````$`\`$``'P+```L`0```@`!`!D```!\"P```````````0#^`0``J`P`
-M`*@#```"``$`&0```*@,```````````!``\"``"T````````````"@`5`@``
-MO`````````````H`[0$``$P0```````````!`!L"``!0$```M`$```(``0`9
-M````4!````````````$`+0(````````````````%`#<"``#8````````````
-M"@#M`0```!(```````````$`&0````02```````````!`#T"``#0$@``H`$`
-M``(``0`9````T!(```````````$`2`(``.0````````````*`$X"``#L````
-M````````"@!4`@``]`````````````H`6@(``'`4```8`````@`!`!D```!P
-M%````````````0!I`@``B!0``%P#```"``$`&0```(@4```````````!`.T!
-M``"\%````````````0`9````^!0```````````$`=@(``.07```H`````@`!
-M`!D```#D%P```````````0".`@``#!@``*@"```"``$`&0````P8````````
-M```!`)X"``"T&@``@`(```(``0`9````M!H```````````$`KP(``#0=```T
-M`````@`!`!D````T'0```````````0"]`@``^`````````````H`PP(``&@=
-M```H`@```@`!`!D```!H'0```````````0#4`@``D!\``&0!```"``$`&0``
-M`)`?```````````!`.T!```0(````````````0`9````+"````````````$`
-MXP(``/0@```T`````@`!`!D```#T(````````````0#S`@````$`````````
-M``H`^0(``"@A``!0`````@`!`!D````H(0```````````0`*`P``>"$``&P`
-M```"``$`&0```'@A```````````!`!D#``#D(0``+`(```(``0`9````Y"$`
-M``````````$`*`,``!`D``"8`P```@`!`!D````0)````````````0`[`P``
-M$`$```````````H`[0$``*`G```````````!`$$#``"H)P``2`$```(``0`9
-M````J"<```````````$`[0$```PH```````````!`!D````<*```````````
-M`0!4`P``%`$```````````H`6@,``!P!```````````*`&`#```D`0``````
-M````"@!F`P``\"@``!@!```"``$`&0```/`H```````````!`.T!```8*0``
-M`````````0`9````1"D```````````$`=@,```@J``"\`P```@`!`!D````(
-M*@```````````0#M`0``)"L```````````$`&0```&0K```````````!`.T!
-M````+````````````0`9````0"P```````````$`A0,````````````````)
-M`(\#``#$+0``&`````(``0`9````Q"T```````````$`H0,``-PM``"H`0``
-M`@`!`!D```#<+0```````````0"Q`P``A"\``%0!```"``$`&0```(0O````
-M```````!`.T!``#4,````````````0#!`P``V#```&`!```"``$`&0```-@P
-M```````````!`-(#```X,@``A`$```(``0`9````.#(```````````$`X@,`
-M`"P!```````````*`.@#```\`0``````````"@#N`P``3`$```````````H`
-M]`,``%P!```````````*`/H#``!L`0``````````"@``!```?`$`````````
-M``H`!@0``(P!```````````*``P$``"<`0``````````"@`2!```K`$`````
-M``````H`&`0``+PS``!``0```@`!`!D```"\,P```````````0`I!```````
-M``````````,`,P0``/PT``!T`````@`!`!D```#\-````````````0!#!```
-M<#4``,P+```"``$`&0```'`U```````````!`%($``"\`0``````````"@!8
-M!```T`$```````````H`7@0``,P!```````````*`&0$``#4`0``````````
-M"@!J!```W`$```````````H`<`0``.0!```````````*`'8$``#L`0``````
-M````"@!\!```/$$``"P!```"``$`&0```#Q!```````````!`(P$``!H0@``
-M9`````(``0`9````:$(```````````$`G`0``,Q"```@`0```@`!`!D```#,
-M0@```````````0#M`0``X$,```````````$`&0```.Q#```````````!`!D`
-M``!$1````````````0`9````G$0```````````$`JP0``-Q$``!(`@```@`!
-M`!D```#<1````````````0#M`0``'$<```````````$`NP0``"1'``!D!@``
-M`@`!`!D````D1P```````````0#M`0``_$@```````````$`&0```"!)````
-M```````!`,L$```\`@``````````"@#1!```B`(```````````H`UP0``)`"
-M```````````*`-T$``"4`@``````````"@#C!```N`(```````````H`Z00`
-M`,`"```````````*`.\$``#0`@``````````"@#U!```X`(```````````H`
-M^P0```@#```````````*``$%```0`P``````````"@`'!0``%`,`````````
-M``H`#04``!@#```````````*`!,%```<`P``````````"@`9!0``(`,`````
-M``````H`'P4``$@#```````````*`"4%``!<`P``````````"@#M`0``>$T`
-M``````````$`*P4``(A-``"H`````@`!`!D```"(30```````````0#M`0``
-MR$T```````````$`&0```-A-```````````!`#L%```P3@``Y`````(``0`9
-M````,$X```````````$`204``!1/```P`````@`!`!D````43P``````````
-M`0`9````1$\```````````$`[0$``!A0```````````!`!D````H4```````
-M`````0#M`0``C%(```````````$`&0```-A2```````````!`.T!``!87@``
-M`````````0`9````;%X```````````$`[0$``*A>```````````!`!D```"L
-M7@```````````0!5!0``C`,```````````H``````````````````P`)`%L%
-M````````!`````$`"0#M`0````````````````D`9P4```0````-`````0`)
-M`',%```4````#P````$`"0""!0``-`````0````!``D`C@4``#@````%````
-M`0`)`)D%``!`````"0````$`"0"D!0``3`````0````!``D`L`4``%````#X
-M`0```0`)`.T!`````````````````P#!!0``;````.`````!``,`S@4``$P!
-M``!P`````0`#``````````````````,`"@#M`0````````````````4`X@4`
-M```````0`````0`%`/,%```0`````0````$`!0`(!@``$0````$````!``4`
-M&P8``!@```!(`````0`%``````````````````,`#``````````````````#
-M``L``````````````````P`-`#`&`````````````!````!'!@``J`$``$0`
-M```2``$`9`8`````````````$````&L&``"4`P``!````!(``0!X!@``F`,`
-M``0````2``$`A`8``)P#``"(````$@`!`)`&`````````````!````"8!@``
-M```````````0````I`8`````````````$````+4&`````````````!````"_
-M!@`````````````0````Q@8`````````````$````,T&`````````````!``
-M``#@!@`````````````0````YP8`````````````$````/8&````````````
-M`!`````/!P`````````````0````(`<`````````````$````#4'````````
-M`````!````!&!P`````````````0````5`<`````````````$````&@'````
-M`````````!````!O!P`````````````0````A@<`````````````$````(T'
-M`````````````!````"5!P`````````````0````IP<`````````````$```
-M`+,'`````````````!````##!P`````````````0````V@<`````````````
-M$````.P'```$$@``S````!(``0#]!P`````````````0````!0@`````````
-M````$`````\(`````````````!`````="``````````````0````,P@`````
-M````````$````#H(`````````````!````!'"``````````````0````4P@`
-M````````````$````&`(`````````````!````!P"``````````````0````
-M@0@`````````````$````)D(`````````````!````"I"``````````````0
-M````O`@`````````````$````,H(`````````````!````#9"```````````
-M```0````Z0@`````````````$````/@(`````````````!`````$"0``````
-M```````0````#PD`````````````$````!L)`````````````!`````G"0``
-M```````````0````,@D`````````````$````#X)`````````````!````!5
-M"0`````````````0````80D`````````````$````',)`````````````!``
-M``"("0`````````````0````F0D`````````````$````+$)````````````
-M`!````#*"0`````````````0````UPD`````````````$````.@)````````
-M`````!````#Z"0`````````````0````!0H`````````````$````!D*````
-M`````````!`````\"@`````````````0````7PH`````````````$````',*
-M`````````````!````"0"@`````````````0````F0H`````````````$```
-M`+(*`````````````!````"^"@`````````````0````Q0H`````````````
-M$````-<*`````````````!````#R"@`````````````0`````0L`````````
-M````$`````\+`````````````!`````K"P`````````````0````0`L``.Q#
-M``!8````$@`!`%\+`````````````!````!S"P``1$0``%@````2``$`CPL`
-M`)Q$``!`````$@`!`*\+`````````````!````#""P`````````````0````
-MX0L`````````````$````.X+`````````````!````#Z"P`````````````0
-M`````@P`````````````$`````P,`````````````!`````9#```````````
-M```0````(`P`````````````$````"P,`````````````!`````^#```````
-M```````0````4`P`````````````$````&,,`````````````!````!S#```
-M1$\``"@/```2``$`?0P`````````````$````)$,`````````````!````"?
-M#``````````````0````M@P`````````````$````,(,`````````````!``
-M``#8#``````````````0````Y@P``&Q>``!`````$@`!`/X,````````````
-M`!`````0#0``K%X``#@````2``$`*`T`````````````$````#<-````````
-M,````!$``P!!#0``,````"0````1``,`5@T``!0````$````$0`%`&P-``!4
-M````&````!$``P``:6]C=&Q?;&EN=7@N8P!H97@R;G5M7VD`)&$`=W!A7W-E
-M=%]A=71H7V%L9W,`<G1W7W=X7W-E=%]F<F5Q`')T=U]W>%]G971?;6]D90!R
-M='=?=WA?9V5T7W-E;G,`<G1W7W=X7V=E=%]R=',`<G1W7W=X7W-E=%]F<F%G
-M`')T=U]W>%]G971?9G)A9P!R='=?=WA?9V5T7W)E=')Y`')T=U]W>%]G971?
-M<&]W97(`<G1W7W=X7W=R:71E7W)F`')T=U]W>%]P<FEV7VYU;&P`9'5M;7D`
-M<G1W7W=X7W-E=%]M=&M?=W!S7W!R;V)E7VEE`')T=U]W>%]G971?<V5N<VET
-M:79I='D`<G1W7W=X7W-E=%]M=&M?=W!S7VEE`')T=U]D<G9E>'1?:&1L`')T
-M=U]S971?<&ED`')T=U]P,G!?<V5T`')T=U]P,G!?9V5T`')T=U]P,G!?9V5T
-M,@!R='=?=&1L<P!R='=?9V5T7W=I<F5L97-S7W-T871S`')T=U]W>%]R96%D
-M7W)F`"Y,0S``<G1W7VUP7V5F=7-E7V=E=``N3$,Q`"Y,0S(`+DQ#-0`N3$,X
-M`"Y,0S$Q`"Y,0S$R`"Y,0S8`+DQ#,3,`+DQ#,30`+DQ#,34`+DQ#,38`+DQ#
-M,3<`+DQ#,3@`)&0`<G1W7W=P<U]S=&%R=`!R='=?;7!?969U<V5?<V5T`"Y,
-M0S$Y`"Y,0S(P`')T=U]R97)E9U]N9%]N86UE`"Y,04Y#2$]2,``N3$,R,@!R
-M='=?<&U?<V5T`"Y,0S(S`"Y,0S(T`"Y,0S(U`')T=U]W>%]W<FET93,R`')T
-M=U]D8F=?<&]R=`!R='=?=WA?<V5T7V-H86YN96Q?<&QA;@!R='=?9V5T7V%P
-M7VEN9F\`<G1W7VUP7VEO8W1L7VAD;`!R='=?=WA?<F5A9#,R`"Y,0S(V`')T
-M=U]W>%]S971?<&UK:60`<G1W7W=X7V=E=%]E;F,`<G1W7W=X7V=E=%]N:6-K
-M`"Y,0S(W`')T=U]W>%]G971?97-S:60`<G1W7W=X7V=E=%]W87``<G1W7W=X
-M7W-E=%]E;F,`=W!A7W-E=%]E;F-R>7!T:6]N`"Y,0S(X`')T=U]W>%]S971?
-M96YC7V5X=``N3$,R.0`N3$,S,``N3$,S,0!R='=?=WA?<V5T7V%U=&@`<G1W
-M7W-E=%]W<&%?:64`+DQ!3D-(3U(Q`')T=U]W>%]S971?9V5N7VEE`')T=U]W
-M>%]G971?<F%T90!R='=?=WA?<V5T7W)A=&4`<G1W7W=X7W-E=%]E<W-I9`!R
-M='=?=WA?9V5T7VYA;64`+DQ#,S(`+DQ#,S,`+DQ#,S0`+DQ#,S4`+DQ#,S8`
-M+DQ#,S<`+DQ#,S@`+DQ#,SD`+DQ#-#``<G1W7W=X7V=E=%]R86YG90`N3$%.
-M0TA/4C(`<G1W7W=X7V=E=%]F<F5Q`'1R86YS;&%T95]S8V%N`"Y,0S0Q`"Y,
-M0S0S`"Y,0S0R`"Y,0S0T`"Y,0S0U`"Y,0S0V`"Y,0S0W`')T=U]W>%]G971?
-M<V-A;@!R='=?=WA?<V5T7VUL;64`<G1W7W=X7W-E=%]W87``<G1W7W=X7W-E
-M=%]S8V%N`')T=U]W>%]S971?<')I=@`N3$,U,@`N3$,U-``N3$,U-0`N3$,U
-M-@`N3$,U-P`N3$,U.``N3$,U.0`N3$,V,``N3$,V,0`N3$,V,@`N3$,V,P`N
-M3$,V-``N3$,V-0`N3$,V-@`N3$,V-P`N3$,V.`!R='=?=WA?<V5T7VUO9&4`
-M<V5T7V=R;W5P7VME>0!S971?=V5P7VME>0`N3$,V.0!#+C8Q.2XT,3$Y-@!#
-M+C8T-BXT,3DR,@!?7V9U;F-?7RXT,30Y-@!#+C<U,2XT,S<X,@!#4U=40T@N
-M-S@T`$-35U1#2"XW.#<`0RXW,S,N-#,U-34`<G1W7W!R:79A=&5?87)G<P!R
-M='=?:&%N9&QE<G,`<G1W7W!R:79A=&5?:&%N9&QE<@!O;&1?:69N86UE+C0R
-M-S0X`&]L9%]B4F5G57-E3&5D+C0R-S4P`&]L9%]I<'-?;6]D92XT,C<T.0!R
-M=&PX,3@X7W-U<W!E;F1?;&]C:P!?7V%E86)I7W5N=VEN9%]C<'!?<'(P`')T
-M=U]I<U]F:71?<F5G=6QA=&]R>5]D;VUA:6X`=6E?<&ED`&UA8U]R96=?9'5M
-M<`!B8E]R96=?9'5M<`!R9E]R96=?9'5M<`!S<')I;G1F`%]R='=?;65M<V5T
-M`%]?8V]P>5]F<F]M7W5S97(`7U]M96UZ97)O`'-T<G-E<`!S=')C;7``<G1W
-M7V5F=7-E7VUA<%]R96%D`'-T<FQE;@!S:6UP;&5?<W1R=&]U;`!%1E5315]'
-M971%9G5S941E9FEN:71I;VX`<G1W7V5F=7-E7V%C8V5S<P!E9G5S95]'971#
-M=7)R96YT4VEZ90!E9G5S95]'971-87A3:7IE`&ME>5\R8VAA<C)N=6T`<G1W
-M7V5F=7-E7VUA<%]W<FET90!P<FEN=&L`7U]A96%B:5]U;G=I;F1?8W!P7W!R
-M,0!I9FYA;64`<W1R;F-P>0!R='=?8VAA;F=E7VEF;F%M90!?<G1W7VUE;6-M
-M<`!R='=?<W=?;&5D7VEN:70`<G1W7V9R965?;F5T=V]R:U]Q=65U90!R='=?
-M<W=?;&5D7V1E:6YI=`!R9G!W<G-T871E7V-H96-K`&II9F9I97,`;6]D7W1I
-M;65R`'-T<E\R8VAA<C)N=6T`3&5A=F5!;&Q0;W=E<E-A=F5-;V1E`'-S8V%N
-M9@!?<G1W7W=R:71E,S(`7W)T=U]W<FET93@`7W)T=U]W<FET93$V`')T=U]G
-M971?<W1A:6YF;P!L;V-A;%]B:%]D:7-A8FQE`')T=U]E;F1?;V9?<75E=65?
-M<V5A<F-H`&QO8V%L7V)H7V5N86)L90!R='=?<V5T7V-H<&QA;E]C;60`<G1W
-M7VUS;&5E<%]O<P!R='=?9V5T7W=P85]I90!R='=?9V5T7W=P83)?:64`7U]C
-M;W!Y7W1O7W5S97(`7W)T=U]M86QL;V,`7W)T=U]R96%D.`!?<G1W7W)E860Q
-M-@!?<G1W7W)E860S,@!?<G1W7VUF<F5E`%]R='=?;65M8W!Y`')T=U]S971?
-M.#`R7S$Q7V%D9%]W97``<G1W7W-E=%]K97D`<G1W7W-E='-T86ME>5]C;60`
-M<G1W7V=E=%]B8VUC7W-T86EN9F\`<G1W7V1I<V%S<V]C7V-M9`!R='=?:6YD
-M:6-A=&5?9&ES8V]N;F5C=`!R='=?9G)E95]A<W-O8U]R97-O=7)C97,`7W)T
-M=U]Z;6%L;&]C`')T=U]P87)S95]W<&%?:64`<G1W7W!A<G-E7W=P83)?:64`
-M<G1W7V=E=%]I90!R='=?<V5T9&%T87)A=&5?8VUD`')T=U]S971?.#`R7S$Q
-M7VEN9G)A<W1R=6-T=7)E7VUO9&4`<G1W7W-E=%\X,#)?,3%?875T:&5N=&EC
-M871I;VY?;6]D90!R='=?<V5T7S@P,E\Q,5]S<VED`')T=U]I<U]C8VMR871E
-M<V]N;'E?:6YC;'5D960`<VYP<FEN=&8`<G1W7VES7V-C:W)A=&5S7VEN8VQU
-M9&5D`')T=U]C:#)F<F5Q`&UE;6-P>0!R='=?=F%L:61A=&5?<W-I9`!R='=?
-M9V5T7V-A<&%B:6QI='E?9G)O;5]I90!R='=?9V5T7W-E8U]I90!R='=?:7-?
-M=W!S7VEE`')T=U]S971?.#`R7S$Q7V1I<V%S<V]C:6%T90!R='=?<V5T7S@P
-M,E\Q,5]B<W-I9`!R='=?:6YD:6-A=&5?=WA?9&ES87-S;V-?979E;G0`=VER
-M96QE<W-?<V5N9%]E=F5N=`!R='=?:6YD:6-A=&5?=WA?87-S;V-?979E;G0`
-M:6YD:6-A=&5?=WA?<V-A;E]C;VUP;&5T95]E=F5N=`!R='=?<VET97-U<G9E
-M>5]C;60`<G1W7W-E=%\X,#)?,3%?8G-S:61?;&ES=%]S8V%N`%]R='=?=FUA
-M;&QO8P!?<G1W7W9M9G)E90!S=')N8VUP`'=A:V5?;&]C:P!S;&5E<%]R97-U
-M;64`;7-L965P`'=A:V5?=6YL;V-K`&EN:71?8VAA;FYE;%]P;&%N`')T=U]S
-M971O<&UO9&5?8VUD`%]R='=?:6YI=%]L:7-T:&5A9`!R='=?96YQ=65U95]C
-M;60`<G1W7VEO8W1L`&9L=7-H7V%L;%]C86U?96YT<GD`<G1W7W-T85]F;'5S
-M:`!U<&1A=&5?<W1A7VEN9F]?87!M;V1E`&%P7V9R965?<W1A`')T=U]C:&5C
-M:U]B96%C;VY?9&%T80!U<&1A=&5?8F5A8V]N`')T;#@Q.#A?<&]W97)?<V%V
-M95]E>&ET`'=A:V5?;&]C:U]D97-T<F]Y`')T;#@Q.#A?<&]W97)?<V%V95]I
-M;FET`'=A:V5?;&]C:U]I;FET`')T=U]R871E<P!A;F1R;VED7W=I9FE?8VUD
-M7W-T<@!R=&PX,3@X7W=A:V5L;V-K7VEN:70`<G1W7VAA;F1L97)S7V1E9@``
-M``!<`P``*P`!`&`#```L``$`W`0``"L[``#@!```+#L``.@$```<!`$`-`4`
-M`!P%`0!$!0``'`4!`'P%```<!@$`G`4``!P'`0#`!0``*SX``,0%```L/@``
-M[`4``!P(`0``!@``*S\```0&```L/P``"`8``!P)`0`D!@``'`H!`#P&```<
-M!0$`3`8``!P$`0!8!@``*T```%P&```L0```<`8``!P$`0"4!@``'`0!`+`&
-M```<!`$`Q`8``!P$`0#D!@``'`0!`/@&```<"P$`#`<``"M!```0!P``+$$`
-M`!0'```<"0$`1`<``!P,`0!8!P``'`P!`(P'```<#0$`N`<``!P*`0#(!P``
-M'`4!`/`'```<!`$```@``!P$`0`4"```'`L!`"P(```K0@``,`@``"Q"```T
-M"```'`D!`%@(```<#@$`<`@``!P%`0!X"```*T,``'P(```L0P``A`@``"M$
-M``"("```+$0``(P(```K10``D`@``"Q%``"D"```'`0!`,`(```<!`$`X`@`
-M`!P$`0#T"```'`L!``@)```K1@``#`D``"Q&```0"0``'`D!`%0)```<#0$`
-M>`D``!P*`0"("0``'`4!`*P)```<!`$`O`D``!P$`0#0"0``'`L!`.0)```K
-M1P``Z`D``"Q'``#L"0``'`D!`#`*```<#0$`5`H``!P*`0!D"@``'`4!`(@*
-M```<!`$`F`H``!P$`0"L"@``'`L!`,`*```K2```Q`H``"Q(``#("@``'`D!
-M`.@*```<#P$`\`H``!P0`0`$"P``*TD```@+```L20``$`L``!P$`0`8"P``
-M'`L!`"P+```K2@``,`L``"Q*```X"P``'`0!`$`+```<"P$`9`L```+U``!H
-M"P```O4``&P+```"]0``<`L```+U``!T"P```O4``'@+```"]0``R`L``!P&
-M`0#8"P``'`<!`-P,```K/@``X`P``"P^```$#0``'`@!`!@-```K4```'`T`
-M`"Q0```@#0``'`D!`$P-```<#`$`6`T``!P+`0!X#0``'!$!`+0-```<#0$`
-MW`T``!P2`0#P#0``*U$``/0-```L40``^`T``!P)`0`D#@``'`P!`#`.```<
-M"P$`4`X``!P1`0"`#@``'`X!`)0.```K1@``F`X``"Q&``"<#@``'`D!`,0.
-M```<"P$`[`X``!P1`0`D#P``'`T!`$P/```<$@$`8`\``"M'``!D#P``+$<`
-M`&@/```<"0$`D`\``!P+`0"P#P``'!$!`.@/```<#0$`$!```!P2`0`D$```
-M'!,!`$P0```"]0``8!```"M5``!D$```+%4``'@0```K%0$`?!```"P5`0",
-M$```'!8!`-00```<!@$`[!```!P'`0``$0``'!<!``P1```K50``$!$``"Q5
-M```4$0``*U8``!@1```L5@``(!$``!P8`0!`$0``'!D!`%`1```K50``5!$`
-M`"Q5``!H$0``'!8!`'@1```K5@``?!$``"Q6``"$$0``'!@!`)@1```<&@$`
-MN!$``"M5``"\$0``+%4``-@1```<&P$``!(```($``!\$@``*QT!`(`2```L
-M'0$`L!(``!P>`0#H$@``*UL``.P2```L6P``]!(``!P8`0!,$P``'!\!`(03
-M```<(`$`I!,``"M<``"H$P``+%P``+`3```<&`$`W!,``"M=``#@$P``+%T`
-M`.03```<(0$`"!0``"L=`0`,%```+!T!`#P4```<'@$`4!0``!P<`0!\%```
-M'"(!`+P4```"`@``P!0```("``#$%````@(``,@4```"`@``S!0```("``#0
-M%````@(``-04```"`@``V!0```("``#<%````@(``.`4```"`@``Y!0```("
-M``#H%````@(``.P4```"`@``\!0```("``#T%````@(``!P5```<(P$`,!4`
-M`!PD`0!$%0``'"(!`"P6```<)0$`=!8``!PF`0"\%@``'"<!`/`6```<*`$`
-M+!<``!P!`0!`%P``'`(!`%07```<`P$`Q!<``!PC`0#4%P``'",!`/@7```<
-M*0$`4!@``!PJ`0"P&```'`8!`,@8```<!P$`U!@``!PF`0`0&0``'"<!`)`9
-M```<*`$`L!D``!PK`0#D&0``'"P!`"P:```<*`$`<!H``!PM`0"D&@``'!@!
-M`.@:```<+@$`*!L``!P&`0!(&P``'`<!`,0;```<+P$`V!L``!PP`0#L&P``
-M'#$!`"`<```<(P$`-!P``!PD`0!('```'"(!`/0<```<+0$`+!T``!PR`0!$
-M'0``'#$!`%`=```K;```5!T``"QL``!<'0``'`0!`)@=```<,P$`M!T``!P8
-M`0#H'0``'!@!``P>```<,P$`A!X``!P8`0"H'@``'`4!`/`>```<!0$`/!\`
-M`!PS`0!8'P``'#,!`!`@```"`@``%"````("```8(````@(``!P@```"`@``
-M("````("```D(````@(``"@@```"`@``="```!PS`0`0(0``*W4``!0A```L
-M=0``'"$``!PS`0!@(0``'#,!`)@A```<!0$`Q"$``!PS`0#8(0``'`4!``0B
-M```<!0$`U",``!PS`0#@(P``'#0!`'`D```K?@``="0``"Q^``!X)```'`D!
-M`-0D```<+@$`["0``!P%`0`H)0``'#,!`$`E```<-`$`;"4``!PS`0"0)0``
-M'#4!`-`E```<)0$`Y"4``!P)`0`T)@``'#,!`$`F```<"0$`6"8``!PS`0!H
-M)@``'#,!`(0F```<-@$`L"8``!PS`0#4)@``'#,!`/0F```<,P$`'"<``!PU
-M`0`D)P``'#<!`#@G```<"0$`F"<``!PR`0"@)P```O4``*0G```"]0``Q"<`
-M`!PN`0#@)P``'`4!`/@G```<!0$`#"@```("```0*````@(``!0H```"`@``
-M&"@```("```<*```*WX``"`H```L?@``*"@``"N$```L*```+(0``#0H```K
-MA0``."@``"R%``!`*```*X8``$0H```LA@``5"@``!P6`0"<*```'#,!`+PH
-M```<,P$`W"@``!PR`0`8*0```@(``!PI```"`@``("D```("```D*0```@(`
-M`"@I```"`@``+"D```("```P*0```@(``#0I```"`@``."D```("```\*0``
-M`@(``$`I```"`@``U"D``!PX`0#<*0``'#D!`.0I```<.@$`>"H``!P[`0"4
-M*@``'#,!`+@J```</`$`["H``!P]`0`D*P```@(``"@K```"`@``+"L```("
-M```P*P```@(``#0K```"`@``."L```("```\*P```@(``$`K```"`@``1"L`
-M``("``!(*P```@(``$PK```"`@``4"L```("``!4*P```@(``%@K```"`@``
-M7"L```("``!@*P```@(````L```"`@``!"P```("```(+````@(```PL```"
-M`@``$"P```("```4+````@(``!@L```"`@``'"P```("```@+````@(``"0L
-M```"`@``*"P```("```L+````@(``#`L```"`@``-"P```("```X+````@(`
-M`#PL```"`@``V"P``"N1``#<+```+)$``!`M```<&`$`2"T``!PS`0"8+0``
-M*Y$``)PM```LD0``O"T``!PR`0`H+@``'#X!`%`N```<,P$`O#```!P_`0#4
-M,````N@``/`P```<'`$`7#$``!P%`0!T,0``'#,!`)`Q```<)P$`M#$``!P8
-M`0#T,0``'$`!``@R```<00$`%#(``!Q"`0!P,@``'#X!`)0R```<0P$`L#(`
-M`"N=``"T,@``+)T``+@R```<1`$`R#(``"N>``#,,@``+)X``-`R```<1`$`
-MW#(``!Q%`0#X,@``*Y\``/PR```LGP```#,``!Q$`0`0,P``*Z```!0S```L
-MH```&#,``!Q$`0`\,P``*Z$``$`S```LH0``1#,``!Q$`0!4,P``*Z(``%@S
-M```LH@``7#,``!Q$`0!T,P``*Z,``'@S```LHP``?#,``!Q$`0",,P``*Z0`
-M`)`S```LI```E#,``!Q$`0"D,P``*Z4``*@S```LI0``K#,``!Q$`0#<,P``
-M'`4!`"@T```KJ```+#0``"RH``"D-```'$8!`!@U```<1@$`1#4``!Q&`0"X
-M-0``'#,!`.0U```<1P$`]#4``!Q'`0``-@``'$@!`&0V```<1P$`=#8``!Q'
-M`0"(-@``'$<!`+`V```</@$`W#8``!PS`0`X-P``'$,!`%@W```KG0``7#<`
-M`"R=``!@-P``'$0!`'`W```KG@``=#<``"R>``!X-P``'$0!`(0W```<10$`
-MI#<``"N?``"H-P``+)\``*PW```<1`$`O#<``"N@``#`-P``+*```,0W```<
-M1`$`[#<``"NA``#P-P``+*$``/0W```<1`$`!#@``"NB```(.```+*(```PX
-M```<1`$`*#@``"NC```L.```+*,``#`X```<1`$`0#@``"ND``!$.```+*0`
-M`$@X```<1`$`=#@``!Q'`0"$.```'$<!`*@X```<20$`O#@``!PS`0`0.0``
-M'$<!`"`Y```<1P$`4#D``!Q&`0"@.0``'$<!`+`Y```<1P$`(#H``!Q'`0`P
-M.@``'$<!`$0Z```<1P$`6#H``"NM``!<.@``+*T``&`Z```<1`$`B#H``"NN
-M``",.@``+*X``)0Z```KKP``G#H``"RO``"@.@``*[```*0Z```LL```Y#H`
-M`!Q$`0`D/```'$<!`#0\```<1P$`;#P``!Q*`0"0/```'`4!`)0\```KL0``
-MF#P``"RQ``#`/```*[(``,0\```LL@``W#P``!P$`0`$/0``'`4!`!P]```<
-M"P$`6#T``!Q'`0!H/0``'$<!`'P]```<1P$`D#T``!P%`0#</0``'$<!`.P]
-M```<1P$``#X``!Q'`0`H/@``'`4!`"P^```KLP``,#X``"RS``!8/@``*[(`
-M`%P^```LL@``=#X``!P$`0"</@``'`4!`+0^```<"P$`\#X``!Q'`0``/P``
-M'$<!`!0_```<1P$`*#\``!P%`0!T/P``'$<!`(0_```<1P$`F#\``!Q'`0`4
-M0```'$L!`'1````<1P$`A$```!Q'`0"80```'$<!`!A!```<1P$`*$$``!Q'
-M`0"`00``'"8!`+Q!```<)P$`]$$``!S_``!`0@``'"@!`)A"```<3`$`K$(`
-M`!Q,`0#<0@``'!P!`/!"```<$P$`($,``!P3`0!00P``'"<!`&1#```<30$`
-MC$,``!P8`0"@0P``'$`!`+1#```<00$`P$,``!Q-`0#@0P```O4``.1#```"
-MZ```Z$,```+U```(1```'`4!`"!$```<!0$`.$0``!Q/`0!@1```'`4!`'A$
-M```<,P$`D$0``!Q/`0"X1```'`4!`-!$```<3P$`]$0``!P<`0!`10``'%$!
-M`%Q%```<40$`G$4``!P%`0"L10``'#,!`+1%```<)@$`V$4``!Q2`0#L10``
-M'"@!``A&```<&`$`+$8``!P%`0!01@``'"$!`'A&```<(0$`G$8``!PS`0"T
-M1@``'"8!`-A&```<4@$`[$8``!PH`0#X1@``'%,!`!Q'```"Z```($<```+U
-M``!,1P``'%0!`(Q'```<!@$`K$<``!P'`0"X1P``'%4!`.A'```KD0``[$<`
-M`"R1```02```'!@!`#1(```<,P$`:$@``!P8`0#$2```'`L!`-1(```<5@$`
-M_$@```("````20```@(```1)```"`@``"$D```("```,20```@(``!!)```"
-M`@``%$D```("```820```@(``!Q)```"`@``($D``"O%```D20``+,4``"A)
-M```<$P$`+$D``"M5```P20``+%4``$A)```<5P$`5$D``"M8`0!820``+%@!
-M`'A)```<$P$`@$D``!Q9`0"420``*\8``)A)```LQ@``S$D``!Q/`0#420``
-M*\<``-A)```LQP``X$D``!Q'`0#H20``*\@``.Q)```LR```\$D``!P3`0#X
-M20``*\D``/Q)```LR0``,$H``!Q/`0`X2@``*\<``#Q*```LQP``1$H``!Q'
-M`0!(2@``*U4``$Q*```L50``9$H``!Q:`0"$2@``*\H``(A*```LR@``E$H`
-M`!P$`0"@2@``*\<``*1*```LQP``K$H``!Q'`0#L2@``*\L``/!*```LRP``
-M^$H``!P$`0`P2P``*\P``#1+```LS```.$L``!P$`0!,2P``*\<``%!+```L
-MQP``6$L``!Q'`0!L2P``*\<``'!+```LQP``>$L``!Q'`0"02P``*\T``)1+
-M```LS0``G$L``!PA`0"D2P``*\X``*A+```LS@``K$L``!P)`0#$2P``*\\`
-M`,A+```LSP``S$L``!P)`0#D2P``*]```.A+```LT```[$L``!P)`0`$3```
-M*]$```A,```LT0``#$P``!P)`0`<3```*](``"!,```LT@``+$P``!P3`0`P
-M3```*UL!`#1,```L6P$`4$P``!PS`0!L3```*\<``'!,```LQP``>$P``!Q'
-M`0"`3```*UL!`(1,```L6P$`M$P``"O3``"X3```+-,``,!,```<!`$`Q$P`
-M`"M;`0#(3```+%L!`,Q,```KU```T$P``"S4``#<3```'!,!`.A,```KQP``
-M[$P``"S'``#T3```'$<!``1-```<"P$`2$T``!PM`0!H30``'%4!`'A-```"
-MZ```?$T```(#``"`30```O4``(1-```"6`$`F$T``!P<`0#(30```@(``,Q-
-M```"`@``T$T```("``#430```@(```1.```<0`$`&$X``!Q<`0!(3@``'#L!
-M`&1.```<.P$`>$X``!PR`0"03@``'`4!`+1.```KD0``N$X``"R1``#03@``
-M'#,!`/1.```<70$`!$\``!Q>`0`H3P``*Y$``"Q/```LD0``B$\``!PN`0#0
-M3P``'`8!`.Q/```<!P$`^$\``!PR`0`84````@(``!Q0```"`@``(%````("
-M```D4````@(``#Q1```<3`$`4%$``!Q,`0"D40``'"T!`+Q1```<,@$`_%$`
-M`!PN`0!$4@``'`8!`&!2```<!P$`;%(``!PR`0",4@```@(``)!2```"`@``
-ME%(```("``"84@```@(``)Q2```"`@``H%(```("``"D4@```@(``*A2```"
-M`@``K%(```("``"P4@```@(``+12```"`@``N%(```("``"\4@```@(``,!2
-M```"`@``Q%(```("``#(4@```@(``,Q2```"`@``T%(```("``#44@```@(`
-M`.A2```<8`$`\%(``!QA`0`T4P``'"4!`%Q3```<,P$`K%,``!PS`0#$4P``
-M'&(!`!!4```<)0$`*%0``!QC`0!@5```'#,!`(Q4```<9`$``%4``!PE`0`<
-M50``'`D!`#!5```<"0$`C%4``!PN`0"D50``'`4!`,15```<,P$`+%8``!PS
-M`0!L5@``'#,!`.!6```<,P$`$%<``!P)`0!,5P``'#,!`'!7```<,P$`D%<`
-M`!PS`0"L5P``'`D!`.17```<,P$`.%@``!PW`0"P6```'#,!`+Q8```<"0$`
-M[%@``!P)`0`,60``'#,!`!Q9```<,P$`.%D``!P)`0!460``'#L!`&A9```<
-M.P$`?%D``!PR`0"(60``'%T!`,!9```<,P$`T%D``!PS`0#@60``'%X!`!A:
-M```<,P$`2%H``!P)`0"$6@``'#,!`*A:```<,P$`R%H``!PS`0#D6@``'`D!
-M`!Q;```<,P$`<%L``!PW`0"D6P``'#(!`.A;```<)0$`+%P``!PS`0!T7```
-M'#(!`)!<```<+@$`K%P``!PS`0#`7```'&4!``A=```<,@$`)%T``!PN`0!`
-M70``'#,!`'Q=```<,@$`F%T``!PN`0"T70``'#,!``!>```<+0$`&%X``!PR
-M`0`T7@``'`D!`%A>```"]0``7%X```+U``!@7@```O4``&1>```"]0``:%X`
-M``+H``!P7@``*U4``'1>```L50``A%X``!Q9`0"87@``'%H!`*!>```<9P$`
-MJ%X```($``"P7@``*U4``+1>```L50``Q%X``"OG``#(7@``+.<``,Q>```<
-M:0$`U%X``!Q7`0`P`````O4``#0````"]0``.`````+U```\`````O4``$``
-M```"]0``1`````+U``!(`````O4``$P````"]0``4`````+U``!4`````@,`
-M`&`````"`P``9`````+H``!H`````C<``'`````"FP``=`````(@``!X````
-M`B```'P````""P``@`````*I``"$`````M8``(@````"#0``C`````(@``"0
-M`````@\``)@````"I@``G`````+!``"L`````B```+`````"(```O`````*X
-M``#``````G@``,0````"M@``R`````(@``#,`````KX``-`````"M```U```
-M``*9``#8`````G8``-P````"(```X`````)S``#L`````I8``/`````"E```
-M]`````(@``#X`````A(``/P````"%`````$```(6```$`0```B````@!```"
-M(```#`$```(@```0`0```A@``!0!```">@``&`$```)O```<`0```B```"`!
-M```"&@``+`$```*2```T`0```H<``#P!```"@```1`$```)M``!,`0```EX`
-M`%`!```":@``5`$```(H``!8`0```F@``%P!```"9@``8`$```(J``!D`0``
-M`DP``&@!```")```;`$```(B``!P`0```B8``'0!```"9```>`$```)@``!\
-M`0```AP``(`!```".0``A`$```(>``"(`0```AX``(P!```"+```D`$```(N
-M``"4`0```C```)P!```"-0``H`$```(>``"D`0```ED``*@!```"'@``K`$`
-M``)3``"P`0```AX``+0!```"3@``N`$```(\````````*@(`````````_@``
-M"````"H"```0````*@(``!@````J`@``(````"H"```H````*@(``#`````J
-M`@``.````"H"``!`````*@(``$@````J`@``4````"H"``!8````*@(``&``
-M```J`@``:````"H"``!P````*@(``'@````J`@``@````"H"``"(````*@(`
-M`)`````J`@``F````"H"``"@````*@(``*@````J`@``L````"H"``"X````
-M*@(``,`````J`@``R````"H"``#0````*@(``-@````J`@``X````"H"``#H
-M````*@(``/`````J`@``\``````4`0#T````*@<``/@````J`@````$``"H"
-M```(`0``*@(``!`!```J`@``&`$``"H"```@`0``*@(``"@!```J`@``,`$`
-M`"H"```X`0``*@(``$`!```J`@``2`$``"H"``!0`0``*@(``%@!```J`@``
-M8`$``"H"``!H`0``*@(``'`!```J`@``>`$``"H"``"``0``*@(``(@!```J
-M`@``D`$``"H"``"8`0``*@(``*`!```J`@``J`$``"H"``"P`0``*@(``+@!
-M```J`@``P`$``"H"``#(`0``*@(``-`!```J`@``V`$``"H"``#@`0``*@(`
-M`.@!```J`@``\`$``"H"``#X`0``*@(````"```J`@``"`(``"H"```0`@``
-L*@(``!@"```J`@``(`(``"H"```H`@``*@(``#`"```J`@``.`(``"H"````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````"BR`8&PL%^$``````````"PL+"`0```
+M`+"PL(#H````L+"P@/````"PL+"`0`$``+"PL("(`0``L+"P@,P!``"PL+"`
+MZ`$``+"PL(`T`@``L+"P@%`"``"PL+"`;`(``+"PL("$`@``L*@!@+P"``"P
+ML+"`Q`(``+"PL(#,`@``L+"P@-0"``"PL+"`W`(``+"PL(#D`@``L+"P@.P"
+M``"PL+"`4`,``+"PL(!8`P``L+"P@&`#``"PL+"`:`,``+"PL(!L`P``L+"P
+M@'`#``"PK@&`^`,``+"PL(``!```L+"P@'@$``"PL*J`O`0``*\HLH`\"P``
+ML*H!@&0,````````"!```+"K!(#`$0``L+"H@(@2``"PK`&`*!0``+"PJ(!`
+M%```L*P#@)@7``"PL*B`O!<``+"O#H!D&@``7X0"@-P<``"PL*B`#!T``+"N
+M`X`P'P``L+"J@)0@``"PL*B`R"```+"PJ(`0(0``L+"J@'PA``"PJ@>`F",`
+M`+"PKH`P)P``L+"N@'0H``"PL*J`A"D``+"O!(!`+0``L+"H@%@M``"PK`&`
+M`"\``+"J!X!4,```7X0*@+`Q``"PJP*`-#,``*\(L8!T-```L+"J@.@T``"O
+M1+*`G$```+"O!H#(00``L+"H@"!"``"PL*Z`/$,``+"I!("40P``L*D$@.Q#
+M``"PJ02`+$0``%^$"H"L1@``KS\8@.1,``"PL*J`A$T``+"PKH!<3@``L+"H
+M@(A.``"PKP*`J%T``+"PJ(#H70``L+"J@`!0\@0+"@D(!P8%!`,"`0#_````
+M<G1W7W=X7W-E=%]W87```$-30T%.(%,!``!3````````4/($!1`0$`T````!
+M``````````4`````4/($X(L```)(``!R='=?=W)I=&4S,@``````X8L```%(
+M$"AR='=?<F5A9#,R````````XHL```````!D<FEV97)?97AT````````XXL`
+M````````````````````````````Y(L```%(``!A<&EN9F\`````````````
+MY8L```)(``!S971P:60`````````````YHL```%(``!W<'-?<W1A<G0`````
+M````YXL```%(``!G971?<V5N<VET:79I='D`Z(L```%(``!W<'-?<')O8E]R
+M97%?:64`Z8L```%(``!W<'-?87-S;V-?<F5Q7VEEZHL```%(``!C:&%N;F5L
+M7W!L86X`````ZXL```)(``!D8F<`````````````````[(L```-(``!R9G<`
+M````````````````[8L```)($"AR9G(`````````````````\(L``$`@``!P
+M,G!?<V5T````````````\8L``$`@0"AP,G!?9V5T````````````\HL``$`@
+M$"!P,G!?9V5T,@``````````]HL``$`@``!P;5]S970`````````````^(L`
+M`!`@``!R97)E9U]N9%]N86UE````^HL``(`@``!E9G5S95]S970`````````
+M^XL``(`@`"]E9G5S95]G970`````````,'@E,#5X```L````<F5A;&UA<``E
+M<R`*`````"5S(`DP>"4P,G@)`"5S("4P,E@`)7,)`"5S"@!R;6%P`````"5S
+M(#!X)3`R6````"5S(`!R96%L<F%W`"5S("4P,G@`)7,*"0````!M86,`=FED
+M<&ED``!A8FQE<F%W`"5S(#H@6R!A=F%I;&%B;&4@<F%W('-I>F5=(#T@)60`
+M)7,@.B!#;VUM86YD(&YO="!F;W5N9`H`=VUA<`````!W<F%W`````$-O;6UA
+M;F0@;F]T(&9O=6YD"@``9&ES86)L925D````;'!S/0````!I<',]`````"5U
+M```P>"4P.'@``#Q7249)0%)%04Q414L^``!715``;F]N90````!42TE0````
+M`$-#35``````245%12`X,#(N,3%B;@```$E%144@.#`R+C$Q8@````!)145%
+M(#@P,BXQ,6)G;@``245%12`X,#(N,3%B9P```$E%144@.#`R+C$Q86X```!)
+M145%(#@P,BXQ,6$`````245%12`X,#(N,3%G;@```$E%144@.#`R+C$Q9P``
+M``!U;F%S<V]C:6%T960`````(%)A=&5S("A-8B]S*3H@```````N-0``)60E
+M<R````!W<&%?:64]`"4P,G@`````<G-N7VEE/0`E<SH@<F9P=W)S=&%T95]C
+M:&5C:R!F86EL+@H`)7,Z('1E;7`M/G-A7V9A;6EL>2`A/2!!4E!(4D1?151(
+M15(N"@```$%.1%)/241?5TE&25]#341?4U1!4E0N+BXN+BXN+BXN"@```'=A
+M:71I;F<@9F]R('=I9FD@9')I=F5R('1O(&)E(')E861Y+BXN"@!35$%25```
+M`$]+``!!3D123TE$7U=)1DE?0TU$7U-43U`N+BXN+BXN+BXN"@````!35$]0
+M`````%=)1DD@<G-S:2`E9`````!,24Y+4U!%140@)60`````34%#041$4B`]
+M("4P,G@Z)3`R>#HE,#)X.B4P,G@Z)3`R>#HE,#)X`"4J<R`E<P``55,``$55
+M``!*4```0TX``&-O=6YT<GD@8V]D93H@)7,L('-E="!C:&%N;F5L('!L86XZ
+M("5D"@!38V%N+4-H86YN96QS(#T@)60``$=E="!#:&%N;F5L<R!R971U<FX@
+M)60@*&EN:71?8VAA;FYE;%]P;&%N/25D*0H``')T;#@Q.#A?=VEF:5]W86ME
+M;&]C:P```%)34TD`````3$E.2U-0145$````34%#041$4@!30T%.+4%#5$E6
+M10!30T%.+5!!4U-)5D4`````0T]53E1260!30T%.+4-(04Y.14Q3`````$=#
+M0SH@*$=.52D@-"XT+C``02H```!A96%B:0`!(`````4W+4$`!@H'00@!$@04
+M`14!%P,8`1D!&@(>`0`N<WEM=&%B`"YS=')T86(`+G-H<W1R=&%B`"YR96PN
+M=&5X=``N<F5L+F1A=&$`+F)S<P`N05)-+F5X=&%B`"YR96PN05)-+F5X:61X
+M`"YR;V1A=&$`+G)O9&%T82YS='(Q+C0`+F-O;6UE;G0`+FYO=&4N1TY5+7-T
+M86-K`"Y!4DTN871T<FEB=71E<P``````````````````````````````````
+M`````````````````````!\````!````!@`````````T````(%X`````````
+M````!``````````;````"0``````````````:)```&`8```/`````0````0`
+M```(````*0````$````#`````````%1>``"\`0`````````````$````````
+M`"4````)``````````````#(J```B`(```\````#````!`````@````O````
+M"`````,`````````$&```&````````````````@`````````-`````$````"
+M`````````!!@```,```````````````$`````````$,````!``!P@@``````
+M```<8```0`(```$`````````!``````````_````"0``````````````4*L`
+M`%@"```/````!P````0````(````3@````$````"`````````%QB``!(`@``
+M```````````$`````````%8````!````,@````````"D9```\`,`````````
+M````!`````$```!E`````0``````````````E&@``!(```````````````$`
+M````````;@````$``````````````*9H```````````````````!````````
+M`'X````#``!P``````````"F:```*P```````````````0`````````1````
+M`P``````````````T6@``(X```````````````$``````````0````(`````
+M``````````AL``#@%@``$````/X````$````$`````D````#````````````
+M``#H@@``?0T``````````````0```````````````````````````````0``
+M````````````!`#Q_P````````````````,``0`````````````````#``,`
+M`````````````````P`%``\`````````0`````(``0`9````````````````
+M``$``````````````````P`&``````````````````,`!P`<````0````*@`
+M```"``$`&0```$`````````````!`"X```#H````"`````(``0`9````Z```
+M``````````$`/@```/````!0`````@`!`!D```#P`````````````0!.````
+M0`$``$@````"``$`&0```$`!```````````!`!D```"(`0```````````0!>
+M````S`$``!P````"``$`&0```,P!```````````!`&T```#H`0``3`````(`
+M`0`9````Z`$```````````$`?0```#0"```<`````@`!`!D````T`@``````
+M`````0"-````4`(``!P````"``$`&0```%`"```````````!`)X```!L`@``
+M&`````(``0`9````;`(```````````$`KP```(0"```X`````@`!`!D```"$
+M`@```````````0"_````O`(```@````"``$`&0```+P"```````````!`-``
+M``#$`@``"`````(``0`9````Q`(```````````$`U@```,P"```(`````@`!
+M`!D```#,`@```````````0#R````U`(```@````"``$`&0```-0"````````
+M```!``D!``#<`@``"`````(``0`9````W`(```````````$`'P$``.0"```(
+M`````@`!`!D```#D`@```````````0`N`0``[`(``&0````"``$`&0```.P"
+M```````````!`#H!``!0`P``"`````(``0`9````4`,```````````$`1@$`
+M`%@#```(`````@`!`!D```!8`P```````````0!2`0``8`,```@````"``$`
+M&0```&`#```````````!`!D```!H`P```````````0`9````;`,`````````
+M``$`&0```'`#```````````!`%\!``#X`P``"`````(``0`9````^`,`````
+M``````$`:`$````$``!X`````@`!`!D`````!````````````0!_`0``>`0`
+M`$0````"``$`&0```'@$```````````!`(X!````````````````"@"3`0``
+MO`0``(`&```"``$`&0```+P$```````````!`*0!```(````````````"@"I
+M`0``#`````````````H`K@$``"@````````````*`+,!```X````````````
+M"@"X`0``4`````````````H`O@$``%@````````````*`,0!```P````````
+M````"@#)`0``8`````````````H`SP$``&@````````````*`-4!``!L````
+M````````"@#;`0``=`````````````H`X0$``'P````````````*`.<!``"<
+M````````````"@#M`0``)`L```````````$`\`$``#P+```H`0```@`!`!D`
+M```\"P```````````0#^`0``9`P``*0#```"``$`&0```&0,```````````!
+M``\"``"T````````````"@`5`@``O`````````````H`[0$```00````````
+M```!`!L"```($```N`$```(``0`9````"!````````````$`+0(`````````
+M```````%`#<"``#8````````````"@#M`0``O!$```````````$`&0```,`1
+M```````````!`#T"``"($@``H`$```(``0`9````B!(```````````$`2`(`
+M`.0````````````*`$X"``#L````````````"@!4`@``]`````````````H`
+M6@(``"@4```8`````@`!`!D````H%````````````0!I`@``0!0``%@#```"
+M``$`&0```$`4```````````!`.T!``!T%````````````0`9````L!0`````
+M``````$`=@(``)@7```D`````@`!`!D```"8%P```````````0".`@``O!<`
+M`*@"```"``$`&0```+P7```````````!`)X"``!D&@``>`(```(``0`9````
+M9!H```````````$`KP(``-P<```P`````@`!`!D```#<'````````````0"]
+M`@``^`````````````H`PP(```P=```D`@```@`!`!D````,'0``````````
+M`0#4`@``,!\``&0!```"``$`&0```#`?```````````!`.T!``"P'P``````
+M`````0`9````S!\```````````$`XP(``)0@```T`````@`!`!D```"4(```
+M`````````0#S`@````$```````````H`^0(``,@@``!(`````@`!`!D```#(
+M(````````````0`*`P``$"$``&P````"``$`&0```!`A```````````!`!D#
+M``!\(0``'`(```(``0`9````?"$```````````$`*`,``)@C``"8`P```@`!
+M`!D```"8(P```````````0`[`P``$`$```````````H`[0$``"@G````````
+M```!`$$#```P)P``1`$```(``0`9````,"<```````````$`[0$``)0G````
+M```````!`!D```"D)P```````````0!4`P``%`$```````````H`6@,``!P!
+M```````````*`&`#```D`0``````````"@!F`P``="@``!`!```"``$`&0``
+M`'0H```````````!`.T!``"<*````````````0`9````R"@```````````$`
+M=@,``(0I``"\`P```@`!`!D```"$*0```````````0#M`0``H"H`````````
+M``$`&0```.`J```````````!`.T!``!\*P```````````0`9````O"L`````
+M``````$`A0,````````````````)`(\#``!`+0``&`````(``0`9````0"T`
+M``````````$`H0,``%@M``"H`0```@`!`!D```!8+0```````````0"Q`P``
+M`"\``%0!```"``$`&0`````O```````````!`.T!``!0,````````````0#!
+M`P``5#```%P!```"``$`&0```%0P```````````!`-(#``"P,0``A`$```(`
+M`0`9````L#$```````````$`X@,``"P!```````````*`.@#```\`0``````
+M````"@#N`P``3`$```````````H`]`,``%P!```````````*`/H#``!L`0``
+M````````"@``!```?`$```````````H`!@0``(P!```````````*``P$``"<
+M`0``````````"@`2!```K`$```````````H`&`0``#0S``!``0```@`!`!D`
+M```T,P```````````0`I!`````````````````,`,P0``'0T``!T`````@`!
+M`!D```!T-````````````0!#!```Z#0``+0+```"``$`&0```.@T````````
+M```!`%($``"\`0``````````"@!8!```T`$```````````H`7@0``,P!````
+M```````*`&0$``#4`0``````````"@!J!```W`$```````````H`<`0``.0!
+M```````````*`'8$``#L`0``````````"@!\!```G$```"P!```"``$`&0``
+M`)Q````````````!`(P$``#(00``6`````(``0`9````R$$```````````$`
+MG`0``"!"```<`0```@`!`!D````@0@```````````0#M`0``,$,`````````
+M``$`&0```#Q#```````````!`!D```"40P```````````0`9````[$,`````
+M``````$`JP0``"Q$``"``@```@`!`!D````L1````````````0#M`0``J$8`
+M``````````$`NP0``*Q&```X!@```@`!`!D```"L1@```````````0#M`0``
+MD$@```````````$`&0```+1(```````````!`,L$```X`@``````````"@#1
+M!```A`(```````````H`UP0``(P"```````````*`-T$``"0`@``````````
+M"@#C!```M`(```````````H`Z00``+P"```````````*`.\$``#,`@``````
+M````"@#U!```W`(```````````H`^P0```0#```````````*``$%```,`P``
+M````````"@`'!0``$`,```````````H`#04``!0#```````````*`!,%```8
+M`P``````````"@`9!0``'`,```````````H`'P4``$0#```````````*`"4%
+M``!8`P``````````"@#M`0``U$P```````````$`*P4``.1,``"@`````@`!
+M`!D```#D3````````````0#M`0``($T```````````$`&0```#!-````````
+M```!`#L%``"$30``V`````(``0`9````A$T```````````$`204``%Q.```L
+M`````@`!`!D```!<3@```````````0`9````B$X```````````$`[0$``&!/
+M```````````!`!D```!P3P```````````0#M`0``R%$```````````$`&0``
+M`!12```````````!`.T!``"470```````````0`9````J%T```````````$`
+M[0$``.1=```````````!`!D```#H70```````````0!5!0``B`,`````````
+M``H``````````````````P`)`%L%````````!`````$`"0#M`0``````````
+M``````D`9P4```0````-`````0`)`',%```4````#P````$`"0""!0``-```
+M``0````!``D`C@4``#@````%`````0`)`)D%``!`````"0````$`"0"D!0``
+M3`````0````!``D`L`4``%````#X`0```0`)`.T!`````````````````P#!
+M!0``;````.`````!``,`S@4``$P!``!P`````0`#``````````````````,`
+M"@#M`0````````````````4`X@4````````0`````0`%`/,%```0`````0``
+M``$`!0`(!@``$0````$````!``4`&P8``!@```!(`````0`%````````````
+M``````,`#``````````````````#``L``````````````````P`-`#`&````
+M`````````!````!'!@``B`$``$0````2``$`9`8`````````````$````&L&
+M``!H`P``!````!(``0!X!@``;`,```0````2``$`A`8``'`#``"(````$@`!
+M`)`&`````````````!````"8!@`````````````0````I`8`````````````
+M$````+4&`````````````!````"_!@`````````````0````Q@8`````````
+M````$````,T&`````````````!````#@!@`````````````0````YP8`````
+M````````$````/8&`````````````!`````/!P`````````````0````(`<`
+M````````````$````#4'`````````````!````!&!P`````````````0````
+M5`<`````````````$````&@'`````````````!````!O!P`````````````0
+M````A@<`````````````$````(T'`````````````!````"5!P``````````
+M```0````IP<`````````````$````+,'`````````````!````##!P``````
+M```````0````V@<`````````````$````.P'``#`$0``R````!(``0#]!P``
+M```````````0````!0@`````````````$`````\(`````````````!`````=
+M"``````````````0````,P@`````````````$````#H(`````````````!``
+M``!'"``````````````0````4P@`````````````$````&`(````````````
+M`!````!P"``````````````0````@0@`````````````$````)D(````````
+M`````!````"I"``````````````0````O`@`````````````$````,H(````
+M`````````!````#9"``````````````0````Z0@`````````````$````/@(
+M`````````````!`````$"0`````````````0````#PD`````````````$```
+M`!L)`````````````!`````G"0`````````````0````,@D`````````````
+M$````#X)`````````````!````!5"0`````````````0````80D`````````
+M````$````',)`````````````!````"("0`````````````0````F0D`````
+M````````$````+$)`````````````!````#*"0`````````````0````UPD`
+M````````````$````.@)`````````````!````#Z"0`````````````0````
+M!0H`````````````$````!D*`````````````!`````\"@`````````````0
+M````7PH`````````````$````',*`````````````!````"0"@``````````
+M```0````F0H`````````````$````+(*`````````````!````"^"@``````
+M```````0````Q0H`````````````$````-<*`````````````!````#R"@``
+M```````````0`````0L`````````````$`````\+`````````````!`````K
+M"P`````````````0````0`L``#Q#``!8````$@`!`%\+`````````````!``
+M``!S"P``E$,``%@````2``$`CPL``.Q#``!`````$@`!`*\+````````````
+M`!````#""P`````````````0````X0L`````````````$````.X+````````
+M`````!````#Z"P`````````````0`````@P`````````````$`````P,````
+M`````````!`````9#``````````````0````(`P`````````````$````"P,
+M`````````````!`````^#``````````````0````4`P`````````````$```
+M`&,,`````````````!````!S#```B$X``"`/```2``$`?0P`````````````
+M$````)$,`````````````!````"?#``````````````0````M@P`````````
+M````$````,(,`````````````!````#8#``````````````0````Y@P``*A=
+M``!`````$@`!`/X,`````````````!`````0#0``Z%T``#@````2``$`*`T`
+M````````````$````#<-````````,````!$``P!!#0``,````"0````1``,`
+M5@T``!0````$````$0`%`&P-``!4````&````!$``P``:6]C=&Q?;&EN=7@N
+M8P!H97@R;G5M7VD`)&$`=W!A7W-E=%]A=71H7V%L9W,`<G1W7W=X7W-E=%]F
+M<F5Q`')T=U]W>%]G971?;6]D90!R='=?=WA?9V5T7W-E;G,`<G1W7W=X7V=E
+M=%]R=',`<G1W7W=X7W-E=%]F<F%G`')T=U]W>%]G971?9G)A9P!R='=?=WA?
+M9V5T7W)E=')Y`')T=U]W>%]G971?<&]W97(`<G1W7W=X7W=R:71E7W)F`')T
+M=U]W>%]P<FEV7VYU;&P`9'5M;7D`<G1W7W=X7W-E=%]M=&M?=W!S7W!R;V)E
+M7VEE`')T=U]W>%]G971?<V5N<VET:79I='D`<G1W7W=X7W-E=%]M=&M?=W!S
+M7VEE`')T=U]D<G9E>'1?:&1L`')T=U]S971?<&ED`')T=U]P,G!?<V5T`')T
+M=U]P,G!?9V5T`')T=U]P,G!?9V5T,@!R='=?=&1L<P!R='=?9V5T7W=I<F5L
+M97-S7W-T871S`')T=U]W>%]R96%D7W)F`"Y,0S``<G1W7VUP7V5F=7-E7V=E
+M=``N3$,Q`"Y,0S(`+DQ#-0`N3$,X`"Y,0S$Q`"Y,0S$R`"Y,0S8`+DQ#,3,`
+M+DQ#,30`+DQ#,34`+DQ#,38`+DQ#,3<`+DQ#,3@`)&0`<G1W7W=P<U]S=&%R
+M=`!R='=?;7!?969U<V5?<V5T`"Y,0S$Y`"Y,0S(P`')T=U]R97)E9U]N9%]N
+M86UE`"Y,04Y#2$]2,``N3$,R,@!R='=?<&U?<V5T`"Y,0S(S`"Y,0S(T`"Y,
+M0S(U`')T=U]W>%]W<FET93,R`')T=U]D8F=?<&]R=`!R='=?=WA?<V5T7V-H
+M86YN96Q?<&QA;@!R='=?9V5T7V%P7VEN9F\`<G1W7VUP7VEO8W1L7VAD;`!R
+M='=?=WA?<F5A9#,R`"Y,0S(V`')T=U]W>%]S971?<&UK:60`<G1W7W=X7V=E
+M=%]E;F,`<G1W7W=X7V=E=%]N:6-K`"Y,0S(W`')T=U]W>%]G971?97-S:60`
+M<G1W7W=X7V=E=%]W87``<G1W7W=X7W-E=%]E;F,`=W!A7W-E=%]E;F-R>7!T
+M:6]N`"Y,0S(X`')T=U]W>%]S971?96YC7V5X=``N3$,R.0`N3$,S,``N3$,S
+M,0!R='=?=WA?<V5T7V%U=&@`<G1W7W-E=%]W<&%?:64`+DQ!3D-(3U(Q`')T
+M=U]W>%]S971?9V5N7VEE`')T=U]W>%]G971?<F%T90!R='=?=WA?<V5T7W)A
+M=&4`<G1W7W=X7W-E=%]E<W-I9`!R='=?=WA?9V5T7VYA;64`+DQ#,S(`+DQ#
+M,S,`+DQ#,S0`+DQ#,S4`+DQ#,S8`+DQ#,S<`+DQ#,S@`+DQ#,SD`+DQ#-#``
+M<G1W7W=X7V=E=%]R86YG90`N3$%.0TA/4C(`<G1W7W=X7V=E=%]F<F5Q`'1R
+M86YS;&%T95]S8V%N`"Y,0S0Q`"Y,0S0S`"Y,0S0R`"Y,0S0T`"Y,0S0U`"Y,
+M0S0V`"Y,0S0W`')T=U]W>%]G971?<V-A;@!R='=?=WA?<V5T7VUL;64`<G1W
+M7W=X7W-E=%]W87``<G1W7W=X7W-E=%]S8V%N`')T=U]W>%]S971?<')I=@`N
+M3$,U,0`N3$,U,P`N3$,U-``N3$,U-0`N3$,U-@`N3$,U-P`N3$,U.``N3$,U
+M.0`N3$,V,``N3$,V,0`N3$,V,@`N3$,V,P`N3$,V-``N3$,V-0`N3$,V-@`N
+M3$,V-P!R='=?=WA?<V5T7VUO9&4`<V5T7V=R;W5P7VME>0!S971?=V5P7VME
+M>0`N3$,V.`!#+C8Q.2XT,3(P.`!#+C8T-"XT,3DS-P!?7V9U;F-?7RXT,34P
+M.`!#+C<T.2XT,S<Y-0!#4U=40T@N-S@R`$-35U1#2"XW.#4`0RXW,S$N-#,U
+M-S``<G1W7W!R:79A=&5?87)G<P!R='=?:&%N9&QE<G,`<G1W7W!R:79A=&5?
+M:&%N9&QE<@!O;&1?:69N86UE+C0R-S8S`&]L9%]B4F5G57-E3&5D+C0R-S8U
+M`&]L9%]I<'-?;6]D92XT,C<V-`!R=&PX,3@X7W-U<W!E;F1?;&]C:P!?7V%E
+M86)I7W5N=VEN9%]C<'!?<'(P`')T=U]I<U]F:71?<F5G=6QA=&]R>5]D;VUA
+M:6X`=6E?<&ED`&UA8U]R96=?9'5M<`!B8E]R96=?9'5M<`!R9E]R96=?9'5M
+M<`!S<')I;G1F`%]R='=?;65M<V5T`%]?8V]P>5]F<F]M7W5S97(`7U]M96UZ
+M97)O`'-T<G-E<`!S=')C;7``<G1W7V5F=7-E7VUA<%]R96%D`'-T<FQE;@!S
+M:6UP;&5?<W1R=&]U;`!%1E5315]'971%9G5S941E9FEN:71I;VX`<G1W7V5F
+M=7-E7V%C8V5S<P!E9G5S95]'971#=7)R96YT4VEZ90!E9G5S95]'971-87A3
+M:7IE`&ME>5\R8VAA<C)N=6T`<G1W7V5F=7-E7VUA<%]W<FET90!P<FEN=&L`
+M7U]A96%B:5]U;G=I;F1?8W!P7W!R,0!I9FYA;64`<W1R;F-P>0!R='=?8VAA
+M;F=E7VEF;F%M90!?<G1W7VUE;6-M<`!R='=?<W=?;&5D7VEN:70`<G1W7V9R
+M965?;F5T=V]R:U]Q=65U90!R='=?<W=?;&5D7V1E:6YI=`!R9G!W<G-T871E
+M7V-H96-K`&II9F9I97,`;6]D7W1I;65R`'-T<E\R8VAA<C)N=6T`3&5A=F5!
+M;&Q0;W=E<E-A=F5-;V1E`'-S8V%N9@!?<G1W7W=R:71E,S(`7W)T=U]W<FET
+M93@`7W)T=U]W<FET93$V`')T=U]G971?<W1A:6YF;P!L;V-A;%]B:%]D:7-A
+M8FQE`')T=U]E;F1?;V9?<75E=65?<V5A<F-H`&QO8V%L7V)H7V5N86)L90!R
+M='=?<V5T7V-H<&QA;E]C;60`<G1W7VUS;&5E<%]O<P!R='=?9V5T7W=P85]I
+M90!R='=?9V5T7W=P83)?:64`7U]C;W!Y7W1O7W5S97(`7W)T=U]M86QL;V,`
+M7W)T=U]R96%D.`!?<G1W7W)E860Q-@!?<G1W7W)E860S,@!?<G1W7VUF<F5E
+M`%]R='=?;65M8W!Y`')T=U]S971?.#`R7S$Q7V%D9%]W97``<G1W7W-E=%]K
+M97D`<G1W7W-E='-T86ME>5]C;60`<G1W7V=E=%]B8VUC7W-T86EN9F\`<G1W
+M7V1I<V%S<V]C7V-M9`!R='=?:6YD:6-A=&5?9&ES8V]N;F5C=`!R='=?9G)E
+M95]A<W-O8U]R97-O=7)C97,`7W)T=U]Z;6%L;&]C`')T=U]P87)S95]W<&%?
+M:64`<G1W7W!A<G-E7W=P83)?:64`<G1W7V=E=%]I90!R='=?<V5T9&%T87)A
+M=&5?8VUD`')T=U]S971?.#`R7S$Q7VEN9G)A<W1R=6-T=7)E7VUO9&4`<G1W
+M7W-E=%\X,#)?,3%?875T:&5N=&EC871I;VY?;6]D90!R='=?<V5T7S@P,E\Q
+M,5]S<VED`')T=U]I<U]C8VMR871E<V]N;'E?:6YC;'5D960`<VYP<FEN=&8`
+M<G1W7VES7V-C:W)A=&5S7VEN8VQU9&5D`')T=U]C:#)F<F5Q`&UE;6-P>0!R
+M='=?=F%L:61A=&5?<W-I9`!R='=?9V5T7V-A<&%B:6QI='E?9G)O;5]I90!R
+M='=?9V5T7W-E8U]I90!R='=?:7-?=W!S7VEE`')T=U]S971?.#`R7S$Q7V1I
+M<V%S<V]C:6%T90!R='=?<V5T7S@P,E\Q,5]B<W-I9`!R='=?:6YD:6-A=&5?
+M=WA?9&ES87-S;V-?979E;G0`=VER96QE<W-?<V5N9%]E=F5N=`!R='=?:6YD
+M:6-A=&5?=WA?87-S;V-?979E;G0`:6YD:6-A=&5?=WA?<V-A;E]C;VUP;&5T
+M95]E=F5N=`!R='=?<VET97-U<G9E>5]C;60`<G1W7W-E=%\X,#)?,3%?8G-S
+M:61?;&ES=%]S8V%N`%]R='=?=FUA;&QO8P!?<G1W7W9M9G)E90!S=')N8VUP
+M`'=A:V5?;&]C:P!S;&5E<%]R97-U;64`;7-L965P`'=A:V5?=6YL;V-K`&EN
+M:71?8VAA;FYE;%]P;&%N`')T=U]S971O<&UO9&5?8VUD`%]R='=?:6YI=%]L
+M:7-T:&5A9`!R='=?96YQ=65U95]C;60`<G1W7VEO8W1L`&9L=7-H7V%L;%]C
+M86U?96YT<GD`<G1W7W-T85]F;'5S:`!U<&1A=&5?<W1A7VEN9F]?87!M;V1E
+M`&%P7V9R965?<W1A`')T=U]C:&5C:U]B96%C;VY?9&%T80!U<&1A=&5?8F5A
+M8V]N`')T;#@Q.#A?<&]W97)?<V%V95]E>&ET`'=A:V5?;&]C:U]D97-T<F]Y
+M`')T;#@Q.#A?<&]W97)?<V%V95]I;FET`'=A:V5?;&]C:U]I;FET`')T=U]R
+M871E<P!A;F1R;VED7W=I9FE?8VUD7W-T<@!R=&PX,3@X7W=A:V5L;V-K7VEN
+M:70`<G1W7VAA;F1L97)S7V1E9@`````X`P``*P`!`#P#```L``$`J`0``"L[
+M``"L!```+#L``+`$```<!`$`_`0``!P%`0`,!0``'`4!`$`%```<!@$`8`4`
+M`!P'`0"$!0``*SX``(@%```L/@``K`4``!P(`0#`!0``*S\``,0%```L/P``
+MR`4``!P)`0#D!0``'`H!`/P%```<!0$`#`8``!P$`0`8!@``*T```!P&```L
+M0```,`8``!P$`0!4!@``'`0!`'`&```<!`$`A`8``!P$`0"D!@``'`0!`+@&
+M```<"P$`S`8``"M!``#0!@``+$$``-0&```<"0$`!`<``!P,`0`8!P``'`P!
+M`$P'```<#0$`>`<``!P*`0"(!P``'`4!`+`'```<!`$`P`<``!P$`0#4!P``
+M'`L!`.P'```K0@``\`<``"Q"``#T!P``'`D!`!@(```<#@$`,`@``!P%`0`X
+M"```*T,``#P(```L0P``1`@``"M$``!("```+$0``$P(```K10``4`@``"Q%
+M``!D"```'`0!`(`(```<!`$`H`@``!P$`0"T"```'`L!`,@(```K1@``S`@`
+M`"Q&``#0"```'`D!`!0)```<#0$`.`D``!P*`0!("0``'`4!`&P)```<!`$`
+M?`D``!P$`0"0"0``'`L!`*0)```K1P``J`D``"Q'``"L"0``'`D!`/`)```<
+M#0$`%`H``!P*`0`D"@``'`4!`$@*```<!`$`6`H``!P$`0!L"@``'`L!`(`*
+M```K2```A`H``"Q(``"("@``'`D!`*@*```<#P$`L`H``!P0`0#$"@``*TD`
+M`,@*```L20``T`H``!P$`0#8"@``'`L!`.P*```K2@``\`H``"Q*``#X"@``
+M'`0!```+```<"P$`)`L```+U```H"P```O4``"P+```"]0``,`L```+U```T
+M"P```O4``#@+```"]0``B`L``!P&`0"8"P``'`<!`)@,```K/@``G`P``"P^
+M``#`#```'`@!`-0,```K4```V`P``"Q0``#<#```'`D!``@-```<#`$`%`T`
+M`!P+`0`T#0``'!$!`'`-```<#0$`F`T``!P2`0"L#0``*U$``+`-```L40``
+MM`T``!P)`0#@#0``'`P!`.P-```<"P$`#`X``!P1`0`\#@``'`X!`%`.```K
+M1@``5`X``"Q&``!8#@``'`D!`(`.```<"P$`J`X``!P1`0#@#@``'`T!``@/
+M```<$@$`'`\``"M'```@#P``+$<``"0/```<"0$`3`\``!P+`0!H#P``'!$!
+M`*`/```<#0$`R`\``!P2`0#<#P``'!,!``00```"]0``&!```"M5```<$```
+M+%4``"P0```K50``,!```"Q5```T$```*Q4!`#@0```L%0$`2!```!P6`0"0
+M$```'`8!`*@0```<!P$`O!```!P7`0#($```*U4``,P0```L50``T!```"M6
+M``#4$```+%8``-P0```<&`$`_!```!P9`0`,$0``*U4``!`1```L50``)!$`
+M`!P6`0`T$0``*U8``#@1```L5@``0!$``!P8`0!4$0``'!H!`'01```K50``
+M>!$``"Q5``"4$0``'!L!`+P1```"!```.!(``"L=`0`\$@``+!T!`&P2```<
+M'@$`H!(``"M;``"D$@``+%L``*P2```<&`$`!!,``!P?`0`\$P``'"`!`%P3
+M```K7```8!,``"Q<``!H$P``'!@!`)03```K70``F!,``"Q=``"<$P``'"$!
+M`,`3```K'0$`Q!,``"P=`0#T$P``'!X!``@4```<'`$`-!0``!PB`0!T%```
+M`@(``'@4```"`@``?!0```("``"`%````@(``(04```"`@``B!0```("``",
+M%````@(``)`4```"`@``E!0```("``"8%````@(``)P4```"`@``H!0```("
+M``"D%````@(``*@4```"`@``K!0```("``#4%```'",!`.@4```<)`$`_!0`
+M`!PB`0#@%0``'"4!`"@6```<)@$`<!8``!PG`0"D%@``'"@!`.`6```<`0$`
+M]!8``!P"`0`(%P``'`,!`'@7```<(P$`B!<``!PC`0"H%P``'"D!```8```<
+M*@$`8!@``!P&`0!X&```'`<!`(08```<)@$`Q!@``!PG`0!$&0``'"@!`&09
+M```<*P$`F!D``!PL`0#@&0``'"@!`"0:```<+0$`5!H``!P8`0"4&@``'"X!
+M`-0:```<!@$`]!H``!P'`0!P&P``'"\!`(0;```<,`$`F!L``!PQ`0#,&P``
+M'",!`.`;```<)`$`]!L``!PB`0"@'```'"T!`-0<```<,@$`[!P``!PQ`0#X
+M'```*VP``/P<```L;````!T``!P$`0`\'0``'#,!`%@=```<&`$`C!T``!P8
+M`0"P'0``'#,!`"@>```<&`$`3!X``!P%`0"4'@``'`4!`-P>```<,P$`^!X`
+M`!PS`0"P'P```@(``+0?```"`@``N!\```("``"\'P```@(``,`?```"`@``
+MQ!\```("``#('P```@(``!0@```<,P$`L"```"MU``"T(```+'4``+P@```<
+M,P$`_"```!PS`0`P(0``'`4!`%PA```<,P$`<"$``!P%`0"<(0``'`4!`&`C
+M```<,P$`;",``!PT`0#X(P``*WX``/PC```L?@```"0``!P)`0!<)```'"X!
+M`'0D```<!0$`L"0``!PS`0#()```'#0!`/0D```<,P$`&"4``!PU`0!8)0``
+M'"4!`&PE```<"0$`O"4``!PS`0#()0``'`D!`.`E```<,P$`\"4``!PS`0`,
+M)@``'#8!`#@F```<,P$`7"8``!PS`0!\)@``'#,!`*0F```<-0$`K"8``!PW
+M`0#`)@``'`D!`"`G```<,@$`*"<```+U```L)P```O4``$PG```<+@$`:"<`
+M`!P%`0"`)P``'`4!`)0G```"`@``F"<```("``"<)P```@(``*`G```"`@``
+MI"<``"M^``"H)P``+'X``+`G```KA```M"<``"R$``"\)P``*X4``,`G```L
+MA0``R"<``"N&``#,)P``+(8``-@G```<%@$`("@``!PS`0!`*```'#,!`&`H
+M```<,@$`G"@```("``"@*````@(``*0H```"`@``J"@```("``"L*````@(`
+M`+`H```"`@``M"@```("``"X*````@(``+PH```"`@``P"@```("``#$*```
+M`@(``%@I```<.`$`8"D``!PY`0!H*0``'#H!`/0I```<.P$`$"H``!PS`0`T
+M*@``'#P!`&@J```</0$`H"H```("``"D*@```@(``*@J```"`@``K"H```("
+M``"P*@```@(``+0J```"`@``N"H```("``"\*@```@(``,`J```"`@``Q"H`
+M``("``#(*@```@(``,PJ```"`@``T"H```("``#4*@```@(``-@J```"`@``
+MW"H```("``!\*P```@(``(`K```"`@``A"L```("``"(*P```@(``(PK```"
+M`@``D"L```("``"4*P```@(``)@K```"`@``G"L```("``"@*P```@(``*0K
+M```"`@``J"L```("``"L*P```@(``+`K```"`@``M"L```("``"X*P```@(`
+M`%0L```KD0``6"P``"R1``",+```'!@!`,0L```<,P$`%"T``"N1```8+0``
+M+)$``#@M```<,@$`I"T``!P^`0#,+0``'#,!`#@P```</P$`4#````+H``!L
+M,```'!P!`-@P```<!0$`\#```!PS`0`,,0``'"<!`#`Q```<&`$`<#$``!Q`
+M`0"$,0``'$$!`)`Q```<0@$`Z#$``!P^`0`,,@``'$,!`"@R```KG0``+#(`
+M`"R=```P,@``'$0!`$`R```KG@``1#(``"R>``!(,@``'$0!`%0R```<10$`
+M<#(``"N?``!T,@``+)\``'@R```<1`$`B#(``"N@``",,@``+*```)`R```<
+M1`$`M#(``"NA``"X,@``+*$``+PR```<1`$`S#(``"NB``#0,@``+*(``-0R
+M```<1`$`[#(``"NC``#P,@``+*,``/0R```<1`$`!#,``"ND```(,P``+*0`
+M``PS```<1`$`'#,``"NE```@,P``+*4``"0S```<1`$`5#,``!P%`0"@,P``
+M*Z@``*0S```LJ```'#0``!Q&`0"0-```'$8!`+PT```<1@$`,#4``!PS`0!<
+M-0``'$<!`&PU```<1P$`>#4``!Q(`0#<-0``'$<!`.PU```<1P$``#8``!Q'
+M`0`H-@``'#X!`%0V```<,P$`L#8``!Q#`0#0-@``*YT``-0V```LG0``V#8`
+M`!Q$`0#H-@``*YX``.PV```LG@``\#8``!Q$`0#\-@``'$4!`!PW```KGP``
+M(#<``"R?```D-P``'$0!`#0W```KH```.#<``"R@```\-P``'$0!`&0W```K
+MH0``:#<``"RA``!L-P``'$0!`'PW```KH@``@#<``"RB``"$-P``'$0!`*`W
+M```KHP``I#<``"RC``"H-P``'$0!`+@W```KI```O#<``"RD``#`-P``'$0!
+M`.PW```<1P$`_#<``!Q'`0`@.```'$D!`#0X```<,P$`B#@``!Q'`0"8.```
+M'$<!`,@X```<1@$`&#D``!Q'`0`H.0``'$<!`)@Y```<1P$`J#D``!Q'`0"\
+M.0``'$<!`-`Y```KK0``U#D``"RM``#8.0``'$0!```Z```KK@``!#H``"RN
+M```(.@``*Z\```PZ```LKP``%#H``"NP```8.@``++```%`Z```<1`$`C#L`
+M`!Q'`0"<.P``'$<!`-0[```<2@$`^#L``!P%`0#\.P``*[$````\```LL0``
+M*#P``"NR```L/```++(``$`\```<!`$`:#P``!P%`0"`/```'`L!`+P\```<
+M1P$`S#P``!Q'`0#@/```'$<!`/0\```<!0$`0#T``!Q'`0!0/0``'$<!`&0]
+M```<1P$`C#T``!P%`0"0/0``*[,``)0]```LLP``O#T``"NR``#`/0``++(`
+M`-0]```<!`$`_#T``!P%`0`4/@``'`L!`%`^```<1P$`8#X``!Q'`0!T/@``
+M'$<!`(@^```<!0$`U#X``!Q'`0#D/@``'$<!`/@^```<1P$`>#\``!Q+`0#0
+M/P``'$<!`.`_```<1P$`]#\``!Q'`0!X0```'$<!`(A````<1P$`X$```!PF
+M`0`<00``'"<!`%1!```<_P``H$$``!PH`0#T00``'$P!``1"```<3`$`,$(`
+M`!P<`0!$0@``'!,!`'1"```<$P$`I$(``!PG`0"X0@``'$T!`.!"```<&`$`
+M]$(``!Q``0`(0P``'$$!`!1#```<30$`,$,```+U```T0P```N@``#A#```"
+M]0``6$,``!P%`0!P0P``'`4!`(A#```<3P$`L$,``!P%`0#(0P``'#,!`.!#
+M```<3P$`"$0``!P%`0`@1```'$\!`$1$```<'`$`D$0``!Q1`0"L1```'%$!
+M`.Q$```<!0$`_$0``!PS`0`$10``'"8!`"A%```<4@$`/$4``!PH`0!810``
+M'!@!`'Q%```<!0$`$$8``!PS`0!$1@``'"8!`&A&```<4@$`?$8``!PH`0"(
+M1@``'%,!`*A&```"Z```U$8``!Q4`0`41P``'`8!`#1'```<!P$`0$<``!Q5
+M`0!T1P``*Y$``'A'```LD0``G$<``!P8`0#$1P``'#,!`/Q'```<&`$`6$@`
+M`!P+`0!H2```'%8!`)!(```"`@``E$@```("``"82````@(``)Q(```"`@``
+MH$@```("``"D2````@(``*A(```"`@``K$@```("``"P2````@(``+1(```K
+MQ0``N$@``"S%``"\2```'!,!`,!(```K50``Q$@``"Q5``#42```*U4``-A(
+M```L50``X$@``!Q7`0#L2```*U@!`/!(```L6`$`$$D``!P3`0`820``'%D!
+M`"Q)```KQ@``,$D``"S&``!D20``'$\!`&Q)```KQP``<$D``"S'``!X20``
+M'$<!`(!)```KR```A$D``"S(``"(20``'!,!`)!)```KR0``E$D``"S)``#(
+M20``'$\!`-!)```KQP``U$D``"S'``#<20``'$<!`.!)```K50``Y$D``"Q5
+M``#T20``*U4``/A)```L50```$H``!Q:`0`D2@``*\H``"A*```LR@``.$H`
+M`!P$`0!$2@``*\<``$A*```LQP``4$H``!Q'`0"02@``*\L``)1*```LRP``
+MF$H``!P$`0#02@``*\P``-1*```LS```V$H``!P$`0#P2@``*\T``/1*```L
+MS0``_$H``!PA`0`$2P``*\X```A+```LS@``#$L``!P)`0`D2P``*\\``"A+
+M```LSP``+$L``!P)`0!$2P``*]```$A+```LT```3$L``!P)`0!D2P``*]$`
+M`&A+```LT0``;$L``!P)`0!\2P``*](``(!+```LT@``C$L``!P3`0"02P``
+M*UL!`)1+```L6P$`L$L``!PS`0#,2P``*\<``-!+```LQP``V$L``!Q'`0#@
+M2P``*UL!`.1+```L6P$`%$P``"O3```83```+-,``"!,```<!`$`)$P``"M;
+M`0`H3```+%L!`"Q,```KU```,$P``"S4```\3```'!,!`$A,```KQP``3$P`
+M`"S'``!43```'$<!`&1,```<"P$`I$P``!PM`0#$3```'%4!`-1,```"Z```
+MV$P```(#``#<3````O4``.!,```"6`$`]$P``!P<`0`@30```@(``"1-```"
+M`@``*$T```("```L30```@(``%Q-```<0`$`<$T``!Q<`0"<30``'#L!`+A-
+M```<.P$`S$T``!PR`0#D30``'`4!``A.```KD0``#$X``"R1```@3@``'#,!
+M`$1.```<70$`5$X``!Q>`0!P3@``*Y$``'1.```LD0``S$X``!PN`0`43P``
+M'`8!`#1/```<!P$`0$\``!PR`0!@3P```@(``&1/```"`@``:$\```("``!L
+M3P```@(``(!0```<3`$`D%```!Q,`0#@4```'"T!`/A0```<,@$`-%$``!PN
+M`0!\40``'`8!`)Q1```<!P$`J%$``!PR`0#(40```@(``,Q1```"`@``T%$`
+M``("``#440```@(``-A1```"`@``W%$```("``#@40```@(``.11```"`@``
+MZ%$```("``#L40```@(``/!1```"`@``]%$```("``#X40```@(``/Q1```"
+M`@```%(```("```$4@```@(```A2```"`@``#%(```("```04@```@(``"12
+M```<8`$`+%(``!QA`0!P4@``'"4!`)A2```<,P$`Z%(``!PS`0``4P``'&(!
+M`$Q3```<)0$`8%,``!QC`0"84P``'#,!`,13```<9`$`.%0``!PE`0!45```
+M'`D!`&A4```<"0$`Q%0``!PN`0#<5```'`4!`/Q4```<,P$`9%4``!PS`0"D
+M50``'#,!`!A6```<,P$`2%8``!P)`0"$5@``'#,!`*A6```<,P$`R%8``!PS
+M`0#D5@``'`D!`!Q7```<,P$`<%<``!PW`0#H5P``'#,!`/17```<"0$`)%@`
+M`!P)`0!$6```'#,!`%18```<,P$`<%@``!P)`0",6```'#L!`*18```<.P$`
+MN%@``!PR`0#$6```'%T!`/Q8```<,P$`#%D``!PS`0`<60``'%X!`%A9```<
+M,P$`B%D``!P)`0#$60``'#,!`.A9```<,P$`"%H``!PS`0`D6@``'`D!`%Q:
+M```<,P$`L%H``!PW`0#D6@``'#(!`"A;```<)0$`;%L``!PS`0"T6P``'#(!
+M`-!;```<+@$`[%L``!PS`0``7```'&4!`$A<```<,@$`9%P``!PN`0"`7```
+M'#,!`+Q<```<,@$`V%P``!PN`0#T7```'#,!`#Q=```<+0$`5%T``!PR`0!P
+M70``'`D!`)1=```"]0``F%T```+U``"<70```O4``*!=```"]0``I%T```+H
+M``"L70``*U4``+!=```L50``P%T``!Q9`0#470``'%H!`-Q=```<9P$`Y%T`
+M``($``#L70``*U4``/!=```L50```%X``"OG```$7@``+.<```A>```<:0$`
+M$%X``!Q7`0`P`````O4``#0````"]0``.`````+U```\`````O4``$`````"
+M]0``1`````+U``!(`````O4``$P````"]0``4`````+U``!4`````@,``&``
+M```"`P``9`````+H``!H`````C<``'`````"FP``=`````(@``!X`````B``
+M`'P````""P``@`````*I``"$`````M8``(@````"#0``C`````(@``"0````
+M`@\``)@````"I@``G`````+!``"L`````B```+`````"(```O`````*X``#`
+M`````G@``,0````"M@``R`````(@``#,`````KX``-`````"M```U`````*9
+M``#8`````G8``-P````"(```X`````)S``#L`````I8``/`````"E```]```
+M``(@``#X`````A(``/P````"%`````$```(6```$`0```B````@!```"(```
+M#`$```(@```0`0```A@``!0!```">@``&`$```)O```<`0```B```"`!```"
+M&@``+`$```*2```T`0```H<``#P!```"@```1`$```)M``!,`0```EX``%`!
+M```":@``5`$```(H``!8`0```F@``%P!```"9@``8`$```(J``!D`0```DP`
+M`&@!```")```;`$```(B``!P`0```B8``'0!```"9```>`$```)@``!\`0``
+M`AP``(`!```".0``A`$```(>``"(`0```AX``(P!```"+```D`$```(N``"4
+M`0```C```)P!```"-0``H`$```(>``"D`0```ED``*@!```"'@``K`$```)3
+M``"P`0```AX``+0!```"3@``N`$```(\````````*@(`````````_@``"```
+M`"H"```0````*@(``!@````J`@``(````"H"```H````*@(``#`````J`@``
+M.````"H"``!`````*@(``$@````J`@``4````"H"``!8````*@(``&`````J
+M`@``:````"H"``!P````*@(``'@````J`@``@````"H"``"(````*@(``)``
+M```J`@``F````"H"``"@````*@(``*@````J`@``L````"H"``"X````*@(`
+M`,`````J`@``R````"H"``#0````*@(``-@````J`@``X````"H"``#H````
+M*@(``/`````J`@``\``````4`0#T````*@<``/@````J`@````$``"H"```(
+M`0``*@(``!`!```J`@``&`$``"H"```@`0``*@(``"@!```J`@``,`$``"H"
+M```X`0``*@(``$`!```J`@``2`$``"H"``!0`0``*@(``%@!```J`@``8`$`
+M`"H"``!H`0``*@(``'`!```J`@``>`$``"H"``"``0``*@(``(@!```J`@``
+MD`$``"H"``"8`0``*@(``*`!```J`@``J`$``"H"``"P`0``*@(``+@!```J
+M`@``P`$``"H"``#(`0``*@(``-`!```J`@``V`$``"H"``#@`0``*@(``.@!
+M```J`@``\`$``"H"``#X`0``*@(````"```J`@``"`(``"H"```0`@``*@(`
+I`!@"```J`@``(`(``"H"```H`@``*@(``#`"```J`@``.`(``"H"````
 `
 end
index e60ef105a17feb7a6a0c62ad044c132a2f30d331..8b1969b779e7ad712b533b0906d55b31b2ba876c 100755 (executable)
@@ -7,7 +7,7 @@
 /*
  * Broadcom BCM4319 driver version.
  */
-#define RTL8192_DRV_VERSION "3.26"
+#define RTL8192_DRV_VERSION "3.28"
 
 #endif /* WIFI_BCM4319_VERSION_H */
 
index 2e54df136b93d1fa1878b9ea9a908e70b30b4cd8..90fcf8a52032e74bcfba6bf8120572b5a49ca3e7 100644 (file)
@@ -55,7 +55,7 @@ static ssize_t wifi_channel_write(struct class *cls, const char *_buf, size_t _c
 */\r
 \r
 static struct class *rkwifi_class = NULL;\r
-static CLASS_ATTR(chip, 0666, wifi_chip_read, NULL);\r
+static CLASS_ATTR(chip, 0664, wifi_chip_read, NULL);\r
 \r
 int rkwifi_sysif_init(void)\r
 {\r
index 26ec079b6e5f720e515a691524ab7e665813b0d7..f4abd3ccd1603c11e90be00db77df236636b09c8 100755 (executable)
@@ -1096,39 +1096,6 @@ static int rk29_adc_battery_probe(struct platform_device *pdev)
     //variable init
        data->client  = client;
        data->adc_val = adc_sync_read(client);
-       
-       //init a timer for adc sample
-       //init a delay work for adc timer work
-    setup_timer(&data->timer, rk29_adc_battery_scan_timer, (unsigned long)data);
-       data->timer.expires  = jiffies + 2000;
-       add_timer(&data->timer);
-
-       INIT_WORK(&data->timer_work, rk29_adc_battery_timer_work);
-       INIT_WORK(&data->resume_work, rk29_adc_battery_resume_check);
-       
-#if defined(CONFIG_BATTERY_RK29_AC_CHARGE)
-       //init dc dectet irq & delay work
-    if (pdata->dc_det_pin != INVALID_GPIO)
-    {
-        irq = gpio_to_irq(pdata->dc_det_pin);
-        
-        irq_flag = gpio_get_value (pdata->dc_det_pin) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
-       ret = request_irq(irq, rk29_adc_battery_dc_wakeup, irq_flag, "rk29_adc_battery", NULL);
-       if (ret) {
-               printk("failed to request dc det irq\n");
-               goto err_dcirq_failed;
-       }
-       enable_irq_wake(irq);
-       
-       INIT_WORK(&data->dcwakeup_work, rk29_adc_battery_dcdet_delaywork);
-    }
-#endif
-    
-    //Power on Battery detect
-       rk29_adc_battery_lowpower_check(data);
-    
-    //power supply register
-    wake_lock_init(&batt_wake_lock, WAKE_LOCK_SUSPEND, "batt_lock");
 
        ret = power_supply_register(&pdev->dev, &rk29_battery_supply);
        if (ret)
@@ -1137,14 +1104,6 @@ static int rk29_adc_battery_probe(struct platform_device *pdev)
                goto err_battery_failed;
        }
        
-#if defined(CONFIG_BATTERY_RK29_AC_CHARGE)
-       ret = power_supply_register(&pdev->dev, &rk29_ac_supply);
-       if (ret)
-       {
-               printk(KERN_INFO "fail to ac power_supply_register\n");
-               goto err_ac_failed;
-       }
-#endif
 
 #if defined(CONFIG_BATTERY_RK29_USB_CHARGE)
        ret = power_supply_register(&pdev->dev, &rk29_usb_supply);
@@ -1154,7 +1113,47 @@ static int rk29_adc_battery_probe(struct platform_device *pdev)
                goto err_usb_failed;
        }
 #endif
-       
+
+       INIT_WORK(&data->timer_work, rk29_adc_battery_timer_work);
+       INIT_WORK(&data->resume_work, rk29_adc_battery_resume_check);
+
+       //init a timer for adc sample
+       //init a delay work for adc timer work
+       setup_timer(&data->timer, rk29_adc_battery_scan_timer, (unsigned long)data);
+       data->timer.expires  = jiffies + 2000;
+       add_timer(&data->timer);
+
+
+       wake_lock_init(&batt_wake_lock, WAKE_LOCK_SUSPEND, "batt_lock");        
+
+#if defined(CONFIG_BATTERY_RK29_AC_CHARGE)
+
+       ret = power_supply_register(&pdev->dev, &rk29_ac_supply);
+       if (ret) {
+               printk(KERN_INFO "fail to ac power_supply_register\n");
+               goto err_ac_failed;
+       }
+       //init dc dectet irq & delay work
+       if (pdata->dc_det_pin != INVALID_GPIO)
+       {
+               INIT_WORK(&data->dcwakeup_work, rk29_adc_battery_dcdet_delaywork);
+               irq = gpio_to_irq(pdata->dc_det_pin);
+               
+               irq_flag = gpio_get_value (pdata->dc_det_pin) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
+               ret = request_irq(irq, rk29_adc_battery_dc_wakeup, irq_flag, "rk29_adc_battery", NULL);
+               if (ret) {
+                       printk("failed to request dc det irq\n");
+                       goto err_dcirq_failed;
+               }
+               enable_irq_wake(irq);
+       
+       }
+#endif
+    
+       //Power on Battery detect
+       rk29_adc_battery_lowpower_check(data);
+    
+
        printk(KERN_INFO "rk29_adc_battery: driver initialized\n");
        
        return 0;
index 3ee30132f446813a56a5de1f5630c26cda3191c2..fdf5c74f9f44870272623aae046a6dd5c101f414 100755 (executable)
@@ -44,9 +44,9 @@ static int batt_step_table[batt_num] = {
        3710,3714,3718,3722,3726,
        3730,3734,3738,3742,3746,
        3750,3756,3764,3774,3786,
-       3800,3808,3817,3827,3838,
+       3800,3808,3817,3827,3845,
        3950,3964,3982,4002,4026,
-       4050,4074,4098,4123,4149,4178
+       4030,4034,4055,4070,4085,4120
 };
 
 static int batt_disp_table[batt_num] = {
@@ -63,16 +63,16 @@ static int batt_disp_table[batt_num] = {
 };
 
 static int batt_chg_step_table[batt_num] = {
-       3530,3565,3600,3635,3655,3680,//+160
-       3700,3717,3734,3745,3755,//+150
-       3770,3778,3786,3795,3803,//+140
+       3520,3525,3575,3600,3620,3644,//+160
+       3662,3670,3684,3700,3715,//+150
+       3720,3748,3756,3775,3790,//+140
        3810,3814,3818,3822,3825,//+130
        3830,3832,3834,3836,3837,//+120
-       3840,3842,3844,3846,3847,//+110
-       3850,3857,3864,3871,3876,//+100
-       3890,3897,3904,3911,3918,//+90
+       3839,3841,3842,3844,3844,//+110
+       3855,3860,3864,3871,3890,//+100
+       3910,3930,3952,3977,3997,//+90
        4030,4047,4064,4080,4096,//+80
-       4120,4132,4144,4156,4170,4180//+70
+       4132,4144,4150,4170,4195,4200//+70
 };
 
 
@@ -739,8 +739,13 @@ void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int
        static int chg_num = 60;
        static int disp_plus = 1000;
        static int disp_minus = 1000;
+       static int disp_minus2 = 1000;
        static int disp_curr = 0;
        static int disp_num = 50;
+       static int batt_level_all = 0;
+       static int batt_level[20];
+       static int avr_num = 0;
+       static int avr_int = 0;
 
 
        *level = wm831x_power->batt_info.level;
@@ -760,27 +765,48 @@ void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int
        {
                disp_plus = 0;
                disp_minus = 0;
+               disp_minus2 = 0;
                disp_curr = 0;
-               
                for(i = 0; i < batt_num; i++){        
-                       if((batt_chg_step_table[i] <= batt_vol) && 
-                                        (batt_chg_step_table[i+1] > batt_vol))
+                       if(batt_vol >= batt_chg_step_table[i] && 
+                                        batt_vol < batt_chg_step_table[i+1])
                                break;     
                }
-               *level = batt_disp_table[i];
-
-               if (batt_vol <= batt_chg_step_table[0])
-                       *level = 0;
-               if (batt_vol >= batt_chg_step_table[batt_num - 1])
-                       *level = 100;
-
-               // ³õʼ״̬
+               if(batt_vol <= batt_chg_step_table[0])
+                       i = 0;
+               if(batt_vol >= batt_chg_step_table[batt_num-1])
+                       i = batt_num-1;
+               if(avr_int==0){
+                       batt_level[avr_num] = batt_disp_table[i];
+                       batt_level_all += batt_level[avr_num];
+                       avr_num++;
+                       if(avr_num >= 20)
+                       {
+                               avr_num = 0;
+                               avr_int = 1;
+                       }
+                       else
+                       {
+                               *level = batt_disp_table[i];
+                               return 0;
+                       }
+               }
+               else {
+                       batt_level_all -= batt_level[avr_num];
+                       batt_level[avr_num]=batt_disp_table[i];
+                       batt_level_all += batt_level[avr_num];
+                       avr_num++;
+               }
+               if(avr_num >= 20) 
+                       avr_num = 0;
+               *level = batt_level_all/20;
                if ((chg_plus == 1000) && (chg_minus == 1000))
                {
                        *level = *level;
                        chg_plus = 0;
                        chg_minus = 0;
                        chg_curr = 0;
+
                }
                else
                {                       
@@ -789,54 +815,15 @@ void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int
                        {
                                chg_minus = 0;
                                chg_curr = 0;
-                               
+                               if(*level < 85)
+                                       chg_num =10;
+                               else
+                                       chg_num = 5;
                                if (++chg_plus > chg_num)
                                {
                                        *level = wm831x_power->batt_info.level + 1;
                                        chg_plus = 0;
-                                       
-                                       if(*level < 85)
-                                       chg_num = 60;
-                                       else 
-                                       chg_num = 20;
-                       
-                               }
-                               else
-                               {
-                                       *level = wm831x_power->batt_info.level;
-                               }               
-                       }
-
-                       else if (*level >= wm831x_power->batt_info.level)
-                       {
-                               chg_plus = 0;
-                               chg_minus = 0;
-
-                               if (++chg_curr > chg_num)
-                               {
-                                       *level = *level;
-                                       chg_curr = 0;
-                               }
-                               else
-                               {
-                                       *level = wm831x_power->batt_info.level;
-                               }
-                       }
-                       else if (*level < (wm831x_power->batt_info.level-1))    
-                       {
-                               chg_plus = 0;
-                               chg_curr = 0;
                                
-                               if (++chg_minus > (chg_num<<1))
-                               {
-                                       *level = wm831x_power->batt_info.level - 1;
-                                       chg_minus = 0;
-
-                                       if(*level < 85)
-                                       chg_num = 60;
-                                       else 
-                                       chg_num = 20;
-
                                }
                                else
                                {
@@ -863,89 +850,91 @@ void wm831x_batt_vol_level(struct wm831x_power *wm831x_power, int batt_vol, int
                chg_plus = 0;
                chg_minus = 0;
                chg_curr = 0;
-
                for(i = 0; i < batt_num; i++){        
                        if(batt_vol >= batt_step_table[i] && 
                                         batt_vol < batt_step_table[i+1])
                                break;     
                }
-               *level = batt_disp_table[i];
-
-               if (batt_vol <= batt_step_table[0])
-                       *level = 0;
-               if (batt_vol >= batt_step_table[batt_num - 1])
-                       *level = 100;
-
-               // ³õʼ״̬
+               if(batt_vol <= batt_step_table[0])
+                       i = 0;
+               if(batt_vol >= batt_step_table[batt_num-1])
+                       i = batt_num-1;
+               if(avr_int==0){
+                       batt_level[avr_num] = batt_disp_table[i];
+                       batt_level_all += batt_level[avr_num];
+                       avr_num++;
+                       if(avr_num >= 20)
+                       {
+                               avr_num = 0;
+                               avr_int = 1;
+                       }
+                       else
+                       {
+                               *level = batt_disp_table[i];
+                               return 0;
+                       }
+               }
+               else {
+                       batt_level_all -= batt_level[avr_num];
+                       batt_level[avr_num]=batt_disp_table[i];
+                       batt_level_all += batt_level[avr_num];
+                       avr_num++;
+               }
+               if(avr_num >= 20) 
+                       avr_num = 0;
+               *level = batt_level_all/20;
                if ((disp_plus == 1000) && (disp_minus == 1000))
                {
                        *level = *level;
                        disp_plus = 0;
                        disp_minus = 0;
+                       disp_minus2 =0;
                        disp_curr = 0;
                }
                else
-               {                       
-
-                       if (*level <= (wm831x_power->batt_info.level-1))        
+               {       
+                       if(*level <= (wm831x_power ->batt_info.level -20))
                        {
                                disp_plus = 0;
                                disp_curr = 0;
-                               
-                               if (++disp_minus > disp_num)
+                               disp_minus2 = 0;
+                               disp_num = 1;
+                                if (++disp_minus > disp_num)
                                {
-                                       *level = wm831x_power->batt_info.level - 1;
+                                       *level = wm831x_power->batt_info.level - 20;
                                        disp_minus = 0;
-
-                                       if((*level < 17) || (*level > 85))
-                                       disp_num = 10;
-                                       else
-                                       disp_num = 50;
-
                                }
                                else
                                {
                                        *level = wm831x_power->batt_info.level;
                                }
                        }
-                       else if (*level <= wm831x_power->batt_info.level)
+                       else if (*level <= (wm831x_power->batt_info.level-1))   
                        {
                                disp_plus = 0;
+                               disp_curr = 0;
                                disp_minus = 0;
-
-                               if (++disp_curr > disp_num)
-                               {
-                                       *level = *level;
-                                       disp_curr = 0;
-                               }
+                               if((*level < 17) || (*level > 85))
+                                       disp_num = 30;
                                else
+                                       disp_num = 80;
+               
+                                if (++disp_minus2 > disp_num)
                                {
-                                       *level = wm831x_power->batt_info.level;
-                               }
-                       }
-                       else if (*level >= (wm831x_power->batt_info.level+1))
-                       {
-                               disp_minus = 0;
-                               disp_curr = 0;
-                               
-                               if (++disp_plus > (disp_num<<1))
-                               {
-                                       *level = wm831x_power->batt_info.level + 1;
-                                       disp_plus = 0;
-                                       if((*level < 17) || (*level > 85))
-                                       disp_num = 10;
-                                       else
-                                       disp_num = 50;
+                                       *level = wm831x_power->batt_info.level - 1;
+                                       disp_minus2 = 0;
                                }
                                else
                                {
+
                                        *level = wm831x_power->batt_info.level;
-                               }               
+                               }
                        }
                        else
                        {
                                disp_plus = 0;
                                disp_minus = 0;
+                               disp_minus2 = 0;
                                disp_curr = 0;
                                *level = wm831x_power->batt_info.level;
                        }
index 91c8043fc5766f0c495debd5fa43070fb48c911f..348bfa844439dd6e7676cddf844dfe3c31105734 100755 (executable)
@@ -21,6 +21,7 @@
 #include <linux/gpio.h>
 #include <linux/slab.h>
 
+#include <linux/delay.h>
 #include <linux/mfd/wm8994/core.h>
 #include <linux/mfd/wm8994/registers.h>
 #include <linux/mfd/wm8994/pdata.h>
@@ -258,6 +259,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
                                ret);
                        goto err_gpio;
                }
+               msleep(50);
        } else
                ldo->is_enabled = true;
 
index e8133d0a60cff77d8d646dae05769777743913c3..21f453f501f2f1bbcf731fdcb91f41759891262c 100644 (file)
           0 - no use,original code
           1 - use
 */
-#define gcdENABLE_MMU_PROTECTING 1
+#define gcdENABLE_MMU_PROTECTING                       1
 
 #endif /* __gc_hal_options_h_ */
 
index d7053961b81ff9c8f9c7a0e39e93cdb73626c61a..cd63265d98deaa30b90574cbf0152e43664a6afb 100644 (file)
@@ -325,7 +325,6 @@ gckMMU_Construct(
        return gcvSTATUS_OK;
 
 OnError:
-       
        /* Roll back. */
        if (mmu != gcvNULL)
        {
@@ -509,7 +508,7 @@ gckMMU_AllocatePages(
                /* Not enough pages avaiable. */
                gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
        }
-               
+
        /* Grab the mutex. */
        gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
        mutex = gcvTRUE;
@@ -641,7 +640,6 @@ gckMMU_AllocatePages(
        return gcvSTATUS_OK;
 
 OnError:
-       
        if (mutex)
        {
                /* Release the mutex. */
@@ -690,7 +688,6 @@ gckMMU_FreePages(
        gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
                                   Mmu, PageTable, PageCount);
 
-
        /* Verify the arguments. */
        gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
        gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
index c958e0e8856989960452ecbef12d11ae7165f354..823e5de8b1d3a006bda0ce34b737b4c5ab304f4a 100755 (executable)
@@ -1003,9 +1003,12 @@ static void drv_exit(void)
 
     unregister_chrdev(major, DRV_NAME);
 #endif
-    
-    shutdown = 1;   
+
+    shutdown = 1;
+          
+       //hyh added 
     return;
+       
     mdelay(100); 
     gckGALDEVICE_Stop(galDevice);
     mdelay(50); 
index 2d6f5dc919283e38019f40894de1ef6ce038806d..1e1b0d4ae36588d079da3f57a96c3d64cbc90827 100755 (executable)
@@ -4557,8 +4557,13 @@ gckOS_WaitSignal(
     if (!signal->manualReset && timeout == 0) timeout = 1;
 
     rc = wait_for_completion_interruptible_timeout(&signal->event, timeout);
+
+#if 1   // dkm : avoid return OK when timeout in kernel3.0
+    status = (rc == 0) ? gcvSTATUS_TIMEOUT : gcvSTATUS_OK;
+#else
     status = ((rc == 0) && !signal->event.done) ? gcvSTATUS_TIMEOUT
                                                 : gcvSTATUS_OK;
+#endif
 
     /* Return status. */
     gcmkFOOTER();
index 6b40a29fe9cc44ac968fff20799962b01a2f27b0..703d281f0688d0e955a023002300913dcf4129e1 100644 (file)
@@ -538,8 +538,9 @@ static int mass_storage_function_init(struct android_usb_function *f,
        if (!config)
                return -ENOMEM;
 
-       config->fsg.nluns = 1;
+       config->fsg.nluns = 2;
        config->fsg.luns[0].removable = 1;
+       config->fsg.luns[1].removable = 1;
 
        common = fsg_common_init(NULL, cdev, &config->fsg);
        if (IS_ERR(common)) {
@@ -550,6 +551,7 @@ static int mass_storage_function_init(struct android_usb_function *f,
        err = sysfs_create_link(&f->dev->kobj,
                                &common->luns[0].dev.kobj,
                                "lun");
+        err = sysfs_create_link(&f->dev->kobj, &common->luns[1].dev.kobj,"lun1");
        if (err) {
                kfree(config);
                return err;
old mode 100644 (file)
new mode 100755 (executable)
index b4b023b..e881ba4
@@ -771,7 +771,7 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr,
        printk("store_file: \"%s\"\n", buf);
 #endif
 
-#ifndef CONFIG_USB_ANDROID_MASS_STORAGE
+#ifndef CONFIG_USB_G_ANDROID
        /* disabled in android because we need to allow closing the backing file
         * if the media was removed
         */
index 8dc95fdfa2fe675d2f91ab64a3a8a5d61fe5cd30..c077022fe7decb1dfdd766c0de952ea6ce59d52a 100644 (file)
@@ -1108,6 +1108,12 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(ZTE_VENDOR_ID, 0xFFFF) },
        { USB_DEVICE(LEADCORE_VENDOR_ID, 0x5700) },
        { USB_DEVICE(LEADCORE_VENDOR_ID, 0x6341) },
+       { USB_DEVICE(0x230d, 0x000d) },
+       { USB_DEVICE(0x0E8D, 0x00A2) },
+       { USB_DEVICE(0x1E89, 0x1A20) },
+       { USB_DEVICE(0x12D1, 0x1C05) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff) },
 
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
        { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
@@ -1332,11 +1338,13 @@ static void option_instat_callback(struct urb *urb)
        int status = urb->status;
        struct usb_serial_port *port =  urb->context;
        struct option_port_private *portdata = usb_get_serial_port_data(port);
+       static int err_times = 0;
 
        dbg("%s", __func__);
        dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
 
        if (status == 0) {
+               err_times = 0;
                struct usb_ctrlrequest *req_pkt =
                                (struct usb_ctrlrequest *)urb->transfer_buffer;
 
@@ -1370,9 +1378,17 @@ static void option_instat_callback(struct urb *urb)
                        dbg("%s: type %x req %x", __func__,
                                req_pkt->bRequestType, req_pkt->bRequest);
                }
-       } else
-               err("%s: error %d", __func__, status);
-
+       }
+       else{
+               if(status == -EPROTO && err_times++ >10){
+                       err_times = 0;
+                       printk("%s,recieve -71 error more than 10 times,so reset usb\n",__FUNCTION__);
+                       usb_queue_reset_device(port->serial->interface);
+                       return;
+               }else           
+                       err("%s : error %d",__func__, status);
+       }
+       
        /* Resubmit urb so we continue receiving IRQ data */
        if (status != -ESHUTDOWN && status != -ENOENT) {
                err = usb_submit_urb(urb, GFP_ATOMIC);
old mode 100644 (file)
new mode 100755 (executable)
index 1c03130..677c3b9
@@ -53,6 +53,10 @@ static struct usb_driver usb_serial_driver = {
        .no_dynamic_id =        1,
        .supports_autosuspend = 1,
 };
+#ifdef CONFIG_MU509
+static int MU509_USB = 0;
+#define MU509_USB_PORT     (SERIAL_TTY_MINORS - 10)
+#endif
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
    the MODULE_DEVICE_TABLE declarations in each serial driver
@@ -97,12 +101,17 @@ static struct usb_serial *get_free_serial(struct usb_serial *serial,
 {
        unsigned int i, j;
        int good_spot;
+       int a=0;
 
        dbg("%s %d", __func__, num_ports);
 
        *minor = 0;
        mutex_lock(&table_lock);
-       for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+#ifdef CONFIG_MU509
+       if (MU509_USB)
+               a= MU509_USB_PORT;
+#endif
+       for (i = a; i < SERIAL_TTY_MINORS; ++i) {
                if (serial_table[i])
                        continue;
 
@@ -1058,6 +1067,12 @@ int usb_serial_probe(struct usb_interface *interface,
        } else {
                serial->attached = 1;
        }
+#ifdef CONFIG_MU509
+               if ((le16_to_cpu(dev->descriptor.idVendor) == 0x12D1 ) && (le16_to_cpu(dev->descriptor.idProduct) == 0x1001))
+                       MU509_USB =1;
+               else
+                       MU509_USB = 0;
+#endif
 
        if (get_free_serial(serial, num_ports, &minor) == NULL) {
                dev_err(&interface->dev, "No more free serial devices\n");
index 3c49a34c7cb625cc18832a614e47c4b2d98b41fe..396a1ff6ef5ba740e5214a70dd7564c1d2a009dd 100755 (executable)
@@ -6,10 +6,17 @@
 
 obj-$(CONFIG_VGASTATE)            += vgastate.o
 obj-y                             += fb_notify.o
+
 obj-$(CONFIG_FB)                  += fb.o
+ifdef CONFIG_MACH_RK29_2906
+fb.o: fb.uu
+       @echo "UUDE    fb.uu"
+       @uudecode fb.uu -o fb.o
+else
 fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
                                      modedb.o fbcvt.o
 fb-objs                           := $(fb-y)
+endif
 
 obj-$(CONFIG_VT)                 += console/
 obj-$(CONFIG_LOGO)               += logo/
diff --git a/drivers/video/fb.uu b/drivers/video/fb.uu
new file mode 100644 (file)
index 0000000..6923fb9
--- /dev/null
@@ -0,0 +1,1187 @@
+begin 644 fb.o
+M?T5,1@$!`0````````````$`*``!``````````````#X<0``````!30`````
+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
+M(*#C_O__ZP``4.(!`*`3````Z@``H.,!<'#B`'"@,P``5N,`<*`#``!7XQT`
+M``H`0*#C@)"?Y01PH.$!L(;B!%"9YP@`H.$&(*#A!$"$X@`05>((```*`##5
+MY0``4^,%```*_O__ZP``4.,"```:!C#5YSH`4^,+<(4`@`!4X^[__QH``%?C
+M!P"@`04```H'`*#A)!"?Y0,@H./^___K`0!PX@``H#,``%KC`'"*%?B/O>@`
+M````Q@```*````#+````<T`MZ010D.4?`%7C,0``BL@@G^4%(8+@%$"2Y0``
+M5.$L```:_O__ZP``4.,2`.`#*0``"@@0C>(.`*#C"$`AY0T0H.'^___K`&"@
+MX0P`A.+^___K``!6XQX``!JD`93E``!0XP,```J\,93E`0`3XP````K^___K
+MA0^$X@!@H./^___K5#"?Y00`H.$%$8/@("&3Y11@@>4!($+B("&#Y?[__^LX
+M,)_E'1:%XP``D^7^___K"!"-X@8`H.,(0"'E#1"@X?[__^L$`*#A&/S_ZP8`
+MH.$```#J%0#@XWR`O>@``````````'!`+>DD0)_E`%"@X00`H.'^___K!0"@
+MX;[__^L`4*#A!`"@X?[__^L%`*#A<("]Z`````#P3RWI`$"@XX"1G^4\T$WB
+M`+"@X03`H.$L$(WE,""-Y00PF><``%/C3P``"@@@D^4"!Q+C3```"DA2D^4`
+M`%7C``!;$P"@H!,!H*`#!!"@$2B@C14I```:+0``Z@@@E.4'8(7@##"@X20!
+MG^4T((WE!$"6Z02@E.4`X(WE-."=Y03`C>4,P(WE%,"-Y200C>4@P(WE"*"-
+MY1#@C>7^___K!#"6Y00@E.4D$)WE`@!3X2#`G>4B```*+P``F@@`E.4`((+@
+M`@!3X1T``#HJ``#J`'"@XPI`B^`'@*#A'*"-Y0`PE>4#`%CAV___.AR@G>4H
+M()WE"*"*X@$@@N(H((WE`#";Y2@@G>4#`%+A[___.@%`H.$P,)WE``!3XQ(`
+M``H``%7C$```"@`PE>4``%/C#0``"@0PE>4*"%/C"@``&@```.H!0*#A!""9
+MYRP0G>7$((+B/`"?Y2#`C>7^___K!`"9YU[__^L@P)WE!$"$XH``5..I__\:
+M`@``Z@&`B.((<(?BU?__ZCS0C>+PC[WH%````,\````"`0``\$$MZ2Q`G^4`
+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
+M,,/C"#"3Y1@@EN(#(-(P`#"@,P``4^,:```:!A"@X04`H.$8(*#C_O__ZP``
+M4./@```:!0"@X000H.'^___K(@``Z@T@H.'H4(WB?SW"XS\PP^,(,)/E&""6
+MX@,@TC``,*`S``!3XP8``!H&$*#A!0"@X1@@H./^___K``!0X\P``!H"``#J
+M!0"@X1@0H..#``#J!`"@X?[__^L``%#CP@``"G_OA.(!S(WB#P"^Z`\`K.@#
+M`)[H`P",Z`P`A.+^___K!1"@X0$,C>+^___K`%"@X;P``.H-,*#A!'"-XG^-
+MP^,_@,CC"#"8Y:`@EN(#(-(P`#"@,P``4^,&```:!P"@X080H.&@(*#C_O__
+MZP``4..G```:`@``Z@<`H.&@$*#C7@``Z@0`H.'^___K``!0XYT```K^___K
+M!Q"@X00`H.'^___K`%"@X?[__^L,`(3B_O__ZP``5>.:```:"#"8Y:`@EN(#
+M(-(P`#"@,P``4^./```:!@"@X000C>*@(*#C_O__ZP``4...```*B```Z@T@
+MH.$27HWB?SW"XS\PP^,(,)/E"""6X@,@TC``,*`S``!3XS<``!H%`*#A!A"@
+MX0@@H./^___K``!0XW@``!H@,9WE`3!#XCX`4^-V``"*!`"@X0`PX.,<48WE
+M)#&-Y?[__^L``%#C:P``"DH?C>('`*#C$$`AY?[__^L,`(3B_O__ZPT@H.%_
+M/<+C/S##XP@PD^4(();B`R#2,``PH#,``%/C7@``&@8`H.$2'HWB"""@X_[_
+M_^L``%#C7```"E<``.H-(*#A$EZ-XG\]PN,_,,/C"#"3Y0@@EN(#(-(P`#"@
+M,P``4^,&```:!0"@X080H.$((*#C_O__ZP``4.-'```:`P``Z@4`H.$($*#C
+M_O__ZT(``.H@,9WE`3!#XCX`4^-```"*)"&=Y1\`4N,]``"*##&?Y0(Q@^`4
+M,)/E``!3XP(``!H!`*#C^!"?Y?[__^LD(9WEZ#"?Y0(Q@^`4,)/E``!3XR\`
+M``H$`*#A$CZ-XAPQC>7^___K``!0XR4```I*'XWB"`"@XQ!`(>7^___K'```
+MZO[__^L``%#C'0``"O[__^L(,)3E!A"@X00`H.$!.(/C"#"$Y?[__^L(,)3E
+M`3C#XP@PA.4`4*#A_O__ZPT``.H$`*#A_O__ZP``4.,,```*(#*4Y40PD^4`
+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
+M`*#A_O__ZP``4.,(`(3E)0``"@@`H.$'$*#A_O__ZP``4.,,`(3E'P``"@@`
+MH.$'$*#A_O__ZP``4.,0`(3E&0``"@``5N,48(0%!0``"@@`H.$'$*#A_O__
+MZP``4.,4`(3E$```"@(`5>,`,*#C*`"$Z%``G]4&``#:!`!5XT@`G]4#``#:
+M1#"?Y0@`5>-``)_E`P"@P000H.'^___K`%!0X@$``!H%``#J"U#@XP0`H.'^
+M___K'#"?Y04@H..T(,/E!0"@X?"!O>CP````"`$``"`!```X`0``+`$``/!`
+M+>D$,)#E'-!-X@!0H.$!8*#A@T"PX70``$H#`%3A<@``.A@0H.,-`*#A_O__
+MZQ0@E>4-`*#A!!"5Y0`@4N(!(*`3T#"@X_[__^L`<%#B9P``&@T@H.$($)7E
+M?SW"XP@`G>4_,,/C"#"3Y00@D>`#(-(P`#"@,P``4^,$```:!""@X?[__^L`
+M`%#C4P``&@$``.H``%3C-P``&@T@H.$,$)7E?SW"XPP`G>4_,,/C"#"3Y00@
+MD>`#(-(P`#"@,P``4^,$```:!""@X?[__^L``%#C00``&@$``.H``%3C)0``
+M&@T@H.$0$)7E?SW"XQ``G>4_,,/C"#"3Y00@D>`#(-(P`#"@,P``4^,$```:
+M!""@X?[__^L``%#C+P``&@$``.H``%3C$P``&A00E>4``%'C$P``"@T@H.$4
+M`)WE?SW"XS\PP^,(,)/E!""1X`,@TC``,*`S``!3XP0``!H$(*#A_O__ZP``
+M4.,;```:!```Z@``5.,"```*!!"@X?[__^L5``#J`#"5Y08`H.$`,(WE_O__
+MZP``4.,2<.`##P``"B`REN4<()/E``!2XP,``!H@,)/E``!3XQ5PX`,#```*
+M#0"@X080H.'^___K`'"@X0P`AN+^___K````Z@UPX.,-`*#A_O__ZP```.H&
+M<.#C!P"@X1S0C>+P@+WH(#"@X_[__^H``*#C'O\OX0``H.,>_R_A``"@XQ[_
+M+^$``*#C'O\OX0``H.,>_R_A2#"?Y0<@H.-P0"WI`%"@X0`@P^4L,I#E`0`3
+MXW"`O0@L0)_EP&"$X@00H.$H`I7E$$"$XO[__^L&`%3A^?__&BPRE>4!,,/C
+M+#*%Y7"`O>CH`0``#````'-`+>D#0*#A`F"@X?[__^L($(WB`#"@XP,@H.$$
+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
+M0%#B&```"@`PU.4``%/C%0``"G@0G^4&(*#C_O__ZP``4.,2```::#"?Y0$@
+MH..<((/E#```ZEPPG^4`0(/E"0``Z@,!D><#(:#A`3"#X@``4.,\,)\%`C"#
+M`*!`@P4!```*(`!3X_7__QH!`*#C$("]Z#H0H.,$`*#A_O__ZP``4.,`,*`3
+M$!"?%>S__QKH___JOP``````````````H```````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````(#`X/#X_/[_`````0,`````
+M```"````+`$``#`!```T`0`````````````$````.`$``$`!``!(`0``````
+M```````0````@`$``*`!``#``0`````````````(````4`$``&`!``!P`0``
+M``````````!&````@`(``)`!```IFP``*````!@````G````"0```&`````"
+M`````````````````````````#P```"``@``X`$``"F;```H````&````"``
+M```+````8`````(`````````````````````````.````"`#``!8`@``@6P`
+M`(`````8````%@````$```!(`````@````````````````````````!7````
+M``0````#``#_5@``.````!@````A````"````*`````(``````````$`````
+M`````````%4```"``@``D`$```)\``!@````(````"D````!````0`````,`
+M```"````````````````````2````(`"``#@`0```GP``)`````H````'@``
+M``@````H`````P````````````````````````!+````@`(``.`!```"?```
+M>````!`````0`````0```$`````#`````````````````````````#P````@
+M`P``6`(``*AA``!8````*````!<````!````@`````0````#````````````
+M````````50```(`"``#@`0``@6P``%`````X````&0````$````X`````P``
+M``````````````````````!9````@`0``&`#```8/```8````!````!N````
+M`0```-@````*``````````$``````````````$@````@`P``6`(``"!.``!`
+M````.````!<````E````>`````8````#````````````````````/``````$
+M`````P``&#P``*@````(````'0````,```"0````!@``````````````````
+M``````!D````@`(``.`!``!*50``8````"`````D````"````&`````&````
+M`````````````````````#P```"`!```8`,``',K``#0````0````!`````$
+M``````$```@`````````````````````````50```"`#``!8`@``3$```*``
+M``!`````)````!````!`````!0````````````````````````!&``````0`
+M```#```5-```D````!@````=`````P```(@````&````````````````````
+M`````%<`````!0````0``-0P```X````$````(`````!````V`````P`````
+M`````0``````````````9````"`#``!8`@``%3@``*````!`````'@````0`
+M``!`````!@````````````````````````!,``````0````#``#T+0``T```
+M``@````D````$````'@````#`````````````````````````$8```"`!```
+M8`,``'4J``!J````.````!0````!````H`````H`````````````````````
+M````/0`````%````!```@B,``,@````P````&@````$```"X`````P``````
+M```````````````````\````>`4``!H$```K)```B````"@````-`````0``
+M`'`````#`````````````````````````$L```!X!0``&@0``!8<``!X````
+M.````!<````*````<`````T````#````````````````````/````'@%```:
+M!```*R0``(`````H````#`````````!P`````P````,`````````````````
+M``!5``````0````#``!_)P``P````"`````B````#@```*`````&````````
+M`````````````````$X```"`!```8`,``((C``#D````6````"``````````
+M5`````P`````````````````````````1@`````%````!```X1X``.`````@
+M````'`````@```"@````"``````````````````````````\````0`8``+`$
+M```<&```,`$``$`````N`````0```,`````#`````P``````````````````
+M`%0```"`!```8`,``.\<``"X````.`$``"``````````@`````P`````````
+M````````````````2@`````%````!```[QP````!```@````(@````,```"0
+M`````P````````````````````````!D``````0````#``#2(0``P````"``
+M```5`````P```,`````*`````````````````````````$P`````!0````0`
+M`.\<``#X````(````"(````#````:`````,`````````````````````````
+M1@```$`&``"P!```JQ0``#`!``!`````+@````$```#``````P``````````
+M``````````````!D````@`0``&`#``!@'```X````"`````1`````@```(``
+M```3`````````````````````````%4`````!0````0``,T8``#@````0```
+M`"P````!````H`````,````#````````````````````2P```$`&``"P!```
+M2A,``#`!``!`````+@````$```#``````P````,````````````````````\
+M````D`8``!H$``#`&@``&`$``&@````>`````P```+`````&`````P``````
+M`````````````%4```!`!@``L`0``,$1```0`0``$````"4````$````P```
+M``,````#````````````````````9``````%````!```?A4````!```@````
+M&@````<```"`````#P````````````````````````!`````"`<``*`%``#[
+M$```,`$``&`````N`````0```,`````#`````P```````````````````$8`
+M```(!P``H`4``*`/```P`0``8````"X````!````P`````,````#````````
+M````````````3@`````"``"``0``P\$``#`````0````$`````$```!`````
+M`P````````````````````````!5``````(``(`!``".L0``,````!`````0
+M`````0```$`````#`````````````````````````$8```!``0``R````%`V
+M`0`0````$````!0````$````,`````$``````````@``````````````/```
+M`$`!``#P````4#8!`!`````0````$`````4````P`````0`````````"````
+M``````````!(````0`$``/`````$^```$````!`````0````!````#`````"
+M``````````(``````````````#@```"0`0``+`$```/9``!`````$`````H`
+M```!````(`````$``````````@``````````````/````)`!```L`0``4,,`
+M`#`````0````"P````$```!``````@`````````"``````````````!(````
+MD`$``"P!``!`G```(````!@````+````$P```$`````#``````````(`````
+M`````````#@```#@`0``+`$``&"T``!0````$`````H````!````*`````$`
+M`````````@``````````````/````.`!```L`0``@J,``#@````0````"P``
+M``$```!0`````@`````````"```````````````_````X`$``"P!``!`G```
+M.````!`````+`````0```%`````"``````````(``````````````$@```#@
+M`0``+`$``&J"```H````&`````L````3````4`````,``````````@``````
+M````````/````(`'``"P!```.10``(````!0`0```0```"8```#0`````P``
+M``,````````````````````\````@`0````#``#?-@``G@```!H````=````
+M`P```(@````&`````P```````````````````#P```!6!0````,``.XU``!X
+M````"@````X````#````(`````4`````````````````````````/``````%
+M```@`P``$"\``,@```!`````&`````$```"(`````P``````````````````
+M```````R````T`(``$`"``!:(0$`0````!`````G````!0```$`````%````
+M``````$``````````````#(````@`P``"`(``,?E``"0````0````$@````<
+M````4`````4``````````0``````````````/````&`#``#@`0``@6P```$`
+M```!`````0````$```````````````````````````````0%!@<'"`D*````
+M`*@#L8"H````L+"H@`````#8`````````!,!````````8P`````````S````
+M`````%8`````````KP```'9I9&5O/0```````'$```!F8B5D`"TM+2TM+2TM
+M+2TM+2TM+2TM+2TM+2TM+2TM+2TM+5)+,CDP-B!N;W0@<W5P;W)T('1H:7,@
+M<F5S;VQU=&EO;BTM+2TM+2TM+2TM+2TM+2TM+2TM+2TM"@`E9"`E<PH`9F(`
+M=6YA8FQE('1O(&=E="!M86IO<B`E9"!F;W(@9F(@9&5V<PH`9W)A<&AI8W,`
+M/#0^56YA8FQE('1O(&-R96%T92!F8B!C;&%S<SL@97)R;F\@/2`E;&0*`&]F
+M;VYL>0!O9F9B`&]F9@`\-SYC:&5C:VEN9R!G96YE<FEC("@E;&QX("5L;'@I
+M('9S(&AW("@E;&QX("5L;'@I"@`\-CYF8CH@8V]N9FQI8W1I;F<@9F(@:'<@
+M=7-A9V4@)7,@=G,@)7,@+2!R96UO=FEN9R!G96YE<FEC(&1R:79E<@H`/#,^
+M)7,Z(&5N86)L92!#3TY&24=?1D)?0DE'7T5.1$E!3B!T;R!S=7!P;W)T('1H
+M:7,@9G)A;65B=69F97(*`"9F8E]I;F9O+3YL;V-K`"9F8E]I;F9O+3YM;5]L
+M;V-K`#PT/E5N86)L92!T;R!C<F5A=&4@9&5V:6-E(&9O<B!F<F%M96)U9F9E
+M<B`E9#L@97)R;F\@/2`E;&0*`#PT/F1E=&5C=&5D(&9B7W-E=%]P87(@97)R
+M;W(L(&5R<F]R(&-O9&4Z("5D"@`E9`H`)7,*`"5D+"5D"@`E8SHE9'@E9"5C
+M+25D"@!B:71S7W!E<E]P:7AE;`!B;&%N:P!C;VYS;VQE`&-U<G-O<@!M;V1E
+M`&UO9&5S`'!A;@!V:7)T=6%L7W-I>F4`;F%M90!S=')I9&4`<F]T871E`'-T
+M871E`#PV/F9B8W9T.B!);G9A;&ED(&EN<'5T('!A<F%M971E<G,*`#PV/F9B
+M8W9T.B!2969R97-H(')A=&4@;F]T($-65"!S=&%N9&%R9`H`/#8^9F)C=G0Z
+M(#8P2'H@<F5F<F5S:"!R871E(&%D=FES960@9F]R(')E9'5C960@8FQA;FMI
+M;F<*`#PV/F9B8W9T.B!!<W!E8W0@<F%T:6\@;F]T($-65"!S=&%N9&%R9`H`
+M9F)C=G0Z("5D>"5D0"5D.B!#5E0@3F%M92`M(`!.;W0@82!#5E0@<W1A;F1A
+M<F0@+2`E9"XE,#-D($UE9V$@4&EX96P@26UA9V4*`"5D`"XE,#-D30`S`#0`
+M.0!!`"U2`#PV/B5S"@```````$L`````````@P`````````>``````````8!
+M````````\`````````#/````````````````````F@```&9B7V=E=%]O<'1I
+M;VYS`&9B7W-E=%]S=7-P96YD`&9B7V=E=%]B=69F97)?;V9F<V5T`&9B7W!A
+M;E]D:7-P;&%Y`&9B7V)L86YK`&9B7W-E=%]V87(`9F)?<VAO=U]L;V=O`')E
+M9VES=&5R961?9F(`;G5M7W)E9VES=&5R961?9F(`=6YR96=I<W1E<E]F<F%M
+M96)U9F9E<@!R96=I<W1E<E]F<F%M96)U9F9E<@!R96UO=F5?8V]N9FQI8W1I
+M;F=?9G)A;65B=69F97)S`&9B7V-L87-S`&9B7W!A9%]U;F%L:6=N961?8G5F
+M9F5R`&9B7W!A9%]A;&EG;F5D7V)U9F9E<@!L;V-K7V9B7VEN9F\`9F)?9V5T
+M7V-O;&]R7V1E<'1H`&9B7V1E<W1R;WE?;6]D961B`&9B7W9A;&ED871E7VUO
+M9&4`9F)?9V5T7VUO9&4`9F)?961I9%]A9&1?;6]N<W!E8W,`9F)?961I9%]T
+M;U]M;VYS<&5C<P!F8E]P87)S95]E9&ED`&9B7V9I<FUW87)E7V5D:60`9F)?
+M:6YV97)T7V-M87!S`&9B7V1E9F%U;'1?8VUA<`!F8E]S971?8VUA<`!F8E]C
+M;W!Y7V-M87``9F)?9&5A;&QO8U]C;6%P`&9B7V%L;&]C7V-M87``9G)A;65B
+M=69F97)?86QL;V,`9G)A;65B=69F97)?<F5L96%S90!F8E]F:6YD7VUO9&5?
+M8W9T`&9B7V9I;F1?;6]D90!F8E]V:61E;VUO9&5?=&]?;6]D96QI<W0`9F)?
+M9FEN9%]N96%R97-T7VUO9&4`9F)?9FEN9%]B97-T7VUO9&4`9F)?;6%T8VA?
+M;6]D90!F8E]A9&1?=FED96]M;V1E`&9B7VUO9&5?:7-?97%U86P`9F)?=F%R
+M7W1O7W9I9&5O;6]D90!F8E]V:61E;VUO9&5?=&]?=F%R`&9B7V9I;F1?8F5S
+M=%]D:7-P;&%Y`&9B7V1E<W1R;WE?;6]D96QI<W0`9F)?;6]D95]O<'1I;VX`
+M`````$(`````````#P````````",`0```````%4!````````.`$```````!^
+M`0```````$D!````````:@$````````F`0```````)T!````````U@$`````
+M``"]`0```````*T!````````R0$```````#F`0```````/0!````````!@(`
+M```````X`@```````(8"````````40(````````:`@```````/D"````````
+M>`(```````#E`@```````)<"````````*P(```````"H`@```````-`"````
+M````O`(```````!F`@``![$!@;"P7X0``````````+"PJ(`X````L+"P@)0`
+M``"PL*F`T````+"O!("<`0``L+"L@#@"``"PL+"`2`(``+"PJ8"(`@``L+"N
+M@*@#``"PL*B`Z`,``+"PJH`\!```L+"H@)@$``"PL+"`I`0``+"PJH#8!```
+ML+"L@!`&````````H`<``*D'L8#\!P``L*D$@&0(``"PL*B`$`H``*\'L8#H
+M"P``KPBQ@(P-``"PL+"`G`T``+"PJ(#8#0``KPBQ@,P.``"J`[&`M`\``+"P
+MJH#H#P``L*\.@(01``"PL*R`P!$``+"K$H#@$P``KS\4@'`6``"L/PF`>!P`
+M`+"PL("\'```L*\X@,P=``!?A!Z`E!X``+"PJH`P(```L*\4@`PG``"PL+"`
+M%"<``+"PL(`8)P``L+"P@!PG``"PL+"`("<``+"PL(`H)P``KPBQ@*0H``"P
+ML+"`K"@``+!?A(#,*0``L+"P@`PJ``"PL*Z`<"L``+"PK(!(+```L*\$@#0M
+M``"PL*B`>"T``+"PK(",+@``L*L&@(PP``"PL+"`E#```+"PL("<,```L+"P
+M@*0P``"PL+"`K#```+"PL("T,```L+"P@+PP``"PL*J`%#$``*H#L8!@,0``
+ML+"H@(PQ``"PL*B`N#$``+"PJ(#D,0``L+"H@`PR``"H`[&`0#(``*@#L8!T
+M,@``J@^Q@.`R``"PL*R`)#,``+"PJ(!8,P``L+"H@(0S``"PL*J`U#,``+"K
+M*(`P-```7X0J@,PT``"PJRB`*#4``%^$*H#4-0``K`.Q@*PV``"N/P&`:#<`
+M`*P#L8#8-P``L+"J@&PX``"PL*J`K#@``+"PJ(#(.```L+"J@'PY``"PL*J`
+M=#H``+"PL(#L.@``L+"P@*P[``"PL*R`0#P``+!?A(#H/```L*L.@$`]``!?
+MA"B`/#X``+"PK("4/@``L+"N@`0_``"PL*R`H#\``+"PK(#H/P``L*\:@-Q%
+M``"PKQJ``0````0````$````+@(``*0!`````````````#T"``"D`0``````
+M``````!#`@``I`$`````````````2P(``*0!`````````````%("``"D`0``
+M``````````!7`@``I`$`````````````70(``*0!`````````````&$"``"D
+M`0````````````!N`@``)`$`````````````<P(``"0!`````````````'H"
+M``"D`0````````````"!`@``I`$`````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```"!`@-$"!`(```````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````#!TL0"$`Y"0``JJH``*JJ``"JJ@``JJI55?__``"JJE55
+M__\``*JJ557__P``````````JJJJJJJJJJH`````JJJJJ@````!55:JJ``"J
+MJ@``JJH``*JJ``"JJ@``````````JJJJJJJJJJI5555555555?__________
+M`````*JJJJH`````556JJE55557_____55555?____\``*JJ``"JJ@``JJH`
+M`*JJ557__U55__]55?__557__P4$!@P0($!,!PD+*1\S1U<`````````````
+M````1T-#.B`H1TY5*2`T+C0N,```1T-#.B`H1TY5*2`T+C0N,```1T-#.B`H
+M1TY5*2`T+C0N,```1T-#.B`H1TY5*2`T+C0N,```1T-#.B`H1TY5*2`T+C0N
+M,```1T-#.B`H1TY5*2`T+C0N,`!!*@```&%E86)I``$@````!3<M00`&"@=!
+M"`$2!!0!%0$7`Q@!&0$:`AX$`"YS>6UT86(`+G-T<G1A8@`N<VAS=')T86(`
+M+G)E;"YT97AT`"YR96PN:6YI="YT97AT`"YR96PN<F]D871A`"Y!4DTN97AT
+M86(N:6YI="YT97AT`"YR96PN05)-+F5X:61X+FEN:70N=&5X=``N<F5L7U]?
+M:W-Y;71A8BMF8E]P861?=6YA;&EG;F5D7V)U9F9E<@`N<F5L7U]?:W-Y;71A
+M8BMF8E]G971?8V]L;W)?9&5P=&@`+G)E;%]?7VMS>6UT86(K<F5G:7-T97)E
+M9%]F8@`N<F5L7U]?:W-Y;71A8BMF8E]P86Y?9&ES<&QA>0`N<F5L7U]?:W-Y
+M;71A8BMF8E]S:&]W7VQO9V\`+G)E;%]?7VMS>6UT86(K<F5M;W9E7V-O;F9L
+M:6-T:6YG7V9R86UE8G5F9F5R<P`N:6YI="YR;V1A=&$`+G)E;%]?7VMS>6UT
+M86(K;G5M7W)E9VES=&5R961?9F(`+G)O9&%T82YS='(Q+C$`+G)E;%]?7VMS
+M>6UT86(K9F)?<V5T7W9A<@`N<F5L7U]?:W-Y;71A8BMU;G)E9VES=&5R7V9R
+M86UE8G5F9F5R`"YR96Q?7U]K<WEM=&%B*V9B7V=E=%]B=69F97)?;V9F<V5T
+M`"YR96Q?7U]K<WEM=&%B*VQO8VM?9F)?:6YF;P`N<F5L7U]?:W-Y;71A8BMF
+M8E]P861?86QI9VYE9%]B=69F97(`+G)E;%]?7VMS>6UT86(K9F)?8VQA<W,`
+M+G)E;%]?7VMS>6UT86(K9F)?9V5T7V]P=&EO;G,`+G)E;%]?7VMS>6UT86(K
+M<F5G:7-T97)?9G)A;65B=69F97(`7U]K<WEM=&%B7W-T<FEN9W,`+G)E;%]?
+M7VMS>6UT86(K9F)?8FQA;FL`+G)E;%]?7VMS>6UT86(K9F)?<V5T7W-U<W!E
+M;F0`+G)E;%]?7VMS>6UT86(K9F)?9FER;7=A<F5?961I9``N<F5L7U]?:W-Y
+M;71A8BMF8E]E9&ED7V%D9%]M;VYS<&5C<P`N<F5L7U]?:W-Y;71A8BMF8E]V
+M86QI9&%T95]M;V1E`"YR96Q?7U]K<WEM=&%B*V9B7W!A<G-E7V5D:60`+G)E
+M;%]?7VMS>6UT86(K9F)?9V5T7VUO9&4`+G)E;%]?7VMS>6UT86(K9F)?961I
+M9%]T;U]M;VYS<&5C<P`N<F5L7U]?:W-Y;71A8BMF8E]D97-T<F]Y7VUO9&5D
+M8@`N<F5L7U]?:W-Y;71A8BMF8E]I;G9E<G1?8VUA<',`+G)E;%]?7VMS>6UT
+M86(K9F)?9&5A;&QO8U]C;6%P`"YR96Q?7U]K<WEM=&%B*V9B7W-E=%]C;6%P
+M`"YR96Q?7U]K<WEM=&%B*V9B7V1E9F%U;'1?8VUA<``N<F5L7U]?:W-Y;71A
+M8BMF8E]C;W!Y7V-M87``+G)E;%]?7VMS>6UT86(K9F)?86QL;V-?8VUA<``N
+M<F5L7U]?:W-Y;71A8BMF<F%M96)U9F9E<E]A;&QO8P`N<F5L7U]?:W-Y;71A
+M8BMF<F%M96)U9F9E<E]R96QE87-E`"YR96Q?7U]K<WEM=&%B*V9B7W9I9&5O
+M;6]D95]T;U]M;V1E;&ES=``N<F5L7U]?:W-Y;71A8BMF8E]A9&1?=FED96]M
+M;V1E`"YR96Q?7U]K<WEM=&%B*V9B7V9I;F1?;F5A<F5S=%]M;V1E`"YR96Q?
+M7U]K<WEM=&%B*V9B7V9I;F1?;6]D95]C=G0`+G)E;%]?7VMS>6UT86)?9W!L
+M*V9B7VUO9&5?;W!T:6]N`"YR96Q?7U]K<WEM=&%B*V9B7VUA=&-H7VUO9&4`
+M+G)E;%]?7VMS>6UT86)?9W!L*V9B7V1E<W1R;WE?;6]D96QI<W0`+G)E;%]?
+M7VMS>6UT86(K9F)?;6]D95]I<U]E<75A;``N<F5L7U]?:W-Y;71A8BMF8E]F
+M:6YD7VUO9&4`+G)E;%]?7VMS>6UT86(K9F)?=F%R7W1O7W9I9&5O;6]D90`N
+M<F5L7U]?:W-Y;71A8BMF8E]F:6YD7V)E<W1?9&ES<&QA>0`N<F5L7U]?:W-Y
+M;71A8BMF8E]V:61E;VUO9&5?=&]?=F%R`"YR96Q?7U]K<WEM=&%B*V9B7V9I
+M;F1?8F5S=%]M;V1E`"Y!4DTN97AT86(`+G)E;"Y!4DTN97AI9'@`+G)E;"YD
+M871A`"YR96PN:6YI=&-A;&PT+FEN:70`+F1A=&$N+G)E861?;6]S=&QY`"YR
+M96PN:6YI="YS971U<``N8G-S`"YC;VUM96YT`"Y!4DTN871T<FEB=71E<P`N
+M;F]T92Y'3E4M<W1A8VL`````````````````````````````````````````
+M```````````````?`````0````8`````````-````*1,``````````````0`
+M````````&P````D``````````````+B$``#(#```=@````$````$````"```
+M`$H````!````!@````````#83```4`$`````````````!``````````E````
+M"0``````````````@)$``)````!V`````P````0````(````.`````$````"
+M`````````"A.``!X#@`````````````$`````````#0````)````````````
+M```0D@``V````'8````%````!`````@```!``````0````(`````````H%P`
+M``````````````````$`````````60````$``'""`````````*!<```0````
+M`P`````````$`````````%4````)``````````````#HD@``&````'8````(
+M````!`````@```!R`````0````(`````````L%P```@```````````````0`
+M````````;@````D```````````````"3```0````=@````H````$````"```
+M`)D````!`````@````````"X7```"```````````````!`````````"5````
+M"0``````````````$),``!````!V````#`````0````(````NP````$````"
+M`````````,!<```(```````````````$`````````+<````)````````````
+M```@DP``$````'8````.````!`````@```#8`````0````(`````````R%P`
+M``@```````````````0`````````U`````D``````````````#"3```0````
+M=@```!`````$````"````/8````!`````@````````#07```"```````````
+M````!`````````#R````"0``````````````0),``!````!V````$@````0`
+M```(````$@$```$````"`````````-A<```(```````````````$````````
+M``X!```)``````````````!0DP``$````'8````4````!`````@````]`0``
+M`0````(`````````X%P```<```````````````$`````````3@$```$````"
+M`````````.A<```(```````````````$`````````$H!```)````````````
+M``!@DP``$````'8````7````!`````@```!K`0```0```#(`````````\%P`
+M`)\#``````````````$````!````?@$```$````"`````````)!@```(````
+M```````````$`````````'H!```)``````````````!PDP``$````'8````:
+M````!`````@```"8`0```0````(`````````F&````@```````````````0`
+M````````E`$```D``````````````("3```0````=@```!P````$````"```
+M`+X!```!`````@````````"@8```"```````````````!`````````"Z`0``
+M"0``````````````D),``!````!V````'@````0````(````X@$```$````"
+M`````````*A@```(```````````````$`````````-X!```)````````````
+M``"@DP``$````'8````@````!`````@```#^`0```0````(`````````L&``
+M``@```````````````0`````````^@$```D``````````````+"3```0````
+M=@```"(````$````"````","```!`````@````````"X8```"```````````
+M````!``````````?`@``"0``````````````P),``!````!V````)`````0`
+M```(````.P(```$````"`````````,!@```(```````````````$````````
+M`#<"```)``````````````#0DP``$````'8````F````!`````@```!9`@``
+M`0````(`````````R&````@```````````````0`````````50(```D`````
+M`````````."3```0````=@```"@````$````"````'D"```!`````@``````
+M``#08```"`,``````````````0````````"/`@```0````(`````````V&,`
+M``@```````````````0`````````BP(```D``````````````/"3```0````
+M=@```"L````$````"````*<"```!`````@````````#@8P``"```````````
+M````!`````````"C`@``"0```````````````)0``!````!V````+0````0`
+M```(````Q0(```$````"`````````.AC```(```````````````$````````
+M`,$"```)```````````````0E```$````'8````O````!`````@```#E`@``
+M`0````(`````````\&,```@```````````````0`````````X0(```D`````
+M`````````""4```0````=@```#$````$````"`````D#```!`````@``````
+M``#X8P``"```````````````!``````````%`P``"0``````````````,)0`
+M`!````!V````,P````0````(````*0,```$````"``````````!D```(````
+M```````````$`````````"4#```)``````````````!`E```$````'8````U
+M````!`````@```!&`P```0````(`````````"&0```@```````````````0`
+M````````0@,```D``````````````%"4```0````=@```#<````$````"```
+M`&$#```!`````@`````````09```"```````````````!`````````!=`P``
+M"0``````````````8)0``!````!V````.0````0````(````A`,```$````"
+M`````````!AD```(```````````````$`````````(`#```)````````````
+M``!PE```$````'8````[````!`````@```"E`P```0````(`````````(&0`
+M``@```````````````0`````````H0,```D``````````````("4```0````
+M=@```#T````$````"````,0#```!`````@`````````H9```"```````````
+M````!`````````#``P``"0``````````````D)0``!````!V````/P````0`
+M```(````XP,```$````"`````````#!D```(```````````````$````````
+M`-\#```)``````````````"@E```$````'8```!!````!`````@```#^`P``
+M`0````(`````````.&0```@```````````````0`````````^@,```D`````
+M`````````+"4```0````=@```$,````$````"````!T$```!`````@``````
+M``!`9```"```````````````!``````````9!```"0``````````````P)0`
+M`!````!V````10````0````(````.00```$````"`````````$AD```(````
+M```````````$`````````#4$```)``````````````#0E```$````'8```!'
+M````!`````@```!6!````0````(`````````4&0```@```````````````0`
+M````````4@0```D``````````````."4```0````=@```$D````$````"```
+M`'<$```!`````@````````!89```"```````````````!`````````!S!```
+M"0``````````````\)0``!````!V````2P````0````(````F@0```$````"
+M`````````&!D```(```````````````$`````````)8$```)````````````
+M````E0``$````'8```!-````!`````@```#"!````0````(`````````:&0`
+M``@```````````````0`````````O@0```D``````````````!"5```0````
+M=@```$\````$````"````.($```!`````@````````!P9```"```````````
+M````!`````````#>!```"0``````````````()4``!````!V````40````0`
+M```(````!@4```$````"`````````'AD```(```````````````$````````
+M``(%```)```````````````PE0``$````'8```!3````!`````@````F!0``
+M`0````(`````````@&0```@```````````````0`````````(@4```D`````
+M`````````$"5```0````=@```%4````$````"````$@%```!`````@``````
+M``"(9```"```````````````!`````````!$!0``"0``````````````4)4`
+M`!````!V````5P````0````(````904```$````"`````````)!D```(````
+M```````````$`````````&$%```)``````````````!@E0``$````'8```!9
+M````!`````@```",!0```0````(`````````F&0```@```````````````0`
+M````````B`4```D``````````````'"5```0````=@```%L````$````"```
+M`*P%```!`````@````````"@9```"```````````````!`````````"H!0``
+M"0``````````````@)4``!````!V````70````0````(````R`4```$````"
+M`````````*AD```(```````````````$`````````,0%```)````````````
+M``"0E0``$````'8```!?````!`````@```#K!0```0````(`````````L&0`
+M``@```````````````0`````````YP4```D``````````````*"5```0````
+M=@```&$````$````"`````\&```!`````@````````"X9```"```````````
+M````!``````````+!@``"0``````````````L)4``!````!V````8P````0`
+M```(````,@8```$````"`````````,!D```(```````````````$````````
+M`"X&```)``````````````#`E0``$````'8```!E````!`````@```!/!@``
+M`0````(`````````R&0```P```````````````0`````````7@8```$``'""
+M`````````-1D``#H`@```0`````````$`````````%H&```)````````````
+M``#0E0``*`,``'8```!H````!`````@```!M!@```0````,`````````O&<`
+M`,P```````````````0`````````:08```D``````````````/B8```@`0``
+M=@```&H````$````"````'<&```!`````P````````"(:```!```````````
+M````!`````````!S!@``"0``````````````&)H```@```!V````;`````0`
+M```(````AP8```$````#`````````(QH``#P`0`````````````$````````
+M`)X&```!`````P````````!\:@``#```````````````!`````````":!@``
+M"0``````````````()H``!````!V````;P````0````(````J@8```@````#
+M`````````(AJ```0```````````````$`````````*\&```!````````````
+M``"(:@``;````````````````0````````"X!@```P``<```````````]&H`
+M`"L```````````````$`````````R`8```$``````````````!]K````````
+M```````````!`````````!$````#```````````````?:P``V`8`````````
+M`````0`````````!`````@``````````````,)H````B``!W````MP$```0`
+M```0````"0````,``````````````#"\``#<$P`````````````!````````
+M`$0"```".@``P`(``!P+`@#D`@``'`L"`!@#```<"P(`M`,``!SI`0#D`P``
+M`C@``/@#```<Z0$`(`0``!S@`0`H!```'`,"`%0$```<Z0$`A`0``!P#`@"0
+M!````C@``)0$```".@``G`0``!T#`@"@!````C@``+0$```<Z0$`S`0``!P#
+M`@`(!0``'!\"`#0%```<Z0$`I`4``!SE`0#H!0``'.`!`/`%```<`P(`#`8`
+M``(.``!P!@``'.D!`-P&```<`P(`$`<``!P#`@!,!P``',8!`'`'```<S@$`
+MF`<```(Z``"L!P``',L!`-`'```<_@$`[`<``!S^`0#T!P``'`,"`%0(```<
+M_@$`[`D``!SV`0#T"0``'/`!``0*```".@``#`H```(.``#D"@``'!T"`&`+
+M```<'`(`@`L``!SV`0"D"P``',T!`-`+```<SP$`Y`L```(Z``"H#```'!T"
+M`/P,```<S0$`*`T``!P:`@!T#0``',\!`(@-```".@``E`T``!T4`@"8#0``
+M`@,``,0-```<"`(`T`T```(Z``#4#0```@X``.0-```<&`(`#`X``!SK`0!L
+M#@``'.L!`*0.```<ZP$`O`X```(Z``#`#@```@X``,0.```".@``R`X```(.
+M``#P#@``',L!`!`/```<_@$`'`\``!P#`@!`#P``',\!`$P/```<#P(`;`\`
+M`!R_`0!\#P``'`<"`)`/```<_@$`K`\```(Z``"P#P```CP``,0/```<Z0$`
+MV`\``!P#`@#D#P```C@``(00```<\`$`1!$``!SP`0!X$0```CH``'P1```"
+M#@``@!$```(.``"<$0``'.D!`+@1```=`P(`O!$```(X``#0$0``'.D!`.P1
+M```<\`$`6!(``!SQ`0!H$@``'/$!`(@2```<Y@$`I!(``!SP`0"X$@``'`T"
+M`-02```<WP$`7!,``!SH`0!H$P``'`X"`(`3```<RP$`F!,``!S^`0"@$P``
+M'`,"`*P3```<`P(`O!,```(X``#`$P```@X``,03```".@``R!,```(\``#,
+M$P```@X``-`3```"#@``U!,```(.``#8$P```@X``-P3```"$`(`#!0``!SH
+M`0`8%```'.@!`"04```<YP$`0!0``!S^`0!4%```'`0"`&P4```<[@$`E!0`
+M`!S-`0#<%```'/8!`.@4```<]@$`!!4``!S^`0!@%0``',T!`'`5```<S0$`
+MI!4``!S-`0"P%0``'/`!`,@5```<$@(`U!4``!S,`0#@%0``'.@!``P6```<
+M#@(`3!8``!S^`0!L%@```@X``!07```<RP$`,!<``!S-`0`X%P``'-0!`$`7
+M```<`P(`K!<``!P<`@"\%P``',L!`,@7```<Z@$`X!<``!S3`0#T%P``'/D!
+M`/P7```<`P(`+!@``!S+`0!(&```',T!`%`8```<`P(`O!@``!P<`@#0&```
+M'-X!``P9```<'`(`+!D``!S+`0!4&0``'`,"`&`9```<$P(`H!D``!P<`@#`
+M&0``',L!`,P9```<Z@$`V!D``!P2`@#@&0``'/D!`.@9```<`P(`&!H``!P:
+M`@!<&@``'!P"`(@:```<RP$`H!H``!S^`0"H&@``'`,"`-P:```<&@(`(!L`
+M`!P<`@`X&P``'/8!`'@;```<'P(`H!L``!S+`0"X&P``'/X!`,`;```<RP$`
+MS!L``!SJ`0#D&P``'+H!`/@;```<^0$`!!P``!S+`0`\'```'`,"`'`<```"
+M.@``=!P```(.``"X'````CH``-P<```<S0$`\!P``!RX`0`$'0``'-,!`!0=
+M```<Z`$`*!T``!SG`0!8'0``',\!`(P=```<RP$`J!T``!S^`0"T'0``'`,"
+M`'@>```<S`$`_!X``!SV`0!<'P``',`!`"@@```".@``N"```!S?`0`T(@``
+M'!T"`$0B```<SP$`)"0``!P=`@#$)@``',\!`-0F```<SP$`W"8``!S/`0``
+M)P```CH```0G```"$`(`""<```(#``"\)P``'/@!`!0H```<^`$`("@``!SX
+M`0`T*```'/@!`)PH```".@``P"D```(Z``#$*0```CH``,@I```".@``_"D`
+M``(#````*@```@,```0J```"`P``""H```(#``"<*@``'!H"`-0J```<&@(`
+M#"L``!P:`@!4*P``'!H"`-PK```<S0$`]"L``!S-`0`,+```',T!`#0L```<
+MS0$`'"T``!S_`0!`+0``',\!`$@M```<SP$`4"T``!S/`0!8+0``',\!`)@M
+M```<X0$`L"T``!P=`@#(+0``'!T"`.`M```<'0(`!"X``!P=`@!(+@``'/\!
+M`&`N```<X0$`>"X```(#``!\+@```@,``(`N```"`P``A"X```(#``"(+@``
+M`CH``+@N```<]@$`U"X``!S7`0`0+P``'!P"`%@O```<'`(`H"\``!P<`@#P
+M+P``'!P"``PP```<]@$`(#```!S+`0!8,```',P!`&0P```<`P(`=#```!SA
+M`0"0,```'=<!`/`P```<'@(`##$```(Z```0,0```C@``"`Q```<O0$`/#$`
+M`!P,`@!$,0``'.H!`%`Q```<^P$`5#$``!SY`0!H,0``'+T!`(0Q```=PP$`
+MB#$```(.``"4,0``'+T!`+`Q```=PP$`M#$```(.``#`,0``'+T!`-PQ```=
+MPP$`X#$```(.``#L,0``'+T!``0R```=PP$`"#(```(.```4,@``'+T!`#0R
+M```<PP$`/#(```(.``!(,@``'+T!`&@R```<PP$`<#(```(.``#0,@``',,!
+M`-PR```"#@``Z#(``!R]`0`L,P``'+T!`&`S```<O0$`?#,``!W#`0"`,P``
+M`@X``)PS```<Z@$`M#,``!S3`0#(,P``'/D!`.0S```<O0$`_#,``!S-`0`,
+M-```'`P"`$`T```<O0$`9#0``!S-`0!T-```'`P"`*@T```<#`(`W#0``!R]
+M`0#T-```',T!``0U```<#`(`.#4``!R]`0!<-0``',T!`&PU```<#`(`H#4`
+M`!P,`@"H-0``'.H!`+0U```<$@(`O#4``!SY`0#@-0``'+T!`/`U```<^`$`
+M&#8``!SJ`0!4-@``'-L!`%PV```<_`$`;#8``!P/`@"<-@``'`\"`*`V```<
+M^0$`O#8``!R]`0#4-@``'/8!`/@V```<ZP$`%#<``!S-`0`@-P``'+@!`'0W
+M```<O0$`B#<``!SJ`0"D-P``'`P"`+`W```<N@$`Q#<``!SY`0#P-P``'!8"
+M``@X```<X@$`/#@``!P>`@!H.````C@``(PX```<'0(`N#@``!S/`0#$.```
+M'<\!``0Z```<^`$`7#H``!SX`0!D.@``'/@!```]```<Z`$`##T``!SG`0#0
+M/0``'/8!`.@]```<XP$`_#T``!SC`0`,/@``'-4!`'`^```<SP$`M#X``!SG
+M`0#</@``',\!`!@_```<YP$`2#\``!S?`0"</P```A`"`,`_```<#@(`7$``
+M`!P8`@`D00``',<!`&Q!```<QP$`L$$``!S'`0!,0@``',<!`(1"```<]@$`
+MS$(``!SZ`0"80P``'.L!`*A#```<&`(`U$4```(#``#810```CP``/A%```<
+M]@$`<$8``!SP`0"<1@``'/`!`.A&```<\`$`$$<``!SX`0`D1P``'/@!`#!'
+M```<^`$`3$<``!SX`0!@1P``'`L"`'A'```<^`$`C$<``!P+`@"D1P``'/@!
+M`+A'```<"P(`]$<``!SX`0`(2```'`L"`"!(```<\`$`2$@``!SX`0!P2```
+M'/@!`)A(```<^`$`L$@``!SX`0#<2```'/@!``!)```<^`$`%$D``!SX`0!4
+M20``'/@!`(!)```<^`$`K$D``!SX`0#820``'/@!`.!)```<^`$`^$D``!SX
+M`0`P2@``'/@!`%!*```<WP$`;$H``!SX`0!\2@``'/@!`(Q*```<"P(`F$H`
+M`!SX`0"X2@``',,!`.1*```<PP$`!$L``!S#`0`@2P``',,!`(Q+```<PP$`
+MK$L``!S#`0"X2P``'/`!`,!+```<SP$`U$L``!SX`0#@2P``'/@!`$Q,```"
+M#@``4$P```(.``!43````@X``%A,```"#@``8$P```(#``!X3````A`"`'Q,
+M```"#@``@$P```(.``"$3````@X``(A,```"#@``C$P```(.``"03````@X`
+M`)1,```"#@``F$P```(.``"<3````@X``*!,```"#@``'````!S1`0`X````
+M'`8"`$P````<\`$`8````!R^`0!X````'/`!`(P````"`P``D`````(.``"4
+M`````@,``)@````"#@``G`````(\``"@`````@X``*0````"#@``R````!SK
+M`0`H`0``'!L"`$`!```"#@``1`$```(Z``!(`0```NP!`$P!```".@``````
+M``),```$`````E0```@````"20``#`````)K```4`````M`!`!@````"`0(`
+M/`````)H``!$`````L(!`'P````"]`$`@`````)E``"$`````F(``)@````"
+MAP``H`````);``"D`````E@``*P````"3P``^`````(Z``#\`````CH````!
+M```".@``$`$```(Z```4`0```CH``!@!```".@``*`$```(Z```L`0```CH`
+M`#`!```".@``0`$```(Z``!$`0```CH``$@!```".@```````"H"````````
+M`,@!``@````J`@````````+)`0`$`````A<````````"`@(`!`````(7````
+M`````MD!``0````"%P````````(2`@`$`````A<````````"Q`$`!`````(7
+M`````````O4!``0````"%P````````*[`0`$`````A<````````"TP$`!```
+M``(7`````````K<!``0````"%P````````(5`@`$`````A<````````"RP$`
+M!`````(7`````````LH!``0````"%P````````*Y`0`$`````A<````````"
+M\P$`!`````(7`````````NT!``0````"%P````````*Z`0`$`````A<`````
+M```"^P$`!`````(7`````````@`"``0````"%P````````+]`0`$`````A<`
+M```````"O`$`!`````(7`````````@H"``0````"%P````````+:`0`$````
+M`A<````````"V`$`!`````(7`````````M8!``0````"%P````````+%`0`$
+M`````A<````````"X0$`!`````(7`````````LP!``0````"%P````````+R
+M`0`$`````A<````````"_P$`!`````(7`````````N\!``0````"%P``````
+M``+2`0`$`````A<````````"%P(`!`````(7`````````ML!``0````"%P``
+M``````(.`@`$`````A<````````"W0$`!`````(7`````````OH!``0````"
+M%P````````+L`0`$`````A<````````"P0$`!`````(7`````````@\"``0`
+M```"%P````````+G`0`$`````A<````````"W`$`!`````(7`````````N@!
+M``0````"%P````````(1`@`$`````A<````````"N`$`!`````(7````````
+M`M4!``0````"%P```````"H!`````````,@!``@````J`0``$````"H!```8
+M````*@$``"`````J`0``*````"H!```P````*@$``#@````J`0``0````"H!
+M``!(````*@$``%`````J`0``6````"H!``!@````*@$``&@````J`0``<```
+M`"H!``!P`````!D"`'0````J-@``>````"H!``"`````*@$``(@````J`0``
+MD````"H!``"8````*@$``*`````J`0``J````"H!``"P````*@$``+@````J
+M`0``P````"H!``#(````*@$``-`````J`0``V````"H!``#@````*@$``.@`
+M```J`0``\````"H!``#X````*@$````!```J`0``"`$``"H!```0`0``*@$`
+M`!@!```J`0``&`$```#(`0`@`0``*@$``"@!```J`0``,`$``"H!```X`0``
+M*@$``$`!```J`0``2`$``"H!``!0`0``*@$``%`!````R`$`6`$``"H!``!@
+M`0``*@$``&@!```J`0``<`$``"H!``!X`0``*@$``(`!```J`0``B`$``"H!
+M``"0`0``*@$``)@!```J`0``F`$```#(`0"@`0``*@$``*@!```J`0``L`$`
+M`"H!``"X`0``*@$``,`!```J`0``R`$``"H!``#0`0``*@$``-@!```J`0``
+MX`$``"H!``#H`0``*@$``/`!```J`0``^`$``"H!`````@``*@$```@"```J
+M`0``$`(``"H!```8`@``*@$``"`"```J`0``*`(``"H!```P`@``*@$``#@"
+M```J`0``0`(``"H!``!(`@``*@$``%`"```J`0``6`(``"H!``!@`@``*@$`
+M`&@"```J`0``<`(``"H!``!X`@``*@$``'@"````R`$`@`(``"H!``"(`@``
+M*@$``)`"```J`0``F`(``"H!``"@`@``*@$``*@"```J`0``L`(``"H!``"X
+M`@``*@$``,`"```J`0``R`(``"H!``#0`@``*@$``-@"```J`0``X`(``"H!
+M``#@`@```,@!``0````".```"`````(X```,`````@X``!0````"5`$`&```
+M``)=`0`<`````@X``"0````"+P$`*`````)E`0`L`````@X``#0````",P$`
+M.`````(M`0`\`````@X``$0````"-0$`2`````(Q`0!,`````@X``%0````"
+M4@$`6`````)C`0!<`````@X``&0````"4`$`:`````)A`0!L`````@X``'0`
+M```"2@$`>`````)?`0!\`````@X``(0````"1P$`B`````);`0",`````@X`
+M`)0````"1`$`G`````(.``"D`````D$!`*P````"#@``M`````(^`0"X````
+M`ED!`+P````"#@``Q`````([`0#(`````CD!```````";@````````(,```$
+M`````G$````````````````````````````````````````#``$`````````
+M`````````P`#``````````````````,`!0`````````````````#``<`````
+M`````````````P`(``````````````````,`"@`````````````````#``P`
+M`````````````````P`.``````````````````,`$``````````````````#
+M`!(``````````````````P`4``````````````````,`%@``````````````
+M```#`!<``````````````````P`9``````````````````,`&@``````````
+M```````#`!P``````````````````P`>``````````````````,`(```````
+M```````````#`"(``````````````````P`D``````````````````,`)@``
+M```````````````#`"@``````````````````P`J``````````````````,`
+M*P`````````````````#`"T``````````````````P`O````````````````
+M``,`,0`````````````````#`#,``````````````````P`U````````````
+M``````,`-P`````````````````#`#D``````````````````P`[````````
+M``````````,`/0`````````````````#`#\``````````````````P!!````
+M``````````````,`0P`````````````````#`$4``````````````````P!'
+M``````````````````,`20`````````````````#`$L`````````````````
+M`P!-``````````````````,`3P`````````````````#`%$`````````````
+M`````P!3``````````````````,`50`````````````````#`%<`````````
+M`````````P!9``````````````````,`6P`````````````````#`%T`````
+M`````````````P!?``````````````````,`80`````````````````#`&,`
+M`````````````````P!E``````````````````,`9P`````````````````#
+M`&@``````````````````P!J``````````````````,`;```````````````
+M```#`&X``````````````````P!O``````````````````,`<0``````````
+M```````#`'(``````````````````P!S``````````````````,`=``!````
+M```````````$`/'_"0`````````X`````@`!`!4``````````````````0`5
+M````.`````````````$`%0```)0````````````!`!4```#0````````````
+M`0`5````G`$```````````$`%0```#@"```````````!`!@```!$`@``````
+M`````0`;````2`(``$`````"``$`%0```$@"```````````!`!4```"(`@``
+M`````````0`G````J`,``$`````"``$`%0```*@#```````````!`!@```#D
+M`P```````````0`T````Z`,``%0````"``$`%0```.@#```````````!`#\`
+M```\!```7`````(``0`5````/`0```````````$`&````)`$```````````!
+M`$L```"8!```#`````(``0`5````F`0```````````$`&````*`$````````
+M```!`!4```"D!````````````0!7````V`0``#@!```"``$`%0```-@$````
+M```````!`!@````,!@```````````0!?````$`8``)`!```"``$`%0```!`&
+M```````````!`!@```"8!P```````````0`5````H`<```````````$`%0``
+M`/P'```````````!`!4```!D"````````````0`8``````H```````````$`
+M9P```!`*``#8`0```@`!`!4````0"@```````````0`8````Y`L`````````
+M``$`<````.@+``"D`0```@`!`!4```#H"P```````````0`8````B`T`````
+M``````$`>````(P-```0`````@`!`!4```",#0```````````0`8````F`T`
+M``````````$`A0```)P-```\`````@`!`!4```"<#0```````````0`8````
+MT`T```````````$`D0````````"H`````@`#`!4``````````````````P`8
+M````C`````````````,`G````*@```"H`````@`#`!4```"H````````````
+M`P`8````0`$```````````,`%0```-@-```````````!`!@```"\#@``````
+M`````0"H````S`X``.@````"``$`%0```,P.```````````!`!@```"L#P``
+M`````````0`5````M`\```````````$`&````.0/```````````!`,(```#H
+M#P``G`$```(``0`5````Z`\```````````$`&````'@1```````````!`!4`
+M``"$$0```````````0`8````O!$```````````$`%0```,`1```````````!
+M`!@```"\$P```````````0`5````X!,```````````$`&````&P6````````
+M```!`.4```!P%@``"`8```(``0`5````<!8```````````$`&````&P<````
+M```````!`/$```!X'```1`````(``0`5````>!P```````````$`&````+@<
+M```````````!`!4```"\'````````````0`8````Q!T```````````$`^@``
+M`,P=``#(`````@`!`!4```#,'0```````````0`5````E!X```````````$`
+M&````"@@```````````!`!4````P(````````````0`8`````"<`````````
+M``$`"@$````````0`````0`%`!@`````````````````!0`:`0``$````&@`
+M```!``4`)P$``'@```!H`````0`%`"\!``#@````"0````$`!0`Z`0``[```
+M``(````!``4`10$````````,`````0!J`!@`````````````````:@!7`0``
+M``````@````!``H`&``````````````````*`'D!``#8````&`````$`*@";
+M`0````````@````!``P`&``````````````````,`+@!```3`0``$P````$`
+M*@#5`0````````@````!``X`&``````````````````.`.T!``!C````#@``
+M``$`*@`%`@````````@````!`!``&``````````````````0`!X"```S````
+M#P````$`*@`W`@````````@````!`!(`&``````````````````2`$X"``!6
+M````#0````$`*@!E`@`````````````!`'$`<0(```0``````````0!Q`'T"
+M```$``````````$`<0")`@````````@````!`!0`&``````````````````4
+M`+,"``"O````(`````$`*@#=`@````````<````!`!8`]0(````````(````
+M`0`7`!@`````````````````%P`1`P``<0```!(````!`"H`+0,````````$
+M`````0!L`!@`````````````````;`!$`P````````@````!`!H`&```````
+M```````````:`%D#``!+````"P````$`*@!N`P```````!0````!`&X`=@,`
+M`)0````(`````0!N`!@```"4````````````;@!Z`P``G`````0````!`&X`
+M@0,``*````"``````0!N`(\#````````"`````$`'``8````````````````
+M`!P`L`,``(,````7`````0`J`-$#````````"`````$`'@`8````````````
+M`````!X`\`,``!X````5`````0`J``\$````````"`````$`(``8````````
+M`````````"``)@0```8!```-`````0`J`#T$````````"`````$`(@`8````
+M`````````````"(`700``/`````6`````0`J`'T$````````"`````$`)``8
+M`````````````````"0`D`0``,\````)`````0`J`*,$````````"`````$`
+M)@`8`````````````````"8`O`0````````/`````0`J`-4$````````"```
+M``$`*``8`````````````````"@`]`0``)H````5`````0`J`!,%```/````
+M#P````$`*@`L!0``0@````D````!`"H`/P4````````(`````0`K`!@`````
+M````````````*P!2!0````````P````!`&\`&`````````````````!O`&8%
+M````````"`````$`+0`8`````````````````"T`?P4`````````````!`#Q
+M_Q4````,)P```````````0`5````%"<```````````$`%0```!@G````````
+M```!`!4````<)P```````````0`5````("<```````````$`%0```"@G````
+M```````!`!@```"8*````````````0`5````I"@```````````$`AP4`````
+M```(`````0`O`!@`````````````````+P"B!0``C`$``!$````!`"H`O04`
+M```````(`````0`Q`!@`````````````````,0#<!0``50$``!4````!`"H`
+M^P4````````(`````0`S`!@`````````````````,P`6!@``.`$``!$````!
+M`"H`,08````````(`````0`U`!@`````````````````-0!)!@``?@$```X`
+M```!`"H`808``"8!```2`````0`J`'T&``!)`0``#`````$`*@"3!@``:@$`
+M`!0````!`"H`L08````````(`````0`W`!@`````````````````-P#'!@``
+M``````@````!`#D`&``````````````````Y`.4&````````"`````$`.P`8
+M`````````````````#L``0<``"0!```(`````0!N`!@````D`0``````````
+M;@`%!P`````````````$`/'_%0```*PH```````````!`!@```#`*0``````
+M`````0`5````S"D```````````$`&````/PI```````````!`!4````,*@``
+M`````````0`5````<"L```````````$`%0```$@L```````````!`!4````T
+M+0```````````0`5````>"T```````````$`&````'@N```````````!`!4`
+M``",+@```````````0`5````C#````````````$`#@<``/`````8`````0`%
+M`!@```#T````````````!0`?!P``+`$```0````!`&X`)`<``#`!```$````
+M`0!N`"L'```T`0``!`````$`;@`Q!P``"`$``!@````!``4`0@<``#@!```(
+M`````0!N`$<'``!``0``"`````$`;@!.!P``2`$```@````!`&X`5`<``"`!
+M```8`````0`%`&8'``"``0``(`````$`;@!L!P``H`$``"`````!`&X`=`<`
+M`,`!```@`````0!N`'L'```X`0``&`````$`!0",!P``4`$``!`````!`&X`
+MD0<``&`!```0`````0!N`)@'``!P`0``$`````$`;@">!P````````@````!
+M`#T`&``````````````````]`+@'``"=`0``$`````$`*@#2!P``K0$``!``
+M```!`"H`[`<``+T!```,`````0`J``((``#)`0``#0````$`*@`9"```U@$`
+M`!`````!`"H`,P@``.8!```.`````0`J`$L(````````"`````$`/P`8````
+M`````````````#\`90@````````(`````0!!`!@`````````````````00![
+M"`````````@````!`$,`&`````````````````!#`)4(````````"`````$`
+M10`8`````````````````$4`K`@````````(`````0!'`!@`````````````
+M````1P`8````+`$``````````&X`Q`@``.`!```(`````0!N`,@(````````
+M``````0`\?_2"```E#````@````"``$`%0```)0P```````````!`.`(``"<
+M,```"`````(``0`5````G#````````````$`ZP@``*0P```(`````@`!`!4`
+M``"D,````````````0#X"```K#````@````"``$`%0```*PP```````````!
+M``4)``"T,```"`````(``0`5````M#````````````$`%0```+PP````````
+M```!`!@````,,0```````````0`1"0``%#$``$P````"``$`%0```!0Q````
+M```````!`!\)``!@,0``+`````(``0`5````8#$```````````$`&````(@Q
+M```````````!`"P)``",,0``+`````(``0`5````C#$```````````$`&```
+M`+0Q```````````!`#@)``"X,0``+`````(``0`5````N#$```````````$`
+M&````.`Q```````````!`$0)``#D,0``*`````(``0`5````Y#$`````````
+M``$`&`````@R```````````!`$X)```,,@``-`````(``0`5````##(`````
+M``````$`&````#PR```````````!`%L)``!`,@``-`````(``0`5````0#(`
+M``````````$`&````'`R```````````!`&0)``!T,@``;`````(``0`5````
+M=#(```````````$`&````-PR```````````!`'`)``#@,@``1`````(``0`5
+M````X#(```````````$`>PD``"0S```T`````@`!`!4````D,P``````````
+M`0"%"0``6#,``"P````"``$`%0```%@S```````````!`!@```"`,P``````
+M`````0"."0``A#,``%`````"``$`%0```(0S```````````!`)<)``#4,P``
+M7`````(``0`5````U#,```````````$`I`D``#`T``"<`````@`!`!4````P
+M-````````````0"R"0``S#0``%P````"``$`%0```,PT```````````!`+P)
+M```H-0``K`````(``0`5````*#4```````````$`Q@D``-0U``#8`````@`!
+M`!4```#4-0```````````0#2"0``K#8``+P````"``$`%0```*PV````````
+M```!`-T)``!H-P``<`````(``0`5````:#<```````````$`%0```-@W````
+M```````!`!@```!H.````````````0`5````;#@```````````$`%0```*PX
+M```````````!`.D)``#T`0``$@````$`*@`%"@``!@(``!0````!`"H`(PH`
+M```````(`````0!)`!@`````````````````20`_"@````````@````!`$L`
+M&`````````````````!+`%T*```,````P`````$`:@`8````#```````````
+M`&H`:@H``.@!```(`````0!N`!@```#H`0``````````;@!N"@``````````
+M```$`/'_=PH``,@X``"T`````@`!`!4```#(.````````````0`5````?#D`
+M``````````$`&````'`Z```````````!`!4```!T.@```````````0`5````
+M[#H```````````$`%0```*P[```````````!`!4```!`/````````````0`5
+M````Z#P```````````$`%0```$`]```````````!`!4````\/@``````````
+M`0`8````C#X```````````$`%0```)0^```````````!`!@```#\/@``````
+M`````0`5````!#\```````````$`&````)P_```````````!`!4```"@/P``
+M`````````0`5````Z#\```````````$`&````-1%```````````!`(,*``!0
+M`0``(`T```$`!0`8````4`$```````````4`B@H````````(`````0!-`!@`
+M````````````````30"M"@``.`(``!D````!`"H`T`H````````(`````0!/
+M`!@`````````````````3P#K"@``A@(``!$````!`"H`!@L````````(````
+M`0!1`!@`````````````````40`E"P``40(``!4````!`"H`1`L````````(
+M`````0!3`!@`````````````````4P!?"P``&@(``!$````!`"H`>@L``"L"
+M```-`````0`J`)$+``!F`@``$@````$`*@"M"P``>`(```X````!`"H`Q0L`
+M`)<"```1`````0`J`.`+``"H`@``%`````$`*@#^"P``O`(``!0````!`"H`
+M'`P``-`"```5`````0`J`#L,``#E`@``%`````$`*@!9#```^0(```\````!
+M`"H`<@P````````(`````0!5`!@`````````````````50"+#`````````@`
+M```!`%<`&`````````````````!7`*,,````````"`````$`60`8````````
+M`````````%D`P0P````````(`````0!;`!@`````````````````6P#<#```
+M``````@````!`%T`&`````````````````!=`/,,````````"`````$`7P`8
+M`````````````````%\`$0T````````(`````0!A`!@`````````````````
+M80`P#0````````@````!`&,`&`````````````````!C`$X-````````"```
+M``$`90`8`````````````````&4`:@T`````````````!`#Q_Q4```#<10``
+M`````````0`8````3$P```````````$`<@T``'`.```(`````0`%`!@```!P
+M#@``````````!0"!#0``M`\``#0````2``$`F`T``'0Z``!X````$@`!`*P-
+M````````!````!$`<0"U#0``_`<``&@````2``$`O@T``"`!```$````$0!N
+M`-`-```H)P``?`$``!(``0#A#0`````````````0````\0T`````````````
+M$``````.``"\,```6````!(``0`2#@`````````````0````'PX``.@\``!8
+M````$@`!`"T.`````````````!`````Y#@`````````````0````0@X``#`@
+M``#<!@``$@`!`$\.``"L*```(`$``!(``0!?#@`````````````0````<`X`
+M````````````$````'X.`````````````!````"5#@``T````,P````2``$`
+MK0X``)0````\````$@`!`,,.``"D!```-````!(``0#0#@``2"P``.P````2
+M``$`W`X`````````````$````.,.`````````````!````#S#@``````````
+M```0````^0X`````````````$`````,/`````````````!`````4#P``;#@`
+M`$`````2``$`)@\``.`3``"0`@``$@`!`#$/``!D"```K`$``!(``0!%#P``
+MK#L``)0````2``$`5P\``!PG```$````$@`!`&D/``!X+0``%`$``!(``0![
+M#P``&"<```0````2``$`CP\``!0```"`````$0!N`)T/```@)P``"````!(`
+M`0"I#P``H#\``$@````2``$`P@\``.@_``#T!0``$@`!`,\/``!`/```J```
+M`!(``0#D#P``C"X````"```2``$`]0\`````````````$`````80````````
+M`````!`````1$```-"T``$0````2``$`(1``````````````$````#00````
+M`````````!````!!$```.`(``!`````2``$`51``````````````$````&80
+M`````````````!````!T$```[#H``,`````2``$`A1```'PY``#X````$@`!
+M`)D0`````````````!````"D$``````````````0````L1``````````````
+M$````+D0```,````!````!$`<0#($```P!$``"`"```2``$`W1``````````
+M````$````.00``",,```"````!(``0#R$``````````````0````^1``````
+M````````$`````81``#,*0``0````!(``0`6$0``V`T``/0````2``$`)1$`
+M````````````$````#01``"$$0``/````!(``0!4$0`````````````0````
+M7A$``)0>``"<`0``$@`!`&X1`````````````!````!\$0`````````````0
+M````BQ$``-Q%``#(!@``$@`!`)P1``"@!P``7````!(``0"K$0``O!P``!`!
+M```2``$`NQ$``!0G```$````$@`!`-`1`````````````!````#G$0``<"L`
+M`-@````2``$`]!$``*0H```(````$@`!``42`````````````!`````.$@``
+M.````%P````2``$`(1(`````````````$````"X2``"4/@``<````!(``0!"
+M$@``!`````0````1`'$`2Q(`````````````$````%T2`````````````!``
+M``!L$@`````````````0````=Q(```@````$````$0!Q`(02```,)P``"```
+M`!(``0"2$@`````````````0````HQ(`````````````$````+(2``#8-P``
+ME````!(``0#!$@``!#\``)P````2``$`TA(``#P^``!8````$@`!`.82````
+M`````````!````#S$@``0#T``/P````2``$`"!,``(@"```@`0``$@`!`!<3
+M```,*@``9`$``!(``0`G$P`````````````0````,!,``)P!``"<````$@`!
+M`$43`````````````!````!5$P``K#@``!P````2``$`:1,`````````````
+M$````'`3`````````````!````"'$P`````````````0````EA,`````````
+M````$````)T3`````````````!````"N$P`````````````0````N!,`````
+M````````$````,L3`````````````!``````9F)M96TN8P!P=71?9F)?:6YF
+M;P`D80`D9`!F8E]S97%?;F5X=`!F8E]S97%?<W1A<G0`9F)?<F5L96%S90!G
+M971?9F)?:6YF;P!F8E]S97%?<W1O<`!F8E]O<&5N`&9B7VUM87``9F)?=W)I
+M=&4`9F)?<F5A9`!P<F]C7V9B7V]P96X`9F)?<V5Q7W-H;W<`9F)M96U?:6YI
+M=`!V:61E;U]S971U<`!D;U]U;G)E9VES=&5R7V9R86UE8G5F9F5R`&1O7W)E
+M;6]V95]C;VYF;&EC=&EN9U]F<F%M96)U9F9E<G,`9&]?9F)?:6]C=&P`9F)?
+M:6]C=&P`9F)?<V5T7VQO9V]C;6%P`'!R;V-?9F)?<V5Q7V]P<P!F8E]P<F]C
+M7V9O<',`9F)?9F]P<P!M87-K+C(V-S@R`$-35U1#2"XT,30`<F5G:7-T<F%T
+M:6]N7VQO8VL`7U]K<WEM=&%B7V9B7W!A9%]U;F%L:6=N961?8G5F9F5R`%]?
+M:W-T<G1A8E]F8E]P861?=6YA;&EG;F5D7V)U9F9E<@!?7VMS>6UT86)?9F)?
+M9V5T7V-O;&]R7V1E<'1H`%]?:W-T<G1A8E]F8E]G971?8V]L;W)?9&5P=&@`
+M7U]K<WEM=&%B7W)E9VES=&5R961?9F(`7U]K<W1R=&%B7W)E9VES=&5R961?
+M9F(`7U]K<WEM=&%B7V9B7W!A;E]D:7-P;&%Y`%]?:W-T<G1A8E]F8E]P86Y?
+M9&ES<&QA>0!?7VMS>6UT86)?9F)?<VAO=U]L;V=O`%]?:W-T<G1A8E]F8E]S
+M:&]W7VQO9V\`7U]K97DN,C@R,#(`7U]K97DN,C@P.#$`7U]K97DN,C@P.#(`
+M7U]K<WEM=&%B7W)E;6]V95]C;VYF;&EC=&EN9U]F<F%M96)U9F9E<G,`7U]K
+M<W1R=&%B7W)E;6]V95]C;VYF;&EC=&EN9U]F<F%M96)U9F9E<G,`7U]S971U
+M<%]S=')?=FED96]?<V5T=7``7U]K<WEM=&%B7VYU;5]R96=I<W1E<F5D7V9B
+M`%]?:W-T<G1A8E]N=6U?<F5G:7-T97)E9%]F8@!?7VEN:71C86QL7V9B;65M
+M7VEN:70T`%]?:W-Y;71A8E]F8E]S971?=F%R`%]?:W-T<G1A8E]F8E]S971?
+M=F%R`&9B7VQO9V\`4D%4`&]F;VYL>0!V:61E;U]O<'1I;VYS`%]?:W-Y;71A
+M8E]U;G)E9VES=&5R7V9R86UE8G5F9F5R`%]?:W-T<G1A8E]U;G)E9VES=&5R
+M7V9R86UE8G5F9F5R`%]?:W-Y;71A8E]F8E]G971?8G5F9F5R7V]F9G-E=`!?
+M7VMS=')T86)?9F)?9V5T7V)U9F9E<E]O9F9S970`7U]K<WEM=&%B7VQO8VM?
+M9F)?:6YF;P!?7VMS=')T86)?;&]C:U]F8E]I;F9O`%]?:W-Y;71A8E]F8E]P
+M861?86QI9VYE9%]B=69F97(`7U]K<W1R=&%B7V9B7W!A9%]A;&EG;F5D7V)U
+M9F9E<@!?7VMS>6UT86)?9F)?8VQA<W,`7U]K<W1R=&%B7V9B7V-L87-S`%]?
+M:W-Y;71A8E]F8E]G971?;W!T:6]N<P!?7VMS=')T86)?9F)?9V5T7V]P=&EO
+M;G,`7U]K<WEM=&%B7W)E9VES=&5R7V9R86UE8G5F9F5R`%]?:W-T<G1A8E]R
+M96=I<W1E<E]F<F%M96)U9F9E<@!?7VMS=')T86)?9F)?<V5T7W-U<W!E;F0`
+M7U]K<W1R=&%B7V9B7V)L86YK`%]?:W-Y;71A8E]F8E]B;&%N:P!?7W-E='5P
+M7W9I9&5O7W-E='5P`%]?:W-Y;71A8E]F8E]S971?<W5S<&5N9`!F8FUO;BYC
+M`%]?:W-Y;71A8E]F8E]F:7)M=V%R95]E9&ED`%]?:W-T<G1A8E]F8E]F:7)M
+M=V%R95]E9&ED`%]?:W-Y;71A8E]F8E]E9&ED7V%D9%]M;VYS<&5C<P!?7VMS
+M=')T86)?9F)?961I9%]A9&1?;6]N<W!E8W,`7U]K<WEM=&%B7V9B7W9A;&ED
+M871E7VUO9&4`7U]K<W1R=&%B7V9B7W9A;&ED871E7VUO9&4`7U]K<WEM=&%B
+M7V9B7W!A<G-E7V5D:60`7U]K<W1R=&%B7V9B7W!A<G-E7V5D:60`7U]K<W1R
+M=&%B7V9B7V1E<W1R;WE?;6]D961B`%]?:W-T<G1A8E]F8E]G971?;6]D90!?
+M7VMS=')T86)?9F)?961I9%]T;U]M;VYS<&5C<P!?7VMS>6UT86)?9F)?9V5T
+M7VUO9&4`7U]K<WEM=&%B7V9B7V5D:61?=&]?;6]N<W!E8W,`7U]K<WEM=&%B
+M7V9B7V1E<W1R;WE?;6]D961B`%)"5`!F8F-M87`N8P!D969A=6QT7S)?8V]L
+M;W)S`')E9#(`9W)E96XR`&)L=64R`&1E9F%U;'1?-%]C;VQO<G,`<F5D-`!G
+M<F5E;C0`8FQU930`9&5F875L=%\Q-E]C;VQO<G,`<F5D,38`9W)E96XQ-@!B
+M;'5E,38`9&5F875L=%\X7V-O;&]R<P!R960X`&=R965N.`!B;'5E.`!?7VMS
+M>6UT86)?9F)?:6YV97)T7V-M87!S`%]?:W-T<G1A8E]F8E]I;G9E<G1?8VUA
+M<',`7U]K<W1R=&%B7V9B7V1E9F%U;'1?8VUA<`!?7VMS=')T86)?9F)?<V5T
+M7V-M87``7U]K<W1R=&%B7V9B7V-O<'E?8VUA<`!?7VMS=')T86)?9F)?9&5A
+M;&QO8U]C;6%P`%]?:W-T<G1A8E]F8E]A;&QO8U]C;6%P`%]?:W-Y;71A8E]F
+M8E]D96%L;&]C7V-M87``7U]K<WEM=&%B7V9B7W-E=%]C;6%P`%]?:W-Y;71A
+M8E]F8E]D969A=6QT7V-M87``7U]K<WEM=&%B7V9B7V-O<'E?8VUA<`!?7VMS
+M>6UT86)?9F)?86QL;V-?8VUA<`!20U0`9F)S>7-F<RYC`'-T;W)E7V-O;G-O
+M;&4`<VAO=U]B;&%N:P!S=&]R95]C=7)S;W(`<VAO=U]C;VYS;VQE`'-H;W=?
+M8W5R<V]R`'-T;W)E7V9B<W1A=&4`<VAO=U]F8G-T871E`'-H;W=?<F]T871E
+M`'-H;W=?<W1R:61E`'-H;W=?;F%M90!S:&]W7W9I<G1U86P`<VAO=U]P86X`
+M;6]D95]S=')I;F<`<VAO=U]M;V1E<P!S:&]W7VUO9&4`<VAO=U]B<'``86-T
+M:79A=&4`<W1O<F5?<F]T871E`'-T;W)E7W9I<G1U86P`<W1O<F5?8G!P`'-T
+M;W)E7W!A;@!S=&]R95]M;V1E<P!S=&]R95]M;V1E`'-T;W)E7V)L86YK`%]?
+M:W-T<G1A8E]F<F%M96)U9F9E<E]A;&QO8P!?7VMS=')T86)?9G)A;65B=69F
+M97)?<F5L96%S90!?7VMS>6UT86)?9G)A;65B=69F97)?86QL;V,`7U]K<WEM
+M=&%B7V9R86UE8G5F9F5R7W)E;&5A<V4`9&5V:6-E7V%T=')S`%)$5`!M;V1E
+M9&(N8P!F8E]T<GE?;6]D90!M;V1E9&(`7U]K<WEM=&%B7V9B7W9I9&5O;6]D
+M95]T;U]M;V1E;&ES=`!?7VMS=')T86)?9F)?=FED96]M;V1E7W1O7VUO9&5L
+M:7-T`%]?:W-Y;71A8E]F8E]A9&1?=FED96]M;V1E`%]?:W-T<G1A8E]F8E]A
+M9&1?=FED96]M;V1E`%]?:W-Y;71A8E]F8E]F:6YD7VYE87)E<W1?;6]D90!?
+M7VMS=')T86)?9F)?9FEN9%]N96%R97-T7VUO9&4`7U]K<WEM=&%B7V9B7V9I
+M;F1?;6]D95]C=G0`7U]K<W1R=&%B7V9B7V9I;F1?;6]D95]C=G0`7U]K<W1R
+M=&%B7V9B7V9I;F1?;6]D90!?7VMS=')T86)?9F)?9FEN9%]B97-T7VUO9&4`
+M7U]K<W1R=&%B7V9B7VUA=&-H7VUO9&4`7U]K<W1R=&%B7V9B7VUO9&5?:7-?
+M97%U86P`7U]K<W1R=&%B7V9B7W9A<E]T;U]V:61E;VUO9&4`7U]K<W1R=&%B
+M7V9B7W9I9&5O;6]D95]T;U]V87(`7U]K<W1R=&%B7V9B7V9I;F1?8F5S=%]D
+M:7-P;&%Y`%]?:W-T<G1A8E]F8E]D97-T<F]Y7VUO9&5L:7-T`%]?:W-T<G1A
+M8E]F8E]M;V1E7V]P=&EO;@!?7VMS>6UT86)?9F)?;6]D95]O<'1I;VX`7U]K
+M<WEM=&%B7V9B7VUA=&-H7VUO9&4`7U]K<WEM=&%B7V9B7V1E<W1R;WE?;6]D
+M96QI<W0`7U]K<WEM=&%B7V9B7VUO9&5?:7-?97%U86P`7U]K<WEM=&%B7V9B
+M7V9I;F1?;6]D90!?7VMS>6UT86)?9F)?=F%R7W1O7W9I9&5O;6]D90!?7VMS
+M>6UT86)?9F)?9FEN9%]B97-T7V1I<W!L87D`7U]K<WEM=&%B7V9B7W9I9&5O
+M;6]D95]T;U]V87(`7U]K<WEM=&%B7V9B7V9I;F1?8F5S=%]M;V1E`&9B8W9T
+M+F,`9F)?8W9T7W9B:5]T86(`=6YR96=I<W1E<E]F<F%M96)U9F9E<@!F8E]V
+M:61E;VUO9&5?=&]?=F%R`&9B7V-L87-S`&9B7V)L86YK`&YU;5]R96=I<W1E
+M<F5D7V9B`&9B7W9A;&ED871E7VUO9&4`9&5V7V=E=%]D<G9D871A`%]?8VQA
+M<W-?8W)E871E`&9B7V-L96%N=7!?9&5V:6-E`&9B7V9I;F1?;&]G;P!F8E]M
+M871C:%]M;V1E`'-E<5]R96QE87-E`'-N<')I;G1F`&9B7W-H;W=?;&]G;P!F
+M8E]I;G9E<G1?8VUA<',`=FU?9V5T7W!A9V5?<')O=`!S:6UP;&5?<W1R=&]L
+M`%]?865A8FE?=6YW:6YD7V-P<%]P<C``9F)?<&%D7W5N86QI9VYE9%]B=69F
+M97(`9F)?<&%D7V%L:6=N961?8G5F9F5R`&QO8VM?9F)?:6YF;P!F8E]S971?
+M8VUA<`!M96UC<'D`<F5M87!?<&9N7W)A;F=E`&MF<F5E`'-E<5]L<V5E:P!P
+M<F]C7V-R96%T95]D871A`&9R86UE8G5F9F5R7V%L;&]C`&9B7W-E=%]V87(`
+M<FM?8VAE8VM?<F5S;VQU=&EO;@!F8E]F:6YD7V)E<W1?;6]D90!F8E]D97-T
+M<F]Y7VUO9&5D8@!F8E]A;&QO8U]C;6%P7V=F<`!F8E]E9&ED7W1O7VUO;G-P
+M96-S`')E9VES=&5R961?9F(`9F)?9V5T7VUO9&4`9F)?=FED96]M;V1E7W1O
+M7VUO9&5L:7-T`&9B7V9I;F1?;6]D90!F8E]F:6YD7VYE87)E<W1?;6]D90!F
+M8E]S971?=7-E<E]C;6%P`&MM96U?8V%C:&5?86QL;V,`;6]D=6QE7W!U=`!F
+M8E]D96%L;&]C7V-M87``9&5V:6-E7V-R96%T95]F:6QE`%]?865A8FE?:61I
+M=@!F8E]S:&]W7V-H87)G95]L;V=O`'!R965M<'1?<V-H961U;&4`9&5V:6-E
+M7V-R96%T90!F8E]M;V1E7VES7V5Q=6%L`&9B7W9A<E]T;U]V:61E;VUO9&4`
+M;75T97A?;&]C:P!C;VYS;VQE7VQO8VL`<W1R;F-M<`!F8E]M;V1E7V]P=&EO
+M;@!R96=I<W1E<E]F<F%M96)U9F9E<@!M96UC;7``9F)?86QL;V-?8VUA<`!P
+M<FEN=&L`7U]M=71E>%]I;FET`&9B7V1E9F%U;'1?8VUA<`!F8E]G971?;W!T
+M:6]N<P!D969A=6QT7VQL<V5E:P!R96UO=F5?8V]N9FQI8W1I;F=?9G)A;65B
+M=69F97)S`%]?;65M>F5R;P!F8E]P<F5P87)E7VQO9V\`7U]A96%B:5]U:61I
+M=@!C;VYS;VQE7W5N;&]C:P!F8E]F:6YD7VUO9&5?8W9T`&9B7W-E=%]S=7-P
+M96YD`&9B7VYE=U]M;V1E;&ES=`!F8E]E9&ED7V%D9%]M;VYS<&5C<P!F8E]N
+M;W1I9FEE<E]C86QL7V-H86EN`&9B7V-O<'E?8VUA<`!F8E]F:7)M=V%R95]E
+M9&ED`'-E<5]R96%D`&9B7V=E=%]C;VQO<E]D97!T:`!M=71E>%]U;FQO8VL`
+M9F)?9&5L971E7W9I9&5O;6]D90!F8E]V861D<@!?7W)E9VES=&5R7V-H<F1E
+M=@!D979I8V5?9&5S=')O>0!S97%?<')I;G1F`&=?4FLR.7AX0VAI<`!F8E]P
+M87)S95]E9&ED`%]?865A8FE?=6ED:79M;V0`<VEM<&QE7W-T<G1O=6P`9F)?
+M:6YI=%]D979I8V4`9F)?861D7W9I9&5O;6]D90!F8E]D97-T<F]Y7VUO9&5L
+M:7-T`&UA;&QO8U]S:7IE<P!F8E]F:6YD7V)E<W1?9&ES<&QA>0!F8E]P86Y?
+M9&ES<&QA>0!F8E]C;6%P7W1O7W5S97(`<V5Q7V]P96X`9F)?9V5T7V)U9F9E
+M<E]O9F9S970`9&5V7W-E=%]D<G9D871A`&9R86UE8G5F9F5R7W)E;&5A<V4`
+M<W1R;&5N`%]?865A8FE?=6YW:6YD7V-P<%]P<C$`7U]C;W!Y7W1O7W5S97(`
+M<W1R8VAR`%]?8V]P>5]F<F]M7W5S97(`7U]K;6%L;&]C`&1E=FEC95]R96UO
+9=F5?9FEL90!?7W)E<75E<W1?;6]D=6QE````
+`
+end
index 9a7b44fe5fd816ab063029b0a70b61b6446e11dc..a1ae79ebfdb3a2cb83bac93987df45e5039b1713 100755 (executable)
@@ -248,9 +248,9 @@ static ssize_t hdmi_restore_init_attrs(struct device *dev,
 }\r
 #endif\r
 static struct device_attribute hdmi_attrs[] = {\r
-       __ATTR(state, 0777, hdmi_show_state_attrs, hdmi_restore_state_attrs),\r
-       __ATTR(enable, 0777, hdmi_show_switch_attrs, hdmi_restore_switch_attrs),\r
-       __ATTR(debug, 0777, hdmi_show_debug_attrs, hdmi_restore_debug_attrs),\r
+       __ATTR(state, 0774, hdmi_show_state_attrs, hdmi_restore_state_attrs),\r
+       __ATTR(enable, 0774, hdmi_show_switch_attrs, hdmi_restore_switch_attrs),\r
+       __ATTR(debug, 0774, hdmi_show_debug_attrs, hdmi_restore_debug_attrs),\r
        //__ATTR(init, 0777, NULL, hdmi_restore_init_attrs),\r
 };\r
 int hdmi_create_attrs(struct hdmi *hdmi)\r
old mode 100644 (file)
new mode 100755 (executable)
index 202766b..da979c2
@@ -307,11 +307,24 @@ struct ion_phys_data {
        unsigned long phys;
        size_t size;
 };
+
 struct ion_flush_data {
        struct ion_handle *handle;
        void *virt;
        size_t size;
 };
+
+struct ion_client_data {
+#define ION_TYPE_GET_TOTAL_SIZE  0
+#define ION_TYPE_SIZE_GET_COUNT  1
+       unsigned int type;
+       union {
+               size_t size;
+               size_t total_size;
+       };
+       unsigned int count;
+};
+
 #define ION_IOC_MAGIC          'I'
 
 /**
@@ -371,4 +384,6 @@ struct ion_flush_data {
 #define ION_CACHE_CLEAN                _IOWR(ION_IOC_MAGIC, 8, struct ion_flush_data)
 #define ION_CACHE_INVALID      _IOWR(ION_IOC_MAGIC, 9, struct ion_flush_data)
 #define ION_GET_PHYS           _IOWR(ION_IOC_MAGIC, 10, unsigned long)
+#define ION_GET_CLIENT         _IOWR(ION_IOC_MAGIC, 11, struct ion_client_data)
+
 #endif /* _LINUX_ION_H */
index 0e0855a94edc90133a1d1658260b8d275b5b7287..8f9411d572f1d38c7e6ee0dbbd5d2292d403f8c5 100755 (executable)
@@ -177,7 +177,6 @@ struct wm8994_pdata {
 
        /* WM8958 microphone bias configuration */
        int micbias[2];
-       
 };
 
 #endif
index 0c69ff84e0f7910e3daa0a890871951169e2d5d3..431461037f968fea9b67467fb34b4b5b83a68c6c 100644 (file)
@@ -20,6 +20,7 @@ struct rk29_mu509_data {
        unsigned int bp_reset_active_low;
        unsigned int bp_wakeup_ap;
        unsigned int ap_wakeup_bp;
+       unsigned int modem_power_en;
 };
 
 #define MODEM_NAME "mu509"
index 0cf11ec0ff3bcd47728070a9ff5826a6037f1d66..d52d36fce6b619d6a8f3755cf2278b0181985f98 100755 (executable)
@@ -258,6 +258,11 @@ enum snd_soc_compress_type {
        SND_SOC_RBTREE_COMPRESSION
 };
 
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+int snd_soc_incall_status(int read_or_write, int status);
+#endif 
+
+
 int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
                             unsigned int freq, int dir);
 int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
index 234f68da715e8f4f661c4ecd764a6de1543443fe..9249dc8dcdd0e63b733c2a4645eff502ebbbf48b 100755 (executable)
Binary files a/mkkrnlimg and b/mkkrnlimg differ
index 9df543470c8bb0289beffbd946b21ab1bb318620..e34829076ddbdb5aec8377c7f96c18d0291ea147 100755 (executable)
@@ -6,6 +6,7 @@ FILES=(
 arch/arm/mach-rk29/clock.c
 arch/arm/mach-rk29/ddr.c
 arch/arm/mach-rk29/vpu*.c
+arch/arm/mach-rk29/verifyID.c
 
 drivers/staging/rk29/ipp/rk29-ipp.c
 )
@@ -57,9 +58,6 @@ arch/arm/configs/rk29_newton_defconfig
 arch/arm/mach-rk29/board-rk29-p91*
 arch/arm/configs/rk29_p91_defconfig
 
-arch/arm/mach-rk29/board-rk29phonepadsdk*
-arch/arm/configs/rk29_phonepadsdk_defconfig
-
 arch/arm/mach-rk29/board-rk29-phonesdk*
 arch/arm/configs/rk29_phonesdk_defconfig
 
index 129acc4c5d790f6430ea63667da52db914547300..7ef6437e47e535e6fd5a6824d445b9edca08a743 100644 (file)
@@ -1,14 +1,22 @@
+/*
+ * rt5625.c  --  RT5625 ALSA SoC audio codec driver
+ *
+ * Copyright 2011 Realtek Semiconductor Corp.
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
-#include <linux/jiffies.h>
-#include <asm/delay.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
-#include <asm/div64.h>
-
+#include <linux/gpio.h>
 #include "rt5625.h"
-
-#if REALTEK_HWDEP
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
+#include <mach/board.h>
+
+#define RT5625_PROC
+#ifdef RT5625_PROC
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/vmalloc.h>
+char debug_write_read = 0;
 #endif
 
-#if 0
+#if 1
 #define DBG(x...) printk(KERN_INFO x)
 #else
 #define DBG(x...) do { } while (0)
 #endif
 
-#define AUDIO_NAME "rt5625"
-#define RT5625_VERSION "0.03 alsa 1.0.21"
-#define ALSA_SOC_VERSION "1.0.21"
+static struct snd_soc_codec *rt5625_codec;
 
-#define RT5625_EQ_FUNC_ENA  0
+#define RT5625_REG_RW 1 /* for debug */
+//#define RT5625_DEMO 1        /* only for demo; please remove it */
 
-static void hp_depop_mode2(struct snd_soc_codec *codec);
-static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute); 
+#define RT5625_F_SMT_PHO
+#define RT5625_PLY_BIT 0
+#define RT5625_PLY_MASK (0x1)
+#define RT5625_REC_BIT 1
+#define RT5625_REC_MASK (0x1 << RT5625_REC_BIT)
+#define RT5625_3G_BIT 2
+#define RT5625_3G_MASK (0x1 << RT5625_3G_BIT)
+#define RT5625_BT_BIT 3
+#define RT5625_BT_MASK (0x1 << RT5625_BT_BIT)
+#define RT5625_VOIP_BIT 4
+#define RT5625_VOIP_MASK (0x1 << RT5625_VOIP_BIT)
 
 struct rt5625_priv {
        unsigned int stereo_sysclk;
        unsigned int voice_sysclk;
-};
 
-struct rt5625_init_reg {
-       u8 reg_index;
-       u16 reg_value;  
+       int vodsp_fun;
+       int spk_ctr_status;
+       int spk_ctr_pin;
+       int spk_ctr_on;
+       int spk_ctr_off;
+#ifdef RT5625_F_SMT_PHO
+       int app_bmp;/* bit{0, 1, 2, 3, 4} = {play, rec, 3g, bt, voip} */
+       int pll_sel;
+       int pll2_sel;
+       int dac_active;
+       int adc_active;
+       int headset;
+       int vodsp_fun_bak;
+#endif
 };
 
-static struct rt5625_init_reg rt5625_init_list[] = {
-
-       {RT5625_HP_OUT_VOL                      , 0x8888},      //default is -12db
-       {RT5625_SPK_OUT_VOL             , 0x8080},      //default is 0db
-       {RT5625_DAC_AND_MIC_CTRL        , 0xee03},      //DAC to hpmixer
-       {RT5625_OUTPUT_MIXER_CTRL       , 0x0748},      //all output from hpmixer
-       {RT5625_MIC_CTRL                        , 0x0500},      //mic boost 20db
-       {RT5625_ADC_REC_MIXER           , 0x3f3f},      //record source from mic1
-       {RT5625_GEN_CTRL_REG1           , 0x0c0a},      //speaker vdd ratio is 1
-       {RT5625_ADC_REC_GAIN            , 0xd5d5},      //gain 15db of ADC by default
-
+#ifdef RT5625_F_SMT_PHO
+static u16 rt5625_voip_back[][2] = {
+       {RT5625_VODSP_PDM_CTL, 0x0000},
+       {RT5625_F_DAC_ADC_VDAC, 0x0000},
 };
+#define RT5625_VOIP_BK_NUM \
+       (sizeof(rt5625_voip_back) / sizeof(rt5625_voip_back[0]))
+#endif
 
-#define RT5625_INIT_REG_NUM ARRAY_SIZE(rt5625_init_list)
-
-#if (RT5625_EQ_FUNC_ENA==1)
-//*************************************************************************************************
-//eq table
-//*************************************************************************************************
-enum
-{
-       NORMAL=0,
-       CLUB,
-       DANCE,
-       LIVE,   
-       POP,
-       ROCK,
-       OPPO,
-       TREBLE,
-       BASS    
+#ifdef RT5625_DEMO
+struct rt5625_init_reg {
+       u8 reg;
+       u16 val;
 };
 
-typedef struct  _HW_EQ_PRESET
-{
-       u16     HwEqType;
-       u16     EqValue[14];
-       u16  HwEQCtrl;
-
-}HW_EQ_PRESET;
-
-
-HW_EQ_PRESET HwEq_Preset[]={
-/*                     0x0             0x1             0x2       0x3   0x4             0x5             0x6             0x7     0x8             0x9             0xa     0xb             0xc             0x6e*/
-       {NORMAL,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x0000},                   
-       {CLUB  ,{0x1C10,0x0000,0xC1CC,0x1E5D,0x0699,0xCD48,0x188D,0x0699,0xC3B6,0x1CD0,0x0699,0x0436,0x0000},0x800E},
-       {DANCE ,{0x1F2C,0x095B,0xC071,0x1F95,0x0616,0xC96E,0x1B11,0xFC91,0xDCF2,0x1194,0xFAF2,0x0436,0x0000},0x800F},
-       {LIVE  ,{0x1EB5,0xFCB6,0xC24A,0x1DF8,0x0E7C,0xC883,0x1C10,0x0699,0xDA41,0x1561,0x0295,0x0436,0x0000},0x800F},
-       {POP   ,{0x1EB5,0xFCB6,0xC1D4,0x1E5D,0x0E23,0xD92E,0x16E6,0xFCB6,0x0000,0x0969,0xF988,0x0436,0x0000},0x800F},
-       {ROCK  ,{0x1EB5,0xFCB6,0xC071,0x1F95,0x0424,0xC30A,0x1D27,0xF900,0x0C5D,0x0FC7,0x0E23,0x0436,0x0000},0x800F},
-       {OPPO  ,{0x0000,0x0000,0xCA4A,0x17F8,0x0FEC,0xCA4A,0x17F8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x800F},
-       {TREBLE,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x188D,0x1699},0x8010},
-       {BASS  ,{0x1A43,0x0C00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x8001},
-       
+static struct rt5625_init_reg init_list[] = {
+       {RT5625_HP_OUT_VOL              , 0x8888},      //default is -12db
+       {RT5625_SPK_OUT_VOL             , 0x8080},      //default is 0db
+       {RT5625_PHONEIN_VOL     , 0xe800},      //phone differential
+       {RT5625_DAC_MIC_CTRL    , 0xee01},      //DAC to hpmixer & spkmixer
+       {RT5625_OUTMIX_CTRL             , 0x2bc8},      //spk from spkmixer; hp from hpmixer; aux from monomixer; classAB
+       {RT5625_ADC_REC_MIXER   , 0x1f1f},      //record source from mic1 & mic2
+       {RT5625_GEN_CTRL1               , 0x0c08},      //speaker vdd ratio is 1; 1.25VDD ratio
 };
+#define RT5625_INIT_REG_LEN ARRAY_SIZE(init_list)
 
+static int rt5625_reg_init(struct snd_soc_codec *codec)
+{
+       int i;
+       for (i = 0; i < RT5625_INIT_REG_LEN; i++)
+               snd_soc_write(codec, init_list[i].reg, init_list[i].val);
+       return 0;
+}
 #endif
-//*************************************************************************************************
-//*************************************************************************************************
-
-/*
- *     bit[0]  for linein playback switch
- *     bit[1] phone
- *     bit[2] mic1
- *     bit[3] mic2
- *     bit[4] vopcm
- *     
- */
-#define HPL_MIXER 0x80
-#define HPR_MIXER 0x82
-static unsigned int reg80 = 0, reg82 = 0;
 
-/*
- *     bit[0][1][2] use for aec control
- *  bit[3] for none  
- *     bit[4] for SPKL pga
- *     bit[5] for SPKR pga
- *     bit[6] for hpl pga
- *     bit[7] for hpr pga
- *  bit[8] for dump dsp
- *  bit[12~15] for eq function
- */
- #define VIRTUAL_REG_FOR_MISC_FUNC 0x84
-static unsigned int reg84 = 0;
-
-
-static const u16 rt5625_reg[] = {
-       0x59b4, 0x8080, 0x8080, 0x8080,         /*reg00-reg06*/
-       0xc800, 0xe808, 0x1010, 0x0808,         /*reg08-reg0e*/
-       0xe0ef, 0xcbcb, 0x7f7f, 0x0000,         /*reg10-reg16*/
-       0xe010, 0x0000, 0x8008, 0x2007,         /*reg18-reg1e*/
-       0x0000, 0x0000, 0x00c0, 0xef00,         /*reg20-reg26*/
-       0x0000, 0x0000, 0x0000, 0x0000,         /*reg28-reg2e*/
-       0x0000, 0x0000, 0x0000, 0x0000,         /*reg30-reg36*/
-       0x0000, 0x0000, 0x0000, 0x0000,         /*reg38-reg3e*/
-       0x0c0a, 0x0000, 0x0000, 0x0000,         /*reg40-reg46*/
-       0x0029, 0x0000, 0xbe3e, 0x3e3e,         /*reg48-reg4e*/
-       0x0000, 0x0000, 0x803a, 0x0000,         /*reg50-reg56*/
-       0x0000, 0x0009, 0x0000, 0x3000,         /*reg58-reg5e*/
-       0x3075, 0x1010, 0x3110, 0x0000,         /*reg60-reg66*/
-       0x0553, 0x0000, 0x0000, 0x0000,         /*reg68-reg6e*/
-       0x0000, 0x0000, 0x0000, 0x0000,         /*reg70-reg76*/
-       0x0000, 0x0000, 0x0000, 0x0000,     /*reg78-reg7e*/
+static const u16 rt5625_reg[0x80] = {
+       [RT5625_RESET] = 0x59b4,
+       [RT5625_SPK_OUT_VOL] = 0x8080,
+       [RT5625_HP_OUT_VOL] = 0x8080,
+       [RT5625_AUX_OUT_VOL] = 0x8080,
+       [RT5625_PHONEIN_VOL] = 0xc800,
+       [RT5625_LINE_IN_VOL] = 0xe808,
+       [RT5625_DAC_VOL] = 0x1010,
+       [RT5625_MIC_VOL] = 0x0808,
+       [RT5625_DAC_MIC_CTRL] = 0xee0f,
+       [RT5625_ADC_REC_GAIN] = 0xcbcb,
+       [RT5625_ADC_REC_MIXER] = 0x7f7f,
+       [RT5625_VDAC_OUT_VOL] = 0xe010,
+       [RT5625_OUTMIX_CTRL] = 0x8008,
+       [RT5625_VODSP_CTL] = 0x2007,
+       [RT5625_DMIC_CTRL] = 0x00c0,
+       [RT5625_PD_CTRL] = 0xef00,
+       [RT5625_GEN_CTRL1] = 0x0c0a,
+       [RT5625_LDO_CTRL] = 0x0029,
+       [RT5625_GPIO_CONFIG] = 0xbe3e,
+       [RT5625_GPIO_POLAR] = 0x3e3e,
+       [RT5625_GPIO_STATUS] = 0x803a,
+       [RT5625_SOFT_VOL_CTRL] = 0x0009,
+       [RT5625_DAC_CLK_CTRL1] = 0x3075,
+       [RT5625_DAC_CLK_CTRL2] = 0x1010,
+       [RT5625_VDAC_CLK_CTRL1] = 0x3110,
+       [RT5625_PS_CTRL] = 0x0553,
+       [RT5625_VENDOR_ID1] = 0x10ec,
+       [RT5625_VENDOR_ID2] = 0x5c02,
 };
 
-
-Voice_DSP_Reg VODSP_AEC_Init_Value[]=
-{
+rt5625_dsp_reg rt5625_dsp_init[] = {
        {0x232C, 0x0025},
        {0x230B, 0x0001},
        {0x2308, 0x007F},
@@ -168,13 +155,13 @@ Voice_DSP_Reg VODSP_AEC_Init_Value[]=
        {0x2304, 0x00FA},
        {0x2305, 0x0500},
        {0x2306, 0x4000},
-       {0x230D, 0x0900},
+       {0x230D, 0x0300},
        {0x230E, 0x0280},
        {0x2312, 0x00B1},
        {0x2314, 0xC000},
        {0x2316, 0x0041},
-       {0x2317, 0x2200},
-       {0x2318, 0x0C00},
+       {0x2317, 0x2800},
+       {0x2318, 0x0800},
        {0x231D, 0x0050},
        {0x231F, 0x4000},
        {0x2330, 0x0008},
@@ -193,1246 +180,2127 @@ Voice_DSP_Reg VODSP_AEC_Init_Value[]=
        {0x22D4, 0x2800},
        {0x22D5, 0x3000},
        {0x2399, 0x2800},
-       {0x230C, 0x0000},       //to enable VODSP AEC function
+       {0x230C, 0x0000},       
 };
-
-
-#define SET_VODSP_REG_INIT_NUM ARRAY_SIZE(VODSP_AEC_Init_Value)
-static struct snd_soc_device *rt5625_socdev;
-
-static inline unsigned int rt5625_read_reg_cache(struct snd_soc_codec *codec, 
-       unsigned int reg)
-{
-       u16 *cache = codec->reg_cache;
-
-       if (reg > 0x7e)
+#define RT5625_DSP_INIT_NUM ARRAY_SIZE(rt5625_dsp_init)
+
+static int rt5625_volatile_register(
+       struct snd_soc_codec *codec, unsigned int reg)
+{
+       switch (reg) {
+       case RT5625_RESET:
+       case RT5625_PD_CTRL:
+       case RT5625_GPIO_STATUS:
+       case RT5625_OTC_STATUS:
+       case RT5625_PRIV_DATA:
+       case RT5625_EQ_CTRL:
+       case RT5625_DSP_DATA:
+       case RT5625_DSP_CMD:
+       case RT5625_VENDOR_ID1:
+       case RT5625_VENDOR_ID2:
+               return 1;
+       default:
                return 0;
-       return cache[reg / 2];
+       }
 }
 
-
-static unsigned int rt5625_read_hw_reg(struct snd_soc_codec *codec, unsigned int reg) 
-{
-       u8 data[2] = {0};
-       unsigned int value = 0x0;
-       
-       data[0] = reg;
-       
-       i2c_master_reg8_recv(codec->control_data,reg,data,2,100 * 1000);        
-                     
-       value = (data[0]<<8) | data[1];
-
-       DBG(KERN_INFO "rt5625_read ok, reg = %x, value = %x\n", reg, value);
-
-       return value;   
+static int rt5625_readable_register(
+       struct snd_soc_codec *codec, unsigned int reg)
+{
+       switch (reg) {
+       case RT5625_RESET:
+       case RT5625_SPK_OUT_VOL:
+       case RT5625_HP_OUT_VOL:
+       case RT5625_AUX_OUT_VOL:
+       case RT5625_PHONEIN_VOL:
+       case RT5625_LINE_IN_VOL:
+       case RT5625_DAC_VOL:
+       case RT5625_MIC_VOL:
+       case RT5625_DAC_MIC_CTRL:
+       case RT5625_ADC_REC_GAIN:
+       case RT5625_ADC_REC_MIXER:
+       case RT5625_VDAC_OUT_VOL:
+       case RT5625_VODSP_PDM_CTL:
+       case RT5625_OUTMIX_CTRL:
+       case RT5625_VODSP_CTL:
+       case RT5625_MIC_CTRL:
+       case RT5625_DMIC_CTRL:
+       case RT5625_PD_CTRL:
+       case RT5625_F_DAC_ADC_VDAC:
+       case RT5625_SDP_CTRL:
+       case RT5625_EXT_SDP_CTRL:
+       case RT5625_PWR_ADD1:
+       case RT5625_PWR_ADD2:
+       case RT5625_PWR_ADD3:
+       case RT5625_GEN_CTRL1:
+       case RT5625_GEN_CTRL2:
+       case RT5625_PLL_CTRL:
+       case RT5625_PLL2_CTRL:
+       case RT5625_LDO_CTRL:
+       case RT5625_GPIO_CONFIG:
+       case RT5625_GPIO_POLAR:
+       case RT5625_GPIO_STICKY:
+       case RT5625_GPIO_WAKEUP:
+       case RT5625_GPIO_STATUS:
+       case RT5625_GPIO_SHARING:
+       case RT5625_OTC_STATUS:
+       case RT5625_SOFT_VOL_CTRL:
+       case RT5625_GPIO_OUT_CTRL:
+       case RT5625_MISC_CTRL:
+       case RT5625_DAC_CLK_CTRL1:
+       case RT5625_DAC_CLK_CTRL2:
+       case RT5625_VDAC_CLK_CTRL1:
+       case RT5625_PS_CTRL:
+       case RT5625_PRIV_INDEX:
+       case RT5625_PRIV_DATA:
+       case RT5625_EQ_CTRL:
+       case RT5625_DSP_ADDR:
+       case RT5625_DSP_DATA:
+       case RT5625_DSP_CMD:
+       case RT5625_VENDOR_ID1:
+       case RT5625_VENDOR_ID2:
+               return 1;
+       default:
+               return 0;
+       }
 }
 
-
-static unsigned int rt5625_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int rt5625_read(struct snd_soc_codec *codec,
+                               unsigned int reg)
 {
-       if ((reg == 0x80)
-               || (reg == 0x82)
-               || (reg == 0x84))
-               return (reg == 0x80) ? reg80 : ((reg == 0x82) ? reg82 : reg84);
-       
-               return rt5625_read_hw_reg(codec, reg);
-}
+       unsigned int val;
 
-
-static inline void rt5625_write_reg_cache(struct snd_soc_codec *codec,
-       unsigned int reg, unsigned int value)
-{
-       u16 *cache = codec->reg_cache;
-       if (reg > 0x7E)
-               return;
-       cache[reg / 2] = value;
+       val = codec->hw_read(codec, reg);
+       return val;
 }
 
 static int rt5625_write(struct snd_soc_codec *codec, unsigned int reg,
        unsigned int value)
 {
+       unsigned int val;
        u8 data[3];
-       unsigned int *regvalue = NULL;
 
        data[0] = reg;
-       data[1] = (value & 0xff00) >> 8;
-       data[2] = value & 0x00ff;
+       data[1] = (value >> 8) & 0xff;
+       data[2] = value & 0xff;
        
-       if ((reg == 0x80)
-               || (reg == 0x82)
-               || (reg == 0x84))
-       {               
-               regvalue = ((reg == 0x80) ? &reg80 : ((reg == 0x82) ? &reg82 : &reg84));
-               *regvalue = value;
-               DBG("rt5625_write ok, reg = %x, value = %x\n", reg, value);
-               return 0;
-       }
-       rt5625_write_reg_cache(codec, reg, value);
-
-       if (codec->hw_write(codec->control_data, data, 3) == 3)
-       {
-               DBG("rt5625_write ok, reg = %x, value = %x\n", reg, value);
-               return 0;
-       }
-       else 
-       {
-               printk("rt5625_write fail\n");
-               return -EIO;
-       }
+       val = codec->hw_write(codec->control_data, data, 3);
+       return val;
 }
 
-int rt5625_write_mask(struct snd_soc_codec *codec, unsigned int reg,unsigned int value,unsigned int mask)
+static int rt5625_reset(struct snd_soc_codec *codec)
 {
-       
-       unsigned char RetVal=0;
-       unsigned  int CodecData;
-
-       DBG("rt5625_write_mask ok, reg = %x, value = %x ,mask= %x\n", reg, value,mask);
+       return snd_soc_write(codec, RT5625_RESET, 0);
+}
 
-       if(!mask)
-               return 0; 
+/**
+ * rt5625_index_write - Write private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ * @value: Private register Data.
+ *
+ * Modify private register for advanced setting. It can be written through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_index_write(struct snd_soc_codec *codec,
+               unsigned int reg, unsigned int value)
+{
+       int ret;
 
-       if(mask!=0xffff)
-        {
-               CodecData=rt5625_read(codec,reg);               
-               CodecData&=~mask;
-               CodecData|=(value&mask);
-               RetVal=rt5625_write(codec,reg,CodecData);
-        }              
-       else
-       {
-               RetVal=rt5625_write(codec,reg,value);
+       ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+               goto err;
        }
+       ret = snd_soc_write(codec, RT5625_PRIV_DATA, value);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+               goto err;
+       }
+       return 0;
 
-       return RetVal;
+err:
+       return ret;
 }
 
-
-void rt5625_write_index(struct snd_soc_codec *codec, unsigned int reg,
-       unsigned int value)
+/**
+ * rt5625_index_read - Read private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ *
+ * Read advanced setting from private register. It can be read through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns private register value or negative error code.
+ */
+static unsigned int rt5625_index_read(
+       struct snd_soc_codec *codec, unsigned int reg)
 {
-       
-       rt5625_write(codec,0x6a,reg);
-       rt5625_write(codec,0x6c,value); 
-}
+       int ret;
 
-unsigned int rt5625_read_index(struct snd_soc_codec *codec, unsigned int reg)
-{
-       unsigned int value = 0x0;
-       rt5625_write(codec,0x6a,reg);
-       value=rt5625_read(codec,0x6c);  
-       
-       return value;
+       ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+               return ret;
+       }
+       return snd_soc_read(codec, RT5625_PRIV_DATA);
 }
 
-void rt5625_write_index_mask(struct snd_soc_codec *codec, unsigned int reg,unsigned int value,unsigned int mask)
+/**
+ * rt5625_index_update_bits - update private register bits
+ * @codec: Audio codec
+ * @reg: Private register index.
+ * @mask: Register mask
+ * @value: New value
+ *
+ * Writes new register value.
+ *
+ * Returns 1 for change, 0 for no change, or negative error code.
+ */
+static int rt5625_index_update_bits(struct snd_soc_codec *codec,
+       unsigned int reg, unsigned int mask, unsigned int value)
 {
-       
-//     unsigned char RetVal=0;
-       unsigned  int CodecData;
-
-       DBG("rt5625_write_index_mask ok, reg = %x, value = %x ,mask= %x\n", reg, value,mask);
+       unsigned int old, new;
+       int change, ret;
 
-       if(!mask)
-               return; 
-
-       if(mask!=0xffff)
-        {
-               CodecData=rt5625_read_index(codec,reg);         
-               CodecData&=~mask;
-               CodecData|=(value&mask);
-               rt5625_write_index(codec,reg,CodecData);
-        }              
-       else
-       {
-               rt5625_write_index(codec,reg,value);
+       ret = rt5625_index_read(codec, reg);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to read private reg: %d\n", ret);
+               goto err;
        }
-}
 
-//#define rt5625_write_mask(c, reg, value, mask) snd_soc_update_bits(c, reg, mask, value)
+       old = ret;
+       new = (old & ~mask) | (value & mask);
+       change = old != new;
+       if (change) {
+               ret = rt5625_index_write(codec, reg, new);
+               if (ret < 0) {
+                       dev_err(codec->dev,
+                               "Failed to write private reg: %d\n", ret);
+                       goto err;
+               }
+       }
+       return change;
 
-#define rt5625_reset(c) rt5625_write(c, RT5625_RESET, 0)
+err:
+       return ret;
+}
 
-/*read/write dsp reg*/
-static int rt5625_wait_vodsp_i2c_done(struct snd_soc_codec *codec)
+/**
+ * rt5625_dsp_done - Wait until DSP is ready.
+ * @codec: SoC Audio Codec device.
+ *
+ * To check voice DSP status and confirm it's ready for next work.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_dsp_done(struct snd_soc_codec *codec)
 {
-       unsigned int checkcount = 0, vodsp_data;
+       unsigned int count = 0, dsp_val;
 
-       vodsp_data = rt5625_read(codec, RT5625_VODSP_REG_CMD);
-       while(vodsp_data & VODSP_BUSY)
-       {
-               if(checkcount > 10)
+       dsp_val = snd_soc_read(codec, RT5625_DSP_CMD);
+       while(dsp_val & RT5625_DSP_BUSY_MASK) {
+               if(count > 10)
                        return -EBUSY;
-               vodsp_data = rt5625_read(codec, RT5625_VODSP_REG_CMD);
-               checkcount ++;          
+               dsp_val = snd_soc_read(codec, RT5625_DSP_CMD);
+               count ++;               
        }
+
        return 0;
 }
 
-static int rt5625_write_vodsp_reg(struct snd_soc_codec *codec, unsigned int vodspreg, unsigned int value)
+/**
+ * rt5625_dsp_write - Write DSP register.
+ * @codec: SoC audio codec device.
+ * @reg: DSP register index.
+ * @value: DSP register Data.
+ *
+ * Modify voice DSP register for sound effect. The DSP can be controlled
+ * through DSP addr (0x70), data (0x72) and cmd (0x74) register. It has
+ * to wait until the DSP is ready.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_dsp_write(struct snd_soc_codec *codec,
+               unsigned int reg, unsigned int value)
 {
-       int ret = 0;
-
-       if(ret != rt5625_wait_vodsp_i2c_done(codec))
-               return -EBUSY;
+       int ret;
 
-       rt5625_write(codec, RT5625_VODSP_REG_ADDR, vodspreg);
-       rt5625_write(codec, RT5625_VODSP_REG_DATA, value);
-       rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_WRITE_ENABLE | VODSP_CMD_MW);
+       ret = rt5625_dsp_done(codec);
+       if (ret < 0) {
+               dev_err(codec->dev, "DSP is busy: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_DATA, value);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_CMD,
+               RT5625_DSP_W_EN | RT5625_DSP_CMD_MW);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+               goto err;
+       }
        mdelay(10);
-       return ret;
+       return 0;
        
+err:
+       return ret;
 }
 
-static unsigned int rt5625_read_vodsp_reg(struct snd_soc_codec *codec, unsigned int vodspreg)
+/**
+ * rt5625_dsp_read - Read DSP register.
+ * @codec: SoC audio codec device.
+ * @reg: DSP register index.
+ *
+ * Read DSP setting value from voice DSP. The DSP can be controlled
+ * through DSP addr (0x70), data (0x72) and cmd (0x74) register. Each
+ * command has to wait until the DSP is ready.
+ *
+ * Returns DSP register value or negative error code.
+ */
+static unsigned int rt5625_dsp_read(
+       struct snd_soc_codec *codec, unsigned int reg)
 {
+       unsigned int val_h, val_l;
        int ret = 0;
-       unsigned int nDataH, nDataL;
-       unsigned int value;
 
-       if(ret != rt5625_wait_vodsp_i2c_done(codec))
-               return -EBUSY;
-       
-       rt5625_write(codec, RT5625_VODSP_REG_ADDR, vodspreg);
-       rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_MR);
+       ret = rt5625_dsp_done(codec);
+       if (ret < 0) {
+               dev_err(codec->dev, "DSP is busy: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_CMD,
+               RT5625_DSP_R_EN | RT5625_DSP_CMD_MR);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+               goto err;
+       }
+
+       /* Read DSP high byte data */
+       ret = rt5625_dsp_done(codec);
+       if (ret < 0) {
+               dev_err(codec->dev, "DSP is busy: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x26);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_CMD,
+               RT5625_DSP_R_EN | RT5625_DSP_CMD_RR);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+               goto err;
+       }
+       ret = rt5625_dsp_done(codec);
+       if (ret < 0) {
+               dev_err(codec->dev, "DSP is busy: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_read(codec, RT5625_DSP_DATA);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
+               goto err;
+       }
+       val_h = ret;
 
-       if (ret != rt5625_wait_vodsp_i2c_done(codec))
-               return -EBUSY;
-       rt5625_write(codec, RT5625_VODSP_REG_ADDR, 0x26);
-       rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_RR);
+       /* Read DSP low byte data */
+       ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x25);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_write(codec, RT5625_DSP_CMD,
+               RT5625_DSP_R_EN | RT5625_DSP_CMD_RR);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+               goto err;
+       }
+       ret = rt5625_dsp_done(codec);
+       if (ret < 0) {
+               dev_err(codec->dev, "DSP is busy: %d\n", ret);
+               goto err;
+       }
+       ret = snd_soc_read(codec, RT5625_DSP_DATA);
+       if (ret < 0) {
+               dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
+               goto err;
+       }
+       val_l = ret;
 
-       if(ret != rt5625_wait_vodsp_i2c_done(codec))
-               return -EBUSY;
-       nDataH = rt5625_read(codec, RT5625_VODSP_REG_DATA);
-       rt5625_write(codec, RT5625_VODSP_REG_ADDR, 0x25);
-       rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_RR);
+       return ((val_h & 0xff) << 8) |(val_l & 0xff);
 
-       if(ret != rt5625_wait_vodsp_i2c_done(codec))
-               return -EBUSY;
-       nDataL = rt5625_read(codec, RT5625_VODSP_REG_DATA);
-       value = ((nDataH & 0xff) << 8) |(nDataL & 0xff);
-       DBG("%s vodspreg=0x%x, value=0x%x\n", __func__, vodspreg, value);
-       return value;
+err:
+       return ret;
 }
 
-static int rt5625_reg_init(struct snd_soc_codec *codec)
-{
-       int i;
+static const char *rt5625_spk_ctr_sel[] = {"Disable", "Enable"};
 
-       for (i = 0; i < RT5625_INIT_REG_NUM; i++)
-               rt5625_write(codec, rt5625_init_list[i].reg_index, rt5625_init_list[i].reg_value);
+/* ADCR function select */
+static const char *adcr_fun_sel[] = {
+       "Stereo ADC", "Voice ADC", "VoDSP", "PDM Slave"};
 
-       return 0;
-}
+static const struct soc_enum adcr_fun_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCR_F_SFT,
+                               ARRAY_SIZE(adcr_fun_sel), adcr_fun_sel);
 
-//*************************************************************************************************
-//*************************************************************************************************
-#if (RT5625_EQ_FUNC_ENA==1)    
-//eq function
-static void rt5625_update_eqmode(struct snd_soc_codec *codec, int mode)
-{
-       u16 HwEqIndex=0;
+/* ADCL function select */
+static const char *adcl_fun_sel[] = {"Stereo ADC", "VoDSP"};
 
-       if(mode==NORMAL)
-       {
-               /*clear EQ parameter*/
-               for(HwEqIndex=0;HwEqIndex<=0x0C;HwEqIndex++)
-               {
-                       rt5625_write_index(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]);
-               }
-               
-               rt5625_write_mask(codec, 0x6e,0x0,EN_HW_EQ_BLK | EN_HW_EQ_HPF | EN_HW_EQ_BP3 | EN_HW_EQ_BP2 | EN_HW_EQ_BP1 | EN_HW_EQ_LPF);             /*disable EQ block*/
-       }
-       else
-       {               
-               /*Fill EQ parameter*/
-               for(HwEqIndex=0;HwEqIndex<=0x0C;HwEqIndex++)
-               {
-                       rt5625_write_index(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]); 
-               }               
+static const struct soc_enum adcl_fun_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCL_F_SFT,
+                       ARRAY_SIZE(adcl_fun_sel), adcl_fun_sel);
 
-               //enable EQ block
-               rt5625_write_mask(codec, 0x6e,HwEq_Preset[mode].HwEQCtrl,EN_HW_EQ_BLK | EN_HW_EQ_HPF | EN_HW_EQ_BP3 | EN_HW_EQ_BP2 | EN_HW_EQ_BP1 | EN_HW_EQ_LPF);              
-               
-               //update EQ parameter
-               rt5625_write_mask(codec, 0x6e,0x0080,0x0080);
-       }
-}
+/* Voice DSP */
+static const char *rt5625_aec_fun[] = {"Disable", "Enable"};
 
+static const SOC_ENUM_SINGLE_DECL(rt5625_aec_fun_enum, 0, 0, rt5625_aec_fun);
 
-static int rt5625_eq_sel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
-       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       u16 Virtual_reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
-       int rt5625_mode=((Virtual_reg)&0xf000)>>12;
-       
-       if ( rt5625_mode == ucontrol->value.integer.value[0])
-               return 0;
+static const char *rt5625_dsp_lrck[] = {"8KHz", "16KHz"};
 
-       rt5625_update_eqmode(codec, ucontrol->value.enumerated.item[0]);
+static const SOC_ENUM_SINGLE_DECL(rt5625_dsp_lrck_enum,
+       RT5625_VODSP_CTL, RT5625_DSP_LRCK_SFT, rt5625_dsp_lrck);
 
-       Virtual_reg &= 0x0fff;
-       Virtual_reg |= (ucontrol->value.integer.value[0])<<12;
-       rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, Virtual_reg);            
-       
-       return 0;
-}
-#endif
-//*************************************************************************************************
-//*************************************************************************************************
-static const char *rt5625_aec_path_sel[] = {"aec func disable","aec func for pcm in/out",
-                                            "aec func for iis in/out","aec func for analog in/out"};           /*0*/                   
-static const char *rt5625_spk_out_sel[] = {"Class AB", "Class D"};                                     /*1*/
-static const char *rt5625_spk_l_source_sel[] = {"LPRN", "LPRP", "LPLN", "MM"};         /*2*/   
-static const char *rt5625_spkmux_source_sel[] = {"VMID", "HP Mixer", 
-                                                       "SPK Mixer", "Mono Mixer"};                                                     /*3*/
-static const char *rt5625_hplmux_source_sel[] = {"VMID","HPL Mixer"};                          /*4*/
-static const char *rt5625_hprmux_source_sel[] = {"VMID","HPR Mixer"};                          /*5*/
-static const char *rt5625_auxmux_source_sel[] = {"VMID", "HP Mixer", 
-                                                       "SPK Mixer", "Mono Mixer"};                                                     /*6*/
-static const char *rt5625_spkamp_ratio_sel[] = {"2.25 Vdd", "2.00 Vdd",
-                                       "1.75 Vdd", "1.50 Vdd", "1.25 Vdd", "1.00 Vdd"};                                /*7*/
-static const char *rt5625_mic1_boost_sel[] = {"Bypass", "+20db", "+30db", "+40db"};    /*8*/
-static const char *rt5625_mic2_boost_sel[] = {"Bypass", "+20db", "+30db", "+40db"};    /*9*/
-static const char *rt5625_dmic_boost_sel[] = {"Bypass", "+6db", "+12db", "+18db", 
-                                       "+24db", "+30db", "+36db", "+42db"};                                            /*10*/
-static const char *rt5625_adcr_func_sel[] = {"Stereo ADC", "Voice ADC", 
-                                       "VoDSP Interface", "PDM Slave Interface"};                                   /*11*/
-#if (RT5625_EQ_FUNC_ENA==1)                                    
-static const char *rt5625_eq_sel[] = {"NORMAL", "CLUB","DANCE", "LIVE","POP",                  /*12*/
-                                       "ROCK", "OPPO", "TREBLE", "BASS"};                                      
-#endif
+static const char *rt5625_bp_ctrl[] = {"Bypass", "Normal"};
 
-static const struct soc_enum rt5625_enum[] = {
-
-SOC_ENUM_SINGLE(VIRTUAL_REG_FOR_MISC_FUNC, 0, 4, rt5625_aec_path_sel),         /*0*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 13, 2, rt5625_spk_out_sel),          /*1*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 14, 4, rt5625_spk_l_source_sel),     /*2*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 10, 4, rt5625_spkmux_source_sel),/*3*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 9, 2, rt5625_hplmux_source_sel),     /*4*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 8, 2, rt5625_hprmux_source_sel),/*5*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 6, 4, rt5625_auxmux_source_sel),/*6*/
-SOC_ENUM_SINGLE(RT5625_GEN_CTRL_REG1, 1, 6, rt5625_spkamp_ratio_sel),          /*7*/
-SOC_ENUM_SINGLE(RT5625_MIC_CTRL, 10, 4,  rt5625_mic1_boost_sel),                       /*8*/
-SOC_ENUM_SINGLE(RT5625_MIC_CTRL, 8, 4, rt5625_mic2_boost_sel),                         /*9*/
-SOC_ENUM_SINGLE(RT5625_DMIC_CTRL, 0, 8, rt5625_dmic_boost_sel),                                /*10*/
-SOC_ENUM_SINGLE(RT5625_DAC_ADC_VODAC_FUN_SEL, 4, 4, rt5625_adcr_func_sel), /*11*/
-#if (RT5625_EQ_FUNC_ENA==1)
-SOC_ENUM_SINGLE(VIRTUAL_REG_FOR_MISC_FUNC, 12, 9, rt5625_eq_sel),    /*EQ mode select mode 12*/
-#endif
-};
+static const SOC_ENUM_SINGLE_DECL(rt5625_bp_ctrl_enum,
+       RT5625_VODSP_CTL, RT5625_DSP_BP_SFT, rt5625_bp_ctrl);
+
+static const char *rt5625_pd_ctrl[] = {"Power down", "Normal"};
 
+static const SOC_ENUM_SINGLE_DECL(rt5625_pd_ctrl_enum,
+       RT5625_VODSP_CTL, RT5625_DSP_PD_SFT, rt5625_pd_ctrl);
 
+static const char *rt5625_rst_ctrl[] = {"Reset", "Normal"};
 
-//*****************************************************************************
-//function:Enable the Voice PCM interface Path
-//*****************************************************************************
-static int ConfigPcmVoicePath(struct snd_soc_codec *codec,unsigned int bEnableVoicePath,unsigned int mode)
+static const SOC_ENUM_SINGLE_DECL(rt5625_rst_ctrl_enum,
+       RT5625_VODSP_CTL, RT5625_DSP_RST_SFT, rt5625_rst_ctrl);
+/* Speaker */
+static const char *rt5625_spk_out[] = {"Class AB", "Class D"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_spk_out_enum,
+       RT5625_OUTMIX_CTRL, RT5625_SPK_T_SFT, rt5625_spk_out);
+
+static const char *rt5625_spkl_src[] = {"LPRN", "LPRP", "LPLN", "MM"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_spkl_src_enum,
+       RT5625_OUTMIX_CTRL, RT5625_SPKN_S_SFT, rt5625_spkl_src);
+
+static const char *rt5625_spkamp_ratio[] = {"2.25 Vdd", "2.00 Vdd",
+               "1.75 Vdd", "1.50 Vdd", "1.25 Vdd", "1.00 Vdd"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_spkamp_ratio_enum,
+       RT5625_GEN_CTRL1, RT5625_SPK_R_SFT, rt5625_spkamp_ratio);
+
+static const char *rt5625_Pin_mode[] = {"IRQ Out", "GPIO enable", "Reserved", "VoDSP bypass"};  
+static const char *rt5625_Pin_configuration[] = {"Output", "Input"};
+static const char *rt5625_Pin_level[] = {"Low", "High"};
+
+/* Output/Input Mode */
+//static const char *rt5625_auxout_mode[] = {"Differential", "Single ended"};
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_auxout_mode_enum,
+//     RT5625_OUTMIX_CTRL, RT5625_AUXOUT_MODE_SFT, rt5625_auxout_mode);
+
+//static const char *rt5625_input_mode[] = {"Single ended", "Differential"};
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_phone_mode_enum,
+//     RT5625_PHONEIN_VOL, RT5625_PHO_DIFF_SFT, rt5625_input_mode);
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_mic1_mode_enum,
+//     RT5625_MIC_VOL, RT5625_MIC1_DIFF_SFT, rt5625_input_mode);
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_mic2_mode_enum,
+//     RT5625_MIC_VOL, RT5625_MIC2_DIFF_SFT, rt5625_input_mode);
+
+static const struct soc_enum rt5625_gpio2_enum[] = {
+SOC_ENUM_SINGLE(RT5625_GPIO_SHARING, 0, 4, rt5625_Pin_mode),         /*0*/
+SOC_ENUM_SINGLE(RT5625_GPIO_CONFIG, 2, 2, rt5625_Pin_configuration),/*1*/
+SOC_ENUM_SINGLE(RT5625_GPIO_OUT_CTRL, 2, 2, rt5625_Pin_level),        /*2*/
+};
+
+static int rt5625_adcr_fun_sel_put(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
 {
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       unsigned int val, mask, bitmask;
 
-       if(bEnableVoicePath)
-        {
-                       //Power on DAC reference
-                       rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD1,PWR_DAC_REF|PWR_VOICE_DF2SE,PWR_DAC_REF|PWR_VOICE_DF2SE);
-                       //Power on Voice DAC/ADC 
-                       rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD2,PWR_VOICE_CLOCK,PWR_VOICE_CLOCK);
-                       //routing voice to HPMixer
-                       rt5625_write_mask(codec,RT5625_VOICE_DAC_OUT_VOL,0,M_V_DAC_TO_HP_MIXER);
-                                       
-               switch(mode)            
-               {
-                       case PCM_SLAVE_MODE_B:  //8kHz sampling rate,16 bits PCM mode and Slave mode,PCM mode is B,MCLK=24.576MHz from Oscillator.
-                                                               //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08C00000,PSKEY_FORMAT=0x0060                         
-
-                               //Enable GPIO 1,3,4,5 to voice interface
-                               //Set I2S to Slave mode
-                               //Voice I2S SYSCLK Source select Main SYSCLK
-                               //Set voice I2S VBCLK Polarity to Invert
-                               //Set Data length to 16 bit
-                               //set Data Fomrat to PCM mode B
-                               //the register 0x36 value's should is 0xC083
-                               rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0xC083);
-
-                               //Set LRCK voice select divide 32
-                               //set voice blck select divide 6 and 8 
-                               //voice filter clock divide 3 and 16
-                               //the register 0x64 value's should is 0x5524
-                               rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-               
-                               break;
+       for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+               ;
+       if (ucontrol->value.enumerated.item[0] > e->max - 1)
+               return -EINVAL;
+       val = ucontrol->value.enumerated.item[0] << e->shift_l;
+       mask = (bitmask - 1) << e->shift_l;
+
+       snd_soc_update_bits(codec, RT5625_PD_CTRL,
+               RT5625_PWR_PR0, RT5625_PWR_PR0);
+       if ((rt5625->app_bmp & RT5625_3G_MASK) &&
+               rt5625->vodsp_fun == RT5625_AEC_EN) {
+               snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM);
+       } else if (rt5625->app_bmp & RT5625_VOIP_MASK &&
+               rt5625->vodsp_fun == RT5625_AEC_EN) {
+               snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM);
+       } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+               snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_VADC);
+       } else {
+               snd_soc_update_bits(codec, e->reg, mask, val);
+       }
+       snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0);
 
-                       case PCM_SLAVE_MODE_A:  //8kHz sampling rate,16 bits PCM and Slave mode,PCM mode is A,MCLK=24.576MHz from Oscillator.
-                                                               //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08C00004,PSKEY_FORMAT=0x0060                         
-
-                               //Enable GPIO 1,3,4,5 to voice interface
-                               //Set I2S to Slave mode
-                               //Voice I2S SYSCLK Source select Main SYSCLK
-                               //Set voice i2s VBCLK Polarity to Invert
-                               //Set Data length to 16 bit
-                               //set Data Fomrat to PCM mode A
-                               //the register 0x36 value's should is 0xC082
-                               rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0xC082);
-
-                               //Set LRCK voice select divide 64
-                               //set voice blck select divide 6 and 8 
-                               //voice filter clock divide 3 and 16
-                               //the register 0x64 value's should is 0x5524
-                               rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-               
-                               break;
+       return 0;
+}
 
-                       case PCM_MASTER_MODE_B: //8kHz sampling rate,16 bits PCM and Master mode,PCM mode is B,Clock from PLL OUT
-                                                               //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08000002,PSKEY_FORMAT=0x0060 
-
-                               //Enable GPIO 1,3,4,5 to voice interface
-                               //Set I2S to master mode
-                               //Set voice i2s VBCLK Polarity to Invert
-                               //Set Data length to 16 bit
-                               //set Data Fomrat to PCM mode B
-                               //the register 0x36 value's should is 0x8083
-                               rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0x8083);
-
-                               //Set LRCK voice select divide 64
-                               //set voice blck select divide 6 and 8 
-                               //voice filter clock divide 3 and 16
-                               //the register 0x64 value's should is 0x5524
-                               rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-               
-                               break;
+static int rt5625_adcl_fun_sel_put(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       unsigned int val, mask, bitmask;
 
-                       default:
-                               //do nothing            
-                               break;
+       for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+               ;
+       if (ucontrol->value.enumerated.item[0] > e->max - 1)
+               return -EINVAL;
+       val = ucontrol->value.enumerated.item[0] << e->shift_l;
+       mask = (bitmask - 1) << e->shift_l;
+
+       snd_soc_update_bits(codec, RT5625_PD_CTRL,
+               RT5625_PWR_PR0, RT5625_PWR_PR0);
+       if ((rt5625->app_bmp & RT5625_3G_MASK) &&
+               rt5625->vodsp_fun == RT5625_AEC_EN) {
+               snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCL_F_DSP);
+       } else {
+               snd_soc_update_bits(codec, e->reg, mask, val);
+       }
+       snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0);
 
-                       }
-               }
-               else
-               {       
-                       //Power down Voice Different to sing-end power
-                       rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD1,0,PWR_VOICE_DF2SE);
-                       //Power down Voice DAC/ADC 
-                       rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD2,0,PWR_VOICE_CLOCK);
-                       //Disable Voice PCM interface   
-                       rt5625_write_mask(codec,RT5625_EXTEND_SDP_CTRL,0,EXT_I2S_FUNC_ENABLE);                  
-               }
-       
        return 0;
 }
 
-static int init_vodsp_aec(struct snd_soc_codec *codec)
+static int rt5625_init_vodsp_aec(struct snd_soc_codec *codec)
 {
-       int i;
-       int ret = 0;
+       int i, ret = 0;
 
        /*disable LDO power*/
-       rt5625_write_mask(codec, RT5625_LDO_CTRL,0,LDO_ENABLE);
+       snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+               RT5625_LDO_MASK, RT5625_LDO_DIS);
        mdelay(20);     
-       rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_NO_PD_MODE_ENA,VODSP_NO_PD_MODE_ENA);
+       snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+               RT5625_DSP_PD_MASK, RT5625_DSP_PD_NOR);
        /*enable LDO power and set output voltage to 1.2V*/
-       rt5625_write_mask(codec, RT5625_LDO_CTRL,LDO_ENABLE|LDO_OUT_VOL_CTRL_1_20V,LDO_ENABLE|LDO_OUT_VOL_CTRL_MASK);
+       snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+               RT5625_LDO_MASK | RT5625_LDO_VC_MASK,
+               RT5625_LDO_EN | RT5625_LDO_VC_1_20V);
        mdelay(20);
        /*enable power of VODSP I2C interface*/ 
-       rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);
+       snd_soc_update_bits(codec, RT5625_PWR_ADD3, RT5625_P_DSP_IF |
+               RT5625_P_DSP_I2C, RT5625_P_DSP_IF | RT5625_P_DSP_I2C);
        mdelay(1);
-       rt5625_write_mask(codec, RT5625_VODSP_CTL,0,VODSP_NO_RST_MODE_ENA);     /*Reset VODSP*/
+       /*Reset VODSP*/
+       snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+               RT5625_DSP_RST_MASK, RT5625_DSP_RST_EN);
        mdelay(1);
-       rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_NO_RST_MODE_ENA,VODSP_NO_RST_MODE_ENA); /*set VODSP to non-reset status*/               
+       /*set VODSP to non-reset status*/
+       snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+               RT5625_DSP_RST_MASK, RT5625_DSP_RST_NOR);
        mdelay(20);
 
        /*initize AEC paramter*/
-       for(i = 0; i < SET_VODSP_REG_INIT_NUM; i++)
-       {
-               ret = rt5625_write_vodsp_reg(codec, VODSP_AEC_Init_Value[i].VoiceDSPIndex,VODSP_AEC_Init_Value[i].VoiceDSPValue);
+       for(i = 0; i < RT5625_DSP_INIT_NUM; i++) {
+               ret = rt5625_dsp_write(codec, rt5625_dsp_init[i].index,
+                                       rt5625_dsp_init[i].value);
                if(ret)
                        return -EIO;
        }               
-
-       schedule_timeout_uninterruptible(msecs_to_jiffies(10)); 
+       mdelay(10);     
+       //printk("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C));
 
        return 0;
 }
 
-//***********************************************************************************************
-//function:Enable/Disable the vodsp interface Path
-//For system clock only suport specific clock,realtek suggest customer to use 24.576Mhz or 22.5792Mhz
-//clock fro MCLK(MCLK=48k*512 or 44.1k*512Mhz)
-//***********************************************************************************************
-static int set_vodsp_aec_path(struct snd_soc_codec *codec, unsigned int mode)
+static int rt5625_aec_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-               switch(mode)
-               {
-
-                       case PCM_IN_PCM_OUT:
-                               //set PCM format
-                               ConfigPcmVoicePath(codec,1,PCM_MASTER_MODE_B);
-                               //set AEC path
-                               rt5625_write_mask(codec, 0x26,0x0300,0x0300);
-                               rt5625_write_mask(codec, RT5625_VODSP_PDM_CTL,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_VOICE|VOICE_PCM_S_SEL_AEC_TXDP
-                                                                                                                        ,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|VOICE_PCM_S_SEL_MASK);
-                               rt5625_write_mask(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|VODAC_SOUR_SEL_VODSP_TXDC
-                                                                                                                                       ,ADCR_FUNC_SEL_MASK|VODAC_SOUR_SEL_MASK);
-                               rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_LRCK_SEL_8K,VODSP_LRCK_SEL_MASK);                                               
-                               rt5625_write_mask(codec, 0x26,0x0000,0x0300);
-                               //set input&output path and power
-                               rt5625_write_mask(codec, 0x3a,0x0c8f,0x0c8f);//power on related bit
-                               rt5625_write_mask(codec, 0x3c,0xa4cb,0xa4cb);//power on related bit
-                               rt5625_write_mask(codec, 0x3e,0x3302,0xf302);//power on related bit
-                                               
-                               rt5625_write(codec, 0x10, 0xee0f);//mute DAC to hpmixer
-                               rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
-                               rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
-                               rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
-                               rt5625_write(codec, 0x14, 0x7f3f);//Mic1->ADCMixer_R
-                               rt5625_write(codec, 0x18, 0xa010);//VoDAC to speakerMixer,0db
-                               rt5625_write(codec, 0x1c, 0x8808);//speaker source from speakermixer
-                                                       
-                               rt5625_write_mask(codec, 0x02,0x0000,0x8080);   //unmute speaker 
+       ucontrol->value.integer.value[0] = rt5625->vodsp_fun;
+       return 0;
+}
 
-                               break;
-                       
-                       
-                       case ANALOG_IN_ANALOG_OUT:      
-                               rt5625_write_mask(codec, 0x26,0x0300,0x0300);
-                               rt5625_write_mask(codec, RT5625_VODSP_PDM_CTL,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_ADCL|VOICE_PCM_S_SEL_AEC_TXDP
-                                                                                                                        ,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|VOICE_PCM_S_SEL_MASK);
-                               rt5625_write_mask(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|VODAC_SOUR_SEL_VODSP_TXDC|DAC_FUNC_SEL_VODSP_TXDP|ADCL_FUNC_SEL_VODSP
-                                                                                                                                       ,ADCR_FUNC_SEL_MASK|VODAC_SOUR_SEL_MASK|DAC_FUNC_SEL_MASK|ADCL_FUNC_SEL_MASK);
-                               rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_LRCK_SEL_16K,VODSP_LRCK_SEL_MASK);      
-                               rt5625_write_mask(codec, 0x26,0x0000,0x0300);
-                               //set input&output path and power
-                               rt5625_write_mask(codec, 0x3a,0xcc8f,0xcc8f);//power on related bit
-                               rt5625_write_mask(codec, 0x3c,0xa7cf,0xa7cf);//power on related bit
-                               rt5625_write_mask(codec, 0x3e,0xf312,0xf312);//power on related bit
-                               
-                               rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
-                               rt5625_write(codec, 0x08, 0xe800);//set phone in to differential mode
-                               rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
-                               rt5625_write(codec, 0x14, 0x773f);//Mic1->ADCMixer_R,phone in-->ADCMixer_L
-                               rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
-                               rt5625_write(codec, 0x1c, 0x88c8);//speaker from spkmixer,monoOut from monoMixer
-                               rt5625_write(codec, 0x18, 0xA010);//unmute VoDAC to spkmixer
-                               rt5625_write(codec, 0x10, 0xee0e);//unmute DAC to monoMixer     
-                               rt5625_write(codec, 0x62, 0x2222);
-                               rt5625_write(codec, 0x64, 0x3122);
-                               rt5625_write_mask(codec, 0x02,0x0000,0x8080);   //unmute speaker 
-                               rt5625_write_mask(codec, 0x06,0x0000,0x8080);   //unmute auxout 
-                               break;
 
-                       case DAC_IN_ADC_OUT:    
-                               rt5625_write_mask(codec, 0x26,0x0300,0x0300);
-                               rt5625_write_mask(codec,RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|DAC_FUNC_SEL_VODSP_TXDC
-                                                                                                                                       ,ADCR_FUNC_SEL_MASK|DAC_FUNC_SEL_MASK);
-                               rt5625_write_mask(codec,RT5625_VODSP_PDM_CTL,VODSP_SRC1_PWR|VODSP_SRC2_PWR|VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_SRC1|REC_S_SEL_SRC2,
-                                                                                                                        VODSP_SRC1_PWR|VODSP_SRC2_PWR|VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|REC_S_SEL_MASK);                                    
-                               rt5625_write_mask(codec,RT5625_VODSP_CTL,VODSP_LRCK_SEL_16K,VODSP_LRCK_SEL_MASK);
-                               rt5625_write_mask(codec, 0x26,0x0000,0x0300);
-                               //set input&output path and power       
-                               rt5625_write_mask(codec, 0x3a,0xcc0f,0xcc0f);//power on related bit
-                               rt5625_write_mask(codec, 0x3c,0xa7cb,0xa7cb);//power on related bit
-                               rt5625_write_mask(codec, 0x3e,0x3302,0x3302);//power on related bit
-                               
-                               rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
-                               rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
-                               rt5625_write(codec, 0x14, 0x7f3f);//Mic1->ADCMixer_R
-                               rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
-                               rt5625_write(codec, 0x1c, 0x8808);//speaker out from spkMixer
-                               rt5625_write(codec, 0x10, 0xee0d);//unmute DAC to spkMixer      
-                               rt5625_write(codec, 0x60, 0x3075);
-                               rt5625_write(codec, 0x62, 0x1010);                                      
-                               rt5625_write_mask(codec, 0x02,0x0000,0x8080);   //unmute speaker 
+static int rt5625_aec_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{ 
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-                               break;
+       if(ucontrol->value.integer.value[0] == rt5625->vodsp_fun)
+               return 0;
+       rt5625->vodsp_fun = ucontrol->value.integer.value[0];
 
-                       case VODSP_AEC_DISABLE:
-                       default:
-                               rt5625_write_mask(codec, 0x02,0x8080,0x8080);//mute speaker out
-                               rt5625_write_mask(codec, 0x06,0x8080,0x8080);//mute auxout              
-                               rt5625_write(codec, 0x22, 0x0500);//Mic boost 20db by default
-                               rt5625_write(codec, 0x14, 0x3f3f);//record from Mic1 by default
-                               rt5625_write(codec, 0x12, 0xD5D5);//ADC_Mixer_R boost 15 db by default
-                               rt5625_write(codec, 0x1c, 0x0748);//all output from HPmixer by default
-                               rt5625_write(codec, 0x10, 0xee03);//DAC to HPmixer by default
-                               rt5625_write(codec, 0x18, 0xe010);//mute VoDAC to mixer by default
-                               rt5625_write_mask(codec, 0x26,0x0300,0x0300);
-                               /*set stereo DAC&Voice DAC&Stereo ADC function select to default*/ 
-                               rt5625_write(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,0);            
-                               /*set VODSP&PDM Control to default*/ 
-                               rt5625_write(codec, RT5625_VODSP_PDM_CTL,0);
-                               rt5625_write_mask(codec, 0x26,0x0000,0x0300);           
-                               rt5625_write_mask(codec, 0x3e,0x0000,0xf312);//power down related bit
-                               rt5625_write_mask(codec, 0x3a,0x0000,0xcc8d);//power down related bit
-                               rt5625_write_mask(codec, 0x3c,0x0000,0x07cf);//power down related bit
-                               
-                       
-                               break;
-               }               
+       switch(rt5625->vodsp_fun) {
+       case RT5625_AEC_EN:
+               break;
+       case RT5625_AEC_DIS:
+               if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+                       ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+                       snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+                               RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN);
+                       snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+                               RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0);
+                       snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+                               RT5625_LDO_MASK, RT5625_LDO_DIS);
+               }
+               break;
+       default:
+               break;
+       }
 
        return 0;
 }
 
-static int enable_vodsp_aec(struct snd_soc_codec *codec, unsigned int VodspAEC_En, unsigned int AEC_mode)
+#ifdef RT5625_F_SMT_PHO
+static int rt5625_app_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       int  ret = 0;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-       
-       if (VodspAEC_En != 0)
-       {       
+       pr_info("App status: %x\n", rt5625->app_bmp);
 
-               //enable power of VODSP I2C interface & VODSP interface
-               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);
-               //enable power of VODSP I2S interface 
-               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1,PWR_I2S_INTERFACE,PWR_I2S_INTERFACE);    
-               //select input/output of VODSP AEC
-               set_vodsp_aec_path(codec, AEC_mode);            
+       return 0;
+}
 
+static int rt5625_cap_voip_chk_put(struct snd_kcontrol *kcontrol, 
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i, upd;
+
+       /* VoIP start up if record & playback all turn on, or AEC       *
+        * is disabled. otherwise, cheat dapm.                  */
+       if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+               (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+               /* backup registers for voip routing */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       rt5625_voip_back[i][1] =
+                               snd_soc_read(codec, rt5625_voip_back[i][0]);
+               /* cheat dapm */
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2);
+               return 0;
        }
-       else
-       {
-               //disable VODSP AEC path
-               set_vodsp_aec_path(codec, VODSP_AEC_DISABLE);
-               //set VODSP AEC to power down mode                      
-               rt5625_write_mask(codec, RT5625_VODSP_CTL,0,VODSP_NO_PD_MODE_ENA);
-               //disable power of VODSP I2C interface & VODSP interface
-               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,0,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);                                
+
+       if (rt5625->headset) {
+               /* backup registers for voip routing */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       rt5625_voip_back[i][1] =
+                               snd_soc_read(codec, rt5625_voip_back[i][0]);
+               /* cheat dapm */
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2);
+       } else
+               rt5625->vodsp_fun = RT5625_AEC_EN;
+
+       upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
        }
 
-       return ret;
+       return 0;
 }
 
-static void rt5625_aec_config(struct snd_soc_codec *codec, unsigned int mode)
+static int rt5625_cap_voip_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       DBG("rt5625_aec_config %d\n",mode);
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i;
 
-       if (mode == VODSP_AEC_DISABLE)
-       {
-               enable_vodsp_aec(codec,0, mode);        
-               /*disable LDO power*/
-               rt5625_write_mask(codec, RT5625_LDO_CTRL,0,LDO_ENABLE);
-       }
-       else
-       {
-               init_vodsp_aec(codec);
-       
-               enable_vodsp_aec(codec,1, mode);                
+       if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+               if (rt5625->headset) {
+                       snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO,
+                               RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO);
+                       /* recover all changes by voip */
+                       for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                               snd_soc_write(codec, rt5625_voip_back[i][0],
+                                               rt5625_voip_back[i][1]);
+                       snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                               RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+               } else {
+                       snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO,
+                               RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO);
+                       rt5625->vodsp_fun = RT5625_AEC_EN;
+                       /* Mic1 & Mic2 boost 0db */
+                       snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+                               RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+                               RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+                       /* Capture volume gain 9db */
+                       snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+                               RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+               }
+       } else {
+               /* recover all changes by voip */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       snd_soc_write(codec, rt5625_voip_back[i][0],
+                                       rt5625_voip_back[i][1]);
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+               if (rt5625->app_bmp & RT5625_3G_MASK &&
+                       rt5625->vodsp_fun ==  RT5625_AEC_EN) {
+                       /* Mic1 boost 0db */
+                       snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+                               RT5625_MIC1_BST_MASK, RT5625_MIC1_BST_BYPASS);
+                       /* Capture volume gain 9db */
+                       snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+                               RT5625_G_ADCR_MASK, 0x11);
+               }
        }
+
+       return 0;
 }
-//****************************************************************************************************************
-//*
-//*function:disable rt5625's function.
-//*
-//*
-//****************************************************************************************************************
-static int rt5625_func_aec_disable(struct snd_soc_codec *codec,int mode)
-{
 
-       switch(mode)
-       {
-               case RT5625_AEC_PCM_IN_OUT:
-               case RT5625_AEC_IIS_IN_OUT:
-               case RT5625_AEC_ANALOG_IN_OUT:
-                       
-                       rt5625_aec_config(codec,VODSP_AEC_DISABLE);     //disable AEC function and path
-                       
-               break;
-               
-               default:
+static int rt5625_hs_voip_chk_put(struct snd_kcontrol *kcontrol, 
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i, upd;
+
+       rt5625->headset = true;
+       if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+               (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+               /* backup registers for voip routing */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       rt5625_voip_back[i][1] =
+                               snd_soc_read(codec, rt5625_voip_back[i][0]);
+               rt5625->vodsp_fun_bak = rt5625->vodsp_fun;
+               /* cheat dapm */
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR, RT5625_REC_IIS_S_ADC);
+               return 0;
+       }
 
-               break;
+       upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
        }
 
        return 0;
 }
 
-
-static int rt5625_get_dsp_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int rt5625_hs_voip_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-        /*cause we choose bit[0][1] to store the mode type*/
-       int mode = (rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC)) & 0x03;  
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i;
+
+       if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO,
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO);
+               /* Mic1 & Mic2 boost 0db */
+               snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+                       RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+                       RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+               /* Capture volume gain 9db */
+               snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+                       RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+       } else {
+               /* recover all changes by voip */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       snd_soc_write(codec, rt5625_voip_back[i][0],
+                                       rt5625_voip_back[i][1]);
+               rt5625->vodsp_fun = rt5625->vodsp_fun_bak;
+               if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM);
+               } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC);
+               } else {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC);
+               }
+       }
 
-       ucontrol->value.integer.value[0] = mode;
        return 0;
 }
 
-
-static int rt5625_set_dsp_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int rt5625_voip_chk_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       u16 Virtual_reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
-       int rt5625_mode=(Virtual_reg)&0x03;
-
-       DBG("rt5625_mode=%d,value[0]=%ld,Virtual_reg=%x\n",rt5625_mode,ucontrol->value.integer.value[0],Virtual_reg);
-
-       if ( rt5625_mode == ucontrol->value.integer.value[0])
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i, upd;
+
+       rt5625->headset = false;
+       /* voip start-up if record is on-going; otherwise, cheat dapm */
+       if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+               (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+               /* backup registers for voip routing */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       rt5625_voip_back[i][1] =
+                               snd_soc_read(codec, rt5625_voip_back[i][0]);
+               rt5625->vodsp_fun_bak = rt5625->vodsp_fun;
+               /* cheat dapm */
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_RXDP_S_MASK | RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR,
+                       RT5625_RXDP_S_SRC1 | RT5625_REC_IIS_S_SRC2);
                return 0;
+       }
 
-       switch(ucontrol->value.integer.value[0])
-       {
-               case RT5625_AEC_PCM_IN_OUT:
-
-                       rt5625_aec_config(codec,PCM_IN_PCM_OUT);//enable AEC PCM in/out function and path
+       upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
+       }
 
-               break;
+       return 0;
+}
 
-               case RT5625_AEC_IIS_IN_OUT:
+static int rt5625_voip_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int i;
 
-                       rt5625_aec_config(codec,DAC_IN_ADC_OUT);//enable AEC IIS in/out function and path
+       if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO,
+                       RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO);
+               /* Mic1 & Mic2 boost 0db */
+               snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+                       RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+                       RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+               /* Capture volume gain 9db */
+               snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+                       RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+       } else {
+               /* recover all changes by voip */
+               for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+                       snd_soc_write(codec, rt5625_voip_back[i][0],
+                                       rt5625_voip_back[i][1]);
+               rt5625->vodsp_fun = rt5625->vodsp_fun_bak;
+               snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+                       RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+               if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM);
+               } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC);
+               } else {
+                       snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+                               RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC);
+               }
+       }
 
-               break;
+       return 0;
+}
 
-               case RT5625_AEC_ANALOG_IN_OUT:
-                       
-                       rt5625_aec_config(codec,ANALOG_IN_ANALOG_OUT);//enable AEC analog in/out function and path
-                       
-               break;
+static int rt5625_voip_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-               case RT5625_AEC_DISABLE:
-       
-                       rt5625_func_aec_disable(codec,rt5625_mode);             //disable previous select function.     
-       
-               break;  
+       ucontrol->value.integer.value[0] =
+               (rt5625->app_bmp & RT5625_VOIP_MASK) >> RT5625_VOIP_BIT;
 
-               default:
+       return 0;
+}
 
-               break;
-       }
+static int rt5625_play_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-       Virtual_reg &= 0xfffc;
-       Virtual_reg |= (ucontrol->value.integer.value[0]);
-       rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, Virtual_reg);
+       ucontrol->value.integer.value[0] =
+               (rt5625->app_bmp & RT5625_PLY_MASK) >> RT5625_PLY_BIT;
 
-       DBG("2rt5625_mode=%d,value[0]=%ld,Virtual_reg=%x\n",rt5625_mode,ucontrol->value.integer.value[0],Virtual_reg);
        return 0;
 }
 
-static int rt5625_dump_dsp_reg(struct snd_soc_codec *codec)
+static int rt5625_play_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       int i;
-
-       rt5625_write_mask(codec, RT5625_VODSP_CTL, VODSP_NO_PD_MODE_ENA,VODSP_NO_PD_MODE_ENA);
-       for (i = 0; i < SET_VODSP_REG_INIT_NUM; i++) {
-               rt5625_read_vodsp_reg(codec, VODSP_AEC_Init_Value[i].VoiceDSPIndex);
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int upd;
+
+       upd = (rt5625->app_bmp & ~RT5625_PLY_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_PLY_BIT);
+       if (rt5625->app_bmp != upd)
+               rt5625->app_bmp = upd;
+
+       if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+               ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO);
        }
+
        return 0;
 }
 
-
-static int rt5625_dump_dsp_put(struct snd_kcontrol *kcontrol, 
+static int rt5625_rec_get(struct snd_kcontrol *kcontrol, 
                struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       int mode = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+       ucontrol->value.integer.value[0] =
+               (rt5625->app_bmp & RT5625_REC_MASK) >> RT5625_REC_BIT;
 
-       mode &= ~(0x01 << 8);
-       mode |= (ucontrol->value.integer.value[0] << 8);
-       rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, mode);
-       rt5625_dump_dsp_reg(codec);
-       
        return 0;
 }
 
-static const struct snd_kcontrol_new rt5625_snd_controls[] = {
-SOC_ENUM_EXT("rt5625 aec mode sel", rt5625_enum[0], rt5625_get_dsp_mode, rt5625_set_dsp_mode),
-SOC_ENUM("SPK Amp Type", rt5625_enum[1]),
-SOC_ENUM("Left SPK Source", rt5625_enum[2]),
-SOC_ENUM("SPK Amp Ratio", rt5625_enum[7]),
-SOC_ENUM("Mic1 Boost", rt5625_enum[8]),
-SOC_ENUM("Mic2 Boost", rt5625_enum[9]),
-SOC_ENUM("Dmic Boost", rt5625_enum[10]),
-SOC_ENUM("ADCR Func", rt5625_enum[11]),
-SOC_DOUBLE("PCM Playback Volume", RT5625_STEREO_DAC_VOL, 8, 0, 63, 1),
-SOC_DOUBLE("LineIn Playback Volume", RT5625_LINE_IN_VOL, 8, 0, 31, 1),
-SOC_SINGLE("Phone Playback Volume", RT5625_PHONEIN_VOL, 8, 31, 1),
-SOC_SINGLE("Mic1 Playback Volume", RT5625_MIC_VOL, 8, 31, 1),
-SOC_SINGLE("Mic2 Playback Volume", RT5625_MIC_VOL, 0, 31, 1),
-SOC_DOUBLE("PCM Capture Volume", RT5625_ADC_REC_GAIN, 8, 0, 31, 1),
-SOC_DOUBLE("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("HPOUT Playback Volume", RT5625_HP_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("HPOUT Playback Switch", RT5625_HP_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("AUXOUT Playback Volume", RT5625_AUX_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("AUXOUT Playback Switch", RT5625_AUX_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("ADC Record Gain", RT5625_ADC_REC_GAIN, 8, 0, 31, 0),
-SOC_SINGLE_EXT("VoDSP Dump", VIRTUAL_REG_FOR_MISC_FUNC, 8, 1, 0,
-                       snd_soc_get_volsw, rt5625_dump_dsp_put),
-#if (RT5625_EQ_FUNC_ENA==1)                    
-SOC_ENUM_EXT("EQ Mode", rt5625_enum[12], snd_soc_get_enum_double, rt5625_eq_sel_put),                          
-#endif
-};
-
-static int rt5625_add_controls(struct snd_soc_codec *codec)
+static int rt5625_rec_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       int err, i;
-
-       for (i = 0; i < ARRAY_SIZE(rt5625_snd_controls); i++){
-               err = snd_ctl_add(codec->card, 
-                               snd_soc_cnew(&rt5625_snd_controls[i],
-                                               codec, NULL));
-               if (err < 0)
-                       return err;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int upd;
+
+       upd = (rt5625->app_bmp & ~RT5625_REC_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_REC_BIT);
+       if (rt5625->app_bmp != upd)
+               rt5625->app_bmp = upd;
+
+       if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+               ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO);
        }
+
+
        return 0;
 }
 
-static void hp_depop_mode2(struct snd_soc_codec *codec)
+static int rt5625_bt_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-        rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
-        rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3, PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL,
-                         PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL);
-        rt5625_write(codec, RT5625_MISC_CTRL,HP_DEPOP_MODE2_EN);
-
-       DBG("delay 500 msec\n");
-
-        schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-               
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-        rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_HP_OUT_AMP|PWR_HP_OUT_ENH_AMP,
-                         PWR_HP_OUT_AMP|PWR_HP_OUT_ENH_AMP);
-       //rt5625_write_mask(codec, RT5625_MISC_CTRL, 0, HP_DEPOP_MODE2_EN);
+       ucontrol->value.integer.value[0] =
+               (rt5625->app_bmp & RT5625_BT_MASK) >> RT5625_BT_BIT;
 
+       return 0;
 }
 
-//enable depop function for mute/unmute
-static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute)
+static int rt5625_bt_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       if(mute)
-       {
-               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
-               rt5625_write(codec, RT5625_MISC_CTRL,M_UM_DEPOP_EN|HP_R_M_UM_DEPOP_EN|HP_L_M_UM_DEPOP_EN);
-               //Mute headphone right/left channel
-               rt5625_write_mask(codec,RT5625_HP_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE);     
-               mdelay(50);
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int upd;
+
+       if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2);
        }
-       else
-       {
-               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
-               rt5625_write(codec, RT5625_MISC_CTRL, M_UM_DEPOP_EN|HP_R_M_UM_DEPOP_EN|HP_L_M_UM_DEPOP_EN);
-               //unMute headphone right/left channel
-               rt5625_write_mask(codec,RT5625_HP_OUT_VOL,0,RT_L_MUTE|RT_R_MUTE);       
-               mdelay(50);
+
+       upd = (rt5625->app_bmp & ~RT5625_BT_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_BT_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_VOIP_MASK);
        }
 
+       return 0;
 }
 
+static int rt5625_3g_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       
+       ucontrol->value.integer.value[0] =
+               (rt5625->app_bmp & RT5625_3G_MASK) >> RT5625_3G_BIT;
 
-/*
- * _DAPM_ Controls
- */
- /*Left ADC Rec mixer*/
- /*Left ADC Rec mixer*/
-static const struct snd_kcontrol_new rt5625_left_adc_rec_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, 12, 1, 1),
-SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, 11, 1, 1),
-SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, 10, 1, 1),
-SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, 9, 1, 1),
-SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, 8, 1, 1),
+       return 0;
+}
 
-};
+static int rt5625_3g_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int upd;
+
+       rt5625->headset = false;
+       if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2);
+       }
 
-/*Left ADC Rec mixer*/
-static const struct snd_kcontrol_new rt5625_right_adc_rec_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, 3, 1, 1),
-SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, 2, 1, 1),
-SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, 1, 1, 1),
-SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, 0, 1, 1),
-};
+       upd = (rt5625->app_bmp & ~RT5625_3G_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_3G_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK);
+       }
 
-/*Left hpmixer mixer*/
-static const struct snd_kcontrol_new rt5625_left_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, 15, 1, 1),
-SOC_DAPM_SINGLE("LineIn Playback Switch", HPL_MIXER, 0, 1, 0),
-SOC_DAPM_SINGLE("Phone Playback Switch", HPL_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", HPL_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", HPL_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", HPL_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("HIFI DAC Playback Switch", RT5625_DAC_AND_MIC_CTRL, 3, 1, 1),
+       return 0;
+}
 
-};
+static int rt5625_hs_3g_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int upd;
+
+       rt5625->headset = true;
+       if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+               snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2,
+                       RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+                       RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2);
+       }
+       upd = (rt5625->app_bmp & ~RT5625_3G_MASK) |
+               (ucontrol->value.integer.value[0] << RT5625_3G_BIT);
+       if (rt5625->app_bmp != upd) {
+               rt5625->app_bmp = upd;
+               rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK);
+       }
 
-/*Right hpmixer mixer*/
-static const struct snd_kcontrol_new rt5625_right_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, 7, 1, 1),
-SOC_DAPM_SINGLE("LineIn Playback Switch", HPR_MIXER, 0, 1, 0),
-SOC_DAPM_SINGLE("Phone Playback Switch", HPR_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", HPR_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", HPR_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", HPR_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("HIFI DAC Playback Switch", RT5625_DAC_AND_MIC_CTRL, 2, 1, 1),
+       return 0;
+}
 
-};
+static int rt5625_dump_dsp_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       int i;
+       u16 val;
 
-/*mono mixer*/
-static const struct snd_kcontrol_new rt5625_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADCL Playback Switch", RT5625_ADC_REC_GAIN, 14, 1, 1),
-SOC_DAPM_SINGLE("ADCR Playback Switch", RT5625_ADC_REC_GAIN, 6, 1, 1),
-SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, 13, 1, 1),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 9, 1, 1),
-SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_AND_MIC_CTRL, 0, 1, 1),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VOICE_DAC_OUT_VOL, 13, 1, 1),
-};
+       pr_info("\n[ RT5625 DSP Register ]\n");
+       for (i = 0; i < RT5625_DSP_INIT_NUM; i++) {
+               val = rt5625_dsp_read(codec, rt5625_dsp_init[i].index);
+               if (val) pr_info("    0x%x: 0x%x\n",
+                       rt5625_dsp_init[i].index, val);
+       }
+       return 0;
+}
 
-/*speaker mixer*/
-static const struct snd_kcontrol_new rt5625_spk_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, 14, 1, 1),   
-SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 10, 1, 1),
-SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_AND_MIC_CTRL, 1, 1, 1),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VOICE_DAC_OUT_VOL, 14, 1, 1),
-};
+static int rt5625_dac_active_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-static int mixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+       ucontrol->value.integer.value[0] = rt5625->dac_active;
+       return 0;
+}
+
+static int rt5625_dac_active_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
 {
-       struct snd_soc_codec *codec = w->codec;
-       unsigned int l, r;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_dapm_widget *w;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-       DBG("enter %s\n", __func__);
+       if(ucontrol->value.integer.value[0] == rt5625->dac_active)
+               return 0;
+       rt5625->dac_active = ucontrol->value.integer.value[0];
 
-       l= rt5625_read(codec, HPL_MIXER);
-       r = rt5625_read(codec, HPR_MIXER);
-       
-       if ((l & 0x1) || (r & 0x1))
-               rt5625_write_mask(codec, 0x0a, 0x0000, 0x8000);
-       else
-               rt5625_write_mask(codec, 0x0a, 0x8000, 0x8000);
+       /* playback is on-going; do nothing when turn off BT */
+       if (rt5625->dac_active == 0 && rt5625->app_bmp & RT5625_PLY_MASK)
+               return 0;
 
-       if ((l & 0x2) || (r & 0x2))
-               rt5625_write_mask(codec, 0x08, 0x0000, 0x8000);
-       else
-               rt5625_write_mask(codec, 0x08, 0x8000, 0x8000);
+       list_for_each_entry(w, &dapm->card->widgets, list)
+       {
+               if (!w->sname || w->dapm != dapm)
+                       continue;
+               if (strstr(w->sname, "Playback")) {
+                       pr_info("widget %s %s %s\n", w->name, w->sname,
+                               rt5625->dac_active ? "active" : "inactive");
+                       w->active = rt5625->dac_active;
+               }
+       }
 
-       if ((l & 0x4) || (r & 0x4))
-               rt5625_write_mask(codec, 0x10, 0x0000, 0x8000);
-       else
-               rt5625_write_mask(codec, 0x10, 0x8000, 0x8000);
+       if (!(rt5625->dac_active))
+               snd_soc_dapm_sync(dapm);
 
-       if ((l & 0x8) || (r & 0x8))
-               rt5625_write_mask(codec, 0x10, 0x0000, 0x0800);
-       else
-               rt5625_write_mask(codec, 0x10, 0x0800, 0x0800);
+       return 0;
+}
 
-       if ((l & 0x10) || (r & 0x10))
-               rt5625_write_mask(codec, 0x18, 0x0000, 0x8000);
-       else
-               rt5625_write_mask(codec, 0x18, 0x8000, 0x8000);
+static int rt5625_adc_active_get(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
+       ucontrol->value.integer.value[0] = rt5625->adc_active;
        return 0;
 }
 
+static int rt5625_adc_active_put(struct snd_kcontrol *kcontrol, 
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_dapm_widget *w;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-/*
- *     bit[0][1] use for aec control
- *     bit[2][3] for ADCR func
- *     bit[4] for SPKL pga
- *     bit[5] for SPKR pga
- *     bit[6] for hpl pga
- *     bit[7] for hpr pga
- */
-static int spk_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
- {
-       struct snd_soc_codec *codec = w->codec;
-       int reg;
-       
-       DBG("enter %s\n", __func__);
-       reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC) & (0x3 << 4);
-       if ((reg >> 4) != 0x3 && reg != 0)
+       if(ucontrol->value.integer.value[0] == rt5625->adc_active)
                return 0;
+       rt5625->adc_active = ucontrol->value.integer.value[0];
 
-       switch (event)
+       /* record is on-going; do nothing when turn off BT */
+       if (rt5625->adc_active == 0 && rt5625->app_bmp & RT5625_REC_MASK)
+               return 0;
+       
+       list_for_each_entry(w, &dapm->card->widgets, list)
        {
-               case SND_SOC_DAPM_POST_PMU:
-                       DBG("after virtual spk power up!\n");
-                       rt5625_write_mask(codec, 0x3e, 0x3000, 0x3000);
-                       rt5625_write_mask(codec, 0x02, 0x0000, 0x8080);
-                       rt5625_write_mask(codec, 0x3a, 0x0400, 0x0400);//power on spk amp
-                       break;
-               case SND_SOC_DAPM_POST_PMD:
-                       DBG("aftet virtual spk power down!\n");
-                       rt5625_write_mask(codec, 0x3a, 0x0000, 0x0400);//power off spk amp
-                       rt5625_write_mask(codec, 0x02, 0x8080, 0x8080);
-                       rt5625_write_mask(codec, 0x3e, 0x0000, 0x3000);                 
-                       break;
-               default:
-                       return 0;
+               if (!w->sname || w->dapm != dapm)
+                       continue;
+               if (strstr(w->sname, "Capture")) {
+                       pr_info("widget %s %s %s\n", w->name, w->sname,
+                               rt5625->adc_active ? "active" : "inactive");
+                       w->active = rt5625->adc_active;
+               }
        }
+
+       if (!(rt5625->adc_active))
+               snd_soc_dapm_sync(dapm);
+
        return 0;
 }
 
+static int rt5625_pll_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
+       ucontrol->value.integer.value[0] = rt5625->pll_sel;
+       return 0;
+}
 
 
-static int hp_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
-{
-       struct snd_soc_codec *codec = w->codec;
-       int reg;
-
-       DBG("enter %s\n", __func__);
+static int rt5625_pll_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{ 
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
-       reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC) & (0x3 << 6);
-       if ((reg >> 6) != 0x3 && reg != 0)
+       if(ucontrol->value.integer.value[0] == rt5625->pll_sel)
                return 0;
-       
-       switch (event)
-       {
-               case SND_SOC_DAPM_POST_PMD:
+       rt5625->pll_sel = ucontrol->value.integer.value[0];
+
+       switch(rt5625->pll_sel) {
+       case RT5625_PLL_DIS:
+               pr_info("%s(): Disable\n", __func__);
+               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                                       RT5625_SCLK_PLL1, 0);
+               snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0);
+               break;
 
-                       DBG("aftet virtual hp power down!\n");
+       case RT5625_PLL_112896_225792:
+               pr_info("%s(): 11.2896>22.5792\n", __func__);
+               snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000);
+               snd_soc_write(codec, RT5625_PLL_CTRL, 0x06a0);
+               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                       RT5625_SCLK_PLL1, RT5625_SCLK_PLL1);
+               snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210);
+               break;
 
-                       hp_mute_unmute_depop(codec,1);//mute hp
-                       rt5625_write_mask(codec, 0x3a, 0x0000, 0x0300);
-                       rt5625_write_mask(codec, 0x3e, 0x0000, 0x0c00);                 
-                       break;
+       case RT5625_PLL_112896_24576:
+               pr_info("%s(): 11.2896->24.576\n", __func__);
+               snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000);
+               snd_soc_write(codec, RT5625_PLL_CTRL, 0x922f);
+               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                       RT5625_SCLK_PLL1, RT5625_SCLK_PLL1);
+               snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210);
+               break;
 
-               case SND_SOC_DAPM_POST_PMU:     
+       default:
+               break;
+       }
 
-                       DBG("after virtual hp power up!\n");
-                       hp_depop_mode2(codec);
-                       hp_mute_unmute_depop(codec,0);//unmute hp
-                       break;
+       return 0;
+}
 
-               default:
-                       return 0;
-       }       
+static int rt5625_pll2_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
+       ucontrol->value.integer.value[0] = rt5625->pll2_sel;
        return 0;
 }
 
+static int rt5625_pll2_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
+       if(ucontrol->value.integer.value[0] == rt5625->pll2_sel)
+               return 0;
+       rt5625->pll2_sel = ucontrol->value.integer.value[0];
+
+       if(rt5625->pll2_sel != RT5625_PLL_DIS) {
+               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                       RT5625_VSCLK_MASK, RT5625_VSCLK_PLL2);
+               snd_soc_write(codec, RT5625_PLL2_CTRL, RT5625_PLL2_EN);
+               snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1,
+                               RT5625_VBCLK_DIV1_4);
+               snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+                       RT5625_PCM_CS_MASK, RT5625_PCM_CS_VSCLK);
+       }
 
-static int aux_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
-{
        return 0;
 }
 
-/*SPKOUT Mux*/
-static const struct snd_kcontrol_new rt5625_spkout_mux_out_controls = 
-SOC_DAPM_ENUM("Route", rt5625_enum[3]);
+static const char *rt5625_pll_sel[] = {"Disable", "11.2896->22.5792", "11.2896->24.576"};
 
-/*HPLOUT MUX*/
-static const struct snd_kcontrol_new rt5625_hplout_mux_out_controls = 
-SOC_DAPM_ENUM("Route", rt5625_enum[4]);
+static const SOC_ENUM_SINGLE_DECL(rt5625_pll_sel_enum, 0, 0, rt5625_pll_sel);
 
-/*HPROUT MUX*/
-static const struct snd_kcontrol_new rt5625_hprout_mux_out_controls = 
-SOC_DAPM_ENUM("Route", rt5625_enum[5]);
-/*AUXOUT MUX*/
-static const struct snd_kcontrol_new rt5625_auxout_mux_out_controls = 
-SOC_DAPM_ENUM("Route", rt5625_enum[6]);
+static const char *rt5625_pll2_sel[] = {"Disable", "Enable"};
 
-static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("Left LineIn"),
-SND_SOC_DAPM_INPUT("Right LineIn"),
-SND_SOC_DAPM_INPUT("Phone"),
-SND_SOC_DAPM_INPUT("Mic1"),
-SND_SOC_DAPM_INPUT("Mic2"),
-
-SND_SOC_DAPM_PGA("Mic1 Boost", RT5625_PWR_MANAG_ADD3, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic2 Boost", RT5625_PWR_MANAG_ADD3, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback DAC", RT5625_PWR_MANAG_ADD2, 9, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback DAC", RT5625_PWR_MANAG_ADD2, 8, 0),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback DAC", RT5625_PWR_MANAG_ADD2, 10, 0),
-
-SND_SOC_DAPM_PGA("Left LineIn PGA", RT5625_PWR_MANAG_ADD3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right LineIn PGA", RT5625_PWR_MANAG_ADD3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Phone PGA", RT5625_PWR_MANAG_ADD3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic1 PGA", RT5625_PWR_MANAG_ADD3, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic2 PGA", RT5625_PWR_MANAG_ADD3, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("VoDAC PGA", RT5625_PWR_MANAG_ADD1, 7, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Left Rec Mixer", RT5625_PWR_MANAG_ADD2, 1, 0,
-       &rt5625_left_adc_rec_mixer_controls[0], ARRAY_SIZE(rt5625_left_adc_rec_mixer_controls)),
-SND_SOC_DAPM_MIXER("Right Rec Mixer", RT5625_PWR_MANAG_ADD2, 0, 0,
-       &rt5625_right_adc_rec_mixer_controls[0], ARRAY_SIZE(rt5625_right_adc_rec_mixer_controls)),
-SND_SOC_DAPM_MIXER_E("Left HP Mixer", RT5625_PWR_MANAG_ADD2, 5, 0,
-       &rt5625_left_hp_mixer_controls[0], ARRAY_SIZE(rt5625_left_hp_mixer_controls),
-       mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER_E("Right HP Mixer", RT5625_PWR_MANAG_ADD2, 4, 0,
-       &rt5625_right_hp_mixer_controls[0], ARRAY_SIZE(rt5625_right_hp_mixer_controls),
-       mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER("MoNo Mixer", RT5625_PWR_MANAG_ADD2, 2, 0, 
-       &rt5625_mono_mixer_controls[0], ARRAY_SIZE(rt5625_mono_mixer_controls)),
-SND_SOC_DAPM_MIXER("SPK Mixer", RT5625_PWR_MANAG_ADD2, 3, 0,
-       &rt5625_spk_mixer_controls[0], ARRAY_SIZE(rt5625_spk_mixer_controls)),  
-SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("DAC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("SPKOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_spkout_mux_out_controls),
-SND_SOC_DAPM_MUX("HPLOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_hplout_mux_out_controls),
-SND_SOC_DAPM_MUX("HPROUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_hprout_mux_out_controls),
-SND_SOC_DAPM_MUX("AUXOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_auxout_mux_out_controls),
-
-SND_SOC_DAPM_PGA_E("SPKL Out PGA", VIRTUAL_REG_FOR_MISC_FUNC, 4, 0, NULL, 0,
-                               spk_pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA_E("SPKR Out PGA", VIRTUAL_REG_FOR_MISC_FUNC, 5, 0, NULL, 0,
-                               spk_pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA_E("HPL Out PGA",VIRTUAL_REG_FOR_MISC_FUNC, 6, 0, NULL, 0, 
-                               hp_pga_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("HPR Out PGA",VIRTUAL_REG_FOR_MISC_FUNC, 7, 0, NULL, 0, 
-                               hp_pga_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("AUX Out PGA",RT5625_PWR_MANAG_ADD3, 14, 0, NULL, 0, 
-                               aux_pga_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-                               
-SND_SOC_DAPM_ADC("Left ADC", "Left ADC HiFi Capture", RT5625_PWR_MANAG_ADD2, 7, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right ADC HiFi Capture", RT5625_PWR_MANAG_ADD2, 6, 0),
-SND_SOC_DAPM_OUTPUT("SPKL"),
-SND_SOC_DAPM_OUTPUT("SPKR"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("AUX"),
-SND_SOC_DAPM_MICBIAS("Mic1 Bias", RT5625_PWR_MANAG_ADD1, 3, 0),
-SND_SOC_DAPM_MICBIAS("Mic2 Bias", RT5625_PWR_MANAG_ADD1, 2, 0),
+static const SOC_ENUM_SINGLE_DECL(rt5625_pll2_sel_enum, 0, 0, rt5625_pll2_sel);
+#endif
+
+static const char *rt5625_AUXOUT_mode[] = {"Differential mode", "Single-ended mode"}; 
+static const char *rt5625_Differential_Input_Control[] = {"Disable", "Enable"};  
+
+static const struct soc_enum rt5625_differential_enum[] = {
+SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, 4, 2, rt5625_AUXOUT_mode),         /*0*/
+SOC_ENUM_SINGLE(RT5625_PHONEIN_VOL, 13, 2, rt5625_Differential_Input_Control),/*1*/
+SOC_ENUM_SINGLE(RT5625_MIC_VOL, 15, 2, rt5625_Differential_Input_Control),        /*2*/
+SOC_ENUM_SINGLE(RT5625_MIC_VOL, 7, 2, rt5625_Differential_Input_Control),         /*3*/
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
-               /*Input PGA*/
-
-               {"Left LineIn PGA", NULL, "Left LineIn"},
-               {"Right LineIn PGA", NULL, "Right LineIn"},
-               {"Phone PGA", NULL, "Phone"},
-               {"Mic1 Boost", NULL, "Mic1"},
-               {"Mic2 Boost", NULL, "Mic2"},
-               {"Mic1 PGA", NULL, "Mic1"},
-               {"Mic2 PGA", NULL, "Mic2"},
-               {"VoDAC PGA", NULL, "Voice DAC"},
-               
-               /*Left ADC mixer*/
-               {"Left Rec Mixer", "LineIn Capture Switch", "Left LineIn"},
-               {"Left Rec Mixer", "Phone Capture Switch", "Phone"},
-               {"Left Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
-               {"Left Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
-               {"Left Rec Mixer", "HP Mixer Capture Switch", "Left HP Mixer"},
-               {"Left Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
-               {"Left Rec Mixer", "MoNo Mixer Capture Switch", "MoNo Mixer"},
-
-               /*Right ADC Mixer*/
-               {"Right Rec Mixer", "LineIn Capture Switch", "Right LineIn"},
-               {"Right Rec Mixer", "Phone Capture Switch", "Phone"},
-               {"Right Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
-               {"Right Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
-               {"Right Rec Mixer", "HP Mixer Capture Switch", "Right HP Mixer"},
-               {"Right Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
-               {"Right Rec Mixer", "MoNo Mixer Capture Switch", "MoNo Mixer"},
-               
-               /*HPL mixer*/
-               {"Left HP Mixer", "ADC Playback Switch", "Left Rec Mixer"},
-               {"Left HP Mixer", "LineIn Playback Switch", "Left LineIn PGA"},
-               {"Left HP Mixer", "Phone Playback Switch", "Phone PGA"},
-               {"Left HP Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
-               {"Left HP Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
-               {"Left HP Mixer", "HIFI DAC Playback Switch", "Left DAC"},
-               {"Left HP Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-               
-               /*HPR mixer*/
-               {"Right HP Mixer", "ADC Playback Switch", "Right Rec Mixer"},
-               {"Right HP Mixer", "LineIn Playback Switch", "Right LineIn PGA"},
-               {"Right HP Mixer", "HIFI DAC Playback Switch", "Right DAC"},
-               {"Right HP Mixer", "Phone Playback Switch", "Phone PGA"},
-               {"Right HP Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
-               {"Right HP Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
-               {"Right HP Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
-               /*DAC Mixer*/
-               {"DAC Mixer", NULL, "Left DAC"},
-               {"DAC Mixer", NULL, "Right DAC"},
-
-               /*line mixer*/
-               {"Line Mixer", NULL, "Left LineIn PGA"},
-               {"Line Mixer", NULL, "Right LineIn PGA"},
-
-               /*spk mixer*/
-               {"SPK Mixer", "Line Mixer Playback Switch", "Line Mixer"},
-               {"SPK Mixer", "Phone Playback Switch", "Phone PGA"},
-               {"SPK Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
-               {"SPK Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
-               {"SPK Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
-               {"SPK Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
-               /*mono mixer*/
-               {"MoNo Mixer", "Line Mixer Playback Switch", "Line Mixer"},
-               {"MoNo Mixer", "ADCL Playback Switch","Left Rec Mixer"},
-               {"MoNo Mixer", "ADCR Playback Switch","Right Rec Mixer"},
-               {"MoNo Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
-               {"MoNo Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
-               {"MoNo Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
-               {"MoNo Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-               
-               /*hp mixer*/
-               {"HP Mixer", NULL, "Left HP Mixer"},
-               {"HP Mixer", NULL, "Right HP Mixer"},
-
-               /*spkout mux*/
-               {"SPKOUT Mux", "HP Mixer", "HP Mixer"},
-               {"SPKOUT Mux", "SPK Mixer", "SPK Mixer"},
-               {"SPKOUT Mux", "Mono Mixer", "MoNo Mixer"},
-               
-               /*hpl out mux*/
-               {"HPLOUT Mux", "HPL Mixer", "Left HP Mixer"},
-               
-               /*hpr out mux*/
-               {"HPROUT Mux", "HPR Mixer", "Right HP Mixer"},
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -3525, 75, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dmic_bst_tlv, 0, 600, 0);
+/* {0, +20, +30, +40} dB */
+static unsigned int mic_bst_tlv[] = {
+       TLV_DB_RANGE_HEAD(2),
+       0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+       1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
+};
 
-               /*aux out mux*/
-               {"AUXOUT Mux", "HP Mixer", "HP Mixer"},
-               {"AUXOUT Mux", "SPK Mixer", "SPK Mixer"},
-               {"AUXOUT Mux", "Mono Mixer", "MoNo Mixer"},
+#ifdef RT5625_REG_RW
+#define REGVAL_MAX 0xffff
+static unsigned int regctl_addr = 0x3e;
+static int rt5625_regctl_info(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 2;
+       uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = REGVAL_MAX;
+       return 0;
+}
 
-               /*spkl out pga*/
-               {"SPKL Out PGA", NULL, "SPKOUT Mux"},
+static int rt5625_regctl_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       ucontrol->value.integer.value[0] = regctl_addr;
+       ucontrol->value.integer.value[1] = snd_soc_read(codec, regctl_addr);
+       return 0;
+}
 
-               /*spkr out pga*/
-               {"SPKR Out PGA", NULL, "SPKOUT Mux"},
-               
-               /*hpl out pga*/
-               {"HPL Out PGA", NULL, "HPLOUT Mux"},
+static int rt5625_regctl_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       regctl_addr = ucontrol->value.integer.value[0];
+       if(ucontrol->value.integer.value[1] <= REGVAL_MAX)
+               snd_soc_write(codec, regctl_addr, ucontrol->value.integer.value[1]);
+       return 0;
+}
+#endif
 
-               /*hpr out pga*/
-               {"HPR Out PGA", NULL, "HPROUT Mux"},
+/*speaker ext control*/
+static const struct soc_enum spk_ctr_enum =
+       SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(rt5625_spk_ctr_sel), rt5625_spk_ctr_sel);
 
-               /*aux out pga*/
-               {"AUX Out PGA", NULL, "AUXOUT Mux"}, 
-               
-               /*left adc*/
-               {"Left ADC", NULL, "Left Rec Mixer"},
-               
-               /*right adc*/
-               {"Right ADC", NULL, "Right Rec Mixer"},
-               
-               /*output*/
-               {"SPKL", NULL, "SPKL Out PGA"},
-               {"SPKR", NULL, "SPKR Out PGA"},
-               {"HPL", NULL, "HPL Out PGA"},
-               {"HPR", NULL, "HPR Out PGA"},
-               {"AUX", NULL, "AUX Out PGA"},
-};
+static int rt5625_spk_ctr_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
 
+       ucontrol->value.integer.value[0] = rt5625->spk_ctr_status;
+       return 0;
+}
 
-static int rt5625_add_widgets(struct snd_soc_codec *codec)
+static int rt5625_spk_ctr_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
 {
-       snd_soc_dapm_new_controls(codec, rt5625_dapm_widgets, 
-                               ARRAY_SIZE(rt5625_dapm_widgets));
-       snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-       snd_soc_dapm_new_widgets(codec);
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+       rt5625->spk_ctr_status = ucontrol->value.integer.value[0];
 
+       if(rt5625->spk_ctr_pin != INVALID_GPIO)
+       {
+               if(rt5625->spk_ctr_status)
+                       gpio_set_value(rt5625->spk_ctr_pin,rt5625->spk_ctr_on);
+               else
+                       gpio_set_value(rt5625->spk_ctr_pin,rt5625->spk_ctr_off);
+       }
        return 0;
 }
 
-struct _pll_div{
-       u32 pll_in;
-       u32 pll_out;
-       u16 regvalue;
+static const struct snd_kcontrol_new rt5625_snd_controls[] = {
+
+       #if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_SPKOUT)
+       SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL,
+               RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE_TLV("Earpiece Playback Volume", RT5625_SPK_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("Earpiece Playback Switch", RT5625_SPK_OUT_VOL,
+               RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       #endif
+
+       #if defined (CONFIG_SND_SOC_RT5625_SPK_FORM_HPOUT)
+       SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_HP_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("SPKOUT Playback Switch", RT5625_HP_OUT_VOL,
+               RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE_TLV("Earpiece Playback Volume", RT5625_HP_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("Earpiece Playback Switch", RT5625_HP_OUT_VOL,
+               RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_ENUM_EXT("SPK_CTR",spk_ctr_enum, rt5625_spk_ctr_get, rt5625_spk_ctr_put),
+       #endif
+
+       SOC_ENUM("SPK Amp Type", rt5625_spk_out_enum),
+       SOC_ENUM("Left SPK Source", rt5625_spkl_src_enum),
+       SOC_ENUM("SPK Amp Ratio", rt5625_spkamp_ratio_enum),
+       //SOC_DOUBLE_TLV("Headphone Playback Volume", RT5625_HP_OUT_VOL,
+       //      RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       //SOC_DOUBLE("Headphone Playback Switch", RT5625_HP_OUT_VOL,
+       //              RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       //SOC_ENUM("AUXOUT Mode Control", rt5625_auxout_mode_enum),
+       SOC_DOUBLE_TLV("AUXOUT Playback Volume", RT5625_AUX_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("AUXOUT Playback Switch", RT5625_AUX_OUT_VOL,
+                       RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE_TLV("PCM Playback Volume", RT5625_DAC_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 63, 1, dmic_bst_tlv),
+       //SOC_ENUM("Phone Mode Control", rt5625_phone_mode_enum),
+       SOC_SINGLE_TLV("Phone Playback Volume", RT5625_PHONEIN_VOL,
+               RT5625_L_VOL_SFT, 31, 1, in_vol_tlv),
+       //SOC_ENUM("MIC1 Mode Control", rt5625_mic1_mode_enum),
+       SOC_SINGLE_TLV("MIC1 Boost", RT5625_MIC_CTRL,
+               RT5625_MIC1_BST_SFT, 3, 0, mic_bst_tlv),
+       SOC_SINGLE_TLV("Mic1 Playback Volume", RT5625_MIC_VOL,
+               RT5625_L_VOL_SFT, 31, 1, in_vol_tlv),
+       //SOC_ENUM("MIC2 Mode Control", rt5625_mic2_mode_enum),
+       SOC_SINGLE_TLV("MIC2 Boost", RT5625_MIC_CTRL,
+               RT5625_MIC2_BST_SFT, 3, 0, mic_bst_tlv),
+       SOC_SINGLE_TLV("Mic2 Playback Volume", RT5625_MIC_VOL,
+               RT5625_R_VOL_SFT, 31, 1, in_vol_tlv),
+       SOC_SINGLE_TLV("Dmic Boost", RT5625_DMIC_CTRL,
+               RT5625_DIG_BST_SFT, 7, 0, dmic_bst_tlv),
+       SOC_DOUBLE_TLV("LineIn Playback Volume", RT5625_LINE_IN_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, in_vol_tlv),
+       SOC_DOUBLE_TLV("PCM Capture Volume", RT5625_ADC_REC_GAIN,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv),
+       //SOC_DOUBLE_TLV("ADC Record Gain", RT5625_ADC_REC_GAIN,
+       //      RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv),
+       /* This item does'nt affect path connected; only for clock choosen */
+       SOC_ENUM_EXT("ADCR fun select Control", adcr_fun_sel_enum,
+               snd_soc_get_enum_double, rt5625_adcr_fun_sel_put),
+       SOC_ENUM_EXT("ADCL fun select Control", adcl_fun_sel_enum,
+               snd_soc_get_enum_double, rt5625_adcl_fun_sel_put),
+
+       /* Voice DSP */
+       SOC_ENUM_EXT("VoDSP AEC", rt5625_aec_fun_enum,
+               rt5625_aec_get, rt5625_aec_put),
+       SOC_ENUM("VoDSP LRCK Control",  rt5625_dsp_lrck_enum),
+       SOC_ENUM("VoDSP BP Pin Control",  rt5625_bp_ctrl_enum),
+       SOC_ENUM("VoDSP Power Down Pin Control",  rt5625_pd_ctrl_enum),
+       SOC_ENUM("VoDSP Reset Pin Control",  rt5625_rst_ctrl_enum),
+
+#ifdef RT5625_F_SMT_PHO
+       SOC_ENUM("GPIO2 mode", rt5625_gpio2_enum[0]),
+       SOC_ENUM("GPIO2 configuration", rt5625_gpio2_enum[1]),
+       SOC_ENUM("GPIO2 level", rt5625_gpio2_enum[2]),
+
+       SOC_SINGLE_EXT("VoDSP Dump", 0, 0, 1, 0, rt5625_dump_dsp_get, NULL),
+       SOC_SINGLE_EXT("DAC Switch", 0, 0, 1, 0, rt5625_dac_active_get, rt5625_dac_active_put),
+       SOC_SINGLE_EXT("ADC Switch", 0, 0, 1, 0, rt5625_adc_active_get, rt5625_adc_active_put),
+       SOC_ENUM_EXT("PLL Switch", rt5625_pll_sel_enum, rt5625_pll_get, rt5625_pll_put),
+       SOC_ENUM_EXT("PLL2 Switch", rt5625_pll2_sel_enum, rt5625_pll2_get, rt5625_pll2_put),
+       SOC_SINGLE_EXT("VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_chk_put),
+       SOC_SINGLE_EXT("VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_put),
+       SOC_SINGLE_EXT("Capture VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_chk_put),
+       SOC_SINGLE_EXT("Capture VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_put),
+       SOC_SINGLE_EXT("Headset VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_chk_put),
+       SOC_SINGLE_EXT("Headset VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_put),
+       SOC_SINGLE_EXT("Playback Switch", 0, 0, 1, 0, rt5625_play_get, rt5625_play_put),
+       SOC_SINGLE_EXT("Record Switch", 0, 0, 1, 0, rt5625_rec_get, rt5625_rec_put),
+       SOC_SINGLE_EXT("BT Switch", 0, 0, 1, 0, rt5625_bt_get, rt5625_bt_put),
+       SOC_SINGLE_EXT("3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_3g_put),
+       SOC_SINGLE_EXT("Headset 3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_hs_3g_put),
+       SOC_SINGLE_EXT("APP disp", 0, 0, 1, 0, rt5625_app_get, NULL),
+#endif
+       //SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL,
+       //      RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       //SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL,
+       //              RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_DOUBLE_TLV("HPOUT Playback Volume", RT5625_HP_OUT_VOL,
+               RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+       SOC_DOUBLE("HPOUT Playback Switch", RT5625_HP_OUT_VOL,
+                       RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+       SOC_ENUM("AUXOUT mode switch", rt5625_differential_enum[0]),
+       SOC_ENUM("Phone Differential Input Control", rt5625_differential_enum[1]),
+       SOC_ENUM("MIC1 Differential Input Control", rt5625_differential_enum[2]),
+       SOC_ENUM("MIC2 Differential Input Control", rt5625_differential_enum[3]),
+
+#ifdef RT5625_REG_RW
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Register Control",
+               .info = rt5625_regctl_info,
+               .get = rt5625_regctl_get,
+               .put = rt5625_regctl_put,
+       },
+#endif
 };
 
 
-/**************************************************************
-  *    watch out!
+ /*Left ADC Rec mixer*/
+static const struct snd_kcontrol_new rt5625_adcl_rec_mixer[] = {
+       SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_MIC1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_MIC2_SFT, 1, 1),
+       SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_LINE_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_PHO_SFT, 1, 1),
+       SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_L_MM_SFT, 1, 1),
+};
+
+/*Right ADC Rec mixer*/
+static const struct snd_kcontrol_new rt5625_adcr_rec_mixer[] = {
+       SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_MIC1_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_MIC2_SFT, 1, 1),
+       SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_LINE_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_PHO_SFT, 1, 1),
+       SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+                               RT5625_M_RM_R_MM_SFT, 1, 1),
+};
+
+/* HP Mixer for mono input */
+static const struct snd_kcontrol_new rt5625_hp_mixer[] = {
+       SOC_DAPM_SINGLE("LineIn Playback Switch", RT5625_LINE_IN_VOL,
+                               RT5625_M_LI_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL,
+                               RT5625_M_PHO_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC1_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC2_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+                               RT5625_M_VDAC_HM_SFT, 1, 1),
+};
+
+/* Left HP Mixer */
+static const struct snd_kcontrol_new rt5625_hpl_mixer[] = {
+       SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN,
+                               RT5625_M_ADCL_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_DACL_HM_SFT, 1, 1),
+};
+
+/* Right HP Mixer */
+static const struct snd_kcontrol_new rt5625_hpr_mixer[] = {
+       SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN,
+                               RT5625_M_ADCR_HM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_DACR_HM_SFT, 1, 1),
+};
+
+/* Mono Mixer */
+static const struct snd_kcontrol_new rt5625_mono_mixer[] = {
+       SOC_DAPM_SINGLE("ADCL Playback Switch", RT5625_ADC_REC_GAIN,
+                               RT5625_M_ADCL_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("ADCR Playback Switch", RT5625_ADC_REC_GAIN,
+                               RT5625_M_ADCR_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL,
+                               RT5625_M_LI_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC1_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC2_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_DAC_MM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+                               RT5625_M_VDAC_MM_SFT, 1, 1),
+};
+
+/* Speaker Mixer */
+static const struct snd_kcontrol_new rt5625_spk_mixer[] = {
+       SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL,
+                               RT5625_M_LI_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL,
+                               RT5625_M_PHO_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC1_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_MIC2_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL,
+                               RT5625_M_DAC_SM_SFT, 1, 1),
+       SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+                               RT5625_M_VDAC_SM_SFT, 1, 1),
+};
+
+static int rt5625_dac_func_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_REG:
+               snd_soc_update_bits(codec, RT5625_PD_CTRL,
+                       RT5625_PWR_PR1, RT5625_PWR_PR1);
+               break;
+
+       case SND_SOC_DAPM_POST_REG:
+               snd_soc_update_bits(codec, RT5625_PD_CTRL,
+                       RT5625_PWR_PR1, 0);
+               break;
+
+       default:
+               return 0;
+       }       
+
+       return 0;
+}
+
+static int rt5625_hpmix_event(struct snd_soc_dapm_widget *w,
+               struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMD:
+               snd_soc_update_bits(codec, RT5625_PWR_ADD2,
+                       RT5625_P_HM_L | RT5625_P_HM_R, 0);
+               break;
+
+       case SND_SOC_DAPM_POST_PMU:
+               snd_soc_update_bits(codec, RT5625_PWR_ADD2,
+                       RT5625_P_HM_L | RT5625_P_HM_R,
+                       RT5625_P_HM_L | RT5625_P_HM_R);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static int rt5625_vodsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMD:
+               //pr_info("%s(): PMD\n", __func__);
+               snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+                       RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+                       RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0);
+               snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+                       RT5625_LDO_MASK, RT5625_LDO_DIS);
+               break;
+
+       case SND_SOC_DAPM_POST_PMU:
+               //pr_info("%s(): PMU\n", __func__);
+               if(rt5625->vodsp_fun == RT5625_AEC_EN)
+                       rt5625_init_vodsp_aec(codec);
+               //pr_info("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C));
+               break;
+
+       default:
+               return 0;
+       }       
+
+       return 0;
+}
+
+
+static void hp_depop_mode2(struct snd_soc_codec *codec)
+{
+       snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+               RT5625_P_SG_EN, RT5625_P_SG_EN);
+       snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+               RT5625_P_HPL_VOL | RT5625_P_HPR_VOL,
+               RT5625_P_HPL_VOL | RT5625_P_HPR_VOL);
+       snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_HP_DEPOP_M2);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(500));
+       snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+               RT5625_P_HPO_AMP | RT5625_P_HPO_ENH,
+               RT5625_P_HPO_AMP | RT5625_P_HPO_ENH);
+}
+
+/* enable depop function for mute/unmute */
+static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute)
+{
+       if(mute) {
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+                       RT5625_P_SG_EN, RT5625_P_SG_EN);
+               snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP |
+                       RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP);
+               snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE,
+                       RT5625_L_MUTE | RT5625_R_MUTE);
+               mdelay(50);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1, RT5625_P_SG_EN, 0);
+       } else {
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+                       RT5625_P_SG_EN, RT5625_P_SG_EN);
+               snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP |
+                       RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP);
+               snd_soc_update_bits(codec,RT5625_HP_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE, 0);
+               mdelay(50);
+       }
+}
+
+static int rt5625_hp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMD:
+               hp_mute_unmute_depop(codec,1);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+                       RT5625_P_HPO_AMP | RT5625_P_HPO_ENH, 0);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+                       RT5625_P_HPL_VOL | RT5625_P_HPR_VOL, 0);
+               break;
+
+       case SND_SOC_DAPM_POST_PMU:
+               hp_depop_mode2(codec);
+               hp_mute_unmute_depop(codec,0);
+               break;
+
+       default:
+               return 0;
+       }       
+
+       return 0;
+}
+
+/* DAC function select MUX */
+static const char *dac_fun_sel[] = {
+       "Stereo DAC", "SRC2 Out", "TxDP", "TxDC"};
+
+static const struct soc_enum dac_fun_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_DAC_F_SFT,
+                               ARRAY_SIZE(dac_fun_sel), dac_fun_sel);
+
+static const struct snd_kcontrol_new dac_fun_sel_mux =
+       SOC_DAPM_ENUM("DAC Function Select Mux", dac_fun_sel_enum);
+
+/* Voice DAC source select MUX */
+static const char *vdac_src_sel[] = {
+       "Voice PCM", "SRC2 Out", "TxDP", "TxDC"};
+
+static const struct soc_enum vdac_src_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_VDAC_S_SFT,
+                               ARRAY_SIZE(vdac_src_sel), vdac_src_sel);
+
+static const struct snd_kcontrol_new vdac_src_sel_mux =
+       SOC_DAPM_ENUM("Voice DAC Source Mux", vdac_src_sel_enum);
+
+/* SRC1 power switch */
+static const struct snd_kcontrol_new src1_pwr_sw_control =
+       SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+                               RT5625_SRC1_PWR_SFT, 1, 0);
+
+/* SRC2 power switch */
+static const struct snd_kcontrol_new src2_pwr_sw_control =
+       SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+                               RT5625_SRC2_PWR_SFT, 1, 0);
+
+/* SRC2 source select MUX */
+static const char *src2_src_sel[] = {"TxDP", "TxDC"};
+
+static const struct soc_enum src2_src_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_SRC2_S_SFT,
+                       ARRAY_SIZE(src2_src_sel), src2_src_sel);
+
+static const struct snd_kcontrol_new src2_src_sel_mux =
+       SOC_DAPM_ENUM("SRC2 Source Mux", src2_src_sel_enum);
+
+/* VoDSP RxDP power switch */
+static const struct snd_kcontrol_new rxdp_pwr_sw_control =
+       SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+                               RT5625_RXDP_PWR_SFT, 1, 0);
+/* VoDSP RxDC power switch */
+static const struct snd_kcontrol_new rxdc_pwr_sw_control =
+       SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+                               RT5625_RXDC_PWR_SFT, 1, 0);
+
+/* VoDSP RxDP source select MUX */
+static const char *rxdp_src_sel[] = {"SRC1 Output", "ADCL to VoDSP",
+                       "Voice to Stereo", "ADCR to VoDSP"};
+
+static const struct soc_enum rxdp_src_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_RXDP_S_SFT,
+                       ARRAY_SIZE(rxdp_src_sel), rxdp_src_sel);
+
+static const struct snd_kcontrol_new rxdp_src_sel_mux =
+       SOC_DAPM_ENUM("RxDP Source Mux", rxdp_src_sel_enum);
+
+/* PCM source select MUX */
+static const char *pcm_src_sel[] = {"ADCR", "TxDP"};
+
+static const struct soc_enum pcm_src_sel_enum =
+       SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_PCM_S_SFT,
+                       ARRAY_SIZE(pcm_src_sel), pcm_src_sel);
+
+static const struct snd_kcontrol_new pcm_src_sel_mux =
+       SOC_DAPM_ENUM("PCM Source Mux", pcm_src_sel_enum);
+
+/* Main stereo record I2S source select MUX */
+static const char *rec_iis_src_sel[] = {"ADC", "Voice to Stereo", "SRC2 Output"};
+
+static const struct soc_enum rec_iis_src_enum =
+       SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_REC_IIS_S_SFT,
+                       ARRAY_SIZE(rec_iis_src_sel), rec_iis_src_sel);
+
+static const struct snd_kcontrol_new rec_iis_src_mux =
+       SOC_DAPM_ENUM("REC I2S Source Mux", rec_iis_src_enum);
+
+/* SPK volume input select MUX */
+static const char *spkvol_input_sel[] = {"VMID", "HP Mixer", "SPK Mixer", "Mono Mixer"};
+
+static const struct soc_enum spkvol_input_enum =
+       SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_SPKVOL_S_SFT,
+                       ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel);
+
+static const struct snd_kcontrol_new spkvol_input_mux =
+       SOC_DAPM_ENUM("SPK Vol Input Mux", spkvol_input_enum);
+
+/* HP volume input select MUX */
+static const char *hpvol_input_sel[] = {"VMID", "HP Mixer"};
+
+static const struct soc_enum hplvol_input_enum =
+       SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_L_S_SFT,
+                       ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel);
+
+static const struct snd_kcontrol_new hplvol_input_mux =
+       SOC_DAPM_ENUM("HPL Vol Input Mux", hplvol_input_enum);
+
+static const struct soc_enum hprvol_input_enum =
+       SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_R_S_SFT,
+                       ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel);
+
+static const struct snd_kcontrol_new hprvol_input_mux =
+       SOC_DAPM_ENUM("HPR Vol Input Mux", hprvol_input_enum);
+
+/* AUX volume input select MUX */
+static const struct soc_enum auxvol_input_enum =
+       SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_AUXVOL_S_SFT,
+                       ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel);
+
+static const struct snd_kcontrol_new auxvol_input_mux =
+       SOC_DAPM_ENUM("AUX Vol Input Mux", auxvol_input_enum);
+
+static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = {
+       /* supply */
+       SND_SOC_DAPM_SUPPLY("IIS Interface", RT5625_PWR_ADD1,
+                               RT5625_P_I2S_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("PLL1", RT5625_PWR_ADD2,
+                               RT5625_P_PLL1_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("PLL2", RT5625_PWR_ADD2,
+                               RT5625_P_PLL2_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_VMID("VMID"),
+       SND_SOC_DAPM_SUPPLY("DAC Ref", RT5625_PWR_ADD1,
+                               RT5625_P_DAC_REF_BIT, 0, NULL, 0),
+       /* microphone bias */
+       SND_SOC_DAPM_MICBIAS("Mic1 Bias", RT5625_PWR_ADD1,
+                                       RT5625_P_MB1_BIT, 0),
+       SND_SOC_DAPM_MICBIAS("Mic2 Bias", RT5625_PWR_ADD1,
+                                       RT5625_P_MB2_BIT, 0),
+
+       /* Input */
+       SND_SOC_DAPM_INPUT("Left LineIn"),
+       SND_SOC_DAPM_INPUT("Right LineIn"),
+       SND_SOC_DAPM_INPUT("Phone"),
+       SND_SOC_DAPM_INPUT("Mic1"),
+       SND_SOC_DAPM_INPUT("Mic2"),
+
+       SND_SOC_DAPM_PGA("Mic1 Boost", RT5625_PWR_ADD3,
+                       RT5625_P_MIC1_BST_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Mic2 Boost", RT5625_PWR_ADD3,
+                       RT5625_P_MIC2_BST_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Phone Rec Mixer", RT5625_PWR_ADD3,
+                       RT5625_P_PH_ADMIX_BIT, 0, NULL, 0),
+
+       SND_SOC_DAPM_MIXER("Left Rec Mixer", RT5625_PWR_ADD2,
+               RT5625_P_ADCL_RM_BIT, 0, rt5625_adcl_rec_mixer,
+               ARRAY_SIZE(rt5625_adcl_rec_mixer)),
+       SND_SOC_DAPM_MIXER("Right Rec Mixer", RT5625_PWR_ADD2,
+               RT5625_P_ADCR_RM_BIT, 0, rt5625_adcr_rec_mixer,
+               ARRAY_SIZE(rt5625_adcr_rec_mixer)),
+
+       SND_SOC_DAPM_ADC("Left ADC", NULL, RT5625_PWR_ADD2,
+                                       RT5625_P_ADCL_BIT, 0),
+       SND_SOC_DAPM_ADC("Right ADC", NULL, RT5625_PWR_ADD2,
+                                       RT5625_P_ADCR_BIT, 0),
+       SND_SOC_DAPM_PGA("ADC", SND_SOC_NOPM, 0, 0, NULL, 0),//johnny-3-9
+       SND_SOC_DAPM_MUX("PCM src select Mux", SND_SOC_NOPM, 0, 0,
+                               &pcm_src_sel_mux),
+       SND_SOC_DAPM_MUX("IIS src select Mux", SND_SOC_NOPM, 0, 0,
+                               &rec_iis_src_mux),
+
+       /* Input Stream Audio Interface */
+       SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Voice Capture", 0, SND_SOC_NOPM, 0, 0),
+
+       /* Voice DSP */
+       SND_SOC_DAPM_MUX("SRC2 src select Mux", SND_SOC_NOPM, 0, 0,
+                               &src2_src_sel_mux),
+       SND_SOC_DAPM_SWITCH("SRC1 Enable", SND_SOC_NOPM, 0, 0,
+                               &src1_pwr_sw_control),
+       SND_SOC_DAPM_SWITCH("SRC2 Enable", SND_SOC_NOPM, 0, 0,
+                               &src2_pwr_sw_control),
+       SND_SOC_DAPM_SWITCH("RxDP Enable", SND_SOC_NOPM, 0, 0,
+                               &rxdp_pwr_sw_control),
+       SND_SOC_DAPM_SWITCH("RxDC Enable", SND_SOC_NOPM, 0, 0,
+                               &rxdc_pwr_sw_control),
+
+       SND_SOC_DAPM_MUX("RxDP src select Mux", SND_SOC_NOPM, 0, 0,
+                               &rxdp_src_sel_mux),
+
+       SND_SOC_DAPM_PGA("TxDP", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("TxDC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("PDM", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("RxDP", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("RxDC", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA_E("Voice DSP", SND_SOC_NOPM,
+               0, 0, NULL, 0, rt5625_vodsp_event,
+               SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+       /* Output */
+       /* Output Stream Audio Interface */
+       SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 HiFi Playback",
+                               0, SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Voice Playback",
+                               0, SND_SOC_NOPM, 0, 0),
+
+       /* DAC function select Mux */
+       SND_SOC_DAPM_MUX_E("DAC fun Mux", SND_SOC_NOPM, 0, 0,
+               &dac_fun_sel_mux, rt5625_dac_func_event,
+               SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
+       /* VDAC source select Mux */
+       SND_SOC_DAPM_MUX_E("VDAC src Mux", SND_SOC_NOPM, 0, 0,
+               &vdac_src_sel_mux, rt5625_dac_func_event,
+               SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
+
+       SND_SOC_DAPM_DAC("Left DAC", NULL, RT5625_PWR_ADD2,
+                                       RT5625_P_DACL_BIT, 0),
+       SND_SOC_DAPM_DAC("Right DAC", NULL, RT5625_PWR_ADD2,
+                                       RT5625_P_DACR_BIT, 0),
+       SND_SOC_DAPM_DAC("Voice DAC", NULL, RT5625_PWR_ADD2,
+                                       RT5625_P_VDAC_BIT, 0),
+
+       SND_SOC_DAPM_PGA("Mic1 Volume", RT5625_PWR_ADD3,
+                               RT5625_P_MIC1_VOL_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Mic2 Volume", RT5625_PWR_ADD3,
+                               RT5625_P_MIC2_VOL_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Left LineIn Volume", RT5625_PWR_ADD3,
+                               RT5625_P_LV_L_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Right LineIn Volume", RT5625_PWR_ADD3,
+                               RT5625_P_LV_R_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Phone Volume", RT5625_PWR_ADD3,
+                               RT5625_P_PH_VOL_BIT, 0, NULL, 0),
+
+       SND_SOC_DAPM_PGA("Left DAC To Mixer", RT5625_PWR_ADD1,
+                               RT5625_P_DACL_MIX_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Right DAC To Mixer", RT5625_PWR_ADD1,
+                               RT5625_P_DACR_MIX_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("Voice DAC To Mixer", RT5625_PWR_ADD1,
+                               RT5625_P_VDAC_MIX_BIT, 0, NULL, 0),
+
+       SND_SOC_DAPM_MIXER("SPK Mixer", RT5625_PWR_ADD2,
+               RT5625_P_SM_BIT, 0, rt5625_spk_mixer,
+               ARRAY_SIZE(rt5625_spk_mixer)),  
+       SND_SOC_DAPM_MIXER("Mono HP Mixer", SND_SOC_NOPM, 0, 0,
+               rt5625_hp_mixer, ARRAY_SIZE(rt5625_hp_mixer)),
+       SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
+               rt5625_hpl_mixer, ARRAY_SIZE(rt5625_hpl_mixer)),
+       SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
+               rt5625_hpr_mixer, ARRAY_SIZE(rt5625_hpr_mixer)),
+       SND_SOC_DAPM_MIXER("Mono Mixer", RT5625_PWR_ADD2,
+               RT5625_P_MM_BIT, 0, rt5625_mono_mixer,
+               ARRAY_SIZE(rt5625_mono_mixer)),
+
+       SND_SOC_DAPM_MIXER_E("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0,
+               rt5625_hpmix_event, SND_SOC_DAPM_PRE_PMD |
+               SND_SOC_DAPM_POST_PMU),
+
+       SND_SOC_DAPM_MIXER("DAC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+       SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_MUX("SPK Vol Input Mux", SND_SOC_NOPM,
+                       0, 0, &spkvol_input_mux),
+       SND_SOC_DAPM_SUPPLY("SPKL Vol", RT5625_PWR_ADD3,
+                       RT5625_P_SPKL_VOL_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("SPKR Vol", RT5625_PWR_ADD3,
+                       RT5625_P_SPKR_VOL_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_MUX("HPL Vol Input Mux", RT5625_PWR_ADD3,
+                       RT5625_P_HPL_VOL_BIT, 0, &hplvol_input_mux),
+       SND_SOC_DAPM_MUX("HPR Vol Input Mux", RT5625_PWR_ADD3,
+                       RT5625_P_HPR_VOL_BIT, 0, &hprvol_input_mux),
+       SND_SOC_DAPM_MUX("AUX Vol Input Mux", RT5625_PWR_ADD3,
+                       RT5625_P_AUX_VOL_BIT, 0, &auxvol_input_mux),
+
+       SND_SOC_DAPM_SUPPLY("SPK Amp", RT5625_PWR_ADD1,
+                               RT5625_P_SPK_AMP_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_PGA_E("HP Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
+               rt5625_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                               
+       SND_SOC_DAPM_OUTPUT("SPKL"),
+       SND_SOC_DAPM_OUTPUT("SPKR"),
+       SND_SOC_DAPM_OUTPUT("HPL"),
+       SND_SOC_DAPM_OUTPUT("HPR"),
+       SND_SOC_DAPM_OUTPUT("AUX"),
+};
+
+static const struct snd_soc_dapm_route rt5625_dapm_routes[] = {
+       {"DAC Ref", NULL, "IIS Interface"},
+       {"DAC Ref", NULL, "PLL1"},
+       {"DAC Ref", NULL, "PLL2"},
+
+       /* Input */
+       {"Phone Rec Mixer", NULL, "Phone"},
+       {"Mic1 Boost", NULL, "Mic1"},
+       {"Mic2 Boost", NULL, "Mic2"},
+
+       {"Left Rec Mixer", "LineIn Capture Switch", "Left LineIn"},
+       {"Left Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"},
+       {"Left Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
+       {"Left Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
+       {"Left Rec Mixer", "HP Mixer Capture Switch", "Left HP Mixer"},
+       {"Left Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
+       {"Left Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"},
+
+       {"Right Rec Mixer", "LineIn Capture Switch", "Right LineIn"},
+       {"Right Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"},
+       {"Right Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
+       {"Right Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
+       {"Right Rec Mixer", "HP Mixer Capture Switch", "Right HP Mixer"},
+       {"Right Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
+       {"Right Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"},
+
+       {"Left ADC", NULL, "DAC Ref"},
+       {"Left ADC", NULL, "Left Rec Mixer"},
+       {"Right ADC", NULL, "DAC Ref"},
+       {"Right ADC", NULL, "Right Rec Mixer"},
+
+       {"PCM src select Mux", "TxDP", "TxDP"},
+       {"PCM src select Mux", "ADCR", "Right ADC"},
+
+       //johnny-3-9 [s]
+       {"ADC", NULL, "Left ADC"},
+       {"ADC", NULL, "Right ADC"},
+       {"IIS src select Mux", "ADC", "ADC"},
+       //{"IIS src select Mux", "ADC", "Left ADC"},
+       //{"IIS src select Mux", "ADC", "Right ADC"},
+       //johnny-3-9 [e]
+       {"IIS src select Mux", "Voice to Stereo", "AIF2RX"},
+       {"IIS src select Mux", "SRC2 Output", "SRC2 Enable"},
+
+       {"AIF2TX", NULL, "IIS Interface"},
+       {"AIF2TX", NULL, "PCM src select Mux"},
+       {"AIF1TX", NULL, "IIS Interface"},
+       {"AIF1TX", NULL, "IIS src select Mux"},
+
+       /* Output */
+       {"AIF1RX", NULL, "IIS Interface"},
+       {"AIF2RX", NULL, "IIS Interface"},
+
+       {"DAC fun Mux", "SRC2 Out", "SRC2 Enable"},
+       {"DAC fun Mux", "TxDP", "TxDP"},
+       {"DAC fun Mux", "TxDC", "TxDC"},
+       {"DAC fun Mux", "Stereo DAC", "AIF1RX"},
+
+       {"VDAC src Mux", "SRC2 Out", "SRC2 Enable"},
+       {"VDAC src Mux", "TxDP", "TxDP"},
+       {"VDAC src Mux", "TxDC", "TxDC"},
+       {"VDAC src Mux", "Voice PCM", "AIF2RX"},
+
+       {"Left DAC", NULL, "DAC Ref"},
+       {"Left DAC", NULL, "DAC fun Mux"},
+       {"Right DAC", NULL, "DAC Ref"},
+       {"Right DAC", NULL, "DAC fun Mux"},
+       {"Voice DAC", NULL, "DAC Ref"},
+       {"Voice DAC", NULL, "VDAC src Mux"},
+
+       {"Left LineIn Volume", NULL, "Left LineIn"},
+       {"Right LineIn Volume", NULL, "Right LineIn"},
+       {"Phone Volume", NULL, "Phone"},
+       {"Mic1 Volume", NULL, "Mic1 Boost"},
+       {"Mic2 Volume", NULL, "Mic2 Boost"},
+
+       {"Left DAC To Mixer", NULL, "Left DAC"},
+       {"Right DAC To Mixer", NULL, "Right DAC"},
+       {"Voice DAC To Mixer", NULL, "Voice DAC"},
+
+       {"DAC Mixer", NULL, "Left DAC To Mixer"},
+       {"DAC Mixer", NULL, "Right DAC To Mixer"},
+       {"Line Mixer", NULL, "Left LineIn Volume"},
+       {"Line Mixer", NULL, "Right LineIn Volume"},
+
+       {"Mono HP Mixer", "LineIn Playback Switch", "Line Mixer"},
+       {"Mono HP Mixer", "Phone Playback Switch", "Phone Volume"},
+       {"Mono HP Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+       {"Mono HP Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+       {"Mono HP Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+       {"Left HP Mixer", "ADC Playback Switch", "Left Rec Mixer"},
+       {"Left HP Mixer", "DAC Playback Switch", "Left DAC To Mixer"},
+       {"Right HP Mixer", "ADC Playback Switch", "Right Rec Mixer"},
+       {"Right HP Mixer", "DAC Playback Switch", "Right DAC To Mixer"},
+
+       {"SPK Mixer", "Line Mixer Playback Switch", "Line Mixer"},
+       {"SPK Mixer", "Phone Playback Switch", "Phone Volume"},
+       {"SPK Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+       {"SPK Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+       {"SPK Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
+       {"SPK Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+
+       {"Mono Mixer", "Line Mixer Playback Switch", "Line Mixer"},
+       {"Mono Mixer", "ADCL Playback Switch","Left Rec Mixer"},
+       {"Mono Mixer", "ADCR Playback Switch","Right Rec Mixer"},
+       {"Mono Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+       {"Mono Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+       {"Mono Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
+       {"Mono Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+
+       {"HP Mixer", NULL, "Mono HP Mixer"},
+       {"HP Mixer", NULL, "Left HP Mixer"},
+       {"HP Mixer", NULL, "Right HP Mixer"},
+
+       {"SPK Vol Input Mux", "VMID", "VMID"},
+       {"SPK Vol Input Mux", "HP Mixer", "HP Mixer"},
+       {"SPK Vol Input Mux", "SPK Mixer", "SPK Mixer"},
+       {"SPK Vol Input Mux", "Mono Mixer", "Mono Mixer"},
+       {"SPK Vol Input Mux", NULL, "SPKL Vol"},
+       {"SPK Vol Input Mux", NULL, "SPKR Vol"},
+       
+       {"HPL Vol Input Mux", "HP Mixer", "HP Mixer"},
+       {"HPL Vol Input Mux", "VMID", "VMID"},
+       {"HP Amp", NULL, "HPL Vol Input Mux"},
+       {"HPR Vol Input Mux", "HP Mixer", "HP Mixer"},
+       {"HPR Vol Input Mux", "VMID", "VMID"},
+       {"HP Amp", NULL, "HPR Vol Input Mux"},
+
+       {"AUX Vol Input Mux", "VMID", "VMID"},
+       {"AUX Vol Input Mux", "HP Mixer", "HP Mixer"},
+       {"AUX Vol Input Mux", "SPK Mixer", "SPK Mixer"},
+       {"AUX Vol Input Mux", "Mono Mixer", "Mono Mixer"},
+
+       {"SPKL", NULL, "SPK Amp"},
+       {"SPKL", NULL, "SPK Vol Input Mux"},
+       {"SPKR", NULL, "SPK Amp"},
+       {"SPKR", NULL, "SPK Vol Input Mux"},
+       {"HPL", NULL, "HP Amp"},
+       {"HPR", NULL, "HP Amp"},
+       {"AUX", NULL, "AUX Vol Input Mux"},
+
+       /* Voice DSP */
+       {"SRC1 Enable", "Switch", "AIF1RX"},
+
+       {"RxDP src select Mux", "Voice to Stereo", "AIF2RX"},
+       {"RxDP src select Mux", "ADCL to VoDSP", "Left ADC"},
+       {"RxDP src select Mux", "SRC1 Output", "SRC1 Enable"},
+       {"RxDP src select Mux", "ADCR to VoDSP", "Right ADC"},
+
+       {"RxDP Enable", "Switch", "RxDP src select Mux"},
+       {"RxDC Enable", "Switch", "Left ADC"},
+
+       {"RxDP", NULL, "RxDP Enable"},
+       {"RxDC", NULL, "RxDC Enable"},
+       {"PDM", NULL, "Right ADC"},
+
+       {"Voice DSP", NULL, "RxDP"},
+       {"Voice DSP", NULL, "RxDC"},
+       {"Voice DSP", NULL, "PDM"},
+
+       {"TxDP", NULL, "Voice DSP"},
+       {"TxDC", NULL, "Voice DSP"},
+
+       {"SRC2 src select Mux", "TxDP", "TxDP"},
+       {"SRC2 src select Mux", "TxDC", "TxDC"},
+       {"SRC2 Enable", "Switch", "SRC2 src select Mux"},
+};
+
+struct _pll_div{
+       u32 pll_in;
+       u32 pll_out;
+       u16 regvalue;
+};
+
+/**************************************************************
+  *    watch out!
   *    our codec support you to select different source as pll input, but if you 
   *    use both of the I2S audio interface and pcm interface instantially. 
   *    The two DAI must have the same pll setting params, so you have to offer
@@ -1440,80 +2308,76 @@ struct _pll_div{
   *    24576000.
   **************************************************************/
 static const struct _pll_div codec_master_pll1_div[] = {
-               
-       {   2048000,  8192000,   0x0ea0},
-       {   3686400,  8192000,   0x4e27},
-       {  12000000,  8192000,   0x456b},
-       {  13000000,  8192000,   0x495f},
-       {  13100000,  8192000,   0x0320},
-       {   2048000,  11289600,  0xf637},
-       {   3686400,  11289600,  0x2f22},
-       {  12000000,  11289600,  0x3e2f},
-       {  13000000,  11289600,  0x4d5b},
-       {  13100000,  11289600,  0x363b},
-       {   2048000,  16384000,  0x1ea0},
-       {   3686400,  16384000,  0x9e27},
-       {  12000000,  16384000,  0x452b},
-       {  13000000,  16384000,  0x542f},
-       {  13100000,  16384000,  0x03a0},
-       {   2048000,  16934400,  0xe625},
-       {   3686400,  16934400,  0x9126},
-       {  12000000,  16934400,  0x4d2c},
-       {  13000000,  16934400,  0x742f},
-       {  13100000,  16934400,  0x3c27},
-       {   2048000,  22579200,  0x2aa0},
-       {   3686400,  22579200,  0x2f20},
-       {  12000000,  22579200,  0x7e2f},
-       {  13000000,  22579200,  0x742f},
-       {  13100000,  22579200,  0x3c27},
-       {   2048000,  24576000,  0x2ea0},
-       {   3686400,  24576000,  0xee27},
-       {  11289600,  24576000,  0x950F},
-       {  12000000,  24576000,  0x2915},
-       {  12288000,  24576000,  0x0600},
-       {  13000000,  24576000,  0x772e},
-       {  13100000,  24576000,  0x0d20},
-       {  26000000,  24576000,  0x2027},
-       {  26000000,  22579200,  0x392f},
-       {  24576000,  22579200,  0x0921},
-       {  24576000,  24576000,  0x02a0},
+       {  2048000,   8192000,  0x0ea0},
+       {  3686400,   8192000,  0x4e27},
+       { 12000000,   8192000,  0x456b},
+       { 13000000,   8192000,  0x495f},
+       { 13100000,   8192000,  0x0320},
+       {  2048000,  11289600,  0xf637},
+       {  3686400,  11289600,  0x2f22},
+       { 12000000,  11289600,  0x3e2f},
+       { 13000000,  11289600,  0x4d5b},
+       { 13100000,  11289600,  0x363b},
+       {  2048000,  16384000,  0x1ea0},
+       {  3686400,  16384000,  0x9e27},
+       { 12000000,  16384000,  0x452b},
+       { 13000000,  16384000,  0x542f},
+       { 13100000,  16384000,  0x03a0},
+       {  2048000,  16934400,  0xe625},
+       {  3686400,  16934400,  0x9126},
+       { 12000000,  16934400,  0x4d2c},
+       { 13000000,  16934400,  0x742f},
+       { 13100000,  16934400,  0x3c27},
+       {  2048000,  22579200,  0x2aa0},
+       {  3686400,  22579200,  0x2f20},
+       { 12000000,  22579200,  0x7e2f},
+       { 13000000,  22579200,  0x742f},
+       { 13100000,  22579200,  0x3c27},
+       {  2048000,  24576000,  0x2ea0},
+       {  3686400,  24576000,  0xee27},
+       { 11289600,  24576000,  0x950F},
+       { 12000000,  24576000,  0x2915},
+       { 12288000,  24576000,  0x0600},
+       { 13000000,  24576000,  0x772e},
+       { 13100000,  24576000,  0x0d20},
+       { 26000000,  24576000,  0x2027},
+       { 26000000,  22579200,  0x392f},
+       { 24576000,  22579200,  0x0921},
+       { 24576000,  24576000,  0x02a0},
 };
 
 static const struct _pll_div codec_bclk_pll1_div[] = {
-
-       {   256000,   4096000,  0x3ea0},
-       {   352800,   5644800,  0x3ea0},
-       {   512000,   8192000,  0x3ea0},
-       {   705600,  11289600,  0x3ea0},
-       {  1024000,  16384000,  0x3ea0},        
-       {  1411200,  22579200,  0x3ea0},
-       {  1536000,  24576000,  0x3ea0},        
-       {  2048000,  16384000,  0x1ea0},        
-       {  2822400,  22579200,  0x1ea0},
-       {  3072000,  24576000,  0x1ea0},
-       {   705600,  11289600,  0x3ea0},
-       {   705600,   8467200,  0x3ab0},
-       {  2822400,  11289600,  0x1ee0},
-       {  3072000,  12288000,  0x1ee0},                        
+       {  256000,   4096000,  0x3ea0},
+       {  352800,   5644800,  0x3ea0},
+       {  512000,   8192000,  0x3ea0},
+       {  705600,  11289600,  0x3ea0},
+       { 1024000,  16384000,  0x3ea0}, 
+       { 1411200,  22579200,  0x3ea0},
+       { 1536000,  24576000,  0x3ea0}, 
+       { 2048000,  16384000,  0x1ea0}, 
+       { 2822400,  22579200,  0x1ea0},
+       { 3072000,  24576000,  0x1ea0},
+       {  705600,  11289600,  0x3ea0},
+       {  705600,   8467200,  0x3ab0},
+       { 2822400,  11289600,  0x1ee0},
+       { 3072000,  12288000,  0x1ee0},                 
 };
 
 static const struct _pll_div codec_vbclk_pll1_div[] = {
-
-       {   256000,   4096000,  0x3ea0},
-       {   352800,   5644800,  0x3ea0},
-       {   512000,   8192000,  0x3ea0},
-       {   705600,  11289600,  0x3ea0},
-       {  1024000,  16384000,  0x3ea0},        
-       {  1411200,  22579200,  0x3ea0},
-       {  1536000,  24576000,  0x3ea0},        
-       {  2048000,  16384000,  0x1ea0},        
-       {  2822400,  22579200,  0x1ea0},
-       {  3072000,  24576000,  0x1ea0},
-       {   705600,  11289600,  0x3ea0},
-       {   705600,   8467200,  0x3ab0},
+       {  256000,   4096000,  0x3ea0},
+       {  352800,   5644800,  0x3ea0},
+       {  512000,   8192000,  0x3ea0},
+       {  705600,  11289600,  0x3ea0},
+       { 1024000,  16384000,  0x3ea0}, 
+       { 1411200,  22579200,  0x3ea0},
+       { 1536000,  24576000,  0x3ea0}, 
+       { 2048000,  16384000,  0x1ea0}, 
+       { 2822400,  22579200,  0x1ea0},
+       { 3072000,  24576000,  0x1ea0},
+       {  705600,  11289600,  0x3ea0},
+       {  705600,   8467200,  0x3ab0},
 };
 
-
 struct _coeff_div_stereo {
        unsigned int mclk;
        unsigned int rate;
@@ -1527,436 +2391,494 @@ struct _coeff_div_voice {
        unsigned int reg64;
 };
 
+/* bclk is config to 32fs, if codec is choose to be slave mode,
+input bclk should be 32*fs */
 static const struct _coeff_div_stereo coeff_div_stereo[] = {
-
-       /*bclk is config to 32fs, if codec is choose to be slave mode , input bclk should be 32*fs */
-       {24576000,  48000,  0x3174,  0x1010},      
-       {12288000,  48000,  0x1174,  0x0000},
-       {18432000,  48000,  0x2174,  0x1111},
-       {36864000,  48000,  0x2274,  0x2020},
-       {49152000,  48000,  0xf074,  0x3030},
-       {24576000,  48000,  0x3172,  0x1010},
-       {24576000,   8000,  0xB274,  0x2424},
-       {24576000,  16000,  0xB174,  0x2222},
-       {24576000,  32000,  0xB074,  0x2121},
-       {22579200,  11025,  0X3374,  0x1414},
-       {22579200,  22050,  0X3274,  0x1212},
-       {22579200,  44100,  0X3174,  0x1010},
-       {0, 0, 0, 0},
+       {24576000, 48000, 0x3174, 0x1010}, 
+       {12288000, 48000, 0x1174, 0x0000},
+       {18432000, 48000, 0x2174, 0x1111},
+       {36864000, 48000, 0x2274, 0x2020},
+       {49152000, 48000, 0xf074, 0x3030},
+       {24576000, 48000, 0x3172, 0x1010},
+       {24576000,  8000, 0xB274, 0x2424},
+       {24576000, 16000, 0xB174, 0x2222},
+       {24576000, 32000, 0xB074, 0x2121},
+       {22579200, 11025, 0X3374, 0x1414},
+       {22579200, 22050, 0X3274, 0x1212},
+       {22579200, 44100, 0X3174, 0x1010},
+       {12288000,  8000, 0xB174, 0x2222},
+       {11289600, 44100, 0X3072, 0x0000},
 };
 
+/* bclk is config to 32fs, if codec is choose to be slave mode,
+input bclk should be 32*fs */
 static const struct _coeff_div_voice coeff_div_voice[] = {
-
-       /*bclk is config to 32fs, if codec is choose to be slave mode , input bclk should be 32*fs */
-       {24576000,  16000,  0x2622}, 
-       {24576000,   8000,  0x2824},
-       {0, 0, 0},
+       {24576000, 16000, 0x2622}, 
+       {24576000, 8000, 0x2824},
+       {2048000,8000,0x3000},
 };
 
 static int get_coeff(unsigned int mclk, unsigned int rate, int mode)
 {
        int i;
 
-       DBG("get_coeff mclk = %d, rate = %d, mode = %d\n", mclk, rate, mode);
+       pr_info("mclk = %d, rate = %d, mode = %d\n", mclk, rate, mode);
 
-       if (!mode) {
+       if (!mode)
                for (i = 0; i < ARRAY_SIZE(coeff_div_stereo); i++) {
-                       if ((coeff_div_stereo[i].rate == rate) && (coeff_div_stereo[i].mclk == mclk))
+                       if ((coeff_div_stereo[i].rate == rate) &&
+                               (coeff_div_stereo[i].mclk == mclk))
                                return i;
                }
-       } else {
+       else
                for (i = 0; i< ARRAY_SIZE(coeff_div_voice); i++) {
-                       if ((coeff_div_voice[i].rate == rate) && (coeff_div_voice[i].mclk == mclk))
+                       if ((coeff_div_voice[i].rate == rate) &&
+                               (coeff_div_voice[i].mclk == mclk))
                                return i;
                }
-       }
 
-       printk("can't find a matched mclk and rate in %s\n", 
+       pr_err("can't find a matched mclk and rate in %s\n",
               (mode ? "coeff_div_voice[]" : "coeff_div_audio[]"));
 
        return -EINVAL;
 }
 
 
-static int rt5625_codec_set_dai_pll(struct snd_soc_dai *codec_dai, 
-               int pll_id, unsigned int freq_in, unsigned int freq_out)
+static int rt5625_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
+                       unsigned int freq_in, unsigned int freq_out)
 {
-       int i;
-       int ret = -EINVAL;
-       struct snd_soc_codec *codec = codec_dai->codec;
-
-       DBG("enter %s pll_id = %d freq_in = %d freq_out = %d\n",
-              __func__, pll_id, freq_in, freq_out);
+       struct snd_soc_codec *codec = dai->codec;
+       int i, ret = -EINVAL;
 
-       if (pll_id < RT5625_PLL1_FROM_MCLK || pll_id > RT5625_PLL1_FROM_VBCLK)
+       if (pll_id < RT5625_PLL_MCLK || pll_id > RT5625_PLL_VBCLK)
                return -EINVAL;
 
-       if (!freq_in || !freq_out)
+       if (!freq_in || !freq_out) {
+               dev_info(dai->dev, "PLL is closed\n");
+               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                       RT5625_SCLK_MASK, RT5625_SCLK_MCLK);
                return 0;
+       }
 
-       if (RT5625_PLL1_FROM_MCLK == pll_id) {
-
+       if (RT5625_PLL_MCLK == pll_id) {
+               for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++)
+                       if ((freq_in == codec_master_pll1_div[i].pll_in) &&
+                               (freq_out == codec_master_pll1_div[i].pll_out)) {
+                               snd_soc_write(codec, RT5625_GEN_CTRL2,
+                                       RT5625_PLL1_S_MCLK);
+                               snd_soc_write(codec, RT5625_PLL_CTRL,
+                                       codec_master_pll1_div[i].regvalue);
+                               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                                       RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
+                               ret = 0;
+                               break;
+                       }
+       } else if (RT5625_PLL_MCLK_TO_VSYSCLK == pll_id) {
                for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++)
                {
                        if ((freq_in == codec_master_pll1_div[i].pll_in) && (freq_out == codec_master_pll1_div[i].pll_out))
                        {
-                               rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x0000);  /*PLL source from MCLK*/
-                               rt5625_write(codec, RT5625_PLL_CTRL, codec_master_pll1_div[i].regvalue);  /*set pll code*/
-                               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000);  /*enable pll1 power*/
-                               rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+                               snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000);  /*PLL source from MCLK*/
+                               snd_soc_write(codec, RT5625_PLL_CTRL, codec_master_pll1_div[i].regvalue);  /*set pll code*/
+                               snd_soc_update_bits(codec, RT5625_GEN_CTRL1, 0x0030, 0x0030);  /* Voice SYSCLK source from FLL1 */
                                ret = 0;
                        }
                }
-       } else if (RT5625_PLL1_FROM_BCLK == pll_id) {
-
+       }else if (RT5625_PLL_BCLK == pll_id) {
                for (i = 0; i < ARRAY_SIZE(codec_bclk_pll1_div); i ++)
-               {
-                       if ((freq_in == codec_bclk_pll1_div[i].pll_in) && (freq_out == codec_bclk_pll1_div[i].pll_out))
-                       {
-                               rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x2000);  /*PLL source from BCLK*/
-                               rt5625_write(codec, RT5625_PLL_CTRL, codec_bclk_pll1_div[i].regvalue);  /*set pll1 code*/
-                               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000);  /*enable pll1 power*/
-                               rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+                       if ((freq_in == codec_bclk_pll1_div[i].pll_in) &&
+                               (freq_out == codec_bclk_pll1_div[i].pll_out)) {
+                               snd_soc_write(codec, RT5625_GEN_CTRL2,
+                                       RT5625_PLL1_S_BCLK);
+                               snd_soc_write(codec, RT5625_PLL_CTRL,
+                                       codec_bclk_pll1_div[i].regvalue);
+                               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                                       RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
                                ret = 0;
+                               break;
                        }
-               }
-       } else if (RT5625_PLL1_FROM_VBCLK == pll_id) {
-
+       } else if (RT5625_PLL_VBCLK == pll_id) {
                for (i = 0; i < ARRAY_SIZE(codec_vbclk_pll1_div); i ++)
-               {
-                       if ((freq_in == codec_vbclk_pll1_div[i].pll_in) && (freq_out == codec_vbclk_pll1_div[i].pll_out))
-                       {
-                               rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x3000);  /*PLL source from VBCLK*/
-                               rt5625_write(codec, RT5625_PLL_CTRL, codec_vbclk_pll1_div[i].regvalue);  /*set pll1 code*/
-                               rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000);  /*enable pll1 power*/
-                               rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+                       if ((freq_in == codec_vbclk_pll1_div[i].pll_in) &&
+                               (freq_out == codec_vbclk_pll1_div[i].pll_out)) {
+                               snd_soc_write(codec, RT5625_GEN_CTRL2,
+                                       RT5625_PLL1_S_VBCLK);
+                               snd_soc_write(codec, RT5625_PLL_CTRL,
+                                       codec_vbclk_pll1_div[i].regvalue);
+                               snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                                       RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
                                ret = 0;
+                               break;
                        }
-               }
        }
-       return 0;
+
+       return ret;
 }
 
 
-static int rt5625_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai, 
+static int rt5625_set_dai_sysclk(struct snd_soc_dai *dai, 
                int clk_id, unsigned int freq, int dir)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct rt5625_priv * rt5625 = codec->private_data;
+       struct snd_soc_codec *codec = dai->codec;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       unsigned int val = 0;
 
-       DBG("sysclk freq %u for audio i2s\n", freq);
-       
-       if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
+       switch (dai->id) {
+       case RT5625_AIF1:
+               if (freq == rt5625->stereo_sysclk)
+                       return 0;
                rt5625->stereo_sysclk = freq;
-               return 0;
+               break;
+
+       case RT5625_AIF2:
+               if (freq == rt5625->voice_sysclk)
+                       return 0;
+               rt5625->voice_sysclk = freq;
+               break;
+
+       default:
+               return -EINVAL;
        }
-       
-       printk("unsupported sysclk freq %u for audio i2s\n", freq);
-              rt5625->stereo_sysclk=24576000;
-       
-       return 0;
-}
 
-static int rt5625_voice_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai, 
-               int clk_id, unsigned int freq, int dir)
-{
-       struct snd_soc_codec *codec = codec_dai->codec;
-       struct rt5625_priv * rt5625 = codec->private_data;
+       switch (clk_id) {
+       case RT5625_SCLK_S_MCLK:
+               break;
 
-       DBG("sysclk freq %u for voice pcm\n", freq);
+       case RT5625_SCLK_S_PLL:
+               val |= RT5625_SCLK_PLL1;
+               break;
 
-       if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
-               rt5625->voice_sysclk = freq;
-               return 0;
-       }                       
+       default:
+               dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+               return -EINVAL;
+       }
+       snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+                       RT5625_SCLK_MASK, val);
 
-       printk("unsupported sysclk freq %u for voice pcm\n", freq);
-              rt5625->voice_sysclk = 24576000;
+       dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
        
        return 0;
 }
 
-
-static int rt5625_hifi_pcm_hw_params(struct snd_pcm_substream *substream, 
+static int rt5625_hw_params(struct snd_pcm_substream *substream, 
                        struct snd_pcm_hw_params *params,
                        struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->card->codec;
-       struct rt5625_priv *rt5625 = codec->private_data;
+       struct snd_soc_codec *codec = rtd->codec;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       unsigned int iface = 0, rate = params_rate(params), coeff;
 
-       unsigned int iface = rt5625_read(codec, RT5625_MAIN_SDP_CTRL) & 0xfff3;
-       int rate = params_rate(params);
-       int coeff = get_coeff(rt5625->stereo_sysclk, rate, 0);
-       
-       DBG("enter %s rate = %d \n", __func__, rate);
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
 
-       switch (params_format(params))
-       {
-               case SNDRV_PCM_FORMAT_S16_LE:
-                       break;
-               case SNDRV_PCM_FORMAT_S20_3LE:
-                       iface |= 0x0004;
-               case SNDRV_PCM_FORMAT_S24_LE:
-                       iface |= 0x0008;
-               case SNDRV_PCM_FORMAT_S8:
-                       iface |= 0x000c;
-       }
-
-       rt5625_write(codec, RT5625_MAIN_SDP_CTRL, iface);
-       rt5625_write_mask(codec, 0x3a, 0xc801, 0xc801);   /*power i2s and dac ref*/
-       if (coeff >= 0) {
-               rt5625_write(codec, RT5625_STEREO_DAC_CLK_CTRL1, coeff_div_stereo[coeff].reg60);
-               rt5625_write(codec, RT5625_STEREO_DAC_CLK_CTRL2, coeff_div_stereo[coeff].reg62);
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               iface |= RT5625_I2S_DL_20;
+               break;
+
+       case SNDRV_PCM_FORMAT_S24_LE:
+               iface |= RT5625_I2S_DL_24;
+               break;
+
+       case SNDRV_PCM_FORMAT_S8:
+               iface |= RT5625_I2S_DL_8;
+               break;
+
+       default:
+               return -EINVAL;
        }
-       
-       return 0;
-}
 
-static int rt5625_voice_pcm_hw_params(struct snd_pcm_substream *substream, 
-                       struct snd_pcm_hw_params *params,
-                       struct snd_soc_dai *dai)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->card->codec;
-       struct rt5625_priv *rt5625 = codec->private_data;
-       struct snd_soc_dapm_widget *w;
-       unsigned int iface = rt5625_read(codec, RT5625_EXTEND_SDP_CTRL) & 0xfff3;
-       int rate = params_rate(params);
-       int coeff = get_coeff(rt5625->voice_sysclk, rate, 1);
+       switch (dai->id) {
+       case RT5625_AIF1:
+               coeff = get_coeff(rt5625->stereo_sysclk, rate, 0);
+               if (coeff < 0) {
+                       dev_err(codec->dev, "Unsupported clock setting\n");
+                       return -EINVAL;
+               }
+               snd_soc_write(codec, RT5625_DAC_CLK_CTRL1,
+                               coeff_div_stereo[coeff].reg60);
+               snd_soc_write(codec, RT5625_DAC_CLK_CTRL2,
+                               coeff_div_stereo[coeff].reg62);
+               snd_soc_update_bits(codec, RT5625_SDP_CTRL,
+                               RT5625_I2S_DL_MASK, iface);
+               break;
 
-       DBG("enter %s rate = %d \n", __func__, rate);
+       case RT5625_AIF2:
+               rate = 8000;
+               coeff = get_coeff(rt5625->voice_sysclk, rate, 1);
+               if (coeff < 0) {
+                       dev_err(codec->dev, "Unsupported clock setting\n");
+                       return -EINVAL;
+               }
+               snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1,
+                               coeff_div_voice[coeff].reg64);
+               iface |= 0x0100; //Voice SYSCLK source from FLL1
+               snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+                               RT5625_I2S_DL_MASK, iface);
+               break;
 
-       list_for_each_entry(w, &codec->dapm_widgets, list)
-       {
-               if (!w->sname)
-                       continue;
-               if (!strcmp(w->name, "Right ADC"))
-                       strcpy(w->sname, "Right ADC Voice Capture");
+       default:
+               return -EINVAL;
        }
-       
-       switch (params_format(params))
-       {
-               case SNDRV_PCM_FORMAT_S16_LE:
-                       break;
-               case SNDRV_PCM_FORMAT_S20_3LE:
-                       iface |= 0x0004;
-               case SNDRV_PCM_FORMAT_S24_LE:
-                       iface |= 0x0008;
-               case SNDRV_PCM_FORMAT_S8:
-                       iface |= 0x000c;
-       }
-       rt5625_write_mask(codec, 0x3a, 0x0801, 0x0801);   /*power i2s and dac ref*/
-       rt5625_write(codec, RT5625_EXTEND_SDP_CTRL, iface);
-       if (coeff >= 0)
-               rt5625_write(codec, RT5625_VOICE_DAC_PCMCLK_CTRL1, coeff_div_voice[coeff].reg64);
+
+#ifdef RT5625_F_SMT_PHO
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               rt5625->app_bmp |= RT5625_PLY_MASK;
+       else
+               rt5625->app_bmp |= RT5625_REC_MASK;
+#endif
 
        return 0;
 }
 
-
-static int rt5625_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+static int rt5625_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
+       struct snd_soc_codec *codec = dai->codec;
+       unsigned int iface = 0;
+       bool slave;
 
-       struct snd_soc_codec *codec = codec_dai->codec;
-       u16 iface = 0;
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               slave = false;
+               break;
 
-       DBG("enter %s fmt = %d\n", __func__, fmt);
+       case SND_SOC_DAIFMT_CBS_CFS:
+               slave = true;
+               break;
 
-       /*set master/slave interface*/
-       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK)
-       {
-               case SND_SOC_DAIFMT_CBM_CFM:
-                       iface = 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_CBS_CFS:
-                       iface = 0x8000;
-                       break;
-               default:
-                       return -EINVAL;
+       default:
+               return -EINVAL;
        }
 
-       /*interface format*/
-       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK)
-       {
-               case SND_SOC_DAIFMT_I2S:
-                       iface |= 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_LEFT_J:
-                       iface |= 0x0001;
-                       break;
-               case SND_SOC_DAIFMT_DSP_A:
-                       iface |= 0x0002;
-                       break;
-               case SND_SOC_DAIFMT_DSP_B:
-                       iface |= 0x0003;
-                       break;
-               default:
-                       return -EINVAL;                 
-       }
-
-       /*clock inversion*/
-       switch (fmt & SND_SOC_DAIFMT_INV_MASK)
-       {
-               case SND_SOC_DAIFMT_NB_NF:
-                       iface |= 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_IB_NF:
-                       iface |= 0x0080;
-                       break;
-               default:
-                       return -EINVAL;
-       }
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               break;
 
-       rt5625_write(codec, RT5625_MAIN_SDP_CTRL, iface);
-       return 0;
-}
+       case SND_SOC_DAIFMT_LEFT_J:
+               iface |= RT5625_I2S_DF_LEFT;
+               break;
 
-static int rt5625_voice_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
-       struct snd_soc_codec *codec = codec_dai->codec;
-       int iface;
+       case SND_SOC_DAIFMT_DSP_A:
+               iface |= RT5625_I2S_DF_PCM_A;
+               break;
 
-       DBG("enter %s\n", __func__);
-       /*set slave/master mode*/
-       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK)
-       {
-               case SND_SOC_DAIFMT_CBM_CFM:
-                       iface = 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_CBS_CFS:
-                       iface = 0x4000;
-                       break;
-               default:
-                       return -EINVAL;                 
-       }
+       case SND_SOC_DAIFMT_DSP_B:
+               iface |= RT5625_I2S_DF_PCM_B;
+               break;
 
-       switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK)
-       {
-               case SND_SOC_DAIFMT_I2S:
-                       iface |= 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_LEFT_J:
-                       iface |= 0x0001;
-                       break;
-               case SND_SOC_DAIFMT_DSP_A:
-                       iface |= 0x0002;
-                       break;
-               case SND_SOC_DAIFMT_DSP_B:
-                       iface |= 0x0003;
-                       break;
-               default:
-                       return -EINVAL;         
-       }
-
-       /*clock inversion*/
-       switch (fmt & SND_SOC_DAIFMT_INV_MASK)
-       {
-               case SND_SOC_DAIFMT_NB_NF:
-                       iface |= 0x0000;
-                       break;
-               case SND_SOC_DAIFMT_IB_NF:
-                       iface |= 0x0080;
-                       break;
-               default:
-                       return -EINVAL;                 
+       default:
+               return -EINVAL;                 
        }
 
-       iface |= 0x8000;      /*enable vopcm*/
-       rt5625_write(codec, RT5625_EXTEND_SDP_CTRL, iface);     
-       return 0;
-}
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
 
+       case SND_SOC_DAIFMT_IB_NF:
+               iface |= RT5625_I2S_BP_INV;
+               break;
 
-static int rt5625_hifi_codec_mute(struct snd_soc_dai *dai, int mute)
-{
-       struct snd_soc_codec *codec = dai->codec;
+       default:
+               return -EINVAL;
+       }
+       iface |= 0x8000;      /*enable vopcm*/
+       
+       switch (dai->id) {
+       case RT5625_AIF1:
+               if (slave)
+                       iface |= RT5625_I2S_M_SLV;
+               snd_soc_update_bits(codec, RT5625_SDP_CTRL,
+                       RT5625_I2S_M_MASK | RT5625_I2S_BP_MASK |
+                       RT5625_I2S_DF_MASK, iface);
+               break;
 
-       if (mute) 
-               rt5625_write_mask(codec, RT5625_STEREO_DAC_VOL, 0x8080, 0x8080);
-       else
-               rt5625_write_mask(codec, RT5625_STEREO_DAC_VOL, 0x0000, 0x8080);
+       case RT5625_AIF2:
+               if (slave)
+                       iface |= RT5625_PCM_M_SLV;
+               snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+                       RT5625_PCM_M_MASK | RT5625_I2S_BP_MASK |
+                       RT5625_I2S_DF_MASK, iface);
+               break;
+
+       default:
+               return -EINVAL;
+       }
        return 0;
 }
 
-static int rt5625_voice_codec_mute(struct snd_soc_dai *dai, int mute)
+#ifdef RT5625_F_SMT_PHO
+static int rt5625_trigger(struct snd_pcm_substream *substream,
+       int cmd, struct snd_soc_dai *dai)
 {
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_codec *codec = rtd->codec;
+       struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+       int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 
-       if (mute)
-               rt5625_write_mask(codec, RT5625_VOICE_DAC_OUT_VOL, 0x1000, 0x1000);
-       else 
-               rt5625_write_mask(codec, RT5625_VOICE_DAC_OUT_VOL, 0x0000, 0x1000);
-       return 0;
-}
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               if (capture)
+                       rt5625->app_bmp |= RT5625_REC_MASK;
+               else
+                       rt5625->app_bmp |= RT5625_PLY_MASK;
+               break;
 
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               if (capture)
+                       rt5625->app_bmp &= ~RT5625_REC_MASK;
+               else
+                       rt5625->app_bmp &= ~RT5625_PLY_MASK;
+               rt5625->app_bmp &= ~RT5625_VOIP_MASK;
+               break;
+
+       default:
+               break;
+       }
+
+       return 0;
+}
+#endif
 
 static int rt5625_set_bias_level(struct snd_soc_codec *codec, 
                        enum snd_soc_bias_level level)
 {
        switch(level) {
        case SND_SOC_BIAS_ON:
+#ifdef RT5625_DEMO
+               snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+                               RT5625_L_MUTE | RT5625_R_MUTE, 0);
+               snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+                               RT5625_L_MUTE | RT5625_R_MUTE, 0);
+#endif
                break;
+
        case SND_SOC_BIAS_PREPARE:
-               rt5625_write(codec, 0x26, 0x0000);
-               rt5625_write_mask(codec, 0x3c, 0x2000, 0x2000);     
-               rt5625_write_mask(codec, 0x3a, 0x000e, 0x000e);         
+               snd_soc_write(codec, RT5625_PD_CTRL, 0x0000);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+                               RT5625_P_MB1 | RT5625_P_MB2,
+                               RT5625_P_MB1 | RT5625_P_MB2);
                break;
+
        case SND_SOC_BIAS_STANDBY:
+#ifdef RT5625_DEMO
+               snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE,
+                       RT5625_L_MUTE | RT5625_R_MUTE);
+               snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE,
+                       RT5625_L_MUTE | RT5625_R_MUTE);
+               snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+                               RT5625_P_MB1 | RT5625_P_MB2, 0);
+#endif
+               if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
+                       snd_soc_write(codec, RT5625_PD_CTRL, 0);
+                       snd_soc_write(codec, RT5625_PWR_ADD1,
+                                       RT5625_P_MAIN_BIAS);
+                       snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF);
+                       codec->cache_only = false;
+                       snd_soc_cache_sync(codec);
+               }
                break;
+
        case SND_SOC_BIAS_OFF:
-               rt5625_write_mask(codec, 0x04, 0x8080, 0x8080);        /*mute hp*/
-               rt5625_write_mask(codec, 0x02, 0x8080, 0x8080);        /*mute spk*/
-               rt5625_write(codec, 0x3e, 0x0000);                                      //power off all bit
-               rt5625_write(codec, 0x3a, 0x0000);                                      //power off all bit
-               rt5625_write(codec, 0x3c, 0x0000);                                      //power off all bit
+#ifdef RT5625_DEMO
+               snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE,
+                       RT5625_L_MUTE | RT5625_R_MUTE);
+               snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+                       RT5625_L_MUTE | RT5625_R_MUTE,
+                       RT5625_L_MUTE | RT5625_R_MUTE);
+#endif
+               snd_soc_write(codec, RT5625_PWR_ADD1, 0x0000);
+               snd_soc_write(codec, RT5625_PWR_ADD2, 0x0000);
+               snd_soc_write(codec, RT5625_PWR_ADD3, 0x0000);
                
                break;
        }
-       codec->bias_level = level;
+       codec->dapm.bias_level = level;
+
+       return 0;
+}
+
+#ifdef RT5625_PROC     
+static int rt5625_proc_init(void);
+#endif
+
+static int rt5625_probe(struct snd_soc_codec *codec)
+{
+       int ret;
+
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+       if (ret != 0) {
+               dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+               return ret;
+       }
+       
+       #ifdef RT5625_PROC      
+       rt5625_proc_init();
+       #endif
+       
+       rt5625_reset(codec);
+       snd_soc_write(codec, RT5625_PD_CTRL, 0);
+       snd_soc_write(codec, RT5625_PWR_ADD1, RT5625_P_MAIN_BIAS);
+       snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF);
+#ifdef RT5625_DEMO
+       rt5625_reg_init(codec);
+#endif
+       codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
+       rt5625_codec = codec;
        return 0;
 }
 
+static int rt5625_remove(struct snd_soc_codec *codec)
+{
+       rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
 
-#define RT5625_STEREO_RATES    SNDRV_PCM_RATE_8000_48000
+#ifdef CONFIG_PM
+static int rt5625_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+       rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
 
-#define RT5626_VOICE_RATES SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000
+static int rt5625_resume(struct snd_soc_codec *codec)
+{
+       rt5625_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       return 0;
+}
+#else
+#define rt5625_suspend NULL
+#define rt5625_resume NULL
+#endif
 
+#define RT5625_STEREO_RATES SNDRV_PCM_RATE_8000_48000
+#define RT5625_VOICE_RATES SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000
 #define RT5625_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
                        SNDRV_PCM_FMTBIT_S20_3LE |\
                        SNDRV_PCM_FMTBIT_S24_LE |\
                        SNDRV_PCM_FMTBIT_S8)
 
-static struct snd_soc_dai_ops rt5625_dai_ops_hifi = {
-
-       .hw_params      = rt5625_hifi_pcm_hw_params,
-//     .digital_mute   = rt5625_hifi_codec_mute,
-       .set_fmt        = rt5625_hifi_codec_set_dai_fmt,
-       .set_pll        = rt5625_codec_set_dai_pll,
-       .set_sysclk     = rt5625_hifi_codec_set_dai_sysclk,
-
-};
-
-
-static struct snd_soc_dai_ops rt5625_dai_ops_voice = {
-
-       .hw_params      = rt5625_voice_pcm_hw_params,
-//     .digital_mute   = rt5625_voice_codec_mute,
-       .set_fmt        = rt5625_voice_codec_set_dai_fmt,
-       .set_pll        = rt5625_codec_set_dai_pll,
-       .set_sysclk     = rt5625_voice_codec_set_dai_sysclk,
-
+struct snd_soc_dai_ops rt5625_aif_dai_ops = {
+#ifdef RT5625_F_SMT_PHO
+       .trigger = rt5625_trigger,
+#endif
+       .hw_params = rt5625_hw_params,
+       .set_fmt = rt5625_set_dai_fmt,
+       .set_sysclk = rt5625_set_dai_sysclk,
+       .set_pll = rt5625_set_dai_pll,
 };
 
-
-
-struct snd_soc_dai rt5625_dai[] = {
-       /*hifi codec dai*/
+struct snd_soc_dai_driver rt5625_dai[] = {
        {
-               .name = "RT5625 HiFi",
-               .id = 1,
+               .name = "rt5625-aif1",
+               .id = RT5625_AIF1,
                .playback = {
                        .stream_name = "HiFi Playback",
                        .channels_min = 1,
@@ -1971,489 +2893,238 @@ struct snd_soc_dai rt5625_dai[] = {
                        .rates = RT5625_STEREO_RATES,
                        .formats = RT5625_FORMATS,
                },
-               
-               .ops = &rt5625_dai_ops_hifi,
+               .ops = &rt5625_aif_dai_ops,
        },
-
-       /*voice codec dai*/
        {
-               .name = "RT5625 Voice",
-               .id = 2,
+               .name = "rt5625-aif2",
+               .id = RT5625_AIF2,
                .playback = {
                        .stream_name = "Voice Playback",
                        .channels_min = 1,
-                       .channels_max = 1,
-                       .rates = RT5626_VOICE_RATES,
+                       .channels_max = 2,
+                       .rates = RT5625_VOICE_RATES,
                        .formats = RT5625_FORMATS,
                },
                .capture = {
                        .stream_name = "Voice Capture",
                        .channels_min = 1,
-                       .channels_max = 1,
-                       .rates = RT5626_VOICE_RATES,
+                       .channels_max = 2,
+                       .rates = RT5625_VOICE_RATES,
                        .formats = RT5625_FORMATS,
                },
-               
-               .ops = &rt5625_dai_ops_voice,
-
+               .ops = &rt5625_aif_dai_ops,
        },
 };
 
-EXPORT_SYMBOL_GPL(rt5625_dai);
-
-
-static void rt5625_work(struct work_struct *work)
-{
-       struct snd_soc_codec *codec =
-                container_of(work, struct snd_soc_codec, delayed_work.work);
-       rt5625_set_bias_level(codec, codec->bias_level);
-}
-
-
-#if defined(CONFIG_SND_HWDEP)
-
-#if REALTEK_HWDEP
-
-#define RT_CE_CODEC_HWDEP_NAME "rt56xx hwdep "
-
-
-static int rt56xx_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-       DBG("enter %s\n", __func__);
-       return 0;
-}
-
-static int rt56xx_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-       DBG("enter %s\n", __func__);
-       return 0;
-}
-
-
-static int rt56xx_hwdep_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct rt56xx_cmd rt56xx;
-       struct rt56xx_cmd __user *_rt56xx = arg;
-       struct rt56xx_reg_state *buf;
-       struct rt56xx_reg_state *p;
-       struct snd_soc_codec *codec = hw->private_data;
-
-       if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx)))
-               return -EFAULT;
-       buf = kmalloc(sizeof(*buf) * rt56xx.number, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-       if (copy_from_user(buf, rt56xx.buf, sizeof(*buf) * rt56xx.number)) {
-               goto err;
-       }
-       switch (cmd) {
-               case RT_READ_CODEC_REG_IOCTL:
-                       for (p = buf; p < buf + rt56xx.number; p++)
-                       {
-                               p->reg_value = codec->read(codec, p->reg_index);
-                       }
-                       if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
-                               goto err;
-                               
-                       break;
-               case RT_WRITE_CODEC_REG_IOCTL:
-                       for (p = buf; p < buf + rt56xx.number; p++)
-                               codec->write(codec, p->reg_index, p->reg_value);
-                       break;
-       }
-
-       kfree(buf);
-       return 0;
-
-err:
-       kfree(buf);
-       return -EFAULT;
-       
-}
-
-static int rt56xx_codec_dump_reg(struct snd_hwdep *hw, struct file *file, unsigned long arg)
-{
-       struct rt56xx_cmd rt56xx;
-       struct rt56xx_cmd __user *_rt56xx = arg;
-       struct rt56xx_reg_state *buf;
-       struct snd_soc_codec *codec = hw->private_data;
-       int number = codec->reg_cache_size;
-       int i;
-
-       DBG("enter %s, number = %d\n", __func__, number);       
-       if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx)))
-               return -EFAULT;
-       
-       buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-
-       for (i = 0; i < number; i++)
-       {
-               buf[i].reg_index = i << 1;
-               buf[i].reg_value = codec->read(codec, buf[i].reg_index);
-       }
-       if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * i))
-               goto err;
-       rt56xx.number = number;
-       if (copy_to_user(_rt56xx, &rt56xx, sizeof(rt56xx)))
-               goto err;
-       kfree(buf);
-       return 0;
-err:
-       kfree(buf);
-       return -EFAULT;
-       
-}
-
-static int rt56xx_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       if (cmd == RT_READ_ALL_CODEC_REG_IOCTL)
-       {
-               return rt56xx_codec_dump_reg(hw, file, arg);
-       }
-       else
-       {
-               return rt56xx_hwdep_ioctl_common(hw, file, cmd, arg);
-       }
-}
-
-int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
-{
-       struct snd_hwdep *hw;
-       struct snd_card *card = codec->card;
-       int err;
-
-       if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0)
-               return err;
-       
-       strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME);
-       hw->private_data = codec;
-       hw->ops.open = rt56xx_hwdep_open;
-       hw->ops.release = rt56xx_hwdep_release;
-       hw->ops.ioctl = rt56xx_hwdep_ioctl;
-       return 0;
-}
-
-#endif
+static struct snd_soc_codec_driver soc_codec_dev_rt5625 = {
+       .probe = rt5625_probe,
+       .remove = rt5625_remove,
+       .suspend = rt5625_suspend,
+       .resume = rt5625_resume,
+       .set_bias_level = rt5625_set_bias_level,
+       .reg_cache_size = 0x80,
+       .reg_word_size = sizeof(u16),
+       .reg_cache_default = rt5625_reg,
+       .volatile_register = rt5625_volatile_register,
+       .readable_register = rt5625_readable_register,
+       .reg_cache_step = 1,
+       .controls = rt5625_snd_controls,
+       .num_controls = ARRAY_SIZE(rt5625_snd_controls),
+       .dapm_widgets = rt5625_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(rt5625_dapm_widgets),
+       .dapm_routes = rt5625_dapm_routes,
+       .num_dapm_routes = ARRAY_SIZE(rt5625_dapm_routes),
+};
 
-#endif
+static const struct i2c_device_id rt5625_i2c_id[] = {
+       { "rt5625", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, rt5625_i2c_id);
 
-static int rt5625_init(struct snd_soc_device *socdev)
+static int rt5625_i2c_probe(struct i2c_client *i2c,
+                   const struct i2c_device_id *id)
 {
+       struct rt5625_priv *rt5625;
+       int ret;
+       struct rt5625_platform_data *pdata = pdata = i2c->dev.platform_data;
 
-       struct snd_soc_codec *codec = socdev->card->codec;
-       int ret = 0;
-
-       codec->name = "RT5625";
-       codec->owner = THIS_MODULE;
-       codec->read = rt5625_read;
-       codec->write = rt5625_write;
-       codec->set_bias_level = rt5625_set_bias_level;
-       codec->dai= rt5625_dai;
-       codec->num_dai = 2;
-       codec->reg_cache_step = 2;              
-       codec->reg_cache_size = ARRAY_SIZE(rt5625_reg)*2;
-       codec->reg_cache = kmemdup(rt5625_reg, sizeof(rt5625_reg), GFP_KERNEL);
-       if (codec->reg_cache == NULL)
+       rt5625 = kzalloc(sizeof(struct rt5625_priv), GFP_KERNEL);
+       if (NULL == rt5625)
                return -ENOMEM;
 
-       rt5625_reset(codec);
+       rt5625->spk_ctr_pin = pdata->spk_ctr_pin;
+       rt5625->spk_ctr_on = pdata->spk_ctr_on;
+       rt5625->spk_ctr_off = pdata->spk_ctr_off;
 
-       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
-       if (ret < 0 )
+       if(rt5625->spk_ctr_pin != INVALID_GPIO)
        {
-               printk(KERN_ERR "rt5625:  failed to create pcms\n");
-               goto pcm_err;
+               gpio_request(rt5625->spk_ctr_pin,NULL);
+               gpio_direction_output(rt5625->spk_ctr_pin,rt5625->spk_ctr_off);
+               rt5625->spk_ctr_status = 0;
        }
-       
-       rt5625_write(codec, RT5625_PD_CTRL_STAT, 0);
-       rt5625_write(codec, RT5625_PWR_MANAG_ADD1, PWR_MAIN_BIAS);
-       rt5625_write(codec, RT5625_PWR_MANAG_ADD2, PWR_MIXER_VREF);
-       rt5625_reg_init(codec);
-       rt5625_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
-       codec->bias_level = SND_SOC_BIAS_STANDBY;
-       schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(80));
-
-#if (RT5625_EQ_FUNC_ENA==1)    
-       rt5625_update_eqmode(codec,POP);
-#endif
-       
-       rt5625_add_controls(codec);
-       rt5625_add_widgets(codec);
-
-       #if defined(CONFIG_SND_HWDEP)
-
-               #if REALTEK_HWDEP
 
-                realtek_ce_init_hwdep(codec);
-
-               #endif
-
-       #endif
-
-       ret = snd_soc_init_card(socdev);
+       i2c_set_clientdata(i2c, rt5625);
 
+       ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5625,
+                       rt5625_dai, ARRAY_SIZE(rt5625_dai));
        if (ret < 0)
-       {
-               printk(KERN_ERR "rt5625: failed to register card\n");
-               goto card_err;
-       }
-       DBG("rt5625: initial ok\n");
-       return 0;
-
-       card_err:
-               snd_soc_free_pcms(socdev);
-               snd_soc_dapm_free(socdev);
-       
-       pcm_err:
-               kfree(codec->reg_cache);
-               return ret;
-       
-       
-}
-
-
-static int rt5625_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
-{
-       struct snd_soc_device *socdev = rt5625_socdev;
-       struct snd_soc_codec *codec = socdev->card->codec;
-       int ret;
-
-       i2c_set_clientdata(i2c, codec);
-       codec->control_data = i2c;
-
-       ret = rt5625_init(socdev);
-       if (ret < 0)
-               pr_err("failed to initialise rt5625\n");
+               kfree(rt5625);
 
        return ret;
 }
 
-static int rt5625_i2c_remove(struct i2c_client *client)
+static __devexit int rt5625_i2c_remove(struct i2c_client *i2c)
 {
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-       kfree(codec->reg_cache);
+       snd_soc_unregister_codec(&i2c->dev);
+       kfree(i2c_get_clientdata(i2c));
        return 0;
 }
 
-static const struct i2c_device_id rt5625_i2c_id[] = {
-               {"rt5625", 0},
-               {}
-};
-MODULE_DEVICE_TABLE(i2c, rt5625_i2c_id);
-static struct i2c_driver rt5625_i2c_driver = {
+struct i2c_driver rt5625_i2c_driver = {
        .driver = {
-               .name = "RT5625 I2C Codec",
+               .name = "rt5625",
                .owner = THIS_MODULE,
        },
-       .probe =    rt5625_i2c_probe,
-       .remove =   rt5625_i2c_remove,
+       .probe = rt5625_i2c_probe,
+       .remove   = __devexit_p(rt5625_i2c_remove),
        .id_table = rt5625_i2c_id,
 };
 
-
-static int rt5625_add_i2c_device(struct platform_device *pdev,
-                                const struct rt5625_setup_data *setup)
+static int __init rt5625_modinit(void)
 {
-#if 0
-       struct i2c_board_info info;
-       struct i2c_adapter *adapter;
-       struct i2c_client *client;
-#endif
-       int ret;
-
-       ret = i2c_add_driver(&rt5625_i2c_driver);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "can't add i2c driver\n");
-               return ret;
-       }
-#if 0
-       memset(&info, 0, sizeof(struct i2c_board_info));
-       info.addr = setup->i2c_address;
-       strlcpy(info.type, "rt5625", I2C_NAME_SIZE);
-
-       adapter = i2c_get_adapter(setup->i2c_bus);
-       if (!adapter) {
-               dev_err(&pdev->dev, "can't get i2c adapter %d\n",
-                       setup->i2c_bus);
-               goto err_driver;
-       }
+       return i2c_add_driver(&rt5625_i2c_driver);
+}
+module_init(rt5625_modinit);
 
-       client = i2c_new_device(adapter, &info);
-       i2c_put_adapter(adapter);
-       if (!client) {
-               dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
-                       (unsigned int)info.addr);
-               goto err_driver;
-       }
-#endif
-       return 0;
-#if 0
-err_driver:
+static void __exit rt5625_modexit(void)
+{
        i2c_del_driver(&rt5625_i2c_driver);
-       return -ENODEV;
-#endif
 }
+module_exit(rt5625_modexit);
 
+MODULE_DESCRIPTION("ASoC RT5625 driver");
+MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
+MODULE_LICENSE("GPL");
 
-static int rt5625_probe(struct platform_device *pdev)
-{
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct rt5625_setup_data *setup;
-       struct snd_soc_codec *codec;
-       struct rt5625_priv *rt5625;
-       int ret;
 
-       pr_info("RT5625 Audio Codec %s", RT5625_VERSION);
+#ifdef RT5625_PROC
 
-       if(socdev->codec_data)
+static ssize_t rt5625_proc_write(struct file *file, const char __user *buffer,
+                          unsigned long len, void *data)
+{
+       char *cookie_pot; 
+       char *p;
+       int reg;
+       int value;
+       
+       cookie_pot = (char *)vmalloc( len );
+       if (!cookie_pot) 
        {
-               setup = socdev->codec_data;             
-       }
-
-       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-       if (codec == NULL)
                return -ENOMEM;
-
-       rt5625 = kzalloc(sizeof(struct rt5625_priv), GFP_KERNEL);
-       if (rt5625 == NULL) {
-               kfree(codec);
-               return -ENOMEM;
-       }
-       codec->private_data = rt5625;
-       socdev->card->codec = codec;
-
-       mutex_init(&codec->mutex);
-       INIT_LIST_HEAD(&codec->dapm_widgets);
-       INIT_LIST_HEAD(&codec->dapm_paths);
-       rt5625_socdev = socdev;
-       INIT_DELAYED_WORK(&codec->delayed_work, rt5625_work);
-
-       ret = -ENODEV;
-//     if (setup->i2c_address) 
+       } 
+       else 
        {
-               codec->hw_write = (hw_write_t)i2c_master_send;
-               //codec->hw_read = (hw_read_t)i2c_master_recv;
-               ret = rt5625_add_i2c_device(pdev, setup);
-       }
-
-       if (ret != 0) {
-               kfree(codec->private_data);
-               kfree(codec);
-               socdev->card->codec = NULL;
+               if (copy_from_user( cookie_pot, buffer, len )) 
+                       return -EFAULT;
        }
-       return ret;
-}
 
-static int run_delayed_work(struct delayed_work *dwork)
-{
-       int ret;
+       switch(cookie_pot[0])
+       {
+       case 'd':
+       case 'D':
+               debug_write_read ++;
+               debug_write_read %= 2;
+               if(debug_write_read != 0)
+                       printk("Debug read and write reg on\n");
+               else    
+                       printk("Debug read and write reg off\n");       
+               break;  
+       case 'r':
+       case 'R':
+               printk("Read reg debug\n");             
+               if(cookie_pot[1] ==':')
+               {
+                       debug_write_read = 1;
+                       strsep(&cookie_pot,":");
+                       while((p=strsep(&cookie_pot,",")))
+                       {
+                               reg = simple_strtol(p,NULL,16);
+                               value = rt5625_read(rt5625_codec,reg);
+                               printk("rt5625_read:0x%04x = 0x%04x\n",reg,value);
+                       }
+                       debug_write_read = 0;
+                       printk("\n");
+               }
+               else
+               {
+                       printk("Error Read reg debug.\n");
+                       printk("For example: echo r:22,23,24,25>rt5625_ts\n");
+               }
+               break;
+       case 'w':
+       case 'W':
+               printk("Write reg debug\n");            
+               if(cookie_pot[1] ==':')
+               {
+                       debug_write_read = 1;
+                       strsep(&cookie_pot,":");
+                       while((p=strsep(&cookie_pot,"=")))
+                       {
+                               reg = simple_strtol(p,NULL,16);
+                               p=strsep(&cookie_pot,",");
+                               value = simple_strtol(p,NULL,16);
+                               rt5625_write(rt5625_codec,reg,value);
+                               printk("rt5625_write:0x%04x = 0x%04x\n",reg,value);
+                       }
+                       debug_write_read = 0;
+                       printk("\n");
+               }
+               else
+               {
+                       printk("Error Write reg debug.\n");
+                       printk("For example: w:22=0,23=0,24=0,25=0>rt5625_ts\n");
+               }
+               break;
+       case 'a':
+               printk("Dump reg \n");          
 
-       /* cancel any work waiting to be queued. */
-       ret = cancel_delayed_work(dwork);
+               for(reg = 0; reg < 0x6e; reg+=2)
+               {
+                       value = rt5625_read(rt5625_codec,reg);
+                       printk("rt5625_read:0x%04x = 0x%04x\n",reg,value);
+               }
 
-       /* if there was any work waiting then we run it now and
-        * wait for it's completion */
-       if (ret) {
-               schedule_delayed_work(dwork, 0);
-               flush_scheduled_work();
+               break;          
+       default:
+               printk("Help for rt5625_ts .\n-->The Cmd list: \n");
+               printk("-->'d&&D' Open or Off the debug\n");
+               printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>rt5625_ts\n");
+               printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rt5625_ts\n");
+               break;
        }
-       return ret;
-}
 
-
-static int rt5625_remove(struct platform_device *pdev)
-{
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->card->codec;
-
-       if (codec->control_data)
-               rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
-       run_delayed_work(&codec->delayed_work);
-       snd_soc_free_pcms(socdev);
-       snd_soc_dapm_free(socdev);
-       i2c_unregister_device(codec->control_data);
-       i2c_del_driver(&rt5625_i2c_driver);
-       kfree(codec->private_data);
-       kfree(codec);
-
-       return 0;
+       return len;
 }
 
+static const struct file_operations rt5625_proc_fops = {
+       .owner          = THIS_MODULE,
+};
 
-static int rt5625_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->card->codec;
-
-       rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-       return 0;
-}
-
-static int rt5625_resume(struct platform_device *pdev)
+static int rt5625_proc_init(void)
 {
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->card->codec;
-
-       
-//     int i;
-//     u8 data[3];
-//     u16 *cache = codec->reg_cache;
-
-#if 1
-       rt5625_reset(codec);
-       rt5625_write(codec, RT5625_PD_CTRL_STAT, 0);
-       rt5625_write(codec, RT5625_PWR_MANAG_ADD1, PWR_MAIN_BIAS);
-       rt5625_write(codec, RT5625_PWR_MANAG_ADD2, PWR_MIXER_VREF);
-       rt5625_reg_init(codec);
-#else
-       /* Sync reg_cache with the hardware */
-       for (i = 0; i < ARRAY_SIZE(rt5625_reg); i++) {
-               if (i == RT5625_RESET)
-                       continue;
-               data[0] = i << 1;
-               data[1] = (0xff00 & cache[i]) >> 8;
-               data[2] = 0x00ff & cache[i];
-               codec->hw_write(codec->control_data, data, 3);
+       struct proc_dir_entry *rt5625_proc_entry;
+       rt5625_proc_entry = create_proc_entry("driver/rt5625_ts", 0777, NULL);
+       if(rt5625_proc_entry != NULL)
+       {
+               rt5625_proc_entry->write_proc = rt5625_proc_write;
+               return 0;
        }
-
-       rt5625_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-#endif
-
-       /* charge rt5625 caps */
-       if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
-               rt5625_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
-               codec->bias_level = SND_SOC_BIAS_ON;
-               schedule_delayed_work(&codec->delayed_work,
-                                       msecs_to_jiffies(100));
+       else
+       {
+               printk("create proc error !\n");
+               return -1;
        }
-
-       return 0;
 }
-
-
-struct snd_soc_codec_device soc_codec_dev_rt5625 = {
-       .probe =        rt5625_probe,
-       .remove =       rt5625_remove,
-       .suspend =      rt5625_suspend,
-       .resume =       rt5625_resume,
-};
-
-EXPORT_SYMBOL_GPL(soc_codec_dev_rt5625);
-
-static int __init rt5625_modinit(void)
-{
-       return snd_soc_register_dais(rt5625_dai, ARRAY_SIZE(rt5625_dai));
-}
-
-static void __exit rt5625_exit(void)
-{
-       snd_soc_unregister_dais(rt5625_dai, ARRAY_SIZE(rt5625_dai));
-}
-
-module_init(rt5625_modinit);
-module_exit(rt5625_exit);
-MODULE_LICENSE("GPL");
+#endif
 
index cb4f73e8bccaf99db0aa34c2b79f321acaa064be..f61e439426dcbd7263d3c3d95e334bc300189cbc 100644 (file)
-#ifndef _RT5625_H
-#define _RT5625_H
-
-#define RT5625_RESET                                           0X00                    //RESET CODEC TO DEFAULT
-#define RT5625_SPK_OUT_VOL                                     0X02                    //SPEAKER OUT VOLUME
-#define RT5625_HP_OUT_VOL                                      0X04                    //HEADPHONE OUTPUT VOLUME
-#define RT5625_AUX_OUT_VOL                                     0X06                    //AUXOUT VOLUME
-#define RT5625_PHONEIN_VOL                                     0X08                    //PHONE INPUT VOLUME
-#define RT5625_LINE_IN_VOL                                     0X0A                    //LINE IN VOLUME
-#define RT5625_STEREO_DAC_VOL                          0X0C                    //STEREO DAC VOLUME
-#define RT5625_MIC_VOL                                         0X0E                    //MICROPHONE VOLUME
-#define RT5625_DAC_AND_MIC_CTRL                                0X10                    //STEREO DAC AND MIC ROUTING CONTROL
-#define RT5625_ADC_REC_GAIN                                    0X12                    //ADC RECORD GAIN
-#define RT5625_ADC_REC_MIXER                           0X14                    //ADC RECORD MIXER CONTROL
-#define RT5625_VOICE_DAC_OUT_VOL                       0X18                    //VOICE DAC OUTPUT VOLUME
-#define RT5625_VODSP_PDM_CTL                           0X1A                    //VODSP & PDM CONTROL
-#define RT5625_OUTPUT_MIXER_CTRL                       0X1C                    //OUTPUT MIXER CONTROL
-#define RT5625_VODSP_CTL                                       0X1E                    //VODSP CONTROL
-#define RT5625_MIC_CTRL                                                0X22                    //MICROPHONE CONTROL
-#define RT5625_DMIC_CTRL                                       0x24
-#define RT5625_PD_CTRL_STAT                                    0X26                    //POWER DOWN CONTROL/STATUS
-#define RT5625_DAC_ADC_VODAC_FUN_SEL           0X2E                    //STEREO DAC,VOICE DAC,STEREO ADC FUNCTION SELECT
-#define        RT5625_MAIN_SDP_CTRL                            0X34                    //MAIN SERIAL DATA PORT CONTROL(STEREO I2S)
-#define RT5625_EXTEND_SDP_CTRL                         0X36                    //EXTEND SERIAL DATA PORT CONTROL(VOICE I2S/PCM)
-#define        RT5625_PWR_MANAG_ADD1                           0X3A                    //POWER MANAGMENT ADDITION 1
-#define RT5625_PWR_MANAG_ADD2                          0X3C                    //POWER MANAGMENT ADDITION 2
-#define RT5625_PWR_MANAG_ADD3                          0X3E                    //POWER MANAGMENT ADDITION 3
-#define RT5625_GEN_CTRL_REG1                           0X40                    //GENERAL PURPOSE CONTROL REGISTER 1
-#define        RT5625_GEN_CTRL_REG2                            0X42                    //GENERAL PURPOSE CONTROL REGISTER 2
-#define RT5625_PLL_CTRL                                                0X44                    //PLL1 CONTROL
-#define RT5625_PLL2_CTRL                                       0X46                    //PLL2 CONTROL
-#define RT5625_LDO_CTRL                                                0X48                    //LDO CONTROL
-#define RT5625_GPIO_PIN_CONFIG                         0X4C                    //GPIO PIN CONFIGURATION
-#define RT5625_GPIO_PIN_POLARITY                       0X4E                    //GPIO PIN POLARITY     
-#define RT5625_GPIO_PIN_STICKY                         0X50                    //GPIO PIN STICKY       
-#define RT5625_GPIO_PIN_WAKEUP                         0X52                    //GPIO PIN WAKE UP
-#define RT5625_GPIO_PIN_STATUS                         0X54                    //GPIO PIN STATUS
-#define RT5625_GPIO_PIN_SHARING                                0X56                    //GPIO PIN SHARING
-#define        RT5625_OVER_TEMP_CURR_STATUS            0X58                    //OVER TEMPERATURE AND CURRENT STATUS
-#define RT5625_SOFT_VOL_CTRL                           0X5A                    //SOFT VOLUME CONTROL SETTING
-#define RT5625_GPIO_OUT_CTRL                           0X5C                    //GPIO OUTPUT PIN CONTRL
-#define RT5625_MISC_CTRL                                       0X5E                    //MISC CONTROL
-#define        RT5625_STEREO_DAC_CLK_CTRL1                     0X60                    //STEREO DAC CLOCK CONTROL 1
-#define RT5625_STEREO_DAC_CLK_CTRL2                    0X62                    //STEREO DAC CLOCK CONTROL 2
-#define RT5625_VOICE_DAC_PCMCLK_CTRL1          0X64                    //VOICE/PCM DAC CLOCK CONTROL 1
-#define RT5625_PSEDUEO_SPATIAL_CTRL                    0X68                    //PSEDUEO STEREO /SPATIAL EFFECT BLOCK CONTROL
-#define RT5625_PRIV_ADDR                                       0X6A                    //PRIVATE ADDRESS
-#define RT5625_PRIV_DATA                                       0X6C                    //PRIVATE DATA 
-#define RT5625_EQ_CTRL_ADC_HPF                         0X6E                    //EQ CONTROL AND STATUS /ADC HPF CONTROL
-#define RT5625_VODSP_REG_ADDR                  0x70                    //VODSP REGISTER ADDRESS
-#define RT5625_VODSP_REG_DATA                  0x72                    //VODSP REGISTER DATA
-#define RT5625_VODSP_REG_CMD                       0x74                        //VODSP REGISTER COMMAND
-
-
-/**************************************************************************************************
- *Bit define of Codec Register
- *************************************************************************************************/
-//global definition
-#define RT_L_MUTE                                              (0x1<<15)               //Mute Left Control
-#define RT_L_ZC                                                        (0x1<<14)               //Mute Left Zero-Cross Detector Control
-#define RT_R_MUTE                                              (0x1<<7)                //Mute Right Control
-#define RT_R_ZC                                                        (0x1<<6)                //Mute Right Zero-Cross Detector Control
-#define RT_M_HP_MIXER                                  (0x1<<15)               //Mute source to HP Mixer
-#define RT_M_SPK_MIXER                                 (0x1<<14)               //Mute source to Speaker Mixer
-#define RT_M_MONO_MIXER                                        (0x1<<13)               //Mute source to Mono Mixer
-
-//Phone Input Volume(0x08)
-#define M_PHONEIN_TO_HP_MIXER                  (0x1<<15)               //Mute Phone In volume to HP mixer
-#define M_PHONEIN_TO_SPK_MIXER                 (0x1<<14)               //Mute Phone In volume to speaker mixer
-
-
-//Mic Routing Control(0x10)
-#define M_MIC1_TO_HP_MIXER                             (0x1<<15)               //Mute MIC1 to HP mixer
-#define M_MIC1_TO_SPK_MIXER                            (0x1<<14)               //Mute MiC1 to SPK mixer
-#define M_MIC1_TO_MONO_MIXER                   (0x1<<13)               //Mute MIC1 to MONO mixer
-#define M_MIC2_TO_HP_MIXER                             (0x1<<11)               //Mute MIC2 to HP mixer
-#define M_MIC2_TO_SPK_MIXER                            (0x1<<10)               //Mute MiC2 to SPK mixer
-#define M_MIC2_TO_MONO_MIXER                   (0x1<<9)                //Mute MIC2 to MONO mixer
-#define M_DAC_TO_HPL_MIXER                             (0x1<<3)                //Mute DAC to HP left mixer
-#define M_DAC_TO_HPR_MIXER                             (0x1<<2)                //Mute DAC to HP right mixer
-#define M_DAC_TO_SPK_MIXER                             (0x1<<1)                //Mute DAC to SPK mixer
-#define M_DAC_TO_MONO_MIXER                            (0x1<<0)                //Mute DAC to MONO mixer
-
-
-
-//ADC Record Gain(0x12)
-#define M_ADC_L_TO_HP_MIXER                            (0x1<<15)               //Mute left of ADC to HP Mixer
-#define M_ADC_L_TO_MONO_MIXER                  (0x1<<14)               //Mute left of ADC to MONO Mixer
-#define ADC_L_ZC_DET                                   (0x1<<13)               //ADC Zero-Cross Detector Control
-#define ADC_L_GAIN_MASK                                        (0x1f<<8)               //ADC Record Gain Left channel Mask
-#define M_ADC_R_TO_HP_MIXER                            (0x1<<7)                //Mute right of ADC to HP Mixer
-#define M_ADC_R_TO_MONO_MIXER                  (0x1<<6)                //Mute right of ADC to MONO Mixer
-#define ADC_R_ZC_DET                                   (0x1<<5)                //ADC Zero-Cross Detector Control
-#define ADC_R_GAIN_MASK                                        (0x1f<<0)               //ADC Record Gain Right channel Mask
-
-//Voice DAC Output Volume(0x18)
-#define M_V_DAC_TO_HP_MIXER                            (0x1<<15)
-#define M_V_DAC_TO_SPK_MIXER                   (0x1<<14)
-#define M_V_DAC_TO_MONO_MIXER                  (0x1<<13)
-
-
-//AEC & PDM Control(0x1A)
-#define VODSP_SRC1_PWR                                 (0x1<<15)               //Enable SRC1 Power
-#define VODSP_SRC2_PWR                                 (0x1<<13)               //Enable SRC2 Power
-
-#define VODSP_SRC2_S_SEL_MASK                  (0x1<<12)               
-#define VODSP_SRC2_S_SEL_TXDP                  (0x0<<12)               //SRC2 source select AEC_TXDP
-#define VODSP_SRC2_S_SEL_TXDC                  (0x1<<12)               //SRC2 source select AEC_TXDC
-
-#define VODSP_RXDP_PWR                                 (0x1<<11)               //Enable AEC RXDP Power
-
-#define VODSP_RXDP_S_SEL_MASK                  (0x3<<9)                
-#define VODSP_RXDP_S_SEL_SRC1                  (0x0<<9)                //AEC RxDP source select SRC1 Output
-#define VODSP_RXDP_S_SEL_ADCL                  (0x1<<9)                //AEC RxDP source select ADC Left to AEC Digital Path
-#define VODSP_RXDP_S_SEL_VOICE                 (0x2<<9)                //AEC RxDP source select Voice to Stereo Digital Path
-#define VODSP_RXDP_S_SEL_ADCR                  (0x3<<9)                //AEC RxDP source select ADC Right to AEC Digital Path
-
-#define VODSP_RXDC_PWR                                 (0x1<<8)                //Enable AEC RXDC Power
-
-#define VOICE_PCM_S_SEL_MASK                   (0x1<<7)                
-#define VOICE_PCM_S_SEL_ADC_R                  (0x0<<7)                //VSADC PCM interface source select ADC R
-#define VOICE_PCM_S_SEL_AEC_TXDP               (0x1<<7)                //VSADC PCM interface source select AEC_TXDP
-
-#define REC_S_SEL_MASK                                 (0x3<<4)                
-#define REC_S_SEL_ADC                                  (0x0<<4)                //Main Stereo Record I2S source select ADC L/R
-#define REC_S_SEL_VOICE                                        (0x1<<4)                //Main Stereo Record I2S source select Voice to Stereo Digital Path
-#define REC_S_SEL_SRC2                                 (0x2<<4)                //Main Stereo Record I2S source select SRC2
-
-
-//Output Mixer Control(0x1C)
-#define        SPKOUT_N_SOUR_MASK                              (0x3<<14)       
-#define        SPKOUT_N_SOUR_LN                                (0x2<<14)
-#define        SPKOUT_N_SOUR_RP                                (0x1<<14)
-#define        SPKOUT_N_SOUR_RN                                (0x0<<14)
-
-#define SPKOUT_SEL_CLASS_D                             (0x1<<13)
-#define SPKOUT_SEL_CLASS_AB                            (0x0<<13)
-
-#define SPK_CLASS_AB_S_AMP                             (0x0<<12)
-#define SPK_CALSS_AB_W_AMP                             (0x1<<12)
-
-#define SPKOUT_INPUT_SEL_MASK                  (0x3<<10)
-#define SPKOUT_INPUT_SEL_MONOMIXER             (0x3<<10)
-#define SPKOUT_INPUT_SEL_SPKMIXER              (0x2<<10)
-#define SPKOUT_INPUT_SEL_HPMIXER               (0x1<<10)
-#define SPKOUT_INPUT_SEL_VMID                  (0x0<<10)
-
-#define HPL_INPUT_SEL_HPLMIXER                 (0x1<<9)
-#define HPR_INPUT_SEL_HPRMIXER                 (0x1<<8)        
-
-#define AUXOUT_INPUT_SEL_MASK                  (0x3<<6)
-#define AUXOUT_INPUT_SEL_MONOMIXER             (0x3<<6)
-#define AUXOUT_INPUT_SEL_SPKMIXER              (0x2<<6)
-#define AUXOUT_INPUT_SEL_HPMIXER               (0x1<<6)
-#define AUXOUT_INPUT_SEL_VMID                  (0x0<<6)
-
-
-//Voice DSP Control(0x1E)
-#define VODSP_SYSCLK_S_SEL_MASK                        (0x1<<15)
-#define VODSP_SYSCLK_S_SEL_M_CLK               (0x0<<15)
-#define VODSP_SYSCLK_S_SEL_V_CLK               (0x1<<15)
-
-#define VODSP_LRCK_SEL_MASK                            (0x1<<13)
-#define VODSP_LRCK_SEL_8K                              (0x0<<13)
-#define VODSP_LRCK_SEL_16K                             (0x1<<13)
-
-#define VODSP_TEST_MODE_ENA                            (0x1<<3)
-#define VODSP_NO_BP_MODE_ENA                   (0x1<<2)
-#define VODSP_NO_PD_MODE_ENA                   (0x1<<1)
-#define VODSP_NO_RST_MODE_ENA                  (0x1<<0)
-
-
-
-
-//Micphone Control define(0x22)
-#define MIC1           1
-#define MIC2           2
-#define MIC_BIAS_90_PRECNET_AVDD       1
-#define        MIC_BIAS_75_PRECNET_AVDD        2
-
-#define MIC1_BOOST_CONTROL_MASK                (0x3<<10)
-#define MIC1_BOOST_CONTROL_BYPASS      (0x0<<10)
-#define MIC1_BOOST_CONTROL_20DB                (0x1<<10)
-#define MIC1_BOOST_CONTROL_30DB                (0x2<<10)
-#define MIC1_BOOST_CONTROL_40DB                (0x3<<10)
-
-#define MIC2_BOOST_CONTROL_MASK                (0x3<<8)
-#define MIC2_BOOST_CONTROL_BYPASS      (0x0<<8)
-#define MIC2_BOOST_CONTROL_20DB                (0x1<<8)
-#define MIC2_BOOST_CONTROL_30DB                (0x2<<8)
-#define MIC2_BOOST_CONTROL_40DB                (0x3<<8)
-
-#define MIC1_BIAS_VOLT_CTRL_MASK       (0x1<<5)
-#define MIC1_BIAS_VOLT_CTRL_90P                (0x0<<5)
-#define MIC1_BIAS_VOLT_CTRL_75P                (0x1<<5)
-
-#define MIC2_BIAS_VOLT_CTRL_MASK       (0x1<<4)
-#define MIC2_BIAS_VOLT_CTRL_90P                (0x0<<4)
-#define MIC2_BIAS_VOLT_CTRL_75P                (0x1<<4)
-
-//PowerDown control of register(0x26)
-//power management bits
-#define RT_PWR_PR7                                     (0x1<<15)       //write this bit to power down the Speaker Amplifier
-#define RT_PWR_PR6                                     (0x1<<14)       //write this bit to power down the Headphone Out and MonoOut
-#define RT_PWR_PR5                                     (0x1<<13)       //write this bit to power down the internal clock(without PLL)
-#define RT_PWR_PR3                                     (0x1<<11)       //write this bit to power down the mixer(vref/vrefout out off)
-#define RT_PWR_PR2                                     (0x1<<10)       //write this bit to power down the mixer(vref/vrefout still on)
-#define RT_PWR_PR1                                     (0x1<<9)        //write this bit to power down the dac
-#define RT_PWR_PR0                                     (0x1<<8)        //write this bit to power down the adc
-#define RT_PWR_REF                                     (0x1<<3)        //read only
-#define RT_PWR_ANL                                     (0x1<<2)        //read only     
-#define RT_PWR_DAC                                     (0x1<<1)        //read only
-#define RT_PWR_ADC                                     (0x1)           //read only
-
-
-//Stereo DAC/Voice DAC/Stereo ADC function(0x2E)
-#define DAC_FUNC_SEL_MASK                      (0x3<<12)
-#define DAC_FUNC_SEL_DAC                       (0x0<<12)               
-#define DAC_FUNC_SEL_SRC2                      (0x1<<12)
-#define DAC_FUNC_SEL_VODSP_TXDP                (0x2<<12)
-#define DAC_FUNC_SEL_VODSP_TXDC                (0x3<<12)
-
-#define VODAC_SOUR_SEL_MASK                    (0x7<<8)
-#define VODAC_SOUR_SEL_VOICE           (0x0<<8)        
-#define VODAC_SOUR_SEL_SRC2                    (0x1<<8)
-#define VODAC_SOUR_SEL_VODSP_TXDP      (0x2<<8)
-#define VODAC_SOUR_SEL_VODSP_TXDC      (0x3<<8)
-
-#define ADCR_FUNC_SEL_MASK                     (0x3<<4)
-#define ADCR_FUNC_SEL_ADC                      (0x0<<4)
-#define ADCR_FUNC_SEL_VOADC                    (0x1<<4)
-#define ADCR_FUNC_SEL_VODSP                    (0x2<<4)
-#define ADCR_FUNC_SEL_PDM                      (0x3<<4)
-
-#define ADCL_FUNC_SEL_MASK                     (0x3<<0)
-#define ADCL_FUNC_SEL_ADC                      (0x0<<0)
-#define ADCL_FUNC_SEL_VODSP                    (0x1<<0)
-
-//Main Serial Data Port Control(0x34)                  
-#define MAIN_I2S_MODE_SEL                      (0x1<<15)               //0:Master mode 1:Slave mode
-#define MAIN_I2S_SADLRCK_CTRL          (0x1<<14)               //0:Disable,ADC and DAC use the same fs,1:Enable
-
-#define MAIN_I2S_PCM_MODE                      (0x1<<6)                //0:Normal SADLRCK/SDALRCK,1:Invert SADLRCK/SDALRCK 
-//Data Length Slection
-#define MAIN_I2S_DL_MASK                       (0x3<<2)                //main i2s Data Length mask     
-#define MAIN_I2S_DL_16                         (0x0<<2)                //16 bits
-#define MAIN_I2S_DL_20                         (0x1<<2)                //20 bits
-#define        MAIN_I2S_DL_24                          (0x2<<2)                //24 bits
-#define MAIN_I2S_DL_32                         (0x3<<2)                //8 bits
-
-//PCM Data Format Selection
-#define MAIN_I2S_DF_MASK                       (0x3)                   //main i2s Data Format mask
-#define MAIN_I2S_DF_I2S                                (0x0)                   //I2S FORMAT 
-#define MAIN_I2S_DF_LEFT                       (0x1)                   //LEFT JUSTIFIED format
-#define        MAIN_I2S_DF_PCM_A                       (0x2)                   //PCM Mode A
-#define MAIN_I2S_DF_PCM_B                              (0x3)                   //PCM Mode B
-
-//Extend Serial Data Port Control(0x36)
-#define EXT_I2S_FUNC_ENABLE                    (0x1<<15)               //Enable PCM interface on GPIO 1,3,4,5  0:GPIO function,1:Voice PCM interface
-#define EXT_I2S_MODE_SEL                       (0x1<<14)               //0:Master      ,1:Slave
-#define EXT_I2S_AUTO_CLK_CTRL          (0x1<<13)               //0:Disable,1:Enable
-#define EXT_I2S_BCLK_POLARITY          (0x1<<7)                //0:Normal 1:Invert
-#define EXT_I2S_PCM_MODE                       (0x1<<6)                //0:Normal VSLRCK,1:Invert VSLRCK 
-//Data Length Slection
-#define EXT_I2S_DL_MASK                                (0x3<<2)                //Extend i2s Data Length mask   
-#define EXT_I2S_DL_32                          (0x3<<2)                //8 bits
-#define        EXT_I2S_DL_24                           (0x2<<2)                //24 bits
-#define EXT_I2S_DL_20                          (0x1<<2)                //20 bits
-#define EXT_I2S_DL_16                          (0x0<<2)                //16 bits
-
-//Voice Data Format
-#define EXT_I2S_DF_MASK                                (0x3)                   //Extend i2s Data Format mask
-#define EXT_I2S_DF_I2S                         (0x0)                   //I2S FORMAT 
-#define EXT_I2S_DF_LEFT                                (0x1)                   //LEFT JUSTIFIED format
-#define        EXT_I2S_DF_PCM_A                        (0x2)                   //PCM Mode A
-#define EXT_I2S_DF_PCM_B                       (0x3)                   //PCM Mode B
-
-//Power managment addition 1 (0x3A),0:Disable,1:Enable
-#define PWR_DAC_DF2SE_L                                (0x1<<15)
-#define PWR_DAC_DF2SE_R                                (0x1<<14)
-#define PWR_ZC_DET_PD                          (0x1<<13)
-#define PWR_I2S_INTERFACE                      (0x1<<11)
-#define PWR_AMP_POWER                          (0x1<<10)
-#define PWR_HP_OUT_AMP                         (0x1<<9)
-#define PWR_HP_OUT_ENH_AMP                     (0x1<<8)
-#define PWR_VOICE_DF2SE                                (0x1<<7)
-#define PWR_SOFTGEN_EN                         (0x1<<6)        
-#define        PWR_MIC_BIAS1_DET                       (0x1<<5)
-#define        PWR_MIC_BIAS2_DET                       (0x1<<4)
-#define PWR_MIC_BIAS1                          (0x1<<3)        
-#define PWR_MIC_BIAS2                          (0x1<<2)        
-#define PWR_MAIN_BIAS                          (0x1<<1)
-#define PWR_DAC_REF                                    (0x1)
-
-
-//Power managment addition 2(0x3C),0:Disable,1:Enable
-#define PWR_PLL1                                       (0x1<<15)
-#define PWR_PLL2                                       (0x1<<14)
-#define PWR_MIXER_VREF                         (0x1<<13)
-#define PWR_TEMP_SENSOR                                (0x1<<12)
-#define PWR_AUX_ADC                                    (0x1<<11)
-#define PWR_VOICE_CLOCK                                (0x1<<10)
-#define PWR_L_DAC_CLK                          (0x1<<9)
-#define PWR_R_DAC_CLK                          (0x1<<8)
-#define PWR_L_ADC_CLK                          (0x1<<7)
-#define PWR_R_ADC_CLK                          (0x1<<6)
-#define PWR_L_HP_MIXER                         (0x1<<5)
-#define PWR_R_HP_MIXER                         (0x1<<4)
-#define PWR_SPK_MIXER                          (0x1<<3)
-#define PWR_MONO_MIXER                         (0x1<<2)
-#define PWR_L_ADC_REC_MIXER                    (0x1<<1)
-#define PWR_R_ADC_REC_MIXER                    (0x1)
-
-
-//Power managment addition 3(0x3E),0:Disable,1:Enable
-#define PWR_OSC_EN                                     (0x1<<15)
-#define PWR_AUXOUT_VOL                         (0x1<<14)
-#define PWR_SPK_OUT                                    (0x1<<13)
-#define PWR_SPK_OUT_N                          (0x1<<12)
-#define PWR_HP_L_OUT_VOL                       (0x1<<11)
-#define PWR_HP_R_OUT_VOL                       (0x1<<10)
-#define PWR_VODSP_INTERFACE                    (0x1<<9)
-#define PWR_I2C_FOR_VODSP                      (0x1<<8)
-#define PWR_LINE_IN_L                          (0x1<<7)
-#define PWR_LINE_IN_R                          (0x1<<6)
-#define PWR_PHONE_VOL                          (0x1<<5)
-#define PWR_PHONE_ADMIXER                      (0x1<<4)
-#define PWR_MIC1_VOL_CTRL                      (0x1<<3)
-#define PWR_MIC2_VOL_CTRL                      (0x1<<2)
-#define PWR_MIC1_BOOST                         (0x1<<1)
-#define PWR_MIC2_BOOST                         (0x1)
-
-//General Purpose Control Register 1(0x40)
-#define GP_CLK_FROM_PLL                                (0x1<<15)       
-#define GP_CLK_FROM_MCLK                       (0x0<<15)       
-
-#define GP_DAC_HI_PA_ENA                       (0x1<<10)       //Enable DAC High Pass Filter
-
-#define GP_EXTCLK_S_SEL_PLL2           (0x1<<6)
-#define GP_EXTCLK_S_SEL_PLL1           (0x0<<6)        
-
-#define GP_EXTCLK_DIR_SEL_OUTPUT       (0x1<<5)
-#define GP_EXTCLK_DIR_SEL_INTPUT       (0x0<<5)
-
-#define GP_VOSYS_S_SEL_PLL2                    (0x0<<4)
-#define GP_VOSYS_S_SEL_EXTCLK          (0x1<<4)
-
-#define GP_SPK_AMP_CTRL_MASK           (0x7<<1)
-#define GP_SPK_AMP_CTRL_RATIO_225      (0x0<<1)                //2.25 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_200      (0x1<<1)                //2.00 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_175      (0x2<<1)                //1.75 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_150      (0x3<<1)                //1.50 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_125      (0x4<<1)                //1.25 Vdd      
-#define GP_SPK_AMP_CTRL_RATIO_100      (0x5<<1)                //1.00 Vdd
-
-//General Purpose Control Register 2(0x42)
-#define GP2_PLL1_SOUR_SEL_MASK         (0x3<<12)
-#define GP2_PLL1_SOUR_SEL_MCLK         (0x0<<12)
-#define GP2_PLL1_SOUR_SEL_BCLK         (0x2<<12)
-#define GP2_PLL1_SOUR_SEL_VBCLK                (0x3<<12)
-
-//PLL Control(0x44)
-#define PLL_M_CODE_MASK                                0xF                             //PLL M code mask
-#define PLL_K_CODE_MASK                                (0x7<<4)                //PLL K code mask
-#define PLL_BYPASS_N                           (0x1<<7)                //bypass PLL N code
-#define PLL_N_CODE_MASK                                (0xFF<<8)               //PLL N code mask
-
-#define PLL_CTRL_M_VAL(m)              ((m)&0xf)
-#define PLL_CTRL_K_VAL(k)              (((k)&0x7)<<4)
-#define PLL_CTRL_N_VAL(n)              (((n)&0xff)<<8)
-
-//PLL2 CONTROL
-#define PLL2_ENA                                       (0x1<<15)
-#define PLL_2_RATIO_8X                         (0x0)
-#define PLL_2_RATIO_16X                                (0x1)
-
-//LDO Control(0x48)
-#define LDO_ENABLE                                     (0x1<<15)
-
-#define LDO_OUT_VOL_CTRL_MASK          (0xf<<0)
-#define LDO_OUT_VOL_CTRL_1_55V         (0xf<<0)
-#define LDO_OUT_VOL_CTRL_1_50V         (0xe<<0)
-#define LDO_OUT_VOL_CTRL_1_45V         (0xd<<0)
-#define LDO_OUT_VOL_CTRL_1_40V         (0xc<<0)
-#define LDO_OUT_VOL_CTRL_1_35V         (0xb<<0)
-#define LDO_OUT_VOL_CTRL_1_30V         (0xa<<0)
-#define LDO_OUT_VOL_CTRL_1_25V         (0x9<<0)
-#define LDO_OUT_VOL_CTRL_1_20V         (0x8<<0)
-#define LDO_OUT_VOL_CTRL_1_15V         (0x7<<0)
-#define LDO_OUT_VOL_CTRL_1_05V         (0x6<<0)
-#define LDO_OUT_VOL_CTRL_1_00V         (0x5<<0)
-#define LDO_OUT_VOL_CTRL_0_95V         (0x4<<0)
-#define LDO_OUT_VOL_CTRL_0_90V         (0x3<<0)
-#define LDO_OUT_VOL_CTRL_0_85V         (0x2<<0)
-#define LDO_OUT_VOL_CTRL_0_80V         (0x1<<0)
-#define LDO_OUT_VOL_CTRL_0_75V         (0x0<<0)
-
-
-
-//GPIO Pin Configuration(0x4C)
-#define GPIO_1                                         (0x1<<1)
-#define        GPIO_2                                          (0x1<<2)
-#define        GPIO_3                                          (0x1<<3)
-#define GPIO_4                                         (0x1<<4)
-#define GPIO_5                                         (0x1<<5)
-
-
-////INTERRUPT CONTROL(0x5E)
-#define DISABLE_FAST_VREG                      (0x1<<15)
-
-#define AVC_TARTGET_SEL_MASK           (0x3<<12)
-#define        AVC_TARTGET_SEL_NONE            (0x0<<12)
-#define        AVC_TARTGET_SEL_R                       (0x1<<12)
-#define        AVC_TARTGET_SEL_L                       (0x2<<12)
-#define        AVC_TARTGET_SEL_BOTH            (0x3<<12)
-
-#define HP_DEPOP_MODE2_EN                      (0x1<<8)
-#define HP_DEPOP_MODE1_EN                      (0x1<<9)
-#define HP_L_M_UM_DEPOP_EN                     (0x1<<7)
-#define HP_R_M_UM_DEPOP_EN                     (0x1<<6)
-#define M_UM_DEPOP_EN                          (0x1<<5)
-
-//Stereo DAC Clock Control 1(0x60)
-#define STEREO_BCLK_DIV1_MASK          (0xF<<12)
-#define STEREO_BCLK_DIV1_1                     (0x0<<12)
-#define STEREO_BCLK_DIV1_2                     (0x1<<12)
-#define STEREO_BCLK_DIV1_3                     (0x2<<12)
-#define STEREO_BCLK_DIV1_4                     (0x3<<12)
-#define STEREO_BCLK_DIV1_5                     (0x4<<12)
-#define STEREO_BCLK_DIV1_6                     (0x5<<12)
-#define STEREO_BCLK_DIV1_7                     (0x6<<12)
-#define STEREO_BCLK_DIV1_8                     (0x7<<12)
-#define STEREO_BCLK_DIV1_9                     (0x8<<12)
-#define STEREO_BCLK_DIV1_10                    (0x9<<12)
-#define STEREO_BCLK_DIV1_11                    (0xA<<12)
-#define STEREO_BCLK_DIV1_12                    (0xB<<12)
-#define STEREO_BCLK_DIV1_13                    (0xC<<12)
-#define STEREO_BCLK_DIV1_14                    (0xD<<12)
-#define STEREO_BCLK_DIV1_15                    (0xE<<12)
-#define STEREO_BCLK_DIV1_16                    (0xF<<12)
-
-#define STEREO_BCLK_DIV2_MASK          (0x7<<8)
-#define STEREO_BCLK_DIV2_2                     (0x0<<8)
-#define STEREO_BCLK_DIV2_4                     (0x1<<8)
-#define STEREO_BCLK_DIV2_8                     (0x2<<8)
-#define STEREO_BCLK_DIV2_16                    (0x3<<8)
-#define STEREO_BCLK_DIV2_32                    (0x4<<8)
-
-#define STEREO_AD_LRCK_DIV1_MASK       (0xF<<4)
-#define STEREO_AD_LRCK_DIV1_1          (0x0<<4)
-#define STEREO_AD_LRCK_DIV1_2          (0x1<<4)
-#define STEREO_AD_LRCK_DIV1_3          (0x2<<4)
-#define STEREO_AD_LRCK_DIV1_4          (0x3<<4)
-#define STEREO_AD_LRCK_DIV1_5          (0x4<<4)
-#define STEREO_AD_LRCK_DIV1_6          (0x5<<4)
-#define STEREO_AD_LRCK_DIV1_7          (0x6<<4)
-#define STEREO_AD_LRCK_DIV1_8          (0x7<<4)
-#define STEREO_AD_LRCK_DIV1_9          (0x8<<4)
-#define STEREO_AD_LRCK_DIV1_10         (0x9<<4)
-#define STEREO_AD_LRCK_DIV1_11         (0xA<<4)
-#define STEREO_AD_LRCK_DIV1_12         (0xB<<4)
-#define STEREO_AD_LRCK_DIV1_13         (0xC<<4)
-#define STEREO_AD_LRCK_DIV1_14         (0xD<<4)
-#define STEREO_AD_LRCK_DIV1_15         (0xE<<4)
-#define STEREO_AD_LRCK_DIV1_16         (0xF<<4)
-
-#define STEREO_AD_LRCK_DIV2_MASK       (0x7<<1)
-#define STEREO_AD_LRCK_DIV2_2          (0x0<<1)
-#define STEREO_AD_LRCK_DIV2_4          (0x1<<1)
-#define STEREO_AD_LRCK_DIV2_8          (0x2<<1)
-#define STEREO_AD_LRCK_DIV2_16         (0x3<<1)
-#define STEREO_AD_LRCK_DIV2_32         (0x4<<1)
-
-#define STEREO_DA_LRCK_DIV_MASK                (1)
-#define STEREO_DA_LRCK_DIV_32          (0)
-#define STEREO_DA_LRCK_DIV_64          (1)
-
-//Stereo DAC Clock Control 2(0x62)
-#define STEREO_DA_FILTER_DIV1_MASK     (0xF<<12)
-#define STEREO_DA_FILTER_DIV1_1                (0x0<<12)
-#define STEREO_DA_FILTER_DIV1_2                (0x1<<12)
-#define STEREO_DA_FILTER_DIV1_3                (0x2<<12)
-#define STEREO_DA_FILTER_DIV1_4                (0x3<<12)
-#define STEREO_DA_FILTER_DIV1_5                (0x4<<12)
-#define STEREO_DA_FILTER_DIV1_6                (0x5<<12)
-#define STEREO_DA_FILTER_DIV1_7                (0x6<<12)
-#define STEREO_DA_FILTER_DIV1_8                (0x7<<12)
-#define STEREO_DA_FILTER_DIV1_9                (0x8<<12)
-#define STEREO_DA_FILTER_DIV1_10       (0x9<<12)
-#define STEREO_DA_FILTER_DIV1_11       (0xA<<12)
-#define STEREO_DA_FILTER_DIV1_12       (0xB<<12)
-#define STEREO_DA_FILTER_DIV1_13       (0xC<<12)
-#define STEREO_DA_FILTER_DIV1_14       (0xD<<12)
-#define STEREO_DA_FILTER_DIV1_15       (0xE<<12)
-#define STEREO_DA_FILTER_DIV1_16       (0xF<<12)
-
-#define STEREO_DA_FILTER_DIV2_MASK     (0x7<<9)
-#define STEREO_DA_FILTER_DIV2_2                (0x0<<9)
-#define STEREO_DA_FILTER_DIV2_4                (0x1<<9)
-#define STEREO_DA_FILTER_DIV2_8                (0x2<<9)
-#define STEREO_DA_FILTER_DIV2_16       (0x3<<9)
-#define STEREO_DA_FILTER_DIV2_32       (0x4<<9)
-
-#define STEREO_AD_FILTER_DIV1_MASK     (0xF<<4)
-#define STEREO_AD_FILTER_DIV1_1                (0x0<<4)
-#define STEREO_AD_FILTER_DIV1_2                (0x1<<4)
-#define STEREO_AD_FILTER_DIV1_3                (0x2<<4)
-#define STEREO_AD_FILTER_DIV1_4                (0x3<<4)
-#define STEREO_AD_FILTER_DIV1_5                (0x4<<4)
-#define STEREO_AD_FILTER_DIV1_6                (0x5<<4)
-#define STEREO_AD_FILTER_DIV1_7                (0x6<<4)
-#define STEREO_AD_FILTER_DIV1_8                (0x7<<4)
-#define STEREO_AD_FILTER_DIV1_9                (0x8<<4)
-#define STEREO_AD_FILTER_DIV1_10       (0x9<<4)
-#define STEREO_AD_FILTER_DIV1_11       (0xA<<4)
-#define STEREO_AD_FILTER_DIV1_12       (0xB<<4)
-#define STEREO_AD_FILTER_DIV1_13       (0xC<<4)
-#define STEREO_AD_FILTER_DIV1_14       (0xD<<4)
-#define STEREO_AD_FILTER_DIV1_15       (0xE<<4)
-#define STEREO_AD_FILTER_DIV1_16       (0xF<<4)
-
-#define STEREO_AD_FILTER_DIV2_MASK     (0x7<<1)
-#define STEREO_AD_FILTER_DIV2_1                (0x0<<1)
-#define STEREO_AD_FILTER_DIV2_2                (0x1<<1)
-#define STEREO_AD_FILTER_DIV2_4                (0x2<<1)
-#define STEREO_AD_FILTER_DIV2_8                (0x3<<1)
-#define STEREO_AD_FILTER_DIV2_16       (0x4<<1)
-#define STEREO_AD_FILTER_DIV2_32       (0x5<<1)
-
-
-//Voice DAC PCM Clock Control 1(0x64)
-#define VOICE_BCLK_DIV1_MASK           (0xF<<12)
-#define VOICE_BCLK_DIV1_1                      (0x0<<12)
-#define VOICE_BCLK_DIV1_2                      (0x1<<12)
-#define VOICE_BCLK_DIV1_3                      (0x2<<12)
-#define VOICE_BCLK_DIV1_4                      (0x3<<12)
-#define VOICE_BCLK_DIV1_5                      (0x4<<12)
-#define VOICE_BCLK_DIV1_6                      (0x5<<12)
-#define VOICE_BCLK_DIV1_7                      (0x6<<12)
-#define VOICE_BCLK_DIV1_8                      (0x7<<12)
-#define VOICE_BCLK_DIV1_9                      (0x8<<12)
-#define VOICE_BCLK_DIV1_10                     (0x9<<12)
-#define VOICE_BCLK_DIV1_11                     (0xA<<12)
-#define VOICE_BCLK_DIV1_12                     (0xB<<12)
-#define VOICE_BCLK_DIV1_13                     (0xC<<12)
-#define VOICE_BCLK_DIV1_14                     (0xD<<12)
-#define VOICE_BCLK_DIV1_15                     (0xE<<12)
-#define VOICE_BCLK_DIV1_16                     (0xF<<12)
-
-#define VOICE_BCLK_DIV2_MASK           (0x7<<8)
-#define VOICE_BCLK_DIV2_2                      (0x0<<8)
-#define VOICE_BCLK_DIV2_4                      (0x1<<8)
-#define VOICE_BCLK_DIV2_8                      (0x2<<8)
-#define VOICE_BCLK_DIV2_16                     (0x3<<8)
-#define VOICE_BCLK_DIV2_32                     (0x4<<8)
-
-#define VOICE_AD_LRCK_DIV1_MASK        (0xF<<4)
-#define VOICE_AD_LRCK_DIV1_1           (0x0<<4)
-#define VOICE_AD_LRCK_DIV1_2           (0x1<<4)
-#define VOICE_AD_LRCK_DIV1_3           (0x2<<4)
-#define VOICE_AD_LRCK_DIV1_4           (0x3<<4)
-#define VOICE_AD_LRCK_DIV1_5           (0x4<<4)
-#define VOICE_AD_LRCK_DIV1_6           (0x5<<4)
-#define VOICE_AD_LRCK_DIV1_7           (0x6<<4)
-#define VOICE_AD_LRCK_DIV1_8           (0x7<<4)
-#define VOICE_AD_LRCK_DIV1_9           (0x8<<4)
-#define VOICE_AD_LRCK_DIV1_10          (0x9<<4)
-#define VOICE_AD_LRCK_DIV1_11          (0xA<<4)
-#define VOICE_AD_LRCK_DIV1_12          (0xB<<4)
-#define VOICE_AD_LRCK_DIV1_13          (0xC<<4)
-#define VOICE_AD_LRCK_DIV1_14          (0xD<<4)
-#define VOICE_AD_LRCK_DIV1_15          (0xE<<4)
-#define VOICE_AD_LRCK_DIV1_16          (0xF<<4)
-
-#define VOICE_AD_LRCK_DIV2_MASK        (0x7<<1)
-#define VOICE_AD_LRCK_DIV2_2           (0x0<<1)
-#define VOICE_AD_LRCK_DIV2_4           (0x1<<1)
-#define VOICE_AD_LRCK_DIV2_8           (0x2<<1)
-#define VOICE_AD_LRCK_DIV2_16          (0x3<<1)
-#define VOICE_AD_LRCK_DIV2_32          (0x4<<1)
-
-#define VOICE_DA_LRCK_DIV_MASK         (1)
-#define VOICE_DA_LRCK_DIV_32           (0)
-#define VOICE_DA_LRCK_DIV_64           (1)
-
-
-//Psedueo Stereo & Spatial Effect Block Control(0x68)
-#define SPATIAL_CTRL_EN                                (0x1<<15)
-#define ALL_PASS_FILTER_EN                     (0x1<<14)
-#define PSEUDO_STEREO_EN                       (0x1<<13)
-#define STEREO_EXPENSION_EN                    (0x1<<12)
-
-#define SPATIAL_3D_GAIN1_MASK                  (0x3<<10)
-#define SPATIAL_3D_GAIN1_1_0                   (0x0<<10)
-#define SPATIAL_3D_GAIN1_1_5                   (0x1<<10)
-#define SPATIAL_3D_GAIN1_2_0                   (0x2<<10)
-
-#define SPATIAL_3D_RATIO1_MASK                 (0x3<<8)
-#define SPATIAL_3D_RATIO1_0_0                  (0x0<<8)
-#define SPATIAL_3D_RATIO1_0_66                 (0x1<<8)
-#define SPATIAL_3D_RATIO1_1_0                  (0x2<<8)
-
-#define SPATIAL_3D_GAIN2_MASK                  (0x3<<6)
-#define SPATIAL_3D_GAIN2_1_0                   (0x0<<6)
-#define SPATIAL_3D_GAIN2_1_5                   (0x1<<6)
-#define SPATIAL_3D_GAIN2_2_0                   (0x2<<6)
-
-#define SPATIAL_3D_RATIO2_MASK                 (0x3<<4)
-#define SPATIAL_3D_RATIO2_0_0                  (0x0<<4)
-#define SPATIAL_3D_RATIO2_0_66                 (0x1<<4)
-#define SPATIAL_3D_RATIO2_1_0                  (0x2<<4)
-
-#define APF_MASK                                       (0x3)
-#define APF_FOR_48K                                    (0x3)
-#define APF_FOR_44_1K                          (0x2)
-#define APF_FOR_32K                                    (0x1)
-
-//EQ Control and Status /ADC HPF Control(0x6E)
-#define EN_HW_EQ_BLK                   (0x1<<15)               //HW EQ block control
-
-#define EQ_SOUR_SEL_DAC                        (0x0<<14)
-#define EQ_SOUR_SEL_ADC                        (0x1<<14)
-
-#define EQ_CHANGE_EN                   (0x1<<7)                //EQ parameter update control
-#define EN_HW_EQ_HPF                   (0x1<<4)                //EQ High Pass Filter Control
-#define EN_HW_EQ_BP3                   (0x1<<3)                //EQ Band-3 Control
-#define EN_HW_EQ_BP2                   (0x1<<2)                //EQ Band-2 Control
-#define EN_HW_EQ_BP1                   (0x1<<1)                //EQ Band-1 Control
-#define EN_HW_EQ_LPF                   (0x1<<0)                //EQ Low Pass Filter Control
-
-
-//AEC register command(0x74)
-
-#define VODSP_BUSY                                     (0x1<<15)       //VODSP I2C busy flag
-
-#define VODSP_S_FROM_VODSP_RD          (0x0<<14)
-#define VODSP_S_FROM_MX72                      (0x1<<14)
-
-#define VODSP_CLK_SEL_MASK                     (0x3<<12)       //VODSP CLK select Mask
-#define VODSP_CLK_SEL_12_288M          (0x0<<12)       //VODSP CLK select 12.288Mhz
-#define VODSP_CLK_SEL_6_144M           (0x1<<12)       //VODSP CLK select 6.144Mhz
-#define VODSP_CLK_SEL_3_072M           (0x2<<12)       //VODSP CLK select 3.072Mhz
-#define VODSP_CLK_SEL_2_048M           (0x3<<12)       //VODSP CLK select 2.0488Mhz
-
-#define VODSP_READ_ENABLE                      (0x1<<9)        //VODSP Read Enable
-#define VODSP_WRITE_ENABLE                     (0x1<<8)        //VODSP Write Enable
-
-#define VODSP_CMD_MASK                         (0xFF<<0)
-#define VODSP_CMD_MW                           (0x3B<<0)               //Memory Write
-#define VODSP_CMD_MR                           (0x37<<0)               //Memory Read
-#define VODSP_CMD_RR                           (0x60<<0)               //Register Read
-#define VODSP_CMD_RW                           (0x68<<0)               //Register Write
-
-
-/*************************************************************************************************
-  *Index register of codec
-  *************************************************************************************************/
-/*Index(0x20) for Auto Volume Control*/ 
-#define        AVC_CH_SEL_MASK                         (0x1<<7)
-#define AVC_CH_SEL_L_CH                                (0x0<<7)
-#define AVC_CH_SEL_R_CH                                (0x1<<7)
-#define ENABLE_AVC_GAIN_CTRL           (0x1<<15)
-//*************************************************************************************************
-//*************************************************************************************************
-
-#define REALTEK_HWDEP 0
-
-#if REALTEK_HWDEP
-
-struct rt56xx_reg_state
-{
-       unsigned int reg_index;
-       unsigned int reg_value;
+/*
+ * rt5625.h  --  RT5625 ALSA SoC audio driver
+ *
+ * Copyright 2011 Realtek Microelectronics
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT5625_H__
+#define __RT5625_H__
+
+#define RT5625_RESET                           0x00
+#define RT5625_SPK_OUT_VOL                     0x02
+#define RT5625_HP_OUT_VOL                      0x04
+#define RT5625_AUX_OUT_VOL                     0x06
+#define RT5625_PHONEIN_VOL                     0x08
+#define RT5625_LINE_IN_VOL                     0x0a
+#define RT5625_DAC_VOL                         0x0c
+#define RT5625_MIC_VOL                         0x0e
+#define RT5625_DAC_MIC_CTRL                    0x10
+#define RT5625_ADC_REC_GAIN                    0x12
+#define RT5625_ADC_REC_MIXER                   0x14
+#define RT5625_VDAC_OUT_VOL                    0x18
+#define RT5625_VODSP_PDM_CTL                   0x1a
+#define RT5625_OUTMIX_CTRL                     0x1c
+#define RT5625_VODSP_CTL                       0x1e
+#define RT5625_MIC_CTRL                                0x22
+#define RT5625_DMIC_CTRL                       0x24
+#define RT5625_PD_CTRL                         0x26
+#define RT5625_F_DAC_ADC_VDAC                  0x2e
+#define RT5625_SDP_CTRL                                0x34
+#define RT5625_EXT_SDP_CTRL                    0x36
+#define RT5625_PWR_ADD1                        0x3a
+#define RT5625_PWR_ADD2                        0x3c
+#define RT5625_PWR_ADD3                        0x3e
+#define RT5625_GEN_CTRL1                       0x40
+#define RT5625_GEN_CTRL2                       0x42
+#define RT5625_PLL_CTRL                                0x44
+#define RT5625_PLL2_CTRL                       0x46
+#define RT5625_LDO_CTRL                                0x48
+#define RT5625_GPIO_CONFIG                     0x4c
+#define RT5625_GPIO_POLAR                      0x4e
+#define RT5625_GPIO_STICKY                     0x50
+#define RT5625_GPIO_WAKEUP                     0x52
+#define RT5625_GPIO_STATUS                     0x54
+#define RT5625_GPIO_SHARING                    0x56
+#define RT5625_OTC_STATUS                      0x58
+#define RT5625_SOFT_VOL_CTRL                   0x5a
+#define RT5625_GPIO_OUT_CTRL                   0x5c
+#define RT5625_MISC_CTRL                       0x5e
+#define RT5625_DAC_CLK_CTRL1                   0x60
+#define RT5625_DAC_CLK_CTRL2                   0x62
+#define RT5625_VDAC_CLK_CTRL1                  0x64
+#define RT5625_PS_CTRL                         0x68
+#define RT5625_PRIV_INDEX                      0x6a
+#define RT5625_PRIV_DATA                       0x6c
+#define RT5625_EQ_CTRL                         0x6e
+#define RT5625_DSP_ADDR                        0x70
+#define RT5625_DSP_DATA                        0x72
+#define RT5625_DSP_CMD                         0x74
+#define RT5625_VENDOR_ID1                      0x7c
+#define RT5625_VENDOR_ID2                      0x7e
+
+/* global definition */
+#define RT5625_L_MUTE                          (0x1 << 15)
+#define RT5625_L_MUTE_SFT                      15
+#define RT5625_L_ZC                            (0x1 << 14)
+#define RT5625_L_VOL_MASK                      (0x1f << 8)
+#define RT5625_L_HVOL_MASK                     (0x3f << 8)
+#define RT5625_L_VOL_SFT                       8
+#define RT5625_R_MUTE                          (0x1 << 7)
+#define RT5625_R_MUTE_SFT                      7
+#define RT5625_R_ZC                            (0x1 << 6)
+#define RT5625_R_VOL_MASK                      (0x1f)
+#define RT5625_R_HVOL_MASK                     (0x3f)
+#define RT5625_R_VOL_SFT                       0
+#define RT5625_M_HPMIX                         (0x1 << 15)
+#define RT5625_M_SPKMIX                        (0x1 << 14)
+#define RT5625_M_MONOMIX                       (0x1 << 13)
+
+/* Phone Input (0x08) */
+#define RT5625_M_PHO_HM                        (0x1 << 15)
+#define RT5625_M_PHO_HM_SFT                    15
+#define RT5625_M_PHO_SM                        (0x1 << 14)
+#define RT5625_M_PHO_SM_SFT                    14
+#define RT5625_PHO_DIFF                                (0x1 << 13)
+#define RT5625_PHO_DIFF_SFT                    13
+#define RT5625_PHO_DIFF_DIS                    (0x0 << 13)
+#define RT5625_PHO_DIFF_EN                     (0x1 << 13)
+
+/* Linein Volume (0x0a) */
+#define RT5625_M_LI_HM                         (0x1 << 15)
+#define RT5625_M_LI_HM_SFT                     15
+#define RT5625_M_LI_SM                         (0x1 << 14)
+#define RT5625_M_LI_SM_SFT                     14
+#define RT5625_M_LI_MM                         (0x1 << 13)
+#define RT5625_M_LI_MM_SFT                     13
+
+/* MIC Input Volume (0x0e) */
+#define RT5625_MIC1_DIFF_MASK                  (0x1 << 15)
+#define RT5625_MIC1_DIFF_SFT                   15
+#define RT5625_MIC1_DIFF_DIS                   (0x0 << 15)
+#define RT5625_MIC1_DIFF_EN                    (0x1 << 15)
+#define RT5625_MIC2_DIFF_MASK                  (0x1 << 7)
+#define RT5625_MIC2_DIFF_SFT                   7
+#define RT5625_MIC2_DIFF_DIS                   (0x0 << 7)
+#define RT5625_MIC2_DIFF_EN                    (0x1 << 7)
+
+/* Stereo DAC and MIC Routing Control (0x10) */
+#define RT5625_M_MIC1_HM                       (0x1 << 15)
+#define RT5625_M_MIC1_HM_SFT                   15
+#define RT5625_M_MIC1_SM                       (0x1 << 14)
+#define RT5625_M_MIC1_SM_SFT                   14
+#define RT5625_M_MIC1_MM                       (0x1 << 13)
+#define RT5625_M_MIC1_MM_SFT                   13
+#define RT5625_M_MIC2_HM                       (0x1 << 11)
+#define RT5625_M_MIC2_HM_SFT                   11
+#define RT5625_M_MIC2_SM                       (0x1 << 10)
+#define RT5625_M_MIC2_SM_SFT                   10
+#define RT5625_M_MIC2_MM                       (0x1 << 9)
+#define RT5625_M_MIC2_MM_SFT                   9
+#define RT5625_M_DACL_HM                       (0x1 << 3)
+#define RT5625_M_DACL_HM_SFT                   3
+#define RT5625_M_DACR_HM                       (0x1 << 2)
+#define RT5625_M_DACR_HM_SFT                   2
+#define RT5625_M_DAC_SM                        (0x1 << 1)
+#define RT5625_M_DAC_SM_SFT                    1
+#define RT5625_M_DAC_MM                        (0x1)
+#define RT5625_M_DAC_MM_SFT                    0
+
+/* ADC Record Gain (0x12) */
+#define RT5625_M_ADCL_HM                       (0x1 << 15)
+#define RT5625_M_ADCL_HM_SFT                   15
+#define RT5625_M_ADCL_MM                       (0x1 << 14)
+#define RT5625_M_ADCL_MM_SFT                   14
+#define RT5625_ADCL_ZCD                        (0x1 << 13)
+#define RT5625_G_ADCL_MASK                     (0x1f << 8)
+#define RT5625_M_ADCR_HM                       (0x1 << 7)
+#define RT5625_M_ADCR_HM_SFT                   7
+#define RT5625_M_ADCR_MM                       (0x1 << 6)
+#define RT5625_M_ADCR_MM_SFT                   6
+#define RT5625_ADCR_ZCD                        (0x1 << 5)
+#define RT5625_G_ADCR_MASK                     (0x1f)
+
+/* ADC Record Mixer Control (0x14) */
+#define RT5625_M_RM_L_MIC1                     (0x1 << 14)
+#define RT5625_M_RM_L_MIC1_SFT         14
+#define RT5625_M_RM_L_MIC2                     (0x1 << 13)
+#define RT5625_M_RM_L_MIC2_SFT         13
+#define RT5625_M_RM_L_LINE                     (0x1 << 12)
+#define RT5625_M_RM_L_LINE_SFT                 12
+#define RT5625_M_RM_L_PHO                      (0x1 << 11)
+#define RT5625_M_RM_L_PHO_SFT                  11
+#define RT5625_M_RM_L_HM                       (0x1 << 10)
+#define RT5625_M_RM_L_HM_SFT                   10
+#define RT5625_M_RM_L_SM                       (0x1 << 9)
+#define RT5625_M_RM_L_SM_SFT                   9
+#define RT5625_M_RM_L_MM                       (0x1 << 8)
+#define RT5625_M_RM_L_MM_SFT                   8
+#define RT5625_M_RM_R_MIC1                     (0x1 << 6)
+#define RT5625_M_RM_R_MIC1_SFT         6
+#define RT5625_M_RM_R_MIC2                     (0x1 << 5)
+#define RT5625_M_RM_R_MIC2_SFT         5
+#define RT5625_M_RM_R_LINE                     (0x1 << 4)
+#define RT5625_M_RM_R_LINE_SFT                 4
+#define RT5625_M_RM_R_PHO                      (0x1 << 3)
+#define RT5625_M_RM_R_PHO_SFT                  3
+#define RT5625_M_RM_R_HM                       (0x1 << 2)
+#define RT5625_M_RM_R_HM_SFT                   2
+#define RT5625_M_RM_R_SM                       (0x1 << 1)
+#define RT5625_M_RM_R_SM_SFT                   1
+#define RT5625_M_RM_R_MM                       (0x1)
+#define RT5625_M_RM_R_MM_SFT                   0
+
+/* Voice DAC Volume (0x18) */
+#define RT5625_M_VDAC_HM                       (0x1 << 15)
+#define RT5625_M_VDAC_HM_SFT                   15
+#define RT5625_M_VDAC_SM                       (0x1 << 14)
+#define RT5625_M_VDAC_SM_SFT                   14
+#define RT5625_M_VDAC_MM                       (0x1 << 13)
+#define RT5625_M_VDAC_MM_SFT                   13
+
+/* AEC & PDM Control (0x1a) */
+#define RT5625_SRC1_PWR                        (0x1 << 15)
+#define RT5625_SRC1_PWR_SFT                    15
+#define RT5625_SRC2_PWR                        (0x1 << 13)
+#define RT5625_SRC2_PWR_SFT                    13
+#define RT5625_SRC2_S_MASK                     (0x1 << 12)             
+#define RT5625_SRC2_S_SFT                      12              
+#define RT5625_SRC2_S_TXDP                     (0x0 << 12)
+#define RT5625_SRC2_S_TXDC                     (0x1 << 12)
+#define RT5625_RXDP_PWR                        (0x1 << 11)
+#define RT5625_RXDP_PWR_SFT                    11
+#define RT5625_RXDP_S_MASK                     (0x3 << 9)              
+#define RT5625_RXDP_S_SFT                      9
+#define RT5625_RXDP_S_SRC1                     (0x0 << 9)
+#define RT5625_RXDP_S_ADCL                     (0x1 << 9)
+#define RT5625_RXDP_S_VOICE                    (0x2 << 9)
+#define RT5625_RXDP_S_ADCR                     (0x3 << 9)
+#define RT5625_RXDC_PWR                        (0x1 << 8)
+#define RT5625_RXDC_PWR_SFT                    8
+#define RT5625_PCM_S_MASK                      (0x1 << 7)              
+#define RT5625_PCM_S_SFT                       7
+#define RT5625_PCM_S_ADCR                      (0x0 << 7)
+#define RT5625_PCM_S_TXDP                      (0x1 << 7)
+#define RT5625_REC_IIS_S_MASK                  (0x3 << 4)
+#define RT5625_REC_IIS_S_SFT                   4
+#define RT5625_REC_IIS_S_ADC                   (0x0 << 4)
+#define RT5625_REC_IIS_S_VOICE                 (0x1 << 4)
+#define RT5625_REC_IIS_S_SRC2                  (0x2 << 4)
+
+/* Output Mixer Control (0x1c) */
+#define RT5625_SPKN_S_MASK                     (0x3 << 14)
+#define RT5625_SPKN_S_SFT                      14
+#define RT5625_SPKN_S_LN                       (0x2 << 14)
+#define RT5625_SPKN_S_RP                       (0x1 << 14)
+#define RT5625_SPKN_S_RN                       (0x0 << 14)
+#define RT5625_SPK_T_MASK                      (0x1 << 13)
+#define RT5625_SPK_T_SFT                       13
+#define RT5625_SPK_T_CLS_D                     (0x1 << 13)
+#define RT5625_SPK_T_CLS_AB                    (0x0 << 13)
+#define RT5625_CLS_AB_MASK                     (0x1 << 12)
+#define RT5625_CLS_AB_SFT                      12
+#define RT5625_CLS_AB_S_AMP                    (0x0 << 12)
+#define RT5625_CLS_AB_W_AMP                    (0x1 << 12)
+#define RT5625_SPKVOL_S_MASK                   (0x3 << 10)
+#define RT5625_SPKVOL_S_SFT                    10
+#define RT5625_SPKVOL_S_MM                     (0x3 << 10)
+#define RT5625_SPKVOL_S_SM                     (0x2 << 10)
+#define RT5625_SPKVOL_S_HM                     (0x1 << 10)
+#define RT5625_SPKVOL_S_VMID                   (0x0 << 10)
+#define RT5625_HPVOL_L_S_MASK                  (0x1 << 9)
+#define RT5625_HPVOL_L_S_SFT                   9
+#define RT5625_HPVOL_L_S_HM                    (0x1 << 9)
+#define RT5625_HPVOL_L_S_VMID                  (0x0 << 9)
+#define RT5625_HPVOL_R_S_MASK                  (0x1 << 8)
+#define RT5625_HPVOL_R_S_SFT                   8
+#define RT5625_HPVOL_R_S_HM                    (0x1 << 8)      
+#define RT5625_HPVOL_R_S_VMID                  (0x0 << 8)
+#define RT5625_AUXVOL_S_MASK                   (0x3 << 6)
+#define RT5625_AUXVOL_S_SFT                    6
+#define RT5625_AUXVOL_S_MM                     (0x3 << 6)
+#define RT5625_AUXVOL_S_SM                     (0x2 << 6)
+#define RT5625_AUXVOL_S_HM                     (0x1 << 6)
+#define RT5625_AUXVOL_S_VMID                   (0x0 << 6)
+#define RT5625_AUXOUT_MODE                     (0x1 << 4)
+#define RT5625_AUXOUT_MODE_SFT         4
+#define RT5625_DACL_HP_MASK                    (0x1 << 1)
+#define RT5625_DACL_HP_SFT                     1
+#define RT5625_DACL_HP_MUTE                    (0x0 << 1)
+#define RT5625_DACL_HP_ON                      (0x1 << 1)
+#define RT5625_DACR_HP_MASK                    (0x1)
+#define RT5625_DACR_HP_SFT                     0
+#define RT5625_DACR_HP_MUTE                    (0x0)
+#define RT5625_DACR_HP_ON                      (0x1)
+
+/* VoDSP Control (0x1e) */
+#define RT5625_DSP_SCLK_S_MASK         (0x1 << 15)
+#define RT5625_DSP_SCLK_S_SFT                  15
+#define RT5625_DSP_SCLK_S_MCLK         (0x0 << 15)
+#define RT5625_DSP_SCLK_S_VCLK                 (0x1 << 15)
+#define RT5625_DSP_LRCK_MASK                   (0x1 << 13)
+#define RT5625_DSP_LRCK_SFT                    13
+#define RT5625_DSP_LRCK_8K                     (0x0 << 13)
+#define RT5625_DSP_LRCK_16K                    (0x1 << 13)
+#define RT5625_DSP_TP_MASK                     (0x1 << 3)
+#define RT5625_DSP_TP_SFT                      3
+#define RT5625_DSP_TP_NOR                      (0x0 << 3)
+#define RT5625_DSP_TP_TEST                     (0x1 << 3)
+#define RT5625_DSP_BP_MASK                     (0x1 << 2)
+#define RT5625_DSP_BP_SFT                      2
+#define RT5625_DSP_BP_EN                       (0x0 << 2)
+#define RT5625_DSP_BP_NOR                      (0x1 << 2)
+#define RT5625_DSP_PD_MASK                     (0x1 << 1)
+#define RT5625_DSP_PD_SFT                      1
+#define RT5625_DSP_PD_EN                       (0x0 << 1)
+#define RT5625_DSP_PD_NOR                      (0x1 << 1)
+#define RT5625_DSP_RST_MASK                    (0x1)
+#define RT5625_DSP_RST_SFT                     0
+#define RT5625_DSP_RST_EN                      (0x0)
+#define RT5625_DSP_RST_NOR                     (0x1)
+
+/* Microphone Control (0x22) */
+#define RT5625_MIC1_BST_MASK                   (0x3 << 10)
+#define RT5625_MIC1_BST_SFT                    10
+#define RT5625_MIC1_BST_BYPASS         (0x0 << 10)
+#define RT5625_MIC1_BST_20DB                   (0x1 << 10)
+#define RT5625_MIC1_BST_30DB                   (0x2 << 10)
+#define RT5625_MIC1_BST_40DB                   (0x3 << 10)
+#define RT5625_MIC2_BST_MASK                   (0x3 << 8)
+#define RT5625_MIC2_BST_SFT                    8
+#define RT5625_MIC2_BST_BYPASS         (0x0 << 8)
+#define RT5625_MIC2_BST_20DB                   (0x1 << 8)
+#define RT5625_MIC2_BST_30DB                   (0x2 << 8)
+#define RT5625_MIC2_BST_40DB                   (0x3 << 8)
+#define RT5625_MB1_OV_MASK                     (0x1 << 5)
+#define RT5625_MB1_OV_90P                      (0x0 << 5)
+#define RT5625_MB1_OV_75P                      (0x1 << 5)
+#define RT5625_MB2_OV_MASK                     (0x1 << 4)
+#define RT5625_MB2_OV_90P                      (0x0 << 4)
+#define RT5625_MB2_OV_75P                      (0x1 << 4)
+#define RT5625_SCD_THD_MASK                    (0x3)
+#define RT5625_SCD_THD_600UA                   (0x0)
+#define RT5625_SCD_THD_1500UA                  (0x1)
+#define RT5625_SCD_THD_2000UA                  (0x2)
+
+/* Digital Boost Control (0x24) */
+#define RT5625_DIG_BST_MASK                    (0x7)
+#define RT5625_DIG_BST_SFT                     0
+
+/* Power Down Control/Status (0x26) */
+#define RT5625_PWR_PR7                         (0x1 << 15)
+#define RT5625_PWR_PR6                         (0x1 << 14)
+#define RT5625_PWR_PR5                         (0x1 << 13)
+#define RT5625_PWR_PR3                         (0x1 << 11)
+#define RT5625_PWR_PR2                         (0x1 << 10)
+#define RT5625_PWR_PR1                         (0x1 << 9)
+#define RT5625_PWR_PR0                         (0x1 << 8)
+#define RT5625_PWR_REF_ST                      (0x1 << 3)
+#define RT5625_PWR_AM_ST                       (0x1 << 2)
+#define RT5625_PWR_DAC_ST                      (0x1 << 1)
+#define RT5625_PWR_ADC_ST                      (0x1)
+
+/* Stereo DAC/Voice DAC/Stereo ADC Function Select (0x2e) */
+#define RT5625_DAC_F_MASK                      (0x3 << 12)
+#define RT5625_DAC_F_SFT                       12
+#define RT5625_DAC_F_DAC                       (0x0 << 12)             
+#define RT5625_DAC_F_SRC2                      (0x1 << 12)
+#define RT5625_DAC_F_TXDP                      (0x2 << 12)
+#define RT5625_DAC_F_TXDC                      (0x3 << 12)
+#define RT5625_VDAC_S_MASK                     (0x7 << 8)
+#define RT5625_VDAC_S_SFT                      8
+#define RT5625_VDAC_S_VOICE                    (0x0 << 8)      
+#define RT5625_VDAC_S_SRC2                     (0x1 << 8)
+#define RT5625_VDAC_S_TXDP                     (0x2 << 8)
+#define RT5625_VDAC_S_TXDC                     (0x3 << 8)
+#define RT5625_ADCR_F_MASK                     (0x3 << 4)
+#define RT5625_ADCR_F_SFT                      4
+#define RT5625_ADCR_F_ADC                      (0x0 << 4)
+#define RT5625_ADCR_F_VADC                     (0x1 << 4)
+#define RT5625_ADCR_F_DSP                      (0x2 << 4)
+#define RT5625_ADCR_F_PDM                      (0x3 << 4)
+#define RT5625_ADCL_F_MASK                     (0x1)
+#define RT5625_ADCL_F_SFT                      0
+#define RT5625_ADCL_F_ADC                      (0x0)
+#define RT5625_ADCL_F_DSP                      (0x1)
+
+/* Main Serial Data Port Control (Stereo IIS) (0x34) */
+#define RT5625_I2S_M_MASK                      (0x1 << 15)
+#define RT5625_I2S_M_SFT                       15
+#define RT5625_I2S_M_MST                       (0x0 << 15)
+#define RT5625_I2S_M_SLV                       (0x1 << 15)
+#define RT5625_I2S_SAD_MASK                    (0x1 << 14)
+#define RT5625_I2S_SAD_SFT                     14
+#define RT5625_I2S_SAD_DIS                     (0x0 << 14)
+#define RT5625_I2S_SAD_EN                      (0x1 << 14)
+#define RT5625_I2S_S_MASK                      (0x1 << 8)
+#define RT5625_I2S_S_SFT                       8
+#define RT5625_I2S_S_MSCLK                     (0x0 << 8)
+#define RT5625_I2S_S_VSCLK                     (0x1 << 8)
+#define RT5625_I2S_BP_MASK                     (0x1 << 7)
+#define RT5625_I2S_BP_SFT                      7
+#define RT5625_I2S_BP_NOR                      (0x0 << 7)
+#define RT5625_I2S_BP_INV                      (0x1 << 7)
+#define RT5625_I2S_LRCK_MASK                   (0x1 << 6)
+#define RT5625_I2S_LRCK_SFT                    6
+#define RT5625_I2S_LRCK_NOR                    (0x0 << 6)
+#define RT5625_I2S_LRCK_INV                    (0x1 << 6)
+#define RT5625_I2S_DL_MASK                     (0x3 << 2)
+#define RT5625_I2S_DL_SFT                      2
+#define RT5625_I2S_DL_16                       (0x0 << 2)
+#define RT5625_I2S_DL_20                       (0x1 << 2)
+#define RT5625_I2S_DL_24                       (0x2 << 2)
+#define RT5625_I2S_DL_8                                (0x3 << 2)
+#define RT5625_I2S_DF_MASK                     (0x3)
+#define RT5625_I2S_DF_SFT                      0
+#define RT5625_I2S_DF_I2S                      (0x0)
+#define RT5625_I2S_DF_LEFT                     (0x1)
+#define RT5625_I2S_DF_PCM_A                    (0x2)
+#define RT5625_I2S_DF_PCM_B                    (0x3)
+
+/* Extend Serial Data Port Control (0x36) */
+#define RT5625_PCM_F_MASK                      (0x1 << 15)
+#define RT5625_PCM_F_SFT                       15
+#define RT5625_PCM_F_GPIO                      (0x0 << 15)
+#define RT5625_PCM_F_PCM                       (0x1 << 15)
+#define RT5625_PCM_M_MASK                      (0x1 << 14)
+#define RT5625_PCM_M_SFT                       14
+#define RT5625_PCM_M_MST                       (0x0 << 14)
+#define RT5625_PCM_M_SLV                       (0x1 << 14)
+#define RT5625_PCM_CS_MASK                     (0x1 << 8)
+#define RT5625_PCM_CS_SFT                      8
+#define RT5625_PCM_CS_SCLK                     (0x0 << 8)
+#define RT5625_PCM_CS_VSCLK                    (0x1 << 8)
+
+/* Power Management Addition 1 (0x3a) */
+#define RT5625_P_DACL_MIX                      (0x1 << 15)
+#define RT5625_P_DACL_MIX_BIT                  15
+#define RT5625_P_DACR_MIX                      (0x1 << 14)
+#define RT5625_P_DACR_MIX_BIT                  14
+#define RT5625_P_ZCD                           (0x1 << 13)
+#define RT5625_P_ZCD_BIT                       13
+#define RT5625_P_I2S                           (0x1 << 11)
+#define RT5625_P_I2S_BIT                       11
+#define RT5625_P_SPK_AMP                       (0x1 << 10)
+#define RT5625_P_SPK_AMP_BIT                   10
+#define RT5625_P_HPO_AMP                       (0x1 << 9)
+#define RT5625_P_HPO_AMP_BIT                   9
+#define RT5625_P_HPO_ENH                       (0x1 << 8)
+#define RT5625_P_HPO_ENH_BIT                   8
+#define RT5625_P_VDAC_MIX                      (0x1 << 7)
+#define RT5625_P_VDAC_MIX_BIT                  7
+#define RT5625_P_SG_EN                         (0x1 << 6)      
+#define RT5625_P_SG_EN_BIT                     6       
+#define RT5625_P_MB1_SCD                       (0x1 << 5)
+#define RT5625_P_MB1_SCD_BIT                   5
+#define RT5625_P_MB2_SCD                       (0x1 << 4)
+#define RT5625_P_MB2_SCD_BIT                   4
+#define RT5625_P_MB1                           (0x1 << 3)      
+#define RT5625_P_MB1_BIT                       3       
+#define RT5625_P_MB2                           (0x1 << 2)      
+#define RT5625_P_MB2_BIT                       2       
+#define RT5625_P_MAIN_BIAS                     (0x1 << 1)
+#define RT5625_P_MAIN_BIAS_BIT                 1
+#define RT5625_P_DAC_REF                       (0x1)
+#define RT5625_P_DAC_REF_BIT                   0
+
+/* Power Management Addition 2 (0x3c) */
+#define RT5625_P_PLL1                          (0x1 << 15)
+#define RT5625_P_PLL1_BIT                              15
+#define RT5625_P_PLL2                          (0x1 << 14)
+#define RT5625_P_PLL2_BIT                              14
+#define RT5625_P_VREF                          (0x1 << 13)
+#define RT5625_P_VREF_BIT                      13
+#define RT5625_P_OVT                           (0x1 << 12)
+#define RT5625_P_OVT_BIT                       12
+#define RT5625_P_AUX_ADC                       (0x1 << 11)
+#define RT5625_P_AUX_ADC_BIT                   11
+#define RT5625_P_VDAC                          (0x1 << 10)
+#define RT5625_P_VDAC_BIT                      10
+#define RT5625_P_DACL                          (0x1 << 9)
+#define RT5625_P_DACL_BIT                      9
+#define RT5625_P_DACR                          (0x1 << 8)
+#define RT5625_P_DACR_BIT                      8
+#define RT5625_P_ADCL                          (0x1 << 7)
+#define RT5625_P_ADCL_BIT                      7
+#define RT5625_P_ADCR                          (0x1 << 6)
+#define RT5625_P_ADCR_BIT                      6
+#define RT5625_P_HM_L                          (0x1 << 5)
+#define RT5625_P_HM_L_BIT                      5
+#define RT5625_P_HM_R                          (0x1 << 4)
+#define RT5625_P_HM_R_BIT                      4
+#define RT5625_P_SM                            (0x1 << 3)
+#define RT5625_P_SM_BIT                                3
+#define RT5625_P_MM                            (0x1 << 2)
+#define RT5625_P_MM_BIT                        2
+#define RT5625_P_ADCL_RM                       (0x1 << 1)
+#define RT5625_P_ADCL_RM_BIT                   1
+#define RT5625_P_ADCR_RM                       (0x1)
+#define RT5625_P_ADCR_RM_BIT                   0
+
+/* Power Management Addition 3 (0x3e) */
+#define RT5625_P_OSC_EN                        (0x1 << 15)
+#define RT5625_P_OSC_EN_BIT                    15
+#define RT5625_P_AUX_VOL                       (0x1 << 14)
+#define RT5625_P_AUX_VOL_BIT                   14
+#define RT5625_P_SPKL_VOL                      (0x1 << 13)
+#define RT5625_P_SPKL_VOL_BIT                  13
+#define RT5625_P_SPKR_VOL                      (0x1 << 12)
+#define RT5625_P_SPKR_VOL_BIT                  12
+#define RT5625_P_HPL_VOL                       (0x1 << 11)
+#define RT5625_P_HPL_VOL_BIT                   11
+#define RT5625_P_HPR_VOL                       (0x1 << 10)
+#define RT5625_P_HPR_VOL_BIT                   10
+#define RT5625_P_DSP_IF                                (0x1 << 9)
+#define RT5625_P_DSP_IF_BIT                    9
+#define RT5625_P_DSP_I2C                       (0x1 << 8)
+#define RT5625_P_DSP_I2C_BIT                   8
+#define RT5625_P_LV_L                          (0x1 << 7)
+#define RT5625_P_LV_L_BIT                      7
+#define RT5625_P_LV_R                          (0x1 << 6)
+#define RT5625_P_LV_R_BIT                      6
+#define RT5625_P_PH_VOL                        (0x1 << 5)
+#define RT5625_P_PH_VOL_BIT                    5
+#define RT5625_P_PH_ADMIX                      (0x1 << 4)
+#define RT5625_P_PH_ADMIX_BIT                  4
+#define RT5625_P_MIC1_VOL                      (0x1 << 3)
+#define RT5625_P_MIC1_VOL_BIT                  3
+#define RT5625_P_MIC2_VOL                      (0x1 << 2)
+#define RT5625_P_MIC2_VOL_BIT                  2
+#define RT5625_P_MIC1_BST                      (0x1 << 1)
+#define RT5625_P_MIC1_BST_BIT                  1
+#define RT5625_P_MIC2_BST                      (0x1)
+#define RT5625_P_MIC2_BST_BIT                  0
+
+/* General Purpose Control Register 1 (0x40) */
+#define RT5625_SCLK_MASK                       (0x1 << 15)
+#define RT5625_SCLK_SFT                                15
+#define RT5625_SCLK_MCLK                       (0x0 << 15)
+#define RT5625_SCLK_PLL1                       (0x1 << 15)
+#define RT5625_VSCLK_MASK                      (0x1 << 4)
+#define RT5625_VSCLK_SFT                       4
+#define RT5625_VSCLK_PLL2                      (0x0<<4)
+#define RT5625_VSCLK_EXTCLK                    (0x1<<4)
+#define RT5625_SPK_R_MASK                      (0x7 << 1)
+#define RT5625_SPK_R_SFT                       1
+#define RT5625_SPK_R_225V                      (0x0 << 1)
+#define RT5625_SPK_R_200V                      (0x1 << 1)
+#define RT5625_SPK_R_175V                      (0x2 << 1)
+#define RT5625_SPK_R_150V                      (0x3 << 1)
+#define RT5625_SPK_R_125V                      (0x4 << 1)
+#define RT5625_SPK_R_100V                      (0x5 << 1)
+
+/* General Purpose Control Register 2 (0x42) */
+#define RT5625_PLL1_S_MASK                     (0x3 << 12)
+#define RT5625_PLL1_S_SFT                      12
+#define RT5625_PLL1_S_MCLK                     (0x0 << 12)
+#define RT5625_PLL1_S_BCLK                     (0x2 << 12)
+#define RT5625_PLL1_S_VBCLK                    (0x3 << 12)
+
+/* PLL2 Control (0x46) */
+#define RT5625_PLL2_MASK                       (0x1 << 15)
+#define RT5625_PLL2_DIS                                (0x0 << 15)
+#define RT5625_PLL2_EN                         (0x1 << 15)
+#define RT5625_PLL2_R_MASK                     (0x1)
+#define RT5625_PLL2_R_8X                       (0x0)
+#define RT5625_PLL2_R_16X                      (0x1)
+
+/* LDO Control (0x48) */
+#define RT5625_LDO_MASK                        (0x1 << 15)
+#define RT5625_LDO_DIS                         (0x0 << 15)
+#define RT5625_LDO_EN                          (0x1 << 15)
+#define RT5625_LDO_VC_MASK                     (0xf)
+#define RT5625_LDO_VC_1_55V                    (0xf<<0)
+#define RT5625_LDO_VC_1_50V                    (0xe<<0)
+#define RT5625_LDO_VC_1_45V                    (0xd<<0)
+#define RT5625_LDO_VC_1_40V                    (0xc<<0)
+#define RT5625_LDO_VC_1_35V                    (0xb<<0)
+#define RT5625_LDO_VC_1_30V                    (0xa<<0)
+#define RT5625_LDO_VC_1_25V                    (0x9<<0)
+#define RT5625_LDO_VC_1_20V                    (0x8<<0)
+#define RT5625_LDO_VC_1_15V                    (0x7<<0)
+#define RT5625_LDO_VC_1_05V                    (0x6<<0)
+#define RT5625_LDO_VC_1_00V                    (0x5<<0)
+#define RT5625_LDO_VC_0_95V                    (0x4<<0)
+#define RT5625_LDO_VC_0_90V                    (0x3<<0)
+#define RT5625_LDO_VC_0_85V                    (0x2<<0)
+#define RT5625_LDO_VC_0_80V                    (0x1<<0)
+#define RT5625_LDO_VC_0_75V                    (0x0<<0)
+
+/* GPIO Pin Configuration (0x4c) */
+#define RT5625_GPIO_5                          (0x1 << 5)
+#define RT5625_GPIO_4                          (0x1 << 4)
+#define RT5625_GPIO_3                          (0x1 << 3)
+#define RT5625_GPIO_2                          (0x1 << 2)
+#define RT5625_GPIO_1                          (0x1 << 1)
+
+/* MISC Control (0x5e) */
+#define RT5625_FAST_VREF_MASK                  (0x1 << 15)
+#define RT5625_FAST_VREF_EN                    (0x0 << 15)
+#define RT5625_FAST_VREF_DIS                   (0x1 << 15)
+#define RT5625_HP_DEPOP_M2                     (0x1 << 8)
+#define RT5625_HP_DEPOP_M1                     (0x1 << 9)
+#define RT5625_HPL_MUM_DEPOP                   (0x1 << 7)
+#define RT5625_HPR_MUM_DEPOP                   (0x1 << 6)
+#define RT5625_MUM_DEPOP                       (0x1 << 5)
+
+/* Stereo DAC Clock Control 1 (0x60) */
+#define RT5625_BCLK_DIV1_MASK                  (0xf << 12)
+#define RT5625_BCLK_DIV1_1                     (0x0 << 12)
+#define RT5625_BCLK_DIV1_2                     (0x1 << 12)
+#define RT5625_BCLK_DIV1_3                     (0x2 << 12)
+#define RT5625_BCLK_DIV1_4                     (0x3 << 12)
+#define RT5625_BCLK_DIV1_5                     (0x4 << 12)
+#define RT5625_BCLK_DIV1_6                     (0x5 << 12)
+#define RT5625_BCLK_DIV1_7                     (0x6 << 12)
+#define RT5625_BCLK_DIV1_8                     (0x7 << 12)
+#define RT5625_BCLK_DIV1_9                     (0x8 << 12)
+#define RT5625_BCLK_DIV1_10                    (0x9 << 12)
+#define RT5625_BCLK_DIV1_11                    (0xa << 12)
+#define RT5625_BCLK_DIV1_12                    (0xb << 12)
+#define RT5625_BCLK_DIV1_13                    (0xc << 12)
+#define RT5625_BCLK_DIV1_14                    (0xd << 12)
+#define RT5625_BCLK_DIV1_15                    (0xe << 12)
+#define RT5625_BCLK_DIV1_16                    (0xf << 12)
+#define RT5625_BCLK_DIV2_MASK                  (0x7 << 8)
+#define RT5625_BCLK_DIV2_2                     (0x0 << 8)
+#define RT5625_BCLK_DIV2_4                     (0x1 << 8)
+#define RT5625_BCLK_DIV2_8                     (0x2 << 8)
+#define RT5625_BCLK_DIV2_16                    (0x3 << 8)
+#define RT5625_BCLK_DIV2_32                    (0x4 << 8)
+#define RT5625_AD_LRCK_DIV1_MASK               (0xf << 4)
+#define RT5625_AD_LRCK_DIV1_1                  (0x0 << 4)
+#define RT5625_AD_LRCK_DIV1_2                  (0x1 << 4)
+#define RT5625_AD_LRCK_DIV1_3                  (0x2 << 4)
+#define RT5625_AD_LRCK_DIV1_4                  (0x3 << 4)
+#define RT5625_AD_LRCK_DIV1_5                  (0x4 << 4)
+#define RT5625_AD_LRCK_DIV1_6                  (0x5 << 4)
+#define RT5625_AD_LRCK_DIV1_7                  (0x6 << 4)
+#define RT5625_AD_LRCK_DIV1_8                  (0x7 << 4)
+#define RT5625_AD_LRCK_DIV1_9                  (0x8 << 4)
+#define RT5625_AD_LRCK_DIV1_10                 (0x9 << 4)
+#define RT5625_AD_LRCK_DIV1_11                 (0xa << 4)
+#define RT5625_AD_LRCK_DIV1_12                 (0xb << 4)
+#define RT5625_AD_LRCK_DIV1_13                 (0xc << 4)
+#define RT5625_AD_LRCK_DIV1_14                 (0xd << 4)
+#define RT5625_AD_LRCK_DIV1_15                 (0xe << 4)
+#define RT5625_AD_LRCK_DIV1_16                 (0xf << 4)
+#define RT5625_AD_LRCK_DIV2_MASK               (0x7 << 1)
+#define RT5625_AD_LRCK_DIV2_2                  (0x0 << 1)
+#define RT5625_AD_LRCK_DIV2_4                  (0x1 << 1)
+#define RT5625_AD_LRCK_DIV2_8                  (0x2 << 1)
+#define RT5625_AD_LRCK_DIV2_16                 (0x3 << 1)
+#define RT5625_AD_LRCK_DIV2_32                 (0x4 << 1)
+#define RT5625_DA_LRCK_DIV_MASK                (1)
+#define RT5625_DA_LRCK_DIV_32                  (0)
+#define RT5625_DA_LRCK_DIV_64                  (1)
+
+/* Stereo DAC Clock Control 2 (0x62) */
+#define RT5625_DF_DIV1_MASK                    (0xF << 12)
+#define RT5625_DF_DIV1_1                       (0x0 << 12)
+#define RT5625_DF_DIV1_2                       (0x1 << 12)
+#define RT5625_DF_DIV1_3                       (0x2 << 12)
+#define RT5625_DF_DIV1_4                       (0x3 << 12)
+#define RT5625_DF_DIV1_5                       (0x4 << 12)
+#define RT5625_DF_DIV1_6                       (0x5 << 12)
+#define RT5625_DF_DIV1_7                       (0x6 << 12)
+#define RT5625_DF_DIV1_8                       (0x7 << 12)
+#define RT5625_DF_DIV1_9                       (0x8 << 12)
+#define RT5625_DF_DIV1_10                      (0x9 << 12)
+#define RT5625_DF_DIV1_11                      (0xA << 12)
+#define RT5625_DF_DIV1_12                      (0xB << 12)
+#define RT5625_DF_DIV1_13                      (0xC << 12)
+#define RT5625_DF_DIV1_14                      (0xD << 12)
+#define RT5625_DF_DIV1_15                      (0xE << 12)
+#define RT5625_DF_DIV1_16                      (0xF << 12)
+#define RT5625_DF_DIV2_MASK                    (0x7 << 9)
+#define RT5625_DF_DIV2_2                       (0x0 << 9)
+#define RT5625_DF_DIV2_4                       (0x1 << 9)
+#define RT5625_DF_DIV2_8                       (0x2 << 9)
+#define RT5625_DF_DIV2_16                      (0x3 << 9)
+#define RT5625_DF_DIV2_32                      (0x4 << 9)
+#define RT5625_AF_DIV1_MASK                    (0xF << 4)
+#define RT5625_AF_DIV1_1                       (0x0 << 4)
+#define RT5625_AF_DIV1_2                       (0x1 << 4)
+#define RT5625_AF_DIV1_3                       (0x2 << 4)
+#define RT5625_AF_DIV1_4                       (0x3 << 4)
+#define RT5625_AF_DIV1_5                       (0x4 << 4)
+#define RT5625_AF_DIV1_6                       (0x5 << 4)
+#define RT5625_AF_DIV1_7                       (0x6 << 4)
+#define RT5625_AF_DIV1_8                       (0x7 << 4)
+#define RT5625_AF_DIV1_9                       (0x8 << 4)
+#define RT5625_AF_DIV1_10                      (0x9 << 4)
+#define RT5625_AF_DIV1_11                      (0xA << 4)
+#define RT5625_AF_DIV1_12                      (0xB << 4)
+#define RT5625_AF_DIV1_13                      (0xC << 4)
+#define RT5625_AF_DIV1_14                      (0xD << 4)
+#define RT5625_AF_DIV1_15                      (0xE << 4)
+#define RT5625_AF_DIV1_16                      (0xF << 4)
+#define RT5625_AF_DIV2_MASK                    (0x7 << 1)
+#define RT5625_AF_DIV2_1                       (0x0 << 1)
+#define RT5625_AF_DIV2_2                       (0x1 << 1)
+#define RT5625_AF_DIV2_4                       (0x2 << 1)
+#define RT5625_AF_DIV2_8                       (0x3 << 1)
+#define RT5625_AF_DIV2_16                      (0x4 << 1)
+#define RT5625_AF_DIV2_32                      (0x5 << 1)
+
+/* Voice DAC PCM Clock Control 1 (0x64) */
+#define RT5625_VBCLK_DIV1_MASK         (0xF << 12)
+#define RT5625_VBCLK_DIV1_1                    (0x0 << 12)
+#define RT5625_VBCLK_DIV1_2                    (0x1 << 12)
+#define RT5625_VBCLK_DIV1_3                    (0x2 << 12)
+#define RT5625_VBCLK_DIV1_4                    (0x3 << 12)
+#define RT5625_VBCLK_DIV1_5                    (0x4 << 12)
+#define RT5625_VBCLK_DIV1_6                    (0x5 << 12)
+#define RT5625_VBCLK_DIV1_7                    (0x6 << 12)
+#define RT5625_VBCLK_DIV1_8                    (0x7 << 12)
+#define RT5625_VBCLK_DIV1_9                    (0x8 << 12)
+#define RT5625_VBCLK_DIV1_10                   (0x9 << 12)
+#define RT5625_VBCLK_DIV1_11                   (0xA << 12)
+#define RT5625_VBCLK_DIV1_12                   (0xB << 12)
+#define RT5625_VBCLK_DIV1_13                   (0xC << 12)
+#define RT5625_VBCLK_DIV1_14                   (0xD << 12)
+#define RT5625_VBCLK_DIV1_15                   (0xE << 12)
+#define RT5625_VBCLK_DIV1_16                   (0xF << 12)
+#define RT5625_VBCLK_DIV2_MASK         (0x7 << 8)
+#define RT5625_VBCLK_DIV2_2                    (0x0 << 8)
+#define RT5625_VBCLK_DIV2_4                    (0x1 << 8)
+#define RT5625_VBCLK_DIV2_8                    (0x2 << 8)
+#define RT5625_VBCLK_DIV2_16                   (0x3 << 8)
+#define RT5625_VBCLK_DIV2_32                   (0x4 << 8)
+#define RT5625_AD_VLRCK_DIV1_MASK              (0xF << 4)
+#define RT5625_AD_VLRCK_DIV1_1                 (0x0 << 4)
+#define RT5625_AD_VLRCK_DIV1_2                 (0x1 << 4)
+#define RT5625_AD_VLRCK_DIV1_3                 (0x2 << 4)
+#define RT5625_AD_VLRCK_DIV1_4                 (0x3 << 4)
+#define RT5625_AD_VLRCK_DIV1_5                 (0x4 << 4)
+#define RT5625_AD_VLRCK_DIV1_6                 (0x5 << 4)
+#define RT5625_AD_VLRCK_DIV1_7                 (0x6 << 4)
+#define RT5625_AD_VLRCK_DIV1_8                 (0x7 << 4)
+#define RT5625_AD_VLRCK_DIV1_9                 (0x8 << 4)
+#define RT5625_AD_VLRCK_DIV1_10                (0x9 << 4)
+#define RT5625_AD_VLRCK_DIV1_11                (0xA << 4)
+#define RT5625_AD_VLRCK_DIV1_12                (0xB << 4)
+#define RT5625_AD_VLRCK_DIV1_13                (0xC << 4)
+#define RT5625_AD_VLRCK_DIV1_14                (0xD << 4)
+#define RT5625_AD_VLRCK_DIV1_15                (0xE << 4)
+#define RT5625_AD_VLRCK_DIV1_16                (0xF << 4)
+#define RT5625_AD_VLRCK_DIV2_MASK              (0x7 << 1)
+#define RT5625_AD_VLRCK_DIV2_2                 (0x0 << 1)
+#define RT5625_AD_VLRCK_DIV2_4                 (0x1 << 1)
+#define RT5625_AD_VLRCK_DIV2_8                 (0x2 << 1)
+#define RT5625_AD_VLRCK_DIV2_16                (0x3 << 1)
+#define RT5625_AD_VLRCK_DIV2_32                (0x4 << 1)
+#define RT5625_DA_VLRCK_DIV_MASK               (1)
+#define RT5625_DA_VLRCK_DIV_32                 (0)
+#define RT5625_DA_VLRCK_DIV_64                 (1)
+
+/* Psedueo Stereo & Spatial Effect Block Control (0x68) */
+#define RT5625_SP_CTRL_EN                      (0x1 << 15)
+#define RT5625_APF_EN                          (0x1 << 14)
+#define RT5625_PS_EN                           (0x1 << 13)
+#define RT5625_STO_EXP_EN                      (0x1 << 12)
+#define RT5625_SP_3D_G1_MASK                   (0x3 << 10)
+#define RT5625_SP_3D_G1_1_0                    (0x0 << 10)
+#define RT5625_SP_3D_G1_1_5                    (0x1 << 10)
+#define RT5625_SP_3D_G1_2_0                    (0x2 << 10)
+#define RT5625_SP_3D_R1_MASK                   (0x3 << 8)
+#define RT5625_SP_3D_R1_0_0                    (0x0 << 8)
+#define RT5625_SP_3D_R1_0_66                   (0x1 << 8)
+#define RT5625_SP_3D_R1_1_0                    (0x2 << 8)
+#define RT5625_SP_3D_G2_MASK                   (0x3 << 6)
+#define RT5625_SP_3D_G2_1_0                    (0x0 << 6)
+#define RT5625_SP_3D_G2_1_5                    (0x1 << 6)
+#define RT5625_SP_3D_G2_2_0                    (0x2 << 6)
+#define RT5625_SP_3D_R2_MASK                   (0x3 << 4)
+#define RT5625_SP_3D_R2_0_0                    (0x0 << 4)
+#define RT5625_SP_3D_R2_0_66                   (0x1 << 4)
+#define RT5625_SP_3D_R2_1_0                    (0x2 << 4)
+#define RT5625_APF_MASK                        (0x3)
+#define RT5625_APF_48K                         (0x3)
+#define RT5625_APF_44_1K                       (0x2)
+#define RT5625_APF_32K                         (0x1)
+
+/* EQ Control and Status /ADC HPF Control (0x6E) */
+#define RT5625_EN_HW_EQ_BLK                    (0x1 << 15)
+#define RT5625_EQ_SRC_DAC                      (0x0 << 14)
+#define RT5625_EQ_SRC_ADC                      (0x1 << 14)
+#define RT5625_EQ_CHG_EN                       (0x1 << 7)
+#define RT5625_EN_HW_EQ_HPF                    (0x1 << 4)
+#define RT5625_EN_HW_EQ_BP3                    (0x1 << 3)
+#define RT5625_EN_HW_EQ_BP2                    (0x1 << 2)
+#define RT5625_EN_HW_EQ_BP1                    (0x1 << 1)
+#define RT5625_EN_HW_EQ_LPF                    (0x1 << 0)
+
+/* VoDSP Register Command (0x74) */
+#define RT5625_DSP_BUSY_MASK                   (0x1 << 15)
+#define RT5625_DSP_DS_MASK                     (0x1 << 14)
+#define RT5625_DSP_DS_VODSP                    (0x0 << 14)
+#define RT5625_DSP_DS_REG72                    (0x1 << 14)
+#define RT5625_DSP_CLK_MASK                    (0x3 << 12)
+#define RT5625_DSP_CLK_12_288M         (0x0 << 12)
+#define RT5625_DSP_CLK_6_144M                  (0x1 << 12)
+#define RT5625_DSP_CLK_3_072M                  (0x2 << 12)
+#define RT5625_DSP_CLK_2_048M                  (0x3 << 12)
+#define RT5625_DSP_R_EN                                (0x1 << 9)
+#define RT5625_DSP_W_EN                        (0x1 << 8)
+#define RT5625_DSP_CMD_MASK                    (0xff)
+#define RT5625_DSP_CMD_SFT                     0
+#define RT5625_DSP_CMD_MW                      (0x3B)  /* Memory Write */
+#define RT5625_DSP_CMD_MR                      (0x37)  /* Memory Read */
+#define RT5625_DSP_CMD_RR                      (0x60)  /* Register Read */
+#define RT5625_DSP_CMD_RW                      (0x68)  /* Register Write */
+
+
+/* Index(0x20) for Auto Volume Control */
+#define RT5625_AVC_CH_MASK                     (0x1 << 7)
+#define RT5625_AVC_CH_L_CH                     (0x0 << 7)
+#define RT5625_AVC_CH_R_CH                     (0x1 << 7)
+#define RT5625_AVC_GAIN_EN                     (0x1 << 15)
+
+
+
+enum {
+       RT5625_AIF1,
+       RT5625_AIF2,
 };
 
-struct rt56xx_cmd
-{
-       size_t number;
-       struct rt56xx_reg_state __user *buf;            
+/* System Clock Source */
+enum {
+       RT5625_SCLK_S_MCLK,
+       RT5625_SCLK_S_PLL,
 };
 
-
-enum 
-{
-       RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt56xx_cmd),
-       RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt56xx_cmd),
-       RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x03, struct rt56xx_cmd),
-};
-
-#endif
-
-
-enum pll_sel
-{
-       RT5625_PLL1_FROM_MCLK = 0,
-       RT5625_PLL1_FROM_BCLK,
-       RT5625_PLL1_FROM_VBCLK,
+enum pll_sel {
+       RT5625_PLL_MCLK = 0,
+       RT5625_PLL_MCLK_TO_VSYSCLK,
+       RT5625_PLL_BCLK,
+       RT5625_PLL_VBCLK,
 };
 
-enum AEC_MODE
-{
-       PCM_IN_PCM_OUT = 0,
-       ANALOG_IN_ANALOG_OUT,
-       DAC_IN_ADC_OUT,
-       VODSP_AEC_DISABLE               
+enum {
+       RT5625_AEC_DIS,
+       RT5625_AEC_EN,
 };
 
-enum
-{
-       PCM_MASTER_MODE_A=0,
-       PCM_MASTER_MODE_B,
-       PCM_SLAVE_MODE_A,
-       PCM_SLAVE_MODE_B,
+//#ifdef RT5625_F_SMT_PHO
+enum {
+       RT5625_PLL_DIS,
+       RT5625_PLL_112896_225792,
+       RT5625_PLL_112896_24576,
 };
+//#endif
 
-
-enum RT5625_FUNC_SEL
-{
-       RT5625_AEC_DISABLE =0,
-       RT5625_AEC_PCM_IN_OUT,
-       RT5625_AEC_IIS_IN_OUT,
-       RT5625_AEC_ANALOG_IN_OUT,
-
-};
-
-
-struct rt5625_setup_data {
-       int i2c_bus;
-       int i2c_address;
-};
-
-typedef struct 
-{ 
-       unsigned short int VoiceDSPIndex;
-       unsigned short int VoiceDSPValue;
-
-}Voice_DSP_Reg;
-
-extern struct snd_soc_dai rt5625_dai[];
-extern struct snd_soc_codec_device soc_codec_dev_rt5625;
+typedef struct { 
+       unsigned short index;
+       unsigned short value;
+} rt5625_dsp_reg;
 
 #endif
index 1a7ead6c3e8551e4ea834eff9fbad066633195ef..2322ac47b789c36678dce185dd260890905861d6 100755 (executable)
@@ -909,6 +909,34 @@ static int wm8994_PA_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+int lineout_event(struct snd_soc_dapm_widget *w,
+                         struct snd_kcontrol *control, int event)
+{
+//     struct snd_soc_codec *codec = w->codec;
+//     struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+//     struct wm8994_pdata *pdata = wm8994->pdata;
+       
+//     printk("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__);
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND  
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               printk("wm8994 is incall status\n");
+               snd_soc_incall_status(1,1);
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               printk("wm8994 exit incall status\n");
+               snd_soc_incall_status(1,0);
+               break;
+
+       default:
+               BUG();
+               break;
+       }
+#endif
+       return 0;
+}
+
 static int aif1clk_ev(struct snd_soc_dapm_widget *w,
                      struct snd_kcontrol *kcontrol, int event)
 {
@@ -1666,8 +1694,20 @@ static const struct snd_soc_dapm_route wm8994_PA_intercon[] = {
 static const struct snd_soc_dapm_widget wm8994_PA_dapm_widgets[] = {
 SND_SOC_DAPM_SPK("PA Driver", wm8994_PA_event),
 };
+/*
+static const struct snd_soc_dapm_route wm8994_lineout_status_intercon[] = {
+       { "LINEOUT1N STATUS", NULL,"LINEOUT1N Driver"},
+       { "LINEOUT1P STATUS", NULL,"LINEOUT1P Driver"}, 
 
+       { "LINEOUT1N", NULL, "LINEOUT1N STATUS" },
+       { "LINEOUT1P", NULL, "LINEOUT1P STATUS" },
+};
 
+static const struct snd_soc_dapm_widget wm8994_lineout_status_dapm_widgets[] = {
+SND_SOC_DAPM_LINE("LINEOUT1N Driver", lineout_event),
+SND_SOC_DAPM_LINE("LINEOUT1P Driver", lineout_event),  
+};
+*/
 /* The size in bits of the FLL divide multiplied by 10
  * to allow rounding later */
 #define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2591,7 +2631,14 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
        struct wm8994 *control = codec->control_data;
        int i, ret;
        
-//     printk("on wm8994.c wm8994_suspend\n");
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND  
+       DBG("on wm8994.c wm8994_suspend\n");
+       if(snd_soc_incall_status(0,0))
+       {
+               DBG("incalling  cannot suspend\n");
+               return 0;
+       }
+#endif
        switch (control->type) {
        case WM8994:
                snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
@@ -2623,7 +2670,15 @@ static int wm8994_resume(struct snd_soc_codec *codec)
        int i, ret;
        unsigned int val, mask;
        
-//     printk("on wm8994.c wm8994_resume\n");
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND  
+       printk("on wm8994.c wm8994_resume\n");
+       if(snd_soc_incall_status(0,0))
+       {
+               DBG("incalling cannot resume\n");
+               return 0;
+       }
+#endif
+
        if (wm8994->revision < 4) {
                /* force a HW read */
                val = wm8994_reg_read(codec->control_data,
@@ -3340,7 +3395,13 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        }
        else
                dev_info(codec->dev, "have not pa control\n");  
-       
+
+       //lineout off
+//     snd_soc_dapm_new_controls(dapm, wm8994_lineout_status_dapm_widgets,
+//                              ARRAY_SIZE(wm8994_lineout_status_dapm_widgets));       
+//     snd_soc_dapm_add_routes(dapm, wm8994_lineout_status_intercon, 
+//                             ARRAY_SIZE(wm8994_lineout_status_intercon));
+               
        return 0;
 
 err_irq:
index 0a1db04b73bd7e97e20f61349528c108fa831a3c..1eef4d3d18bc9f8685d69428e925b26c958d22ee 100755 (executable)
@@ -140,6 +140,11 @@ struct wm8994_priv {
        const struct firmware *mbc;
        const struct firmware *mbc_vss;
        const struct firmware *enh_eq;
+
+       unsigned int lineout_status:1;
 };
 
+int lineout_event(struct snd_soc_dapm_widget *w,
+                         struct snd_kcontrol *control, int event);
+
 #endif
index aef36262cf44438dde35043f071d5a4465abbe9f..e57d1d5c1dbc890e1d204ea22f32839cfd854f19 100755 (executable)
@@ -26,6 +26,7 @@
 #include <sound/tlv.h>
 
 #include "wm8993.h"
+#include "wm8994.h"
 #include "wm_hubs.h"
 
 const DECLARE_TLV_DB_SCALE(wm_hubs_spkmix_tlv, -300, 300, 0);
@@ -653,10 +654,17 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
 SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
                   line2p_mix, ARRAY_SIZE(line2p_mix)),
 
-SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
-                NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
-                NULL, 0),
+//SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
+//              NULL, 0),
+//SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
+//              NULL, 0),
+SND_SOC_DAPM_PGA_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
+                NULL, 0,
+                lineout_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_PGA_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
+                NULL, 0,
+                lineout_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+                
 SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
                 NULL, 0),
 SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
index e58d9f09d4ab15db315c91e60f213a2503fcccf8..98169399de09fcf6d39992508ffa0458ab3cc9d6 100755 (executable)
@@ -80,11 +80,27 @@ config SND_RK29_SOC_RT5625
        tristate "SoC I2S Audio support for rockchip - RT5625"
        depends on SND_RK29_SOC
        select SND_RK29_SOC_I2S
-       select SND_SOC_RT5625
        help
          Say Y if you want to add support for SoC audio on rockchip
          with the RT5625.
 
+choice
+       depends on SND_RK29_SOC_RT5625
+       prompt  "RT5625 hardware select"
+
+       config SND_SOC_RT5625_SPK_FORM_SPKOUT
+       bool "spk from spkout"
+       select SND_SOC_RT5625
+       help
+         if your codec output hardware connect is spk from spkout, choose it
+
+       config SND_SOC_RT5625_SPK_FORM_HPOUT
+       bool "spk from hpout"
+       select SND_SOC_RT5625
+       help
+         if your codec output hardware connect is spk from spkout, choose it
+endchoice
+
 config SND_RK29_SOC_WM8994
        tristate "SoC I2S Audio support for rockchip - WM8994"
        depends on SND_RK29_SOC
@@ -137,5 +153,11 @@ config ADJUST_VOL_BY_CODEC
     default n
     help
          adjust volume by codec
-                 
+
+config PHONE_INCALL_IS_SUSPEND
+       bool "Incalling Whether suspend codec"
+    default n
+    help
+               set "y" phone incall status cannot into suspend codec
+               
 endif
index fda7169c582e5c13e6c9fff5f8cf6901e4553143..9a72e440ceb41482b1c68d23f08695f44d9f2a23 100644 (file)
-/*
- * rk29_rt5625.c  --  SoC audio for rockchip
- *
- * Driver for rockchip rt5625 audio
- *
- *  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/device.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/soc-dapm.h>
-#include <asm/io.h>
-#include <mach/hardware.h>
-#include <mach/rk29_iomap.h>
-#include "../codecs/rt5625.h"
-#include "rk29_pcm.h"
-#include "rk29_i2s.h"
-
-#if 0
-#define        DBG(x...)       printk(KERN_INFO x)
-#else
-#define        DBG(x...)
-#endif
-
-static int rk29_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-       unsigned int pll_out = 0;
-       int ret;
-
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);    
-       /*by Vincent Hsiung for EQ Vol Change*/
-       #define HW_PARAMS_FLAG_EQVOL_ON 0x21
-       #define HW_PARAMS_FLAG_EQVOL_OFF 0x22
-       if (codec_dai->ops->hw_params && ((params->flags == HW_PARAMS_FLAG_EQVOL_ON) || (params->flags == HW_PARAMS_FLAG_EQVOL_OFF)))
-       {
-               ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent
-               DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-       } else {
-                
-               /* set codec DAI configuration */
-               #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
-
-               ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
-               #endif  
-               #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 
-
-               ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); 
-               #endif
-               if (ret < 0)
-                       return ret; 
-
-               /* set cpu DAI configuration */
-               #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
-               ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-               #endif  
-               #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 
-               ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 
-               #endif          
-               if (ret < 0)
-                       return ret;
-       }
-
-       switch(params_rate(params)) {
-               case 8000:
-               case 16000:
-               case 24000:
-               case 32000:
-               case 48000:
-                       pll_out = 12288000;
-                       break;
-               case 11025:
-               case 22050:
-               case 44100:
-                       pll_out = 11289600;
-                       break;
-               default:
-                       DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
-                       return -EINVAL;
-                       break;
-       }
-
-       DBG("Enter:%s, %d, rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
-
-       /*Set the system clk for codec*/
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
-       if (ret < 0)
-       {
-                      DBG("rk29_hw_params_rt5625:failed to set the sysclk for codec side\n"); 
-               return ret;
-       }
-
-       snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
-       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
-       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
-
-       DBG("Enter:%s, %d, pll_out/4/params_rate(params) = %d \n", __FUNCTION__, __LINE__, (pll_out/4)/params_rate(params));
-       return 0;
-}
-
-static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = {
-       
-       SND_SOC_DAPM_MIC("Mic Jack", NULL),
-       SND_SOC_DAPM_SPK("Ext Spk", NULL),
-       SND_SOC_DAPM_HP("Headphone Jack", NULL),
-
-};
-
-static const struct snd_soc_dapm_route audio_map[]={
-
-       /* Mic Jack --> MIC_IN*/
-       {"Mic1 Bias", NULL, "Mic Jack"},
-       {"Mic1", NULL, "Mic1 Bias"},
-       /* HP_OUT --> Headphone Jack */
-       {"Headphone Jack", NULL, "HPL"},
-       {"Headphone Jack", NULL, "HPR"},
-       /* LINE_OUT --> Ext Speaker */
-       {"Ext Spk", NULL, "SPKL"},
-       {"Ext Spk", NULL, "SPKR"},
-} ;
-
-/*
- * Logic for a rt5625 as connected on a rockchip board.
- */
-static int rk29_rt5625_init(struct snd_soc_codec *codec)
-{        
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-
-       /* Add specific widgets */
-       snd_soc_dapm_new_controls(codec, rt5625_dapm_widgets,
-                            ARRAY_SIZE(rt5625_dapm_widgets));
-
-       /* Set up specific audio path audio_mapnects */
-       snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-       //snd_soc_dapm_nc_pin(codec, "HP_L");
-       //snd_soc_dapm_nc_pin(codec, "HP_R");
-       snd_soc_dapm_sync(codec);
-
-       return 0;
-}
-
-static int rt5625_voice_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
-       unsigned int pll_out = 0;
-       int ret;
-
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);    
-       
-       /* set codec DAI configuration */
-       /*#if defined (CONFIG_SND_CODEC_SOC_SLAVE) 
-       DBG("Enter::%s----codec slave\n",__FUNCTION__);
-
-       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
-                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
-       #endif*/
-       //#if defined (CONFIG_SND_CODEC_SOC_MASTER) 
-       DBG("Enter::%s----codec master\n",__FUNCTION__);
-
-       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
-               SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM ); 
-       //#endif
-
-       switch(params_rate(params)) {
-               case 8000:
-               case 16000:
-               case 24000:
-               case 32000:
-               case 48000:
-                       pll_out = 12288000;
-                       break;
-               case 11025:
-               case 22050:
-               case 44100:
-                       pll_out = 11289600;
-                       break;
-               default:
-                       DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
-                       return -EINVAL;
-                       break;
-       }
-
-       snd_soc_dai_set_pll(codec_dai, RT5625_PLL1_FROM_MCLK, pll_out, 24576000);
-
-       /*Set the system clk for codec*/
-       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);
-
-       if (ret < 0) {
-               printk("rk29_hw_params_rt5625:failed to set the sysclk for codec side\n"); 
-               return ret;
-       }
-
-       ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
-       return 0;
-}
-
-static struct snd_soc_ops rk29_ops = {
-       .hw_params = rk29_hw_params,
-};
-
-static struct snd_soc_ops rt5625_voice_ops = {
-       .hw_params = rt5625_voice_hw_params,
-};
-
-static struct snd_soc_dai_link rk29_dai[] = {
-       {
-               .name = "RT5625-1",
-               .stream_name = "RT5625 PCM-1",
-               .cpu_dai = &rk29_i2s_dai,
-               .codec_dai = &rt5625_dai[0],
-               .init = rk29_rt5625_init,
-               .ops = &rk29_ops,
-       },
-       {
-               .name = "RT5625-2",
-               .stream_name = "RT5625 PCM-2",
-               .cpu_dai = &rk29_i2s_dai,
-               .codec_dai = &rt5625_dai[1],
-               .init = rk29_rt5625_init,
-               .ops = &rt5625_voice_ops,
-       }
-};
-
-static struct snd_soc_card snd_soc_card_rk29 = {
-       .name = "RK29_RT5625",
-       .platform = &rk29_soc_platform,
-       .dai_link = &rk29_dai,
-       .num_links = 1,
-};
-
-
-static struct snd_soc_device rk29_snd_devdata = {
-       .card = &snd_soc_card_rk29,
-       .codec_dev = &soc_codec_dev_rt5625,
-};
-
-static struct platform_device *rk29_snd_device;
-
-static int __init audio_card_init(void)
-{
-       int ret =0;
-
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-
-       rk29_snd_device = platform_device_alloc("soc-audio", -1);
-       if (!rk29_snd_device) {
-                 DBG("platform device allocation failed\n");
-                 ret = -ENOMEM;
-                 return ret;
-       }
-       platform_set_drvdata(rk29_snd_device, &rk29_snd_devdata);
-       rk29_snd_devdata.dev = &rk29_snd_device->dev;
-       ret = platform_device_add(rk29_snd_device);
-       if (ret) {
-               DBG("platform device add failed\n");
-               platform_device_put(rk29_snd_device);
-       }
-       return ret;
-}
-
-static void __exit audio_card_exit(void)
-{
-       platform_device_unregister(rk29_snd_device);
-}
-
-module_init(audio_card_init);
-module_exit(audio_card_exit);
-/* Module information */
-MODULE_AUTHOR("rockchip");
-MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
-MODULE_LICENSE("GPL");
+/*\r
+ * rk29_rt5625.c  --  SoC audio for rockchip\r
+ *\r
+ * Driver for rockchip rt5625 audio\r
+ *\r
+ *  This program is free software; you can redistribute  it and/or modify it\r
+ *  under  the terms of  the GNU General  Public License as published by the\r
+ *  Free Software Foundation;  either version 2 of the  License, or (at your\r
+ *  option) any later version.\r
+ *\r
+ *\r
+ */\r
+\r
+#include <linux/module.h>\r
+#include <linux/device.h>\r
+#include <sound/core.h>\r
+#include <sound/pcm.h>\r
+#include <sound/soc.h>\r
+#include <sound/soc-dapm.h>\r
+#include <asm/io.h>\r
+#include <mach/hardware.h>\r
+#include <mach/rk29_iomap.h>\r
+#include "../codecs/rt5625.h"\r
+#include "rk29_pcm.h"\r
+#include "rk29_i2s.h"\r
+\r
+#if 1\r
+#define        DBG(x...)       printk(KERN_INFO x)\r
+#else\r
+#define        DBG(x...)\r
+#endif\r
+\r
+static int rk29_hw_params(struct snd_pcm_substream *substream,\r
+       struct snd_pcm_hw_params *params)\r
+{\r
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;\r
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;\r
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;\r
+       unsigned int pll_out = 0;\r
+       int ret;\r
+\r
+       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);    \r
+       /*by Vincent Hsiung for EQ Vol Change*/\r
+       #define HW_PARAMS_FLAG_EQVOL_ON 0x21\r
+       #define HW_PARAMS_FLAG_EQVOL_OFF 0x22\r
+       if (codec_dai->driver->ops->hw_params && ((params->flags == HW_PARAMS_FLAG_EQVOL_ON) || (params->flags == HW_PARAMS_FLAG_EQVOL_OFF)))\r
+       {\r
+               ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent\r
+               DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);\r
+       } else {\r
+                \r
+               /* set codec DAI configuration */\r
+               #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) \r
+\r
+               ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |\r
+                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);\r
+               #endif  \r
+               #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) \r
+\r
+               ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |\r
+                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); \r
+               #endif\r
+               if (ret < 0)\r
+                       return ret; \r
+\r
+               /* set cpu DAI configuration */\r
+               #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) \r
+               ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |\r
+                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);\r
+               #endif  \r
+               #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) \r
+               ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |\r
+                               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); \r
+               #endif          \r
+               if (ret < 0)\r
+                       return ret;\r
+       }\r
+\r
+       switch(params_rate(params)) {\r
+               case 8000:\r
+               case 16000:\r
+               case 24000:\r
+               case 32000:\r
+               case 48000:\r
+                       pll_out = 12288000;\r
+                       break;\r
+               case 11025:\r
+               case 22050:\r
+               case 44100:\r
+                       pll_out = 11289600;\r
+                       break;\r
+               default:\r
+                       DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));\r
+                       return -EINVAL;\r
+                       break;\r
+       }\r
+\r
+       DBG("Enter:%s, %d, rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));\r
+\r
+       /*Set the system clk for codec*/\r
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);\r
+       if (ret < 0)\r
+       {\r
+                      DBG("rk29_hw_params_rt5625:failed to set the sysclk for codec side\n"); \r
+               return ret;\r
+       }\r
+\r
+       snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);\r
+       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);\r
+       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);\r
+\r
+       DBG("Enter:%s, %d, pll_out/4/params_rate(params) = %d \n", __FUNCTION__, __LINE__, (pll_out/4)/params_rate(params));\r
\r
+       return 0;\r
+}\r
+\r
+static int rt5625_voice_hw_params(struct snd_pcm_substream *substream,\r
+       struct snd_pcm_hw_params *params)\r
+{\r
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;\r
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;\r
+       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;\r
+       unsigned int pll_out = 0;\r
+       int ret;\r
+\r
+       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);    \r
+       \r
+       /* set codec DAI configuration */\r
+       //#if defined (CONFIG_SND_CODEC_SOC_SLAVE) \r
+       DBG("Enter::%s----codec slave\n",__FUNCTION__);\r
+\r
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |\r
+                               SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS);\r
+       /*#endif\r
+       //#if defined (CONFIG_SND_CODEC_SOC_MASTER) \r
+       DBG("Enter::%s----codec master\n",__FUNCTION__);\r
+\r
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |\r
+               SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM ); \r
+       #endif*/\r
+\r
+       switch(params_rate(params)) {\r
+               case 8000:\r
+               case 16000:\r
+               case 24000:\r
+               case 32000:\r
+               case 48000:\r
+                       pll_out = 12288000;\r
+                       break;\r
+               case 11025:\r
+               case 22050:\r
+               case 44100:\r
+                       pll_out = 11289600;\r
+                       break;\r
+               default:\r
+                       DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));\r
+                       return -EINVAL;\r
+                       break;\r
+       }\r
+\r
+       snd_soc_dai_set_pll(codec_dai, RT5625_PLL_MCLK_TO_VSYSCLK, 0, pll_out, 24576000);\r
+\r
+       /*Set the system clk for codec*/\r
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 24576000, SND_SOC_CLOCK_IN);\r
+\r
+       if (ret < 0) {\r
+               printk("rk29_hw_params_rt5625:failed to set the sysclk for codec side\n"); \r
+               return ret;\r
+       }\r
+\r
+       ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);\r
\r
+       return 0;\r
+}\r
+\r
+static struct snd_soc_ops rk29_ops = {\r
+       .hw_params = rk29_hw_params,\r
+};\r
+\r
+static struct snd_soc_ops rt5625_voice_ops = {\r
+       .hw_params = rt5625_voice_hw_params,\r
+};\r
+\r
+static struct snd_soc_dai_link rk29_dai[] = {\r
+       {\r
+               .name = "RT5625 I2S1",\r
+               .stream_name = "RT5625 PCM",\r
+               .codec_name = "rt5625.0-001f",\r
+               .platform_name = "rockchip-audio",\r
+               .cpu_dai_name = "rk29_i2s.0",\r
+               .codec_dai_name = "rt5625-aif1",\r
+               .ops = &rk29_ops,\r
+       },\r
+       {\r
+               .name = "RT5625 I2S2",\r
+               .stream_name = "RT5625 PCM",\r
+               .codec_name = "rt5625.0-001f",\r
+               .platform_name = "rockchip-audio",\r
+               .cpu_dai_name = "rk29_i2s.0",\r
+               .codec_dai_name = "rt5625-aif2",\r
+               .ops = &rt5625_voice_ops,\r
+       },\r
+};\r
+\r
+static struct snd_soc_card snd_soc_card_rk29 = {\r
+       .name = "RK29_RT5625",\r
+       .dai_link = rk29_dai,\r
+       .num_links = 2,\r
+};\r
+\r
+static struct platform_device *rk29_snd_device;\r
+\r
+static int __init audio_card_init(void)\r
+{\r
+       int ret =0;\r
+\r
+       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);\r
+\r
+       rk29_snd_device = platform_device_alloc("soc-audio", -1);\r
+       if (!rk29_snd_device) {\r
+                 printk("platform device allocation failed\n");\r
+                 return -ENOMEM;\r
+       }\r
+\r
+       platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29);\r
+       ret = platform_device_add(rk29_snd_device);\r
+       if (ret) {\r
+               printk("platform device add failed\n");\r
+\r
+               platform_device_put(rk29_snd_device);\r
+               return ret;\r
+       }\r
+               \r
+        return ret;\r
+}\r
+\r
+static void __exit audio_card_exit(void)\r
+{\r
+       platform_device_unregister(rk29_snd_device);\r
+}\r
+\r
+module_init(audio_card_init);\r
+module_exit(audio_card_exit);\r
+/* Module information */\r
+MODULE_AUTHOR("rockchip");\r
+MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");\r
+MODULE_LICENSE("GPL");\r
index 493ae7c4c0414deee8355a7e31134cd90b23ed4f..4610963ae48f6ce81a2604d5f08af314263cb193 100644 (file)
@@ -1031,6 +1031,21 @@ static struct snd_pcm_ops soc_pcm_ops = {
        .pointer        = soc_pcm_pointer,
 };
 
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+int snd_soc_incall_status(int read_or_write, int status)
+{
+       static int now_status = 0;
+       if(read_or_write == 1)
+       {//write
+               now_status = status;
+       }
+
+       return now_status;
+}
+EXPORT_SYMBOL_GPL(snd_soc_incall_status);
+#endif
+
+
 #ifdef CONFIG_PM_SLEEP
 /* powers down audio subsystem for suspend */
 int snd_soc_suspend(struct device *dev)
@@ -1038,7 +1053,14 @@ int snd_soc_suspend(struct device *dev)
        struct snd_soc_card *card = dev_get_drvdata(dev);
        struct snd_soc_codec *codec;
        int i;
-
+       
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+       if(snd_soc_incall_status(0,0))
+       {
+               printk("card is incall cannot into suspend\n");
+               return 0;
+       }
+#endif 
        /* If the initialization of this soc device failed, there is no codec
         * associated with it. Just bail out in this case.
         */
@@ -1188,6 +1210,7 @@ static void soc_resume_deferred(struct work_struct *work)
                 * left with bias OFF or STANDBY and suspended so we must now
                 * resume.  Otherwise the suspend was suppressed.
                 */
+
                if (codec->driver->resume && codec->suspended) {
                        switch (codec->dapm.bias_level) {
                        case SND_SOC_BIAS_STANDBY:
@@ -1258,7 +1281,14 @@ int snd_soc_resume(struct device *dev)
 {
        struct snd_soc_card *card = dev_get_drvdata(dev);
        int i, ac97_control = 0;
-
+       
+#ifdef CONFIG_PHONE_INCALL_IS_SUSPEND
+       if(snd_soc_incall_status(0,0))
+       {
+               printk("card is incall cannot into suspend\n");
+               return 0;
+       }
+#endif
        /* AC97 devices might have other drivers hanging off them so
         * need to resume immediately.  Other drivers don't have that
         * problem and may take a substantial amount of time to resume