Merge branch develop-3.10 into develop-3.10-next
authorHuang, Tao <huangtao@rock-chips.com>
Thu, 20 Nov 2014 11:55:43 +0000 (19:55 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 20 Nov 2014 11:55:43 +0000 (19:55 +0800)
102 files changed:
arch/arm/boot/dts/act8846.dtsi
arch/arm/boot/dts/rk3036-rk88.dts
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3126-86v.dts
arch/arm/boot/dts/rk3126-cif-sensor.dtsi
arch/arm/boot/dts/rk3126-sdk.dts
arch/arm/boot/dts/rk3128-sdk.dts
arch/arm/boot/dts/rk312x-clocks.dtsi
arch/arm/boot/dts/rk312x.dtsi
arch/arm/boot/dts/rk3288-clocks.dtsi
arch/arm/boot/dts/rk3288-tb.dts
arch/arm/boot/dts/rk3288-tb_8846.dts
arch/arm/boot/dts/rk3288.dtsi
arch/arm/configs/rk3036_defconfig
arch/arm/configs/rockchip_defconfig
arch/arm/mach-rockchip/cpu.c
arch/arm/mach-rockchip/dvfs.c
arch/arm/mach-rockchip/efuse.c
arch/arm/mach-rockchip/efuse.h
arch/arm/mach-rockchip/pm-rk3288.c
arch/arm/mach-rockchip/rk3036.c
arch/arm/mach-rockchip/rk312x.c
arch/arm/mach-rockchip/rk3288.c
arch/arm/mach-rockchip/rk_camera.c
arch/arm/mach-rockchip/rk_camera.h
arch/arm/mach-rockchip/rk_camera_sensor_info.h
arch/arm/mach-rockchip/vcodec_service.c
drivers/base/dma-buf.c
drivers/clk/rockchip/clk-pll.c
drivers/dma/pl330.c
drivers/i2c/busses/i2c-rockchip.c
drivers/iio/adc/rockchip_adc.c
drivers/input/remotectl/rockchip_pwm_remotectl.c
drivers/iommu/rockchip-iommu.c
drivers/iommu/rockchip-iommu.h
drivers/iommu/rockchip-iovmm.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/generic_sensor.h
drivers/media/video/rk30_camera_oneframe.c
drivers/media/video/rk30_camera_pingpong.c
drivers/media/video/rk_camsys/Kconfig
drivers/media/video/rk_camsys/Makefile
drivers/media/video/rk_camsys/camsys_drv.c
drivers/media/video/rk_camsys/camsys_gpio.h
drivers/media/video/rk_camsys/camsys_internal.h
drivers/media/video/rk_camsys/camsys_marvin.c
drivers/media/video/rk_camsys/ext_flashled_drv/Kconfig [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/Makefile [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.c [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.h [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.c [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.h [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.c [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.h [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.c [new file with mode: 0755]
drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.h [new file with mode: 0755]
drivers/mfd/rk808.c
drivers/mfd/rk818.c
drivers/mfd/rt5036-misc.c
drivers/mmc/host/rk_sdmmc.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c
drivers/net/wireless/rockchip_wlan/rtl8192cu/include/autoconf.h
drivers/net/wireless/rockchip_wlan/rtl8723au/include/autoconf.h
drivers/net/wireless/rockchip_wlan/rtl8723bu/include/autoconf.h
drivers/power/ricoh619-battery.c
drivers/power/rk30_factory_adc_battery.c
drivers/pwm/pwm-rockchip.c
drivers/staging/android/ion/ion.c
drivers/staging/android/trace/ion.h
drivers/usb/dwc_otg_310/dwc_otg_attr.c
drivers/usb/dwc_otg_310/dwc_otg_cil.c
drivers/usb/dwc_otg_310/dwc_otg_driver.c
drivers/usb/dwc_otg_310/usbdev_rk3126.c
drivers/usb/dwc_otg_310/usbdev_rk32.c
drivers/usb/host/Makefile
drivers/usb/host/ehci-hcd.c [changed mode: 0644->0755]
drivers/usb/host/ehci-rockchip.c
drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi.c
drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.c
drivers/video/rockchip/hdmi/chips/rk3036/rk3036_hdmi_hw.h
drivers/video/rockchip/hdmi/rk_hdmi_task.c
drivers/video/rockchip/lcdc/rk3036_lcdc.c
drivers/video/rockchip/lcdc/rk312x_lcdc.c
drivers/video/rockchip/rk_fb.c
drivers/video/rockchip/screen/lcd_mipi.c
drivers/video/rockchip/transmitter/rk32_mipi_dsi.c
drivers/video/rockchip/tve/rk3036/rk3036_tve.c [changed mode: 0644->0755]
include/linux/mmc/rk_mmc.h
include/linux/power/rockchip-adc-battery.h
include/linux/rk_fb.h
include/linux/rockchip/common.h
include/linux/rockchip/dvfs.h
include/media/camsys_head.h
include/sound/pcm_params.h [changed mode: 0644->0755]
mm/mmap.c
sound/soc/codecs/hdmi_i2s.c [changed mode: 0644->0755]
sound/soc/codecs/rk312x_codec.c
sound/soc/rockchip/rk_hdmi_i2s.c [changed mode: 0644->0755]
sound/soc/rockchip/rk_pcm.c
sound/soc/rockchip/rk_spdif.c
sound/usb/card.c

index 421a09a52e1418e6c0fef4c9f2827351a64d146d..c8ba4b5bdc585bb11f27dbc1ebad72aa01fabfe4 100644 (file)
@@ -82,6 +82,7 @@
                        reg = <10>;
                        regulator-compatible = "act_ldo7";
                        regulator-always-on;
+                       /* regulator-always-on; */
                        regulator-boot-on;
                };
 
@@ -93,4 +94,4 @@
                };
        };
                
-};
\ No newline at end of file
+};
index e28e56b25864f94c7168fd40d7806733e2b6c815..40fbeccc67a62fd499e690319856a19a1dcd6c29 100755 (executable)
@@ -1,6 +1,9 @@
 /dts-v1/;
-
+#include <dt-bindings/rkfb/rk_fb.h>
 #include "rk3036.dtsi"
+#include "rk3036-pinctrl.dtsi"
+#include "lcd-box.dtsi"
+#include <dt-bindings/input/input.h>
 
 / {
 
                pwms = <&pwm2 0 25000>;
                rockchip,pwm_id= <2>;
                rockchip,pwm_voltage_map= <950000 975000 1000000 1025000 1050000 1075000 1100000 1125000 1150000 1175000 1200000 1225000 1250000 1275000 1300000 1325000 1350000 1375000 1400000 1425000 1450000>;
-               rockchip,pwm_voltage= <1250000>;
+               rockchip,pwm_voltage= <1300000>;
                rockchip,pwm_min_voltage= <950000>;
                rockchip,pwm_max_voltage= <1450000>;
-               rockchip,pwm_suspend_voltage= <1250000>;
+               rockchip,pwm_suspend_voltage= <1000000>;
                rockchip,pwm_coefficient= <500>;
-               status = "disabled";
+               status = "okay";
                regulators {
                        #address-cells = <1>;
                        #size-cells = <0>;
                };
        };
 
+       gpio_poweroff {
+               compatible = "gpio-poweroff";
+               gpios = <&gpio1 GPIO_A2 GPIO_ACTIVE_LOW>;
+       };
+
        wireless-wlan {
                compatible = "wlan-platdata";
+
                /* wifi_chip_type - wifi chip define
-               * bcmwifi ==> like ap6xxx, rk90x, ...;
-               * rtkwifi ==> like rtl8188xx, rtl8723xx, ...;
+               * bcmwifi ==> like ap6xxx, rk90x;
+               * rtkwifi ==> like rtl8188xx, rtl8723xx,rtl8812auv;
                * esp8089 ==> esp8089;
                * other   ==> for other wifi;
                */
                wifi_chip_type = "esp8089";
-               sdio_vref = <1800>; //1800mv or 3300mv
+               sdio_vref = <0>; //1800mv or 3300mv
 
-               //keep_wifi_power_on;
                //power_ctrl_by_pmu;
+               //keep_wifi_power_on;
                //power_pmu_regulator = "act_ldo3";
                //power_pmu_enable_level = <1>; //1->HIGH, 0->LOW
 
                //vref_pmu_regulator = "act_ldo3";
                //vref_pmu_enable_level = <1>; //1->HIGH, 0->LOW
 
-               //WIFI,poweren_gpio = <&gpio4 GPIO_D4 GPIO_ACTIVE_HIGH>;
-               //WIFI,host_wake_irq = <&gpio4 GPIO_D6 GPIO_ACTIVE_HIGH>;
+               WIFI,poweren_gpio = <&gpio2 GPIO_D6 GPIO_ACTIVE_HIGH>;
+               WIFI,host_wake_irq = <&gpio2 GPIO_C4 GPIO_ACTIVE_HIGH>;
                //WIFI,reset_gpio = <&gpio0 GPIO_A2 GPIO_ACTIVE_LOW>;
 
                status = "okay";
     };
 
-/*    wireless-bluetooth {
+       /* wireless-bluetooth {
                compatible = "bluetooth-platdata";
                //wifi-bt-power-toggle;
 
 
        };*/
 
+       usb_control {
+               compatible = "rockchip,rk3036-usb-control";
+               host_drv_gpio = <&gpio2 GPIO_C7 GPIO_ACTIVE_LOW>;
+               otg_drv_gpio = <&gpio0 GPIO_D2 GPIO_ACTIVE_LOW>;
+
+               rockchip,remote_wakeup;
+               rockchip,usb_irq_wakeup;
+       };
+
+       usb0: usb@10180000 {
+       /*0 - Normal, 1 - Force Host, 2 - Force Device*/
+       rockchip,usb-mode = <1>;
+       };
+
+       key {
+               compatible = "rockchip,key";
+       };
+
+       codec_hdmi_spdif: codec-hdmi-spdif {
+               compatible = "hdmi-spdif";
+       };
+
+       rockchip-hdmi-spdif {
+               compatible = "rockchip-hdmi-spdif";
+               dais {
+                       dai0 {
+                               audio-codec = <&codec_hdmi_spdif>;
+                               i2s-controller = <&spdif>;
+                       };
+               };
+       };
+
+       rockchip-spdif-card {
+               compatible = "rockchip-spdif-card";
+               dais {
+                       dai0 {
+                               audio-codec = <&codec_hdmi_spdif>;
+                               i2s-controller = <&spdif>;
+                       };
+               };
+       };
+
+       rockchip-audio {
+               compatible = "rk3036-audio";
+               dais {
+                       dai0 {
+                               audio-codec = <&codec>;
+                               i2s-controller = <&i2s>;
+                               format = "i2s";
+                               //continuous-clock;
+                               //bitclock-inversion;
+                               //frame-inversion;
+                               //bitclock-master;
+                               //frame-master;
+                       };
+               };
+       };
+};
+
+&uart0{
+       status = "okay";
+       dma-names = "!tx", "!rx";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+};
 
 &nandc {
+       status = "okay"; // used nand set "okay" ,used emmc set "disabled"
+};
+
+&nandc0reg {
        status = "disabled"; // used nand set "disabled" ,used emmc set "okay"
-};  
+};
 
 &emmc {
-       clock-frequency = <100000000>;
-       clock-freq-min-max = <400000 100000000>;
+       clock-frequency = <37500000>;
+       clock-freq-min-max = <400000 37500000>;
 
         supports-highspeed;
        supports-emmc;
         bootpart-no-access;
 
        supports-DDR_MODE;
-       //caps2-mmc-hs200;
 
         ignore-pm-notify;
        keep-power-in-suspend;
-       
-       //poll-hw-reset 
-       status = "okay";
+
+       //poll-hw-reset
+       status = "disabled";
 };
-    
+
 &sdmmc {
-               clock-frequency = <50000000>;
-               clock-freq-min-max = <400000 50000000>;
+               clock-frequency = <37500000>;
+               clock-freq-min-max = <400000 37500000>;
                supports-highspeed;
                supports-sd;
                broken-cd;
                card-detect-delay = <200>;
 
                ignore-pm-notify;
-               keep-power-in-suspend;
-       
-               //vmmc-supply = <&rk808_ldo5_reg>;
+               keep-power-in-suspend;
+
+               //vmmc-supply = <&rk808_ldo5_reg>;
                status = "okay";
 };
-               
+
 &sdio {
-               clock-frequency = <50000000>;
-               clock-freq-min-max = <200000 50000000>;
+               clock-frequency = <37500000>;
+               clock-freq-min-max = <200000 37500000>;
                supports-highspeed;
                supports-sdio;
                ignore-pm-notify;
                keep-power-in-suspend;
-               //cap-sdio-irq;
+               cap-sdio-irq;
                status = "okay";
 };
 
-&uart0 {
+
+&i2c1 {
        status = "okay";
-       dma-names = "!tx", "!rx";
-       //pinctrl-0 = <&uart0_xfer &uart0_cts>;
+        rtc@51 {
+                compatible = "rtc,hym8563";
+                reg = <0x51>;
+                //irq_gpio = <&gpio0 GPIO_A4 IRQ_TYPE_EDGE_FALLING>;
+        };
 };
 
+
 &rk_screen {
         display-timings = <&disp_timings>;
 };
 
+&fb {
+       rockchip,disp-mode = <NO_DUAL>;
+       rockchip,uboot-logo-on = <1>;
+};
+
 &lcdc {
        status = "okay";
 };
 
 &tve {
-       status = "disabled";
+       status = "okay";
 };
 
 &hdmi {
        status = "okay";
        //rockchips,hdmi_audio_source = <0>;
 };
+
+&vmac {
+//     pmu_regulator = "act_ldo5";
+//     pmu_enable_level = <1>; //1->HIGH, 0->LOW
+//      power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>;
+        reset-gpio = <&gpio2 GPIO_C6 GPIO_ACTIVE_LOW>;
+};
+
+&dwc_control_usb {
+       usb_uart {
+               status = "disabled";
+       };
+};
+
+&pwm2 {
+        status = "okay";
+};
+
+&remotectl {
+       handle_cpu_id = <1>;
+       ir_key1{
+               rockchip,usercode = <0x4040>;
+               rockchip,key_table =
+                       <0xf2   KEY_REPLY>,
+                       <0xba   KEY_BACK>,
+                       <0xf4   KEY_UP>,
+                       <0xf1   KEY_DOWN>,
+                       <0xef   KEY_LEFT>,
+                       <0xee   KEY_RIGHT>,
+                       <0xbd   KEY_HOME>,
+                       <0xea   KEY_VOLUMEUP>,
+                       <0xe3   KEY_VOLUMEDOWN>,
+                       <0xe2   KEY_SEARCH>,
+                       <0xb2   KEY_POWER>,
+                       <0xbc   KEY_MUTE>,
+                       <0xec   KEY_MENU>,
+                       <0xbf   0x190>,
+                       <0xe0   0x191>,
+                       <0xe1   0x192>,
+                       <0xe9   183>,
+                       <0xe6   248>,
+                       <0xe8   185>,
+                       <0xe7   186>,
+                       <0xf0   388>,
+                       <0xbe   0x175>;
+       };
+       ir_key2{
+               rockchip,usercode = <0xff00>;
+               rockchip,key_table =
+                       <0xf9   KEY_HOME>,
+                       <0xbf   KEY_BACK>,
+                       <0xfb   KEY_MENU>,
+                       <0xaa   KEY_REPLY>,
+                       <0xb9   KEY_UP>,
+                       <0xe9   KEY_DOWN>,
+                       <0xb8   KEY_LEFT>,
+                       <0xea   KEY_RIGHT>,
+                       <0xeb   KEY_VOLUMEDOWN>,
+                       <0xef   KEY_VOLUMEUP>,
+                       <0xf7   KEY_MUTE>,
+                       <0xe7   KEY_POWER>,
+                       <0xfc   KEY_POWER>,
+                       <0xa9   KEY_VOLUMEDOWN>,
+                       <0xa8   KEY_VOLUMEDOWN>,
+                       <0xe0   KEY_VOLUMEDOWN>,
+                       <0xa5   KEY_VOLUMEDOWN>,
+                       <0xab   183>,
+                       <0xb7   388>,
+                       <0xf8   184>,
+                       <0xaf   185>,
+                       <0xed   KEY_VOLUMEDOWN>,
+                       <0xee   186>,
+                       <0xb3   KEY_VOLUMEDOWN>,
+                       <0xf1   KEY_VOLUMEDOWN>,
+                       <0xf2   KEY_VOLUMEDOWN>,
+                       <0xf3   KEY_SEARCH>,
+                       <0xb4   KEY_VOLUMEDOWN>,
+                       <0xbe   KEY_SEARCH>;
+       };
+       ir_key3{
+               rockchip,usercode = <0x1dcc>;
+               rockchip,key_table =
+                       <0xee   KEY_REPLY>,
+                       <0xf0   KEY_BACK>,
+                       <0xf8   KEY_UP>,
+                       <0xbb   KEY_DOWN>,
+                       <0xef   KEY_LEFT>,
+                       <0xed   KEY_RIGHT>,
+                       <0xfc   KEY_HOME>,
+                       <0xf1   KEY_VOLUMEUP>,
+                       <0xfd   KEY_VOLUMEDOWN>,
+                       <0xb7   KEY_SEARCH>,
+                       <0xff   KEY_POWER>,
+                       <0xf3   KEY_MUTE>,
+                       <0xbf   KEY_MENU>,
+                       <0xf9   0x191>,
+                       <0xf5   0x192>,
+                       <0xb3   388>,
+                       <0xbe   KEY_1>,
+                       <0xba   KEY_2>,
+                       <0xb2   KEY_3>,
+                       <0xbd   KEY_4>,
+                       <0xf9   KEY_5>,
+                       <0xb1   KEY_6>,
+                       <0xfc   KEY_7>,
+                       <0xf8   KEY_8>,
+                       <0xb0   KEY_9>,
+                       <0xb6   KEY_0>,
+                       <0xb5   KEY_BACKSPACE>;
+       };
+};
index 2747643fb9cc1ac9bb6ee30ab61a100ade699f5a..0f885bea42d279b30df617a404db8176f372d6c3 100755 (executable)
@@ -17,6 +17,7 @@
                i2c0 = &i2c0;
                i2c1 = &i2c1;
                i2c2 = &i2c2;
+               lcdc = &lcdc;
                spi0 = &spi0;
        };
 
index d42823efb1b0fa93842e40eb045dbca6c1e53592..4d4b47103ddb693f1898c97d4c32b67e9e75617d 100644 (file)
                                >;
                        temp-limit-enable = <1>;
                        target-temp = <85>;
+                       status = "okay";
                };
         };
 };
 
        };
        
-
-       adc-battery {
-               compatible = "rk30-adc-battery";
-                io-channels = <&adc 0>;
-               dc_det_gpio = <&gpio2 GPIO_B1 GPIO_ACTIVE_LOW>;
-               //bat_low_gpio = <&gpio0 GPIO_A7 GPIO_ACTIVE_LOW>;
-               //chg_ok_gpio = <&gpio0 GPIO_B1 GPIO_ACTIVE_HIGH>;
-               bat_table = <0 0 0 0 100 100
+        adc-battery {
+                compatible = "rk30-adc-battery";
+                io-channels = <&adc 0>, <&adc 3>;
+                dc_det_gpio = <&gpio2 GPIO_B1 GPIO_ACTIVE_LOW>;
+                auto_calibration = <0>;
+                ref_voltage = <3300>;
+                //bat_low_gpio = <&gpio0 GPIO_A7 GPIO_ACTIVE_LOW>;
+                //chg_ok_gpio = <&gpio0 GPIO_B1 GPIO_ACTIVE_HIGH>;
+                bat_table = <0 0 0 0 100 100
                  3500 3619 3678 3734 3742 3783 3813 3884 3968 4110 4220
                  3750 3710 3770 3830 3850 3880 3910 3980 4060 4240 4300
                 >;
-               is_dc_charge = <1>;
-               is_usb_charge = <0>;
-
-       }; 
+                is_dc_charge = <1>;
+                is_usb_charge = <0>;
 
+        };
        
 };
 
 &rk3126_cif_sensor{
        status = "okay";
 };
+
+&gmac {
+        status = "disabled";
+};
index 63857b6936c39bd803d7bef08dabcee8006017df..49651152be3603c7f5f6c41a43f824fe508be66d 100755 (executable)
@@ -48,7 +48,7 @@
                };
 
                
-                gc0309{
+                gc0329{
                        is_front = <0>;
                        //rockchip,power = <&gpio2 GPIO_B2 GPIO_ACTIVE_HIGH>;
                        //rockchip,power_pmu_name1 = "rk818_ldo4";
                        rockchip,powerdown = <&gpio3 GPIO_B3 GPIO_ACTIVE_HIGH>;
                        //rockchip,powerdown_pmu = "";
                        //rockchip,powerdown_pmu_voltage = <3000000>;
-                       pwdn_active = <gc0309_PWRDN_ACTIVE>;
+                       pwdn_active = <gc0329_PWRDN_ACTIVE>;
                        pwr_active = <PWR_ACTIVE_HIGH>;
                        mir = <0>;
-                       flash_attach = <0>;
-                       resolution = <gc0309_FULL_RESOLUTION>;
-                       powerup_sequence = <gc0309_PWRSEQ>;
+                       flash_attach = <1>;
+                       //rockchip,flash = <>;
+                       flash_active = <1>;
+                       resolution = <gc0329_FULL_RESOLUTION>;
+                       powerup_sequence = <gc0329_PWRSEQ>;
                        orientation = <0>;              
-                       i2c_add = <gc0309_I2C_ADDR>;
+                       i2c_add = <gc0329_I2C_ADDR>;
                        i2c_rata = <100000>;
                        i2c_chl = <1>;
                        cif_chl = <0>;
index 86b44c024d09bece0d8d2ee00e099c7cc1ba4434..81f6ca18d3af61c464724003e5266528c2cb7ddd 100755 (executable)
@@ -87,7 +87,7 @@
                };
 };
 &sdmmc {
-       cd-gpios = <&gpio2 GPIO_A3 GPIO_ACTIVE_HIGH>;/*CD GPIO*/
+       cd-gpios = <&gpio2 GPIO_A7 GPIO_ACTIVE_HIGH>;/*CD GPIO*/
 };
 
 &codec {
 &clk_core_dvfs_table {
        operating-points = <
                /* KHz    uV */
-               216000 975000
-               408000 975000
-               600000 1075000
-               696000 1100000
-               816000 1150000
-               1008000 1300000
-               1200000 1375000
+               216000 950000
+               408000 950000
+               600000 1050000
+               696000 1050000
+               816000 1125000
+               1008000 1275000
+               1200000 1400000
                >;
+       virt-temp-limit-1-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      1008000
+               85      1200000
+               95      1200000
+               100     1200000
+               >;
+       virt-temp-limit-2-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      912000
+               85      1008000
+               95      1104000
+               100     1200000
+               >;
+       virt-temp-limit-3-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      816000
+               85      912000
+               95      100800
+               100     110400
+               >;
+       virt-temp-limit-4-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      816000
+               85      912000
+               95      100800
+               100     110400
+               >;
+       temp-limit-enable = <1>;
+       target-temp = <85>;
        status="okay";
 };
 
                /* KHz    uV */
                200000 950000
                300000 950000
-               400000 1000000
+               400000 1025000
                533000 1225000
                >;
 
index 3bbb9b85f2c630d4a519ac0965cdfb2e15df7034..64dc3119fc463917c2bc4f0a8aa43cc62cd840a0 100755 (executable)
                1296000 1350000
                1320000 1375000
                >;
+       virt-temp-limit-1-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      1008000
+               85      1200000
+               95      1200000
+               100     1200000
+               >;
+       virt-temp-limit-2-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      912000
+               85      1008000
+               95      1104000
+               100     1200000
+               >;
+       virt-temp-limit-3-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      816000
+               85      912000
+               95      100800
+               100     110400
+               >;
+       virt-temp-limit-4-cpu-busy = <
+       /* target-temp  limit-freq */
+               75      816000
+               85      912000
+               95      100800
+               100     110400
+               >;
+       temp-limit-enable = <1>;
+       target-temp = <85>;
        status="okay";
 };
 
index 00f6af51ec8835b134d1cf33fafe95cddf6cdba9..1cdc3b63317f16cccd58d3aa5544af619320dc3b 100755 (executable)
                                                #clock-cells = <0>;
                                                rockchip,clkops-idx =
                                                        <CLKOPS_RATE_MUX_DIV>;
-                                               rockchip,flags = <CLK_SET_RATE_NO_REPARENT>;
                                        };
 
                                        clk_cif_out: clk_cif_out_mux {
index fb0a437537e6ec49bce3fafae6dbb5d2b9967243..795e112edb1611ec2745f5933954245e39fe2ca1 100755 (executable)
                                                0          3
                                        >;
                                        regu-mode-en = <0>;
+                                       lkg_adjust_volt_en = <1>;
+                                       channel = <0>;
+                                       def_table_lkg = <35>;
+                                       min_adjust_freq = <1200000>;
+                                       lkg_adjust_volt_table = <
+                                               /*lkg(mA)  volt(uV)*/
+                                               60         25000
+                                               >;
                                };
                        };
                };
index 4d7a7591f5ced8f21be682e6756308bd6ea3b692..9a1769372ac618162b4f7608f6bf7a7f2a32013c 100755 (executable)
                                        hclk_vio: hclk_vio_div {
                                                compatible = "rockchip,rk3188-div-con";
                                                rockchip,bits = <8 5>;
-                                               clocks = <&aclk_vio0>;
+                                               clocks = <&clk_gates15 11>;
                                                clock-output-names = "hclk_vio";
                                                rockchip,div-type = <CLK_DIVIDER_PLUS_ONE>;
                                                #clock-cells = <0>;
                                        reg = <0x019c 0x4>;
                                        clocks =
                                                <&aclk_rga>,            <&hclk_vio>,
-                                               <&aclk_vio0>,           <&hclk_vio>,
+                                               <&clk_gates15 11>,      <&hclk_vio>,
 
-                                               <&dummy>,               <&aclk_vio0>,
-                                               <&hclk_vio>,            <&aclk_vio1>,
+                                               <&dummy>,               <&clk_gates15 11>,
+                                               <&hclk_vio>,            <&clk_gates15 12>,
 
-                                               <&hclk_vio>,            <&hclk_vio>,
-                                               <&hclk_vio>,            <&aclk_vio0>,
+                                               <&hclk_vio>,            <&dummy>,
+                                               <&dummy>,               <&aclk_vio0>,
 
                                                <&aclk_vio1>,           <&aclk_rga>,
-                                               <&aclk_vio0>,           <&hclk_vio>;
+                                               <&clk_gates15 11>,      <&hclk_vio>;
 
                                        clock-output-names =
-                                               "reserved", /*"g_aclk_rga",*/   "g_hclk_rga",
+                                               "reserved", /*"g_aclk_rga"*/    "g_hclk_rga",
                                                "g_aclk_iep",           "g_hclk_iep",
 
                                                "g_aclk_lcdc_iep",              "g_aclk_lcdc0",
                                                "g_hclk_lcdc0",         "g_aclk_lcdc1",
 
-                                               "g_hclk_lcdc1",         "g_h_vio_ahb",
-                                               "g_hclk_vio_niu",               "g_aclk_vio0_niu",
+                                               "g_hclk_lcdc1",         "reserved", /* "g_h_vio_ahb" */
+                                               "reserved",/*"g_hclk_vio_niu"*/         "g_aclk_vio0_niu",
 
-                                               "g_aclk_vio1_niu",              "reserved",/*"g_aclk_rga_niu",*/
+                                               "g_aclk_vio1_niu",              "reserved",/*"g_aclk_rga_niu"*/
                                                "g_aclk_vip",           "g_hclk_vip";
                                                 rockchip,suspend-clkgating-setting=<0x0 0x0>;
 
                                        reg = <0x01a0 0x4>;
                                        clocks =
                                                <&pclkin_cif>,          <&hclk_vio>,
-                                               <&aclk_vio1>,           <&pclkin_isp>,
+                                               <&clk_gates15 12>,      <&pclkin_isp>,
 
                                                <&hclk_vio>,            <&hclk_vio>,
                                                <&hclk_vio>,            <&hclk_vio>,
 
                                                <&hclk_vio>,            <&hclk_vio>,
-                                               <&hclk_vio>,            <&hclk_vio>,
+                                               <&dummy>,               <&dummy>,
 
                                                <&dummy>,               <&dummy>,
                                                <&dummy>,               <&dummy>;
                                                "g_p_mipi_csi",         "g_pclk_lvds_phy",
 
                                                "g_pclk_edp_ctrl",              "g_p_hdmi_ctrl",
-                                               "g_hclk_vio2_h2p",              "g_pclk_vio2_h2p",
+                                               "reserved",             "reserved", /* bit10:"g_hclk_vio2_h2p" bit11: "g_pclk_vio2_h2p" */
 
                                                "reserved",             "reserved",
                                                "reserved",             "reserved";
index c7cd3c0b28d84d30e56f3aeb8e7236af5a2672fa..12c24d322a5ff693164ef74fbb300b4dbc06748a 100755 (executable)
        power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>;
 //     power-pmu = "act_ldo"
        reset-gpio = <&gpio4 GPIO_A7 GPIO_ACTIVE_LOW>;
+       status = "disabled";  //if want to use gmac, please set "okay"
 };
 
 &pinctrl {
index 6706a96a614769edc8ed566edae53418d93538d7..e2e2902205a6270515ae4352a5144461d3105ac2 100644 (file)
@@ -54,7 +54,7 @@
         BT,power_gpio = <&gpio4 GPIO_D3 GPIO_ACTIVE_HIGH>;
         BT,reset_gpio = <&gpio4 GPIO_D5 GPIO_ACTIVE_HIGH>;
         BT,wake_gpio = <&gpio4 GPIO_D2 GPIO_ACTIVE_HIGH>;
-        BT,wake_host_irq = <&gpio4 GPIO_D7 GPIO_ACTIVE_LOW>;
+        BT,wake_host_irq = <&gpio4 GPIO_D7 GPIO_ACTIVE_HIGH>;
 
         status = "okay";
     };
         clock_in_out = "input";
         tx_delay = <0x28>;
         rx_delay = <0x10>;
+       status = "disabled"; //if want to use gmac, please set "okay"
 };
 
 &pinctrl {
 };
 
 &spi0 {
-       status = "okay";
+       status = "disabled";
        max-freq = <48000000>;  
        /*
        spi_test@00 {
 };
 
 &spi1 {
-       status = "okay";
+       status = "disabled";
        max-freq = <48000000>;
        /*
        spi_test@10 {
 };
 
 &spi2 {
-       status = "okay";
+       status = "disabled";
        max-freq = <48000000>;
        /*
        spi_test@20 {
        rockchip,cabc_mode = <0>;
        power_ctr: power_ctr {
                rockchip,debug = <0>;
+               /*lcd_18:lcd18 {
+                       rockchip,power_type = <REGULATOR>;
+                       rockchip,regulator_name = "vcc_18";
+                       rockchip,regulator_voltage = <1800000>;
+                       rockchip,delay = <5>;
+               };*/
+
                lcd_en:lcd_en {
                        rockchip,power_type = <GPIO>;
                        gpios = <&gpio7 GPIO_A3 GPIO_ACTIVE_HIGH>;
        //      1704000 1350000
        //      1800000 1400000
                >;
+        support-pvtm = <1>;
+        pvtm-operating-points = <
+                /* KHz    uV    margin(uV)*/
+                126000 900000   25000
+                216000 900000   25000
+                312000 900000   25000
+                408000 900000   25000
+                600000 900000   25000
+                696000 950000   25000
+                816000 1000000  25000
+                1008000 1050000 25000
+                1200000 1100000 25000
+                1416000 1200000 25000
+                1512000 1300000 25000
+                1608000 1350000 25000
+                >;
        status="okay";
 };
 
index 2bc7971ea1489ce435629a5965fc8068a66b4fc1..a15825a4e90eac07f675d6c894ae299630318ba7 100755 (executable)
        clocks-enable {
                compatible = "rockchip,clocks-enable";
                clocks =
+                               /*PLL*/
+                               <&clk_dpll>, <&clk_gpll>,
+
                                /*PD_CORE*/
                                <&clk_gates0 2>, <&clk_core0>,
                                <&clk_core1>, <&clk_core2>,
                                /*PD_BUS*/
                                <&aclk_bus>, <&clk_gates0 3>,
                                <&hclk_bus>, <&pclk_bus>,
-                               <&clk_gates13 8>, <&clk_crypto>,
+                               <&clk_gates13 8>,
                                <&clk_gates0 7>,
 
                                /*TIMER*/
                                <&clk_gates10 12>,/*aclk_dma1*/
                                <&clk_gates10 13>,/*aclk_strc_sys*/
                                <&clk_gates10 4>,/*aclk_intmem*/
-                               <&clk_gates11 6>,/*aclk_crypto*/
-                               <&clk_gates11 8>,/*aclk_ccp*/
 
                                /*hclk_bus*/
-                               <&clk_gates11 7>,/*hclk_crypto*/
                                <&clk_gates10 9>,/*hclk_rom*/
 
                                /*pclk_bus*/
                                <&clk_gates17 2>,/*pclk_pmu_niu*/
                                <&clk_gates17 3>,/*pclk_sgrf*/
 
-                               /*hclk_vio*/
-                               <&clk_gates15 9>,/*hclk_vio_ahb_arbi*/
-                               <&clk_gates15 10>,/*hclk_vio_niu*/
-                               <&clk_gates16 10>,/*hclk_vio2_h2p*/
-                               <&clk_gates16 11>,/*pclk_vio2_h2p*/
-
-                               /*aclk_vio0*/
-                               <&clk_gates15 11>,/*aclk_vio0_niu*/
-
-                               /*aclk_vio1*/
-                               <&clk_gates15 12>,/*aclk_vio1_niu*/
-
-                               /*HDMI*/
-                               //<&clk_gates5 12>,/*hdmi_hdcp_clk*/
-
                                /*UART*/
                                <&clk_gates11 9>,/*pclk_uart2*/
 
                pinctrl-0 = <&i2c1_sda &i2c1_scl>;
                pinctrl-1 = <&i2c1_gpio>;
                gpios = <&gpio8 GPIO_A4 GPIO_ACTIVE_LOW>, <&gpio8 GPIO_A5 GPIO_ACTIVE_LOW>;
-               clocks = <&clk_gates10 3>;
+               clocks = <&clk_gates6 13>;
                rockchip,check-idle = <1>;
                status = "disabled";
        };
                pinctrl-0 = <&i2c2_sda &i2c2_scl>;
                pinctrl-1 = <&i2c2_gpio>;
                gpios = <&gpio6 GPIO_B1 GPIO_ACTIVE_LOW>, <&gpio6 GPIO_B2 GPIO_ACTIVE_LOW>;
-               clocks = <&clk_gates6 13>;
+               clocks = <&clk_gates10 3>;
                rockchip,check-idle = <1>;
                status = "disabled";
        };
                                                816000 1100000
                                                1008000 1100000
                                                >;
+                                       channel = <0>;
                                        temp-limit-enable = <1>;
                                        target-temp = <80>;
-                                       temp-channel = <1>;
                                        normal-temp-limit = <
                                        /*delta-temp    delta-freq*/
                                                3       96000
                                                300000 1200000
                                                400000 1200000
                                                >;
+                                       channel = <2>;
                                        status = "disabled";
                                };
                        };
                                                300000 1200000
                                                400000 1200000
                                                >;
+                                       channel = <1>;
                                        status = "okay";
                                        regu-mode-table = <
                                                /*freq     mode*/
index a53fcf8d8e70cc8375c6c35823a9e79c496a711a..c292299f04b3b0bf8829fb8ce4cc91f7f09923b5 100644 (file)
@@ -82,7 +82,6 @@ CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
 CONFIG_NETFILTER=y
 CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_SECMARK=y
 CONFIG_NF_CONNTRACK_EVENTS=y
 CONFIG_NF_CT_PROTO_DCCP=y
 CONFIG_NF_CT_PROTO_SCTP=y
@@ -99,12 +98,10 @@ CONFIG_NF_CT_NETLINK=y
 CONFIG_NETFILTER_TPROXY=y
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
 CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
 CONFIG_NETFILTER_XT_TARGET_LOG=y
 CONFIG_NETFILTER_XT_TARGET_MARK=y
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
-CONFIG_NETFILTER_XT_TARGET_SECMARK=y
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
 CONFIG_NETFILTER_XT_MATCH_COMMENT=y
 CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
@@ -231,7 +228,7 @@ CONFIG_MFD_RK808=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_ROCKCHIP_PWM_REGULATOR=y
-CONFIG_MALI400=y
+CONFIG_MALI400=m
 # CONFIG_MALI400_PROFILING is not set
 CONFIG_MALI_SHARED_INTERRUPTS=y
 CONFIG_FB=y
@@ -283,13 +280,8 @@ CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_ROCKCHIP=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_HYM8563=y
-CONFIG_RK808_RTC=y
 CONFIG_STAGING=y
 CONFIG_ZSMALLOC=y
 CONFIG_ZRAM=y
index 063a7620d933aac17cfbcb7a37092abf7d1e89b5..aff19327449532b1c4b9a0299090130172fbb552 100644 (file)
@@ -384,7 +384,13 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_RC_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_CAMSYS_DRV=y
+CONFIG_FLASHLIGHT=y
+CONFIG_LEDS_RT8547=y
+# CONFIG_RK30_CAMERA_ONEFRAME is not set
 CONFIG_MALI_MIDGARD=m
 CONFIG_MALI_MIDGARD_DVFS=y
 CONFIG_MALI_MIDGARD_RT_PM=y
index d9aaa12a07d1e2b76afb4bff11cf6cfb956668f2..a8b4c226a52de297a8b77127ee1eb4eb21217404 100644 (file)
@@ -28,6 +28,10 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr, char
        else
                type = "";
 
+       if (rockchip_get_cpu_version())
+               return sprintf(buf, "%sv%lu\n", type,
+                              rockchip_get_cpu_version());
+
        return sprintf(buf, "%s\n", type);
 }
 
index ea62aa4d6cd9dbc8df25525015d1a2d6905f30dc..0944f56230a68162efa3668cc7fbfa047b9173df 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/tick.h>
 #include <dt-bindings/clock/rk_system_status.h>
 #include "../../../drivers/clk/rockchip/clk-pd.h"
+#include "efuse.h"
 
 extern int rockchip_tsadc_get_temp(int chn);
 
@@ -858,6 +859,160 @@ static void dvfs_temp_limit_work_func(struct work_struct *work)
 }
 #endif
 
+static struct cpufreq_frequency_table rk3288v0_arm_pvtm_table[] = {
+       {.frequency = 216000,  .index = 4006},
+       {.frequency = 408000,  .index = 6518},
+       {.frequency = 600000,  .index = 8345},
+       {.frequency = 816000,  .index = 11026},
+       {.frequency = 1008000,  .index = 12906},
+       {.frequency = 1200000,  .index = 15532},
+       {.frequency = 1416000,  .index = 18076},
+       {.frequency = 1608000,  .index = 21282},
+       {.frequency = CPUFREQ_TABLE_END, .index = 1},
+};
+
+static struct pvtm_info rk3288v0_arm_pvtm_info = {
+       .compatible = "rockchip,rk3288",
+       .pvtm_table = rk3288v0_arm_pvtm_table,
+       .channel = ARM_DVFS_CH,
+       .process_version = RK3288_PROCESS_V0,
+       .scan_rate_hz = 216000000,
+       .sample_time_us = 1000,
+       .volt_step_uv = 12500,
+       .delta_pvtm_by_volt = 400,
+       .delta_pvtm_by_temp = 14,
+       .volt_margin_uv = 25000,
+       .min_volt_uv = 850000,
+       .max_volt_uv = 1400000,
+};
+
+static struct cpufreq_frequency_table rk3288v1_arm_pvtm_table[] = {
+       {.frequency = 216000,  .index = 4710},
+       {.frequency = 408000,  .index = 7200},
+       {.frequency = 600000,  .index = 9192},
+       {.frequency = 816000,  .index = 12560},
+       {.frequency = 1008000,  .index = 14741},
+       {.frequency = 1200000,  .index = 16886},
+       {.frequency = 1416000,  .index = 20081},
+       {.frequency = 1608000,  .index = 24061},
+       {.frequency = CPUFREQ_TABLE_END, .index = 1},
+};
+
+static struct pvtm_info rk3288v1_arm_pvtm_info = {
+       .compatible = "rockchip,rk3288",
+       .pvtm_table = rk3288v1_arm_pvtm_table,
+       .channel = ARM_DVFS_CH,
+       .process_version = RK3288_PROCESS_V1,
+       .scan_rate_hz = 216000000,
+       .sample_time_us = 1000,
+       .volt_step_uv = 12500,
+       .delta_pvtm_by_volt = 450,
+       .delta_pvtm_by_temp = 7,
+       .volt_margin_uv = 25000,
+       .min_volt_uv = 850000,
+       .max_volt_uv = 1400000,
+};
+
+static struct pvtm_info *pvtm_info_table[] = {
+       &rk3288v0_arm_pvtm_info,
+       &rk3288v1_arm_pvtm_info
+};
+
+static int pvtm_set_single_dvfs(struct dvfs_node *dvfs_node, u32 idx,
+                               struct pvtm_info *info, int *pvtm_list,
+                               u32 min_pvtm)
+{
+       struct cpufreq_frequency_table *dvfs_table = dvfs_node->dvfs_table;
+       struct cpufreq_frequency_table *pvtm_table = dvfs_node->pvtm_table;
+       int target_pvtm, pvtm_margin, volt_margin;
+       unsigned int n_voltages = dvfs_node->vd->n_voltages;
+       int *volt_list = dvfs_node->vd->volt_list;
+       int n, temp;
+
+       volt_margin = info->volt_margin_uv + pvtm_table[idx].index;
+       n = volt_margin/info->volt_step_uv;
+       if (volt_margin%info->volt_step_uv)
+               n++;
+
+       pvtm_margin = n*info->delta_pvtm_by_volt;
+       temp = rockchip_tsadc_get_temp(1);
+       target_pvtm = min_pvtm+temp * info->delta_pvtm_by_temp + pvtm_margin;
+
+       DVFS_DBG("=====%s: temp:%d, freq:%d, target pvtm:%d=====\n",
+                __func__, temp, dvfs_table[idx].frequency, target_pvtm);
+
+       for (n = 0; n < n_voltages; n++) {
+               if (pvtm_list[n] >= target_pvtm) {
+                       dvfs_table[idx].index = volt_list[n];
+                       DVFS_DBG("freq[%d]=%d, volt=%d\n",
+                                idx, dvfs_table[idx].frequency, volt_list[n]);
+
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+
+       return 0;
+}
+
+static void pvtm_set_dvfs_table(struct dvfs_node *dvfs_node)
+{
+       struct cpufreq_frequency_table *dvfs_table = dvfs_node->dvfs_table;
+       struct pvtm_info *info = dvfs_node->pvtm_info;
+       struct regulator *regulator = dvfs_node->vd->regulator;
+       int i, j;
+       int ret = 0;
+       int pvtm_list[VD_VOL_LIST_CNT] = {0};
+       unsigned int n_voltages = dvfs_node->vd->n_voltages;
+       int *volt_list = dvfs_node->vd->volt_list;
+
+       if (!info)
+               return;
+
+       clk_set_rate(dvfs_node->clk, info->scan_rate_hz);
+       DVFS_DBG("%s:%lu\n", __func__, clk_get_rate(dvfs_node->clk));
+
+       for (i = 0; i < n_voltages; i++) {
+               if ((volt_list[i] >= info->min_volt_uv) &&
+                   (volt_list[i] <= info->max_volt_uv)) {
+                       regulator_set_voltage(regulator, volt_list[i],
+                                             volt_list[i]);
+                       pvtm_list[i] = pvtm_get_value(info->channel,
+                                                     info->sample_time_us);
+               }
+       }
+
+       for (i = 0; dvfs_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               for (j = 0; info->pvtm_table[j].frequency !=
+                    CPUFREQ_TABLE_END; j++)
+                       if (info->pvtm_table[j].frequency >=
+                           dvfs_table[i].frequency) {
+                               int min_pvtm = info->pvtm_table[j].index;
+
+                               ret = pvtm_set_single_dvfs(dvfs_node,
+                                                          i,
+                                                          info,
+                                                          pvtm_list,
+                                                          min_pvtm);
+                               break;
+                       }
+
+               if (ret) {
+                       DVFS_WARNING("freq: %d can not reach target pvtm\n",
+                                    dvfs_table[i].frequency);
+                       break;
+               }
+
+               if (info->pvtm_table[j].frequency == CPUFREQ_TABLE_END) {
+                       DVFS_WARNING("not support freq :%d, max freq is %d\n",
+                                    dvfs_table[i].frequency,
+                                    info->pvtm_table[j-1].frequency);
+                       break;
+               }
+       }
+}
+
 static void dvfs_virt_temp_limit_work_func(void)
 {
        const struct cpufreq_frequency_table *limits_table = NULL;
@@ -995,7 +1150,6 @@ static void dvfs_temp_limit_work_func(struct work_struct *work)
 }
 static DECLARE_DELAYED_WORK(dvfs_temp_limit_work, dvfs_temp_limit_work_func);
 
-
 int dvfs_clk_enable_limit(struct dvfs_node *clk_dvfs_node, unsigned int min_rate, unsigned int max_rate)
 {
        u32 rate = 0, ret = 0;
@@ -1137,6 +1291,68 @@ int dvfs_set_freq_volt_table(struct dvfs_node *clk_dvfs_node, struct cpufreq_fre
 }
 EXPORT_SYMBOL(dvfs_set_freq_volt_table);
 
+static int get_adjust_volt_by_leakage(struct dvfs_node *dvfs_node)
+{
+       int leakage = 0;
+       int delta_leakage = 0;
+       int i = 0;
+       int adjust_volt = 0;
+
+       if (!dvfs_node->vd)
+               return 0;
+
+       if (dvfs_node->lkg_info.def_table_lkg == -1)
+               return 0;
+
+       leakage = rockchip_get_leakage(dvfs_node->channel);
+       if (!leakage || (leakage == 0xff))
+               return 0;
+
+       delta_leakage = leakage - dvfs_node->lkg_info.def_table_lkg;
+       if (delta_leakage <= 0) {
+               for (i = 0; (dvfs_node->lkg_info.table[i].dlt_volt !=
+                       CPUFREQ_TABLE_END); i++) {
+                       if (leakage > dvfs_node->lkg_info.table[i].lkg) {
+                               adjust_volt =
+                                       dvfs_node->lkg_info.table[i].dlt_volt;
+                       } else {
+                               return adjust_volt;
+                       }
+               }
+       } else if (delta_leakage > 0) {
+               for (i = 0; (dvfs_node->lkg_info.table[i].dlt_volt !=
+                       CPUFREQ_TABLE_END); i++) {
+                       if (leakage <= dvfs_node->lkg_info.table[i].lkg) {
+                               adjust_volt =
+                                       -dvfs_node->lkg_info.table[i].dlt_volt;
+                               return adjust_volt;
+                       }
+               }
+       }
+       return adjust_volt;
+}
+
+static void adjust_table_by_leakage(struct dvfs_node *dvfs_node)
+{
+       int i, adjust_volt = get_adjust_volt_by_leakage(dvfs_node);
+
+       if (!adjust_volt)
+               return;
+
+       if (!dvfs_node->dvfs_table)
+               return;
+
+       if (dvfs_node->lkg_info.min_adjust_freq == -1)
+               return;
+
+       for (i = 0;
+       (dvfs_node->dvfs_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+               if (dvfs_node->dvfs_table[i].frequency >=
+                       dvfs_node->lkg_info.min_adjust_freq)
+                       dvfs_node->dvfs_table[i].index += adjust_volt;
+       }
+}
+
 int clk_enable_dvfs(struct dvfs_node *clk_dvfs_node)
 {
        struct cpufreq_frequency_table clk_fv;
@@ -1144,7 +1360,6 @@ int clk_enable_dvfs(struct dvfs_node *clk_dvfs_node)
        unsigned int mode;
        int ret;
 
-
        if (!clk_dvfs_node)
                return -EINVAL;
        
@@ -1184,6 +1399,10 @@ int clk_enable_dvfs(struct dvfs_node *clk_dvfs_node)
                dvfs_table_round_clk_rate(clk_dvfs_node);
                dvfs_get_rate_range(clk_dvfs_node);
                clk_dvfs_node->freq_limit_en = 1;
+               if (clk_dvfs_node->lkg_adjust_volt_en)
+                       adjust_table_by_leakage(clk_dvfs_node);
+               if (clk_dvfs_node->support_pvtm)
+                       pvtm_set_dvfs_table(clk_dvfs_node);
                dvfs_table_round_volt(clk_dvfs_node);
                clk_dvfs_node->set_freq = clk_dvfs_node_get_rate_kz(clk_dvfs_node->clk);
                clk_dvfs_node->last_set_rate = clk_dvfs_node->set_freq*1000;
@@ -1587,25 +1806,6 @@ int rk_regist_clk(struct dvfs_node *clk_dvfs_node)
 }
 EXPORT_SYMBOL_GPL(rk_regist_clk);
 
-static int rk_convert_cpufreq_table(struct dvfs_node *dvfs_node)
-{
-       struct opp *opp;
-       struct device *dev;
-       struct cpufreq_frequency_table *table;
-       int i;
-
-       table = dvfs_node->dvfs_table;
-       dev = &dvfs_node->dev;
-
-       for (i = 0; table[i].frequency!= CPUFREQ_TABLE_END; i++){
-               opp = opp_find_freq_exact(dev, table[i].frequency * 1000, true);
-               if (IS_ERR(opp))
-                       return PTR_ERR(opp);
-               table[i].index = opp_get_voltage(opp);
-       }
-       return 0;
-}
-
 static struct cpufreq_frequency_table *of_get_temp_limit_table(struct device_node *dev_node, const char *propname)
 {
        struct cpufreq_frequency_table *temp_limt_table = NULL;
@@ -1642,6 +1842,222 @@ static struct cpufreq_frequency_table *of_get_temp_limit_table(struct device_nod
 
 }
 
+static int of_get_dvfs_table(struct device_node *dev_node,
+                            struct cpufreq_frequency_table **dvfs_table)
+{
+       struct cpufreq_frequency_table *tmp_dvfs_table = NULL;
+       const struct property *prop;
+       const __be32 *val;
+       int nr, i;
+
+       prop = of_find_property(dev_node, "operating-points", NULL);
+       if (!prop)
+               return -EINVAL;
+       if (!prop->value)
+               return -EINVAL;
+
+       nr = prop->length / sizeof(u32);
+       if (nr % 2) {
+               pr_err("%s: Invalid freq list\n", __func__);
+               return -EINVAL;
+       }
+
+       tmp_dvfs_table = kzalloc(sizeof(*tmp_dvfs_table) *
+                            (nr/2 + 1), GFP_KERNEL);
+       val = prop->value;
+
+       for (i = 0; i < nr/2; i++) {
+               tmp_dvfs_table[i].frequency = be32_to_cpup(val++);
+               tmp_dvfs_table[i].index = be32_to_cpup(val++);
+       }
+
+       tmp_dvfs_table[i].index = 0;
+       tmp_dvfs_table[i].frequency = CPUFREQ_TABLE_END;
+
+       *dvfs_table = tmp_dvfs_table;
+
+       return 0;
+}
+
+
+static int of_get_dvfs_pvtm_table(struct device_node *dev_node,
+                                 struct cpufreq_frequency_table **dvfs_table,
+                                 struct cpufreq_frequency_table **pvtm_table)
+{
+       struct cpufreq_frequency_table *tmp_dvfs_table = NULL;
+       struct cpufreq_frequency_table *tmp_pvtm_table = NULL;
+       const struct property *prop;
+       const __be32 *val;
+       int nr, i;
+
+       prop = of_find_property(dev_node, "pvtm-operating-points", NULL);
+       if (!prop)
+               return -EINVAL;
+       if (!prop->value)
+               return -EINVAL;
+
+       nr = prop->length / sizeof(u32);
+       if (nr % 3) {
+               pr_err("%s: Invalid freq list\n", __func__);
+               return -EINVAL;
+       }
+
+       tmp_dvfs_table = kzalloc(sizeof(*tmp_dvfs_table) *
+                            (nr/3 + 1), GFP_KERNEL);
+
+       tmp_pvtm_table = kzalloc(sizeof(*tmp_pvtm_table) *
+                            (nr/3 + 1), GFP_KERNEL);
+
+       val = prop->value;
+
+       for (i = 0; i < nr/3; i++) {
+               tmp_dvfs_table[i].frequency = be32_to_cpup(val++);
+               tmp_dvfs_table[i].index = be32_to_cpup(val++);
+
+               tmp_pvtm_table[i].frequency = tmp_dvfs_table[i].frequency;
+               tmp_pvtm_table[i].index = be32_to_cpup(val++);
+       }
+
+       tmp_dvfs_table[i].index = 0;
+       tmp_dvfs_table[i].frequency = CPUFREQ_TABLE_END;
+
+       tmp_pvtm_table[i].index = 0;
+       tmp_pvtm_table[i].frequency = CPUFREQ_TABLE_END;
+
+       *dvfs_table = tmp_dvfs_table;
+       *pvtm_table = tmp_pvtm_table;
+
+       return 0;
+}
+
+static struct lkg_adjust_volt_table
+       *of_get_lkg_adjust_volt_table(struct device_node *np,
+       const char *propname)
+{
+       struct lkg_adjust_volt_table *lkg_adjust_volt_table = NULL;
+       const struct property *prop;
+       const __be32 *val;
+       int nr, i;
+
+       prop = of_find_property(np, propname, NULL);
+       if (!prop)
+               return NULL;
+       if (!prop->value)
+               return NULL;
+
+       nr = prop->length / sizeof(s32);
+       if (nr % 2) {
+               pr_err("%s: Invalid freq list\n", __func__);
+               return NULL;
+       }
+
+       lkg_adjust_volt_table =
+               kzalloc(sizeof(struct lkg_adjust_volt_table) *
+               (nr/2 + 1), GFP_KERNEL);
+
+       val = prop->value;
+
+       for (i = 0; i < nr/2; i++) {
+               lkg_adjust_volt_table[i].lkg = be32_to_cpup(val++);
+               lkg_adjust_volt_table[i].dlt_volt = be32_to_cpup(val++);
+       }
+
+       lkg_adjust_volt_table[i].lkg = 0;
+       lkg_adjust_volt_table[i].dlt_volt = CPUFREQ_TABLE_END;
+
+       return lkg_adjust_volt_table;
+}
+
+static int dvfs_node_parse_dt(struct device_node *np,
+                             struct dvfs_node *dvfs_node)
+{
+       int process_version = rockchip_process_version();
+       int i = 0;
+       int ret;
+
+       of_property_read_u32_index(np, "channel", 0, &dvfs_node->channel);
+
+       pr_info("channel:%d, lkg:%d\n",
+               dvfs_node->channel, rockchip_get_leakage(dvfs_node->channel));
+
+       of_property_read_u32_index(np, "regu-mode-en", 0,
+                                  &dvfs_node->regu_mode_en);
+       if (dvfs_node->regu_mode_en)
+               dvfs_node->regu_mode_table = of_get_regu_mode_table(np);
+       else
+               dvfs_node->regu_mode_table = NULL;
+
+       of_property_read_u32_index(np, "temp-limit-enable", 0,
+                                  &temp_limit_enable);
+       if (temp_limit_enable) {
+               of_property_read_u32_index(np, "target-temp", 0, &target_temp);
+               pr_info("target-temp:%d\n", target_temp);
+               dvfs_node->nor_temp_limit_table =
+                       of_get_temp_limit_table(np,
+                                               "normal-temp-limit");
+               dvfs_node->per_temp_limit_table =
+                       of_get_temp_limit_table(np,
+                                               "performance-temp-limit");
+               dvfs_node->virt_temp_limit_table[0] =
+                       of_get_temp_limit_table(np,
+                                               "virt-temp-limit-1-cpu-busy");
+               dvfs_node->virt_temp_limit_table[1] =
+                       of_get_temp_limit_table(np,
+                                               "virt-temp-limit-2-cpu-busy");
+               dvfs_node->virt_temp_limit_table[2] =
+                       of_get_temp_limit_table(np,
+                                               "virt-temp-limit-3-cpu-busy");
+               dvfs_node->virt_temp_limit_table[3] =
+                       of_get_temp_limit_table(np,
+                                               "virt-temp-limit-4-cpu-busy");
+       }
+       dvfs_node->temp_limit_rate = -1;
+
+       ret = of_property_read_u32_index(np, "support-pvtm", 0,
+                                        &dvfs_node->support_pvtm);
+       if (!ret) {
+               if (of_get_dvfs_pvtm_table(np, &dvfs_node->dvfs_table,
+                                          &dvfs_node->pvtm_table))
+                       return -EINVAL;
+
+               for (i = 0; i < ARRAY_SIZE(pvtm_info_table); i++) {
+                       struct pvtm_info *pvtm_info = pvtm_info_table[i];
+
+                       if ((pvtm_info->channel == dvfs_node->channel) &&
+                           (pvtm_info->process_version == process_version) &&
+                            of_machine_is_compatible(pvtm_info->compatible)) {
+                               dvfs_node->pvtm_info = pvtm_info;
+                               break;
+                       }
+               }
+
+               if (!dvfs_node->pvtm_info)
+                       dvfs_node->support_pvtm = 0;
+       } else {
+               if (of_get_dvfs_table(np, &dvfs_node->dvfs_table))
+                       return -EINVAL;
+       }
+
+       of_property_read_u32_index(np, "lkg_adjust_volt_en", 0,
+                                  &dvfs_node->lkg_adjust_volt_en);
+       if (dvfs_node->lkg_adjust_volt_en) {
+               dvfs_node->lkg_info.def_table_lkg = -1;
+               of_property_read_u32_index(np, "def_table_lkg", 0,
+                                          &dvfs_node->lkg_info.def_table_lkg);
+
+               dvfs_node->lkg_info.min_adjust_freq = -1;
+               of_property_read_u32_index(np, "min_adjust_freq", 0,
+                                          &dvfs_node->lkg_info.min_adjust_freq
+                                          );
+
+               dvfs_node->lkg_info.table =
+                       of_get_lkg_adjust_volt_table(np,
+                                                    "lkg_adjust_volt_table");
+       }
+
+       return 0;
+}
+
 int of_dvfs_init(void)
 {
        struct vd_node *vd;
@@ -1649,10 +2065,10 @@ int of_dvfs_init(void)
        struct device_node *dvfs_dev_node, *clk_dev_node, *vd_dev_node, *pd_dev_node;
        struct dvfs_node *dvfs_node;
        struct clk *clk;
-       const __be32 *val;
        int ret;
 
        DVFS_DBG("%s\n", __func__);
+       pr_info("process version: %d\n", rockchip_process_version());
 
        dvfs_dev_node = of_find_node_by_name(NULL, "dvfs");
        if (IS_ERR_OR_NULL(dvfs_dev_node)) {
@@ -1717,56 +2133,8 @@ int of_dvfs_init(void)
                                dvfs_node->pd = pd;
                                dvfs_node->vd = vd;
 
-                               val = of_get_property(clk_dev_node, "regu-mode-en", NULL);
-                               if (val)
-                                       dvfs_node->regu_mode_en = be32_to_cpup(val);
-                               if (dvfs_node->regu_mode_en)
-                                       dvfs_node->regu_mode_table = of_get_regu_mode_table(clk_dev_node);
-                               else
-                                       dvfs_node->regu_mode_table = NULL;
-
-                               val = of_get_property(clk_dev_node, "temp-limit-enable", NULL);
-                               if (val)
-                                       temp_limit_enable = be32_to_cpup(val);
-                               if (temp_limit_enable) {
-                                       val = of_get_property(clk_dev_node, "target-temp", NULL);
-                                       if (val)
-                                               target_temp = be32_to_cpup(val);
-                                       val = of_get_property(clk_dev_node, "temp-channel", NULL);
-                                       if (val)
-                                               dvfs_node->temp_channel = be32_to_cpup(val);
-
-                                       dvfs_node->nor_temp_limit_table = of_get_temp_limit_table(clk_dev_node, "normal-temp-limit");
-                                       dvfs_node->per_temp_limit_table = of_get_temp_limit_table(clk_dev_node, "performance-temp-limit");
-                                       dvfs_node->virt_temp_limit_table[0] =
-                                               of_get_temp_limit_table(clk_dev_node, "virt-temp-limit-1-cpu-busy");
-                                       dvfs_node->virt_temp_limit_table[1] =
-                                               of_get_temp_limit_table(clk_dev_node, "virt-temp-limit-2-cpu-busy");
-                                       dvfs_node->virt_temp_limit_table[2] =
-                                               of_get_temp_limit_table(clk_dev_node, "virt-temp-limit-3-cpu-busy");
-                                       dvfs_node->virt_temp_limit_table[3] =
-                                               of_get_temp_limit_table(clk_dev_node, "virt-temp-limit-4-cpu-busy");
-                               }
-                               dvfs_node->temp_limit_rate = -1;
-                               dvfs_node->dev.of_node = clk_dev_node;
-                               ret = of_init_opp_table(&dvfs_node->dev);
-                               if (ret) {
-                                       DVFS_ERR("%s:clk(%s) get opp table err:%d\n", __func__, dvfs_node->name, ret);
-                                       kfree(dvfs_node);
-                                       continue;
-                               }
-                               
-                               ret = opp_init_cpufreq_table(&dvfs_node->dev, &dvfs_node->dvfs_table);
-                               if (ret) {
-                                       DVFS_ERR("%s:clk(%s) get cpufreq table err:%d\n", __func__, dvfs_node->name, ret);
-                                       kfree(dvfs_node);
-                                       continue;
-                               }
-                               ret = rk_convert_cpufreq_table(dvfs_node);
-                               if (ret) {
-                                       kfree(dvfs_node);
+                               if (dvfs_node_parse_dt(clk_dev_node, dvfs_node))
                                        continue;
-                               }
                                
                                clk = clk_get(NULL, clk_dev_node->name);
                                if (IS_ERR(clk)){
index d988b313cd1e6ae1f7fb3a0e532ba5f657cc4329..235e124e9be656e464e7cf471ea15f2787bb3281 100644 (file)
@@ -21,6 +21,7 @@ static u8 efuse_buf[32] = {};
 struct rockchip_efuse {
        int (*get_leakage)(int ch);
        int efuse_version;
+       int process_version;
 };
 
 static struct rockchip_efuse efuse;
@@ -67,6 +68,13 @@ static int __init rk3288_get_efuse_version(void)
        return ret;
 }
 
+static int __init rk3288_get_process_version(void)
+{
+       int ret = efuse_buf[6]&0x0f;
+
+       return ret;
+}
+
 static int rk3288_get_leakage(int ch)
 {
        if ((ch < 0) || (ch > 2))
@@ -89,11 +97,51 @@ static void __init rk3288_set_system_serial(void)
        system_serial_high = crc32(system_serial_low, buf + 8, 8);
 }
 
+int rk312x_efuse_readregs(u32 addr, u32 length, u8 *buf)
+{
+       int ret = length;
+
+       if (!length)
+               return 0;
+
+       efuse_writel(EFUSE_LOAD, REG_EFUSE_CTRL);
+       udelay(2);
+       do {
+               efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
+                               (~(EFUSE_A_MASK << RK312X_EFUSE_A_SHIFT)),
+                               REG_EFUSE_CTRL);
+               efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
+                               ((addr & EFUSE_A_MASK) << RK312X_EFUSE_A_SHIFT),
+                               REG_EFUSE_CTRL);
+               udelay(2);
+               efuse_writel(efuse_readl(REG_EFUSE_CTRL) |
+                               EFUSE_STROBE, REG_EFUSE_CTRL);
+               udelay(2);
+               *buf = efuse_readl(REG_EFUSE_DOUT);
+               efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
+                               (~EFUSE_STROBE), REG_EFUSE_CTRL);
+               udelay(2);
+               buf++;
+               addr++;
+       } while (--length);
+       udelay(2);
+       efuse_writel(efuse_readl(REG_EFUSE_CTRL) &
+                       (~EFUSE_LOAD) , REG_EFUSE_CTRL);
+       udelay(1);
+
+       return ret;
+}
+
 int rockchip_efuse_version(void)
 {
        return efuse.efuse_version;
 }
 
+int rockchip_process_version(void)
+{
+       return efuse.process_version;
+}
+
 int rockchip_get_leakage(int ch)
 {
        if (efuse.get_leakage)
@@ -110,10 +158,17 @@ void __init rockchip_efuse_init(void)
                if (ret == 32) {
                        efuse.get_leakage = rk3288_get_leakage;
                        efuse.efuse_version = rk3288_get_efuse_version();
+                       efuse.process_version = rk3288_get_process_version();
                        rockchip_set_cpu_version((efuse_buf[6] >> 4) & 3);
                        rk3288_set_system_serial();
                } else {
                        pr_err("failed to read eFuse, return %d\n", ret);
                }
+       } else if (cpu_is_rk312x()) {
+               ret = rk312x_efuse_readregs(0, 32, efuse_buf);
+               if (ret == 32)
+                       efuse.get_leakage = rk3288_get_leakage;
+               else
+                       pr_err("failed to read eFuse, return %d\n", ret);
        }
 }
index 77b26fb0cc5b9b29c3c8afc713be01df5bc1b11d..0d04994b9b695c8905bbf989043bc50e73335a15 100644 (file)
@@ -5,6 +5,7 @@
 
 /* eFuse controller register */
 #define EFUSE_A_SHIFT          (6)
+#define RK312X_EFUSE_A_SHIFT   (7)
 #define EFUSE_A_MASK           (0x3FF)
 //#define EFUSE_PD             (1 << 5)
 //#define EFUSE_PS             (1 << 4)
 #define GPU_LEAKAGE_CH 1
 #define LOG_LEAKAGE_CH 2
 
+#define RK3288_PROCESS_V0      0
+#define RK3288_PROCESS_V1      1
+
 int rockchip_efuse_version(void);
+int rockchip_process_version(void);
 int rockchip_get_leakage(int ch);
 #endif
index 850cf0edf6842c4b0a1c260d258d71f59126b40e..d2f98c5857f8cd54c887bd30e972167743d4178a 100755 (executable)
@@ -32,7 +32,6 @@ __weak void rk_usb_power_up(void);
 //static void ddr_gpio_set_in_output(u8 port,u8 bank,u8 b_gpio,u8 type);
 static void ddr_pin_set_fun(u8 port,u8 bank,u8 b_gpio,u8 fun);
 
-
 /*************************cru define********************************************/
 
 
@@ -60,7 +59,6 @@ enum rk_plls_id {
 #define RK3288_PLL_BYPASS CRU_W_MSK_SETBITS(1,0,0x1)
 #define RK3288_PLL_NO_BYPASS CRU_W_MSK_SETBITS(0,0,0x1)
 
-
 /*******************************gpio define **********************************************/
 
 /* GPIO control registers */
@@ -932,7 +930,6 @@ static u32 sgrf_soc_con0,pmu_wakeup_cfg0,pmu_wakeup_cfg1,pmu_pwr_mode_con0,pmu_p
 static u32  rkpm_slp_mode_set(u32 ctrbits)
 {
     u32 mode_set,mode_set1;
-    
     // setting gpio0_a0 arm off pin
 
     sgrf_soc_con0=reg_readl(RK_SGRF_VIRT+RK3288_SGRF_SOC_CON0);
@@ -970,8 +967,11 @@ static u32  rkpm_slp_mode_set(u32 ctrbits)
     }
     else if(rkpm_chk_val_ctrbits(ctrbits,RKPM_CTR_ARMDP_LPMD))
     {
-        rkpm_ddr_printascii("-armdp-");            
-        mode_set|=BIT(pmu_a12_0_pd_en);
+       rkpm_ddr_printascii("-armdp-");
+       mode_set |= BIT(pmu_a12_0_pd_en)
+                       | BIT(pmu_sref0_enter_en) | BIT(pmu_sref1_enter_en)
+                       | BIT(pmu_ddr0_gating_en) | BIT(pmu_ddr1_gating_en)
+                       | BIT(pmu_chip_pd_en);
     }
     else if(rkpm_chk_val_ctrbits(ctrbits,RKPM_CTR_ARMOFF_LPMD))
     {   
@@ -1022,13 +1022,17 @@ static u32  rkpm_slp_mode_set(u32 ctrbits)
         rkpm_ddr_printascii("osc_off");        
         pmu_writel(32*30,RK3288_PMU_OSC_CNT);  
         pmu_writel(32*30,RK3288_PMU_STABL_CNT);  
-    }
-    else
-    {
-        pmu_writel(24*1000*10,RK3288_PMU_STABL_CNT);  
-        
-       // pmu_writel(24*1000*20,RK3288_PMU_CORE_PWRDWN_CNT);  
-    }
+    } else if (mode_set & BIT(pmu_a12_0_pd_en)) {
+       pmu_writel(0x0, RK3288_PMU_STABL_CNT);
+       pmu_writel(0x0, RK3288_PMU_OSC_CNT);
+       pmu_writel(0x0, RK3288_PMU_PLL_CNT);
+       pmu_writel(0x0, RK3288_PMU_DDR0IO_PWRON_CNT);
+       pmu_writel(0x0, RK3288_PMU_DDR1IO_PWRON_CNT);
+       pmu_writel(0x0, RK3288_PMU_GPU_PWRUP_CNT);
+       pmu_writel(0x0, RK3288_PMU_WAKEUP_RST_CLR_CNT);
+       /*pmu_writel(100,RK3288_PMU_CORE_PWRUP_CNT);*/
+       } else
+       pmu_writel(24*1000*10, RK3288_PMU_STABL_CNT);
 
     if(mode_set&BIT(pmu_ddr0io_ret_en))
     {
@@ -1043,7 +1047,7 @@ static u32  rkpm_slp_mode_set(u32 ctrbits)
     
   //  rkpm_ddr_printhex(mode_set);
   //  rkpm_ddr_printhex(pmu_readl(RK3288_PMU_PWRMODE_CON));
-  
+
     return (pmu_readl(RK3288_PMU_PWRMODE_CON));  
 }
 
@@ -1127,10 +1131,8 @@ static void  rkpm_peri_save(u32 power_mode)
 {
 //    u32 gpio_gate[2];
 
-    if(power_mode&BIT(pmu_scu_en))
-    {
-        rkpm_gic_dist_save(&slp_gic_save[0]);   
-    }
+       if (power_mode & (BIT(pmu_scu_en) | BIT(pmu_a12_0_pd_en)))
+               rkpm_gic_dist_save(&slp_gic_save[0]);
 #if 0
     gpio_gate[0]=cru_readl(RK3288_CRU_GATEID_CONS(RK3288_CLKGATE_PCLK_GPIO0));
     gpio_gate[1]=cru_readl(RK3288_CRU_GATEID_CONS(RK3288_CLKGATE_PCLK_GPIO1));
@@ -1176,13 +1178,12 @@ static void  rkpm_peri_save(u32 power_mode)
 
 static inline void  rkpm_peri_resume(u32 power_mode)
 {
-    if(power_mode&BIT(pmu_scu_en))
-    {       
-        //fiq_glue_resume();
-        rkpm_gic_dist_resume(&slp_gic_save[0]);          
-        fiq_glue_resume();
-        //rkpm_ddr_printascii("gic res");       
-    }  
+       if (power_mode & (BIT(pmu_scu_en) | BIT(pmu_a12_0_pd_en))) {
+               /*fiq_glue_resume();*/
+               rkpm_gic_dist_resume(&slp_gic_save[0]);
+               fiq_glue_resume();
+               /*rkpm_ddr_printascii("gic res");*/
+       }
     if(power_mode&BIT(pmu_bus_pd_en))
    {
         slp_i2c_resume(0);// i2c pmu
@@ -1963,7 +1964,8 @@ int gpio7_pin_iomux1;
 
 static void gtclks_suspend(void)
 {
-    int i;
+       int i;
+
        gpio7_pin_data1= gpio7_readl(0);
        gpio7_pin_dir1 = gpio7_readl(0x04);
        gpio7_pin_iomux1 =  gpio7_readl(0x6c);
@@ -1973,6 +1975,7 @@ static void gtclks_suspend(void)
 
   // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKGATES_CON(0)
                                           //          ,RK3288_CRU_CLKGATES_CON(RK3288_CRU_CLKGATES_CON_CNT-1));
+
     for(i=0;i<RK3288_CRU_CLKGATES_CON_CNT;i++)
     {
             clk_ungt_save[i]=cru_readl(RK3288_CRU_CLKGATES_CON(i));   
@@ -2038,7 +2041,6 @@ static void gtclks_resume(void)
      //rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKGATES_CON(0)
                                                  //   ,RK3288_CRU_CLKGATES_CON(RK3288_CRU_CLKGATES_CON_CNT-1));
        grf_writel(0x00040004, 0x6c);
-
 }
 /********************************pll power down***************************************/
 
@@ -2095,41 +2097,59 @@ static inline void plls_suspend(u32 pll_id)
     cru_writel(RK3288_PLL_PWR_DN, RK3288_PLL_CONS((pll_id), 3));
     
 }
-static inline void plls_resume(u32 pll_id)
+static inline void plls_resume_pre(u32 pll_id)
 {
-        u32 pllcon0, pllcon1, pllcon2;
+       u32 pllcon0, pllcon1, pllcon2;
 
-        if((plls_con3_save[pll_id]&RK3288_PLL_PWR_DN_MSK))
-            return ;
-         
-        //enter slowmode
-        cru_writel(RK3288_PLL_MODE_SLOW(pll_id), RK3288_CRU_MODE_CON);      
-        
-        cru_writel(RK3288_PLL_PWR_ON, RK3288_PLL_CONS((pll_id),3));
-        cru_writel(RK3288_PLL_NO_BYPASS, RK3288_PLL_CONS((pll_id),3));
-        
-        pllcon0 =plls_con0_save[pll_id];// cru_readl(RK3288_PLL_CONS((pll_id),0));
-        pllcon1 = plls_con1_save[pll_id];//cru_readl(RK3288_PLL_CONS((pll_id),1));
-        pllcon2 = plls_con2_save[pll_id];//cru_readl(RK3288_PLL_CONS((pll_id),2));
-
-        //enter rest
-        cru_writel(RK3288_PLL_RESET, RK3288_PLL_CONS(pll_id,3));
-        cru_writel(pllcon0|CRU_W_MSK(0,0xf)|CRU_W_MSK(8,0x3f), RK3288_PLL_CONS(pll_id,0));
-        cru_writel(pllcon1, RK3288_PLL_CONS(pll_id,1));
-        cru_writel(pllcon2, RK3288_PLL_CONS(pll_id,2));
-        
-        pll_udelay(5);
-        //udelay(5); //timer7 delay
+       cru_writel(RK3288_PLL_MODE_SLOW(pll_id), RK3288_CRU_MODE_CON);
 
-        //return form rest
-        cru_writel(RK3288_PLL_RESET_RESUME, RK3288_PLL_CONS(pll_id,3));
+       cru_writel(RK3288_PLL_PWR_ON, RK3288_PLL_CONS((pll_id), 3));
+       cru_writel(RK3288_PLL_NO_BYPASS, RK3288_PLL_CONS((pll_id), 3));
+
+       pllcon0 = plls_con0_save[pll_id];
+       pllcon1 = plls_con1_save[pll_id];
+       pllcon2 = plls_con2_save[pll_id];
+
+       /*enter rest*/
+       cru_writel(RK3288_PLL_RESET, RK3288_PLL_CONS(pll_id, 3));
+       cru_writel(pllcon0 | CRU_W_MSK(0, 0xf) | CRU_W_MSK(8, 0x3f)
+               , RK3288_PLL_CONS(pll_id, 0));
+       cru_writel(pllcon1, RK3288_PLL_CONS(pll_id, 1));
+       cru_writel(pllcon2, RK3288_PLL_CONS(pll_id, 2));
+}
+
+static inline void plls_resume(void)
+{
+       plls_resume_pre(APLL_ID);
+       plls_resume_pre(GPLL_ID);
+       plls_resume_pre(CPLL_ID);
+       plls_resume_pre(NPLL_ID);
+
+       pll_udelay(5);
+
+       /*return form rest*/
+       cru_writel(RK3288_PLL_RESET_RESUME, RK3288_PLL_CONS(APLL_ID, 3));
+       cru_writel(RK3288_PLL_RESET_RESUME, RK3288_PLL_CONS(GPLL_ID, 3));
+       cru_writel(RK3288_PLL_RESET_RESUME, RK3288_PLL_CONS(CPLL_ID, 3));
+       cru_writel(RK3288_PLL_RESET_RESUME, RK3288_PLL_CONS(NPLL_ID, 3));
+
+       /*wating lock state*/
+       pll_udelay(168);
+
+       pm_pll_wait_lock(APLL_ID);
+       pm_pll_wait_lock(GPLL_ID);
+       pm_pll_wait_lock(CPLL_ID);
+       pm_pll_wait_lock(NPLL_ID);
 
-        //wating lock state
-        pll_udelay(168);
-        pm_pll_wait_lock(pll_id);
-        
-        cru_writel(plls_con3_save[pll_id]|(RK3288_PLL_BYPASS_MSK<<16),RK3288_PLL_CONS(pll_id,3));
 
+       cru_writel(plls_con3_save[APLL_ID] | (RK3288_PLL_BYPASS_MSK << 16)
+               , RK3288_PLL_CONS(APLL_ID, 3));
+       cru_writel(plls_con3_save[GPLL_ID] | (RK3288_PLL_BYPASS_MSK << 16)
+               , RK3288_PLL_CONS(GPLL_ID, 3));
+       cru_writel(plls_con3_save[CPLL_ID] | (RK3288_PLL_BYPASS_MSK << 16)
+               , RK3288_PLL_CONS(CPLL_ID, 3));
+       cru_writel(plls_con3_save[NPLL_ID] | (RK3288_PLL_BYPASS_MSK << 16)
+               , RK3288_PLL_CONS(NPLL_ID, 3));
 }
 
 static u32 clk_sel0,clk_sel1, clk_sel10,clk_sel26,clk_sel33,clk_sel36, clk_sel37;
@@ -2224,48 +2244,44 @@ static void pm_plls_suspend(void)
 
 static void pm_plls_resume(void)
 {
+       /* core_m0 core_mp a12_core*/
+       cru_writel(clk_sel0 | (CRU_W_MSK(0, 0xf) | CRU_W_MSK(4, 0xf)
+       | CRU_W_MSK(8, 0xf)), RK3288_CRU_CLKSELS_CON(0));
+       /*core0 core1 core2 core3*/
+       cru_writel(clk_sel36 | (CRU_W_MSK(0, 0x7) | CRU_W_MSK(4, 0x7)
+       | CRU_W_MSK(8, 0x7) | CRU_W_MSK(12, 0x7)), RK3288_CRU_CLKSELS_CON(36));
+       /* l2ram atclk pclk*/
+       cru_writel(clk_sel37 | (CRU_W_MSK(0, 0x7) | CRU_W_MSK(4, 0x1f)
+       | CRU_W_MSK(9, 0x1f)), RK3288_CRU_CLKSELS_CON(37));
+
+       /*resume APLL_ID GPLL_ID CPLL_ID NPLL_ID*/
+       plls_resume();
+
+       cru_writel(cru_mode_con | (RK3288_PLL_MODE_MSK(APLL_ID) << 16)
+               , RK3288_CRU_MODE_CON);
+
+       /*peri aclk hclk pclk*/
+       cru_writel(clk_sel10 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x3)
+       | CRU_W_MSK(12, 0x3)), RK3288_CRU_CLKSELS_CON(10));
+       /*pd bus gpll sel*/
+       cru_writel(clk_sel1 | CRU_W_MSK(15, 0x1), RK3288_CRU_CLKSELS_CON(1));
+       /*pd_bus clk 8*/
+       cru_writel(clk_sel1 | (CRU_W_MSK(0, 0x7) | CRU_W_MSK(3, 0x1f)
+       | CRU_W_MSK(8, 0x3) | CRU_W_MSK(12, 0x7)), RK3288_CRU_CLKSELS_CON(1));
+
+       /*crypto*/
+       cru_writel(clk_sel26 | CRU_W_MSK(6, 0x3), RK3288_CRU_CLKSELS_CON(26));
+
+       /*pmu alive */
+       cru_writel(clk_sel33 | CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x1f)
+       , RK3288_CRU_CLKSELS_CON(33));
+       cru_writel(cru_mode_con | (RK3288_PLL_MODE_MSK(GPLL_ID) << 16)
+               , RK3288_CRU_MODE_CON);
+       cru_writel(cru_mode_con | (RK3288_PLL_MODE_MSK(CPLL_ID) << 16)
+               , RK3288_CRU_MODE_CON);
+       cru_writel(cru_mode_con | (RK3288_PLL_MODE_MSK(NPLL_ID) << 16)
+               , RK3288_CRU_MODE_CON);
 
-
-        // core_m0 core_mp a12_core
-        cru_writel(clk_sel0|(CRU_W_MSK(0,0xf)|CRU_W_MSK(4,0xf)|CRU_W_MSK(8,0xf)),RK3288_CRU_CLKSELS_CON(0));
-        // core0 core1 core2 core3
-        cru_writel(clk_sel36|(CRU_W_MSK(0,0x7)|CRU_W_MSK(4,0x7)|CRU_W_MSK(8,0x7)|CRU_W_MSK(12,0x7))
-                        , RK3288_CRU_CLKSELS_CON(36));
-        // l2ram atclk pclk
-        cru_writel(clk_sel37|(CRU_W_MSK(0,0x7)|CRU_W_MSK(4,0x1f)|CRU_W_MSK(9,0x1f)) , RK3288_CRU_CLKSELS_CON(37));
-        
-        plls_resume(APLL_ID);    
-        cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(APLL_ID)<<16), RK3288_CRU_MODE_CON);
-        
-        // peri aclk hclk pclk
-        cru_writel(clk_sel10|(CRU_W_MSK(0,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x3))
-                                                                            , RK3288_CRU_CLKSELS_CON(10));
-        //pd bus gpll sel
-        cru_writel(clk_sel1|CRU_W_MSK(15,0x1), RK3288_CRU_CLKSELS_CON(1));
-        // pd_bus clk 
-        cru_writel(clk_sel1|(CRU_W_MSK(0,0x7)|CRU_W_MSK(3,0x1f)|CRU_W_MSK(8,0x3)|CRU_W_MSK(12,0x7))
-                    , RK3288_CRU_CLKSELS_CON(1));
-                
-        // crypto
-        cru_writel(clk_sel26|CRU_W_MSK(6,0x3), RK3288_CRU_CLKSELS_CON(26));
-    
-        
-          // pmu alive 
-        cru_writel(clk_sel33|CRU_W_MSK(0,0x1f)|CRU_W_MSK(8,0x1f), RK3288_CRU_CLKSELS_CON(33));
-
-        plls_resume(GPLL_ID);   
-        cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(GPLL_ID)<<16), RK3288_CRU_MODE_CON);       
-        
-        plls_resume(CPLL_ID);    
-        cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(CPLL_ID)<<16), RK3288_CRU_MODE_CON);
-        
-        plls_resume(NPLL_ID);       
-        cru_writel(cru_mode_con|(RK3288_PLL_MODE_MSK(NPLL_ID)<<16), RK3288_CRU_MODE_CON);
-
-       // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_PLL_CONS((0), 0),RK3288_PLL_CONS((4), 3)); 
-       // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_MODE_CON,RK3288_CRU_MODE_CON);   
-       // rkpm_ddr_regs_dump(RK_CRU_VIRT,RK3288_CRU_CLKSELS_CON(0),RK3288_CRU_CLKSELS_CON(42));
-        
 }
 
 static __sramdata u32  sysclk_clksel0_con,sysclk_clksel1_con,sysclk_clksel10_con,sysclk_mode_con;
index 99fec2de39fd7b2f7a03251f96c0476c027bc35c..e0f0a25bd1b5dbcefed4f2d88ef26154d6b2a7aa 100755 (executable)
@@ -583,13 +583,10 @@ void PIE_FUNC(pwm_regulator_suspend)(void)
        }
 
        if (rkpm_chk_sram_ctrbit(RKPM_CTR_VOL_PWM2)) {
-               FUNC(sram_printch)('p');
-               FUNC(sram_printch)('o');
-               FUNC(sram_printch)('l');
-       rkpm_pwm_duty2 = readl_relaxed(RK_PWM_VIRT + 0x28);
-       writel_relaxed(PWM_VOLTAGE, RK_PWM_VIRT + 0x28);
+               rkpm_pwm_duty2 = readl_relaxed(RK_PWM_VIRT + 0x28);
+               writel_relaxed(PWM_VOLTAGE, RK_PWM_VIRT + 0x28);
        }
-       rkpm_udelay(30);
+       //rkpm_udelay(30);
 }
 
 void PIE_FUNC(pwm_regulator_resume)(void)
index d9e08033a7b075e05a15e9bf8e41211daf133faa..7c8f69acbc65373a10cace12e00849591e9607e7 100755 (executable)
@@ -144,6 +144,7 @@ static void __init rk312x_dt_map_io(void)
        dsb();
 
        rk312x_boot_mode_init();
+       rockchip_efuse_init();
 }
 
 static void __init rk3126_dt_map_io(void)
index abcdb16e7c78dbb65275c24f67cf27e216338978..71fd7ff4467d58993173563f692300e45decf187 100755 (executable)
@@ -30,6 +30,7 @@
 #include <linux/rockchip/grf.h>
 #include <linux/rockchip/iomap.h>
 #include <linux/rockchip/pmu.h>
+#include <linux/fb.h>
 #include <asm/cpuidle.h>
 #include <asm/cputype.h>
 #include <asm/mach/arch.h>
@@ -490,6 +491,40 @@ static void __init rk3288_init_cpuidle(void)
        if (ret)
                pr_err("%s: failed to register cpuidle driver: %d\n", __func__, ret);
 }
+
+static int rk3288_pll_early_suspend_notifier_call(struct notifier_block *self,
+                               unsigned long action, void *data)
+{
+       struct fb_event *event = data;
+       int blank_mode = *((int *)event->data);
+
+       if (action == FB_EARLY_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_UNBLANK:
+                       clk_prepare_enable(clk_get_sys(NULL, "clk_cpll"));
+                       clk_prepare_enable(clk_get_sys(NULL, "clk_npll"));
+                       break;
+               default:
+                       break;
+               }
+       } else if (action == FB_EVENT_BLANK) {
+               switch (blank_mode) {
+               case FB_BLANK_POWERDOWN:
+                       clk_disable_unprepare(clk_get_sys(NULL, "clk_cpll"));
+                       clk_disable_unprepare(clk_get_sys(NULL, "clk_npll"));
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block rk3288_pll_early_suspend_notifier = {
+       .notifier_call = rk3288_pll_early_suspend_notifier_call,
+};
+
 #ifdef CONFIG_PM
 static void __init rk3288_init_suspend(void);
 #endif
@@ -596,10 +631,11 @@ void inline rkpm_periph_pd_dn(bool on)
 static void __init rk3288_init_suspend(void)
 {
     printk("%s\n",__FUNCTION__);
+    fb_register_client(&rk3288_pll_early_suspend_notifier);
     rockchip_suspend_init();       
     rkpm_pie_init();
     rk3288_suspend_init();
-   rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume);  
+   rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume);
 }
 
 #if 0
index 3407b1cea6c9ad4705020bd4b0fda5a1e7c56c10..0eed737a56826b8662177098433170c06957a0c2 100644 (file)
@@ -163,7 +163,7 @@ static int  rk_dts_sensor_probe(struct platform_device *pdev)
                u32     powerdown = INVALID_GPIO,power = INVALID_GPIO,reset = INVALID_GPIO;
                u32 af = INVALID_GPIO,flash = INVALID_GPIO;
 
-               int pwr_active = 0, rst_active = 0, pwdn_active = 0;
+               int pwr_active = 0, rst_active = 0, pwdn_active = 0,flash_active = 0;
                int orientation = 0;
                struct rkcamera_platform_data *new_camera; 
                
@@ -231,6 +231,9 @@ static int  rk_dts_sensor_probe(struct platform_device *pdev)
                }
                if (of_property_read_u32(cp, "rockchip,flash", &flash)) {
                                dprintk("%s:Get %s rockchip,flash failed!\n",__func__, cp->name);                               
+               }               
+               if (of_property_read_u32(cp, "flash_active", &flash_active)) {
+                               dprintk("%s:Get %s flash_active failed!\n",__func__, cp->name);                         
                }
                if (of_property_read_u32(cp, "i2c_add", &i2c_add)) {
                        printk("%s:Get %s rockchip,i2c_add failed!\n",__func__, cp->name);                              
@@ -261,7 +264,10 @@ static int rk_dts_sensor_probe(struct platform_device *pdev)
                new_camera->io.gpio_power = power;
                new_camera->io.gpio_af = af;
                new_camera->io.gpio_flash = flash;
-               new_camera->io.gpio_flag = ((pwr_active&0x01)<<RK29_CAM_POWERACTIVE_BITPOS)|((rst_active&0x01)<<RK29_CAM_RESETACTIVE_BITPOS)|((pwdn_active&0x01)<<RK29_CAM_POWERDNACTIVE_BITPOS);
+               new_camera->io.gpio_flag = ((pwr_active&0x01)<<RK29_CAM_POWERACTIVE_BITPOS)
+                                                                       |((rst_active&0x01)<<RK29_CAM_RESETACTIVE_BITPOS)
+                                                                       |((pwdn_active&0x01)<<RK29_CAM_POWERDNACTIVE_BITPOS)
+                                                                       |((flash_active&0x01)<<RK29_CAM_FLASHACTIVE_BITPOS);
                new_camera->orientation = orientation;
                new_camera->resolution = resolution;
                new_camera->mirror = mir;
@@ -524,7 +530,6 @@ static int sensor_flash_default_cb (struct rk29camera_gpio_res *res, int on)
 
        debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
 
-
     if (camera_flash != INVALID_GPIO) {
                if (camera_io_init & RK29_CAM_FLASHACTIVE_MASK) {
             switch (on)
index 75037d75d242772f2951342664fee3ada8f992b1..02db4b0aef43c60a6bd579dcbf92ba9ec684268a 100644 (file)
@@ -26,6 +26,7 @@
 #include <media/soc_camera.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include "rk_camera_sensor_info.h"
 
 #define RK29_CAM_PLATFORM_DEV_ID 33
 #define RK_CAM_PLATFORM_DEV_ID_0 RK29_CAM_PLATFORM_DEV_ID
@@ -44,8 +45,6 @@
 #define RK29_CAM_FLASHACTIVE_BITPOS    0x03
 #define RK29_CAM_AFACTIVE_BITPOS       0x04
 
-#define RK_CAM_NUM 0 //YZM
-#define RK29_CAM_SUPPORT_NUMS  RK_CAM_NUM
 #define RK_CAM_SUPPORT_RESOLUTION 0x800000
 
 #define _CONS(a,b) a##b
 
  
 /*---------------- 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_OV2660 ov2660 /*yzm*/
-
-#define RK29_CAM_SENSOR_OV7690 ov7690
-#define RK29_CAM_SENSOR_OV3640 ov3640
-#define RK29_CAM_SENSOR_OV3660 ov3660
-#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_GC0328  gc0328
-#define RK29_CAM_SENSOR_GC0329  gc0329
-#define RK29_CAM_SENSOR_GC2035 gc2035
-#define RK29_CAM_SENSOR_SIV120B  siv120b
-#define RK29_CAM_SENSOR_SIV121D  siv121d
-#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_SP0718  sp0718
-#define RK29_CAM_SENSOR_SP0838  sp0838
-#define RK29_CAM_SENSOR_SP2518  sp2518
-#define RK29_CAM_SENSOR_S5K5CA  s5k5ca
-#define RK29_CAM_ISP_MTK9335   mtk9335isp
-#define RK29_CAM_SENSOR_HM2057  hm2057
-#define RK29_CAM_SENSOR_HM5065  hm5065
-#define RK29_CAM_SENSOR_NT99160 nt99160  //oyyf@rock-chips.com 
-#define RK29_CAM_SENSOR_NT99240 nt99240  //oyyf@rock-chips.com 
-#define RK29_CAM_SENSOR_NT99252 nt99252  //oyyf@rock-chips.com 
-#define RK29_CAM_SENSOR_NT99340 nt99340  //oyyf@rock-chips.com 
-#define RK29_CAM_ISP_ICATCH7002_MI1040  icatchmi1040   
-#define RK29_CAM_ISP_ICATCH7002_OV5693  icatchov5693
-#define RK29_CAM_ISP_ICATCH7002_OV8825  icatchov8825   //zyt
-#define RK29_CAM_ISP_ICATCH7002_OV2720  icatchov2720   //zyt
-
-#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_OV2660 "ov2660"  /*yzm*/
-
-
-#define RK29_CAM_SENSOR_NAME_OV7690 "ov7690"
-#define RK29_CAM_SENSOR_NAME_OV3640 "ov3640"
-#define RK29_CAM_SENSOR_NAME_OV3660 "ov3660"
-#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_GC0328  "gc0328"
-#define RK29_CAM_SENSOR_NAME_GC2035  "gc2035"
-#define RK29_CAM_SENSOR_NAME_GC0329  "gc0329"
-#define RK29_CAM_SENSOR_NAME_SIV120B "siv120b"
-#define RK29_CAM_SENSOR_NAME_SIV121D "siv121d"
-#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 RK29_CAM_SENSOR_NAME_SP0718  "sp0718"
-#define RK29_CAM_SENSOR_NAME_SP0838  "sp0838"
-#define RK29_CAM_SENSOR_NAME_SP2518  "sp2518"
-#define RK29_CAM_SENSOR_NAME_S5K5CA  "s5k5ca"
-#define RK29_CAM_ISP_NAME_MTK9335ISP "mtk9335isp"
-#define RK29_CAM_SENSOR_NAME_HM2057  "hm2057"
-#define RK29_CAM_SENSOR_NAME_HM5065  "hm5065"
-#define RK29_CAM_ISP_NAME_ICATCH7002_MI1040 "icatchmi1040"
-#define RK29_CAM_ISP_NAME_ICATCH7002_OV5693 "icatchov5693"
-#define RK29_CAM_ISP_NAME_ICATCH7002_OV8825 "icatchov8825" //zyt
-#define RK29_CAM_ISP_NAME_ICATCH7002_OV2720 "icatchov2720" //zyt
-
-//Sensor full resolution define
-#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 ov2660_FULL_RESOLUTION     0x200000           // 2 megapixel
-
-#define ov7690_FULL_RESOLUTION     0x300000           // 2 megapixel
-#define ov3640_FULL_RESOLUTION     0x300000           // 3 megapixel
-#define ov3660_FULL_RESOLUTION     0x300000           // 3 megapixel
-#define ov5640_FULL_RESOLUTION     0x500000           // 5 megapixel
-#if defined(CONFIG_SOC_CAMERA_OV5642_INTERPOLATION_8M)
-       #define ov5642_FULL_RESOLUTION     0x800000            // 8 megapixel
-#else  
-    #define ov5642_FULL_RESOLUTION     0x500000           // 5 megapixel
-#endif
-#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
-#if defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_5M)
-       #define gc0308_FULL_RESOLUTION     0x500000            // 5 megapixel
-#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_3M)
-       #define gc0308_FULL_RESOLUTION     0x300000            // 3 megapixel
-#elif defined(CONFIG_SOC_CAMERA_GC0308_INTERPOLATION_2M)
-       #define gc0308_FULL_RESOLUTION     0x200000            // 2 megapixel
-#else
-       #define gc0308_FULL_RESOLUTION     0x30000            // 0.3 megapixel#endif
-#endif
-#define gc0328_FULL_RESOLUTION     0x30000            // 0.3 megapixel
-#define gc0307_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 siv121d_FULL_RESOLUTION     0x30000            // 0.3 megapixel
-#define sid130B_FULL_RESOLUTION     0x200000           // 2 megapixel    
-
-#if defined(CONFIG_SOC_CAMERA_HI253_INTERPOLATION_5M) 
-       #define hi253_FULL_RESOLUTION       0x500000                    // 5 megapixel
-#elif defined(CONFIG_SOC_CAMERA_HI253_INTERPOLATION_3M)
-       #define hi253_FULL_RESOLUTION       0x300000           // 3 megapixel
-#else
-       #define hi253_FULL_RESOLUTION       0x200000           // 2 megapixel
-#endif
-
-#define hi704_FULL_RESOLUTION       0x30000            // 0.3 megapixel
-#define nt99250_FULL_RESOLUTION     0x200000           // 2 megapixel
-#define sp0718_FULL_RESOLUTION      0x30000            // 0.3 megapixel
-#define sp0838_FULL_RESOLUTION      0x30000            // 0.3 megapixel
-#define sp2518_FULL_RESOLUTION      0x200000            // 2 megapixel
-#define gc0329_FULL_RESOLUTION      0x30000            // 0.3 megapixel
-#define s5k5ca_FULL_RESOLUTION      0x300000            // 3 megapixel
-#define mtk9335isp_FULL_RESOLUTION  0x500000                   //5 megapixel
-#define gc2035_FULL_RESOLUTION      0x200000            // 2 megapixel
-#define hm2057_FULL_RESOLUTION      0x200000            // 2 megapixel
-#define hm5065_FULL_RESOLUTION      0x500000            // 5 megapixel
-#define nt99160_FULL_RESOLUTION     0x100000           // oyyf@rock-chips.com:  1 megapixel 1280*720    
-#define nt99240_FULL_RESOLUTION     0x200000           // oyyf@rock-chips.com:  2 megapixel 1600*1200
-#define nt99252_FULL_RESOLUTION     0x200000           // oyyf@rock-chips.com:  2 megapixel 1600*1200
-#define nt99340_FULL_RESOLUTION     0x300000           // oyyf@rock-chips.com:  3 megapixel 2048*1536
-#define icatchmi1040_FULL_RESOLUTION 0x200000
-#define icatchov5693_FULL_RESOLUTION 0x500000
-#define icatchov8825_FULL_RESOLUTION 0x800000                                  //zyt
-#define icatchov2720_FULL_RESOLUTION 0x210000                   //zyt
-#define end_FULL_RESOLUTION         0x00
-
-//Sensor i2c addr define
-#define ov7675_I2C_ADDR             0x78            
-#define ov9650_I2C_ADDR             0x60           
-#define ov2640_I2C_ADDR             0x60
-#define ov2655_I2C_ADDR             0x60
-#define ov2659_I2C_ADDR             0x60
-
-#define ov2660_I2C_ADDR             0x60   /*yzm*/
-
-#define ov7690_I2C_ADDR             0x42
-#define ov3640_I2C_ADDR             0x78
-#define ov3660_I2C_ADDR             0x78
-#define ov5640_I2C_ADDR             0x78
-#define ov5642_I2C_ADDR             0x78
-
-#define s5k6aa_I2C_ADDR             0x78           //0x5a
-#define s5k5ca_I2C_ADDR             0x78           //0x5a
-
-#define mt9d112_I2C_ADDR             0x78
-#define mt9d113_I2C_ADDR             0x78
-#define mt9t111_I2C_ADDR             0x78           // 0x7a 
-
-#define mt9p111_I2C_ADDR            0x78            //0x7a
-#define gt2005_I2C_ADDR             0x78           
-#define gc0307_I2C_ADDR             0x42
-#define gc0328_I2C_ADDR             0x42
-#define gc0308_I2C_ADDR             0x42
-#define gc0309_I2C_ADDR             0x42
-#define gc0329_I2C_ADDR             0x62           
-#define gc2015_I2C_ADDR             0x60
-#define gc2035_I2C_ADDR             0x78            
-
-#define siv120b_I2C_ADDR             INVALID_VALUE           
-#define siv121d_I2C_ADDR             INVALID_VALUE           
-#define sid130B_I2C_ADDR             0x37
-
-#define hi253_I2C_ADDR             0x40
-#define hi704_I2C_ADDR             0x60
-
-#define nt99160_I2C_ADDR             0x54
-#define nt99240_I2C_ADDR             0x6c
-#define nt99250_I2C_ADDR             0x6c
-#define nt99252_I2C_ADDR             0x6c
-#define nt99340_I2C_ADDR             0x76
-
-#define sp0718_I2C_ADDR             0x42
-#define sp0838_I2C_ADDR             INVALID_VALUE  
-#define sp0a19_I2C_ADDR             0x7a
-#define sp1628_I2C_ADDR             0x78
-#define sp2518_I2C_ADDR             0x60 
-#define mtk9335isp_I2C_ADDR         0x50 
-#define hm2057_I2C_ADDR             0x48
-#define hm5065_I2C_ADDR             0x3e
-#define icatchmi1040_I2C_ADDR          0x78
-#define icatchov5693_I2C_ADDR       0x78
-#define icatchov8825_I2C_ADDR       0x78  //zyt
-#define icatchov2720_I2C_ADDR       0x78  //zyt
-#define end_I2C_ADDR                INVALID_VALUE
-
-
-//Sensor power down active level define
-#define ov7675_PWRDN_ACTIVE             0x01            
-#define ov9650_PWRDN_ACTIVE             0x01           
-#define ov2640_PWRDN_ACTIVE             0x01
-#define ov2655_PWRDN_ACTIVE             0x01
-#define ov2659_PWRDN_ACTIVE             0x01
-
-#define ov2660_PWRDN_ACTIVE             0x01  /*yzm*/
-
-#define ov7690_PWRDN_ACTIVE             0x01
-#define ov3640_PWRDN_ACTIVE             0x01
-#define ov3660_PWRDN_ACTIVE             0x01
-#define ov5640_PWRDN_ACTIVE             0x01
-#define ov5642_PWRDN_ACTIVE             0x01
-
-#define s5k6aa_PWRDN_ACTIVE             0x00           
-#define s5k5ca_PWRDN_ACTIVE             0x00           
-
-#define mt9d112_PWRDN_ACTIVE             0x01
-#define mt9d113_PWRDN_ACTIVE             0x01
-#define mt9t111_PWRDN_ACTIVE             0x01  
-#define mt9p111_PWRDN_ACTIVE             0x01
-
-#define gt2005_PWRDN_ACTIVE             0x00           
-#define gc0307_PWRDN_ACTIVE             0x01
-#define gc0308_PWRDN_ACTIVE             0x01
-#define gc0328_PWRDN_ACTIVE             0x01
-#define gc0309_PWRDN_ACTIVE             0x01
-#define gc0329_PWRDN_ACTIVE             0x01           
-#define gc2015_PWRDN_ACTIVE             0x01
-#define gc2035_PWRDN_ACTIVE             0x01            
-
-#define siv120b_PWRDN_ACTIVE             INVALID_VALUE           
-#define siv121d_PWRDN_ACTIVE             INVALID_VALUE           
-#define sid130B_PWRDN_ACTIVE             0x37
-
-#define hi253_PWRDN_ACTIVE             0x01
-#define hi704_PWRDN_ACTIVE             0x01
-
-#define nt99160_PWRDN_ACTIVE             0x01
-#define nt99240_PWRDN_ACTIVE             0x01
-#define nt99250_PWRDN_ACTIVE             0x01
-#define nt99252_PWRDN_ACTIVE             0x01
-#define nt99340_PWRDN_ACTIVE             0x01
-
-#define sp0718_PWRDN_ACTIVE             0x01
-#define sp0838_PWRDN_ACTIVE             0x01  
-#define sp0a19_PWRDN_ACTIVE             0x01
-#define sp1628_PWRDN_ACTIVE             0x01
-#define sp2518_PWRDN_ACTIVE             0x01 
-#define hm2057_PWRDN_ACTIVE             0x01
-#define hm5065_PWRDN_ACTIVE             0x00
-#define mtk9335isp_PWRDN_ACTIVE         0x01 
-#define end_PWRDN_ACTIVE                INVALID_VALUE
-
-
-//Sensor power up sequence  define
-//type: bit0-bit4
-#define SENSOR_PWRSEQ_BEGIN         0x00
-#define SENSOR_PWRSEQ_AVDD          0x01
-#define SENSOR_PWRSEQ_DOVDD         0x02
-#define SENSOR_PWRSEQ_DVDD          0x03
-#define SENSOR_PWRSEQ_PWR           0x04
-#define SENSOR_PWRSEQ_HWRST         0x05
-#define SENSOR_PWRSEQ_PWRDN         0x06
-#define SENSOR_PWRSEQ_CLKIN         0x07
-#define SENSOR_PWRSEQ_END           0x0F
-
-#define SENSOR_PWRSEQ_SET(type,idx)    (type<<(idx*4))
-#define SENSOR_PWRSEQ_GET(seq,idx)     ((seq>>(idx*4))&0x0f)
-
-#define sensor_PWRSEQ_DEFAULT      (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,1)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN,2)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,3))
-
-#define ov7675_PWRSEQ                   sensor_PWRSEQ_DEFAULT            
-#define ov9650_PWRSEQ                   sensor_PWRSEQ_DEFAULT  
-#define ov2640_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov2655_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov2659_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define ov2660_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define ov7690_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov3640_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov3660_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov5640_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define ov5642_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define s5k6aa_PWRSEQ                   sensor_PWRSEQ_DEFAULT         
-#define s5k5ca_PWRSEQ                   sensor_PWRSEQ_DEFAULT          
-
-#define mt9d112_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define mt9d113_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define mt9t111_PWRSEQ                   sensor_PWRSEQ_DEFAULT 
-#define mt9p111_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define gt2005_PWRSEQ                   sensor_PWRSEQ_DEFAULT          
-#define gc0307_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define gc0308_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define gc0328_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define gc0309_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define gc0329_PWRSEQ                   sensor_PWRSEQ_DEFAULT          
-#define gc2015_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define gc2035_PWRSEQ                   sensor_PWRSEQ_DEFAULT            
-
-#define siv120b_PWRSEQ                   sensor_PWRSEQ_DEFAULT         
-#define siv121d_PWRSEQ                   sensor_PWRSEQ_DEFAULT         
-#define sid130B_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define hi253_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define hi704_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define nt99160_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define nt99240_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define nt99250_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define nt99252_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define nt99340_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define sp0718_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define sp0838_PWRSEQ                   sensor_PWRSEQ_DEFAULT  
-#define sp0a19_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define sp1628_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define sp2518_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define hm2057_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-#define hm5065_PWRSEQ                   (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,1)|\
-                                        SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
-                                        SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWRDN,0)|\
-                                        SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,3))
-#define mtk9335isp_PWRSEQ               sensor_PWRSEQ_DEFAULT
-#define icatchov5693_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))
-                                    
-#define icatchov8825_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))     //zyt                                    
-                                    
-#define icatchov2720_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))     //zyt 
-
-#define icatchmi1040_PWRSEQ               (SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_PWR,0)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_HWRST,2)|\
-                                    SENSOR_PWRSEQ_SET(SENSOR_PWRSEQ_CLKIN,1))
-
-#define end_PWRSEQ                      0xffffffff
-                                          
-
-
+/*
+ move to rk_camera_sensor_info.h   yzm                                    
+*/
 /*---------------- Camera Sensor Must Define Macro End  ------------------------*/
 
 
index b37ffdb3e49a0ab994672fcc771c6383a42e9c21..7b5e380cd2d3bbe74eff00459a268157d678b758 100644 (file)
@@ -8,9 +8,6 @@
 #define RK29_CAM_SENSOR_OV2640 ov2640
 #define RK29_CAM_SENSOR_OV2655 ov2655
 #define RK29_CAM_SENSOR_OV2659 ov2659
-
-#define RK29_CAM_SENSOR_OV2660 ov2660 /*yzm*/
-
 #define RK29_CAM_SENSOR_OV7690 ov7690
 #define RK29_CAM_SENSOR_OV3640 ov3640
 #define RK29_CAM_SENSOR_OV3660 ov3660
 #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_OV2660 "ov2660"  /*yzm*/
-
-
 #define RK29_CAM_SENSOR_NAME_OV7690 "ov7690"
 #define RK29_CAM_SENSOR_NAME_OV3640 "ov3640"
 #define RK29_CAM_SENSOR_NAME_OV3660 "ov3660"
 #define ov2640_I2C_ADDR             0x60
 #define ov2655_I2C_ADDR             0x60
 #define ov2659_I2C_ADDR             0x60
-
-#define ov2660_I2C_ADDR             0x60   /*yzm*/
-
 #define ov7690_I2C_ADDR             0x42
 #define ov3640_I2C_ADDR             0x78
 #define ov3660_I2C_ADDR             0x78
 #define ov2640_PWRDN_ACTIVE             0x01
 #define ov2655_PWRDN_ACTIVE             0x01
 #define ov2659_PWRDN_ACTIVE             0x01
-
-#define ov2660_PWRDN_ACTIVE             0x01  /*yzm*/
-
 #define ov7690_PWRDN_ACTIVE             0x01
 #define ov3640_PWRDN_ACTIVE             0x01
 #define ov3660_PWRDN_ACTIVE             0x01
 #define ov2640_PWRSEQ                   sensor_PWRSEQ_DEFAULT
 #define ov2655_PWRSEQ                   sensor_PWRSEQ_DEFAULT
 #define ov2659_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
-#define ov2660_PWRSEQ                   sensor_PWRSEQ_DEFAULT
-
 #define ov7690_PWRSEQ                   sensor_PWRSEQ_DEFAULT
 #define ov3640_PWRSEQ                   sensor_PWRSEQ_DEFAULT
 #define ov3660_PWRSEQ                   sensor_PWRSEQ_DEFAULT
index 1ecf9c77249dc36eb3963db591562f4ba020ce46..d2ae69ffc24f1447f4417002b771883f5361c54e 100755 (executable)
@@ -384,6 +384,11 @@ typedef struct vpu_service_info {
        struct delayed_work     simulate_work;
 } vpu_service_info;
 
+struct vcodec_combo {
+       struct vpu_service_info *vpu_srv;
+       struct vpu_service_info *hevc_srv;
+};
+
 typedef struct vpu_request
 {
        unsigned long *req;
@@ -395,6 +400,7 @@ typedef struct vpu_request
 static struct dentry *parent; // debugfs root directory for all device (vpu, hevc).
 /* mutex for selecting operation registers of vpu or hevc */
 static struct mutex g_mode_mutex;
+static struct vcodec_combo g_combo;
 
 #ifdef CONFIG_DEBUG_FS
 static int vcodec_debugfs_init(void);
@@ -714,12 +720,31 @@ static void vpu_service_power_on(struct vpu_service_info *pservice)
                vpu_queue_power_off_work(pservice);
                last = now;
        }
+
        if (pservice->enabled)
                return ;
 
        pservice->enabled = true;
        printk("%s: power on\n", dev_name(pservice->dev));
 
+       if (cpu_is_rk3036() || cpu_is_rk312x()) {
+               if (pservice == g_combo.vpu_srv) {
+                       if (g_combo.hevc_srv != NULL && g_combo.hevc_srv->mmu_dev) {
+                               u32 config;
+                               vcodec_enter_mode_nolock(g_combo.hevc_srv->dev_id, &config);
+                               rockchip_iovmm_deactivate(g_combo.hevc_srv->dev);
+                               vcodec_exit_mode_nolock(g_combo.hevc_srv->dev_id, config);
+                       }
+               } else if (pservice == g_combo.hevc_srv) {
+                       if (g_combo.vpu_srv != NULL && g_combo.vpu_srv->mmu_dev) {
+                               u32 config;
+                               vcodec_enter_mode_nolock(g_combo.vpu_srv->dev_id, &config);
+                               rockchip_iovmm_deactivate(g_combo.vpu_srv->dev);
+                               vcodec_exit_mode_nolock(g_combo.vpu_srv->dev_id, config);
+                       }
+               }
+       }
+
 #if VCODEC_CLOCK_ENABLE
        if (pservice->aclk_vcodec)
                clk_prepare_enable(pservice->aclk_vcodec);
@@ -755,8 +780,11 @@ static void vpu_service_power_on(struct vpu_service_info *pservice)
        wake_lock(&pservice->wake_lock);
 
 #if defined(CONFIG_VCODEC_MMU)
-       if (pservice->mmu_dev)
+       if (pservice->mmu_dev) {
+               vcodec_enter_mode(pservice->dev_id);
                rockchip_iovmm_activate(pservice->dev);
+               vcodec_exit_mode();
+       }
 #endif    
 }
 
@@ -1691,6 +1719,7 @@ static int vcodec_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct vpu_service_info *pservice = devm_kzalloc(dev, sizeof(struct vpu_service_info), GFP_KERNEL);
        char *prop = (char*)dev_name(dev);
+       u32 config;
 #if defined(CONFIG_VCODEC_MMU)
        u32 iommu_en = 0;
        char mmu_dev_dts_name[40];
@@ -1704,15 +1733,17 @@ static int vcodec_probe(struct platform_device *pdev)
 
        if (strcmp(dev_name(dev), "hevc_service") == 0) {
                pservice->dev_id = VCODEC_DEVICE_ID_HEVC;
+               g_combo.hevc_srv = pservice;
        } else if (strcmp(dev_name(dev), "vpu_service") == 0) {
                pservice->dev_id = VCODEC_DEVICE_ID_VPU;
+               g_combo.vpu_srv = pservice;
        } else {
                dev_err(dev, "Unknown device %s to probe\n", dev_name(dev));
                return -1;
        }
 
        mutex_init(&g_mode_mutex);
-       vcodec_enter_mode(pservice->dev_id);
+       vcodec_enter_mode_nolock(pservice->dev_id, &config);
 
        wake_lock_init(&pservice->wake_lock, WAKE_LOCK_SUSPEND, "vpu");
        INIT_LIST_HEAD(&pservice->waiting);
@@ -1880,7 +1911,7 @@ static int vcodec_probe(struct platform_device *pdev)
                rockchip_iovmm_set_fault_handler(pservice->dev, vcodec_sysmmu_fault_handler);
        }
 #endif
-       vcodec_exit_mode();
+       vcodec_exit_mode_nolock(pservice->dev_id, config);
        vpu_service_power_off(pservice);
 
        pr_info("init success\n");
@@ -2313,6 +2344,9 @@ static int __init vcodec_service_init(void)
 {
        int ret;
 
+       g_combo.hevc_srv = NULL;
+       g_combo.vpu_srv = NULL;
+
        if ((ret = platform_driver_register(&vcodec_driver)) != 0) {
                pr_err("Platform device register failed (%d).\n", ret);
                return ret;
index 08fe897c0b4cfcdc4c2eed939870cf46ddf57735..303afaa43ce73309329f20c64908464a55b63cfd 100644 (file)
@@ -90,6 +90,13 @@ static inline int is_dma_buf_file(struct file *file)
        return file->f_op == &dma_buf_fops;
 }
 
+#ifdef CONFIG_ARCH_ROCKCHIP
+int dma_buf_is_dma_buf(struct file *file)
+{
+       return is_dma_buf_file(file);
+}
+#endif
+
 /**
  * dma_buf_export_named - Creates a new dma_buf, and associates an anon file
  * with this buffer, so it can be exported.
index 42dfef3284546cb509032bf460b3b738682cb893..07bfd3d5f4f8f11cfb3ea997975e6c4a531365e5 100755 (executable)
@@ -824,10 +824,113 @@ static int clk_pll_set_rate_3188plus(struct clk_hw *hw, unsigned long rate,
        return ret;
 }
 
+static int clk_pll_is_enabled_3188plus(struct clk_hw *hw)
+{
+       unsigned long flags;
+       struct clk_pll *pll = to_clk_pll(hw);
+       int ret;
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       if (_RK3188_PLL_MODE_IS_NORM(pll->mode_offset, pll->mode_shift))
+               ret = 1;
+       else
+               ret = 0;
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static int clk_pll_enable_3188plus(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags;
+       unsigned long rst_dly;
+       u32 nr;
+
+       clk_debug("%s enter\n", __func__);
+
+       if (clk_pll_is_enabled_3188plus(hw)) {
+               clk_debug("pll has been enabled\n");
+               return 0;
+       }
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       //power up
+       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //enter reset
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       //cru_writel(clk_set->pllcon0, pll->reg + RK3188_PLL_CON(0));
+       //cru_writel(clk_set->pllcon1, pll->reg + RK3188_PLL_CON(1));
+       //cru_writel(clk_set->pllcon2, pll->reg + RK3188_PLL_CON(2));
+
+       udelay(5);
+
+       //return from reset
+       cru_writel(_RK3188PLUS_PLL_RESET_SET(0), pll->reg + RK3188_PLL_CON(3));
+
+       //wating lock state
+       nr = RK3188PLUS_PLL_NR(cru_readl(pll->reg + RK3188_PLL_CON(0)));
+       rst_dly = ((nr*500)/24+1);
+       udelay(rst_dly);
+
+       pll_wait_lock(hw);
+
+       //return from slow
+       cru_writel(_RK3188_PLL_MODE_NORM_SET(pll->mode_shift), pll->mode_offset);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       clk_debug("pll %s dump reg:\n con0=0x%08x,\n con1=0x%08x,\n con2=0x%08x,\n"
+                       "con3=0x%08x,\n mode=0x%08x\n",
+                       __clk_get_name(hw->clk),
+                       cru_readl(pll->reg + RK3188_PLL_CON(0)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(1)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(2)),
+                       cru_readl(pll->reg + RK3188_PLL_CON(3)),
+                       cru_readl(pll->mode_offset));
+
+       return 0;
+}
+
+static void clk_pll_disable_3188plus(struct clk_hw *hw)
+{
+       struct clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags;
+
+       clk_debug("%s enter\n", __func__);
+
+       if(pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       //enter slowmode
+       cru_writel(_RK3188_PLL_MODE_SLOW_SET(pll->mode_shift), pll->mode_offset);
+
+       //power down
+       cru_writel(_RK3188PLUS_PLL_POWERDOWN_SET(1), pll->reg + RK3188_PLL_CON(3));
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+
 static const struct clk_ops clk_pll_ops_3188plus = {
        .recalc_rate = clk_pll_recalc_rate_3188plus,
        .round_rate = clk_pll_round_rate_3188plus,
        .set_rate = clk_pll_set_rate_3188plus,
+       .enable = clk_pll_enable_3188plus,
+       .disable = clk_pll_disable_3188plus,
+       .is_enabled = clk_pll_is_enabled_3188plus,
 };
 
 /* CLK_PLL_3188PLUS_AUTO type ops */
@@ -1003,6 +1106,9 @@ static const struct clk_ops clk_pll_ops_3188plus_auto = {
        .recalc_rate = clk_pll_recalc_rate_3188plus_auto,
        .round_rate = clk_pll_round_rate_3188plus_auto,
        .set_rate = clk_pll_set_rate_3188plus_auto,
+       .enable = clk_pll_enable_3188plus,
+       .disable = clk_pll_disable_3188plus,
+       .is_enabled = clk_pll_is_enabled_3188plus,
 };
 
 
index 5a5614d83f34dbc65e27ab70cf2639394eb10a7e..3310b50fafec3c3d3cc48c9052f36e288147f005 100755 (executable)
@@ -288,7 +288,7 @@ static unsigned cmd_line;
 
 /* The number of default descriptors */
 
-#define NR_DEFAULT_DESC        16
+#define NR_DEFAULT_DESC        32
 
 /* Populated by the PL330 core driver for DMA API driver's info */
 struct pl330_config {
@@ -2760,22 +2760,29 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
        struct dma_pl330_dmac *pdmac = pch->dmac;
        u8 *peri_id = pch->chan.private;
        struct dma_pl330_desc *desc;
+       int i = 0;
 
        /* Pluck one desc from the pool of DMAC */
        desc = pluck_desc(pdmac);
 
        /* If the DMAC pool is empty, alloc new */
        if (!desc) {
-               if (!add_desc(pdmac, GFP_ATOMIC, 1))
-                       return NULL;
+               for(i = 0; i < 3; i++) {
+                       if (!add_desc(pdmac, GFP_ATOMIC, 1))
+                               continue;
 
-               /* Try again */
-               desc = pluck_desc(pdmac);
-               if (!desc) {
-                       dev_err(pch->dmac->pif.dev,
-                               "%s:%d ALERT!\n", __func__, __LINE__);
-                       return NULL;
+                       /* Try again */
+                       desc = pluck_desc(pdmac);
+                       if (!desc) {
+                               dev_err(pch->dmac->pif.dev,
+                                       "%s:%d i=%d ALERT!\n", __func__, __LINE__,i);
+                               continue;
+                       }
+                       break;
                }
+
+               if(!desc && i >= 3)
+                       return NULL;
        }
 
        /* Initialize the descriptor */
index 061c5da0919ca4c1509e3750e2564b11937c8e88..3f64ff054538ab63a599b72ce9a2c0c3ca796522 100644 (file)
@@ -330,9 +330,9 @@ static void rockchip_i2c_set_clk(struct rockchip_i2c *i2c, unsigned long scl_rat
 static void rockchip_i2c_init_hw(struct rockchip_i2c *i2c, unsigned long scl_rate)
 {
        i2c->scl_rate = 0;
-//     clk_prepare_enable(i2c->clk);
+       clk_enable(i2c->clk);
        rockchip_i2c_set_clk(i2c, scl_rate);
-//     clk_disable_unprepare(i2c->clk);
+       clk_disable(i2c->clk);
 }
 
 /* returns TRUE if we this is the last byte in the current message */
@@ -738,7 +738,7 @@ static int rockchip_i2c_xfer(struct i2c_adapter *adap,
        struct rockchip_i2c *i2c = i2c_get_adapdata(adap);
        unsigned long scl_rate = i2c->scl_rate;
 
-//     clk_prepare_enable(i2c->clk);
+       clk_enable(i2c->clk);
        if (i2c->check_idle) {
                int state, retry = 10;
                while (retry--) {
@@ -776,7 +776,7 @@ static int rockchip_i2c_xfer(struct i2c_adapter *adap,
        ret = rockchip_i2c_doxfer(i2c, msgs, num);
        i2c_dbg(i2c->dev, "i2c transfer stop: addr: 0x%04x, state: %d, ret: %d\n", msgs[0].addr, ret, i2c->state);
 
-//     clk_disable_unprepare(i2c->clk);
+       clk_disable(i2c->clk);
        return (ret < 0) ? ret : num;
 }
 
@@ -907,7 +907,12 @@ static int rockchip_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
-       clk_prepare_enable(i2c->clk); // FIXME: enable i2c clock temporarily
+       ret = clk_prepare(i2c->clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Could not prepare clock\n");
+               return ret;
+       }
+
        i2c->i2c_rate = clk_get_rate(i2c->clk);
 
        rockchip_i2c_init_hw(i2c, 100 * 1000);
@@ -928,6 +933,7 @@ static int rockchip_i2c_remove(struct platform_device *pdev)
        struct rockchip_i2c *i2c = platform_get_drvdata(pdev);
 
        i2c_del_adapter(&i2c->adap);
+       clk_unprepare(i2c->clk);
 
        return 0;
 }
index 256f036da4a95882ec57c2739189f92fcca34e6f..974903cc511d257d4f0413f8c47451843a3e65e7 100755 (executable)
@@ -120,6 +120,9 @@ static int rk_read_raw(struct iio_dev *indio_dev,
 
        INIT_COMPLETION(info->completion);
 
+       clk_enable(info->clk);
+       clk_enable(info->pclk);
+
         /* Select the channel to be used and Trigger conversion */
         writel_relaxed(0x08, info->regs + ADC_DELAY_PU_SOC);
        writel_relaxed(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chan->channel)|ADC_CTRL_IRQ_ENABLE, info->regs + ADC_CTRL);
@@ -137,6 +140,9 @@ static int rk_read_raw(struct iio_dev *indio_dev,
                ret = -ETIMEDOUT;
        }
 
+       clk_disable(info->clk);
+       clk_disable(info->pclk);
+
        mutex_unlock(&indio_dev->mlock);
 
        return ret;
@@ -166,8 +172,14 @@ static int rk_adc_reg_access(struct iio_dev *indio_dev,
        if (readval == NULL)
                return -EINVAL;
 
+       clk_enable(info->clk);
+       clk_enable(info->pclk);
+
        *readval = readl_relaxed(info->regs + reg);
 
+       clk_disable(info->clk);
+       clk_disable(info->pclk);
+
        return 0;
 }
 
@@ -190,7 +202,7 @@ static const struct iio_chan_spec rk_adc_iio_channels[] = {
        ADC_CHANNEL(0, "adc0"),
        ADC_CHANNEL(1, "adc1"),
        ADC_CHANNEL(2, "adc2"),
-       ADC_CHANNEL(3, "adc3"),
+       ADC_CHANNEL(6, "adc6"),
 };
 
 static int rk_adc_remove_devices(struct device *dev, void *c)
@@ -255,7 +267,7 @@ static int rk_adc_probe(struct platform_device *pdev)
            ret = PTR_ERR(info->pclk);
            goto err_iio;
        }
-       clk_prepare_enable(info->pclk);
+       clk_prepare(info->pclk);
        
        info->clk = devm_clk_get(&pdev->dev, "saradc");
        if (IS_ERR(info->clk)) {
@@ -274,7 +286,7 @@ static int rk_adc_probe(struct platform_device *pdev)
            dev_err(&pdev->dev, "failed to set adc clk\n");
            goto err_pclk;
        }
-       clk_prepare_enable(info->clk);
+       clk_prepare(info->clk);
 
     //device register
        indio_dev->name = dev_name(&pdev->dev);
@@ -310,10 +322,10 @@ err_iio_dev:
        iio_device_unregister(indio_dev);
        
 err_clk:
-       clk_disable_unprepare(info->clk);
+       clk_unprepare(info->clk);
 
 err_pclk:
-       clk_disable_unprepare(info->pclk);
+       clk_unprepare(info->pclk);
        
 err_iio:
        iio_device_free(indio_dev);
@@ -327,8 +339,8 @@ static int rk_adc_remove(struct platform_device *pdev)
 
        device_for_each_child(&pdev->dev, NULL,
                                rk_adc_remove_devices);
-       clk_disable_unprepare(info->clk);
-       clk_disable_unprepare(info->pclk);
+       clk_unprepare(info->clk);
+       clk_unprepare(info->pclk);
        iio_device_unregister(indio_dev);
        free_irq(info->irq, info);
        iio_device_free(indio_dev);
index 871de6584f48cb30c8c9cdba5ef8e93d70741e49..d474bed30e821336b07d32d4a51442bdd81b257b 100755 (executable)
@@ -527,7 +527,7 @@ static int rk_pwm_probe(struct platform_device *pdev)
        cpumask_set_cpu(cpu_id, &cpumask);
        irq_set_affinity(irq, &cpumask);
        ret = devm_request_irq(&pdev->dev, irq, rockchip_pwm_irq,
-                              0, "rk_pwm_irq", ddata);
+                              IRQF_NO_SUSPEND, "rk_pwm_irq", ddata);
        if (ret) {
                dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq);
                return ret;
index b5a815cb1d889a82f7c6659fe84b959840bc0e8a..308ef650bdb6e6c83fa225e193ccc8d1f590adf6 100755 (executable)
@@ -49,35 +49,30 @@ enum iommu_entry_flags {
        IOMMU_FLAGS_MASK = 0x1FF,
 };
 
-#define lv1ent_fault(sent) ((*(sent) & IOMMU_FLAGS_PRESENT) == 0)
-#define lv1ent_page(sent) ((*(sent) & IOMMU_FLAGS_PRESENT) == 1)
-#define lv2ent_fault(pent) ((*(pent) & IOMMU_FLAGS_PRESENT) == 0)
-#define spage_phys(pent) (*(pent) & SPAGE_MASK)
-#define spage_offs(iova) ((iova) & 0x0FFF)
+#define rockchip_lv1ent_fault(sent) ((*(sent) & IOMMU_FLAGS_PRESENT) == 0)
+#define rockchip_lv1ent_page(sent) ((*(sent) & IOMMU_FLAGS_PRESENT) == 1)
+#define rockchip_lv2ent_fault(pent) ((*(pent) & IOMMU_FLAGS_PRESENT) == 0)
+#define rockchip_spage_phys(pent) (*(pent) & SPAGE_MASK)
+#define rockchip_spage_offs(iova) ((iova) & 0x0FFF)
 
-#define lv1ent_offset(iova) (((iova)>>22) & 0x03FF)
-#define lv2ent_offset(iova) (((iova)>>12) & 0x03FF)
+#define rockchip_lv1ent_offset(iova) (((iova)>>22) & 0x03FF)
+#define rockchip_lv2ent_offset(iova) (((iova)>>12) & 0x03FF)
 
 #define NUM_LV1ENTRIES 1024
 #define NUM_LV2ENTRIES 1024
 
 #define LV2TABLE_SIZE (NUM_LV2ENTRIES * sizeof(long))
 
-#define lv2table_base(sent) (*(sent) & 0xFFFFFFFE)
+#define rockchip_lv2table_base(sent) (*(sent) & 0xFFFFFFFE)
 
-#define mk_lv1ent_page(pa) ((pa) | IOMMU_FLAGS_PRESENT)
+#define rockchip_mk_lv1ent_page(pa) ((pa) | IOMMU_FLAGS_PRESENT)
 /*write and read permission for level2 page default*/
-#define mk_lv2ent_spage(pa) ((pa) | IOMMU_FLAGS_PRESENT | \
+#define rockchip_mk_lv2ent_spage(pa) ((pa) | IOMMU_FLAGS_PRESENT | \
                             IOMMU_FLAGS_READ_PERMISSION | \
                             IOMMU_FLAGS_WRITE_PERMISSION)
 
 #define IOMMU_REG_POLL_COUNT_FAST 1000
 
-/*rk3036:vpu and hevc share ahb interface*/
-#define BIT_VCODEC_SEL_3036 (1<<3)
-#define BIT_VCODEC_SEL_312x (1<<15)
-
-
 /**
  * MMU register numbers
  * Used in the register read/write routines.
@@ -175,46 +170,17 @@ enum iommu_status_bits {
 
 static struct kmem_cache *lv2table_kmem_cache;
 
-static void rockchip_vcodec_select(const char *string)
-{
-       if (strstr(string,"hevc")) {
-               if (cpu_is_rk3036()) {
-                       writel_relaxed(readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_CON1) |
-                             (BIT_VCODEC_SEL_3036) | (BIT_VCODEC_SEL_3036 << 16),
-                             RK_GRF_VIRT + RK3036_GRF_SOC_CON1);
-               } else {
-                       writel_relaxed(readl_relaxed(RK_GRF_VIRT + RK312X_GRF_SOC_CON1) |
-                             (BIT_VCODEC_SEL_312x) | (BIT_VCODEC_SEL_312x << 16),
-                             RK_GRF_VIRT + RK312X_GRF_SOC_CON1);
-               }
-       } else if (strstr(string,"vpu")) {
-               if (cpu_is_rk3036()) {
-                       writel_relaxed((readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_CON1) &
-                              (~BIT_VCODEC_SEL_3036)) | (BIT_VCODEC_SEL_3036 << 16),
-                              RK_GRF_VIRT + RK3036_GRF_SOC_CON1);
-               } else {
-                       writel_relaxed((readl_relaxed(RK_GRF_VIRT + RK312X_GRF_SOC_CON1) &
-                              (~BIT_VCODEC_SEL_312x)) | (BIT_VCODEC_SEL_312x << 16),
-                              RK_GRF_VIRT + RK312X_GRF_SOC_CON1);
-               }
-       }
-}
-static unsigned long *section_entry(unsigned long *pgtable, unsigned long iova)
+static unsigned long *rockchip_section_entry(unsigned long *pgtable, unsigned long iova)
 {
-       return pgtable + lv1ent_offset(iova);
+       return pgtable + rockchip_lv1ent_offset(iova);
 }
 
-static unsigned long *page_entry(unsigned long *sent, unsigned long iova)
+static unsigned long *rockchip_page_entry(unsigned long *sent, unsigned long iova)
 {
-       return (unsigned long *)__va(lv2table_base(sent)) + lv2ent_offset(iova);
+       return (unsigned long *)__va(rockchip_lv2table_base(sent)) +
+               rockchip_lv2ent_offset(iova);
 }
 
-static char *iommu_fault_name[IOMMU_FAULTS_NUM] = {
-       "PAGE FAULT",
-       "BUS ERROR",
-       "UNKNOWN FAULT"
-};
-
 struct rk_iommu_domain {
        struct list_head clients; /* list of iommu_drvdata.node */
        unsigned long *pgtable; /* lv1 page table, 4KB */
@@ -223,26 +189,26 @@ struct rk_iommu_domain {
        spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
 };
 
-static bool set_iommu_active(struct iommu_drvdata *data)
+static bool rockchip_set_iommu_active(struct iommu_drvdata *data)
 {
        /* return true if the IOMMU was not active previously
           and it needs to be initialized */
        return ++data->activations == 1;
 }
 
-static bool set_iommu_inactive(struct iommu_drvdata *data)
+static bool rockchip_set_iommu_inactive(struct iommu_drvdata *data)
 {
        /* return true if the IOMMU is needed to be disabled */
        BUG_ON(data->activations < 1);
        return --data->activations == 0;
 }
 
-static bool is_iommu_active(struct iommu_drvdata *data)
+static bool rockchip_is_iommu_active(struct iommu_drvdata *data)
 {
        return data->activations > 0;
 }
 
-static void iommu_disable_stall(void __iomem *base)
+static void rockchip_iommu_disable_stall(void __iomem *base)
 {
        int i;
        u32 mmu_status;
@@ -252,15 +218,22 @@ static void iommu_disable_stall(void __iomem *base)
        } else {
                goto skip_vop_mmu_disable;
        }
-       if (0 == (mmu_status & IOMMU_STATUS_BIT_PAGING_ENABLED))
+
+       if (0 == (mmu_status & IOMMU_STATUS_BIT_PAGING_ENABLED)) {
                return;
+       }
+
        if (mmu_status & IOMMU_STATUS_BIT_PAGE_FAULT_ACTIVE) {
                pr_info("Aborting MMU disable stall request since it is in pagefault state.\n");
                return;
        }
+
+       if (!(mmu_status & IOMMU_STATUS_BIT_STALL_ACTIVE)) {
+               return;
+       }
+
        skip_vop_mmu_disable:
-       __raw_writel(IOMMU_COMMAND_DISABLE_STALL,
-                    base + IOMMU_REGISTER_COMMAND);
+       __raw_writel(IOMMU_COMMAND_DISABLE_STALL, base + IOMMU_REGISTER_COMMAND);
 
        for (i = 0; i < IOMMU_REG_POLL_COUNT_FAST; ++i) {
                u32 status;
@@ -273,20 +246,24 @@ static void iommu_disable_stall(void __iomem *base)
                                j++;
                        return; 
                }
+
                if (0 == (status & IOMMU_STATUS_BIT_STALL_ACTIVE))
                        break;
+
                if (status & IOMMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
                        break;
+
                if (0 == (mmu_status & IOMMU_STATUS_BIT_PAGING_ENABLED))
                        break;
        }
+
        if (IOMMU_REG_POLL_COUNT_FAST == i) {
                pr_info("Disable stall request failed, MMU status is 0x%08X\n",
                      __raw_readl(base + IOMMU_REGISTER_STATUS));
        }
 }
 
-static bool iommu_enable_stall(void __iomem *base)
+static bool rockchip_iommu_enable_stall(void __iomem *base)
 {
        int i;
 
@@ -297,15 +274,24 @@ static bool iommu_enable_stall(void __iomem *base)
        } else {
                goto skip_vop_mmu_enable;
        }
-       if (0 == (mmu_status & IOMMU_STATUS_BIT_PAGING_ENABLED))
+
+       if (0 == (mmu_status & IOMMU_STATUS_BIT_PAGING_ENABLED)) {
+               return true;
+       }
+
+       if (mmu_status & IOMMU_STATUS_BIT_STALL_ACTIVE){
+               pr_info("MMU stall already enabled\n");
                return true;
+       }
+
        if (mmu_status & IOMMU_STATUS_BIT_PAGE_FAULT_ACTIVE) {
-               pr_info("Aborting MMU stall request since it is in pagefault state.\n");
+               pr_info("Aborting MMU stall request since it is in pagefault state. mmu status is 0x%08x\n",
+                       mmu_status);
                return false;
        }
+
        skip_vop_mmu_enable:
-       __raw_writel(IOMMU_COMMAND_ENABLE_STALL,
-                    base + IOMMU_REGISTER_COMMAND);
+       __raw_writel(IOMMU_COMMAND_ENABLE_STALL, base + IOMMU_REGISTER_COMMAND);
 
        for (i = 0; i < IOMMU_REG_POLL_COUNT_FAST; ++i) {
                if (base != rk312x_vop_mmu_base) {
@@ -316,27 +302,33 @@ static bool iommu_enable_stall(void __iomem *base)
                                j++;
                        return true;
                }
+
                if (mmu_status & IOMMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
                        break;
+
                if ((mmu_status & IOMMU_STATUS_BIT_STALL_ACTIVE) &&
                    (0 == (mmu_status & IOMMU_STATUS_BIT_STALL_NOT_ACTIVE)))
                        break;
+
                if (0 == (mmu_status & (IOMMU_STATUS_BIT_PAGING_ENABLED)))
                        break;
        }
+
        if (IOMMU_REG_POLL_COUNT_FAST == i) {
                pr_info("Enable stall request failed, MMU status is 0x%08X\n",
                       __raw_readl(base + IOMMU_REGISTER_STATUS));
                return false;
        }
+
        if (mmu_status & IOMMU_STATUS_BIT_PAGE_FAULT_ACTIVE) {
                pr_info("Aborting MMU stall request since it has a pagefault.\n");
                return false;
        }
+
        return true;
 }
 
-static bool iommu_enable_paging(void __iomem *base)
+static bool rockchip_iommu_enable_paging(void __iomem *base)
 {
        int i;
 
@@ -355,15 +347,17 @@ static bool iommu_enable_paging(void __iomem *base)
                        return true;
                }
        }
+
        if (IOMMU_REG_POLL_COUNT_FAST == i) {
                pr_info("Enable paging request failed, MMU status is 0x%08X\n",
                       __raw_readl(base + IOMMU_REGISTER_STATUS));
                return false;
        }
+
        return true;
 }
 
-static bool iommu_disable_paging(void __iomem *base)
+static bool rockchip_iommu_disable_paging(void __iomem *base)
 {
        int i;
 
@@ -382,55 +376,61 @@ static bool iommu_disable_paging(void __iomem *base)
                        return true;
                }
        }
+
        if (IOMMU_REG_POLL_COUNT_FAST == i) {
                pr_info("Disable paging request failed, MMU status is 0x%08X\n",
                       __raw_readl(base + IOMMU_REGISTER_STATUS));
                return false;
        }
+
        return true;
 }
 
-static void iommu_page_fault_done(void __iomem *base, const char *dbgname)
+static void rockchip_iommu_page_fault_done(void __iomem *base, const char *dbgname)
 {
        pr_info("MMU: %s: Leaving page fault mode\n",
                dbgname);
        __raw_writel(IOMMU_COMMAND_PAGE_FAULT_DONE,
                     base + IOMMU_REGISTER_COMMAND);
 }
-
-static bool iommu_zap_tlb(void __iomem *base)
+#if 1
+static int rockchip_iommu_zap_tlb_without_stall (void __iomem *base)
 {
-       bool stall_success;
+       __raw_writel(IOMMU_COMMAND_ZAP_CACHE, base + IOMMU_REGISTER_COMMAND);
 
-       if (rk312x_vop_mmu_base != base)
-               stall_success = iommu_enable_stall(base);
-       else
-               stall_success = true;
+       return 0;
+}
+#endif
 
-       __raw_writel(IOMMU_COMMAND_ZAP_CACHE,
-                    base + IOMMU_REGISTER_COMMAND);
-       if (!stall_success)
-               return false;
+#if 0
+static int rockchip_iommu_zap_tlb(void __iomem *base)
+{
+       if (!rockchip_iommu_enable_stall(base)) {
+               pr_err("%s failed\n", __func__);
+               return -1;
+       }
 
-       if (rk312x_vop_mmu_base != base)
-               iommu_disable_stall(base);
-       else
-               return true;
+       __raw_writel(IOMMU_COMMAND_ZAP_CACHE, base + IOMMU_REGISTER_COMMAND);
 
-       return true;
+       rockchip_iommu_disable_stall(base);
+
+       return 0;
 }
-extern bool __clk_is_enabled(struct clk *clk);
-static inline bool iommu_raw_reset(void __iomem *base)
+#endif
+
+static inline bool rockchip_iommu_raw_reset(void __iomem *base)
 {
        int i;
        unsigned int ret;
+       unsigned int grf_value;
 
        __raw_writel(0xCAFEBABE, base + IOMMU_REGISTER_DTE_ADDR);
 
        if (base != rk312x_vop_mmu_base) {
                ret = __raw_readl(base + IOMMU_REGISTER_DTE_ADDR);
                if (!(0xCAFEB000 == ret)) {
-                       pr_info("error when %s.\n", __func__);
+                       grf_value = readl_relaxed(RK_GRF_VIRT + RK3036_GRF_SOC_CON1);
+                       pr_info("error when %s. grf = 0x%08x\n", __func__, grf_value);
                        return false;
                }
        }
@@ -448,6 +448,7 @@ static inline bool iommu_raw_reset(void __iomem *base)
                        return true;
                }
        }
+
        if (IOMMU_REG_POLL_COUNT_FAST == i) {
                pr_info("%s,Reset request failed, MMU status is 0x%08X\n",
                       __func__, __raw_readl(base + IOMMU_REGISTER_DTE_ADDR));
@@ -456,36 +457,32 @@ static inline bool iommu_raw_reset(void __iomem *base)
        return true;
 }
 
-static void __iommu_set_ptbase(void __iomem *base, unsigned long pgd)
+static void rockchip_iommu_set_ptbase(void __iomem *base, unsigned long pgd)
 {
        __raw_writel(pgd, base + IOMMU_REGISTER_DTE_ADDR);
 }
 
-static bool iommu_reset(void __iomem *base, const char *dbgname)
+static bool rockchip_iommu_reset(void __iomem *base, const char *dbgname)
 {
-       bool err = true;
+       bool ret = true;
 
-       err = iommu_enable_stall(base);
-       if (!err) {
-               pr_info("%s:stall failed: %s\n", __func__, dbgname);
-               return err;
+       ret = rockchip_iommu_raw_reset(base);
+       if (!ret) {
+               pr_info("(%s), %s failed\n", dbgname, __func__);
+               return ret;
        }
-       err = iommu_raw_reset(base);
-       if (err) {
-               if (base != rk312x_vop_mmu_base)
-                       __raw_writel(IOMMU_INTERRUPT_PAGE_FAULT |
+
+       if (base != rk312x_vop_mmu_base)
+               __raw_writel(IOMMU_INTERRUPT_PAGE_FAULT |
                             IOMMU_INTERRUPT_READ_BUS_ERROR,
-                            base+IOMMU_REGISTER_INT_MASK);
-               else
-                       __raw_writel(0x00, base + IOMMU_REGISTER_INT_MASK);
-       }
-       iommu_disable_stall(base);
-       if (!err)
-               pr_info("%s: failed: %s\n", __func__, dbgname);
-       return err;
+                            base + IOMMU_REGISTER_INT_MASK);
+       else
+               __raw_writel(0x00, base + IOMMU_REGISTER_INT_MASK);
+
+       return ret;
 }
 
-static inline void pgtable_flush(void *vastart, void *vaend)
+static inline void rockchip_pgtable_flush(void *vastart, void *vaend)
 {
 #ifdef CONFIG_ARM
        dmac_flush_range(vastart, vaend);
@@ -495,212 +492,191 @@ static inline void pgtable_flush(void *vastart, void *vaend)
 #endif
 }
 
-static void set_fault_handler(struct iommu_drvdata *data,
-                               rockchip_iommu_fault_handler_t handler)
+static void dump_pagetbl(dma_addr_t fault_address, u32 addr_dte)
 {
-       unsigned long flags;
-
-       write_lock_irqsave(&data->lock, flags);
-       data->fault_handler = handler;
-       write_unlock_irqrestore(&data->lock, flags);
+       u32 dte_index, pte_index, page_offset;
+       u32 mmu_dte_addr;
+       phys_addr_t mmu_dte_addr_phys, dte_addr_phys;
+       u32 *dte_addr;
+       u32 dte;
+       phys_addr_t pte_addr_phys = 0;
+       u32 *pte_addr = NULL;
+       u32 pte = 0;
+       phys_addr_t page_addr_phys = 0;
+       u32 page_flags = 0;
+
+       dte_index = rockchip_lv1ent_offset(fault_address);
+       pte_index = rockchip_lv2ent_offset(fault_address);
+       page_offset = (u32)(fault_address & 0x00000fff);
+
+       mmu_dte_addr = addr_dte;
+       mmu_dte_addr_phys = (phys_addr_t)mmu_dte_addr;
+
+       dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index);
+       dte_addr = phys_to_virt(dte_addr_phys);
+       dte = *dte_addr;
+
+       if (!(IOMMU_FLAGS_PRESENT & dte))
+               goto print_it;
+
+       pte_addr_phys = ((phys_addr_t)dte & 0xfffff000) + (pte_index * 4);
+       pte_addr = phys_to_virt(pte_addr_phys);
+       pte = *pte_addr;
+
+       if (!(IOMMU_FLAGS_PRESENT & pte))
+               goto print_it;
+
+       page_addr_phys = ((phys_addr_t)pte & 0xfffff000) + page_offset;
+       page_flags = pte & 0x000001fe;
+
+print_it:
+       pr_err("iova = %pad: dte_index: 0x%03x pte_index: 0x%03x page_offset: 0x%03x\n",
+               &fault_address, dte_index, pte_index, page_offset);
+       pr_err("mmu_dte_addr: %pa dte@%pa: %#08x valid: %u pte@%pa: %#08x valid: %u page@%pa flags: %#03x\n",
+               &mmu_dte_addr_phys, &dte_addr_phys, dte,
+               (dte & IOMMU_FLAGS_PRESENT), &pte_addr_phys, pte,
+               (pte & IOMMU_FLAGS_PRESENT), &page_addr_phys, page_flags);
 }
 
-static int default_fault_handler(struct device *dev,
-                                enum rk_iommu_inttype itype,
-                                unsigned long pgtable_base,
-                                unsigned long fault_addr,
-                                unsigned int status)
+static irqreturn_t rockchip_iommu_irq(int irq, void *dev_id)
 {
-       struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
+       /* SYSMMU is in blocked when interrupt occurred. */
+       struct iommu_drvdata *data = dev_id;
+       u32 status;
+       u32 rawstat;
+       dma_addr_t fault_address;
+       int i;
+       unsigned long flags;
+       int ret;
+       u32 reg_status;
 
-       if (!data) {
-               dev_err(dev->archdata.iommu,"%s,iommu device not assigned yet\n", __func__);
-               return 0;
+       spin_lock_irqsave(&data->data_lock, flags);
+
+       if (!rockchip_is_iommu_active(data)) {
+               spin_unlock_irqrestore(&data->data_lock, flags);
+               return IRQ_HANDLED;
        }
-       if ((itype >= IOMMU_FAULTS_NUM) || (itype < IOMMU_PAGEFAULT))
-               itype = IOMMU_FAULT_UNKNOWN;
 
-       if (itype == IOMMU_BUSERROR)
-               dev_err(dev->archdata.iommu,"%s occured at 0x%lx(Page table base: 0x%lx)\n",
-                      iommu_fault_name[itype], fault_addr, pgtable_base);
+       for (i = 0; i < data->num_res_mem; i++) {
+               status = __raw_readl(data->res_bases[i] +
+                                    IOMMU_REGISTER_INT_STATUS);
+               if (status == 0)
+                       continue;
 
-       if (itype == IOMMU_PAGEFAULT)
-               dev_err(dev->archdata.iommu,"IOMMU:Page fault detected at 0x%lx from bus id %d of type %s on %s\n",
-                      fault_addr,
-                      (status >> 6) & 0x1F,
-                      (status & 32) ? "write" : "read",
-                      data->dbgname);
+               rawstat = __raw_readl(data->res_bases[i] +
+                                     IOMMU_REGISTER_INT_RAWSTAT);
 
-       dev_err(dev->archdata.iommu,"Generating Kernel OOPS... because it is unrecoverable.\n");
+               reg_status = __raw_readl(data->res_bases[i] +
+                                        IOMMU_REGISTER_STATUS);
 
-       BUG();
+               dev_info(data->iommu, "1.rawstat = 0x%08x,status = 0x%08x,reg_status = 0x%08x\n",
+                        rawstat, status, reg_status);
 
-       return 0;
-}
+               if (rawstat & IOMMU_INTERRUPT_PAGE_FAULT) {
+                       u32 dte;
+                       int flags;
 
-static void dump_pagetbl(u32 fault_address, u32 addr_dte)
-{
-       u32 lv1_offset;
-       u32 lv2_offset;
-
-       u32 *lv1_entry_pa;
-       u32 *lv1_entry_va;
-       u32 *lv1_entry_value;
-
-       u32 *lv2_base;
-       u32 *lv2_entry_pa;
-       u32 *lv2_entry_va;
-       u32 *lv2_entry_value;
-
-
-       lv1_offset = lv1ent_offset(fault_address);
-       lv2_offset = lv2ent_offset(fault_address);
-
-       lv1_entry_pa = (u32 *)addr_dte + lv1_offset;
-       lv1_entry_va = (u32 *)(__va(addr_dte)) + lv1_offset;
-       lv1_entry_value = (u32 *)(*lv1_entry_va);
-
-       lv2_base = (u32 *)((*lv1_entry_va) & 0xfffffffe);
-       lv2_entry_pa = (u32 *)lv2_base + lv2_offset;
-       lv2_entry_va = (u32 *)(__va(lv2_base)) + lv2_offset;
-       lv2_entry_value = (u32 *)(*lv2_entry_va);
-
-       dev_info(NULL,"fault address = 0x%08x,dte addr pa = 0x%08x,va = 0x%08x\n",
-               fault_address, addr_dte, (u32)__va(addr_dte));
-       dev_info(NULL,"lv1_offset = 0x%x,lv1_entry_pa = 0x%08x,lv1_entry_va = 0x%08x\n",
-               lv1_offset, (u32)lv1_entry_pa, (u32)lv1_entry_va);
-       dev_info(NULL,"lv1_entry_value(*lv1_entry_va) = 0x%08x,lv2_base = 0x%08x\n",
-               (u32)lv1_entry_value, (u32)lv2_base);
-       dev_info(NULL,"lv2_offset = 0x%x,lv2_entry_pa = 0x%08x,lv2_entry_va = 0x%08x\n",
-               lv2_offset, (u32)lv2_entry_pa, (u32)lv2_entry_va);
-       dev_info(NULL,"lv2_entry value(*lv2_entry_va) = 0x%08x\n",
-               (u32)lv2_entry_value);
-}
+                       fault_address = __raw_readl(data->res_bases[i] +
+                                           IOMMU_REGISTER_PAGE_FAULT_ADDR);
 
-static irqreturn_t rockchip_iommu_irq(int irq, void *dev_id)
-{
-       /* SYSMMU is in blocked when interrupt occurred. */
-       struct iommu_drvdata *data = dev_id;
-       struct resource *irqres;
-       struct platform_device *pdev;
-       enum rk_iommu_inttype itype = IOMMU_FAULT_UNKNOWN;
-       u32 status;
-       u32 rawstat;
-       u32 int_status;
-       u32 fault_address;
-       int i, ret = 0;
+                       dte = __raw_readl(data->res_bases[i] +
+                                         IOMMU_REGISTER_DTE_ADDR);
 
-       read_lock(&data->lock);
+                       flags = (status & 32) ? 1 : 0;
 
-       if (!is_iommu_active(data)) {
-               read_unlock(&data->lock);
-               return IRQ_HANDLED;
-       }
-       
-       if(cpu_is_rk312x() || cpu_is_rk3036())
-               rockchip_vcodec_select(data->dbgname);
-       
-       pdev = to_platform_device(data->iommu);
+                       dev_err(data->iommu, "Page fault detected at %pad from bus id %d of type %s on %s\n",
+                               &fault_address, (status >> 6) & 0x1F,
+                               (flags == 1) ? "write" : "read", data->dbgname);
 
-       for (i = 0; i < data->num_res_irq; i++) {
-               irqres = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-               if (irqres && ((int)irqres->start == irq)) {
-                       if (data->res_bases[i] == rk312x_vop_mmu_base) {
-                               read_unlock(&data->lock);
-                               return IRQ_HANDLED;
-                       }
-                       break;
+                       dump_pagetbl(fault_address, dte);
+
+                       if (data->domain)
+                               report_iommu_fault(data->domain, data->iommu,
+                                                  fault_address, flags);
+
+                       rockchip_iommu_page_fault_done(data->res_bases[i],
+                                                      data->dbgname);
                }
-       }
 
-       if (i == data->num_res_irq) {
-               itype = IOMMU_FAULT_UNKNOWN;
-       } else {
-               int_status = __raw_readl(data->res_bases[i] +
-                                        IOMMU_REGISTER_INT_STATUS);
-
-               if (int_status != 0) {
-                       /*mask status*/
-                       __raw_writel(0x00, data->res_bases[i] +
-                                    IOMMU_REGISTER_INT_MASK);
-
-                       rawstat = __raw_readl(data->res_bases[i] +
-                                             IOMMU_REGISTER_INT_RAWSTAT);
-
-                       if (rawstat & IOMMU_INTERRUPT_PAGE_FAULT) {
-                               fault_address = __raw_readl(data->res_bases[i] +
-                               IOMMU_REGISTER_PAGE_FAULT_ADDR);
-                               itype = IOMMU_PAGEFAULT;
-                       } else if (rawstat & IOMMU_INTERRUPT_READ_BUS_ERROR) {
-                               itype = IOMMU_BUSERROR;
-                       } else {
-                               goto out;
-                       }
-                       dump_pagetbl(fault_address,
-                                    __raw_readl(data->res_bases[i] +
-                                    IOMMU_REGISTER_DTE_ADDR));
-               } else {
-                       goto out;
+               if (rawstat & IOMMU_INTERRUPT_READ_BUS_ERROR) {
+                       dev_err(data->iommu, "bus error occured at %pad\n",
+                               &fault_address);
                }
-       }
 
-       if (data->fault_handler) {
-               unsigned long base = __raw_readl(data->res_bases[i] +
-                                                IOMMU_REGISTER_DTE_ADDR);
+               if (rawstat & ~(IOMMU_INTERRUPT_READ_BUS_ERROR |
+                   IOMMU_INTERRUPT_PAGE_FAULT)) {
+                       dev_err(data->iommu, "unexpected int_status: %#08x\n\n",
+                               rawstat);
+               }
+
+               __raw_writel(rawstat, data->res_bases[i] +
+                            IOMMU_REGISTER_INT_CLEAR);
+
                status = __raw_readl(data->res_bases[i] +
-                                    IOMMU_REGISTER_STATUS);
-               ret = data->fault_handler(data->dev, itype, base,
-                                         fault_address, status);
-       }
+                                    IOMMU_REGISTER_INT_STATUS);
 
-       if (!ret && (itype != IOMMU_FAULT_UNKNOWN)) {
-               if (IOMMU_PAGEFAULT == itype) {
-                       iommu_zap_tlb(data->res_bases[i]);
-                       iommu_page_fault_done(data->res_bases[i],
-                                              data->dbgname);
-                       __raw_writel(IOMMU_INTERRUPT_PAGE_FAULT |
-                                    IOMMU_INTERRUPT_READ_BUS_ERROR,
-                                    data->res_bases[i] +
-                                    IOMMU_REGISTER_INT_MASK);
-               }
-       } else {
-               dev_err(data->iommu,"(%s) %s is not handled.\n",
-                      data->dbgname, iommu_fault_name[itype]);
-       }
+               rawstat = __raw_readl(data->res_bases[i] +
+                                     IOMMU_REGISTER_INT_RAWSTAT);
+
+               reg_status = __raw_readl(data->res_bases[i] +
+                                        IOMMU_REGISTER_STATUS);
 
-out:
-       read_unlock(&data->lock);
+               dev_info(data->iommu, "2.rawstat = 0x%08x,status = 0x%08x,reg_status = 0x%08x\n",
+                        rawstat, status, reg_status);
 
+               ret = rockchip_iommu_zap_tlb_without_stall(data->res_bases[i]);
+               if (ret)
+                       dev_err(data->iommu, "(%s) %s failed\n", data->dbgname,
+                               __func__);
+       }
+
+       spin_unlock_irqrestore(&data->data_lock, flags);
        return IRQ_HANDLED;
 }
 
-static bool __rockchip_iommu_disable(struct iommu_drvdata *data)
+static bool rockchip_iommu_disable(struct iommu_drvdata *data)
 {
        unsigned long flags;
        int i;
-       bool disabled = false;
+       bool ret = false;
+
+       spin_lock_irqsave(&data->data_lock, flags);
+
+       if (!rockchip_set_iommu_inactive(data)) {
+               spin_unlock_irqrestore(&data->data_lock, flags);
+               dev_info(data->iommu,"(%s) %d times left to be disabled\n",
+                        data->dbgname, data->activations);
+               return ret;
+       }
 
-       write_lock_irqsave(&data->lock, flags);
+       for (i = 0; i < data->num_res_mem; i++) {
+               ret = rockchip_iommu_enable_stall(data->res_bases[i]);
+               if (!ret) {
+                       dev_info(data->iommu, "(%s), %s failed\n",
+                                data->dbgname, __func__);
+                       spin_unlock_irqrestore(&data->data_lock, flags);
+                       return false;
+               }
 
-       if (!set_iommu_inactive(data))
-               goto finish;
+               __raw_writel(0, data->res_bases[i] + IOMMU_REGISTER_INT_MASK);
 
-       for (i = 0; i < data->num_res_mem; i++)
-               iommu_disable_paging(data->res_bases[i]);
+               ret = rockchip_iommu_disable_paging(data->res_bases[i]);
+               if (!ret) {
+                       rockchip_iommu_disable_stall(data->res_bases[i]);
+                       spin_unlock_irqrestore(&data->data_lock, flags);
+                       dev_info(data->iommu, "%s error\n", __func__);
+                       return ret;
+               }
+               rockchip_iommu_disable_stall(data->res_bases[i]);
+       }
 
-       disabled = true;
        data->pgtable = 0;
-       data->domain = NULL;
-finish:
-       write_unlock_irqrestore(&data->lock, flags);
 
-       if (disabled)
-               dev_info(data->iommu,"(%s) Disabled\n", data->dbgname);
-       else
-               dev_info(data->iommu,"(%s) %d times left to be disabled\n",
-                       data->dbgname, data->activations);
+       spin_unlock_irqrestore(&data->data_lock, flags);
+
+       dev_info(data->iommu,"(%s) Disabled\n", data->dbgname);
 
-       return disabled;
+       return ret;
 }
 
 /* __rk_sysmmu_enable: Enables System MMU
@@ -709,89 +685,102 @@ finish:
  * 0 if the System MMU has been just enabled and 1 if System MMU was already
  * enabled before.
  */
-static int __rockchip_iommu_enable(struct iommu_drvdata *data,
-                                   unsigned long pgtable,
-                                   struct iommu_domain *domain)
+static int rockchip_iommu_enable(struct iommu_drvdata *data, unsigned long pgtable)
 {
        int i, ret = 0;
        unsigned long flags;
 
-       write_lock_irqsave(&data->lock, flags);
+       spin_lock_irqsave(&data->data_lock, flags);
 
-       if (!set_iommu_active(data)) {
+       if (!rockchip_set_iommu_active(data)) {
                if (WARN_ON(pgtable != data->pgtable)) {
                        ret = -EBUSY;
-                       set_iommu_inactive(data);
+                       rockchip_set_iommu_inactive(data);
                } else {
                        ret = 1;
                }
 
-               dev_info(data->iommu,"(%s) Already enabled\n", data->dbgname);
-               goto finish;
-       }
+               spin_unlock_irqrestore(&data->data_lock, flags);
+               dev_info(data->iommu, "(%s) Already enabled\n", data->dbgname);
 
-       data->pgtable = pgtable;
+               return ret;
+       }
 
        for (i = 0; i < data->num_res_mem; i++) {
-               bool status;
-
-               status = iommu_enable_stall(data->res_bases[i]);
-               if (status) {
-                       __iommu_set_ptbase(data->res_bases[i], pgtable);
-                       __raw_writel(IOMMU_COMMAND_ZAP_CACHE,
-                                    data->res_bases[i] +
-                                    IOMMU_REGISTER_COMMAND);
+               ret = rockchip_iommu_enable_stall(data->res_bases[i]);
+               if (!ret) {
+                       dev_info(data->iommu, "(%s), %s failed\n",
+                                data->dbgname, __func__);
+                       spin_unlock_irqrestore(&data->data_lock, flags);
+                       return -EBUSY;
                }
+
+               if (!strstr(data->dbgname, "isp")) {
+                       if (!rockchip_iommu_reset(data->res_bases[i],
+                            data->dbgname)) {
+                               spin_unlock_irqrestore(&data->data_lock, flags);
+                               return -ENOENT;
+                       }
+               }
+
+               rockchip_iommu_set_ptbase(data->res_bases[i], pgtable);
+
+               __raw_writel(IOMMU_COMMAND_ZAP_CACHE, data->res_bases[i] +
+                            IOMMU_REGISTER_COMMAND);
+
                __raw_writel(IOMMU_INTERRUPT_PAGE_FAULT |
                             IOMMU_INTERRUPT_READ_BUS_ERROR,
-                            data->res_bases[i]+IOMMU_REGISTER_INT_MASK);
-               iommu_enable_paging(data->res_bases[i]);
-               iommu_disable_stall(data->res_bases[i]);
+                            data->res_bases[i] + IOMMU_REGISTER_INT_MASK);
+
+               ret = rockchip_iommu_enable_paging(data->res_bases[i]);
+               if (!ret) {
+                       spin_unlock_irqrestore(&data->data_lock, flags);
+                       dev_info(data->iommu, "(%s), %s failed\n",
+                                data->dbgname, __func__);
+                       return -EBUSY;
+               }
+
+               rockchip_iommu_disable_stall(data->res_bases[i]);
        }
 
-       data->domain = domain;
+       data->pgtable = pgtable;
 
        dev_info(data->iommu,"(%s) Enabled\n", data->dbgname);
-finish:
-       write_unlock_irqrestore(&data->lock, flags);
-
-       return ret;
-}
 
-bool rockchip_iommu_disable(struct device *dev)
-{
-       struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
-       bool disabled;
+       spin_unlock_irqrestore(&data->data_lock, flags);
 
-       disabled = __rockchip_iommu_disable(data);
-
-       return disabled;
+       return 0;
 }
 
-void rockchip_iommu_tlb_invalidate(struct device *dev)
+int rockchip_iommu_tlb_invalidate(struct device *dev)
 {
        unsigned long flags;
        struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
 
-       read_lock_irqsave(&data->lock, flags);
-       
-       if(cpu_is_rk312x() || cpu_is_rk3036())
-               rockchip_vcodec_select(data->dbgname);
-       
-       if (is_iommu_active(data)) {
+       spin_lock_irqsave(&data->data_lock, flags);
+
+       if (rockchip_is_iommu_active(data)) {
                int i;
+               int ret;
 
                for (i = 0; i < data->num_res_mem; i++) {
-                       if (!iommu_zap_tlb(data->res_bases[i]))
-                               dev_err(dev->archdata.iommu,"%s,invalidating TLB failed\n",
-                                      data->dbgname);
+                       ret = rockchip_iommu_zap_tlb_without_stall(data->res_bases[i]);
+                       if (ret) {
+                               dev_err(dev->archdata.iommu, "(%s) %s failed\n",
+                                       data->dbgname, __func__);
+                               spin_unlock_irqrestore(&data->data_lock, flags);
+                               return ret;
+                       }
+                               
                }
        } else {
-               dev_dbg(dev->archdata.iommu,"(%s) Disabled. Skipping invalidating TLB.\n",
+               dev_dbg(dev->archdata.iommu, "(%s) Disabled. Skipping invalidating TLB.\n",
                        data->dbgname);
        }
 
-       read_unlock_irqrestore(&data->lock, flags);
+       spin_unlock_irqrestore(&data->data_lock, flags);
+
+       return 0;
 }
 
 static phys_addr_t rockchip_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -804,31 +793,31 @@ static phys_addr_t rockchip_iommu_iova_to_phys(struct iommu_domain *domain,
 
        spin_lock_irqsave(&priv->pgtablelock, flags);
 
-       entry = section_entry(priv->pgtable, iova);
-       entry = page_entry(entry, iova);
-       phys = spage_phys(entry) + spage_offs(iova);
+       entry = rockchip_section_entry(priv->pgtable, iova);
+       entry = rockchip_page_entry(entry, iova);
+       phys = rockchip_spage_phys(entry) + rockchip_spage_offs(iova);
 
        spin_unlock_irqrestore(&priv->pgtablelock, flags);
 
        return phys;
 }
 
-static int lv2set_page(unsigned long *pent, phys_addr_t paddr,
+static int rockchip_lv2set_page(unsigned long *pent, phys_addr_t paddr,
                       size_t size, short *pgcnt)
 {
-       if (!lv2ent_fault(pent))
+       if (!rockchip_lv2ent_fault(pent))
                return -EADDRINUSE;
 
-       *pent = mk_lv2ent_spage(paddr);
-       pgtable_flush(pent, pent + 1);
+       *pent = rockchip_mk_lv2ent_spage(paddr);
+       rockchip_pgtable_flush(pent, pent + 1);
        *pgcnt -= 1;
        return 0;
 }
 
-static unsigned long *alloc_lv2entry(unsigned long *sent,
+static unsigned long *rockchip_alloc_lv2entry(unsigned long *sent,
                                     unsigned long iova, short *pgcounter)
 {
-       if (lv1ent_fault(sent)) {
+       if (rockchip_lv1ent_fault(sent)) {
                unsigned long *pent;
 
                pent = kmem_cache_zalloc(lv2table_kmem_cache, GFP_ATOMIC);
@@ -836,13 +825,13 @@ static unsigned long *alloc_lv2entry(unsigned long *sent,
                if (!pent)
                        return NULL;
 
-               *sent = mk_lv1ent_page(__pa(pent));
+               *sent = rockchip_mk_lv1ent_page(__pa(pent));
                kmemleak_ignore(pent);
                *pgcounter = NUM_LV2ENTRIES;
-               pgtable_flush(pent, pent + NUM_LV2ENTRIES);
-               pgtable_flush(sent, sent + 1);
+               rockchip_pgtable_flush(pent, pent + NUM_LV2ENTRIES);
+               rockchip_pgtable_flush(sent, sent + 1);
        }
-       return page_entry(sent, iova);
+       return rockchip_page_entry(sent, iova);
 }
 
 static size_t rockchip_iommu_unmap(struct iommu_domain *domain,
@@ -856,9 +845,9 @@ static size_t rockchip_iommu_unmap(struct iommu_domain *domain,
 
        spin_lock_irqsave(&priv->pgtablelock, flags);
 
-       ent = section_entry(priv->pgtable, iova);
+       ent = rockchip_section_entry(priv->pgtable, iova);
 
-       if (unlikely(lv1ent_fault(ent))) {
+       if (unlikely(rockchip_lv1ent_fault(ent))) {
                if (size > SPAGE_SIZE)
                        size = SPAGE_SIZE;
                goto done;
@@ -866,16 +855,16 @@ static size_t rockchip_iommu_unmap(struct iommu_domain *domain,
 
        /* lv1ent_page(sent) == true here */
 
-       ent = page_entry(ent, iova);
+       ent = rockchip_page_entry(ent, iova);
 
-       if (unlikely(lv2ent_fault(ent))) {
+       if (unlikely(rockchip_lv2ent_fault(ent))) {
                size = SPAGE_SIZE;
                goto done;
        }
 
        *ent = 0;
        size = SPAGE_SIZE;
-       priv->lv2entcnt[lv1ent_offset(iova)] += 1;
+       priv->lv2entcnt[rockchip_lv1ent_offset(iova)] += 1;
        goto done;
 
 done:
@@ -901,15 +890,15 @@ static int rockchip_iommu_map(struct iommu_domain *domain, unsigned long iova,
 
        spin_lock_irqsave(&priv->pgtablelock, flags);
 
-       entry = section_entry(priv->pgtable, iova);
+       entry = rockchip_section_entry(priv->pgtable, iova);
 
-       pent = alloc_lv2entry(entry, iova,
-                             &priv->lv2entcnt[lv1ent_offset(iova)]);
+       pent = rockchip_alloc_lv2entry(entry, iova,
+                             &priv->lv2entcnt[rockchip_lv1ent_offset(iova)]);
        if (!pent)
                ret = -ENOMEM;
        else
-               ret = lv2set_page(pent, paddr, size,
-                                 &priv->lv2entcnt[lv1ent_offset(iova)]);
+               ret = rockchip_lv2set_page(pent, paddr, size,
+                               &priv->lv2entcnt[rockchip_lv1ent_offset(iova)]);
 
        if (ret) {
                pr_info("%s: Failed to map iova 0x%lx/0x%x bytes\n", __func__,
@@ -920,8 +909,7 @@ static int rockchip_iommu_map(struct iommu_domain *domain, unsigned long iova,
        return ret;
 }
 
-static void rockchip_iommu_detach_device(struct iommu_domain *domain,
-                                        struct device *dev)
+static void rockchip_iommu_detach_device(struct iommu_domain *domain, struct device *dev)
 {
        struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
        struct rk_iommu_domain *priv = domain->priv;
@@ -931,35 +919,32 @@ static void rockchip_iommu_detach_device(struct iommu_domain *domain,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       list_for_each(pos, &priv->clients)
-       {
+       list_for_each(pos, &priv->clients) {
                if (list_entry(pos, struct iommu_drvdata, node) == data) {
                        found = true;
                        break;
                }
        }
-       if (!found)
-               goto finish;
-       
-       if(cpu_is_rk312x() || cpu_is_rk3036())
-               rockchip_vcodec_select(data->dbgname);
-       
-       if (__rockchip_iommu_disable(data)) {
-               dev_info(dev->archdata.iommu,"%s: Detached IOMMU with pgtable %#lx\n",
+
+       if (!found) {
+               spin_unlock_irqrestore(&priv->lock, flags);
+               return;
+       }
+
+       if (rockchip_iommu_disable(data)) {
+               dev_dbg(dev->archdata.iommu,"%s: Detached IOMMU with pgtable %#lx\n",
                        __func__, __pa(priv->pgtable));
-               list_del(&data->node);
-               INIT_LIST_HEAD(&data->node);
+               data->domain = NULL;
+               list_del_init(&data->node);
 
        } else
-               dev_info(dev->archdata.iommu,"%s: Detaching IOMMU with pgtable %#lx delayed",
+               dev_err(dev->archdata.iommu,"%s: Detaching IOMMU with pgtable %#lx delayed",
                        __func__, __pa(priv->pgtable));
 
-finish:
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static int rockchip_iommu_attach_device(struct iommu_domain *domain,
-                                       struct device *dev)
+static int rockchip_iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 {
        struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
        struct rk_iommu_domain *priv = domain->priv;
@@ -968,16 +953,13 @@ static int rockchip_iommu_attach_device(struct iommu_domain *domain,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       if(cpu_is_rk312x() || cpu_is_rk3036())
-               rockchip_vcodec_select(data->dbgname);
-       
-       ret = __rockchip_iommu_enable(data, __pa(priv->pgtable), domain);
+       ret = rockchip_iommu_enable(data, __pa(priv->pgtable));
 
        if (ret == 0) {
                /* 'data->node' must not be appeared in priv->clients */
                BUG_ON(!list_empty(&data->node));
-               data->dev = dev;
                list_add_tail(&data->node, &priv->clients);
+               data->domain = domain;
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -999,26 +981,14 @@ static int rockchip_iommu_attach_device(struct iommu_domain *domain,
 static void rockchip_iommu_domain_destroy(struct iommu_domain *domain)
 {
        struct rk_iommu_domain *priv = domain->priv;
-       struct iommu_drvdata *data;
-       unsigned long flags;
        int i;
 
        WARN_ON(!list_empty(&priv->clients));
 
-       spin_lock_irqsave(&priv->lock, flags);
-
-       list_for_each_entry(data, &priv->clients, node) {
-               if(cpu_is_rk312x() || cpu_is_rk3036())
-                       rockchip_vcodec_select(data->dbgname);
-               while (!rockchip_iommu_disable(data->dev))
-                       ; /* until System MMU is actually disabled */
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        for (i = 0; i < NUM_LV1ENTRIES; i++)
-               if (lv1ent_page(priv->pgtable + i))
+               if (rockchip_lv1ent_page(priv->pgtable + i))
                        kmem_cache_free(lv2table_kmem_cache,
-                                       __va(lv2table_base(priv->pgtable + i)));
+                                       __va(rockchip_lv2table_base(priv->pgtable + i)));
 
        free_pages((unsigned long)priv->pgtable, 0);
        free_pages((unsigned long)priv->lv2entcnt, 0);
@@ -1048,7 +1018,7 @@ static int rockchip_iommu_domain_init(struct iommu_domain *domain)
        if (!priv->lv2entcnt)
                goto err_counter;
 
-       pgtable_flush(priv->pgtable, priv->pgtable + NUM_LV1ENTRIES);
+       rockchip_pgtable_flush(priv->pgtable, priv->pgtable + NUM_LV1ENTRIES);
 
        spin_lock_init(&priv->lock);
        spin_lock_init(&priv->pgtablelock);
@@ -1075,43 +1045,14 @@ static struct iommu_ops rk_iommu_ops = {
        .pgsize_bitmap = SPAGE_SIZE,
 };
 
-static int rockchip_iommu_prepare(void)
-{
-       int ret = 0;
-       static int registed;
-
-       if (registed)
-               return 0;
-
-       lv2table_kmem_cache = kmem_cache_create("rk-iommu-lv2table",
-                                               LV2TABLE_SIZE,
-                                               LV2TABLE_SIZE,
-                                               0, NULL);
-       if (!lv2table_kmem_cache) {
-               pr_info("%s: failed to create kmem cache\n", __func__);
-               return -ENOMEM;
-       }
-       ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
-       if (!ret)
-               registed = 1;
-       else
-               pr_info("%s:failed to set iommu to bus\r\n", __func__);
-       return ret;
-}
-
 static int  rockchip_get_iommu_resource_num(struct platform_device *pdev,
                                             unsigned int type)
 {
        int num = 0;
        int i;
-#if 0
-       pr_info("dev num_resources %d type = 0x%08x\n",pdev->num_resources, type);
-#endif
+
        for (i = 0; i < pdev->num_resources; i++) {
                struct resource *r = &pdev->resource[i];
-#if 0
-dev_info(&pdev->dev, "r[%d] start %08x end %08x flags %08lx name (%s) resource_type %08lx\n", i, r->start, r->end, r->flags, r->name, resource_type(r));
-#endif
                if (type == resource_type(r))
                        num++;
        }
@@ -1119,44 +1060,6 @@ dev_info(&pdev->dev, "r[%d] start %08x end %08x flags %08lx name (%s) resource_t
        return num;
 }
 
-static struct kobject *dump_mmu_object;
-
-static int dump_mmu_pagetbl(struct device *dev, struct device_attribute *attr,
-                           const char *buf, u32 count)
-{
-       u32 fault_address;
-       u32 iommu_dte;
-       u32 mmu_base;
-       void __iomem *base;
-       u32 ret;
-
-       ret = kstrtouint(buf, 0, &mmu_base);
-       if (ret)
-               dev_dbg(dev,"%s is not in hexdecimal form.\n", buf);
-       base = ioremap(mmu_base, 0x100);
-       if (base != rk312x_vop_mmu_base) {
-               iommu_dte = __raw_readl(base + IOMMU_REGISTER_DTE_ADDR);
-               fault_address = __raw_readl(base + IOMMU_REGISTER_PAGE_FAULT_ADDR);
-               dump_pagetbl(fault_address, iommu_dte);
-       } else {
-               dev_dbg(dev,"vop mmu not support\n");
-       }
-       return count;
-}
-
-static DEVICE_ATTR(dump_mmu_pgtable, 0644, NULL, dump_mmu_pagetbl);
-
-void dump_iommu_sysfs_init(void)
-{
-       u32 ret;
-
-       dump_mmu_object = kobject_create_and_add("rk_iommu", NULL);
-       if (dump_mmu_object == NULL)
-               return;
-       ret = sysfs_create_file(dump_mmu_object,
-                               &dev_attr_dump_mmu_pgtable.attr);
-}
-
 static int rockchip_iommu_probe(struct platform_device *pdev)
 {
        int i, ret;
@@ -1164,58 +1067,36 @@ static int rockchip_iommu_probe(struct platform_device *pdev)
        struct iommu_drvdata *data;
        
        dev = &pdev->dev;
-       
-#if 0
-struct resource *res = pdev->resource;
-
-for (i = 0; i < pdev->num_resources; i++, res++) {
-       pr_info("r[%d] start %08x end %08x flags %08lx name (%s) resource_type %08lx\n", i, res->start, res->end, res->flags, res->name,   resource_type(res));
-}
-#endif
-       ret = rockchip_iommu_prepare();
-       if (ret) {
-               dev_err(dev,"%s,failed\r\n", __func__);
-               goto err_alloc;
-       }
 
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data) {
                dev_dbg(dev, "Not enough memory\n");
-               ret = -ENOMEM;
-               goto err_alloc;
+               return -ENOMEM;
        }
+
        dev_set_drvdata(dev, data);
-/*
-       ret = dev_set_drvdata(dev, data);
-       if (ret)
-       {
-               dev_dbg(dev, "Unabled to initialize driver data\n");
-               goto err_init;
-       }
-*/
-       if (pdev->dev.of_node) {
-               of_property_read_string(pdev->dev.of_node,
-                                       "dbgname", &(data->dbgname));
-       } else {
-               dev_dbg(dev,
-                               "dbgname not assigned in device tree or device node not exist\r\n");
-       }
+
+       if (pdev->dev.of_node)
+               of_property_read_string(pdev->dev.of_node, "dbgname",
+                                       &(data->dbgname));
+       else
+               dev_dbg(dev, "dbgname not assigned in device tree or device node not exist\r\n");
 
        dev_info(dev,"(%s) Enter\n", data->dbgname);
        
-
        data->num_res_mem = rockchip_get_iommu_resource_num(pdev,
                                IORESOURCE_MEM);
        if (0 == data->num_res_mem) {
                dev_err(dev,"can't find iommu memory resource \r\n");
-               goto err_init;
+               return -ENOMEM;
        }
        dev_dbg(dev,"data->num_res_mem=%d\n", data->num_res_mem);
+
        data->num_res_irq = rockchip_get_iommu_resource_num(pdev,
                                IORESOURCE_IRQ);
        if (0 == data->num_res_irq) {
                dev_err(dev,"can't find iommu irq resource \r\n");
-               goto err_init;
+               return -ENOMEM;
        }
        dev_dbg(dev,"data->num_res_irq=%d\n", data->num_res_irq);
 
@@ -1223,8 +1104,7 @@ for (i = 0; i < pdev->num_resources; i++, res++) {
                                sizeof(*data->res_bases), GFP_KERNEL);
        if (data->res_bases == NULL) {
                dev_err(dev, "Not enough memory\n");
-               ret = -ENOMEM;
-               goto err_init;
+               return -ENOMEM;
        }
 
        for (i = 0; i < data->num_res_mem; i++) {
@@ -1233,69 +1113,58 @@ for (i = 0; i < pdev->num_resources; i++, res++) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
                if (!res) {
                        dev_err(dev,"Unable to find IOMEM region\n");
-                       ret = -ENOENT;
-                       goto err_res;
+                       return -ENOENT;
                }
-               data->res_bases[i] = devm_ioremap(dev,res->start, resource_size(res));
-               dev_dbg(dev,"res->start = 0x%08x  ioremap to  data->res_bases[%d] = 0x%08x\n",
-                       res->start, i, (unsigned int)data->res_bases[i]);
+
+               data->res_bases[i] = devm_ioremap(dev,res->start,
+                                                 resource_size(res));
                if (!data->res_bases[i]) {
-                       pr_err("Unable to map IOMEM @ PA:%#x\n", res->start);
-                       ret = -ENOENT;
-                       goto err_res;
+                       dev_err(dev, "Unable to map IOMEM @ PA:%#x\n",
+                               res->start);
+                       return -ENOMEM;
                }
 
-               if (cpu_is_rk312x() || cpu_is_rk3036()) {
-                       rockchip_vcodec_select(data->dbgname);
-                       if (strstr(data->dbgname, "vop") && cpu_is_rk312x()) {
-                               rk312x_vop_mmu_base = data->res_bases[0];
-                               dev_dbg(dev,"rk312x_vop_mmu_base = 0x%08x\n",(unsigned int)rk312x_vop_mmu_base);
-                       }
-               }
-               if (!strstr(data->dbgname, "isp")) {
-                       if (!iommu_reset(data->res_bases[i], data->dbgname)) {
-                               ret = -ENOENT;
-                               goto err_res;
-                       }
+               dev_dbg(dev,"res->start = 0x%08x ioremap to data->res_bases[%d] = 0x%08x\n",
+                       res->start, i, (unsigned int)data->res_bases[i]);
+
+               if (strstr(data->dbgname, "vop") && cpu_is_rk312x()) {
+                       rk312x_vop_mmu_base = data->res_bases[0];
+                       dev_dbg(dev, "rk312x_vop_mmu_base = 0x%08x\n",
+                               (unsigned int)rk312x_vop_mmu_base);
                }
        }
 
        for (i = 0; i < data->num_res_irq; i++) {
-               ret = platform_get_irq(pdev, i);
-               if (ret <= 0) {
-                       dev_err(dev,"Unable to find IRQ resource\n");
-                       goto err_irq;
-               }
                if (cpu_is_rk312x() && strstr(data->dbgname, "vop")) {
                        dev_info(dev, "skip request vop mmu irq\n");
                        continue;
                }
+
+               ret = platform_get_irq(pdev, i);
+               if (ret <= 0) {
+                       dev_err(dev,"Unable to find IRQ resource\n");
+                       return -ENOENT;
+               }
+
                ret = devm_request_irq(dev, ret, rockchip_iommu_irq,
                                  IRQF_SHARED, dev_name(dev), data);
                if (ret) {
-                       dev_err(dev,"Unabled to register interrupt handler\n");
-                       goto err_irq;
+                       dev_err(dev, "Unabled to register interrupt handler\n");
+                       return -ENOENT;
                }
        }
+
        ret = rockchip_init_iovmm(dev, &data->vmm);
        if (ret)
-               goto err_irq;
+               return ret;
 
        data->iommu = dev;
-       rwlock_init(&data->lock);
+       spin_lock_init(&data->data_lock);
        INIT_LIST_HEAD(&data->node);
 
-       set_fault_handler(data, &default_fault_handler);
-
        dev_info(dev,"(%s) Initialized\n", data->dbgname);
-       return 0;
 
-err_irq:
-err_res:
-err_init:
-err_alloc:
-       dev_err(dev, "Failed to initialize\n");
-       return ret;
+       return 0;
 }
 
 #ifdef CONFIG_OF
@@ -1326,7 +1195,19 @@ static struct platform_driver rk_iommu_driver = {
 
 static int __init rockchip_iommu_init_driver(void)
 {
-       dump_iommu_sysfs_init();
+       int ret;
+
+       lv2table_kmem_cache = kmem_cache_create("rk-iommu-lv2table",
+                                               LV2TABLE_SIZE, LV2TABLE_SIZE,
+                                               0, NULL);
+       if (!lv2table_kmem_cache) {
+               pr_info("%s: failed to create kmem cache\n", __func__);
+               return -ENOMEM;
+       }
+
+       ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops);
+       if (ret)
+               return ret;
 
        return platform_driver_register(&rk_iommu_driver);
 }
index 761b681209810efe1df8d15f21210ddb2b2b824b..c5813638e3b936a77ee61ae5bb157b6629eaf756 100755 (executable)
@@ -29,15 +29,13 @@ struct rk_iovmm {
 struct iommu_drvdata {
        struct list_head node; /* entry of rk_iommu_domain.clients */
        struct device *iommu;   /*  IOMMU's device descriptor */
-       struct device *dev;     /* Owner of  IOMMU */
        int num_res_mem;
        int num_res_irq;
        const char *dbgname;
        void __iomem **res_bases;
        int activations;
-       rwlock_t lock;
+       spinlock_t data_lock;
        struct iommu_domain *domain; /* domain given to iommu_attach_device() */
-       rockchip_iommu_fault_handler_t fault_handler;
        unsigned long pgtable;
        struct rk_iovmm vmm;
 };
@@ -74,31 +72,18 @@ static inline int rockchip_init_iovmm(struct device *iommu,
 
 #ifdef CONFIG_ROCKCHIP_IOMMU
 
-/**
-* rockchip_iommu_disable() - disable iommu mmu of ip
-* @owner: The device whose IOMMU is about to be disabled.
-*
-* This function disable  iommu to transfer address
- * from virtual address to physical address
- */
-bool rockchip_iommu_disable(struct device *owner);
-
 /**
  * rockchip_iommu_tlb_invalidate() - flush all TLB entry in iommu
  * @owner: The device whose IOMMU.
  *
  * This function flush all TLB entry in iommu
  */
-void rockchip_iommu_tlb_invalidate(struct device *owner);
+int rockchip_iommu_tlb_invalidate(struct device *owner);
 
 #else /* CONFIG_ROCKCHIP_IOMMU */
-static inline bool rockchip_iommu_disable(struct device *owner)
-{
-       return false;
-}
-static inline void rockchip_iommu_tlb_invalidate(struct device *owner)
+static inline int rockchip_iommu_tlb_invalidate(struct device *owner)
 {
-       return false;
+       return -1;
 }
 
 #endif
index 1079ea17d7467fef902aff822c8cb73ef2a62bb6..94faaffce39ada1c7cfae43db1ab03af769904a3 100755 (executable)
@@ -33,12 +33,7 @@ static struct rk_vm_region *find_region(struct rk_iovmm *vmm, dma_addr_t iova)
 void rockchip_iovmm_set_fault_handler(struct device *dev,
                                       rockchip_iommu_fault_handler_t handler)
 {
-       unsigned long flags;
-       struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
-       
-       write_lock_irqsave(&data->lock, flags);
-       data->fault_handler = handler;
-       write_unlock_irqrestore(&data->lock, flags);
+       return;
 }
 
 int rockchip_iovmm_activate(struct device *dev)
@@ -141,11 +136,13 @@ dma_addr_t rockchip_iovmm_map(struct device *dev,
 
        spin_unlock(&vmm->lock);
 
-       rockchip_iommu_tlb_invalidate(dev);
-       /*
-       pr_err("IOVMM: Allocated VM region @ %#x/%#X bytes.\n",
+       ret = rockchip_iommu_tlb_invalidate(dev);
+       if (ret)
+               goto err_map_map;
+
+       dev_dbg(dev->archdata.iommu, "IOVMM: Allocated VM region @ %#x/%#X bytes.\n",
        region->start, region->size);
-       */
+       
        return region->start;
 
 err_map_map:
@@ -154,7 +151,7 @@ err_map_map:
 err_map_noiomem:
        kfree(region);
 err_map_nomem:
-       pr_err("IOVMM: Failed to allocated VM region for %#x bytes.\n", size);
+       dev_err(dev->archdata.iommu, "IOVMM: Failed to allocated VM region for %#x bytes.\n", size);
        return (dma_addr_t)ret;
 }
 
@@ -189,10 +186,10 @@ void rockchip_iovmm_unmap(struct device *dev, dma_addr_t iova)
        gen_pool_free(vmm->vmm_pool, region->start, region->size);
 
        WARN_ON(unmapped_size != region->size);
-       /*
-       pr_err("IOVMM: Unmapped %#x bytes from %#x.\n",
+       
+       dev_dbg(dev->archdata.iommu, "IOVMM: Unmapped %#x bytes from %#x.\n",
                unmapped_size, region->start);
-       */
+       
        kfree(region);
 }
 
@@ -203,7 +200,7 @@ int rockchip_iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size)
        int ret;
 
        if (WARN_ON((phys + size) >= IOVA_START)) {
-               pr_err("Unable to create one to one mapping for %#x @ %#x\n",
+               dev_err(dev->archdata.iommu, "Unable to create one to one mapping for %#x @ %#x\n",
                       size, phys);
                return -EINVAL;
        }
@@ -232,7 +229,9 @@ int rockchip_iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size)
 
        spin_unlock(&vmm->lock);
 
-       rockchip_iommu_tlb_invalidate(dev);
+       ret = rockchip_iommu_tlb_invalidate(dev);
+       if (ret)
+               return ret;
 
        return 0;
 }
@@ -262,9 +261,8 @@ void rockchip_iovmm_unmap_oto(struct device *dev, phys_addr_t phys)
        spin_unlock(&vmm->lock);
 
        unmapped_size = iommu_unmap(vmm->domain, region->start, region->size);
-       rockchip_iommu_tlb_invalidate(dev);
        WARN_ON(unmapped_size != region->size);
-       pr_err("IOVMM: Unmapped %#x bytes from %#x.\n",
+       dev_dbg(dev->archdata.iommu, "IOVMM: Unmapped %#x bytes from %#x.\n",
               unmapped_size, region->start);
 
        kfree(region);
@@ -295,13 +293,13 @@ int rockchip_init_iovmm(struct device *iommu, struct rk_iovmm *vmm)
 
        INIT_LIST_HEAD(&vmm->regions_list);
 
-       pr_info("IOVMM: Created %#x B IOVMM from %#x.\n",
+       dev_info(iommu, "IOVMM: Created %#x B IOVMM from %#x.\n",
                IOVM_SIZE, IOVA_START);
        return 0;
 err_setup_domain:
        gen_pool_destroy(vmm->vmm_pool);
 err_setup_genalloc:
-       pr_err("IOVMM: Failed to create IOVMM (%d)\n", ret);
+       dev_err(iommu, "IOVMM: Failed to create IOVMM (%d)\n", ret);
 
        return ret;
 }
index 4274f0b18ca455f8cf8734208416f6a786f0b9c1..6a92b1a916ed40af2ae494cb5449c95336e007ec 100644 (file)
@@ -16,4 +16,8 @@ menu "rockchip camera sensor interface driver"
                depends on ROCKCHIP_CAMERA_SENSOR_INTERFACE
                default y
                
+       config RK30_CAMERA_PINGPONG
+               tristate "rk30_camera_pingpong"
+               depends on ROCKCHIP_CAMERA_SENSOR_INTERFACE
+               
 endmenu                
index 00df4b1e3e58cee13bef47b1215393a1535d5685..51299a5644be5a3c8051e9f7cbc3cc56da0c56a5 100644 (file)
@@ -1,3 +1,21 @@
+obj-$(CONFIG_RK30_CAMERA_PINGPONG) += rk30_camera_pingpong.o generic_sensor.o \\r
+gc0307.o \\r
+gc0308.o \\r
+gc0309.o \\r
+gc0328.o \\r
+gc0329.o \\r
+gc2015.o \\r
+gc2035.o \\r
+gt2005.o \\r
+hm2057.o \\r
+hm5065.o \\r
+mt9p111.o \\r
+nt99160_2way.o \\r
+nt99240_2way.o \\r
+ov2659.o \\r
+ov5640.o \\r
+sp0838.o \\r
+sp2518.o\r
 obj-$(CONFIG_RK30_CAMERA_ONEFRAME) += rk30_camera_oneframe.o generic_sensor.o \\r
 gc0307.o \\r
 gc0308.o \\r
index 12024982cb8c35bdfdb0a4497eb17dbaceced2b1..a6f26a9f47f2ab1242822b3af961f4c6518e5c98 100755 (executable)
@@ -517,6 +517,14 @@ static inline int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct
     //struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));\r
     int value = ext_ctrl->value;\r
 \r
+       \r
+       if(value == 0xfefe5a5a){        \r
+               if ((ctrl_info->cur_value == 2) || (ctrl_info->cur_value == 1)) {\r
+                       generic_sensor_ioctrl(icd, Sensor_Flash, Flash_On);                                     \r
+               }\r
+               \r
+               return 0;\r
+       }\r
     if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) {\r
         printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value,\r
             ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum);\r
index bb6ca97866f93b17c11d3ce11adec14201dacb03..e1ffdc1a1bd0be098686010e61a874513c99e23a 100755 (executable)
@@ -193,11 +193,16 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 /*********yzm**********/
 
 static u32 CRU_PCLK_REG30;
+static u32 CRU_CLK_OUT;
+static u32 clk_cif_out_src_gate_en;
+static u32 CRU_CLKSEL29_CON;
+static u32 cif0_clk_sel;
 static u32 ENANABLE_INVERT_PCLK_CIF0;
 static u32 DISABLE_INVERT_PCLK_CIF0;
 static u32 ENANABLE_INVERT_PCLK_CIF1;
 static u32 DISABLE_INVERT_PCLK_CIF1;
-       
+static u32 CHIP_NAME;
+
 #define write_cru_reg(addr, val)            __raw_writel(val, addr+RK_CRU_VIRT)
 #define read_cru_reg(addr)                  __raw_readl(addr+RK_CRU_VIRT)
 #define mask_cru_reg(addr, msk, val)        write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
@@ -272,8 +277,13 @@ static u32 DISABLE_INVERT_PCLK_CIF1;
                 1. Add  power and powerdown controled by PMU.
 *v0.1.8:
                 1. Support front and rear camera support are the same.
+*v0.1.9:
+                1. Support pingpong mode.
+                2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0
+                3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
+                4. Support flash control when preview size == picture size
 */
-#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0x8)
+#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0x9)
 static int version = RK_CAM_VERSION_CODE;
 module_param(version, int, S_IRUGO);
 
@@ -491,6 +501,13 @@ static void rk_camera_diffchips(const char *rockchip_name)
                DISABLE_INVERT_PCLK_CIF0  = ((0x1<<23)|(0x0<<7));
                ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
                DISABLE_INVERT_PCLK_CIF1  = DISABLE_INVERT_PCLK_CIF0;
+
+               CRU_CLK_OUT = 0xdc;
+               clk_cif_out_src_gate_en = ((0x1<<23)|(0x1<<7));
+               CRU_CLKSEL29_CON = 0xb8;
+               cif0_clk_sel = ((0x1<<23)|(0x0<<7));
+
+               CHIP_NAME = 3126;
        }
 }
 static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
@@ -562,7 +579,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
        int bytes_per_line_host;
        fmt.packing = SOC_MBUS_PACKING_1_5X8;
 
-       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
 
                bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
@@ -1217,7 +1234,6 @@ static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
 {
     int err = 0,cif;    
     struct rk_cif_clk *clk;
-    struct clk *cif_clk_out_div;
 
        debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
@@ -1247,31 +1263,19 @@ static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
         clk_set_rate(clk->cif_clk_out,clk_rate);
         clk->on = true;
     } else if (!on && clk->on) {
+               clk_set_rate(clk->cif_clk_out,36000000);/*yzm :just for close clk which base on XIN24M */
        msleep(100);
         clk_disable_unprepare(clk->aclk_cif);
        clk_disable_unprepare(clk->hclk_cif);
        clk_disable_unprepare(clk->cif_clk_in);
+               if(CHIP_NAME == 3126){
+                       write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
+                       write_cru_reg(CRU_CLK_OUT, 0x00800080);
+               }
        clk_disable_unprepare(clk->cif_clk_out);
        clk_disable_unprepare(clk->pd_cif);
-        clk->on = false;
-        if(cif){
-            cif_clk_out_div =  clk_get(NULL, "cif1_out_div");
-        }else{
-            cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
-            if(IS_ERR_OR_NULL(cif_clk_out_div)) {
-                cif_clk_out_div =  clk_get(NULL, "cif_out_div");
-            }
-        }
-        
-        if(!IS_ERR_OR_NULL(cif_clk_out_div)) {   /* ddl@rock-chips.com: v0.3.0x13 */ 
-            err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
-            clk_put(cif_clk_out_div);
-        } else {
-            err = -1;
-        }
-        
-        if(err)
-           RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__); 
+               
+               clk->on = false;
     }
     //spin_unlock(&clk->lock);
 rk_camera_clk_ctrl_end:
@@ -1536,7 +1540,7 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
         }
     } else {
                if(IS_CIF0()){
-                       write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
+                       write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFFF7F ) | DISABLE_INVERT_PCLK_CIF0);
         } else {
                        write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
         }
@@ -2651,7 +2655,7 @@ static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
                cif_ctrl_val |= ENABLE_CAPTURE;
         write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
         spin_unlock_irqrestore(&pcdev->lock,flags);
-        printk("%s:stream enable CIF_CIF_CTRL 0x%lx",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
+        printk("%s:stream enable CIF_CIF_CTRL 0x%lx\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
                hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
         pcdev->fps_timer.istarted = true;
        } else {
index d24a0b7b0fa76934f53b59361659ad1db3339f59..5b8a39b01e865116976744fe45d34f2fa8b33dc0 100755 (executable)
@@ -1,15 +1,3 @@
-/*
- * V4L2 Driver for RK28 camera host
- *
- * Copyright (C) 2006, Sascha Hauer, Pengutronix
- * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK30) ||defined(CONFIG_ARCH_RK3188)
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <linux/kthread.h>
-#include <mach/iomux.h>
+
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-dma-contig.h>
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
-#include <mach/io.h>
-#include <plat/ipp.h>
-#include <plat/vpu_service.h>
+#include <media/videobuf-core.h>
+#include <linux/rockchip/iomap.h>
+
 #include "../../video/rockchip/rga/rga.h"
-#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK3188)
-#include <mach/rk30_camera.h>
-#include <mach/cru.h>
-#include <mach/pmu.h>
-#endif
+#include "../../../arch/arm/mach-rockchip/rk30_camera.h"/*yzm*/
+#include <linux/rockchip/cru.h>
 
-#if defined(CONFIG_ARCH_RK2928)
+/*******yzm*********
+
+#include <plat/efuse.h>
+#if (defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026))
 #include <mach/rk2928_camera.h>
 #include <mach/cru.h>
 #include <mach/pmu.h>
 #define SOFT_RST_CIF1 (SOFT_RST_MAX+1)
 #endif
+*/
 #include <asm/cacheflush.h>
+
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <media/soc_camera.h>
+#include <media/camsys_head.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
 static int debug = 0;
 module_param(debug, int, S_IRUGO|S_IWUSR);
 
-#if defined(CONFIG_TRACE_LOG_PRINTK)
- #define RK30_CAM_DEBUG_TRACE(format, ...) printk(KERN_ERR"rk30_camera: " format, ## __VA_ARGS__)
-#else
- #define RK30_CAM_DEBUG_TRACE(format, ...)
-#endif
-#define RK30_CAM_LOG_TRACE(format, ...) printk(KERN_WARNING"rk30_camera: " format, ## __VA_ARGS__)
+#define CAMMODULE_NAME     "rk_cam_cif"   
+
+#define wprintk(level, fmt, arg...) do {                       \
+       if (debug >= level)                                     \
+           printk(KERN_ERR "%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)
 
 #define dprintk(level, fmt, arg...) do {                       \
        if (debug >= level)                                     \
-       printk(KERN_WARNING"rk_camera: " fmt , ## arg); } while (0)
+           printk(KERN_ERR"%s(%d): " fmt,CAMMODULE_NAME,__LINE__,## arg); } while (0)      
+
+#define RKCAMERA_TR(format, ...)  printk(KERN_ERR "%s(%d):" format,CAMMODULE_NAME,__LINE__,## __VA_ARGS__)
+#define RKCAMERA_DG1(format, ...) wprintk(1, format, ## __VA_ARGS__)
+#define RKCAMERA_DG2(format, ...) dprintk(2, format, ## __VA_ARGS__)
+#define debug_printk(format, ...) dprintk(3, format, ## __VA_ARGS__)
 
-#define RKCAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
-#define RKCAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
-// CIF Reg Offset
+/* CIF Reg Offset*/
 #define  CIF_CIF_CTRL                       0x00
 #define  CIF_CIF_INTEN                      0x04
 #define  CIF_CIF_INTSTAT                    0x08
@@ -98,8 +98,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define         CIF_CIF_LAST_LINE                  0x68
 #define         CIF_CIF_LAST_PIX                   0x6c
 
-//The key register bit descrition
-// CIF_CTRL Reg , ignore SCM,WBC,ISP,
+/*The key register bit descrition*/
+/* CIF_CTRL Reg , ignore SCM,WBC,ISP,*/
 #define  DISABLE_CAPTURE              (0x00<<0)
 #define  ENABLE_CAPTURE               (0x01<<0)
 #define  MODE_ONEFRAME                (0x00<<1)
@@ -107,12 +107,12 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define  MODE_LINELOOP                (0x02<<1)
 #define  AXI_BURST_16                 (0x0F << 12)
 
-//CIF_CIF_INTEN
+/*CIF_CIF_INTEN*/
 #define  FRAME_END_EN                  (0x01<<1)
 #define  BUS_ERR_EN                            (0x01<<6)
 #define  SCL_ERR_EN                            (0x01<<7)
 
-//CIF_CIF_FOR
+/*CIF_CIF_FOR*/
 #define  VSY_HIGH_ACTIVE                   (0x01<<0)
 #define  VSY_LOW_ACTIVE                    (0x00<<0)
 #define  HSY_LOW_ACTIVE                               (0x01<<1)
@@ -145,7 +145,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define  UV_STORAGE_ORDER_UVUV             (0x00<<19)
 #define  UV_STORAGE_ORDER_VUVU             (0x01<<19)
 
-//CIF_CIF_SCL_CTRL
+/*CIF_CIF_SCL_CTRL*/
 #define ENABLE_SCL_DOWN                    (0x01<<0)           
 #define DISABLE_SCL_DOWN                   (0x00<<0)
 #define ENABLE_SCL_UP                      (0x01<<1)           
@@ -163,14 +163,17 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 
 #define MIN(x,y)   ((x<y) ? x: y)
 #define MAX(x,y)    ((x>y) ? x: y)
-#define RK_SENSOR_12MHZ      12*1000*1000 
 #define RK_SENSOR_24MHZ      24*1000*1000          /* MHz */
-#define RK_SENSOR_48MHZ      48*1000*1000
+#define RK_SENSOR_48MHZ      48
+
+#define __raw_readl(p)           (*(unsigned long *)(p))
+#define __raw_writel(v,p)     (*(unsigned long *)(p) = (v))
 
 #define write_cif_reg(base,addr, val)  __raw_writel(val, addr+(base))
 #define read_cif_reg(base,addr) __raw_readl(addr+(base))
 #define mask_cif_reg(addr, msk, val)    write_cif_reg(addr, (val)|((~(msk))&read_cif_reg(addr)))
 
+/*
 #if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)
 //CRU,PIXCLOCK
 #define CRU_PCLK_REG30                     0xbc
@@ -185,11 +188,35 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define RQUEST_RST_CIF0                    (0x01 << 14)
 #define RQUEST_RST_CIF1                    (0x01 << 15)
 
-#define write_cru_reg(addr, val)  __raw_writel(val, addr+RK30_CRU_BASE)
-#define read_cru_reg(addr) __raw_readl(addr+RK30_CRU_BASE)
-#define mask_cru_reg(addr, msk, val)   write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
+#define write_cru_reg(addr, val)            __raw_writel(val, addr+RK30_CRU_BASE)
+#define read_cru_reg(addr)                  __raw_readl(addr+RK30_CRU_BASE)
+#define mask_cru_reg(addr, msk, val)        write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
+#endif
+*/
+/*********yzm**********/
+
+static u32 CRU_PCLK_REG30;
+static u32 CRU_CLK_OUT;
+static u32 CRU_CLKSEL29_CON;
+static u32 ENANABLE_INVERT_PCLK_CIF0;
+static u32 DISABLE_INVERT_PCLK_CIF0;
+static u32 ENANABLE_INVERT_PCLK_CIF1;
+static u32 DISABLE_INVERT_PCLK_CIF1;
+static u32 CHIP_NAME;
+       
+#define write_cru_reg(addr, val)            __raw_writel(val, addr+RK_CRU_VIRT)
+#define read_cru_reg(addr)                  __raw_readl(addr+RK_CRU_VIRT)
+#define mask_cru_reg(addr, msk, val)        write_cru_reg(addr,(val)|((~(msk))&read_cru_reg(addr)))
+/*********yzm*********end*/
+/*
+#if defined(CONFIG_ARCH_RK2928)
+#define write_cru_reg(addr, val)  
+#define read_cru_reg(addr)                 0 
+#define mask_cru_reg(addr, msk, val)   
 #endif
+*/
 
+/*
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
 //GRF_IO_CON3                        0x100
 #define CIF_DRIVER_STRENGTH_2MA            (0x00 << 12)
@@ -203,43 +230,24 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CIF_CLKOUT_AMP_1V8                 (0x01 << 10)
 #define CIF_CLKOUT_AMP_MASK                (0x01 << 26)
 
-#define write_grf_reg(addr, val)  __raw_writel(val, addr+RK30_GRF_BASE)
-#define read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
-#define mask_grf_reg(addr, msk, val)   write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
+#define write_grf_reg(addr, val)           __raw_writel(val, addr+RK30_GRF_BASE)
+#define read_grf_reg(addr)                 __raw_readl(addr+RK30_GRF_BASE)
+#define mask_grf_reg(addr, msk, val)       write_grf_reg(addr,(val)|((~(msk))&read_grf_reg(addr)))
 #else
 #define write_grf_reg(addr, val)  
-#define read_grf_reg(addr)                0
+#define read_grf_reg(addr)                 0
 #define mask_grf_reg(addr, msk, val)   
 #endif
+*/
+#define CAM_WORKQUEUE_IS_EN()   (false)//(true)
+#define CAM_IPPWORK_IS_EN()     (false)/*((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))*/
 
-#if defined(CONFIG_ARCH_RK2928)
-#define write_cru_reg(addr, val)  
-#define read_cru_reg(addr)                 0 
-#define mask_cru_reg(addr, msk, val)   
-#endif
-
-
-//when work_with_ipp is not enabled,CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF is not defined.something wrong with it
-#ifdef CONFIG_VIDEO_RK29_WORK_IPP//CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
-#ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
-#define CAM_WORKQUEUE_IS_EN()   ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)\
-                                      || (pcdev->icd_cb.sensor_cb))
-#define CAM_IPPWORK_IS_EN()     ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height))                                  
-#else
-#define CAM_WORKQUEUE_IS_EN()  (true)
-#define CAM_IPPWORK_IS_EN()     ((pcdev->zoominfo.a.c.width != pcdev->icd->user_width) || (pcdev->zoominfo.a.c.height != pcdev->icd->user_height))
-#endif
-#else //CONFIG_VIDEO_RK29_WORK_IPP
-#define CAM_WORKQUEUE_IS_EN()    (false)
-#define CAM_IPPWORK_IS_EN()      (false) 
-#endif
-
-#define IS_CIF0()              (pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)
+#define IS_CIF0()              (true)/*(pcdev->hostid == RK_CAM_PLATFORM_DEV_ID_0)*/
 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
 #define CROP_ALIGN_BYTES (0x03)
 #define CIF_DO_CROP 0
 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
-#define CROP_ALIGN_BYTES (0x03)
+#define CROP_ALIGN_BYTES (0x0f)
 #define CIF_DO_CROP 0
 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
 #define CROP_ALIGN_BYTES (0x03)
@@ -248,87 +256,61 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
 #define CROP_ALIGN_BYTES (0x0F)
 #define CIF_DO_CROP 1
 #endif
-//Configure Macro
+
 /*
-*                       Driver Version Note
-*
-*v0.0.x : this driver is 2.6.32 kernel driver;
-*v0.1.x : this driver is 3.0.8 kernel driver;
-*
-*v0.x.1 : this driver first support rk2918;
-*v0.x.2 : fix this driver support v4l2 format is V4L2_PIX_FMT_NV12 and V4L2_PIX_FMT_NV16,is not V4L2_PIX_FMT_YUV420 
-*                and V4L2_PIX_FMT_YUV422P;
-*v0.x.3 : this driver support VIDIOC_ENUM_FRAMEINTERVALS;
-*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 : digital zoom use the ipp to do scale and crop , otherwise ipp just do the scale. Something wrong with digital zoom if
-          we do crop with cif and do scale with ipp , we will fix this  next version.
-*v0.x.8 : temp version,reinit capture list when setup video buf.
-*v0.x.9 : 1. add the case of IPP unsupportted ,just cropped by CIF(not do the scale) this version. 
-          2. flush workqueue when releas buffer
-*v0.x.a: 1. reset cif and wake up vb when cif have't receive data in a fixed time(now setted as 2 secs) so that app can
-             be quitted
-          2. when the flash is on ,flash off in a fixed time to prevent from flash light too hot.
-          3. when front and back camera are the same sensor,and one has the flash ,other is not,flash can't work corrrectly ,fix it
-          4. add  menu configs for convineuent to customize sensor series
-*v0.x.b:  specify the version is  NOT sure stable.
-*v0.x.c:  1. add cif reset when resolution changed to avoid of collecting data erro
-          2. irq process is splitted to two step.
-*v0.x.e: fix bugs of early suspend when display_pd is closed. 
-*v0.x.f: fix calculate ipp memory size is enough or not in try_fmt function; 
-*v0.x.11: fix struct rk_camera_work may be reentrant
-*v0.x.13: 1.add scale by arm,rga and pp.
-          2.CIF do the crop when digital zoom.
-                 3.fix bug in prob func:request mem twice. 
-                 4.video_vq may be null when reinit work,fix it
-                 5.arm scale algorithm has something wrong(may exceed the bound of width or height) ,fix it.
-*v0.x.15: 
-*         1. support rk3066b;
-*v0.4.15:
-*         1. cif work on pingping mode;
-*v0.x.17: 
-*         1. support 8Mega picture;
-*v0.x.19:
-*         1. invalidate the limit which scale is invalidat when scale ratio > 2;
-*v0.x.1b: 1. fix oops bug  when using arm to do scale_crop if preview buffer is not allocated correctly 
-          2. rk_camera_set_fmt will called twice, optimize the procedure. at the first time call ,just to do the sensor init.
-
-*v0.x.1c:
-*         1. fix query resolution error;
-*v0.x.1d: 
-*         1. add mv9335+ov5650 driver;
-*         2. fix 2928 digitzoom erro(arm crop scale) of selected zone;
-*v0.x.1f:
-*         1. support rk3188
-*v0.x.21:
-                 1. cif change mode to free run.support icatch 7002.
+*v0.1.0 : this driver is 3.10 kernel driver;
+               copy and updata from v0.3.0x19;
+               support rk312x;
+*v0.1.1:
+         1. spin lock in struct rk_cif_clk is not neccessary,and scheduled func clk_get called in this spin lock scope
+            cause warning, so remove this spin lock .
+*v0.1.2:
+                1. rk3126 and rk3128 use different dts file.            
+*v0.1.3:
+                1. i2c 1 and wifi use the common io in rk3128,so just enable i2c1 in rk3126 dts file
+*v0.1.4:
+                1. When cif was at work, the aclk is closed ,may cause bus abnormal ,so sleep 100ms before close aclk 
+*v0.1.5:       
+           1. Improve the code to support all configuration.reset,af,flash...
+*v0.1.6:
+                1. Delete SOCAM_DATAWIDTH_8 in SENSOR_BUS_PARAM parameters,it conflict with V4L2_MBUS_PCLK_SAMPLE_FALLING.
+*v0.1.7:
+                1. Add  power and powerdown controled by PMU.
+*v0.1.8:
+                1. Support front and rear camera support are the same.
+*v0.1.9:
+                1. Support pingpong mode.
+                2. Fix cif_clk_out cannot close which base on XIN24M and cannot turn to 0.
+                3. Move Camera Sensor Macro from rk_camera.h to rk_camera_sensor_info.h
 */
-#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 4, 0x21)
+#define RK_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 0x9)
+static int version = RK_CAM_VERSION_CODE;
+module_param(version, int, S_IRUGO);
 
 /* limit to rk29 hardware capabilities */
-#define RK_CAM_BUS_PARAM   (SOCAM_MASTER |\
-                SOCAM_HSYNC_ACTIVE_HIGH |\
-                SOCAM_HSYNC_ACTIVE_LOW |\
-                SOCAM_VSYNC_ACTIVE_HIGH |\
-                SOCAM_VSYNC_ACTIVE_LOW |\
-                SOCAM_PCLK_SAMPLE_RISING |\
-                SOCAM_PCLK_SAMPLE_FALLING|\
-                SOCAM_DATA_ACTIVE_HIGH |\
-                SOCAM_DATA_ACTIVE_LOW|\
+#define RK_CAM_BUS_PARAM   (V4L2_MBUS_MASTER |\
+                V4L2_MBUS_HSYNC_ACTIVE_HIGH |\
+                V4L2_MBUS_HSYNC_ACTIVE_LOW |\
+                V4L2_MBUS_VSYNC_ACTIVE_HIGH |\
+                V4L2_MBUS_VSYNC_ACTIVE_LOW |\
+                V4L2_MBUS_PCLK_SAMPLE_RISING |\
+                V4L2_MBUS_PCLK_SAMPLE_FALLING|\
+                V4L2_MBUS_DATA_ACTIVE_HIGH |\
+                V4L2_MBUS_DATA_ACTIVE_LOW|\
                 SOCAM_DATAWIDTH_8|SOCAM_DATAWIDTH_10|\
                 SOCAM_MCLK_24MHZ |SOCAM_MCLK_48MHZ)
 
 #define RK_CAM_W_MIN        48
 #define RK_CAM_H_MIN        32
-#define RK_CAM_W_MAX        3856            /* ddl@rock-chips.com : 10M Pixel */
+#define RK_CAM_W_MAX        3856                /* ddl@rock-chips.com : 10M Pixel */
 #define RK_CAM_H_MAX        2764
-#define RK_CAM_FRAME_INVAL_INIT 0
-#define RK_CAM_FRAME_INVAL_DC 0          /* ddl@rock-chips.com :  */
-#define RK30_CAM_FRAME_MEASURE  5
+#define RK_CAM_FRAME_INVAL_INIT      0
+#define RK_CAM_FRAME_INVAL_DC        0          /* ddl@rock-chips.com :  */
+#define RK30_CAM_FRAME_MEASURE       5
+
+
 extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf);
 extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf);
-
 /* buffer for one video frame */
 struct rk_camera_buffer
 {
@@ -337,7 +319,6 @@ struct rk_camera_buffer
     enum v4l2_mbus_pixelcode   code;
     int                        inwork;
 };
-
 enum rk_camera_reg_state
 {
        Reg_Invalidate,
@@ -353,7 +334,7 @@ struct rk_camera_reg
        unsigned int cifFmt;
     unsigned int cifVirWidth;
     unsigned int cifScale;
-//     unsigned int VipCrm;
+/*     unsigned int VipCrm;*/
        enum rk_camera_reg_state Inval;
 };
 struct rk_camera_work
@@ -362,31 +343,26 @@ struct rk_camera_work
        struct rk_camera_dev *pcdev;
        struct work_struct work;
     struct list_head queue;
-    unsigned int index; 
-    unsigned int ts;
+    unsigned int index;    
 };
-
 struct rk_camera_frmivalenum
 {
     struct v4l2_frmivalenum fival;
     struct rk_camera_frmivalenum *nxt;
 };
-
 struct rk_camera_frmivalinfo
 {
     struct soc_camera_device *icd;
     struct rk_camera_frmivalenum *fival_list;
 };
-
 struct rk_camera_zoominfo
 {
     struct semaphore sem;
     struct v4l2_crop a;
     int vir_width;
-   int vir_height;
+    int vir_height;
     int zoom_rate;
 };
-
 #if CAMERA_VIDEOBUF_ARM_ACCESS
 struct rk29_camera_vbinfo
 {
@@ -395,37 +371,25 @@ struct rk29_camera_vbinfo
     unsigned int size;
 };
 #endif
-
 struct rk_camera_timer{
        struct rk_camera_dev *pcdev;
        struct hrtimer timer;
     bool istarted;
 };
-struct rk_cif_clk
+struct rk_cif_clk 
 {
-    //************must modify start************/
-    struct clk *pd_cif;
-    struct clk *aclk_cif;
+    /************must modify start************/
+       struct clk *pd_cif;
+       struct clk *aclk_cif;
     struct clk *hclk_cif;
     struct clk *cif_clk_in;
     struct clk *cif_clk_out;
-    //************must modify end************/
+       /************must modify end************/
 
-    spinlock_t lock;
+   // spinlock_t lock;
     bool on;
 };
-static struct rk_cif_clk  cif_clk[2];
-struct hdr_exposure
-{
-    unsigned int set_ts;
-    unsigned int get_ts;
-    unsigned int code;
-};
-struct rk_hdr_info_s
-{
-    bool en;
-    struct hdr_exposure frame[3];
-};
+
 struct rk_cif_crop
 {
     spinlock_t lock;
@@ -433,87 +397,84 @@ struct rk_cif_crop
     struct v4l2_rect bounds;
 };
 
-#define CONFIG_CIF_STOP_SYNC 1
+struct rk_cif_irqinfo
+{
+    unsigned int irq;
+    unsigned long cifirq_idx;
+    unsigned long cifirq_normal_idx;
+    unsigned long cifirq_abnormal_idx;
+
+    unsigned long dmairq_idx;
+    spinlock_t lock;
+};
 
 struct rk_camera_dev
 {
-       struct soc_camera_host  soc_host;
-       struct device           *dev;
-       /* RK2827x is only supposed to handle one camera on its Quick Capture
-        * interface. If anyone ever builds hardware to enable more than
-        * one camera, they will have to modify this driver too */
-       struct soc_camera_device *icd;
+    struct soc_camera_host     soc_host;    
+    struct device              *dev;
+    /* RK2827x is only supposed to handle one camera on its Quick Capture
+     * interface. If anyone ever builds hardware to enable more than
+     * one camera, they will have to modify this driver too */
+    struct soc_camera_device *icd;
+    void __iomem *base;
+    int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
 
-       //************must modify start************/
-       struct clk *pd_cif;
-       struct clk *aclk_cif;
-    struct clk *hclk_cif;
-    struct clk *cif_clk_in;
-    struct clk *cif_clk_out;
-       //************must modify end************/
-       void __iomem *base;
-       int frame_inval;           /* ddl@rock-chips.com : The first frames is invalidate  */
-       unsigned int irq;
-       unsigned int fps;
+    unsigned int fps;
     unsigned int last_fps;
     unsigned long frame_interval;
-       unsigned int pixfmt;
-       //for ipp       
-       unsigned int vipmem_phybase;
+    unsigned int pixfmt;
+    /*for ipp  */
+    unsigned int vipmem_phybase;
     void __iomem *vipmem_virbase;
-       unsigned int vipmem_size;
-       unsigned int vipmem_bsize;
+    unsigned int vipmem_size;
+    unsigned int vipmem_bsize;
 #if CAMERA_VIDEOBUF_ARM_ACCESS    
     struct rk29_camera_vbinfo *vbinfo;
-#endif  
-       unsigned int vbinfo_count;
-
-       int host_width;
-       int host_height;
-       int host_left;  //sensor output size ?
-       int host_top;
-       int hostid;
+    unsigned int vbinfo_count;
+#endif    
+    int host_width;
+    int host_height;
+    int host_left;  /*sensor output size ?*/
+    int host_top;
+    int hostid;
     int icd_width;
     int icd_height;
+
     struct rk_cif_crop cropinfo;
+    struct rk_cif_irqinfo irqinfo;
 
-       struct rk29camera_platform_data *pdata;
-       struct resource         *res;
-       struct list_head        capture;
-       struct rk_camera_zoominfo zoominfo;
+    struct rk29camera_platform_data *pdata;
+    struct resource            *res;
+    struct list_head   capture;
+    struct rk_camera_zoominfo zoominfo;
 
-       spinlock_t              lock;
+    spinlock_t         lock;
 
        struct videobuf_buffer  *active0;
        struct videobuf_buffer  *active1;
-       struct rk_camera_reg reginfo_suspend;
-       struct workqueue_struct *camera_wq;
-       struct rk_camera_work *camera_work;
+       int active_buf;
+    struct rk_camera_reg reginfo_suspend;
+    struct workqueue_struct *camera_wq;
+    struct rk_camera_work *camera_work;
     struct list_head camera_work_queue;
     spinlock_t camera_work_lock;
-       unsigned int camera_work_count;
-       struct rk_camera_timer fps_timer;
-       struct rk_camera_work camera_reinit_work;
-       int icd_init;
-       rk29_camera_sensor_cb_s icd_cb;
-       struct rk_camera_frmivalinfo icd_frmival[2];
+    unsigned int camera_work_count;
+    struct rk_camera_timer fps_timer;
+    struct rk_camera_work camera_reinit_work;
+    int icd_init;
+    rk29_camera_sensor_cb_s icd_cb;
+    struct rk_camera_frmivalinfo icd_frmival[2];
     bool timer_get_fps;
     unsigned int reinit_times; 
     struct videobuf_queue *video_vq;
-    volatile bool stop_cif;
-#if CONFIG_CIF_STOP_SYNC
-       wait_queue_head_t cif_stop_done;
-       volatile  bool cif_stopped;
-#endif
+    atomic_t stop_cif;
     struct timeval first_tv;
-
-    struct rk_hdr_info_s  hdr_info;
-//     spinlock_t              irq_lock;
+    
+    int chip_id;
 };
 
 static const struct v4l2_queryctrl rk_camera_controls[] =
 {
-       #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
     {
         .id            = V4L2_CID_ZOOM_ABSOLUTE,
         .type          = V4L2_CTRL_TYPE_INTEGER,
@@ -522,29 +483,84 @@ static const struct v4l2_queryctrl rk_camera_controls[] =
         .maximum       = 300,
         .step          = 5,
         .default_value = 100,
-    },
-    #endif
-
-    {
-        .id            = V4L2_CID_HDR,
-        .type          = V4L2_CTRL_TYPE_BOOLEAN,
-        .name          = "HDR",
-        .minimum       = 0,
-        .maximum       = 1,
-        .step          = 1,
-        .default_value = 0,
     }
-
-    
 };
 
+static struct rk_cif_clk  cif_clk[2];
+
 static DEFINE_MUTEX(camera_lock);
 static const char *rk_cam_driver_description = "RK_Camera";
 
 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable);
 static void rk_camera_capture_process(struct work_struct *work);
 
-// #define OPTIMIZE_MEMORY_USE
+static void rk_camera_diffchips(const char *rockchip_name)
+{
+       if(strstr(rockchip_name,"3128")||strstr(rockchip_name,"3126"))
+       {       
+               CRU_PCLK_REG30 = 0xbc;
+               ENANABLE_INVERT_PCLK_CIF0 = ((0x1<<23)|(0x1<<7));
+               DISABLE_INVERT_PCLK_CIF0  = ((0x1<<23)|(0x0<<7));
+               ENANABLE_INVERT_PCLK_CIF1 = ENANABLE_INVERT_PCLK_CIF0;
+               DISABLE_INVERT_PCLK_CIF1  = DISABLE_INVERT_PCLK_CIF0;
+               
+               CRU_CLK_OUT = 0xdc;
+               CRU_CLKSEL29_CON = 0xb8;
+
+               CHIP_NAME = 3126;
+       }
+}
+static inline void rk_cru_set_soft_reset(u32 idx, bool on , u32 RK_CRU_SOFTRST_CON)
+{
+       void __iomem *reg = RK_CRU_VIRT + RK_CRU_SOFTRST_CON;
+       u32 val = on ? 0x10001U << 14 : 0x10000U << 14;
+       writel_relaxed(val, reg);
+       dsb();
+}
+
+static void rk_camera_cif_reset(struct rk_camera_dev *pcdev, int only_rst)
+{
+    int ctrl_reg,inten_reg,crop_reg,set_size_reg,for_reg,vir_line_width_reg,scl_reg,y_reg,uv_reg;
+       u32 RK_CRU_SOFTRST_CON = 0;
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+       if(strstr(pcdev->pdata->rockchip_name,"3128")||strstr(pcdev->pdata->rockchip_name,"3126"))
+               RK_CRU_SOFTRST_CON = RK312X_CRU_SOFTRSTS_CON(6);
+       
+       if (only_rst == true) {
+        rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
+        udelay(5);
+        rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON);
+    } else {
+        ctrl_reg = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+        if (ctrl_reg & ENABLE_CAPTURE) {
+            write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
+        }
+       crop_reg = read_cif_reg(pcdev->base,CIF_CIF_CROP);
+       set_size_reg = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
+       inten_reg = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
+       for_reg = read_cif_reg(pcdev->base,CIF_CIF_FOR);
+       vir_line_width_reg = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
+       scl_reg = read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
+       y_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_Y);
+       uv_reg = read_cif_reg(pcdev->base, CIF_CIF_FRM0_ADDR_UV);
+       
+       rk_cru_set_soft_reset(0, true ,RK_CRU_SOFTRST_CON);
+       udelay(5);
+       rk_cru_set_soft_reset(0, false ,RK_CRU_SOFTRST_CON); 
+
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, ctrl_reg&~ENABLE_CAPTURE);
+           write_cif_reg(pcdev->base,CIF_CIF_INTEN, inten_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_CROP, crop_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, set_size_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_FOR, for_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,vir_line_width_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,scl_reg);
+           write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y,y_reg);      /*ddl@rock-chips.com v0.3.0x13 */
+           write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV,uv_reg);
+    }
+    return;
+}
+
 
 /*
  *  Videobuf operations
@@ -553,7 +569,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
                                unsigned int *size)
 {
     struct soc_camera_device *icd = vq->priv_data;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
        unsigned int i;
     struct rk_camera_work *wk;
@@ -563,6 +579,9 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
        int bytes_per_line_host;
        fmt.packing = SOC_MBUS_PACKING_1_5X8;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
                bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
                                                icd->current_fmt->host_fmt);
        if(icd->current_fmt->host_fmt->fourcc ==  V4L2_PIX_FMT_RGB565)
@@ -573,6 +592,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
        else
                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);*/ /*yzm*/
 
        if (bytes_per_line_host < 0)
                return bytes_per_line_host;
@@ -582,17 +602,14 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
        pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line_host * pcdev->host_height);
 
        if (CAM_WORKQUEUE_IS_EN()) {
-        #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_OFF
-        if (CAM_IPPWORK_IS_EN()) 
-        #endif
-        {
+               
+        if (CAM_IPPWORK_IS_EN())  {
             BUG_ON(pcdev->vipmem_size<pcdev->vipmem_bsize);
-        #ifndef OPTIMIZE_MEMORY_USE
                if (*count > pcdev->vipmem_size/pcdev->vipmem_bsize) {    /* Buffers must be limited, when this resolution is genered by IPP */
                        *count = pcdev->vipmem_size/pcdev->vipmem_bsize;
                }
-               #endif
         }
+        
                if ((pcdev->camera_work_count != *count) && pcdev->camera_work) {
                        kfree(pcdev->camera_work);
                        pcdev->camera_work = NULL;
@@ -602,7 +619,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
                if (pcdev->camera_work == NULL) {
                        pcdev->camera_work = wk = kzalloc(sizeof(struct rk_camera_work)*(*count), GFP_KERNEL);
                        if (pcdev->camera_work == NULL) {
-                               RK30_CAM_DEBUG_TRACE("\n %s kmalloc fail\n", __FUNCTION__);
+                               RKCAMERA_TR("kmalloc failed\n");
                                BUG();
                        }
             INIT_LIST_HEAD(&pcdev->camera_work_queue);
@@ -624,7 +641,7 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
         if (pcdev->vbinfo == NULL) {
             pcdev->vbinfo = kzalloc(sizeof(struct rk29_camera_vbinfo)*(*count), GFP_KERNEL);
             if (pcdev->vbinfo == NULL) {
-                               RK30_CAM_DEBUG_TRACE("\n %s vbinfo kmalloc fail\n", __FUNCTION__);
+                               RKCAMERA_TR("vbinfo kmalloc fail\n");
                                BUG();
                        }
             memset(pcdev->vbinfo,0,sizeof(struct rk29_camera_vbinfo)*(*count));
@@ -632,10 +649,8 @@ static int rk_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
         }
 #endif        
        }
-       
-       pcdev->vbinfo_count = *count;
     pcdev->video_vq = vq;
-    RK30_CAM_DEBUG_TRACE("%s..%d.. videobuf size:%d, vipmem_buf size:%d, count:%d \n",__FUNCTION__,__LINE__, *size,pcdev->vipmem_size, *count);
+    RKCAMERA_DG1("videobuf size:%d, vipmem_buf size:%d, count:%d \n",*size,pcdev->vipmem_size, *count);
 
     return 0;
 }
@@ -643,7 +658,10 @@ static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer
 {
     struct soc_camera_device *icd = vq->priv_data;
 
-    dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+
+    dev_dbg(icd->control, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,/*yzm*/
             &buf->vb, buf->vb.baddr, buf->vb.bsize);
 
        /* ddl@rock-chips.com: buf_release called soc_camera_streamoff and soc_camera_close*/
@@ -656,9 +674,9 @@ static void rk_videobuf_free(struct videobuf_queue *vq, struct rk_camera_buffer
         * This waits until this buffer is out of danger, i.e., until it is no
         * longer in STATE_QUEUED or STATE_ACTIVE
         */
-       //videobuf_waiton(vq, &buf->vb, 0, 0);
+       videobuf_waiton(vq, &buf->vb, 0, 0);
     videobuf_dma_contig_free(vq, &buf->vb);
-    dev_dbg(&icd->dev, "%s freed\n", __func__);
+    /*dev_dbg(&icd->dev, "%s freed\n", __func__);*/ /*yzm*/
     buf->vb.state = VIDEOBUF_NEEDS_INIT;
        return;
 }
@@ -669,13 +687,16 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer
     int ret;
     int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
                                                icd->current_fmt->host_fmt);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+       
        if ((bytes_per_line < 0) || (vb->boff == 0))
                return -EINVAL;
 
     buf = container_of(vb, struct rk_camera_buffer, vb);
 
-    dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
-            vb, vb->baddr, vb->bsize);
+    /*dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,*/ /*yzm*/
+      /*      vb, vb->baddr, vb->bsize);*/ /*yzm*/
     
     /* Added list head initialization on alloc */
     WARN_ON(!list_empty(&vb->queue));    
@@ -683,9 +704,9 @@ static int rk_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer
     BUG_ON(NULL == icd->current_fmt);
 
     if (buf->code    != icd->current_fmt->code ||
-        vb->width   != icd->user_width ||
-        vb->height  != icd->user_height ||
-        vb->field   != field) {
+            vb->width   != icd->user_width ||
+            vb->height  != icd->user_height ||
+             vb->field   != field) {
         buf->code    = icd->current_fmt->code;
         vb->width   = icd->user_width;
         vb->height  = icd->user_height;
@@ -714,77 +735,46 @@ out:
     return ret;
 }
 
-#if 0
-static void rk_camera_store_register(struct rk_camera_dev *pcdev)
-{
-#if defined(CONFIG_ARCH_RK3188)
-       pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
-       pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
-       pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
-       pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
-       pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
-       pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
-       pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
-       
-       cru_set_soft_reset(SOFT_RST_CIF0, true);
-       udelay(3);
-       cru_set_soft_reset(SOFT_RST_CIF0, false);
-       
-#endif
-}
-static void rk_camera_restore_register(struct rk_camera_dev *pcdev)
-{
-#if defined(CONFIG_ARCH_RK3188)
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
-       write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
-       write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
-       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
-       write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
-       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
-       write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
-#endif
-}
-#endif
-
 static inline void rk_videobuf_capture(struct videobuf_buffer *vb,struct rk_camera_dev *rk_pcdev, int fmt_ready)
 {
        unsigned int y_addr,uv_addr;
        struct rk_camera_dev *pcdev = rk_pcdev;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+
     if (vb) {
-               if (CAM_WORKQUEUE_IS_EN()) {
-                   #ifdef OPTIMIZE_MEMORY_USE
-                       y_addr = vb->boff;
-                       uv_addr = y_addr + vb->width * vb->height;
-                   #else
+               if (CAM_WORKQUEUE_IS_EN() & CAM_IPPWORK_IS_EN()) {
                        y_addr = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
                        uv_addr = y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
                        if (y_addr > (pcdev->vipmem_phybase + pcdev->vipmem_size - pcdev->vipmem_bsize)) {
-                               RK30_CAM_DEBUG_TRACE("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
+                               RKCAMERA_TR("vipmem for IPP is overflow! %dx%d -> %dx%d vb_index:%d\n",pcdev->host_width,pcdev->host_height,
                                                  pcdev->icd->user_width,pcdev->icd->user_height, vb->i);
                                BUG();
                        }
-                       #endif
                } else {
                        y_addr = vb->boff;
                        uv_addr = y_addr + vb->width * vb->height;
                }
-        
-               switch(fmt_ready)
-               {
-                       case 0:
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
-                       write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
-                               break;
-                       case 1:
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
-                       write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
-                               break;
-                       default:
-                               RK30_CAM_DEBUG_TRACE("%s(%d): fmt_ready(%d) is wrong!\n", __FUNCTION__, __LINE__,fmt_ready);
-                               break;
-               }
-      
+#if defined(CONFIG_ARCH_RK3188)
+               rk_camera_cif_reset(pcdev,false);
+#endif
+
+       switch(fmt_ready)
+       {
+               case 0:
+                       write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, y_addr);
+                       write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, uv_addr);
+                       break;
+               case 1:
+                       write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, y_addr);
+                       write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, uv_addr);
+                       break;
+               default:
+                       printk("%s(%d): fmt_ready(%d) is wrong!\n", __FUNCTION__, __LINE__,fmt_ready);
+                       break;
+       }
+
     }
 }
 /* Locking: Caller holds q->irqlock */
@@ -792,15 +782,14 @@ static void rk_videobuf_queue(struct videobuf_queue *vq,
                                 struct videobuf_buffer *vb)
 {
     struct soc_camera_device *icd = vq->priv_data;
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
 #if CAMERA_VIDEOBUF_ARM_ACCESS    
     struct rk29_camera_vbinfo *vb_info;
 #endif
 
-    dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
-            vb, vb->baddr, vb->bsize);
-   // spin_lock_irqsave(&pcdev->irq_lock, flags);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
     vb->state = VIDEOBUF_QUEUED;
        if (list_empty(&pcdev->capture)) {
@@ -831,56 +820,40 @@ static void rk_videobuf_queue(struct videobuf_queue *vq,
                 vb_info->size = vb->bsize;
                 vb_info->phy_addr = vb->boff;
             } else {
-                RK30_CAM_DEBUG_TRACE("%s..%d:ioremap videobuf %d failed\n",__FUNCTION__,__LINE__, vb->i);
+                RKCAMERA_TR("ioremap videobuf %d failed\n",vb->i);
             }
         }
     }
-#endif
-    if((((read_cif_reg(pcdev->base,CIF_CIF_CTRL)) & ENABLE_CAPTURE) == 0)){
-        if (!pcdev->active0) {
-            pcdev->active0 = vb;
-            rk_videobuf_capture(vb,pcdev,0);
-               list_del_init(&(vb->queue));
-        } else if (!pcdev->active1) {
-            pcdev->active1 = vb;
-            rk_videobuf_capture(vb,pcdev,1);
-               list_del_init(&(vb->queue));
-        }
-    }
-       //spin_unlock_irqrestore(&pcdev->irq_lock, flags);
-}
-static int rk_pixfmt2ippfmt(unsigned int pixfmt, int *ippfmt)
-{
-       switch (pixfmt)
-       {
-               case V4L2_PIX_FMT_NV16:
-               case V4L2_PIX_FMT_NV61:
-               {
-                       *ippfmt = IPP_Y_CBCR_H2V1;
-                       break;
-               }
-               case V4L2_PIX_FMT_NV12:
-               case V4L2_PIX_FMT_NV21:
-               {
-                       *ippfmt = IPP_Y_CBCR_H2V2;
-                       break;
-               }
-               default:
-                       goto rk_pixfmt2ippfmt_err;
-       }
+#endif    
 
-       return 0;
-rk_pixfmt2ippfmt_err:
-       return -1;
+       if (!pcdev->active0) {
+               pcdev->active0 = vb;
+               rk_videobuf_capture(vb,pcdev,0);                
+        /*if (atomic_read(&pcdev->stop_cif) == false) {           //ddl@rock-chips.com v0.3.0x13
+            write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
+        }  */     
+               list_del_init(&(vb->queue));
+       } else if (!pcdev->active1) {
+               pcdev->active1 = vb;
+               rk_videobuf_capture(vb,pcdev,1);
+        /*if (atomic_read(&pcdev->stop_cif) == false) {           //ddl@rock-chips.com v0.3.0x13
+            write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
+        } */           
+               list_del_init(&(vb->queue));
+       }
+       
 }
 
-#if 0
+#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_RGA)
 static int rk_pixfmt2rgafmt(unsigned int pixfmt, int *ippfmt)
 {
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
        switch (pixfmt)
        {
                case V4L2_PIX_FMT_YUV420:
-               case V4L2_PIX_FMT_UYVY: // yuv 422, but sensor has defined this format(in fact ,should be defined yuv 420), treat this as yuv 420.
+               case V4L2_PIX_FMT_UYVY: /* yuv 422, but sensor has defined this format(in fact ,should be defined yuv 420), treat this as yuv 420.*/
                case V4L2_PIX_FMT_YUYV: 
                        {
                                *ippfmt = RK_FORMAT_YCbCr_420_SP;
@@ -912,7 +885,6 @@ rk_pixfmt2rgafmt_err:
        return -1;
 }
 #endif
-
 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
 static int rk_camera_scale_crop_pp(struct work_struct *work){
        struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
@@ -922,33 +894,8 @@ static int rk_camera_scale_crop_pp(struct work_struct *work){
        unsigned long int flags;
        int scale_times,w,h;
        int src_y_offset;
-       PP_OP_HANDLE hnd;
-       PP_OPERATION init;
        int ret = 0;
-       vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
-       
-       memset(&init, 0, sizeof(init));
-       init.srcAddr    = vipdata_base;
-       init.srcFormat  = PP_IN_FORMAT_YUV420SEMI;
-       init.srcWidth   = init.srcHStride = pcdev->zoominfo.vir_width;
-       init.srcHeight  = init.srcVStride = pcdev->zoominfo.vir_height;
-       
-       init.dstAddr    = vb->boff;
-       init.dstFormat  = PP_OUT_FORMAT_YUV420INTERLAVE;
-       init.dstWidth   = init.dstHStride = pcdev->icd->user_width;
-       init.dstHeight  = init.dstVStride = pcdev->icd->user_height;
-
-       printk("srcWidth = %d,srcHeight = %d,dstWidth = %d,dstHeight = %d\n",init.srcWidth,init.srcHeight,init.dstWidth,init.dstHeight);
-       #if 0
-       ret = ppOpInit(&hnd, &init);
-       if (!ret) {
-               ppOpPerform(hnd);
-               ppOpSync(hnd);
-               ppOpRelease(hnd);
-       } else {
-               printk("can not create ppOp handle\n");
-       }
-       #endif
+
        return ret;
 }
 #endif
@@ -969,414 +916,43 @@ static int rk_camera_scale_crop_rga(struct work_struct *work){
        int rga_times = 3;
        const struct soc_mbus_pixelfmt *fmt;
        int ret = 0;
-       fmt = soc_mbus_get_fmtdesc(pcdev->icd->current_fmt->code);
-       vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
-       if((pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB565)
-               && (pcdev->icd->current_fmt->host_fmt->fourcc != V4L2_PIX_FMT_RGB24)){
-               RK30_CAM_DEBUG_TRACE("RGA not support this format !\n");
-               goto do_ipp_err;
-               }
-       if ((pcdev->icd->user_width > 0x800) || (pcdev->icd->user_height > 0x800)) {
-               scale_times = MAX((pcdev->icd->user_width/0x800),(pcdev->icd->user_height/0x800));                
-               scale_times++;
-       } else {
-               scale_times = 1;
-       }
-       session.pid = current->pid;
-       INIT_LIST_HEAD(&session.waiting);
-       INIT_LIST_HEAD(&session.running);
-       INIT_LIST_HEAD(&session.list_session);
-       init_waitqueue_head(&session.wait);
-       /* no need to protect */
-       list_add_tail(&session.list_session, &rga_service.session);
-       atomic_set(&session.task_running, 0);
-       atomic_set(&session.num_done, 0);
-       
-       memset(&req,0,sizeof(struct rga_req));
-       req.src.act_w = pcdev->zoominfo.a.c.width/scale_times;
-       req.src.act_h = pcdev->zoominfo.a.c.height/scale_times;
-
-       req.src.vir_w = pcdev->zoominfo.vir_width;
-       req.src.vir_h =pcdev->zoominfo.vir_height;
-       req.src.yrgb_addr = vipdata_base;
-       req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
-       req.src.v_addr = req.src.uv_addr ;
-       req.src.format =fmt->fourcc;
-       rk_pixfmt2rgafmt(fmt->fourcc,&req.src.format);
-       req.src.x_offset = pcdev->zoominfo.a.c.left;
-       req.src.y_offset = pcdev->zoominfo.a.c.top;
-
-       req.dst.act_w = pcdev->icd->user_width/scale_times;
-       req.dst.act_h = pcdev->icd->user_height/scale_times;
-
-       req.dst.vir_w = pcdev->icd->user_width;
-       req.dst.vir_h = pcdev->icd->user_height;
-       req.dst.x_offset = 0;
-       req.dst.y_offset = 0;
-       req.dst.yrgb_addr = vb->boff;
-       rk_pixfmt2rgafmt(pcdev->icd->current_fmt->host_fmt->fourcc,&req.dst.format);
-       req.clip.xmin = 0;
-       req.clip.xmax = req.dst.vir_w-1;
-       req.clip.ymin = 0;
-       req.clip.ymax = req.dst.vir_h -1;
-
-       req.rotate_mode = 1;
-       req.scale_mode = 2;
-
-       req.sina = 0;
-       req.cosa = 65536;
-       req.mmu_info.mmu_en = 0;
-
-       for (h=0; h<scale_times; h++) {
-               for (w=0; w<scale_times; w++) {
-                       rga_times = 3;
-       
-                       req.src.yrgb_addr = vipdata_base;
-                       req.src.uv_addr =vipdata_base + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;;
-                       req.src.x_offset = pcdev->zoominfo.a.c.left+w*pcdev->zoominfo.a.c.width/scale_times;
-                       req.src.y_offset = pcdev->zoominfo.a.c.top+h*pcdev->zoominfo.a.c.height/scale_times;
-                       req.dst.x_offset =  pcdev->icd->user_width*w/scale_times;
-                       req.dst.y_offset = pcdev->icd->user_height*h/scale_times;
-                       req.dst.yrgb_addr = vb->boff ;
-               //      RK30_CAM_DEBUG_TRACE("src.act_w = %d , src.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.src.act_w,req.src.act_h ,req.src.vir_w,req.src.vir_h,req.src.x_offset,req.src.y_offset);
-               //      RK30_CAM_DEBUG_TRACE("dst.act_w = %d , dst.act_h  = %d! vir_w = %d , vir_h = %d,off_x = %d,off_y = %d\n",req.dst.act_w,req.dst.act_h ,req.dst.vir_w,req.dst.vir_h,req.dst.x_offset,req.dst.y_offset);
-               //      RK30_CAM_DEBUG_TRACE("req.src.yrgb_addr = 0x%x,req.dst.yrgb_addr = 0x%x\n",req.src.yrgb_addr,req.dst.yrgb_addr);
-
-                       while(rga_times-- > 0) {
-                               if (rga_blit_sync(&session, &req)){
-                                       RK30_CAM_DEBUG_TRACE("rga do erro,do again,rga_times = %d!\n",rga_times);
-                                } else {
-                                       break;
-                                }
-                       }
-               
-                       if (rga_times <= 0) {
-                               spin_lock_irqsave(&pcdev->lock, flags);
-                               vb->state = VIDEOBUF_NEEDS_INIT;
-                               spin_unlock_irqrestore(&pcdev->lock, flags);
-                               mutex_lock(&rga_service.lock);
-                               list_del(&session.list_session);
-                               rga_service_session_clear(&session);
-                               mutex_unlock(&rga_service.lock);
-                               goto session_done;
-                       }
-                       }
-       }
-       session_done:
-       mutex_lock(&rga_service.lock);
-       list_del(&session.list_session);
-       rga_service_session_clear(&session);
-       mutex_unlock(&rga_service.lock);
 
-       do_ipp_err:
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
 
                return ret;
        
 }
 
 #endif
-#if ((defined(CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON)) && (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP))
+#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
 
 static int rk_camera_scale_crop_ipp(struct work_struct *work)
 {
-       struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
-       struct videobuf_buffer *vb = camera_work->vb;
-       struct rk_camera_dev *pcdev = camera_work->pcdev;
-       int vipdata_base;
-       unsigned long int flags;
-
-       struct rk29_ipp_req ipp_req;
-       int src_y_offset,src_uv_offset,dst_y_offset,dst_uv_offset,src_y_size,dst_y_size;
-       int scale_times,w,h;
-       int ret = 0;
-    /*
-    *ddl@rock-chips.com: 
-    * IPP Dest image resolution is 2047x1088, so scale operation break up some times
-    */
-    if ((pcdev->icd->user_width > 0x7f0) || (pcdev->icd->user_height > 0x430)) {
-        scale_times = MAX((pcdev->icd->user_width/0x7f0),(pcdev->icd->user_height/0x430));        
-        scale_times++;
-    } else {
-        scale_times = 1;
-    }
-    memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
-#ifdef OPTIMIZE_MEMORY_USE
-    //need copy to ipp buffer?
-    if((pcdev->zoominfo.a.c.width != pcdev->zoominfo.vir_width)
-        ||(pcdev->zoominfo.a.c.height != pcdev->zoominfo.vir_height)){
-            if((pcdev->zoominfo.vir_width != pcdev->icd->user_width) || (pcdev->zoominfo.vir_height != pcdev->icd->user_height)){
-                printk("OPTIMIZE_MEMORY_USE erro: src size not equal to dst size\n");
-                goto do_ipp_err;
-            }
-            ipp_req.timeout = 3000;
-            ipp_req.flag = IPP_ROT_0; 
-            ipp_req.store_clip_mode =1;
-            ipp_req.src0.w = pcdev->zoominfo.vir_width/scale_times;
-            ipp_req.src0.h = pcdev->zoominfo.vir_height/scale_times;
-            ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
-            ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
-            ipp_req.src_vir_w =  pcdev->zoominfo.vir_width; 
-            ipp_req.dst_vir_w = pcdev->icd->user_width; 
-            rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
-            rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
-            vipdata_base = pcdev->vipmem_phybase;
-            src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;  //vipmem
-            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++) {
-                    src_y_offset = (h*pcdev->zoominfo.vir_height/scale_times)* pcdev->zoominfo.vir_width 
-                                +  w*pcdev->zoominfo.vir_width/scale_times;
-                           src_uv_offset = (h*pcdev->zoominfo.vir_height/scale_times)* pcdev->zoominfo.vir_width/2
-                                + w*pcdev->zoominfo.vir_width/scale_times;
-
-                    dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
-                    dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
-                       ipp_req.src0.YrgbMst = vb->boff + src_y_offset;
-                       ipp_req.src0.CbrMst = vb->boff + src_y_size + src_uv_offset;
-                       ipp_req.dst0.YrgbMst = vipdata_base + dst_y_offset;
-                       ipp_req.dst0.CbrMst = vipdata_base + dst_y_size + dst_uv_offset;
-                    if (ipp_blit_sync(&ipp_req)){
-                        RK30_CAM_DEBUG_TRACE("ipp do erro\n");
-                     }
-                 }
-             }
-            memset(&ipp_req, 0, sizeof(struct rk29_ipp_req));
-        }
-#endif
-
-    ipp_req.timeout = 3000;
-    ipp_req.flag = IPP_ROT_0; 
-    ipp_req.store_clip_mode =1;
-    ipp_req.src0.w = pcdev->zoominfo.a.c.width/scale_times;
-    ipp_req.src0.h = pcdev->zoominfo.a.c.height/scale_times;
-    ipp_req.src_vir_w = pcdev->zoominfo.vir_width; 
-    rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.src0.fmt);
-    ipp_req.dst0.w = pcdev->icd->user_width/scale_times;
-    ipp_req.dst0.h = pcdev->icd->user_height/scale_times;
-    ipp_req.dst_vir_w = pcdev->icd->user_width;        
-    rk_pixfmt2ippfmt(pcdev->pixfmt, &ipp_req.dst0.fmt);
-#ifdef OPTIMIZE_MEMORY_USE
-    if((pcdev->zoominfo.a.c.width != pcdev->zoominfo.vir_width)
-        ||(pcdev->zoominfo.a.c.height != pcdev->zoominfo.vir_height)){
-        vipdata_base = pcdev->vipmem_phybase;
-    }else
-        vipdata_base = vb->boff;
-
-#else
-    vipdata_base = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;
-#endif
-    src_y_size = pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;  //vipmem
-    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++) {
-            int ipp_times = 3;
-            src_y_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width 
-                        + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
-                   src_uv_offset = (pcdev->zoominfo.a.c.top + h*pcdev->zoominfo.a.c.height/scale_times)* pcdev->zoominfo.vir_width/2
-                        + pcdev->zoominfo.a.c.left + w*pcdev->zoominfo.a.c.width/scale_times;
-
-            dst_y_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times + pcdev->icd->user_width*w/scale_times;
-            dst_uv_offset = pcdev->icd->user_width*pcdev->icd->user_height*h/scale_times/2 + pcdev->icd->user_width*w/scale_times;
-
-               ipp_req.src0.YrgbMst = vipdata_base + src_y_offset;
-               ipp_req.src0.CbrMst = vipdata_base + src_y_size + src_uv_offset;
-               ipp_req.dst0.YrgbMst = vb->boff + dst_y_offset;
-               ipp_req.dst0.CbrMst = vb->boff + dst_y_size + dst_uv_offset;
-               while(ipp_times-- > 0) {
-                if (ipp_blit_sync(&ipp_req)){
-                    RK30_CAM_DEBUG_TRACE("ipp do erro,do again,ipp_times = %d!\n",ipp_times);
-                 } else {
-                    break;
-                 }
-            }
-            
-            if (ipp_times <= 0) {
-                       spin_lock_irqsave(&pcdev->lock, flags);
-                       vb->state = VIDEOBUF_NEEDS_INIT;
-                       spin_unlock_irqrestore(&pcdev->lock, flags);
-                       RK30_CAM_DEBUG_TRACE("Capture image(vb->i:0x%x) which IPP operated is error:\n",vb->i);
-                       RK30_CAM_DEBUG_TRACE("widx:%d hidx:%d ",w,h);
-                       RK30_CAM_DEBUG_TRACE("%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);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.YrgbMst:0x%x ipp_req.src0.CbrMst:0x%x \n", ipp_req.src0.YrgbMst,ipp_req.src0.CbrMst);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.w:0x%x ipp_req.src0.h:0x%x \n",ipp_req.src0.w,ipp_req.src0.h);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.src0.fmt:0x%x\n",ipp_req.src0.fmt);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.YrgbMst:0x%x ipp_req.dst0.CbrMst:0x%x \n",ipp_req.dst0.YrgbMst,ipp_req.dst0.CbrMst);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.w:0x%x ipp_req.dst0.h:0x%x \n",ipp_req.dst0.w ,ipp_req.dst0.h);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.dst0.fmt:0x%x\n",ipp_req.dst0.fmt);
-                       RK30_CAM_DEBUG_TRACE("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);
-                       RK30_CAM_DEBUG_TRACE("ipp_req.timeout:0x%x ipp_req.flag :0x%x\n",ipp_req.timeout,ipp_req.flag);
-                
-                       goto do_ipp_err;
-               }
-        }
-    }
-
-do_ipp_err:
-       return ret;    
-}
-#endif
-#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
-static int rk_camera_scale_crop_arm(struct work_struct *work)
-{
-    struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);      
-    struct videobuf_buffer *vb = camera_work->vb;      
-    struct rk_camera_dev *pcdev = camera_work->pcdev;  
-    struct rk29_camera_vbinfo *vb_info;        
-    unsigned char *psY,*pdY,*psUV,*pdUV; 
-    unsigned char *src,*dst;
-    unsigned long src_phy,dst_phy;
-    int srcW,srcH,cropW,cropH,dstW,dstH;
-    long zoomindstxIntInv,zoomindstyIntInv;
-    long x,y;
-    long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
-    long sX,sY;
-    long r0,r1,a,b,c,d;
-    int ret = 0;
-
-    src_phy = pcdev->vipmem_phybase + vb->i*pcdev->vipmem_bsize;    
-    src = psY = (unsigned char*)(pcdev->vipmem_virbase + vb->i*pcdev->vipmem_bsize);
-    psUV = psY + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
-       
-    srcW = pcdev->zoominfo.vir_width;
-    srcH = pcdev->zoominfo.vir_height;
-    cropW = pcdev->zoominfo.a.c.width;
-    cropH = pcdev->zoominfo.a.c.height;
-       
-    psY = psY + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width+pcdev->zoominfo.a.c.left;
-    psUV = psUV + pcdev->zoominfo.a.c.top*pcdev->zoominfo.vir_width/2+pcdev->zoominfo.a.c.left; 
-    
-    vb_info = pcdev->vbinfo+vb->i; 
-    dst_phy = vb_info->phy_addr;
-    dst = pdY = (unsigned char*)vb_info->vir_addr; 
-    pdUV = pdY + pcdev->icd->user_width*pcdev->icd->user_height;
-    dstW = pcdev->icd->user_width;
-    dstH = pcdev->icd->user_height;
-
-    zoomindstxIntInv = ((unsigned long)(cropW)<<16)/dstW + 1;
-    zoomindstyIntInv = ((unsigned long)(cropH)<<16)/dstH + 1;
-    //y
-    //for(y = 0; y<dstH - 1 ; y++ ) {   
-    for(y = 0; y<dstH; y++ ) {   
-        yCoeff00 = (y*zoomindstyIntInv)&0xffff;
-        yCoeff01 = 0xffff - yCoeff00; 
-        sY = (y*zoomindstyIntInv >> 16);
-        sY = (sY >= srcH - 1)? (srcH - 2) : sY;      
-        for(x = 0; x<dstW; x++ ) {
-            xCoeff00 = (x*zoomindstxIntInv)&0xffff;
-            xCoeff01 = 0xffff - xCoeff00;      
-            sX = (x*zoomindstxIntInv >> 16);
-            sX = (sX >= srcW -1)?(srcW- 2) : sX;
-            a = psY[sY*srcW + sX];
-            b = psY[sY*srcW + sX + 1];
-            c = psY[(sY+1)*srcW + sX];
-            d = psY[(sY+1)*srcW + sX + 1];
-
-            r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
-            r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
-            r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
-
-            pdY[x] = r0;
-        }
-        pdY += dstW;
-    }
-
-    dstW /= 2;
-    dstH /= 2;
-    srcW /= 2;
-    srcH /= 2;
-
-    //UV
-    //for(y = 0; y<dstH - 1 ; y++ ) {
-    for(y = 0; y<dstH; y++ ) {
-        yCoeff00 = (y*zoomindstyIntInv)&0xffff;
-        yCoeff01 = 0xffff - yCoeff00; 
-        sY = (y*zoomindstyIntInv >> 16);
-        sY = (sY >= srcH -1)? (srcH - 2) : sY;      
-        for(x = 0; x<dstW; x++ ) {
-            xCoeff00 = (x*zoomindstxIntInv)&0xffff;
-            xCoeff01 = 0xffff - xCoeff00;      
-            sX = (x*zoomindstxIntInv >> 16);
-            sX = (sX >= srcW -1)?(srcW- 2) : sX;
-            //U
-            a = psUV[(sY*srcW + sX)*2];
-            b = psUV[(sY*srcW + sX + 1)*2];
-            c = psUV[((sY+1)*srcW + sX)*2];
-            d = psUV[((sY+1)*srcW + sX + 1)*2];
-
-            r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
-            r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
-            r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
-
-            pdUV[x*2] = r0;
-
-            //V
-            a = psUV[(sY*srcW + sX)*2 + 1];
-            b = psUV[(sY*srcW + sX + 1)*2 + 1];
-            c = psUV[((sY+1)*srcW + sX)*2 + 1];
-            d = psUV[((sY+1)*srcW + sX + 1)*2 + 1];
-
-            r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
-            r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
-            r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
-
-            pdUV[x*2 + 1] = r0;
-        }
-        pdUV += dstW*2;
-    }
-
-rk_camera_scale_crop_arm_end:
-
-    dmac_flush_range((void*)src,(void*)(src+pcdev->vipmem_bsize));
-    outer_flush_range((phys_addr_t)src_phy,(phys_addr_t)(src_phy+pcdev->vipmem_bsize));
-    
-    dmac_flush_range((void*)dst,(void*)(dst+vb_info->size));
-    outer_flush_range((phys_addr_t)dst_phy,(phys_addr_t)(dst_phy+vb_info->size));
-
-       return ret;    
+   
+       return 0;    
 }
 #endif
-
 static void rk_camera_capture_process(struct work_struct *work)
 {
     struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);    
     struct videobuf_buffer *vb = camera_work->vb;    
     struct rk_camera_dev *pcdev = camera_work->pcdev;    
-    //enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;    
-    struct device *control = to_soc_camera_control(pcdev->icd);
-    struct v4l2_subdev *sd=dev_get_drvdata(control);
+    /*enum v4l2_mbus_pixelcode icd_code = pcdev->icd->current_fmt->code;    */
     unsigned long flags = 0;    
-    int err = 0,i;    
+    int err = 0;    
 
-    if (!CAM_WORKQUEUE_IS_EN())        
-        goto rk_camera_capture_process_end; 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
-    camera_work->vb->rk_code = 0x00;
-    if (pcdev->hdr_info.en) {
-               printk("rk_camera_capture_process hdr %d fps\n",camera_work->ts);
-        if (pcdev->hdr_info.frame[0].set_ts == 0) {
-            v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,(void*)pcdev->hdr_info.frame[0].code);
-            pcdev->hdr_info.frame[0].set_ts = pcdev->fps;
-            printk("set hdr %d @ %d fps\n",0,pcdev->fps);
-        } else {
-            if ((camera_work->ts - pcdev->hdr_info.frame[0].set_ts) > 1) {
-                for (i=0; i<3; i++) {
-                    if (pcdev->hdr_info.frame[i].get_ts == 0) {
-                                               printk("get hdr %d @ %d fps %dx%d\n",i,camera_work->ts,camera_work->vb->width,camera_work->vb->height);
-                        pcdev->hdr_info.frame[i].get_ts = camera_work->ts;
-                        RK_VIDEOBUF_CODE_SET(camera_work->vb->rk_code,pcdev->hdr_info.frame[i].code);
-                        break;
-                    }
-                }
 
-                if (i==2) {
-                    v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,(void*)RK_VIDEOBUF_HDR_EXPOSURE_FINISH);
-                    pcdev->hdr_info.en = false;
-                    printk("hdr off\n");
-                }
-            }
-        }
+    if (atomic_read(&pcdev->stop_cif)==true) {
+        err = -EINVAL;
+        goto rk_camera_capture_process_end; 
     }
     
+    if (!CAM_WORKQUEUE_IS_EN()) {
+        err = -EINVAL;
+        goto rk_camera_capture_process_end; 
+    }
     
     down(&pcdev->zoominfo.sem);
     if (pcdev->icd_cb.scale_crop_cb){
@@ -1397,132 +973,120 @@ rk_camera_capture_process_end:
                }
     }       
     spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
-    list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);
+    list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
     spin_unlock_irqrestore(&pcdev->camera_work_lock, flags); 
-    wake_up(&(camera_work->vb->done));  
+    wake_up(&(camera_work->vb->done));     /* ddl@rock-chips.com : v0.3.9 */ 
     return;
 }
-#if defined(CONFIG_ARCH_RK3188)
-static void rk_camera_store_resore_register(struct rk_camera_dev *pcdev)
+
+static void rk_camera_cifrest_delay(struct work_struct *work)
 {
+    struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);  
+    struct rk_camera_dev *pcdev = camera_work->pcdev; 
+    unsigned long flags = 0;   
 
-       pcdev->reginfo_suspend.cifCtrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
-       pcdev->reginfo_suspend.cifCrop = read_cif_reg(pcdev->base,CIF_CIF_CROP);
-       pcdev->reginfo_suspend.cifFs = read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE);
-       pcdev->reginfo_suspend.cifIntEn = read_cif_reg(pcdev->base,CIF_CIF_INTEN);
-       pcdev->reginfo_suspend.cifFmt= read_cif_reg(pcdev->base,CIF_CIF_FOR);
-       pcdev->reginfo_suspend.cifVirWidth = read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH);
-       pcdev->reginfo_suspend.cifScale= read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL);
-       
-       cru_set_soft_reset(SOFT_RST_CIF0, true);
-       udelay(5);
-       cru_set_soft_reset(SOFT_RST_CIF0, false);
-       
-    if (pcdev->reginfo_suspend.cifCtrl&ENABLE_CAPTURE)
-        write_cif_reg(pcdev->base,CIF_CIF_CTRL, pcdev->reginfo_suspend.cifCtrl&~ENABLE_CAPTURE);
-       write_cif_reg(pcdev->base,CIF_CIF_INTEN, pcdev->reginfo_suspend.cifIntEn);
-       write_cif_reg(pcdev->base,CIF_CIF_CROP, pcdev->reginfo_suspend.cifCrop);
-       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, pcdev->reginfo_suspend.cifFs);
-       write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
-       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
-       write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+    
+    mdelay(1);
+    rk_camera_cif_reset(pcdev,false);
+
+    spin_lock_irqsave(&pcdev->camera_work_lock, flags);    
+    list_add_tail(&camera_work->queue, &pcdev->camera_work_queue);    
+    spin_unlock_irqrestore(&pcdev->camera_work_lock, flags); 
+
+    spin_lock_irqsave(&pcdev->lock,flags);
+    if (atomic_read(&pcdev->stop_cif) == false) {
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL) | ENABLE_CAPTURE));
+        RKCAMERA_DG2("After reset cif, enable capture again!\n");
+    }
+    spin_unlock_irqrestore(&pcdev->lock,flags);
+    return;
+}
+
+static inline irqreturn_t rk_camera_cifirq(int irq, void *data)
+{
+    struct rk_camera_dev *pcdev = data;
+    struct rk_camera_work *wk;
+    unsigned int reg_cifctrl, reg_lastpix, reg_lastline;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+
+    write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200);  /* clear vip interrupte single  */
+    
+    reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+    reg_lastpix = read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX);
+    reg_lastline = read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE);
        
+    pcdev->irqinfo.cifirq_idx++;    
+    if ((reg_lastline != pcdev->host_height) /*|| (reg_lastpix != pcdev->host_width)*/) {
+        pcdev->irqinfo.cifirq_abnormal_idx = pcdev->irqinfo.cifirq_idx;
+        RKCAMERA_DG2("Cif irq-%ld is error, %dx%d != %dx%d\n",pcdev->irqinfo.cifirq_abnormal_idx,
+                    reg_lastpix,reg_lastline,pcdev->host_width,pcdev->host_height);
+    } else {
+        pcdev->irqinfo.cifirq_normal_idx = pcdev->irqinfo.cifirq_idx;
+    }
+/*    
+    if(reg_cifctrl & ENABLE_CAPTURE) {
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl & ~ENABLE_CAPTURE));
+    } 
+*/
+    if (pcdev->irqinfo.cifirq_abnormal_idx>0) {
+        if ((pcdev->irqinfo.cifirq_idx - pcdev->irqinfo.cifirq_abnormal_idx) == 1 ) {
+            if (!list_empty(&pcdev->camera_work_queue)) {
+                RKCAMERA_DG2("Receive cif irq-%ld and queue work to cif reset\n",pcdev->irqinfo.cifirq_idx);
+                wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
+                list_del_init(&wk->queue);
+                INIT_WORK(&(wk->work), rk_camera_cifrest_delay);
+                wk->pcdev = pcdev;                
+                queue_work(pcdev->camera_wq, &(wk->work));
+            }  
+        }
+    }
+    
+    return IRQ_HANDLED;
 }
-#endif
 
-static irqreturn_t rk_camera_irq(int irq, void *data)
+static inline irqreturn_t rk_camera_dmairq(int irq, void *data)
 {
     struct rk_camera_dev *pcdev = data;
     struct videobuf_buffer *vb;
        struct rk_camera_work *wk;
        struct timeval tv;
-    unsigned long tmp_intstat;
-    unsigned long tmp_cifctrl; 
-       unsigned long tmp_cif_frmst; 
+    unsigned long reg_cifctrl;
+       unsigned long tmp_cif_frmst;    
        struct videobuf_buffer **active = 0;
+       struct videobuf_buffer *active_buf = NULL;
        int flag = 0;
-        unsigned int invalid_y_addr ,invalid_uv_addr;
-#ifdef OPTIMIZE_MEMORY_USE
-       invalid_y_addr = 0/*pcdev->vipmem_phybase + pcdev->vipmem_bsize*/;
-       invalid_uv_addr = 0/*invalid_y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height*/;
-#else
-       invalid_y_addr = pcdev->vipmem_phybase + pcdev->vbinfo_count *pcdev->vipmem_bsize;
-       invalid_uv_addr = invalid_y_addr + pcdev->zoominfo.vir_width*pcdev->zoominfo.vir_height;
-#endif 
-    tmp_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
-    tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
-       tmp_cif_frmst = read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS);
 
-#if (CONFIG_CIF_STOP_SYNC == 0)
-    if(pcdev->stop_cif == true) {
-               //RK30_CAM_DEBUG_TRACE("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
-               write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
-               return IRQ_HANDLED;
-       }
-#endif
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
-    if ((tmp_intstat & 0x0200) /*&& ((tmp_intstat & 0x1)==0)*/) {//bit9 =1 ,bit0 = 0
-       write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x0200);  /* clear vip interrupte single  */
- //       if(tmp_cifctrl & ENABLE_CAPTURE)
- //           write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
-         return IRQ_HANDLED;
-    }
-    
-    /* ddl@rock-chps.com : Current VIP is run in One Frame Mode, Frame 1 is validate */
-    if (tmp_cif_frmst & (CIF_F0_READY | CIF_F1_READY)) {
-       write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01);  /* clear vip interrupte single  */
-#if CONFIG_CIF_STOP_SYNC 
-                       if(pcdev->stop_cif == true) {
-                               //RK30_CAM_DEBUG_TRACE("%s(%d): cif has stopped by app,needn't to deal this irq\n",__FUNCTION__,__LINE__);
-                               write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);  /* clear vip interrupte single  */
-                               
-#if 1
-                               //              write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0);     //capture complete interrupt enable
-                                               {
-#if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928))
-                                       mdelay(100);
-                                       if(IS_CIF0()){
-                                               cru_set_soft_reset(SOFT_RST_CIF0, true);
-                                               udelay(5);
-                                               cru_set_soft_reset(SOFT_RST_CIF0, false);
-                       
-                                       }else{
-                                               cru_set_soft_reset(SOFT_RST_CIF1, true);
-                                               udelay(5);
-                                               cru_set_soft_reset(SOFT_RST_CIF1, false);
-                                       }
-#elif defined(CONFIG_ARCH_RK3188)
-                                       cru_set_soft_reset(SOFT_RST_CIF0, true);
-                                       udelay(5);
-                                       cru_set_soft_reset(SOFT_RST_CIF0, false);
-#endif
-                               }
-#endif
-                           spin_lock(&pcdev->lock);
-                               pcdev->cif_stopped = true;
-                               wake_up(&pcdev->cif_stop_done);
-                               spin_unlock(&pcdev->lock);
-                               return IRQ_HANDLED;
-                       }
-#endif
-        if (!pcdev->fps) {
+
+    reg_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+       tmp_cif_frmst = read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS);
+    /* ddl@rock-chps.com : Current VIP is run in Pingpong Frame Mode */
+    if (tmp_cif_frmst & (CIF_F0_READY | CIF_F1_READY)) {   //frame 0 or 1  ready yzm
+        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0x01);  /* clear vip interrupte single  */
+
+        pcdev->irqinfo.dmairq_idx++;
+        if (pcdev->irqinfo.cifirq_abnormal_idx == pcdev->irqinfo.dmairq_idx) {
+            write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000003);
+            goto end;
+        }
+
+        if (!pcdev->fps) {//µÚÒ»´Î½øÈëÖжÏ
             do_gettimeofday(&pcdev->first_tv);            
         }
-process_another_frame: 
+               
         if((tmp_cif_frmst & CIF_F0_READY) && (tmp_cif_frmst & CIF_F1_READY)){
-                   printk(KERN_DEBUG"%s:f0 && f1 ready ,need to resart cif!!!!!\n",__func__);
-           spin_lock(&pcdev->lock);
-
-            rk_camera_store_resore_register(pcdev);
-                       rk_videobuf_capture(pcdev->active0,pcdev,0);
-                       rk_videobuf_capture(pcdev->active1,pcdev,1);
-                       tmp_cifctrl &=~ENABLE_CAPTURE;
-                   spin_unlock(&pcdev->lock);
+                   printk("%s:f0 && f1 ready ,need to resart cif!!!!!\n",__func__);
+                       reg_cifctrl &=~ENABLE_CAPTURE;
 
-                       goto RK_CAMERA_IRQ_END;
+                       goto end;
         }
-               pcdev->fps++;
-        
+        pcdev->fps++;
+               
                if (tmp_cif_frmst & CIF_F0_READY){
                        active = &pcdev->active0;
                        flag = 0;
@@ -1531,105 +1095,103 @@ process_another_frame:
                        flag = 1;
                } else {
                        printk("irq frame status erro \n");
-                       goto RK_CAMERA_IRQ_END;
+                       goto end;
                }
-#if 0  
                if (!(*active)){
-                       goto RK_CAMERA_IRQ_END;
+                       printk("active = NULL\n");
+                       goto end;
                }
-#endif
-               if (pcdev->frame_inval>0) {
-                       pcdev->frame_inval--;
+               
+        if (pcdev->frame_inval>0) {//¹ØÓÚ¹ýÂËÇ°¼¸Ö¡µÄ£¬ÏÖÔÚûÓÐÓõ½
+            pcdev->frame_inval--;
                        rk_videobuf_capture(*active,pcdev,flag);
-                       goto first_frame_done;
-               } else if (pcdev->frame_inval) {
-                       RK30_CAM_DEBUG_TRACE("frame_inval : %0x",pcdev->frame_inval);
-                       pcdev->frame_inval = 0;
-               }
+        } else if (pcdev->frame_inval) {
+            RKCAMERA_TR("frame_inval : %0x",pcdev->frame_inval);
+            pcdev->frame_inval = 0;
+        }
         
-               if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {
-                       do_gettimeofday(&tv);            
-                       pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
-                                                                       /(RK30_CAM_FRAME_MEASURE-1);
+        if(pcdev->fps == RK30_CAM_FRAME_MEASURE) {//¹ýÂËÇ°¼¸Ö¡,¿ªÊ¼¶¨Ê±
+            do_gettimeofday(&tv);            
+            pcdev->frame_interval = ((tv.tv_sec*1000000 + tv.tv_usec) - (pcdev->first_tv.tv_sec*1000000 + pcdev->first_tv.tv_usec))
+                /(RK30_CAM_FRAME_MEASURE-1);
+        }
+        
+        vb = *active;
+        
+        if (!vb) {
+            printk("no acticve buffer!!!\n");
+            goto end;
         }
-               
-               vb = *active;
-               
-#if 0
-               if(!vb){
-                       RK30_CAM_DEBUG_TRACE("no acticve buffer!!!\n");
-                       goto RK_CAMERA_IRQ_END;
-               }
 
-               if (vb->stream.prev != &(pcdev->video_vq->stream)) {
-                       RK30_CAM_DEBUG_TRACE("vb(%d) isn't first node in stream list\n", vb->i);
-                       goto RK_CAMERA_IRQ_END;
-               }
-#endif
-               *active = NULL;
-           spin_lock(&pcdev->lock);
-               if (!list_empty(&pcdev->capture)) {
-                       *active = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
-                       if (*active) {
-                               WARN_ON((*active)->state != VIDEOBUF_QUEUED); 
-                               if (tmp_cif_frmst & CIF_F0_READY){
-                               pcdev->active0 = *active;
-                       } else if (tmp_cif_frmst & CIF_F1_READY){
-                               pcdev->active1 = *active;
+        if (!list_empty(&pcdev->capture)) {
+                       active_buf = list_entry(pcdev->capture.next, struct videobuf_buffer, queue);
+            if (active_buf) {
+                
+                WARN_ON(active_buf->state != VIDEOBUF_QUEUED);
+                               if ((flag == 0) && ((active_buf->i)%2 == 0)){                                   
+                               pcdev->active0 = active_buf;
+                       } else if ((flag == 1) && ((active_buf->i)%2 == 1)){
+                               pcdev->active1 = active_buf;
                        }else{
-                    printk("irq frame status erro !\n");
+                    RKCAMERA_DG1("irq frame status erro or no a suitable buf!\n");
+                                       goto end;
                        }
-                               rk_videobuf_capture((*active),pcdev,flag);
-                               list_del_init(&((*active)->queue));
-                       }
-               }
-           spin_unlock(&pcdev->lock);
-               if ((*active) == NULL) {
-               //      RK30_CAM_DEBUG_TRACE("%s video_buf queue is empty!\n",__FUNCTION__);
-                       if(flag == 0){                  
-                           pcdev->active0 = NULL;
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y, invalid_y_addr);
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV, invalid_uv_addr);
-                               }else{
-                           pcdev->active1 = NULL;
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_Y, invalid_y_addr);
-                               write_cif_reg(pcdev->base,CIF_CIF_FRM1_ADDR_UV, invalid_uv_addr);
-                               }
-               }
-               if(vb)
-                       do_gettimeofday(&vb->ts);
-               if (CAM_WORKQUEUE_IS_EN()) {
-                       if(vb){
-                                       if (!list_empty(&pcdev->camera_work_queue)) {
-                                               wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
-                                               list_del_init(&wk->queue);
-                                               INIT_WORK(&(wk->work), rk_camera_capture_process);
-                                               wk->vb = vb;
-                                               wk->pcdev = pcdev;
-                                       wk->ts = pcdev->fps;
-                                               queue_work(pcdev->camera_wq, &(wk->work));
-                                       }else{
-                                               printk("work queue is empty \n!!!!!!!!");
-                                       }
-                               }
-               } else {
-                       if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
-                               vb->state = VIDEOBUF_DONE;              
-                               vb->field_count++;
-                       }
-                       wake_up(&vb->done);
-               }
+                               rk_videobuf_capture(active_buf,pcdev,flag);
+                               list_del_init(&(active_buf->queue));
+            }
+        }else{
+                       RKCAMERA_DG1("video_buf queue is empty!\n");
+                       goto end;
+        }
+                       
+        do_gettimeofday(&vb->ts);
+        if (CAM_WORKQUEUE_IS_EN()) {
+            if (!list_empty(&pcdev->camera_work_queue)) {
+                wk = list_entry(pcdev->camera_work_queue.next, struct rk_camera_work, queue);
+                list_del_init(&wk->queue);
+                INIT_WORK(&(wk->work), rk_camera_capture_process);
+                wk->vb = vb;
+                wk->pcdev = pcdev;
+                queue_work(pcdev->camera_wq, &(wk->work));
+            }                                  
+        } else {
+            if ((vb->state == VIDEOBUF_QUEUED) || (vb->state == VIDEOBUF_ACTIVE)) {
+                vb->state = VIDEOBUF_DONE;             
+                vb->field_count++;
+            }
+            wake_up(&vb->done);
+        }
     }
-first_frame_done:
-       if ((tmp_cif_frmst & CIF_F0_READY) && (tmp_cif_frmst & CIF_F1_READY)){
-                   printk(KERN_DEBUG"%s:f0 && f1 ready ,need to process f1 too!!!!!\n",__func__);
-            tmp_cif_frmst &=~CIF_F0_READY;
-            goto process_another_frame;
-       }
 
-RK_CAMERA_IRQ_END:
-    if((tmp_cifctrl & ENABLE_CAPTURE) == 0)
-        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
+end:
+    if((reg_cifctrl & ENABLE_CAPTURE) == 0)
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (reg_cifctrl | ENABLE_CAPTURE));
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t rk_camera_irq(int irq, void *data)
+{
+    struct rk_camera_dev *pcdev = data;
+    unsigned long reg_intstat;
+
+
+    spin_lock(&pcdev->lock);
+
+    if(atomic_read(&pcdev->stop_cif) == true) {
+        write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xffffffff);
+        goto end;
+    }
+
+    reg_intstat = read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s() ,reg_intstat 0x%lx\n", __FILE__, __LINE__,__FUNCTION__,reg_intstat);
+    if (reg_intstat & 0x0200)
+        rk_camera_cifirq(irq,data);
+
+    if (reg_intstat & 0x01) 
+        rk_camera_dmairq(irq,data);
+
+end:    
+    spin_unlock(&pcdev->lock);
     return IRQ_HANDLED;
 }
 
@@ -1639,13 +1201,17 @@ static void rk_videobuf_release(struct videobuf_queue *vq,
 {
     struct rk_camera_buffer *buf = container_of(vb, struct rk_camera_buffer, vb);
     struct soc_camera_device *icd = vq->priv_data;
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
 #if CAMERA_VIDEOBUF_ARM_ACCESS    
     struct rk29_camera_vbinfo *vb_info =NULL;
 #endif
 
 #ifdef DEBUG
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
     dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
             vb, vb->baddr, vb->bsize);
 
@@ -1666,26 +1232,22 @@ static void rk_videobuf_release(struct videobuf_queue *vq,
     }
 #endif
 
-       #if 0   /* ddl@rock-chips.com: this wait operation is not nessary, invalidate in v0.x.1f */
-       if (vb == pcdev->active0 || vb == pcdev->active1) {
-               RK30_CAM_DEBUG_TRACE("%s Wait for this video buf(0x%x) write finished!\n ",__FUNCTION__,(unsigned int)vb);
-               interruptible_sleep_on_timeout(&vb->done, msecs_to_jiffies(500));
-               RK30_CAM_DEBUG_TRACE("%s This video buf(0x%x) write finished, release now!!\n",__FUNCTION__,(unsigned int)vb);
-       }
-       #endif
-       flush_workqueue(pcdev->camera_wq); 
+    flush_workqueue(pcdev->camera_wq); 
+    
+    rk_videobuf_free(vq, buf);
+    
 #if CAMERA_VIDEOBUF_ARM_ACCESS
-       if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
-               vb_info = pcdev->vbinfo + vb->i;
+    if ((pcdev->vbinfo) && (vb->i < pcdev->vbinfo_count)) {
+        vb_info = pcdev->vbinfo + vb->i;
         
-               if (vb_info->vir_addr) {
-                       iounmap(vb_info->vir_addr);
-                       release_mem_region(vb_info->phy_addr, vb_info->size);
-                       memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
-               }
+        if (vb_info->vir_addr) {
+            iounmap(vb_info->vir_addr);
+            release_mem_region(vb_info->phy_addr, vb_info->size);
+            memset(vb_info, 0x00, sizeof(struct rk29_camera_vbinfo));
+        }       
+               
        }
-#endif    
-       rk_videobuf_free(vq, buf);
+#endif  
 }
 
 static struct videobuf_queue_ops rk_videobuf_ops =
@@ -1699,9 +1261,12 @@ static struct videobuf_queue_ops rk_videobuf_ops =
 static void rk_camera_init_videobuf(struct videobuf_queue *q,
                                       struct soc_camera_device *icd)
 {
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
     /* We must pass NULL as dev pointer, then all pci_* dma operations
      * transform to normal dma_* ones. */
     videobuf_queue_dma_contig_init(q,
@@ -1710,83 +1275,80 @@ static void rk_camera_init_videobuf(struct videobuf_queue *q,
                                    V4L2_BUF_TYPE_VIDEO_CAPTURE,
                                    V4L2_FIELD_NONE,
                                    sizeof(struct rk_camera_buffer),
-                                   icd,&icd->video_lock);
+                                   icd,&(ici->host_lock) );
 }
 
-static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate){
-    int err = 0,cif;
+static int rk_camera_mclk_ctrl(int cif_idx, int on, int clk_rate)
+{
+    int err = 0,cif;    
     struct rk_cif_clk *clk;
-    struct clk *cif_clk_out_div;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
 
     cif = cif_idx - RK29_CAM_PLATFORM_DEV_ID;
     if ((cif<0)||(cif>1)) {
         RKCAMERA_TR(KERN_ERR "cif index(%d) is invalidate\n",cif_idx);
         err = -1;
         goto rk_camera_clk_ctrl_end;
-    }
+    } 
 
     clk = &cif_clk[cif];
-
+   
     if(!clk->aclk_cif || !clk->hclk_cif || !clk->cif_clk_in || !clk->cif_clk_out) {
         RKCAMERA_TR(KERN_ERR "failed to get cif clock source\n");
         err = -ENOENT;
         goto rk_camera_clk_ctrl_end;
     }
-    spin_lock(&clk->lock);
-    if (on && !clk->on) {
-        clk_enable(clk->pd_cif);
-        clk_enable(clk->aclk_cif);
-        clk_enable(clk->hclk_cif);
-        clk_enable(clk->cif_clk_in);
-        clk_enable(clk->cif_clk_out);
+   
+    //spin_lock(&clk->lock);
+    if (on && !clk->on) {  
+        clk_prepare_enable(clk->pd_cif);    /*yzm*/
+        clk_prepare_enable(clk->aclk_cif);
+       clk_prepare_enable(clk->hclk_cif);
+       clk_prepare_enable(clk->cif_clk_in);
+       clk_prepare_enable(clk->cif_clk_out);
         clk_set_rate(clk->cif_clk_out,clk_rate);
-        mdelay(10);
         clk->on = true;
-        
     } else if (!on && clk->on) {
-        clk_disable(clk->aclk_cif);
-        clk_disable(clk->hclk_cif);
-        clk_disable(clk->cif_clk_in);
-
-        clk_disable(clk->cif_clk_out);
-        clk_disable(clk->pd_cif);
+               clk_set_rate(clk->cif_clk_out,36000000);/*yzm :just for close clk which base on XIN24M */
+       msleep(100);
+        clk_disable_unprepare(clk->aclk_cif);
+       clk_disable_unprepare(clk->hclk_cif);
+       clk_disable_unprepare(clk->cif_clk_in);
+               if(CHIP_NAME == 3126){
+                       write_cru_reg(CRU_CLKSEL29_CON, 0x007c0000);
+                       write_cru_reg(CRU_CLK_OUT, 0x00800080);
+               }
+       clk_disable_unprepare(clk->cif_clk_out);
+       clk_disable_unprepare(clk->pd_cif);
         clk->on = false;
-        if(cif){
-            cif_clk_out_div =  clk_get(NULL, "cif1_out_div");
-        }else{
-            cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
-            if(IS_ERR_OR_NULL(cif_clk_out_div)) {
-                cif_clk_out_div =  clk_get(NULL, "cif_out_div");
-            }
-        }
-
-        if(IS_ERR_OR_NULL(cif_clk_out_div)) {
-            err = clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
-            clk_put(cif_clk_out_div);
-        } else {
-            err = -1;
-        }
-
-        if(err)
-           RKCAMERA_TR("WARNING %s_%s_%d: camera sensor mclk maybe not close, please check!!!\n", __FILE__, __FUNCTION__, __LINE__);
     }
-    spin_unlock(&clk->lock);
+    //spin_unlock(&clk->lock);
 rk_camera_clk_ctrl_end:
     return err;
 }
 static int rk_camera_activate(struct rk_camera_dev *pcdev, struct soc_camera_device *icd)
 {
-    write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
+    /*
+    * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
+    */
 
-    write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01);    //capture complete interrupt enable
-    RK30_CAM_DEBUG_TRACE("%s..%d.. CIF_CIF_CTRL = 0x%x\n",__FUNCTION__,__LINE__,read_cif_reg(pcdev->base, CIF_CIF_CTRL));
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+       
+    write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
+       //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01);    //capture complete interrupt enable
     return 0;
-RK_CAMERA_ACTIVE_ERR:
-    return -ENODEV;
 }
 
 static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
-{
+{ 
+    /*
+    * ddl@rock-chips.com : Cif clk control in rk_sensor_power which in rk_camera.c
+    */
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+    
     return;
 }
 
@@ -1794,8 +1356,8 @@ static void rk_camera_deactivate(struct rk_camera_dev *pcdev)
  * there can be only one camera on RK28 quick capture interface */
 static int rk_camera_add_device(struct soc_camera_device *icd)
 {
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-    struct rk_camera_dev *pcdev = ici->priv;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
+    struct rk_camera_dev *pcdev = ici->priv;    /*Initialize in rk_camra_prob*/
     struct device *control = to_soc_camera_control(icd);
     struct v4l2_subdev *sd;
     int ret,i,icd_catch;
@@ -1803,6 +1365,9 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
     struct v4l2_cropcap cropcap;
     struct v4l2_mbus_framefmt mf;
     const struct soc_camera_format_xlate *xlate = NULL;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
     
     mutex_lock(&camera_lock);
 
@@ -1811,11 +1376,13 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
         goto ebusy;
     }
 
-    RK30_CAM_DEBUG_TRACE("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
+    RKCAMERA_DG1("%s driver attached to %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
 
        pcdev->frame_inval = RK_CAM_FRAME_INVAL_INIT;
+    //pcdev->active = NULL;    
     pcdev->active0 = NULL;
        pcdev->active1 = NULL;
+       pcdev->active_buf = 0;
     pcdev->icd = NULL;
        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
     pcdev->zoominfo.zoom_rate = 100;
@@ -1830,7 +1397,7 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
     if (ret)
         goto ebusy;
     /* ddl@rock-chips.com : v4l2_subdev is not created when ici->ops->add called in soc_camera_probe  */
-    if (control) {
+    if (control) {             //TRUE in open ,FALSE in kernel start
         sd = dev_get_drvdata(control);
                v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_IOREQUEST,(void*)pcdev->pdata);
         #if 0
@@ -1838,8 +1405,9 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
         if (ret)
             goto ebusy;
         #endif
+               /* call generic_sensor_ioctl*/
         v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_CB_REGISTER,(void*)(&pcdev->icd_cb));
-
+               /* call generic_sensor_cropcap*/
         if (v4l2_subdev_call(sd, video, cropcap, &cropcap) == 0) {
             memcpy(&pcdev->cropinfo.bounds ,&cropcap.bounds,sizeof(struct v4l2_rect));
         } else {
@@ -1857,9 +1425,11 @@ static int rk_camera_add_device(struct soc_camera_device *icd)
             pcdev->cropinfo.bounds.height = mf.height;
         }
     }
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
     pcdev->icd = icd;
     pcdev->icd_init = 0;
-
+    
     icd_catch = 0;
     for (i=0; i<2; i++) {
         if (pcdev->icd_frmival[i].icd == icd)
@@ -1887,37 +1457,31 @@ ebusy:
 }
 static void rk_camera_remove_device(struct soc_camera_device *icd)
 {
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
-       struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+       /*struct v4l2_subdev *sd = soc_camera_to_subdev(icd);*/
 #if CAMERA_VIDEOBUF_ARM_ACCESS    
     struct rk29_camera_vbinfo *vb_info;
     unsigned int i;
-#endif    
+#endif 
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
 
        mutex_lock(&camera_lock);
     BUG_ON(icd != pcdev->icd);
 
-    RK30_CAM_DEBUG_TRACE("%s driver detached from %s\n",RK29_CAM_DRV_NAME,dev_name(icd->pdev));
-
-       /* ddl@rock-chips.com: Application will call VIDIOC_STREAMOFF before close device, but
+    RKCAMERA_DG1("%s driver detached from %s\n",RK29_CAM_DRV_NAME,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. */
-       if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {
+       /*if (read_cif_reg(pcdev->base,CIF_CIF_CTRL) & ENABLE_CAPTURE) {*/
+       if ((atomic_read(&pcdev->stop_cif) == false) && pcdev->fps_timer.istarted) {       /* ddl@rock-chips.com: v0.3.0x15*/
                rk_camera_s_stream(icd,0);
-       }
-    
-    //soft reset  the registers
-    #if 0 //has somthing wrong when suspend and resume now
-    if(IS_CIF0()){
-        write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF0|RQUEST_RST_CIF0 | (read_cru_reg(CRU_CIF_RST_REG30)));
-        write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF0)) | MASK_RST_CIF0);
-    }else{
-        write_cru_reg(CRU_CIF_RST_REG30,MASK_RST_CIF1|RQUEST_RST_CIF1 | (read_cru_reg(CRU_CIF_RST_REG30)));
-        write_cru_reg(CRU_CIF_RST_REG30,(read_cru_reg(CRU_CIF_RST_REG30)&(~RQUEST_RST_CIF1)) | MASK_RST_CIF1);
-    }
-    #endif
-    v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);
-    //if stream off is not been executed,timer is running.
+       } 
+       /* move DEACTIVATE into generic_sensor_s_power*/
+    /* v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_DEACTIVATE,NULL);*/ /*yzm*/
+    /* if stream off is not been executed,timer is running.*/
     if(pcdev->fps_timer.istarted){
          hrtimer_cancel(&pcdev->fps_timer.timer);
          pcdev->fps_timer.istarted = false;
@@ -1948,8 +1512,10 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
                pcdev->vbinfo_count = 0;
        }
 #endif
-       pcdev->active0 = NULL;
+       //pcdev->active = NULL;
+    pcdev->active0 = NULL;
        pcdev->active1 = NULL;
+       pcdev->active_buf = 0;
     pcdev->icd = NULL;
     pcdev->icd_cb.sensor_cb = NULL;
        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
@@ -1959,19 +1525,20 @@ static void rk_camera_remove_device(struct soc_camera_device *icd)
     INIT_LIST_HEAD(&pcdev->capture);
 
        mutex_unlock(&camera_lock);
-       RK30_CAM_DEBUG_TRACE("%s exit\n",__FUNCTION__);
 
        return;
 }
 static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
-    unsigned long bus_flags, camera_flags, common_flags;
-    unsigned int cif_ctrl_val = 0;
+    unsigned long bus_flags, camera_flags, common_flags = 0;
+    unsigned int cif_for = 0;
        const struct soc_mbus_pixelfmt *fmt;
        int ret = 0;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /*yzm*/
        struct rk_camera_dev *pcdev = ici->priv;
-    RK30_CAM_DEBUG_TRACE("%s..%d..\n",__FUNCTION__,__LINE__);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
 
        fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
        if (!fmt)
@@ -1995,90 +1562,90 @@ static int rk_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
        default:
                return -EINVAL;
        }
-    
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
        if (icd->ops->query_bus_param)
        camera_flags = icd->ops->query_bus_param(icd);
        else
                camera_flags = 0;
 
+/**************yzm************
     common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
     if (!common_flags) {
         ret = -EINVAL;
         goto RK_CAMERA_SET_BUS_PARAM_END;
     }
+*/
+/***************yzm************end*/
 
+       
+       common_flags = camera_flags;
     ret = icd->ops->set_bus_param(icd, common_flags);
     if (ret < 0)
         goto RK_CAMERA_SET_BUS_PARAM_END;
 
-    cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_FOR);
-       RK30_CAM_DEBUG_TRACE("%s..%d..cif_ctrl_val = 0x%x\n",__FUNCTION__,__LINE__,cif_ctrl_val);
-    if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) {
+    cif_for = read_cif_reg(pcdev->base,CIF_CIF_FOR);
+    
+    if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) {
                if(IS_CIF0()) {
                write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF0);
-            RK30_CAM_DEBUG_TRACE("enable cif0 pclk invert\n");
         } else {
                write_cru_reg(CRU_PCLK_REG30, read_cru_reg(CRU_PCLK_REG30) | ENANABLE_INVERT_PCLK_CIF1);
-            RK30_CAM_DEBUG_TRACE("enable cif1 pclk invert\n");
         }
     } else {
                if(IS_CIF0()){
                        write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFFEFF ) | DISABLE_INVERT_PCLK_CIF0);
-            RK30_CAM_DEBUG_TRACE("diable cif0 pclk invert\n");
         } else {
                        write_cru_reg(CRU_PCLK_REG30, (read_cru_reg(CRU_PCLK_REG30) & 0xFFFEFFF) | DISABLE_INVERT_PCLK_CIF1);
-            RK30_CAM_DEBUG_TRACE("diable cif1 pclk invert\n");
         }
     }
-    if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) {
-        cif_ctrl_val |= HSY_LOW_ACTIVE;
+    
+    if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) {
+        cif_for |= HSY_LOW_ACTIVE;
     } else {
-               cif_ctrl_val &= ~HSY_LOW_ACTIVE;
+               cif_for &= ~HSY_LOW_ACTIVE;
     }
-    if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) {
-        cif_ctrl_val |= VSY_HIGH_ACTIVE;
+    if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) {
+        cif_for |= VSY_HIGH_ACTIVE;
     } else {
-               cif_ctrl_val &= ~VSY_HIGH_ACTIVE;
+               cif_for &= ~VSY_HIGH_ACTIVE;
     }
 
-    /* ddl@rock-chips.com : Don't enable capture here, enable in stream_on */
+    // ddl@rock-chips.com : Don't enable capture here, enable in stream_on 
     //vip_ctrl_val |= ENABLE_CAPTURE;
-    write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_ctrl_val);
-    RK30_CAM_DEBUG_TRACE("%s..ctrl:0x%x CIF_CIF_FOR=%x  \n",__FUNCTION__,cif_ctrl_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
+    write_cif_reg(pcdev->base,CIF_CIF_FOR, cif_for);
+    RKCAMERA_DG1("CIF_CIF_FOR: 0x%x \n",cif_for);
 
 RK_CAMERA_SET_BUS_PARAM_END:
        if (ret)
-       RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d \n",__FUNCTION__,__LINE__, ret);
+       RKCAMERA_TR("rk_camera_set_bus_param ret = %d \n", ret);
     return ret;
 }
 
 static int rk_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 {
-    unsigned long bus_flags, camera_flags;
-    int ret;
+/*    unsigned long bus_flags, camera_flags;*/
+/*    int ret;*/
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+/**********yzm***********
 
     bus_flags = RK_CAM_BUS_PARAM;
        if (icd->ops->query_bus_param) {
-        camera_flags = icd->ops->query_bus_param(icd);
+        camera_flags = icd->ops->query_bus_param(icd);  //generic_sensor_query_bus_param()
        } else {
                camera_flags = 0;
        }
     ret = soc_camera_bus_param_compatible(camera_flags, bus_flags) ;
 
-       /* rockchip BUGBUG
-               if (ret < 0)
-                       dev_warn(icd->dev.parent,
-                                "Flags incompatible: camera %lx, host %lx\n",
-                                camera_flags, bus_flags);
-       */
-       if(!ret){
-               dev_warn(icd->dev.parent, "Flags incompatible: camera %lx, host %lx\n", camera_flags, bus_flags);
-               ret = -EINVAL;
-       }
-       else{
-               ret = 0;
-       }
+    if (ret < 0)
+        dev_warn(icd->dev.parent,
+                        "Flags incompatible: camera %lx, host %lx\n",
+                        camera_flags, bus_flags);
+
     return ret;
+*///************yzm **************end
+       return 0;
+
 }
 
 static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
@@ -2119,11 +1686,12 @@ static const struct soc_mbus_pixelfmt rk_camera_formats[] = {
                .packing                = SOC_MBUS_PACKING_2X8_PADHI,
                .order                  = SOC_MBUS_ORDER_LE,
        }
+
 };
 
 static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect)
 {
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
     unsigned int cif_fs = 0,cif_crop = 0;
     unsigned int cif_fmt_val = read_cif_reg(pcdev->base,CIF_CIF_FOR) | INPUT_MODE_YUV|YUV_INPUT_422|INPUT_420_ORDER_EVEN|OUTPUT_420_ORDER_EVEN;
@@ -2131,6 +1699,9 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
        const struct soc_mbus_pixelfmt *fmt;
        fmt = soc_mbus_get_fmtdesc(icd_code);
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
        if((host_pixfmt == V4L2_PIX_FMT_RGB565) || (host_pixfmt == V4L2_PIX_FMT_RGB24)){
                if(fmt->fourcc == V4L2_PIX_FMT_NV12)
                        host_pixfmt = V4L2_PIX_FMT_NV12;
@@ -2187,47 +1758,22 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
                        cif_fmt_val = YUV_INPUT_ORDER_YUYV(cif_fmt_val);
             break;
     }
-#if 1
-        {
-#if (defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928))
-           mdelay(100);
-            if(IS_CIF0()){
-        //             pmu_set_idle_request(IDLE_REQ_VIO, true);
-                       cru_set_soft_reset(SOFT_RST_CIF0, true);
-                       udelay(5);
-                       cru_set_soft_reset(SOFT_RST_CIF0, false);
-        //             pmu_set_idle_request(IDLE_REQ_VIO, false);
-
-            }else{
-        //             pmu_set_idle_request(IDLE_REQ_VIO, true);
-                       cru_set_soft_reset(SOFT_RST_CIF1, true);
-                       udelay(5);
-                       cru_set_soft_reset(SOFT_RST_CIF1, false);
-        //             pmu_set_idle_request(IDLE_REQ_VIO, false);  
-            }
-#elif defined(CONFIG_ARCH_RK3188)
-//             pmu_set_idle_request(IDLE_REQ_VIO, true);
-               cru_set_soft_reset(SOFT_RST_CIF0, true);
-               udelay(5);
-               cru_set_soft_reset(SOFT_RST_CIF0, false);
-//             pmu_set_idle_request(IDLE_REQ_VIO, false);
 
-#endif
-        }
+    mdelay(100);
+    rk_camera_cif_reset(pcdev,true);
+    
     write_cif_reg(pcdev->base,CIF_CIF_CTRL,AXI_BURST_16|MODE_PINGPONG|DISABLE_CAPTURE);   /* ddl@rock-chips.com : vip ahb burst 16 */
-    write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200);    //capture complete interrupt enable
-#endif
+    //write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200);    /*capture complete interrupt enable*/
+
     write_cif_reg(pcdev->base,CIF_CIF_FOR,cif_fmt_val);         /* ddl@rock-chips.com: VIP capture mode and capture format must be set before FS register set */
 
-   // read_cif_reg(pcdev->base,CIF_CIF_INTSTAT);                /* clear vip interrupte single  */
-    write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF);
-       /* 
-    if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
+    write_cif_reg(pcdev->base,CIF_CIF_INTSTAT,0xFFFFFFFF); 
+    /*if((read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_PINGPONG)
                ||(read_cif_reg(pcdev->base,CIF_CIF_CTRL) & MODE_LINELOOP)) {
            BUG();      
-    } else*/{ // this is one frame mode
-           cif_crop = (rect->left+ (rect->top<<16));
-           cif_fs      = ((rect->width ) + (rect->height<<16));
+    } else*/{ /* this is one frame mode*/
+           cif_crop = (rect->left + (rect->top <<16));
+           cif_fs      = (rect->width + (rect->height <<16));
        }
 
        write_cif_reg(pcdev->base,CIF_CIF_CROP, cif_crop);
@@ -2235,9 +1781,9 @@ static void rk_camera_setup_format(struct soc_camera_device *icd, __u32 host_pix
        write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, rect->width);
        write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000003);
 
-    //MUST bypass scale 
+    /*MUST bypass scale */
        write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL,0x10);
-    RK30_CAM_DEBUG_TRACE("%s.. crop:0x%x fs:0x%x cif_fmt_val:0x%x CIF_CIF_FOR:0x%x\n",__FUNCTION__,cif_crop,cif_fs,cif_fmt_val,read_cif_reg(pcdev->base,CIF_CIF_FOR));
+    RKCAMERA_DG1("CIF_CIF_CROP:0x%x  CIF_CIF_FS:0x%x  CIF_CIF_FOR:0x%x\n",cif_crop,cif_fs,cif_fmt_val);
        return;
 }
 
@@ -2245,12 +1791,15 @@ static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx
                                  struct soc_camera_format_xlate *xlate)
 {
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-    struct device *dev = icd->dev.parent;
+       struct device *dev = icd->parent;/*yzm*/
     int formats = 0, ret;
        enum v4l2_mbus_pixelcode code;
        const struct soc_mbus_pixelfmt *fmt;
 
-       ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
+       ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);  /*call generic_sensor_enum_fmt()*/
        if (ret < 0)
                /* No more formats */
                return 0;
@@ -2266,66 +1815,69 @@ static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx
         return 0;
 
     switch (code) {
-            case V4L2_MBUS_FMT_UYVY8_2X8:
-            case V4L2_MBUS_FMT_YUYV8_2X8:
-            case V4L2_MBUS_FMT_YVYU8_2X8:
-            case V4L2_MBUS_FMT_VYUY8_2X8:
+        case V4L2_MBUS_FMT_UYVY8_2X8:
+        case V4L2_MBUS_FMT_YUYV8_2X8:
+        case V4L2_MBUS_FMT_YVYU8_2X8:
+        case V4L2_MBUS_FMT_VYUY8_2X8:
+        {
+        
 #if (CONFIG_CAMERA_SCALE_CROP_MACHINE != RK_CAM_SCALE_CROP_RGA)
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[0];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[0].name,code);
-               }
-               
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[1];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[1].name,code);
-               }
-               
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[2];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[2].name,code);
-               } 
-               
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[3];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[3].name,code);
-               }
-               break;  
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[0];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[0].name,code);
+               }
+               
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[1];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[1].name,code);
+               }
+               
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[2];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[2].name,code);
+               } 
+               
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[3];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[3].name,code);
+               }
+               break;  
 #else 
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[4];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[4].name,code);
-               }
-               formats++;
-               if (xlate) {
-                       xlate->host_fmt = &rk_camera_formats[5];
-                       xlate->code = code;
-                       xlate++;
-                       dev_dbg(dev, "Providing format %s using code %d\n",
-                               rk_camera_formats[5].name,code);
-               }
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[4];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[4].name,code);
+               }
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = &rk_camera_formats[5];
+                       xlate->code = code;
+                       xlate++;
+                       dev_dbg(dev, "Providing format %s using code %d\n",
+                               rk_camera_formats[5].name,code);
+               }
                        break;          
 #endif                 
+        }
         default:
             break;
     }
@@ -2335,13 +1887,34 @@ static int rk_camera_get_formats(struct soc_camera_device *icd, unsigned int idx
 
 static void rk_camera_put_formats(struct soc_camera_device *icd)
 {
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
        return;
 }
+static int rk_camera_cropcap(struct soc_camera_device *icd, struct v4l2_cropcap *cropcap)
+{
+    struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+    int ret=0;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+    ret = v4l2_subdev_call(sd, video, cropcap, cropcap);
+    if (ret != 0)
+        goto end;
+    /* ddl@rock-chips.com: driver decide the cropping rectangle */
+    memset(&cropcap->defrect,0x00,sizeof(struct v4l2_rect));
+end:    
+    return ret;
+}
 static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *crop)
 {
-    struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
     spin_lock(&pcdev->cropinfo.lock);
     memcpy(&crop->c,&pcdev->cropinfo.c,sizeof(struct v4l2_rect));
     spin_unlock(&pcdev->cropinfo.lock);
@@ -2349,46 +1922,55 @@ static int rk_camera_get_crop(struct soc_camera_device *icd,struct v4l2_crop *cr
     return 0;
 }
 static int rk_camera_set_crop(struct soc_camera_device *icd,
-                              struct v4l2_crop *a)
+                              const struct v4l2_crop *crop)
 {
-    struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-       struct v4l2_mbus_framefmt mf;
-       u32 fourcc = icd->current_fmt->host_fmt->fourcc;
-    int ret;
-
-    ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
-    if (ret < 0)
-        return ret;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
+    struct rk_camera_dev *pcdev = ici->priv;
 
-    if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height)))  {
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
 
-        mf.width = a->c.left + a->c.width;
-        mf.height = a->c.top + a->c.height;
 
-        v4l_bound_align_image(&mf.width, RK_CAM_W_MIN, RK_CAM_W_MAX, 1,
-            &mf.height, RK_CAM_H_MIN, RK_CAM_H_MAX, 0,
-            fourcc == V4L2_PIX_FMT_NV16 ?4 : 0);
+    spin_lock(&pcdev->cropinfo.lock);
+    memcpy(&pcdev->cropinfo.c,&crop->c,sizeof(struct v4l2_rect));
+    spin_unlock(&pcdev->cropinfo.lock);
+    return 0;
+}
+static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
+{
+    bool ret = false;
 
-        ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
-        if (ret < 0)
-            return ret;
-    }
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
 
-    rk_camera_setup_format(icd, fourcc, mf.code, &a->c);
 
-    icd->user_width = mf.width;
-    icd->user_height = mf.height;
+    if (f->fmt.pix.priv == 0xfefe5a5a) {
+        ret = true;
+    }   
+   
+       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
+               ret = true;
+       } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
+               ret = true;
+       }
 
-    return 0;
+       if (ret == true)
+               RKCAMERA_DG1("%dx%d is capture format\n",f->fmt.pix.width, f->fmt.pix.height);
+       return ret;
 }
-
 static int rk_camera_set_fmt(struct soc_camera_device *icd,
                              struct v4l2_format *f)
 {
-    struct device *dev = icd->dev.parent;
+       struct device *dev = icd->parent;/*yzm*/
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
     const struct soc_camera_format_xlate *xlate = NULL;
-       struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
     struct v4l2_pix_format *pix = &f->fmt.pix;
     struct v4l2_mbus_framefmt mf;
@@ -2396,11 +1978,14 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
     int ret,usr_w,usr_h,sensor_w,sensor_h;
     int stream_on = 0;
     int ratio, bounds_aspect;
-    
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+       
        usr_w = pix->width;
        usr_h = pix->height;
     
-    RK30_CAM_DEBUG_TRACE("enter width:%d  height:%d\n",usr_w,usr_h);
+    RKCAMERA_DG1("enter width:%d  height:%d\n",usr_w,usr_h);
     xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
     if (!xlate) {
         dev_err(dev, "Format %x not found\n", pix->pixelformat);
@@ -2410,9 +1995,9 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
     
     /* ddl@rock-chips.com: sensor init code transmit in here after open */
     if (pcdev->icd_init == 0) {
-        v4l2_subdev_call(sd,core, init, 0); 
+        v4l2_subdev_call(sd,core, init, 0);  /*call generic_sensor_init()*/
         pcdev->icd_init = 1;
-        return 0;
+        return 0;                                                      /*directly return !!!!!!*/
     }
     stream_on = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
     if (stream_on & ENABLE_CAPTURE)
@@ -2426,7 +2011,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
     mf.reserved[0] = pix->priv;              /* ddl@rock-chips.com : v0.3.3 */
     mf.reserved[1] = 0;
 
-    ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
+    ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);  /*generic_sensor_s_fmt*/
     if (mf.code != xlate->code)
                return -EINVAL;                 
 
@@ -2434,7 +2019,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
         (pcdev->cropinfo.c.height == pcdev->cropinfo.bounds.height)) {
         bounds_aspect = (pcdev->cropinfo.bounds.width*10/pcdev->cropinfo.bounds.height);
         if ((mf.width*10/mf.height) != bounds_aspect) {
-            RK30_CAM_DEBUG_TRACE("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
+            RKCAMERA_DG1("User request fov unchanged in %dx%d, But sensor %dx%d is croped, so switch to full resolution %dx%d\n",
                         usr_w,usr_h,mf.width, mf.height,pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.height);
             
             mf.width   = pcdev->cropinfo.bounds.width/4;
@@ -2455,10 +2040,10 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
     sensor_w = mf.width;
     sensor_h = mf.height;
 
-    ratio = ((mf.width*mf.reserved[1])/100)&(~0x03);      // 4 align
+    ratio = ((mf.width*mf.reserved[1])/100)&(~0x03);      /* 4 align*/
     mf.width -= ratio;
 
-    ratio = ((ratio*mf.height/mf.width)+1)&(~0x01);       // 2 align
+    ratio = ((ratio*mf.height/mf.width)+1)&(~0x01);       /* 2 align*/
     mf.height -= ratio;
 
        if ((mf.width != usr_w) || (mf.height != usr_h)) {
@@ -2477,7 +2062,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
                spin_lock(&pcdev->cropinfo.lock);
                if (((mf.width*10/mf.height) != (usr_w*10/usr_h))) {  
             if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {        
-                //Scale + Crop center is for keep aspect ratio unchange
+                /*Scale + Crop center is for keep aspect ratio unchange*/
                 ratio = ((mf.width*10/usr_w) >= (mf.height*10/usr_h))?(mf.height*10/usr_h):(mf.width*10/usr_w);
                 pcdev->host_width = ratio*usr_w/10;
                 pcdev->host_height = ratio*usr_h/10;
@@ -2487,7 +2072,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
                 pcdev->host_left = ((sensor_w-pcdev->host_width )>>1);
                 pcdev->host_top = ((sensor_h-pcdev->host_height)>>1);
             } else {    
-                //Scale + crop(user define)
+                /*Scale + crop(user define)*/
                 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
                 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
                 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width);
@@ -2498,13 +2083,13 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
             pcdev->host_top &= (~0x01);
         } else { 
             if ((pcdev->cropinfo.c.width == 0)&&(pcdev->cropinfo.c.height == 0)) {
-                //Crop Center for cif can work , then scale
+                /*Crop Center for cif can work , then scale*/
                 pcdev->host_width = mf.width;
                 pcdev->host_height = mf.height;
                 pcdev->host_left = ((sensor_w - mf.width)>>1)&(~0x01);
                 pcdev->host_top = ((sensor_h - mf.height)>>1)&(~0x01);
             } else {
-                //Crop center for cif can work + crop(user define), then scale 
+                /*Crop center for cif can work + crop(user define), then scale */
                 pcdev->host_width = pcdev->cropinfo.c.width*mf.width/pcdev->cropinfo.bounds.width;
                 pcdev->host_height = pcdev->cropinfo.c.height*mf.height/pcdev->cropinfo.bounds.height;
                 pcdev->host_left = (pcdev->cropinfo.c.left*mf.width/pcdev->cropinfo.bounds.width)+((sensor_w - mf.width)>>1);
@@ -2539,7 +2124,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
        rect.top = pcdev->host_top;
         
         down(&pcdev->zoominfo.sem);
-#if CIF_DO_CROP   // this crop is only for digital zoom
+#if CIF_DO_CROP   /* this crop is only for digital zoom*/
         pcdev->zoominfo.a.c.left = 0;
         pcdev->zoominfo.a.c.top = 0;
         pcdev->zoominfo.a.c.width = pcdev->host_width*100/pcdev->zoominfo.zoom_rate;
@@ -2548,7 +2133,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
         pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
         pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
         pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
-        //recalculate the CIF width & height
+        /*recalculate the CIF width & height*/
         rect.width = pcdev->zoominfo.a.c.width ;
         rect.height = pcdev->zoominfo.a.c.height;
         rect.left = ((((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1))+pcdev->host_left)&(~0x01);
@@ -2558,7 +2143,7 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
         pcdev->zoominfo.a.c.width &= ~CROP_ALIGN_BYTES;
         pcdev->zoominfo.a.c.height = pcdev->host_height*100/pcdev->zoominfo.zoom_rate;
         pcdev->zoominfo.a.c.height &= ~CROP_ALIGN_BYTES;
-        //now digital zoom use ipp to do crop and scale
+        /*now digital zoom use ipp to do crop and scale*/
         if(pcdev->zoominfo.zoom_rate != 100){
             pcdev->zoominfo.a.c.left = ((pcdev->host_width - pcdev->zoominfo.a.c.width)>>1)&(~0x01);
             pcdev->zoominfo.a.c.top = ((pcdev->host_height - pcdev->zoominfo.a.c.height)>>1)&(~0x01);
@@ -2588,13 +2173,14 @@ static int rk_camera_set_fmt(struct soc_camera_device *icd,
             }
         }
         
-        RK30_CAM_DEBUG_TRACE("%s CIF Host:%dx%d@(%d,%d) Sensor:%dx%d->%dx%d User crop:(%d,%d,%d,%d)in(%d,%d) (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name,
+        RKCAMERA_DG1("%s CIF Host:%dx%d@(%d,%d) Sensor:%dx%d->%dx%d User crop:(%d,%d,%d,%d)in(%d,%d) (zoom: %dx%d@(%d,%d)->%dx%d)\n",xlate->host_fmt->name,
                                   pcdev->host_width,pcdev->host_height,pcdev->host_left,pcdev->host_top,
                                   sensor_w,sensor_h,mf.width,mf.height,
                                   pcdev->cropinfo.c.left,pcdev->cropinfo.c.top,pcdev->cropinfo.c.width,pcdev->cropinfo.c.height,
                                   pcdev->cropinfo.bounds.width,pcdev->cropinfo.bounds.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);
+                                  
         rk_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); 
         
                if (CAM_IPPWORK_IS_EN()) {
@@ -2616,39 +2202,18 @@ RK_CAMERA_SET_FMT_END:
        RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
     return ret;
 }
-static bool rk_camera_fmt_capturechk(struct v4l2_format *f)
-{
-    bool ret = false;
-
-       if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) {
-               ret = true;
-       } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) {
-               ret = true;
-       } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) {
-               ret = true;
-       } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) {
-               ret = true;
-       } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) {
-               ret = true;
-       } else if ((f->fmt.pix.width == 3264) && (f->fmt.pix.height == 2448)) {
-               ret = true;
-       }
 
-       if (ret == true)
-               RK30_CAM_DEBUG_TRACE("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height);
-       return ret;
-}
 static int rk_camera_try_fmt(struct soc_camera_device *icd,
                                    struct v4l2_format *f)
 {
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
        struct rk_camera_dev *pcdev = ici->priv;
     struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
     const struct soc_camera_format_xlate *xlate;
     struct v4l2_pix_format *pix = &f->fmt.pix;
     __u32 pixfmt = pix->pixelformat;
     int ret,usr_w,usr_h,i;
-       bool is_capture = rk_camera_fmt_capturechk(f);
+       bool is_capture = rk_camera_fmt_capturechk(f);  /* testing f is in line with the already set*/
        bool vipmem_is_overflow = false;
     struct v4l2_mbus_framefmt mf;
     int bytes_per_line_host;
@@ -2656,15 +2221,18 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
        usr_w = pix->width;
        usr_h = pix->height;
     
-    xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+    xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);  
     if (!xlate) {
-        dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,
+        /*dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,*/
+               dev_err(icd->parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF,/*yzm*/
                        (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF);
         ret = -EINVAL;
-        RK30_CAM_DEBUG_TRACE("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
+        RKCAMERA_TR("%s(version:%c%c%c) support format:\n",rk_cam_driver_description,(RK_CAM_VERSION_CODE&0xff0000)>>16,
             (RK_CAM_VERSION_CODE&0xff00)>>8,(RK_CAM_VERSION_CODE&0xff));
         for (i = 0; i < icd->num_user_formats; i++)
-                   RK30_CAM_DEBUG_TRACE("(%c%c%c%c)-%s\n",
+                   RKCAMERA_TR("(%c%c%c%c)-%s\n",
                    icd->user_formats[i].host_fmt->fourcc & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 8) & 0xFF,
                        (icd->user_formats[i].host_fmt->fourcc >> 16) & 0xFF, (icd->user_formats[i].host_fmt->fourcc >> 24) & 0xFF,
                        icd->user_formats[i].host_fmt->name);
@@ -2691,39 +2259,34 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
     if ((usr_w == 10000) && (usr_h == 10000)) {
         mf.reserved[6] = 0xfefe5a5a;
     }
-
+       /* call generic_sensor_try_fmt()*/
        ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
        if (ret < 0)
                goto RK_CAMERA_TRY_FMT_END;
     
-       //query resolution.
+       /*query resolution.*/
        if((usr_w == 10000) && (usr_h == 10000)) {
                pix->width = mf.width;
         pix->height = mf.height;
-        RK30_CAM_DEBUG_TRACE("%s: Sensor resolution : %dx%d\n",__FUNCTION__,mf.width,mf.height);
+        RKCAMERA_DG1("Sensor resolution : %dx%d\n",mf.width,mf.height);
                goto RK_CAMERA_TRY_FMT_END;
        } else {
-        RK30_CAM_DEBUG_TRACE("%s: user demand: %dx%d  sensor output: %dx%d \n",__FUNCTION__,usr_w,usr_h,mf.width,mf.height);
-       }
-    
-       #ifdef CONFIG_VIDEO_RK29_WORK_IPP       
+        RKCAMERA_DG1("user demand: %dx%d  sensor output: %dx%d \n",usr_w,usr_h,mf.width,mf.height);
+       }    
+           
        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); 
-        #ifndef OPTIMIZE_MEMORY_USE
                if (is_capture) {
                        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(bytes_per_line_host*mf.height)*4 > pcdev->vipmem_size);
-               }
-               #else
-                   vipmem_is_overflow =false;
-               #endif
+               }        
                if (vipmem_is_overflow == false) {
                        pix->width = usr_w;
                        pix->height = usr_h;
                } else {
-                       RK30_CAM_DEBUG_TRACE("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);
+                       /*RKCAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",mf.width,mf.height,usr_w,usr_h);*/ /*yzm*/
             pix->width = mf.width;
             pix->height = mf.height;            
                }
@@ -2731,24 +2294,14 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
         #if 0     
         if ((mf.width < usr_w) || (mf.height < usr_h)) {
             if (((usr_w>>1) > mf.width) || ((usr_h>>1) > mf.height)) {
-                RK30_CAM_DEBUG_TRACE("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",mf.width,mf.height,usr_w,usr_h);
+                RKCAMERA_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;
             }
         }    
         #endif
        }
-       #else
-       //need to change according to crop and scale capablicity
-       if ((mf.width > usr_w) && (mf.height > usr_h)) {
-                       pix->width = usr_w;
-                       pix->height = usr_h;
-           } else if ((mf.width < usr_w) && (mf.height < usr_h)) {
-                       RK30_CAM_DEBUG_TRACE("%dx%d can't scale up to %dx%d!\n",mf.width,mf.height,usr_w,usr_h);
-            pix->width = mf.width;
-               pix->height     = mf.height;    
-        }
-    #endif
+       
     pix->colorspace    = mf.colorspace;    
 
     switch (mf.field) {
@@ -2758,14 +2311,14 @@ static int rk_camera_try_fmt(struct soc_camera_device *icd,
                break;
        default:
                /* TODO: support interlaced at least in pass-through mode */
-               dev_err(icd->dev.parent, "Field type %d unsupported.\n",
+               dev_err(icd->parent, "Field type %d unsupported.\n",
                        mf.field);
                goto RK_CAMERA_TRY_FMT_END;
        }
 
 RK_CAMERA_TRY_FMT_END:
-       if (ret)
-       RK30_CAM_DEBUG_TRACE("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
+       if (ret<0)
+       RKCAMERA_TR("\n%s..%d.. ret = %d  \n",__FUNCTION__,__LINE__, ret);
     return ret;
 }
 
@@ -2774,6 +2327,9 @@ static int rk_camera_reqbufs(struct soc_camera_device *icd,
 {
     int i;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
     /* This is for locking debugging only. I removed spinlocks and now I
      * check whether .prepare is ever called on a linked buffer, or whether
      * a dma IRQ can occur for an in-work or unlinked buffer. Until now
@@ -2793,6 +2349,9 @@ static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
     struct soc_camera_device *icd = file->private_data;
     struct rk_camera_buffer *buf;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
     buf = list_entry(icd->vb_vidq.stream.next, struct rk_camera_buffer,
                     vb.stream);
 
@@ -2804,6 +2363,10 @@ static unsigned int rk_camera_poll(struct file *file, poll_table *pt)
 
     return 0;
 }
+/*
+*card:  sensor name _ facing _ device index - orientation _ fov horizontal _ fov vertical
+*           10          5           1            3              3                3         + 5 < 32           
+*/
 
 static int rk_camera_querycap(struct soc_camera_host *ici,
                                 struct v4l2_capability *cap)
@@ -2814,49 +2377,49 @@ static int rk_camera_querycap(struct soc_camera_host *ici,
     char fov[9];
     int i;
 
-    strlcpy(cap->card, dev_name(pcdev->icd->pdev), 20);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+
+    strlcpy(cap->card, dev_name(pcdev->icd->pdev), 18);       
     memset(orientation,0x00,sizeof(orientation));
-    for (i=0; i<RK_CAM_NUM;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);
-            sprintf(fov,"_50_50");
-        }
-    }
 
     i=0;
     new_camera = pcdev->pdata->register_dev_new;
-    while (strstr(new_camera->dev_name,"end")==NULL) {
+    while(new_camera != NULL){
         if (strcmp(dev_name(pcdev->icd->pdev), new_camera->dev_name) == 0) {
             sprintf(orientation,"-%d",new_camera->orientation);
             sprintf(fov,"_%d_%d",new_camera->fov_h,new_camera->fov_v);
         }
-        new_camera++;
+        new_camera = new_camera->next_camera;
     }
-
+    
     if (orientation[0] != '-') {
         RKCAMERA_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"))
+        if (strstr(dev_name(pcdev->icd->pdev),"front")) 
             strcat(cap->card,"-270");
-        else
+        else 
             strcat(cap->card,"-90");
     } else {
-        strcat(cap->card,orientation);
+        strcat(cap->card,orientation); 
     }
-
+    
     strcat(cap->card,fov);                          /* ddl@rock-chips.com: v0.3.f */
     cap->version = RK_CAM_VERSION_CODE;
     cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
 
     return 0;
 }
 static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
 {
-    struct soc_camera_host *ici =
-                    to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
        struct v4l2_subdev *sd;
     int ret = 0;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
        mutex_lock(&camera_lock);
        if ((pcdev->icd == icd) && (icd->ops->suspend)) {
                rk_camera_s_stream(icd, 0);
@@ -2875,9 +2438,9 @@ static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
                pcdev->reginfo_suspend.Inval = Reg_Validate;
                rk_camera_deactivate(pcdev);
 
-               RK30_CAM_DEBUG_TRACE("%s Enter Success...\n", __FUNCTION__);
+               RKCAMERA_DG1("%s Enter Success...\n", __FUNCTION__);
        } else {
-               RK30_CAM_DEBUG_TRACE("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
+               RKCAMERA_DG1("%s icd has been deattach, don't need enter suspend\n", __FUNCTION__);
        }
        mutex_unlock(&camera_lock);
     return ret;
@@ -2885,12 +2448,14 @@ static int rk_camera_suspend(struct soc_camera_device *icd, pm_message_t state)
 
 static int rk_camera_resume(struct soc_camera_device *icd)
 {
-    struct soc_camera_host *ici =
-                    to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
        struct v4l2_subdev *sd;
     int ret = 0;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
        mutex_lock(&camera_lock);
        if ((pcdev->icd == icd) && (icd->ops->resume)) {
                if (pcdev->reginfo_suspend.Inval == Reg_Validate) {
@@ -2902,12 +2467,13 @@ static int rk_camera_resume(struct soc_camera_device *icd)
                        write_cif_reg(pcdev->base,CIF_CIF_FOR, pcdev->reginfo_suspend.cifFmt);
                        write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH,pcdev->reginfo_suspend.cifVirWidth);
                        write_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL, pcdev->reginfo_suspend.cifScale);
+                       //rk_videobuf_capture(pcdev->active,pcdev);                     
                        rk_videobuf_capture(pcdev->active0,pcdev,0);
-                       rk_videobuf_capture(pcdev->active0,pcdev,1);
+                       rk_videobuf_capture(pcdev->active1,pcdev,1);
                        rk_camera_s_stream(icd, 1);
                        pcdev->reginfo_suspend.Inval = Reg_Invalidate;
                } else {
-                       RK30_CAM_DEBUG_TRACE("Resume fail, vip register recored is invalidate!!\n");
+                       RKCAMERA_TR("Resume fail, vip register recored is invalidate!!\n");
                        goto rk_camera_resume_end;
                }
 
@@ -2915,9 +2481,9 @@ static int rk_camera_resume(struct soc_camera_device *icd)
                sd = soc_camera_to_subdev(icd);
                v4l2_subdev_call(sd, video, s_stream, 1);
 
-               RK30_CAM_DEBUG_TRACE("%s Enter success\n",__FUNCTION__);
+               RKCAMERA_DG1("%s Enter success\n",__FUNCTION__);
        } else {
-               RK30_CAM_DEBUG_TRACE("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
+               RKCAMERA_DG1("%s icd has been deattach, don't need enter resume\n", __FUNCTION__);
        }
 
 rk_camera_resume_end:
@@ -2930,56 +2496,94 @@ static void rk_camera_reinit_work(struct work_struct *work)
     struct v4l2_subdev *sd;
        struct rk_camera_work *camera_work = container_of(work, struct rk_camera_work, work);
        struct rk_camera_dev *pcdev = camera_work->pcdev;
-    struct soc_camera_link *tmp_soc_cam_link;
+    /*struct soc_camera_link *tmp_soc_cam_link;*/
+    struct v4l2_mbus_framefmt mf;
     int index = 0;
        unsigned long flags = 0;
+    int ctrl;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+       //return;
+       
     if(pcdev->icd == NULL)
         return;
     sd = soc_camera_to_subdev(pcdev->icd);
-    tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
-       //dump regs
+    /*tmp_soc_cam_desc = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
+       /*dump regs*/
        {
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_INTEN = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_INTSTAT = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_FOR = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_CROP = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_SET_SIZE = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_SCL_CTRL = 0x%x\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
-               RK30_CAM_DEBUG_TRACE("CRU_PCLK_REG30 = 0X%x\n",read_cru_reg(CRU_PCLK_REG30));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_LAST_LINE = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
+               RKCAMERA_TR("CIF_CIF_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CTRL));
+               RKCAMERA_TR("CIF_CIF_INTEN = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTEN));
+               RKCAMERA_TR("CIF_CIF_INTSTAT = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_INTSTAT));
+               RKCAMERA_TR("CIF_CIF_FOR = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FOR));
+               RKCAMERA_TR("CIF_CIF_CROP = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CROP));
+               RKCAMERA_TR("CIF_CIF_SET_SIZE = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SET_SIZE));
+               RKCAMERA_TR("CIF_CIF_SCL_CTRL = 0x%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_CTRL));
+               RKCAMERA_TR("CRU_PCLK_REG30 = 0X%lx\n",read_cru_reg(CRU_PCLK_REG30));
+               RKCAMERA_TR("CIF_CIF_LAST_LINE = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_LINE));
                
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_LAST_PIX = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
-               RK30_CAM_DEBUG_TRACE("CIF_CIF_VIR_LINE_WIDTH = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
-       RK30_CAM_DEBUG_TRACE("CIF_CIF_LINE_NUM_ADDR = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
-       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRM0_ADDR_Y = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
-       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRM0_ADDR_UV = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
-       RK30_CAM_DEBUG_TRACE("CIF_CIF_FRAME_STATUS = 0X%x\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
+               RKCAMERA_TR("CIF_CIF_LAST_PIX = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LAST_PIX));
+               RKCAMERA_TR("CIF_CIF_VIR_LINE_WIDTH = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH));
+       RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
+       RKCAMERA_TR("CIF_CIF_FRM0_ADDR_Y = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_Y));
+       RKCAMERA_TR("CIF_CIF_FRM0_ADDR_UV = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRM0_ADDR_UV));
+       RKCAMERA_TR("CIF_CIF_FRAME_STATUS = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS));
+       RKCAMERA_TR("CIF_CIF_SCL_VALID_NUM = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_SCL_VALID_NUM));
+       RKCAMERA_TR("CIF_CIF_CUR_DST = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_CUR_DST));
+       RKCAMERA_TR("CIF_CIF_LINE_NUM_ADDR = 0X%lx\n",read_cif_reg(pcdev->base,CIF_CIF_LINE_NUM_ADDR));
        }
-    return;
-    pcdev->stop_cif = true;
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
-       RK30_CAM_DEBUG_TRACE("the reinit times = %d\n",pcdev->reinit_times);
-   if(pcdev->video_vq && pcdev->video_vq->irqlock){
-       spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
-       for (index = 0; index < VIDEO_MAX_FRAME; index++) {
-               if (NULL == pcdev->video_vq->bufs[index])
-                       continue;
+       
+    ctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);          /*ddl@rock-chips.com v0.3.0x13*/
+    if (pcdev->reinit_times == 1) {
+        if (ctrl & ENABLE_CAPTURE) {        
+            RKCAMERA_TR("Sensor data transfer may be error, so reset CIF and reinit sensor for resume!\n");
+            pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
+            rk_camera_cif_reset(pcdev,false);
+
+            
+            v4l2_subdev_call(sd,core, init, 0); 
+            
+            mf.width   = pcdev->icd_width;
+            mf.height  = pcdev->icd_height;
+            mf.field   = V4L2_FIELD_NONE;            
+            mf.code            = pcdev->icd->current_fmt->code;
+            mf.reserved[0] = 0x5a5afefe;              
+            mf.reserved[1] = 0;
+
+            v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
             
-               if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) 
-            {
-                       list_del_init(&pcdev->video_vq->bufs[index]->queue);
-                       pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
-                       wake_up_all(&pcdev->video_vq->bufs[index]->done);
+            write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
+        } else if (pcdev->irqinfo.cifirq_idx != pcdev->irqinfo.dmairq_idx) { 
+            RKCAMERA_TR("CIF may be error, so reset cif for resume\n");
+            pcdev->irqinfo.cifirq_idx = pcdev->irqinfo.dmairq_idx;
+            rk_camera_cif_reset(pcdev,false);
+            write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)|ENABLE_CAPTURE));
+        }
+        return;
+    }
+    
+    atomic_set(&pcdev->stop_cif,true);
+       write_cif_reg(pcdev->base,CIF_CIF_CTRL, (read_cif_reg(pcdev->base,CIF_CIF_CTRL)&(~ENABLE_CAPTURE)));
+       RKCAMERA_DG1("the reinit times = %d\n",pcdev->reinit_times);
+       
+    if(pcdev->video_vq && pcdev->video_vq->irqlock){
+        spin_lock_irqsave(pcdev->video_vq->irqlock, flags);
+        for (index = 0; index < VIDEO_MAX_FRAME; index++) {
+            if (NULL == pcdev->video_vq->bufs[index])
+                continue;
+
+            if (pcdev->video_vq->bufs[index]->state == VIDEOBUF_QUEUED) {
+                list_del_init(&pcdev->video_vq->bufs[index]->queue);
+                pcdev->video_vq->bufs[index]->state = VIDEOBUF_NEEDS_INIT;
+                wake_up_all(&pcdev->video_vq->bufs[index]->done);
                 printk("wake up video buffer index = %d  !!!\n",index);
-               }
-       }
-       spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags); 
+            }
+        }
+        spin_unlock_irqrestore(pcdev->video_vq->irqlock, flags); 
     }else{
-    RK30_CAM_DEBUG_TRACE("video queue has somthing wrong !!\n");
+        RKCAMERA_TR("video queue has somthing wrong !!\n");
     }
 
-       RK30_CAM_DEBUG_TRACE("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
+       RKCAMERA_TR("the %d reinit times ,wake up video buffers!\n ",pcdev->reinit_times);
 }
 static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
 {
@@ -2987,17 +2591,20 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
        struct rk_camera_timer *fps_timer = container_of(timer, struct rk_camera_timer, timer);
        struct rk_camera_dev *pcdev = fps_timer->pcdev;
     int rec_flag,i;
-   // static unsigned int last_fps = 0;
-    struct soc_camera_link *tmp_soc_cam_link;
-    tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);
+       /*static unsigned int last_fps = 0;*/
+       /*struct soc_camera_link *tmp_soc_cam_link;*/ /*yzm*/
+       /*tmp_soc_cam_link = to_soc_camera_link(pcdev->icd);*/ /*yzm*/
 
-       RK30_CAM_DEBUG_TRACE("rk_camera_fps_func fps:%d\n",(pcdev->fps - pcdev->last_fps)/3);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+       RKCAMERA_DG1("rk_camera_fps_func fps:0x%x\n",pcdev->fps);
        if ((pcdev->fps < 1) || (pcdev->last_fps == pcdev->fps)) {
-               RK30_CAM_DEBUG_TRACE("Camera host haven't recevie data from sensor,Reinit sensor delay,last fps = %d,pcdev->fps = %d!\n",pcdev->last_fps,pcdev->fps);
+               RKCAMERA_TR("Camera host haven't recevie data from sensor,last fps = %d,pcdev->fps = %d,cif_irq: %ld,dma_irq: %ld!\n",
+                           pcdev->last_fps,pcdev->fps,pcdev->irqinfo.cifirq_idx, pcdev->irqinfo.dmairq_idx);
                pcdev->camera_reinit_work.pcdev = pcdev;
-               //INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
+               /*INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);*/
         pcdev->reinit_times++;
-               queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));
+               queue_work(pcdev->camera_wq,&(pcdev->camera_reinit_work.work));//Æô¶¯¹¤×÷¶ÓÁжÔÓ¦µÄº¯Êý
        } else if(!pcdev->timer_get_fps) {
            pcdev->timer_get_fps = true;
            for (i=0; i<2; i++) {
@@ -3010,7 +2617,7 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
         fival_pre = fival_nxt;
         while (fival_nxt != NULL) {
 
-            RK30_CAM_DEBUG_TRACE("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(&pcdev->icd->dev),
+            RKCAMERA_DG1("%s %c%c%c%c %dx%d framerate : %d/%d\n", dev_name(pcdev->icd->control), /*yzm*/
                 fival_nxt->fival.pixel_format & 0xFF, (fival_nxt->fival.pixel_format >> 8) & 0xFF,
                            (fival_nxt->fival.pixel_format >> 16) & 0xFF, (fival_nxt->fival.pixel_format >> 24),
                            fival_nxt->fival.width, fival_nxt->fival.height, fival_nxt->fival.discrete.denominator,
@@ -3057,10 +2664,14 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
             }
         }
        }
+
+    if ((pcdev->last_fps != pcdev->fps) && (pcdev->reinit_times))             /*ddl@rock-chips.com v0.3.0x13*/
+        pcdev->reinit_times = 0;
+       
     pcdev->last_fps = pcdev->fps ;
     pcdev->fps_timer.timer.node.expires= ktime_add_us(pcdev->fps_timer.timer.node.expires, ktime_to_us(ktime_set(3, 0)));
     pcdev->fps_timer.timer._softexpires= ktime_add_us(pcdev->fps_timer.timer._softexpires, ktime_to_us(ktime_set(3, 0)));
-    //return HRTIMER_NORESTART;
+    /*return HRTIMER_NORESTART;*/
     if(pcdev->reinit_times >=2)
         return HRTIMER_NORESTART;
     else
@@ -3068,65 +2679,80 @@ static enum hrtimer_restart rk_camera_fps_func(struct hrtimer *timer)
 }
 static int rk_camera_s_stream(struct soc_camera_device *icd, int enable)
 {
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-       struct rk_camera_dev *pcdev = ici->priv;
-       int cif_ctrl_val;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
+    struct rk_camera_dev *pcdev = ici->priv;
+    int cif_ctrl_val;
        int ret;
        unsigned long flags;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);     
+
        WARN_ON(pcdev->icd != icd);
 
        cif_ctrl_val = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
        if (enable) {
                pcdev->fps = 0;
-               pcdev->last_fps = 0;
-               pcdev->frame_interval = 0;
+        pcdev->last_fps = 0;
+        pcdev->frame_interval = 0;
                hrtimer_cancel(&(pcdev->fps_timer.timer));
                pcdev->fps_timer.pcdev = pcdev;
-               pcdev->timer_get_fps = false;
-               pcdev->reinit_times  = 0;
-               pcdev->stop_cif = false;
-               pcdev->cif_stopped = false;
-               //      hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
+        pcdev->timer_get_fps = false;
+        pcdev->reinit_times  = 0;
+
+        spin_lock_irqsave(&pcdev->lock,flags);
+        atomic_set(&pcdev->stop_cif,false);
+        pcdev->irqinfo.cifirq_idx = 0;
+        pcdev->irqinfo.cifirq_normal_idx = 0;
+        pcdev->irqinfo.cifirq_abnormal_idx = 0;
+        pcdev->irqinfo.dmairq_idx = 0;
+               
+               write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x01|0x200);    /*capture complete interrupt enable*/
                cif_ctrl_val |= ENABLE_CAPTURE;
-               write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+        spin_unlock_irqrestore(&pcdev->lock,flags);
+        printk("%s:stream enable CIF_CIF_CTRL 0x%lx\n",__func__,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
                hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
-               pcdev->fps_timer.istarted = true;
+        pcdev->fps_timer.istarted = true;
        } else {
-           //cancel timer before stop cif
+           /*cancel timer before stop cif*/
                ret = hrtimer_cancel(&pcdev->fps_timer.timer);
         pcdev->fps_timer.istarted = false;
         flush_work(&(pcdev->camera_reinit_work.work));
+        
         cif_ctrl_val &= ~ENABLE_CAPTURE;
                spin_lock_irqsave(&pcdev->lock, flags);
-               //      write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
-        pcdev->stop_cif = true;
+       write_cif_reg(pcdev->base,CIF_CIF_CTRL, cif_ctrl_val);
+        atomic_set(&pcdev->stop_cif,true);
+               write_cif_reg(pcdev->base,CIF_CIF_INTEN, 0x0); 
        spin_unlock_irqrestore(&pcdev->lock, flags);
-#if CONFIG_CIF_STOP_SYNC
-                               init_waitqueue_head(&pcdev->cif_stop_done);
-                               if (wait_event_timeout(pcdev->cif_stop_done, pcdev->cif_stopped, msecs_to_jiffies(1000)) == 0) {
-                                       RKCAMERA_DG("%s:%d, wait cif stop timeout!",__func__,__LINE__);
-                               }
-#endif
-               //mdelay(35);
                flush_workqueue((pcdev->camera_wq));
-               RK30_CAM_DEBUG_TRACE("STREAM_OFF cancel timer and flush work:0x%x \n", ret);
+               msleep(100);
        }
-    //must be reinit,or will be somthing wrong in irq process.
+    /*must be reinit,or will be somthing wrong in irq process.*/
     if(enable == false) {
+        //pcdev->active = NULL;        
         pcdev->active0 = NULL;
                pcdev->active1 = NULL;
+               pcdev->active_buf = 0;
         INIT_LIST_HEAD(&pcdev->capture);
-       }
+    }
+       RKCAMERA_DG1("s_stream: enable : 0x%x , CIF_CIF_CTRL = 0x%lx\n",enable,read_cif_reg(pcdev->base,CIF_CIF_CTRL));
        return 0;
 }
 int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frmivalenum *fival)
 {
-    struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
     struct rk_camera_dev *pcdev = ici->priv;
+    struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
     struct rk_camera_frmivalenum *fival_list = NULL;
     struct v4l2_frmivalenum *fival_head = NULL;
+    struct rkcamera_platform_data *new_camera;
     int i,ret = 0,index;
+    const struct soc_camera_format_xlate *xlate;
+    struct v4l2_mbus_framefmt mf;
+    __u32 pixfmt;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);     
     
     index = fival->index & 0x00ffffff;
     if ((fival->index & 0xff000000) == 0xff000000) {   /* ddl@rock-chips.com: detect framerate */ 
@@ -3155,139 +2781,181 @@ int rk_camera_enum_frameintervals(struct soc_camera_device *icd, struct v4l2_frm
                 ret = -EINVAL;
             }
         } else {
-            RK30_CAM_DEBUG_TRACE("%s: fival_list is NULL\n",__FUNCTION__);
+            RKCAMERA_TR("%s: fival_list is NULL\n",__FUNCTION__);
             ret = -EINVAL;
         }
     }  else {  
 
-        for (i=0; i<RK_CAM_NUM; 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) {
-            RK30_CAM_DEBUG_TRACE("%s: %s is not registered in rk_camera_platform_data!!",__FUNCTION__,dev_name(pcdev->icd->pdev));
-            ret = -EINVAL;
-            goto rk_camera_enum_frameintervals_end;
-        }
-        
-        i = 0;
-        while (fival_head->width && fival_head->height) {
-            if ((fival->pixel_format == fival_head->pixel_format)
-                && (fival->height == fival_head->height) 
-                && (fival->width == fival_head->width)) {
-                if (i == index) {
-                    break;
+        if (fival_head) {
+            i = 0;
+            while (fival_head->width && fival_head->height) {
+                if ((fival->pixel_format == fival_head->pixel_format)
+                    && (fival->height == fival_head->height) 
+                    && (fival->width == fival_head->width)) {
+                    if (i == index) {
+                        break;
+                    }
+                    i++;
                 }
-                i++;
+                fival_head++;  
             }
-            fival_head++;  
-        }
 
-        if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
-            memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
-            RK30_CAM_DEBUG_TRACE("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->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)
-                RK30_CAM_DEBUG_TRACE("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->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
-                RK30_CAM_DEBUG_TRACE("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->icd->pdev),
-                    fival->width,fival->height, 
+            if ((i == index) && (fival->height == fival_head->height) && (fival->width == fival_head->width)) {
+                memcpy(fival, fival_head, sizeof(struct v4l2_frmivalenum));
+
+                pixfmt = fival->pixel_format;     /* ddl@rock-chips.com: v0.3.9 */
+                xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+                memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
+               mf.width        = fival->width;
+               mf.height       = fival->height;                
+               mf.code         = xlate->code;                
+
+               v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+                
+                fival->reserved[1] = (mf.width<<16)|(mf.height);
+                
+                RKCAMERA_DG1("%s %dx%d@%c%c%c%c framerate : %d/%d\n", dev_name(pcdev->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);
-            ret = -EINVAL;
+                            fival->discrete.denominator,fival->discrete.numerator);                        
+            } else {
+                if (index == 0)
+                    RKCAMERA_TR("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->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
+                    RKCAMERA_DG1("%s have not catch %d%d@%c%c%c%c index(%d) framerate\n",dev_name(pcdev->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);
+                ret = -EINVAL;
+                goto rk_camera_enum_frameintervals_end;
+            }
+        } else {
+            i = 0x00;
+            new_camera = pcdev->pdata->register_dev_new;
+            while(new_camera != NULL){
+                if (strcmp(new_camera->dev_name, dev_name(pcdev->icd->pdev)) == 0) {
+                    i = 0x01;                
+                    break;
+                }
+                new_camera = new_camera->next_camera;
+            }
+
+            if (i == 0x00) {
+                printk(KERN_ERR "%s(%d): %s have not found in new_camera[] and rk_camera_platform_data!",
+                    __FUNCTION__,__LINE__,dev_name(pcdev->icd->pdev));
+            } else {
+
+                pixfmt = fival->pixel_format;     /* ddl@rock-chips.com: v0.3.9 */
+                xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+                memset(&mf,0x00,sizeof(struct v4l2_mbus_framefmt));
+               mf.width        = fival->width;
+               mf.height       = fival->height;                
+               mf.code         = xlate->code;                
+
+               v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
+                
+                fival->discrete.numerator= 1000;
+                fival->discrete.denominator = 15000;
+                fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+                fival->reserved[1] = (mf.width<<16)|(mf.height);                
+            }
         }
     }
 rk_camera_enum_frameintervals_end:
     return ret;
 }
 
-#ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
 static int rk_camera_set_digit_zoom(struct soc_camera_device *icd,
                                                                const struct v4l2_queryctrl *qctrl, int zoom_rate)
 {
        struct v4l2_crop a;
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
        struct rk_camera_dev *pcdev = ici->priv;
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+
 #if CIF_DO_CROP    
        unsigned long tmp_cifctrl; 
 #endif 
 
-       //change the crop and scale parameters
+       /*change the crop and scale parameters*/
        
 #if CIF_DO_CROP
-       a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       //a.c.width = pcdev->host_width*100/zoom_rate;
-       a.c.width = pcdev->host_width*100/zoom_rate;
-       a.c.width &= ~CROP_ALIGN_BYTES;    
-       a.c.height = pcdev->host_height*100/zoom_rate;
-       a.c.height &= ~CROP_ALIGN_BYTES;
-       a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
-       a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
-       pcdev->stop_cif = true;
-       tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
-       write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
-       hrtimer_cancel(&(pcdev->fps_timer.timer));
-       flush_workqueue((pcdev->camera_wq));
-       down(&pcdev->zoominfo.sem);
-       pcdev->zoominfo.a.c.left = 0;
-       pcdev->zoominfo.a.c.top = 0;
-       pcdev->zoominfo.a.c.width = a.c.width;
-       pcdev->zoominfo.a.c.height = a.c.height;
-       pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
-       pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
-       pcdev->frame_inval = 1;
-       write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
-       write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
-       write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
-       write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
+    a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    /*a.c.width = pcdev->host_width*100/zoom_rate;*/
+    a.c.width = pcdev->host_width*100/zoom_rate;
+    a.c.width &= ~CROP_ALIGN_BYTES;    
+    a.c.height = pcdev->host_height*100/zoom_rate;
+    a.c.height &= ~CROP_ALIGN_BYTES;
+    a.c.left = (((pcdev->host_width - a.c.width)>>1)+pcdev->host_left)&(~0x01);
+    a.c.top = (((pcdev->host_height - a.c.height)>>1)+pcdev->host_top)&(~0x01);
+    atomic_set(&pcdev->stop_cif,true);
+    tmp_cifctrl = read_cif_reg(pcdev->base,CIF_CIF_CTRL);
+    write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl & ~ENABLE_CAPTURE));
+    hrtimer_cancel(&(pcdev->fps_timer.timer));
+    flush_workqueue((pcdev->camera_wq));
+    
+    down(&pcdev->zoominfo.sem);
+    pcdev->zoominfo.a.c.left = 0;
+    pcdev->zoominfo.a.c.top = 0;
+    pcdev->zoominfo.a.c.width = a.c.width;
+    pcdev->zoominfo.a.c.height = a.c.height;
+    pcdev->zoominfo.vir_width = pcdev->zoominfo.a.c.width;
+    pcdev->zoominfo.vir_height = pcdev->zoominfo.a.c.height;
+    pcdev->frame_inval = 1;
+    write_cif_reg(pcdev->base,CIF_CIF_CROP, (a.c.left + (a.c.top<<16)));
+    write_cif_reg(pcdev->base,CIF_CIF_SET_SIZE, ((a.c.width ) + (a.c.height<<16)));
+    write_cif_reg(pcdev->base,CIF_CIF_VIR_LINE_WIDTH, a.c.width);
+    write_cif_reg(pcdev->base,CIF_CIF_FRAME_STATUS,  0x00000002);//frame1 has been ready to receive data,frame 2 is not used
+    //if(pcdev->active)
+        //rk_videobuf_capture(pcdev->active,pcdev);        
        if(pcdev->active0)
                rk_videobuf_capture(pcdev->active0,pcdev,0);
        if(pcdev->active1)
                rk_videobuf_capture(pcdev->active1,pcdev,1);
-       if(tmp_cifctrl & ENABLE_CAPTURE)
-               write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
-       up(&pcdev->zoominfo.sem);
-       pcdev->stop_cif = false;
-       hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
-       RK30_CAM_DEBUG_TRACE("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
+    if(tmp_cifctrl & ENABLE_CAPTURE)
+        write_cif_reg(pcdev->base,CIF_CIF_CTRL, (tmp_cifctrl | ENABLE_CAPTURE));
+    up(&pcdev->zoominfo.sem);
+    
+    atomic_set(&pcdev->stop_cif,false);
+    hrtimer_start(&(pcdev->fps_timer.timer),ktime_set(3, 0),HRTIMER_MODE_REL);
+    RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
 #else
-       a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       a.c.width = pcdev->host_width*100/zoom_rate;
-       a.c.width &= ~CROP_ALIGN_BYTES;    
-       a.c.height = pcdev->host_height*100/zoom_rate;
-       a.c.height &= ~CROP_ALIGN_BYTES;
-       a.c.left = (pcdev->host_width - a.c.width)>>1;
-       a.c.top = (pcdev->host_height - a.c.height)>>1;
-       down(&pcdev->zoominfo.sem);
-       pcdev->zoominfo.a.c.height = a.c.height;
-       pcdev->zoominfo.a.c.width = a.c.width;
-       pcdev->zoominfo.a.c.top = a.c.top;
-       pcdev->zoominfo.a.c.left = a.c.left;
-       pcdev->zoominfo.vir_width = pcdev->host_width;
-       pcdev->zoominfo.vir_height= pcdev->host_height;
-       up(&pcdev->zoominfo.sem);
-       RK30_CAM_DEBUG_TRACE("%s..zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n",__FUNCTION__, zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
+    a.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    a.c.width = pcdev->host_width*100/zoom_rate;
+    a.c.width &= ~CROP_ALIGN_BYTES;    
+    a.c.height = pcdev->host_height*100/zoom_rate;
+    a.c.height &= ~CROP_ALIGN_BYTES;
+    a.c.left = (pcdev->host_width - a.c.width)>>1;
+    a.c.top = (pcdev->host_height - a.c.height)>>1;
+    
+    down(&pcdev->zoominfo.sem);
+    pcdev->zoominfo.a.c.height = a.c.height;
+    pcdev->zoominfo.a.c.width = a.c.width;
+    pcdev->zoominfo.a.c.top = a.c.top;
+    pcdev->zoominfo.a.c.left = a.c.left;
+    pcdev->zoominfo.vir_width = pcdev->host_width;
+    pcdev->zoominfo.vir_height= pcdev->host_height;
+    up(&pcdev->zoominfo.sem);
+    
+    RKCAMERA_DG1("zoom_rate:%d (%dx%d at (%d,%d)-> %dx%d)\n", zoom_rate,a.c.width, a.c.height, a.c.left, a.c.top, icd->user_width, icd->user_height );
 #endif 
 
        return 0;
 }
-#endif
+
 static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
        struct soc_camera_host_ops *ops, int id)
 {
-       int i;
 
+       int i;
        for (i = 0; i < ops->num_controls; i++)
                if (ops->controls[i].id == id)
                        return &ops->controls[i];
@@ -3299,31 +2967,28 @@ static inline struct v4l2_queryctrl const *rk_camera_soc_camera_find_qctrl(
 static int rk_camera_set_ctrl(struct soc_camera_device *icd,
                                                                struct v4l2_control *sctrl)
 {
-
-       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);/*yzm*/
        const struct v4l2_queryctrl *qctrl;
-#ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON    
     struct rk_camera_dev *pcdev = ici->priv;
-#endif
+
     int ret = 0;
 
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
        qctrl = rk_camera_soc_camera_find_qctrl(ici->ops, sctrl->id);
        if (!qctrl) {
                ret = -ENOIOCTLCMD;
         goto rk_camera_set_ctrl_end;
        }
-       
-    if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
-               ret = -EINVAL;
-        goto rk_camera_set_ctrl_end;
-       }
-       
+
        switch (sctrl->id)
        {
-       #ifdef CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON
                case V4L2_CID_ZOOM_ABSOLUTE:
                {
-                       
+                       if ((sctrl->value < qctrl->minimum) || (sctrl->value > qctrl->maximum)){
+                       ret = -EINVAL;
+                goto rk_camera_set_ctrl_end;
+               }
             ret = rk_camera_set_digit_zoom(icd, qctrl, sctrl->value);
                        if (ret == 0) {
                                pcdev->zoominfo.zoom_rate = sctrl->value;
@@ -3332,32 +2997,6 @@ static int rk_camera_set_ctrl(struct soc_camera_device *icd,
             }
                        break;
                }
-    #endif
-
-        case V4L2_CID_HDR:
-        {            
-            if (pcdev->hdr_info.en != sctrl->value) {
-                pcdev->hdr_info.en = sctrl->value;
-                if (sctrl->value) {
-                                       struct device *control = to_soc_camera_control(pcdev->icd);
-                                       struct v4l2_subdev *sd=dev_get_drvdata(control);
-
-                    printk("hdr on\n");
-                    pcdev->hdr_info.frame[0].code = RK_VIDEOBUF_HDR_EXPOSURE_MINUS_1;
-                    pcdev->hdr_info.frame[0].set_ts = 0;
-                    pcdev->hdr_info.frame[0].get_ts = 0;
-                    pcdev->hdr_info.frame[1].code = RK_VIDEOBUF_HDR_EXPOSURE_NORMAL;
-                    pcdev->hdr_info.frame[1].set_ts = 0;
-                    pcdev->hdr_info.frame[1].get_ts = 0;
-                    pcdev->hdr_info.frame[2].code = RK_VIDEOBUF_HDR_EXPOSURE_PLUS_1;
-                    pcdev->hdr_info.frame[2].set_ts = 0;
-                    pcdev->hdr_info.frame[2].get_ts = 0;
-                    v4l2_subdev_call(sd, core, ioctl, RK29_CAM_SUBDEV_HDR_EXPOSURE,RK_VIDEOBUF_HDR_EXPOSURE_NORMAL);
-                }
-            }
-            break;
-        }
-    
                default:
                        ret = -ENOIOCTLCMD;
                        break;
@@ -3366,16 +3005,6 @@ rk_camera_set_ctrl_end:
        return ret;
 }
 
-int rk_camera_enum_fsizes(struct soc_camera_device *icd, struct v4l2_frmsizeenum *fsize)
-{
-    struct device *control = to_soc_camera_control(icd);
-    struct v4l2_subdev *sd;
-
-    sd = dev_get_drvdata(control);
-    return v4l2_subdev_call(sd, video, enum_framesizes, fsize);
-
-}
-
 static struct soc_camera_host_ops rk_soc_camera_host_ops =
 {
     .owner             = THIS_MODULE,
@@ -3384,8 +3013,9 @@ static struct soc_camera_host_ops rk_soc_camera_host_ops =
     .suspend   = rk_camera_suspend,
     .resume            = rk_camera_resume,
     .enum_frameinervals = rk_camera_enum_frameintervals,
-    .enum_fsizes = rk_camera_enum_fsizes,
+    .cropcap    = rk_camera_cropcap,
     .set_crop  = rk_camera_set_crop,
+    .get_crop   = rk_camera_get_crop,
     .get_formats       = rk_camera_get_formats, 
     .put_formats       = rk_camera_put_formats,
     .set_fmt   = rk_camera_set_fmt,
@@ -3401,94 +3031,83 @@ static struct soc_camera_host_ops rk_soc_camera_host_ops =
     .num_controls = ARRAY_SIZE(rk_camera_controls)
 };
 
-static void rk_camera_cif_iomux(int cif_index)
+/**********yzm***********/
+static int rk_camera_cif_iomux(struct device *dev)
 {
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
-    switch(cif_index){
-        case 0:
-                       iomux_set(CIF0_CLKOUT);
-            write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_4MA));
-            write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
-            #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
-               iomux_set(CIF0_D0);
-               iomux_set(CIF0_D1);
-            #endif
-            #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
-               iomux_set(CIF0_D10);
-               iomux_set(CIF0_D11);
-            RK30_CAM_DEBUG_TRACE("%s(%d): WARNING: Cif 0 is configurated that support RAW 12bit, so I2C3 is invalidate!!\n",__FUNCTION__,__LINE__);
-            #endif
-            
-            break;
-        default:
-            RK30_CAM_DEBUG_TRACE("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
-            break;
+
+    struct pinctrl      *pinctrl;
+    struct pinctrl_state    *state;
+    int retval = 0;
+    char state_str[20] = {0};
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+    strcpy(state_str,"cif_pin_jpe");
+
+       /*__raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);*/
+
+
+    /*mux CIF0_CLKOUT*/
+
+    pinctrl = devm_pinctrl_get(dev);
+    if (IS_ERR(pinctrl)) {
+        printk(KERN_EMERG "%s:Get pinctrl failed!\n",__func__);
+        return -1;
     }
-#elif defined(CONFIG_ARCH_RK30)
-    switch(cif_index){
-        case 0:
-            rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
-            #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & (RK_CAM_INPUT_FMT_RAW10|RK_CAM_INPUT_FMT_RAW12))
-               rk30_mux_api_set(GPIO1B4_CIF0DATA0_NAME, GPIO1B_CIF0_DATA0);
-               rk30_mux_api_set(GPIO1B5_CIF0DATA1_NAME, GPIO1B_CIF0_DATA1);
-            #endif
-            #if (CONFIG_CAMERA_INPUT_FMT_SUPPORT & RK_CAM_INPUT_FMT_RAW12)
-               rk30_mux_api_set(GPIO1B6_CIFDATA10_NAME, GPIO1B_CIF_DATA10);
-               rk30_mux_api_set(GPIO1B7_CIFDATA11_NAME, GPIO1B_CIF_DATA11);
-            #endif
-            break;
-        case 1:
-            rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
-            rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
-            rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
-            rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
-            rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
-            rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
-            rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
-            rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
-            
-            rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
-            rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
-            rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
-            rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
-            rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
-            rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
-            rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
-            rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
-            break;
-        default:
-            RK30_CAM_DEBUG_TRACE("%s(%d): Cif index(%d) is invalidate!!!\n",__FUNCTION__,__LINE__, cif_index);
-            break;
+    state = pinctrl_lookup_state(pinctrl,
+                         state_str);
+    if (IS_ERR(state)){
+        dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
+        return -1;
         }
-#endif
-                
+
+    if (!IS_ERR(state)) {
+        retval = pinctrl_select_state(pinctrl, state);
+        if (retval){
+            dev_err(dev,
+                "%s:could not set %s pins\n",__func__,state_str);
+                return -1;
+
+                }
+    }
+    return 0;
             
 }
+/***********yzm***********/
 static int rk_camera_probe(struct platform_device *pdev)
 {
     struct rk_camera_dev *pcdev;
     struct resource *res;
     struct rk_camera_frmivalenum *fival_list,*fival_nxt;
-    struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
     int irq,i;
     int err = 0;
     struct rk_cif_clk *clk=NULL;
+       struct device *dev_cif = ((struct rk29camera_platform_data*)pdev->dev.platform_data)->cif_dev;/*yzm*/
 
-    printk("%s version: v%d.%d.%d  Zoom by %s\n",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+       RKCAMERA_TR("%s version: v%d.%d.%d  Zoom by %s",RK29_CAM_DRV_NAME,(RK_CAM_VERSION_CODE&0xff0000)>>16,
         (RK_CAM_VERSION_CODE&0xff00)>>8,RK_CAM_VERSION_CODE&0xff,CAMERA_SCALE_CROP_MACHINE);    
 
     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_1) && (RK_SUPPORT_CIF1 == 0)) {
-        RK30_CAM_DEBUG_TRACE("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
+        RKCAMERA_TR("%s(%d): This chip is not support CIF1!!\n",__FUNCTION__,__LINE__);
         BUG();
     }
 
     if ((pdev->id == RK_CAM_PLATFORM_DEV_ID_0) && (RK_SUPPORT_CIF0 == 0)) {
-        RK30_CAM_DEBUG_TRACE("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
+        RKCAMERA_TR("%s(%d): This chip is not support CIF0!!\n",__FUNCTION__,__LINE__);
         BUG();
     }
-    
+
+/***********yzm**********/
+       rk_camera_diffchips(((struct rk29camera_platform_data*)pdev->dev.platform_data)->rockchip_name);
+
     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
     irq = platform_get_irq(pdev, 0);
+
+       /*      irq = irq_of_parse_and_map(dev_cif->of_node, 0);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n res = [%x--%x] \n",res->start , res->end);
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n irq_num = %d\n", irq);
+       */
     if (!res || irq < 0) {
         err = -ENODEV;
         goto exit;
@@ -3500,70 +3119,53 @@ static int rk_camera_probe(struct platform_device *pdev)
         goto exit_alloc;
     }
 
-       pcdev->zoominfo.zoom_rate = 100;
-       pcdev->hostid = pdev->id;
-    /*config output clk*/ // must modify start
-    if(IS_CIF0()){
+    pcdev->zoominfo.zoom_rate = 100;
+    pcdev->hostid = pdev->id;        /* get host id*/
+    #ifdef CONFIG_SOC_RK3028
+    pcdev->chip_id = rk3028_version_val();
+    #else
+    pcdev->chip_id = -1;
+    #endif
+
+       /***********yzm***********/
+       if (IS_CIF0()) {
+               debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$/is_cif0\n");
         clk = &cif_clk[0];
-        cif_clk[0].pd_cif = clk_get(NULL, "pd_cif0");
-        cif_clk[0].aclk_cif = clk_get(NULL, "aclk_cif0");
-        cif_clk[0].hclk_cif = clk_get(NULL, "hclk_cif0");
-        cif_clk[0].cif_clk_in = clk_get(NULL, "cif0_in");
-        cif_clk[0].cif_clk_out = clk_get(NULL, "cif0_out");
-        spin_lock_init(&cif_clk[0].lock);
+        cif_clk[0].pd_cif = devm_clk_get(dev_cif, "pd_cif0");
+        cif_clk[0].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
+        cif_clk[0].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
+        cif_clk[0].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
+        cif_clk[0].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
+        //spin_lock_init(&cif_clk[0].lock);
         cif_clk[0].on = false;
-        rk_camera_cif_iomux(0);
+        rk_camera_cif_iomux(dev_cif);/*yzm*/
     } else {
-        clk = &cif_clk[1];
-        cif_clk[1].pd_cif = clk_get(NULL, "pd_cif1");
-        cif_clk[1].aclk_cif = clk_get(NULL, "aclk_cif1");
-        cif_clk[1].hclk_cif = clk_get(NULL, "hclk_cif1");
-        cif_clk[1].cif_clk_in = clk_get(NULL, "cif1_in");
-        cif_clk[1].cif_clk_out = clk_get(NULL, "cif1_out");
-        spin_lock_init(&cif_clk[1].lock);
+       clk = &cif_clk[1];
+        cif_clk[1].pd_cif = devm_clk_get(dev_cif, "pd_cif0");/*cif0  only yzm*/
+        cif_clk[1].aclk_cif = devm_clk_get(dev_cif, "aclk_cif0");
+        cif_clk[1].hclk_cif = devm_clk_get(dev_cif, "hclk_cif0");
+        cif_clk[1].cif_clk_in = devm_clk_get(dev_cif, "cif0_in");
+        cif_clk[1].cif_clk_out = devm_clk_get(dev_cif, "cif0_out");
+        //spin_lock_init(&cif_clk[1].lock);
         cif_clk[1].on = false;
-        
-        rk_camera_cif_iomux(1);
+        rk_camera_cif_iomux(dev_cif);/*yzm*/
     }
-    
-    
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
+       /***********yzm**********/
     dev_set_drvdata(&pdev->dev, pcdev);
     pcdev->res = res;
     pcdev->pdata = pdev->dev.platform_data;             /* ddl@rock-chips.com : Request IO in init function */
-       pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
+                                       /*= rk_camera_platform_data */
        if (pcdev->pdata && pcdev->pdata->io_init) {
-        pcdev->pdata->io_init();
-    }
-       #ifdef CONFIG_VIDEO_RK29_WORK_IPP
-    meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
-    meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
-    
-    if (meminfo_ptr->vbase == NULL) {
-
-        if ((meminfo_ptr->start == meminfo_ptrr->start)
-            && (meminfo_ptr->size == meminfo_ptrr->size) && meminfo_ptrr->vbase) {
+               
+        pcdev->pdata->io_init();/* call rk_sensor_io_init()*/
 
-            meminfo_ptr->vbase = meminfo_ptrr->vbase;
-        } else {        
-        
-            if (!request_mem_region(meminfo_ptr->start,meminfo_ptr->size,"rk29_vipmem")) {
-                err = -EBUSY;
-                RK30_CAM_DEBUG_TRACE("%s(%d): request_mem_region(start:0x%x size:0x%x) failed \n",__FUNCTION__,__LINE__, pcdev->pdata->meminfo.start,pcdev->pdata->meminfo.size);
-                goto exit_ioremap_vipmem;
-            }
-            meminfo_ptr->vbase = pcdev->vipmem_virbase = ioremap_cached(meminfo_ptr->start,meminfo_ptr->size);
-            if (pcdev->vipmem_virbase == NULL) {
-                RK30_CAM_DEBUG_TRACE("%s(%d): ioremap of CIF internal memory(Ex:IPP process/raw process) failed\n",__FUNCTION__,__LINE__);
-                err = -ENXIO;
-                goto exit_ioremap_vipmem;
-            }
-        }
+        if (pcdev->pdata->sensor_mclk == NULL)
+            pcdev->pdata->sensor_mclk = rk_camera_mclk_ctrl;
     }
-    
-    pcdev->vipmem_phybase = meminfo_ptr->start;
-       pcdev->vipmem_size = meminfo_ptr->size;
-    pcdev->vipmem_virbase = meminfo_ptr->vbase;
-       #endif
+
     INIT_LIST_HEAD(&pcdev->capture);
     INIT_LIST_HEAD(&pcdev->camera_work_queue);
     spin_lock_init(&pcdev->lock);
@@ -3590,13 +3192,13 @@ static int rk_camera_probe(struct platform_device *pdev)
         }
     }
        
-    pcdev->irq = irq;
+    pcdev->irqinfo.irq = irq;
     pcdev->dev = &pdev->dev;
 
     /* config buffer address */
     /* request irq */
     if(irq > 0){
-        err = request_irq(pcdev->irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
+        err = request_irq(pcdev->irqinfo.irq, rk_camera_irq, 0, RK29_CAM_DRV_NAME,
                           pcdev);
         if (err) {
             dev_err(pcdev->dev, "Camera interrupt register failed \n");
@@ -3604,15 +3206,15 @@ static int rk_camera_probe(struct platform_device *pdev)
         }
        }
    
-//#ifdef CONFIG_VIDEO_RK29_WORK_IPP
     if(IS_CIF0()) {
        pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif0");
     } else {
        pcdev->camera_wq = create_workqueue("rk_cam_wkque_cif1");
     }
-    if (pcdev->camera_wq == NULL)
-       goto exit_free_irq;
-//#endif
+    if (pcdev->camera_wq == NULL) {
+        RKCAMERA_TR("%s(%d): Create workqueue failed!\n",__FUNCTION__,__LINE__);
+        goto exit_free_irq;
+    }
 
        pcdev->camera_reinit_work.pcdev = pcdev;
        INIT_WORK(&(pcdev->camera_reinit_work.work), rk_camera_reinit_work);
@@ -3624,18 +3226,23 @@ static int rk_camera_probe(struct platform_device *pdev)
     }
     pcdev->soc_host.drv_name   = RK29_CAM_DRV_NAME;
     pcdev->soc_host.ops                = &rk_soc_camera_host_ops;
-    pcdev->soc_host.priv               = pcdev;
+    pcdev->soc_host.priv               = pcdev;        /*to itself,csll in rk_camera_add_device*/
     pcdev->soc_host.v4l2_dev.dev       = &pdev->dev;
     pcdev->soc_host.nr         = pdev->id;
-
+       debug_printk("/$$$$$$$$$$$$$$$$$$$$$$/next soc_camera_host_register\n");
     err = soc_camera_host_register(&pcdev->soc_host);
-    if (err)
+
+
+    if (err) {
+        RKCAMERA_TR("%s(%d): soc_camera_host_register failed\n",__FUNCTION__,__LINE__);
         goto exit_free_irq;
+    }
        pcdev->fps_timer.pcdev = pcdev;
        hrtimer_init(&(pcdev->fps_timer.timer), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        pcdev->fps_timer.timer.function = rk_camera_fps_func;
     pcdev->icd_cb.sensor_cb = NULL;
-#if ((defined(CONFIG_VIDEO_RK29_DIGITALZOOM_IPP_ON)) && (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP))
+
+#if (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_IPP)
     pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_ipp;
 #elif (CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_ARM)
     pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_arm;
@@ -3644,7 +3251,6 @@ static int rk_camera_probe(struct platform_device *pdev)
 #elif(CONFIG_CAMERA_SCALE_CROP_MACHINE == RK_CAM_SCALE_CROP_PP)
        pcdev->icd_cb.scale_crop_cb = rk_camera_scale_crop_pp; 
 #endif
-    RK30_CAM_DEBUG_TRACE("%s(%d) Exit  \n",__FUNCTION__,__LINE__);
     return 0;
 
 exit_free_irq:
@@ -3659,7 +3265,7 @@ exit_free_irq:
         }
     }
     
-    free_irq(pcdev->irq, pcdev);
+    free_irq(pcdev->irqinfo.irq, pcdev);
        if (pcdev->camera_wq) {
                destroy_workqueue(pcdev->camera_wq);
                pcdev->camera_wq = NULL;
@@ -3668,20 +3274,19 @@ exit_reqirq:
     iounmap(pcdev->base);
 exit_ioremap_vip:
     release_mem_region(res->start, res->end - res->start + 1);
-exit_ioremap_vipmem:
-    if (pcdev->vipmem_virbase)
-        iounmap(pcdev->vipmem_virbase);
-    release_mem_region(pcdev->vipmem_phybase,pcdev->vipmem_size);
 exit_reqmem_vip:
-    if(pcdev->aclk_cif)
-        pcdev->aclk_cif = NULL;
-    if(pcdev->hclk_cif)
-        pcdev->hclk_cif = NULL;
-    if(pcdev->cif_clk_in)
-        pcdev->cif_clk_in = NULL;
-    if(pcdev->cif_clk_out)
-        pcdev->cif_clk_out = NULL;
-
+    if (clk) {
+        if (clk->pd_cif)
+            clk_put(clk->pd_cif);
+        if (clk->aclk_cif)
+            clk_put(clk->aclk_cif);
+        if (clk->hclk_cif)
+            clk_put(clk->hclk_cif);
+        if (clk->cif_clk_in)
+            clk_put(clk->cif_clk_in);
+        if (clk->cif_clk_out)
+            clk_put(clk->cif_clk_out);
+    }
     kfree(pcdev);
 exit_alloc:
 
@@ -3689,15 +3294,17 @@ exit:
     return err;
 }
 
-static int __devexit rk_camera_remove(struct platform_device *pdev)
+static int __exit rk_camera_remove(struct platform_device *pdev)
 {
     struct rk_camera_dev *pcdev = platform_get_drvdata(pdev);
     struct resource *res;
     struct rk_camera_frmivalenum *fival_list,*fival_nxt;
-    struct rk29camera_mem_res *meminfo_ptr,*meminfo_ptrr;
     int i;
-    
-    free_irq(pcdev->irq, pcdev);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
+       
+    free_irq(pcdev->irqinfo.irq, pcdev);
 
        if (pcdev->camera_wq) {
                destroy_workqueue(pcdev->camera_wq);
@@ -3716,18 +3323,6 @@ static int __devexit rk_camera_remove(struct platform_device *pdev)
 
     soc_camera_host_unregister(&pcdev->soc_host);
 
-    meminfo_ptr = IS_CIF0()? (&pcdev->pdata->meminfo):(&pcdev->pdata->meminfo_cif1);
-    meminfo_ptrr = IS_CIF0()? (&pcdev->pdata->meminfo_cif1):(&pcdev->pdata->meminfo);
-    if (meminfo_ptr->vbase) {
-        if (meminfo_ptr->vbase == meminfo_ptrr->vbase) {
-            meminfo_ptr->vbase = NULL;
-        } else {
-            iounmap((void __iomem*)pcdev->vipmem_virbase);
-            release_mem_region(pcdev->vipmem_phybase, pcdev->vipmem_size);
-            meminfo_ptr->vbase = NULL;
-        }
-    }
-
     res = pcdev->res;
     iounmap((void __iomem*)pcdev->base);
     release_mem_region(res->start, res->end - res->start + 1);
@@ -3746,27 +3341,34 @@ static int __devexit rk_camera_remove(struct platform_device *pdev)
 static struct platform_driver rk_camera_driver =
 {
     .driver    = {
-        .name  = RK29_CAM_DRV_NAME,
+        .name  = RK29_CAM_DRV_NAME,       /*host */      
     },
     .probe             = rk_camera_probe,
-    .remove            = __devexit_p(rk_camera_remove),
+    .remove            = (rk_camera_remove),
 };
 
 static int rk_camera_init_async(void *unused)
 {
-    platform_driver_register(&rk_camera_driver);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+    platform_driver_register(&rk_camera_driver);       
     return 0;
 }
 
-static int __devinit rk_camera_init(void)
+static int __init rk_camera_init(void)
 {
-    RK30_CAM_DEBUG_TRACE("%s..%s..%d  \n",__FUNCTION__,__FILE__,__LINE__);
+
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
+
     kthread_run(rk_camera_init_async, NULL, "rk_camera_init");
+       
     return 0;
 }
 
 static void __exit rk_camera_exit(void)
 {
+       debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);
+
     platform_driver_unregister(&rk_camera_driver);
 }
 
@@ -3776,4 +3378,3 @@ module_exit(rk_camera_exit);
 MODULE_DESCRIPTION("RKSoc Camera Host driver");
 MODULE_AUTHOR("ddl <ddl@rock-chips>");
 MODULE_LICENSE("GPL");
-#endif
index 8d22522235c7e350067882e8c3e7fe5f0834e25e..d99c686e70f74a29cf15a963f3b7a3d91a8dc3d0 100755 (executable)
@@ -1,10 +1,12 @@
 config CAMSYS_DRV
        tristate "camsys driver "
-       default y
+       default n
        
 menu "RockChip camera system driver"
        depends on CAMSYS_DRV
        
+source "drivers/media/video/rk_camsys/ext_flashled_drv/Kconfig"
+       
 config CAMSYS_MRV
        tristate "camsys driver for marvin isp "
        default y
@@ -16,3 +18,4 @@ config CAMSYS_CIF
        ---help---
 
 endmenu          
+
index dfd880042164074a680a7c893dd0af45381d80f5..5704148ecc43a985edc0da943e4b7e1289043b9e 100755 (executable)
@@ -4,4 +4,5 @@
 obj-$(CONFIG_CAMSYS_DRV) += camsys_drv.o 
 obj-$(CONFIG_CAMSYS_MRV) += camsys_marvin.o camsys_mipicsi_phy.o camsys_soc_priv.o 
 obj-$(CONFIG_CAMSYS_CIF) += camsys_cif.o
+obj-y                                   += ext_flashled_drv/
 
index f0a088a69e1f71f7d82ace7196b6e7ed53cb2108..93bbab53a20011e989a12790983d6c61ec761b16 100755 (executable)
@@ -5,6 +5,7 @@
 #include "camsys_mipicsi_phy.h"
 #include "camsys_gpio.h"
 #include "camsys_soc_priv.h"
+#include "ext_flashled_drv/rk_ext_fshled_ctl.h"
 
 unsigned int camsys_debug=1;
 module_param(camsys_debug, int, S_IRUGO|S_IWUSR);
@@ -186,6 +187,18 @@ static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *cams
     
     extdev->dev_cfg = devio->dev_cfg;
     extdev->fl.fl.active = devio->fl.fl.active;
+    extdev->fl.ext_fsh_dev = NULL;
+    //should register external flash device ?
+    if(strlen(devio->fl.fl_drv_name) && (strcmp(devio->fl.fl_drv_name,"Internal") != 0)
+        && (strcmp(devio->fl.fl_drv_name,"NC") != 0)){
+        //register flash device
+        extdev->fl.ext_fsh_dev = camsys_register_ext_fsh_dev(&devio->fl);
+        if(extdev->fl.ext_fsh_dev == NULL){
+            camsys_err("register ext flash %s failed!",devio->fl.fl_drv_name);
+            err = -EINVAL;
+            goto fail;
+        }
+    }
     regulator_info = &devio->avdd;
     regulator = &extdev->avdd;
     for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
@@ -305,6 +318,9 @@ static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_de
             gpio++;
         }
 
+        if(extdev->fl.ext_fsh_dev != NULL){
+            camsys_deregister_ext_fsh_dev(extdev->fl.ext_fsh_dev);
+        }
         //spin_lock(&camsys_dev->lock);
         mutex_lock(&camsys_dev->extdevs.mut);
         list_del_init(&extdev->list);
@@ -340,6 +356,10 @@ static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_de
                     }
                     gpio++;
                 }
+
+                if(extdev->fl.ext_fsh_dev != NULL){
+                    camsys_deregister_ext_fsh_dev(extdev->fl.ext_fsh_dev);
+                }
                 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
                 list_del_init(&extdev->list);
                 list_del_init(&extdev->active);
@@ -387,7 +407,7 @@ static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
             } 
             case CamSys_Flash_Trigger:
             {
-                camsys_dev->flash_trigger_cb(camsys_dev, devctl->on);
+                camsys_dev->flash_trigger_cb(camsys_dev,devctl->rev[0], devctl->on);
                 break;
             }
             case CamSys_IOMMU:
@@ -423,6 +443,8 @@ static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
                             }
                         }
                     }
+                }else if(devctl->ops == CamSys_Flash_Trigger){
+                    err = camsys_ext_fsh_ctrl(extdev->fl.ext_fsh_dev,devctl->rev[0],devctl->on);
                 }
                 
             } else {
@@ -1184,7 +1206,7 @@ static int camsys_platform_probe(struct platform_device *pdev){
     list_add_tail(&camsys_dev->list, &camsys_devs.devs);
     spin_unlock(&camsys_devs.lock);
 
-    
+    camsys_init_ext_fsh_module();  
     camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
     return 0;
 request_mem_fail:
@@ -1259,6 +1281,8 @@ static int  camsys_platform_remove(struct platform_device *pdev)
         list_del_init(&camsys_dev->list);
         spin_unlock(&camsys_devs.lock);
 
+        camsys_deinit_ext_fsh_module();
+
         kfree(camsys_dev);
         camsys_dev=NULL;
     } else {
index 3c282ea3f53eb123e9740988240b034e43e4ae53..1c6d2e2a8f2d36da488225e765b21ccf866cfa9c 100755 (executable)
@@ -55,7 +55,11 @@ static inline unsigned int camsys_gpio_group(unsigned char *io_name)
         group = 5;      
     } else if (strstr(io_name,"PIN6")) {
         group = 6;      
-    } 
+    } else if (strstr(io_name,"PIN7")) {
+        group = 7;      
+    } else if (strstr(io_name,"PIN8")) {
+        group = 8;      
+    }  
 
     return group;
 }
index 45550564697973eafc743b83d13143119e503536..a4daf9829f8805a5055962a466da83dfd3c4aa79 100755 (executable)
                 1) enable or disable IOMMU just depending on CONFIG_ROCKCHIP_IOMMU. 
 *v0.0x17.0:
                 1) isp iommu status depend on vpu iommu status.
+*v0.0x18.0:
+         1) add flashlight RT8547 driver
+         2) support torch mode
+*v0.0x19.0:
+         1) set CONFIG_CAMSYS_DRV disable as default,enable in defconfig file if needed.
 */
-#define CAMSYS_DRIVER_VERSION                   KERNEL_VERSION(0,0x17,0)
+#define CAMSYS_DRIVER_VERSION                   KERNEL_VERSION(0,0x19,0)
 
 
 #define CAMSYS_PLATFORM_DRV_NAME                "RockChip-CamSys"
@@ -196,6 +201,9 @@ typedef struct camsys_gpio_s {
 } camsys_gpio_t;
 typedef struct camsys_flash_s {
     camsys_gpio_t        fl;
+    camsys_gpio_t        fl_en;
+    void*   ext_fsh_dev;            
+    //flash call back
 } camsys_flash_t;
 typedef struct camsys_extdev_s {
     unsigned char            dev_name[CAMSYS_NAME_LEN];
@@ -263,7 +271,7 @@ typedef struct camsys_dev_s {
     int (*phy_cb) (camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, void* ptr);
     int (*iomux)(camsys_extdev_t *extdev,void *ptr);
     int (*platform_remove)(struct platform_device *pdev);
-    int (*flash_trigger_cb)(void *ptr, unsigned int on);
+    int (*flash_trigger_cb)(void *ptr,int mode , unsigned int on);
     int (*iommu_cb)(void *ptr,camsys_sysctrl_t *devctl);
 } camsys_dev_t;
 
index c6a61d8b7317e048aa638fc52e55f08a34a4f932..a7544ca3080cf24b0c5d962d1bdef65d52694ffb 100755 (executable)
@@ -126,7 +126,7 @@ fail:
     return -1;
 }
 
-static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on)
+static int camsys_mrv_flash_trigger_cb(void *ptr,int mode,unsigned int on)
 {
     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
     struct device *dev = &(camsys_dev->pdev->dev);
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/Kconfig b/drivers/media/video/rk_camsys/ext_flashled_drv/Kconfig
new file mode 100755 (executable)
index 0000000..370ee54
--- /dev/null
@@ -0,0 +1,26 @@
+config FLASHLIGHT
+       bool "Flashlight Support"
+       default n
+       help
+         This option enables the led sysfs class in /sys/class/flashlight.
+
+config LEDS_RT8547
+       bool "LED Support for RT8547"
+       select RT_FLASH_LED
+       default n
+       help
+         This option enabled support for RT8547 LED drivers
+
+config LEDS_RT8547_DBG
+       bool "LED RT8547 Debug Info"
+       depends on LEDS_RT8547
+       default n
+       help
+         This option enabled RT8547 LED drivers debug option
+
+config RT_FLASH_LED
+       bool "Richtek flash LED driver support"
+       depends on FLASHLIGHT
+       default n
+       help
+         Say Y here to enable Richtek's flash LED driver HAL architecture
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/Makefile b/drivers/media/video/rk_camsys/ext_flashled_drv/Makefile
new file mode 100755 (executable)
index 0000000..c96b20e
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_FLASHLIGHT)               += flashlight.o rk_ext_fshled_ctl.o
+obj-$(CONFIG_RT_FLASH_LED)             += rtfled.o
+obj-$(CONFIG_LEDS_RT8547)              += leds-rt8547.o
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.c b/drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.c
new file mode 100755 (executable)
index 0000000..f63a65f
--- /dev/null
@@ -0,0 +1,544 @@
+/* drivers/leds/flashlight.c
+ * Flashlight Class Device Driver
+ *
+ * Copyright (C) 2013 Richtek Technology Corp.
+ * Author: Patrick Chang <patrick_chang@richtek.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; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include "flashlight.h"
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+static const char const *flashlight_type_string[] = {
+       [FLASHLIGHT_TYPE_XENON] = "Xenon",
+       [FLASHLIGHT_TYPE_LED] = "LED",
+       [FLASHLIFHT_TYPE_BULB] = "Bulb",
+};
+
+static const char const *flashlight_mode_string[] = {
+       [FLASHLIGHT_MODE_OFF] = "Off",
+       [FLASHLIGHT_MODE_TORCH] = "Torch",
+       [FLASHLIGHT_MODE_FLASH] = "Flash",
+       [FLASHLIGHT_MODE_MIXED] = "Mixed",
+};
+
+static ssize_t flashlight_show_name(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%s\n",
+                      flashlight_dev->props.alias_name ?
+                      flashlight_dev->props.alias_name : "anonymous");
+}
+
+static ssize_t flashlight_show_type(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%s\n",
+                      flashlight_type_string[flashlight_dev->props.type]);
+}
+
+static ssize_t flashlight_show_mode(struct device *dev,
+                                   struct device_attribute *attr, char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%s\n",
+                      flashlight_mode_string[flashlight_dev->props.mode]);
+}
+
+static ssize_t flashlight_show_torch_max_brightness(struct device *dev,
+                                                   struct device_attribute
+                                                   *attr, char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.torch_max_brightness);
+}
+
+static ssize_t flashlight_show_strobe_max_brightness(struct device *dev,
+                                                    struct device_attribute
+                                                    *attr, char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n",
+                      flashlight_dev->props.strobe_max_brightness);
+}
+
+static ssize_t flashlight_show_color_temperature(struct device *dev,
+                                                struct device_attribute *attr,
+                                                char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.color_temperature);
+}
+
+static ssize_t flashlight_show_strobe_delay(struct device *dev,
+                                           struct device_attribute *attr,
+                                           char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.strobe_delay);
+}
+
+static ssize_t flashlight_store_strobe_timeout(struct device *dev,
+                                              struct device_attribute *attr,
+                                              const char *buf, size_t count)
+{
+       int rc;
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+       long timeout;
+
+       rc = kstrtol(buf, 0, &timeout);
+       if (rc)
+               return rc;
+       rc = flashlight_dev->ops->set_strobe_timeout(flashlight_dev, timeout);
+       if (rc == 0)
+               rc = count;
+       return rc;
+}
+
+static ssize_t flashlight_show_strobe_timeout(struct device *dev,
+                                             struct device_attribute *attr,
+                                             char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.strobe_timeout);
+}
+
+static ssize_t flashlight_store_torch_brightness(struct device *dev,
+                                                struct device_attribute *attr,
+                                                const char *buf, size_t count)
+{
+       int rc;
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+       long brightness;
+
+       rc = kstrtol(buf, 0, &brightness);
+       if (rc)
+               return rc;
+
+       rc = -ENXIO;
+
+       mutex_lock(&flashlight_dev->ops_lock);
+       if (flashlight_dev->ops && flashlight_dev->ops->set_torch_brightness) {
+               if (brightness > flashlight_dev->props.torch_max_brightness)
+                       rc = -EINVAL;
+               else {
+                       pr_debug("flashlight: set torch brightness to %ld\n",
+                                brightness);
+                       flashlight_dev->props.torch_brightness = brightness;
+                       flashlight_dev->ops->
+                           set_torch_brightness(flashlight_dev, brightness);
+                       rc = count;
+               }
+       }
+       mutex_unlock(&flashlight_dev->ops_lock);
+
+       return rc;
+}
+
+static ssize_t flashlight_show_torch_brightness(struct device *dev,
+                                               struct device_attribute *attr,
+                                               char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.torch_brightness);
+}
+
+static ssize_t flashlight_store_strobe_brightness(struct device *dev,
+                                                 struct device_attribute *attr,
+                                                 const char *buf, size_t count)
+{
+       int rc;
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+       long brightness;
+
+       rc = kstrtol(buf, 0, &brightness);
+       if (rc)
+               return rc;
+
+       rc = -ENXIO;
+
+       mutex_lock(&flashlight_dev->ops_lock);
+       if (flashlight_dev->ops && flashlight_dev->ops->set_strobe_brightness) {
+               if (brightness > flashlight_dev->props.strobe_max_brightness)
+                       rc = -EINVAL;
+               else {
+                       pr_debug("flashlight: set strobe brightness to %ld\n",
+                                brightness);
+                       flashlight_dev->props.strobe_brightness = brightness;
+                       flashlight_dev->ops->
+                           set_strobe_brightness(flashlight_dev, brightness);
+                       rc = count;
+               }
+       }
+       mutex_unlock(&flashlight_dev->ops_lock);
+       return rc;
+}
+
+static ssize_t flashlight_show_strobe_brightness(struct device *dev,
+                                                struct device_attribute *attr,
+                                                char *buf)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       return sprintf(buf, "%d\n", flashlight_dev->props.strobe_brightness);
+}
+
+static struct class *flashlight_class;
+
+static int flashlight_suspend(struct device *dev, pm_message_t state)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       if (flashlight_dev->ops)
+               flashlight_dev->ops->suspend(flashlight_dev, state);
+       return 0;
+}
+
+static int flashlight_resume(struct device *dev)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       if (flashlight_dev->ops)
+               flashlight_dev->ops->resume(flashlight_dev);
+       return 0;
+}
+
+static void flashlight_device_release(struct device *dev)
+{
+       struct flashlight_device *flashlight_dev = to_flashlight_device(dev);
+
+       kfree(flashlight_dev);
+}
+
+static struct device_attribute flashlight_device_attributes[] = {
+       __ATTR(name, 0444, flashlight_show_name, NULL),
+       __ATTR(type, 0444, flashlight_show_type, NULL),
+       __ATTR(mode, 0444, flashlight_show_mode, NULL),
+       __ATTR(torch_max_brightness, 0444,
+              flashlight_show_torch_max_brightness, NULL),
+       __ATTR(strobe_max_brightness, 0444,
+              flashlight_show_strobe_max_brightness, NULL),
+       __ATTR(color_temperature, 0444,
+              flashlight_show_color_temperature, NULL),
+       __ATTR(strobe_delay, 0444,
+              flashlight_show_strobe_delay, NULL),
+       __ATTR(strobe_timeout, 0644,
+              flashlight_show_strobe_timeout,
+              flashlight_store_strobe_timeout),
+       __ATTR(torch_brightness, 0644,
+              flashlight_show_torch_brightness,
+              flashlight_store_torch_brightness),
+       __ATTR(strobe_brightness, 0644,
+              flashlight_show_strobe_brightness,
+              flashlight_store_strobe_brightness),
+       __ATTR_NULL,
+};
+
+/**
+ * flashlight_device_register - create and register a new object of
+ *   flashlight_device class.
+ * @name: the name of the new object(must be the same as the name of the
+ *   respective framebuffer device).
+ * @parent: a pointer to the parent device
+ * @devdata: an optional pointer to be stored for private driver use. The
+ *   methods may retrieve it by using bl_get_data(flashlight_dev).
+ * @ops: the flashlight operations structure.
+ *
+ * Creates and registers new flashlight device. Returns either an
+ * ERR_PTR() or a pointer to the newly allocated device.
+ */
+struct flashlight_device *flashlight_device_register(const char *name,
+                                                    struct device *parent,
+                                                    void *devdata,
+                                                    const struct flashlight_ops
+                                                    *ops,
+                                                    const struct
+                                                    flashlight_properties
+                                                    *props)
+{
+       struct flashlight_device *flashlight_dev;
+       int rc;
+
+       pr_debug("flashlight_device_register: name=%s\n", name);
+       flashlight_dev = kzalloc(sizeof(*flashlight_dev), GFP_KERNEL);
+       if (!flashlight_dev)
+               return ERR_PTR(-ENOMEM);
+
+       mutex_init(&flashlight_dev->ops_lock);
+       flashlight_dev->dev.class = flashlight_class;
+       flashlight_dev->dev.parent = parent;
+       flashlight_dev->dev.release = flashlight_device_release;
+       dev_set_name(&flashlight_dev->dev, name);
+       dev_set_drvdata(&flashlight_dev->dev, devdata);
+       /* Copy properties */
+       if (props) {
+               memcpy(&flashlight_dev->props, props,
+                      sizeof(struct flashlight_properties));
+       }
+       rc = device_register(&flashlight_dev->dev);
+       if (rc) {
+               kfree(flashlight_dev);
+               return ERR_PTR(rc);
+       }
+       flashlight_dev->ops = ops;
+       return flashlight_dev;
+}
+EXPORT_SYMBOL(flashlight_device_register);
+
+/**
+ * flashlight_device_unregister - unregisters a flashlight device object.
+ * @flashlight_dev: the flashlight device object to be unregistered and freed.
+ *
+ * Unregisters a previously registered via flashlight_device_register object.
+ */
+void flashlight_device_unregister(struct flashlight_device *flashlight_dev)
+{
+       if (!flashlight_dev)
+               return;
+
+       mutex_lock(&flashlight_dev->ops_lock);
+       flashlight_dev->ops = NULL;
+       mutex_unlock(&flashlight_dev->ops_lock);
+       device_unregister(&flashlight_dev->dev);
+}
+EXPORT_SYMBOL(flashlight_device_unregister);
+
+int flashlight_list_color_temperature(struct flashlight_device *flashlight_dev,
+                                     int selector)
+{
+       if (flashlight_dev->ops && flashlight_dev->ops->list_color_temperature)
+               return flashlight_dev->ops->
+                   list_color_temperature(flashlight_dev, selector);
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_list_color_temperature);
+
+int flashlight_set_color_temperature(struct flashlight_device *flashlight_dev,
+                                    int minK, int maxK)
+{
+       int selector = 0;
+       int rc;
+
+       if ((flashlight_dev->ops == NULL) ||
+           (flashlight_dev->ops->set_color_temperature == NULL))
+               return -EINVAL;
+       for (selector = 0;; selector++) {
+               rc = flashlight_list_color_temperature(flashlight_dev,
+                                                      selector);
+               if (rc < 0)
+                       return rc;
+               if (rc >= minK && rc <= maxK) {
+                       mutex_lock(&flashlight_dev->ops_lock);
+                       rc = flashlight_dev->ops->
+                           set_color_temperature(flashlight_dev, rc);
+                       mutex_unlock(&flashlight_dev->ops_lock);
+                       if (rc == 0)
+                               flashlight_dev->props.color_temperature = rc;
+                       return rc;
+               }
+
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_set_color_temperature);
+
+int flashlight_set_torch_brightness(struct flashlight_device *flashlight_dev,
+                                   int brightness_level)
+{
+       int rc;
+
+       if ((flashlight_dev->ops == NULL) ||
+           (flashlight_dev->ops->set_torch_brightness == NULL))
+               return -EINVAL;
+       if (brightness_level > flashlight_dev->props.torch_max_brightness)
+               return -EINVAL;
+       mutex_lock(&flashlight_dev->ops_lock);
+       rc = flashlight_dev->ops->set_torch_brightness(flashlight_dev,
+                                                      brightness_level);
+       mutex_unlock(&flashlight_dev->ops_lock);
+       if (rc < 0)
+               return rc;
+       flashlight_dev->props.torch_brightness = brightness_level;
+       return rc;
+
+}
+EXPORT_SYMBOL(flashlight_set_torch_brightness);
+
+int flashlight_set_strobe_brightness(struct flashlight_device *flashlight_dev,
+                                    int brightness_level)
+{
+       int rc;
+
+       if ((flashlight_dev->ops == NULL) ||
+           (flashlight_dev->ops->set_strobe_brightness == NULL))
+               return -EINVAL;
+       if (brightness_level > flashlight_dev->props.strobe_max_brightness)
+               return -EINVAL;
+       mutex_lock(&flashlight_dev->ops_lock);
+       rc = flashlight_dev->ops->set_strobe_brightness(flashlight_dev,
+                                                       brightness_level);
+       mutex_unlock(&flashlight_dev->ops_lock);
+       if (rc < 0)
+               return rc;
+       flashlight_dev->props.strobe_brightness = brightness_level;
+       return rc;
+}
+EXPORT_SYMBOL(flashlight_set_strobe_brightness);
+
+int flashlight_list_strobe_timeout(struct flashlight_device *flashlight_dev,
+                                  int selector)
+{
+       if (flashlight_dev->ops && flashlight_dev->ops->list_strobe_timeout) {
+               return flashlight_dev->ops->list_strobe_timeout(flashlight_dev,
+                                                               selector);
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_list_strobe_timeout);
+
+int flashlight_set_strobe_timeout(struct flashlight_device *flashlight_dev,
+                                 int min_ms, int max_ms)
+{
+       int selector = 0;
+       int rc = -EINVAL;
+       int timeout;
+
+       if ((flashlight_dev->ops == NULL) ||
+           (flashlight_dev->ops->set_strobe_timeout == NULL))
+               return -EINVAL;
+       for (selector = 0;; selector++) {
+               timeout =
+                   flashlight_list_strobe_timeout(flashlight_dev, selector);
+               if (timeout < 0)
+                       return timeout;
+               if (timeout >= min_ms && timeout <= max_ms) {
+                       mutex_lock(&flashlight_dev->ops_lock);
+                       rc = flashlight_dev->ops->
+                           set_strobe_timeout(flashlight_dev, timeout);
+                       mutex_unlock(&flashlight_dev->ops_lock);
+                       if (rc == 0)
+                               flashlight_dev->props.strobe_timeout = timeout;
+                       return rc;
+               }
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_set_strobe_timeout);
+
+int flashlight_set_mode(struct flashlight_device *flashlight_dev, int mode)
+{
+       int rc;
+
+       if (mode >= FLASHLIGHT_MODE_MAX || mode < 0)
+               return -EINVAL;
+       if ((flashlight_dev->ops == NULL) ||
+           (flashlight_dev->ops->set_mode == NULL)) {
+               flashlight_dev->props.mode = mode;
+               return 0;
+       }
+       mutex_lock(&flashlight_dev->ops_lock);
+       rc = flashlight_dev->ops->set_mode(flashlight_dev, mode);
+       mutex_unlock(&flashlight_dev->ops_lock);
+       if (rc < 0)
+               return rc;
+       flashlight_dev->props.mode = mode;
+       return rc;
+}
+EXPORT_SYMBOL(flashlight_set_mode);
+
+int flashlight_strobe(struct flashlight_device *flashlight_dev)
+{
+       if (flashlight_dev->props.mode == FLASHLIGHT_MODE_FLASH
+           || flashlight_dev->props.mode == FLASHLIGHT_MODE_MIXED) {
+               if (flashlight_dev->ops == NULL ||
+                   flashlight_dev->ops->strobe == NULL)
+                       return -EINVAL;
+               return flashlight_dev->ops->strobe(flashlight_dev);
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_strobe);
+
+static int flashlight_match_device_by_name(struct device *dev, const void *data)
+{
+       const char *name = data;
+
+       return strcmp(dev_name(dev), name) == 0;
+}
+
+struct flashlight_device *find_flashlight_by_name(char *name)
+{
+       struct device *dev;
+
+       if (!name)
+               return (struct flashlight_device *)NULL;
+       dev = class_find_device(flashlight_class, NULL, (void*)name,
+                               flashlight_match_device_by_name);
+
+       return dev ? to_flashlight_device(dev) : NULL;
+
+}
+EXPORT_SYMBOL(find_flashlight_by_name);
+
+int flashlight_strobe_charge(struct flashlight_device *flashlight_dev,
+                            flashlight_charge_event_cb cb, void *data,
+                            int start)
+{
+
+       if (flashlight_dev->ops->strobe_charge)
+               return flashlight_dev->ops->strobe_charge(flashlight_dev,
+                                                         cb, data, start);
+       if (flashlight_dev->props.type == FLASHLIGHT_TYPE_LED) {
+               if (cb)
+                       cb(data, 0);
+               return 0;
+       }
+       return -EINVAL;
+}
+EXPORT_SYMBOL(flashlight_strobe_charge);
+
+static void __exit flashlight_class_exit(void)
+{
+       class_destroy(flashlight_class);
+}
+
+static int __init flashlight_class_init(void)
+{
+       flashlight_class = class_create(THIS_MODULE, "flashlight");
+       if (IS_ERR(flashlight_class)) {
+               pr_err(
+                      "Unable to create flashlight class; errno = %ld\n",
+                      PTR_ERR(flashlight_class));
+               return PTR_ERR(flashlight_class);
+       }
+       flashlight_class->dev_attrs = flashlight_device_attributes;
+       flashlight_class->suspend = flashlight_suspend;
+       flashlight_class->resume = flashlight_resume;
+       return 0;
+}
+subsys_initcall(flashlight_class_init);
+module_exit(flashlight_class_exit);
+
+MODULE_DESCRIPTION("Flashlight Class Device");
+MODULE_AUTHOR("Patrick Chang <patrick_chang@richtek.com>");
+MODULE_VERSION("1.0.0_G");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.h b/drivers/media/video/rk_camsys/ext_flashled_drv/flashlight.h
new file mode 100755 (executable)
index 0000000..48b1ea2
--- /dev/null
@@ -0,0 +1,138 @@
+/* include/linux/leds/flashlight.h
+ * Header of Flashlight Class Device Driver
+ *
+ * Copyright (C) 2013 Richtek Technology Corp.
+ * Patrick Chang <patrick_chang@richtek.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 LINUX_LEDS_FLASHLIGHT_H
+#define LINUX_LEDS_FLASHLIGHT_H
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+typedef enum flashlight_type {
+       FLASHLIGHT_TYPE_XENON = 0,
+       FLASHLIGHT_TYPE_LED,
+       FLASHLIFHT_TYPE_BULB,
+       FLASHLIGHT_TYPE_MAX,
+} flashlight_type_t;
+typedef enum flashlight_mode {
+       FLASHLIGHT_MODE_OFF = 0,
+       FLASHLIGHT_MODE_TORCH,
+       FLASHLIGHT_MODE_FLASH,
+       /* MIXED mode means TORCH + FLASH */
+       FLASHLIGHT_MODE_MIXED,
+       FLASHLIGHT_MODE_MAX,
+} flashlight_mode_t;
+
+struct flashlight_device;
+
+typedef int (*flashlight_charge_event_cb) (void *data, int remains);
+
+struct flashlight_ops {
+       int (*set_torch_brightness)(struct flashlight_device *, int);
+       int (*set_strobe_brightness)(struct flashlight_device *, int);
+       int (*set_strobe_timeout)(struct flashlight_device *, int);
+       int (*list_strobe_timeout)(struct flashlight_device *, int);
+       int (*set_mode)(struct flashlight_device *, int);
+       int (*set_color_temperature)(struct flashlight_device *, int);
+       int (*list_color_temperature)(struct flashlight_device *, int);
+       int (*strobe_charge)(struct flashlight_device *,
+                             flashlight_charge_event_cb, void *, int);
+       int (*strobe)(struct flashlight_device *);
+       int (*suspend)(struct flashlight_device *, pm_message_t);
+       int (*resume)(struct flashlight_device *);
+};
+
+struct flashlight_properties {
+       /* Flashlight type */
+       enum flashlight_type type;
+       /* Xenon type flashlight doesn't support torch mode */
+       enum flashlight_mode mode;
+       /* Color temperature, unit: K, 0 means unknown */
+       int color_temperature;
+       int torch_brightness;
+       int torch_max_brightness;
+       int strobe_brightness;
+       int strobe_max_brightness;
+       int strobe_delay;
+       int strobe_timeout;
+       const char *alias_name;
+};
+
+struct flashlight_device {
+       /* Flashlight properties */
+       struct flashlight_properties props;
+       const struct flashlight_ops *ops;
+       struct mutex ops_lock;
+       struct device dev;
+};
+
+extern struct flashlight_device *flashlight_device_register(const char *name,
+                                                       struct device *parent,
+                                                       void *devdata,
+                                                       const struct
+                                                       flashlight_ops * ops,
+                                                       const struct
+                                                       flashlight_properties
+                                                       *props);
+extern void flashlight_device_unregister(struct flashlight_device
+                                        *flashlight_dev);
+extern struct flashlight_device *find_flashlight_by_name(char *name);
+extern int flashlight_list_color_temperature(struct flashlight_device
+                                            *flashlight_dev, int selector);
+extern int flashlight_set_color_temperature(struct flashlight_device
+                                           *flashlight_dev, int minK,
+                                           int maxK);
+extern int flashlight_set_torch_brightness(struct flashlight_device
+                                          *flashlight_dev,
+                                          int brightness_level);
+extern int flashlight_set_strobe_brightness(struct flashlight_device
+                                           *flashlight_dev,
+                                           int brightness_level);
+extern int flashlight_list_strobe_timeout(struct flashlight_device
+                                         *flashlight_dev, int selector);
+extern int flashlight_set_strobe_timeout(struct flashlight_device
+                                        *flashlight_dev, int min_ms,
+                                        int max_ms);
+extern int flashlight_set_mode(struct flashlight_device *flashlight_dev,
+                              int mode);
+
+extern int flashlight_strobe(struct flashlight_device *flashlight_dev);
+
+/* flashlight_charge_event_cb(void *data, int remains)
+ * description :
+ *   callback function of flashlight charging progress
+ * arguments :
+ *  @data : data pass by flashlight_strobe_charge()
+ *  @remains : remained time to full chargerd, unit : ms ; 0 means ready
+ * return : 0 means succeess, otherwise see definitions in errno.h
+ */
+
+/* flashlight_strobe_chargestruct flashlight_device *flashlight_dev,
+ *                      flashlight_charge_event_cb cb, void *data, int start)
+ * description :
+ * flashlight start / stop  charging
+ * @flashlight_dev : flashlight devices
+ * @flashlight_charge_event_cb : callback function to report progress
+ * @data : bypass to callback function
+ * @start : 1 means start; 0 means stop
+ */
+extern int flashlight_strobe_charge(struct flashlight_device *flashlight_dev,
+                                   flashlight_charge_event_cb cb, void *data,
+                                   int start);
+
+#define to_flashlight_device(obj) \
+       container_of(obj, struct flashlight_device, dev)
+
+static inline void *flashlight_get_data(struct flashlight_device
+                                       *flashlight_dev)
+{
+       return dev_get_drvdata(&flashlight_dev->dev);
+}
+#endif /*LINUX_LEDS_FLASHLIGHT_H */
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.c b/drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.c
new file mode 100755 (executable)
index 0000000..f4cdc7e
--- /dev/null
@@ -0,0 +1,881 @@
+/*
+ *  drivers/leds/leds-rt8547.c
+ *  Driver for Richtek RT8547 LED Flash IC
+ *
+ *  Copyright (C) 2014 Richtek Technology Corp.
+ *  cy_huang <cy_huang@richtek.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; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#endif /* #ifdef CONFIG_OF */
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#endif /* #ifdef CONFIG_DEBUG_FS */
+
+#include "rtfled.h"
+#include "leds-rt8547.h"
+
+struct rt8547_chip {
+       rt_fled_info_t base;
+       struct device *dev;
+       struct rt8547_platform_data *pdata;
+       spinlock_t io_lock;
+       unsigned char suspend:1;
+       int in_use_mode;
+#ifdef CONFIG_DEBUG_FS
+       struct flashlight_device *fled_dev;
+       unsigned char reg_addr;
+       unsigned char reg_data;
+#endif                         /* #ifdef CONFIG_DEBUG_FS */
+};
+
+#ifdef CONFIG_DEBUG_FS
+struct rt_debug_st {
+       void *info;
+       int id;
+};
+
+enum {
+       RT8547_DBG_REG,
+       RT8547_DBG_DATA,
+       RT8547_DBG_REGS,
+       RT8547_DBG_FLED,
+       RT8547_DBG_MAX
+};
+
+static struct dentry *debugfs_rt_dent;
+static struct dentry *debugfs_file[RT8547_DBG_MAX];
+static struct rt_debug_st rtdbg_data[RT8547_DBG_MAX];
+#endif /* #ifdef CONFIG_DEBUG_FS */
+
+static unsigned char rt8547_reg_initval[] = {
+       0x06,                   /* REG 0x01 */
+       0x12,                   /* REG 0x02 */
+       0x02,                   /* REG 0x03 */
+       0x0F,                   /* REG 0x04 */
+};
+
+static inline int rt8547_send_bit(struct rt8547_platform_data *pdata,
+                                 unsigned char bit)
+{
+       if (bit) {
+               gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
+               udelay(RT8547_SHORT_DELAY);
+               gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
+               udelay(RT8547_LONG_DELAY);
+       } else {
+               gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
+               udelay(RT8547_LONG_DELAY);
+               gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
+               udelay(RT8547_SHORT_DELAY);
+       }
+       return 0;
+}
+
+static inline int rt8547_send_byte(struct rt8547_platform_data *pdata,
+                                  unsigned char byte)
+{
+       int i;
+
+       /*Send order is high bit to low bit */
+       for (i = 7; i >= 0; i--)
+               rt8547_send_bit(pdata, byte & (0x1 << i));
+       return 0;
+}
+
+static inline int rt8547_send_special_byte(struct rt8547_platform_data *pdata,
+                                          unsigned char byte)
+{
+       int i;
+
+       /*Only send three bit for register address */
+       for (i = 2; i >= 0; i--)
+               rt8547_send_bit(pdata, byte & (0x1 << i));
+       return 0;
+}
+
+static inline int rt8547_start_xfer(struct rt8547_platform_data *pdata)
+{
+       gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
+       udelay(RT8547_START_DELAY);
+       return 0;
+}
+
+static inline int rt8547_stop_xfer(struct rt8547_platform_data *pdata)
+{
+       /*Redundant one bit as the stop condition */
+       rt8547_send_bit(pdata, 1);
+       return 0;
+}
+
+static int rt8547_send_data(struct rt8547_chip *chip, unsigned char reg,
+                           unsigned char data)
+{
+       struct rt8547_platform_data *pdata = chip->pdata;
+       unsigned long flags;
+       unsigned char xfer_data[3];     /*0: adddr, 1: reg, 2: reg data*/
+
+       xfer_data[0] = RT8547_ONEWIRE_ADDR;
+       xfer_data[1] = reg;
+       xfer_data[2] = data;
+       RT_DBG("rt8547-> 0: 0x%02x, 1: 0x%02x, 2: 0x%02x\n", xfer_data[0],
+              xfer_data[1], xfer_data[2]);
+       spin_lock_irqsave(&chip->io_lock, flags);
+       rt8547_start_xfer(pdata);
+       rt8547_send_byte(pdata, xfer_data[0]);
+       rt8547_send_special_byte(pdata, xfer_data[1]);
+       rt8547_send_byte(pdata, xfer_data[2]);
+       rt8547_stop_xfer(pdata);
+       spin_unlock_irqrestore(&chip->io_lock, flags);
+       /*write back to reg array*/
+       rt8547_reg_initval[reg - 1] = data;
+       return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int reg_debug_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static int get_parameters(char *buf, long int *param1, int num_of_par)
+{
+       char *token;
+       int base, cnt;
+
+       token = strsep(&buf, " ");
+
+       for (cnt = 0; cnt < num_of_par; cnt++) {
+               if (token != NULL) {
+                       if ((token[1] == 'x') || (token[1] == 'X'))
+                               base = 16;
+                       else
+                               base = 10;
+
+                       if (kstrtoul(token, base, &param1[cnt]) != 0)
+                               return -EINVAL;
+
+                       token = strsep(&buf, " ");
+               } else
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static ssize_t reg_debug_read(struct file *filp, char __user *ubuf,
+                             size_t count, loff_t *ppos)
+{
+       struct rt_debug_st *st = filp->private_data;
+       struct rt8547_chip *di = st->info;
+       char lbuf[1000];
+       int i = 0, j = 0;
+
+       lbuf[0] = '\0';
+       switch (st->id) {
+       case RT8547_DBG_REG:
+               snprintf(lbuf, sizeof(lbuf), "0x%x\n", di->reg_addr);
+               break;
+       case RT8547_DBG_DATA:
+               di->reg_data = rt8547_reg_initval[di->reg_addr - 1];
+               snprintf(lbuf, sizeof(lbuf), "0x%x\n", di->reg_data);
+               break;
+       case RT8547_DBG_REGS:
+               for (i = RT8547_FLED_REG0; i < RT8547_FLED_REGMAX; i++)
+                       j += snprintf(lbuf + j, 20, "0x%02x:%02x\n", i,
+                                     rt8547_reg_initval[i - 1]);
+               break;
+       case RT8547_DBG_FLED:
+               snprintf(lbuf, sizeof(lbuf), "%d\n", di->in_use_mode);
+               break;
+       default:
+               return -EINVAL;
+
+       }
+       return simple_read_from_buffer(ubuf, count, ppos, lbuf, strlen(lbuf));
+}
+
+static ssize_t reg_debug_write(struct file *filp,
+                              const char __user *ubuf, size_t cnt,
+                              loff_t *ppos)
+{
+       struct rt_debug_st *st = filp->private_data;
+       struct rt8547_chip *di = st->info;
+       char lbuf[32];
+       int rc;
+       long int param[5];
+
+       if (cnt > sizeof(lbuf) - 1)
+               return -EINVAL;
+
+       rc = copy_from_user(lbuf, ubuf, cnt);
+       if (rc)
+               return -EFAULT;
+
+       lbuf[cnt] = '\0';
+
+       switch (st->id) {
+       case RT8547_DBG_REG:
+               rc = get_parameters(lbuf, param, 1);
+               if ((param[0] < RT8547_FLED_REGMAX) && (rc == 0)) {
+                       if ((param[0] >= RT8547_FLED_REG0
+                            && param[0] <= RT8547_FLED_REG3))
+                               di->reg_addr = (unsigned char)param[0];
+                       else
+                               rc = -EINVAL;
+               } else
+                       rc = -EINVAL;
+               break;
+       case RT8547_DBG_DATA:
+               rc = get_parameters(lbuf, param, 1);
+               if ((param[0] <= 0xff) && (rc == 0)) {
+                       rt8547_send_data(di, di->reg_addr,
+                                        (unsigned char)param[0]);
+               } else
+                       rc = -EINVAL;
+               break;
+       case RT8547_DBG_FLED:
+               if (!di->fled_dev)
+                       di->fled_dev = find_flashlight_by_name("rt-flash-led");
+               rc = get_parameters(lbuf, param, 1);
+               if ((param[0] <= FLASHLIGHT_MODE_FLASH) && (rc == 0)
+                   && di->fled_dev) {
+                       switch (param[0]) {
+                       case FLASHLIGHT_MODE_TORCH:
+                               flashlight_set_torch_brightness(di->fled_dev,
+                                                               2);
+                               flashlight_set_mode(di->fled_dev,
+                                                   FLASHLIGHT_MODE_TORCH);
+                               break;
+                       case FLASHLIGHT_MODE_FLASH:
+                               flashlight_set_strobe_timeout(di->fled_dev,
+                                                             256, 256);
+                               flashlight_set_strobe_brightness(di->fled_dev,
+                                                                18);
+                               flashlight_set_mode(di->fled_dev,
+                                                   FLASHLIGHT_MODE_FLASH);
+                               flashlight_strobe(di->fled_dev);
+                               break;
+                       case FLASHLIGHT_MODE_OFF:
+                               flashlight_set_mode(di->fled_dev,
+                                                   FLASHLIGHT_MODE_OFF);
+                               break;
+                       }
+               } else
+                       rc = -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+       if (rc == 0)
+               rc = cnt;
+       return rc;
+}
+
+static const struct file_operations reg_debug_ops = {
+       .open = reg_debug_open,
+       .write = reg_debug_write,
+       .read = reg_debug_read
+};
+
+static void rt8547_create_debugfs(struct rt8547_chip *chip)
+{
+       RT_DBG("add debugfs for RT8547\n");
+       debugfs_rt_dent = debugfs_create_dir("rt8547_dbg", 0);
+       if (!IS_ERR(debugfs_rt_dent)) {
+               rtdbg_data[0].info = chip;
+               rtdbg_data[0].id = RT8547_DBG_REG;
+               debugfs_file[0] = debugfs_create_file("reg",
+                                                     S_IFREG | S_IRUGO,
+                                                     debugfs_rt_dent,
+                                                     (void *)&rtdbg_data[0],
+                                                     &reg_debug_ops);
+
+               rtdbg_data[1].info = chip;
+               rtdbg_data[1].id = RT8547_DBG_DATA;
+               debugfs_file[1] = debugfs_create_file("data",
+                                                     S_IFREG | S_IRUGO,
+                                                     debugfs_rt_dent,
+                                                     (void *)&rtdbg_data[1],
+                                                     &reg_debug_ops);
+
+               rtdbg_data[2].info = chip;
+               rtdbg_data[2].id = RT8547_DBG_REGS;
+               debugfs_file[2] = debugfs_create_file("regs",
+                                                     S_IFREG | S_IRUGO,
+                                                     debugfs_rt_dent,
+                                                     (void *)&rtdbg_data[2],
+                                                     &reg_debug_ops);
+
+               rtdbg_data[3].info = chip;
+               rtdbg_data[3].id = RT8547_DBG_FLED;
+               debugfs_file[3] = debugfs_create_file("fled",
+                                                     S_IFREG | S_IRUGO,
+                                                     debugfs_rt_dent,
+                                                     (void *)&rtdbg_data[3],
+                                                     &reg_debug_ops);
+       } else {
+               dev_err(chip->dev, "create debugfs failed\n");
+       }
+}
+
+static void rt8547_remove_debugfs(void)
+{
+       if (!IS_ERR(debugfs_rt_dent))
+               debugfs_remove_recursive(debugfs_rt_dent);
+}
+#endif /* #ifdef CONFIG_DEBUG_FS */
+
+static inline void rt8547_fled_power_on(struct rt8547_platform_data *pdata)
+{
+    if (gpio_is_valid(pdata->flset_gpio))
+       gpio_set_value(pdata->flset_gpio, ((pdata->flset_active) & 0x1));
+}
+
+static inline void rt8547_fled_power_off(struct rt8547_platform_data *pdata)
+{
+    if (gpio_is_valid(pdata->flset_gpio))
+       gpio_set_value(pdata->flset_gpio, (~(pdata->flset_active) & 0x1));
+       udelay(RT8547_STOP_DELAY);
+}
+
+static inline void rt8547_fled_ctrl_en(struct rt8547_platform_data *pdata,
+                                      int en)
+{
+    if (gpio_is_valid(pdata->ctl_gpio)){
+       if (en)
+               gpio_set_value(pdata->ctl_gpio, ((pdata->ctl_active) & 0x1));
+       else
+               gpio_set_value(pdata->ctl_gpio, (~(pdata->ctl_active) & 0x1));
+       }
+       RT_DBG("en %d\n", en);
+}
+
+static inline void rt8547_fled_flash_en(struct rt8547_platform_data *pdata,
+                                       int en)
+{
+    if (gpio_is_valid(pdata->flen_gpio)){
+       if (en)
+               gpio_set_value(pdata->flen_gpio, ((pdata->flen_active) & 0x1));
+       else
+               gpio_set_value(pdata->flen_gpio, (~(pdata->flen_active) & 0x1));
+       }
+       RT_DBG("en %d\n", en);
+}
+
+static int rt8547_fled_init(struct rt_fled_info *info)
+{
+       RT_DBG("\n");
+       return 0;
+}
+
+static int rt8547_fled_resume(struct rt_fled_info *info)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+
+       RT_DBG("\n");
+       fi->suspend = 0;
+       return 0;
+}
+
+static int rt8547_fled_suspend(struct rt_fled_info *info, pm_message_t state)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+
+       RT_DBG("\n");
+       fi->suspend = 1;
+       return 0;
+}
+
+static int rt8547_fled_set_mode(struct rt_fled_info *info,
+                               flashlight_mode_t mode)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+       int ret = 0;
+
+       RT_DBG("mode=%d\n", mode);
+       switch (mode) {
+       case FLASHLIGHT_MODE_TORCH:
+               if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
+                       rt8547_fled_power_on(fi->pdata);
+               tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
+               tmp |= RT8547_MODESEL_MASK;
+               rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
+               rt8547_fled_ctrl_en(fi->pdata, 1);
+               rt8547_fled_flash_en(fi->pdata, 1);
+               fi->in_use_mode = mode;
+               break;
+       case FLASHLIGHT_MODE_FLASH:
+               if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
+                       rt8547_fled_power_on(fi->pdata);
+               tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
+               tmp &= ~RT8547_MODESEL_MASK;
+               rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
+               fi->in_use_mode = mode;
+               break;
+       case FLASHLIGHT_MODE_OFF:
+               rt8547_fled_flash_en(fi->pdata, 0);
+               rt8547_fled_ctrl_en(fi->pdata, 0);
+               if (fi->in_use_mode != FLASHLIGHT_MODE_OFF)
+                       rt8547_fled_power_off(fi->pdata);
+               fi->in_use_mode = mode;
+               break;
+       case FLASHLIGHT_MODE_MIXED:
+       default:
+               ret = -EINVAL;
+       }
+       return 0;
+}
+
+static int rt8547_fled_get_mode(struct rt_fled_info *info)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+
+       RT_DBG("\n");
+       return fi->in_use_mode;
+}
+
+static int rt8547_fled_strobe(struct rt_fled_info *info)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+
+       RT_DBG("\n");
+       rt8547_fled_flash_en(fi->pdata, 0);
+       rt8547_fled_ctrl_en(fi->pdata, 0);
+       rt8547_fled_ctrl_en(fi->pdata, 1);
+       rt8547_fled_flash_en(fi->pdata, 1);
+       return 0;
+}
+
+static int rt8547_fled_torch_current_list(struct rt_fled_info *info,
+                                         int selector)
+{
+       RT_DBG("selector=%d\n", selector);
+       return 25000 + selector * 25000;        /* unit: uA */
+}
+
+static int rt8547_fled_strobe_current_list(struct rt_fled_info *info,
+                                          int selector)
+{
+       RT_DBG("selector=%d\n", selector);
+       return 100000 + selector * 50000;       /* unit: uA */
+}
+
+static int rt8547_fled_timeout_level_list(struct rt_fled_info *info,
+                                         int selector)
+{
+       RT_DBG("selector=%d\n", selector);
+       return 100000 + selector * 50000;       /* unit: uA */
+}
+
+static int rt8547_fled_lv_protection_list(struct rt_fled_info *info,
+                                         int selector)
+{
+       RT_DBG("selector=%d\n", selector);
+       return 3000 + selector * 100;   /* unit: mV */
+}
+
+static int rt8547_fled_strobe_timeout_list(struct rt_fled_info *info,
+                                          int selector)
+{
+       RT_DBG("selector=%d\n", selector);
+       return 64 + selector * 32;      /* unit: mS */
+}
+
+static int rt8547_fled_set_torch_current_sel(struct rt_fled_info *info,
+                                            int selector)
+{
+
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+
+       RT_DBG("selector=%d\n", selector);
+       tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
+       tmp &= ~RT8547_TCLEVEL_MASK;
+       tmp |= selector;
+       rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
+       return 0;
+}
+
+static int rt8547_fled_set_strobe_current_sel(struct rt_fled_info *info,
+                                             int selector)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+
+       RT_DBG("selector=%d\n", selector);
+       tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
+       tmp &= ~RT8547_SCLEVEL_MASK;
+       tmp |= selector;
+       rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
+       return 0;
+}
+
+static int rt8547_fled_set_timeout_level_sel(struct rt_fled_info *info,
+                                            int selector)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+
+       RT_DBG("selector=%d\n", selector);
+       if (selector > RT8547_TOL_MAX)
+               return -EINVAL;
+       tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
+       tmp &= ~RT8547_TOCLEVEL_MASK;
+       tmp |= (selector << RT8547_TOCLEVEL_SHFT);
+       rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
+       return 0;
+}
+
+static int rt8547_fled_set_lv_protection_sel(struct rt_fled_info *info,
+                                            int selector)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+
+       RT_DBG("selector=%d\n", selector);
+       if (selector > RT8547_LVP_MAX)
+               return -EINVAL;
+       tmp = rt8547_reg_initval[RT8547_FLED_REG0 - 1];
+       tmp &= ~RT8547_LVP_MASK;
+       tmp |= selector;
+       rt8547_send_data(fi, RT8547_FLED_REG0, tmp);
+       return 0;
+}
+
+static int rt8547_fled_set_strobe_timeout_sel(struct rt_fled_info *info,
+                                             int selector)
+{
+       struct rt8547_chip *fi = (struct rt8547_chip *)info;
+       unsigned char tmp = 0;
+
+       RT_DBG("selector=%d\n", selector);
+       if (selector > RT8547_STO_MAX)
+               return -EINVAL;
+       tmp = rt8547_reg_initval[RT8547_FLED_REG3 - 1];
+       tmp &= ~RT8547_STO_MASK;
+       tmp |= selector;
+       rt8547_send_data(fi, RT8547_FLED_REG3, tmp);
+       return 0;
+}
+
+static int rt8547_fled_get_torch_current_sel(struct rt_fled_info *info)
+{
+       int selector =
+           rt8547_reg_initval[RT8547_FLED_REG2 - 1] & RT8547_TCLEVEL_MASK;
+
+       return selector;
+}
+
+static int rt8547_fled_get_strobe_current_sel(struct rt_fled_info *info)
+{
+       int selector =
+           rt8547_reg_initval[RT8547_FLED_REG1 - 1] & RT8547_SCLEVEL_MASK;
+
+       return selector;
+}
+
+static int rt8547_fled_get_timeout_level_sel(struct rt_fled_info *info)
+{
+       int selector =
+           rt8547_reg_initval[RT8547_FLED_REG1 - 1] & RT8547_TOCLEVEL_MASK;
+
+       selector >>= RT8547_TOCLEVEL_SHFT;
+       return selector;
+}
+
+static int rt8547_fled_get_lv_protection_sel(struct rt_fled_info *info)
+{
+       int selector =
+           rt8547_reg_initval[RT8547_FLED_REG0 - 1] & RT8547_LVP_MASK;
+
+       return selector;
+}
+
+static int rt8547_fled_get_strobe_timeout_sel(struct rt_fled_info *info)
+{
+       int selector =
+           rt8547_reg_initval[RT8547_FLED_REG3 - 1] & RT8547_STO_MASK;
+
+       return selector;
+}
+
+static struct rt_fled_hal rt8547_fled_hal = {
+       .fled_init = rt8547_fled_init,
+       .fled_suspend = rt8547_fled_suspend,
+       .fled_resume = rt8547_fled_resume,
+       .fled_set_mode = rt8547_fled_set_mode,
+       .fled_get_mode = rt8547_fled_get_mode,
+       .fled_strobe = rt8547_fled_strobe,
+       .fled_torch_current_list = rt8547_fled_torch_current_list,
+       .fled_strobe_current_list = rt8547_fled_strobe_current_list,
+       .fled_timeout_level_list = rt8547_fled_timeout_level_list,
+       .fled_lv_protection_list = rt8547_fled_lv_protection_list,
+       .fled_strobe_timeout_list = rt8547_fled_strobe_timeout_list,
+       /* method to set */
+       .fled_set_torch_current_sel = rt8547_fled_set_torch_current_sel,
+       .fled_set_strobe_current_sel = rt8547_fled_set_strobe_current_sel,
+       .fled_set_timeout_level_sel = rt8547_fled_set_timeout_level_sel,
+       .fled_set_lv_protection_sel = rt8547_fled_set_lv_protection_sel,
+       .fled_set_strobe_timeout_sel = rt8547_fled_set_strobe_timeout_sel,
+       /* method to get */
+       .fled_get_torch_current_sel = rt8547_fled_get_torch_current_sel,
+       .fled_get_strobe_current_sel = rt8547_fled_get_strobe_current_sel,
+       .fled_get_timeout_level_sel = rt8547_fled_get_timeout_level_sel,
+       .fled_get_lv_protection_sel = rt8547_fled_get_lv_protection_sel,
+       .fled_get_strobe_timeout_sel = rt8547_fled_get_strobe_timeout_sel,
+};
+
+static struct flashlight_properties rt8547_fled_props = {
+       .type = FLASHLIGHT_TYPE_LED,
+       .torch_brightness = 2,
+       .torch_max_brightness = 15,
+       .strobe_brightness = 18,
+       .strobe_max_brightness = 30,
+       .strobe_delay = 2,
+       .strobe_timeout = 544,
+       .alias_name = "rt8547-fled",
+};
+
+static void rt8547_parse_dt(struct rt8547_platform_data *pdata,
+                           struct device *dev)
+{
+#ifdef CONFIG_OF
+       struct device_node *np = dev->of_node;
+       u32 tmp;
+
+       if (of_property_read_u32(np, "rt,def_lvp", &tmp) < 0) {
+               dev_warn(dev, "use 3V as the default lvp\n");
+       } else {
+               if (tmp > RT8547_LVP_MAX)
+                       tmp = RT8547_LVP_MAX;
+               rt8547_reg_initval[RT8547_FLED_REG0 - 1] &= ~RT8547_LVP_MASK;
+               rt8547_reg_initval[RT8547_FLED_REG0 - 1] |= tmp;
+       }
+
+       if (of_property_read_u32(np, "rt,def_tol", &tmp) < 0) {
+               dev_warn(dev, "use 100mA as the default timeout level\n");
+       } else {
+               if (tmp > RT8547_TOL_MAX)
+                       tmp = RT8547_TOL_MAX;
+               tmp <<= RT8547_TOCLEVEL_SHFT;
+               rt8547_reg_initval[RT8547_FLED_REG1 - 1] &=
+                   ~RT8547_TOCLEVEL_MASK;
+               rt8547_reg_initval[RT8547_FLED_REG1 - 1] |= tmp;
+       }
+       pdata->flen_gpio = of_get_named_gpio(np, "rt,flen_gpio", 0);
+       pdata->ctl_gpio = of_get_named_gpio(np, "rt,ctl_gpio", 0);
+       pdata->flset_gpio = of_get_named_gpio(np, "rt,flset_gpio", 0);
+#endif /* #ifdef CONFIG_OF */
+}
+
+static void rt8547_parse_pdata(struct rt8547_platform_data *pdata,
+                              struct device *dev)
+{
+       u32 tmp;
+
+       tmp = pdata->def_lvp;
+       rt8547_reg_initval[RT8547_FLED_REG0 - 1] &= ~RT8547_LVP_MASK;
+       rt8547_reg_initval[RT8547_FLED_REG0 - 1] |= tmp;
+
+       tmp = pdata->def_tol;
+       tmp <<= RT8547_TOCLEVEL_SHFT;
+       rt8547_reg_initval[RT8547_FLED_REG1 - 1] &= ~RT8547_TOCLEVEL_MASK;
+       rt8547_reg_initval[RT8547_FLED_REG1 - 1] |= tmp;
+}
+
+static int rt8547_io_init(struct rt8547_platform_data *pdata,
+                         struct device *dev)
+{
+       int rc = 0;
+
+       if (gpio_is_valid(pdata->flen_gpio)) {
+               rc = gpio_request_one(pdata->flen_gpio, ((~(pdata->flen_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
+                                     "rt8547_flen");
+               if (rc < 0) {
+                       dev_err(dev, "request rt8547 flash en pin fail\n");
+                       goto gpio_request1;
+               }
+
+       }
+
+       if(gpio_is_valid(pdata->ctl_gpio)){
+               rc = gpio_request_one(pdata->ctl_gpio, ((~(pdata->ctl_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
+                                     "rt8547_ctl");
+               if (rc < 0) {
+                       dev_err(dev, "request rt8547 ctl pin fail\n");
+                       goto gpio_request2;
+               }
+       }
+
+       if(gpio_is_valid(pdata->flset_gpio)){
+               rc = gpio_request_one(pdata->flset_gpio, ((~(pdata->flset_active) & 0x1) ? GPIOF_OUT_INIT_HIGH:GPIOF_OUT_INIT_LOW),
+                                     "rt8547_flset");
+               if (rc < 0) {
+                       dev_err(dev, "request rt8547 flash set pin fail\n");
+                       goto gpio_request3;
+               }
+       }
+       return 0;
+gpio_request3:
+    if(gpio_is_valid(pdata->ctl_gpio))
+       gpio_free(pdata->ctl_gpio);
+gpio_request2:
+    if (gpio_is_valid(pdata->flen_gpio))
+       gpio_free(pdata->flen_gpio);
+gpio_request1:
+       return rc;
+
+}
+
+static int rt8547_io_deinit(struct rt8547_platform_data *pdata)
+{
+    if (gpio_is_valid(pdata->flen_gpio)){
+       gpio_direction_input(pdata->flen_gpio);
+       gpio_free(pdata->flen_gpio);
+       }
+    if(gpio_is_valid(pdata->ctl_gpio)){
+       gpio_direction_input(pdata->ctl_gpio);
+       gpio_free(pdata->ctl_gpio);
+       }
+       if(gpio_is_valid(pdata->flset_gpio)){
+       gpio_direction_input(pdata->flset_gpio);
+       gpio_free(pdata->flset_gpio);
+       }
+       return 0;
+}
+
+static void rt8547_reg_init(struct rt8547_chip *chip)
+{
+       RT_DBG("\n");
+       rt8547_send_data(chip, RT8547_FLED_REG0,
+                        rt8547_reg_initval[RT8547_FLED_REG0 - 1]);
+       rt8547_send_data(chip, RT8547_FLED_REG1,
+                        rt8547_reg_initval[RT8547_FLED_REG1 - 1]);
+       rt8547_send_data(chip, RT8547_FLED_REG2,
+                        rt8547_reg_initval[RT8547_FLED_REG2 - 1]);
+       rt8547_send_data(chip, RT8547_FLED_REG3,
+                        rt8547_reg_initval[RT8547_FLED_REG3 - 1]);
+}
+
+static struct platform_device rt_fled_pdev = {
+       .name = "rt-flash-led",
+       .id = -1,
+};
+
+static int rt8547_led_probe(struct platform_device *pdev)
+{
+       struct rt8547_platform_data *pdata = pdev->dev.platform_data;
+       struct rt8547_chip *chip;
+       bool use_dt = pdev->dev.of_node;
+       int ret = 0;
+
+       chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+       if (use_dt) {
+               pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       goto err_probe;
+               rt8547_parse_dt(pdata, &pdev->dev);
+       } else {
+               if (!pdata)
+                       goto err_probe;
+               rt8547_parse_pdata(pdata, &pdev->dev);
+       }
+
+       ret = rt8547_io_init(pdata, &pdev->dev);
+       if (ret < 0)
+               goto err_io;
+
+       chip->dev = &pdev->dev;
+       chip->pdata = pdata;
+       spin_lock_init(&chip->io_lock);
+       chip->in_use_mode = FLASHLIGHT_MODE_OFF;
+       platform_set_drvdata(pdev, chip);
+
+       rt8547_fled_power_on(pdata);
+       rt8547_reg_init(chip);
+       rt8547_fled_power_off(pdata);
+
+       chip->base.hal = &rt8547_fled_hal;
+       chip->base.init_props = &rt8547_fled_props;
+       rt_fled_pdev.dev.parent = &pdev->dev;
+       ret = platform_device_register(&rt_fled_pdev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "register rtfled fail\n");
+               goto err_io;
+       }
+#ifdef CONFIG_DEBUG_FS
+       rt8547_create_debugfs(chip);
+#endif /* #ifdef CONFIG_DEBUG_FS */
+       dev_info(&pdev->dev, "driver successfully registered\n");
+       return 0;
+err_io:
+       if (use_dt)
+               devm_kfree(&pdev->dev, pdata);
+err_probe:
+       devm_kfree(&pdev->dev, chip);
+       return ret;
+}
+
+static int rt8547_led_remove(struct platform_device *pdev)
+{
+       struct rt8547_chip *chip = platform_get_drvdata(pdev);
+
+#ifdef CONFIG_DEBUG_FS
+       rt8547_remove_debugfs();
+#endif /* #ifdef CONFIG_DEBUG_FS */
+       platform_device_unregister(&rt_fled_pdev);
+       rt8547_io_deinit(chip->pdata);
+       return 0;
+}
+
+static const struct of_device_id rt_match_table[] = {
+       {.compatible = "rt,rt8547",},
+       {},
+};
+
+static struct platform_driver rt8547_led_driver = {
+       .driver = {
+                  .name = "rt8547",
+                  .owner = THIS_MODULE,
+                  .of_match_table = rt_match_table,
+                  },
+       .probe = rt8547_led_probe,
+       .remove = rt8547_led_remove,
+};
+
+static int rt8547_led_init(void)
+{
+       return platform_driver_register(&rt8547_led_driver);
+}
+
+module_init(rt8547_led_init);
+
+static void rt8547_led_exit(void)
+{
+       platform_driver_unregister(&rt8547_led_driver);
+}
+
+module_exit(rt8547_led_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
+MODULE_DESCRIPTION("LED Flash Driver for RT8547");
+MODULE_VERSION(RT8547_DRV_VER);
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.h b/drivers/media/video/rk_camsys/ext_flashled_drv/leds-rt8547.h
new file mode 100755 (executable)
index 0000000..a1a7a8e
--- /dev/null
@@ -0,0 +1,84 @@
+/* include/linux/leds-rt8547.h
+ * Include file of driver to Richtek RT8547 LED Flash IC
+ *
+ * Copyright (C) 2014 Richtek Technology Corporation
+ * Author: CY_Huang <cy_huang@richtek.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 __LINUX_LEDS_RT8547_H
+#define __LINUX_LEDS_RT8547_H
+
+#define RT8547_DRV_VER "1.0.2_G"
+
+enum {
+       RT8547_FLED_REG0 = 0x01,
+       RT8547_FLED_REG1,
+       RT8547_FLED_REG2,
+       RT8547_FLED_REG3,
+       RT8547_FLED_REGMAX,
+};
+
+enum {
+       RT8547_LVP_3V,
+       RT8547_LVP_3P1V,
+       RT8547_LVP_3P2V,
+       RT8547_LVP_3P3V,
+       RT8547_LVP_3P4V,
+       RT8547_LVP_3P5V,
+       RT8547_LVP_3P6V,
+       RT8547_LVP_3P7V,
+       RT8547_LVP_3P8V,
+       RT8547_LVP_MAX = RT8547_LVP_3P8V,
+};
+
+enum {
+       RT8547_TOL_100mA,
+       RT8547_TOL_150mA,
+       RT8547_TOL_200mA,
+       RT8547_TOL_250mA,
+       RT8547_TOL_300mA,
+       RT8547_TOL_350mA,
+       RT8547_TOL_400mA,
+       RT8547_TOL_MAX = RT8547_TOL_400mA,
+};
+
+#define RT8547_STO_MAX 36
+
+#define RT8547_LVP_MASK 0x0F
+#define RT8547_TOCLEVEL_MASK 0xE0
+#define RT8547_TOCLEVEL_SHFT 5
+#define RT8547_SCLEVEL_MASK 0x1F
+#define RT8547_SWRST_MASK 0x20
+#define RT8547_MODESEL_MASK 0x10
+#define RT8547_TCLEVEL_MASK 0x0F
+#define RT8547_STO_MASK 0x3F
+
+struct rt8547_platform_data {
+       int flen_gpio;
+       int flen_active;
+       int ctl_gpio;
+       int ctl_active;
+       int flset_gpio;
+       int flset_active;
+       unsigned char def_lvp:4;
+       unsigned char def_tol:3;
+};
+
+/* one wire protocol parameter */
+#define RT8547_ONEWIRE_ADDR 0x99
+#define RT8547_LONG_DELAY 9
+#define RT8547_SHORT_DELAY 4
+#define RT8547_START_DELAY 10
+#define RT8547_STOP_DELAY 1500
+
+#ifdef CONFIG_LEDS_RT8547_DBG
+#define RT_DBG(fmt, args...) pr_info("%s: " fmt, __func__, ##args)
+#else
+#define RT_DBG(fmt, args...)
+#endif /* #ifdef CONFIG_LEDS_RT8547_DBG */
+
+#endif /* #ifndef __LINUX_LEDS_RT8547_H */
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.c b/drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.c
new file mode 100755 (executable)
index 0000000..8d11019
--- /dev/null
@@ -0,0 +1,168 @@
+#include "rk_ext_fshled_ctl.h"
+#include "../camsys_gpio.h"
+#include "flashlight.h"
+#include "leds-rt8547.h"
+
+typedef struct ext_fsh_info_s{
+    struct      platform_device pdev;
+    char*       dev_model;    
+    struct      list_head         list;
+}ext_fsh_info_t;
+
+struct ext_fsh_dev_list_s{
+    struct list_head         dev_list;
+};
+
+static struct ext_fsh_dev_list_s g_ext_fsh_devs;
+
+int camsys_init_ext_fsh_module()
+{
+    camsys_trace(1,"init external flash module");
+    INIT_LIST_HEAD(&g_ext_fsh_devs.dev_list);
+    return 0;
+}
+
+int camsys_deinit_ext_fsh_module()
+{
+    ext_fsh_info_t* cur_fsh_info = NULL;
+    camsys_trace(1,"deinit external flash module");
+    if (!list_empty(&g_ext_fsh_devs.dev_list)) {
+        list_for_each_entry(cur_fsh_info, &g_ext_fsh_devs.dev_list, list) {
+            if (cur_fsh_info) {
+               platform_device_unregister(&cur_fsh_info->pdev);
+               list_del_init(&cur_fsh_info->list);
+               /* free after unregister device ?*/
+               kfree(cur_fsh_info->pdev.dev.platform_data);
+               kfree(cur_fsh_info);
+               cur_fsh_info = NULL;
+            }
+        }
+    }
+    
+    INIT_LIST_HEAD(&g_ext_fsh_devs.dev_list);
+    return 0;
+}
+void* camsys_register_ext_fsh_dev(camsys_flash_info_t *fsh_info)
+{
+    ext_fsh_info_t* new_dev = NULL;
+    if(strcmp(fsh_info->fl_drv_name,"rt8547") == 0){
+        struct rt8547_platform_data* new_rt_dev = NULL;
+        new_dev = kzalloc(sizeof(ext_fsh_info_t),GFP_KERNEL);
+        if(!new_dev){
+            camsys_err("register new ext flash dev erro !");
+            goto fail0;
+        }
+        
+        new_rt_dev = kzalloc(sizeof(ext_fsh_info_t),GFP_KERNEL);
+        if(!new_rt_dev){
+            camsys_err("register new ext flash dev erro !");
+            goto fail1;
+        }
+
+        new_dev->pdev.id = -1;
+        new_dev->pdev.name = fsh_info->fl_drv_name;
+        new_dev->pdev.dev.platform_data = (void*)new_rt_dev;
+        new_dev->dev_model = "rt-flash-led";
+
+        new_rt_dev->flen_gpio = camsys_gpio_get(fsh_info->fl_en.name);
+        new_rt_dev->flen_active = fsh_info->fl_en.active;
+        camsys_trace(1,"flen name :%s,gpio %d,active %d \n",fsh_info->fl_en.name,new_rt_dev->flen_gpio,new_rt_dev->flen_active);
+        new_rt_dev->flset_gpio = camsys_gpio_get(fsh_info->fl.name );
+        new_rt_dev->flset_active = fsh_info->fl.active;
+        camsys_trace(1,"flset name :%s, gpio %d, active %d \n",fsh_info->fl.name,new_rt_dev->flset_gpio,new_rt_dev->flset_active);
+        new_rt_dev->ctl_gpio   = -1;
+        new_rt_dev->def_lvp = RT8547_LVP_3V;
+           new_rt_dev->def_tol = RT8547_TOL_100mA;
+
+    //    new_rt_dev->def_lvp = RT8547_LVP_MAX;
+       //    new_rt_dev->def_tol = RT8547_TOL_MAX;
+
+       if(platform_device_register(&new_dev->pdev) < 0){
+               camsys_err("register rtfled fail\n");
+               kfree(new_rt_dev);
+               goto fail1;
+       }
+
+        list_add_tail(&new_dev->list, &g_ext_fsh_devs.dev_list);
+        camsys_trace(1,"register new rt led dev success !");
+    }
+    
+    return (void*)new_dev;
+fail1:
+    if(new_dev)
+        kfree(new_dev);
+fail0:
+    return NULL;
+}
+
+int camsys_deregister_ext_fsh_dev(void* dev)
+{
+    ext_fsh_info_t* cur_fsh_info = NULL;
+    if (!list_empty(&g_ext_fsh_devs.dev_list)) {
+        list_for_each_entry(cur_fsh_info, &g_ext_fsh_devs.dev_list, list) {
+            if (dev == cur_fsh_info) {
+                camsys_trace(1,"unregister  ext flsh dev !");
+               platform_device_unregister(&cur_fsh_info->pdev);
+               list_del_init(&cur_fsh_info->list);
+               /* free after unregister device ?*/
+               kfree(cur_fsh_info->pdev.dev.platform_data);
+               kfree(cur_fsh_info);
+            }
+        }
+    }
+    return 0;
+}
+
+/*******************************
+mode:
+    0:  CAM_ENGINE_FLASH_OFF = 0x00,
+    1:  CAM_ENGINE_FLASH_AUTO = 0x01,
+    2:  CAM_ENGINE_FLASH_ON = 0x02,
+    3:  CAM_ENGINE_FLASH_RED_EYE = 0x03,
+    5:  CAM_ENGINE_FLASH_TORCH = 0x05
+********************************/
+int camsys_ext_fsh_ctrl(void* dev,int mode,unsigned int on)
+{
+    ext_fsh_info_t* cur_fsh_info = NULL;
+    struct flashlight_device *fled_dev = NULL;
+    if (!list_empty(&g_ext_fsh_devs.dev_list)) {
+        list_for_each_entry(cur_fsh_info, &g_ext_fsh_devs.dev_list, list) {
+            if (dev == cur_fsh_info) {
+            break;
+            }
+        }
+    }
+    if(cur_fsh_info == NULL){
+               camsys_err("this flash dev have not been registered !");
+        return -1;
+    }
+
+    fled_dev = find_flashlight_by_name(cur_fsh_info->dev_model);
+    switch(mode){
+        case 0: /* off */
+           /* set flashlight mode to Off */
+            flashlight_set_mode(fled_dev, FLASHLIGHT_MODE_OFF);
+            break;
+        case 2: /* flash on */
+           /* set strobe timeout to 256ms */
+           //flashlight_set_strobe_timeout(fled_dev, 256, 256);
+           flashlight_set_strobe_timeout(fled_dev, 512, 512);
+           /* set strobe brightness to to index 18 (1A), refer to the datasheet for the others */
+           flashlight_set_strobe_brightness(fled_dev, 18);
+           /* set flashlight mode to Strobe */
+           flashlight_set_mode(fled_dev, FLASHLIGHT_MODE_FLASH);
+           flashlight_strobe(fled_dev);
+            break;
+        case 5: /* torch */
+            /* set the torch brightness index 2 (75mA), refer to the datasheet for index current value. */
+            flashlight_set_torch_brightness(fled_dev, 2);
+            /* set flashlight mode to Torch */
+            flashlight_set_mode(fled_dev, FLASHLIGHT_MODE_TORCH);
+            break;
+        default:
+               camsys_err("not support this mode %d !",mode);
+    }
+
+    return 0;
+}
+
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.h b/drivers/media/video/rk_camsys/ext_flashled_drv/rk_ext_fshled_ctl.h
new file mode 100755 (executable)
index 0000000..d66af0d
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __RK_EXT_FSHLED_H__
+#define __RK_EXT_FSHLED_H__
+#include "../camsys_internal.h"
+//register flash dev
+extern int camsys_init_ext_fsh_module(void);
+extern int camsys_deinit_ext_fsh_module(void);
+extern void* camsys_register_ext_fsh_dev(camsys_flash_info_t *fsh_info);
+extern int camsys_deregister_ext_fsh_dev(void* dev);
+extern int camsys_ext_fsh_ctrl(void* dev,int mode,unsigned int on);
+#endif
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.c b/drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.c
new file mode 100755 (executable)
index 0000000..8417431
--- /dev/null
@@ -0,0 +1,401 @@
+/* drivers/leds/rtfled.c
+ * Richtek Flash LED Universal Architecture
+ *
+ * Copyright (C) 2013 Richtek Technology Corp.
+ * Author: Patrick Chang <patrick_chang@richtek.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; either version 2
+ * of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "rtfled.h"
+#include <linux/init.h>
+#include <linux/version.h>
+
+#define RTFLED_INFO(format, args...) \
+       pr_info("%s:%s() line-%d: " format, \
+         ALIAS_NAME, __func__, __LINE__, ## args)
+#define RTFLED_WARN(format, args...) \
+       pr_warn("%s:%s() line-%d: " format, \
+         ALIAS_NAME, __func__, __LINE__, ## args)
+#define RTFLED_ERR(format, args...) \
+       pr_err("%s:%s() line-%d: " format, \
+         ALIAS_NAME, __func__, __LINE__, ## args)
+
+#define RT_FLED_DEVICE  "rt-flash-led"
+#define ALIAS_NAME RT_FLED_DEVICE
+
+rt_fled_info_t *rt_fled_get_info_by_name(char *name)
+{
+       struct flashlight_device *flashlight_dev;
+
+       flashlight_dev = find_flashlight_by_name(name ? name : RT_FLED_DEVICE);
+       if (flashlight_dev == NULL)
+               return (rt_fled_info_t *) NULL;
+       return flashlight_get_data(flashlight_dev);
+}
+EXPORT_SYMBOL(rt_fled_get_info_by_name);
+
+static int rtfled_set_torch_brightness(struct flashlight_device *flashlight_dev,
+                                      int brightness_sel)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       return info->hal->fled_set_torch_current_sel(info, brightness_sel);
+}
+
+static int rtfled_set_strobe_brightness(struct flashlight_device
+                                       *flashlight_dev, int brightness_sel)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       return info->hal->fled_set_strobe_current_sel(info, brightness_sel);
+}
+
+static int rtfled_set_strobe_timeout(struct flashlight_device *flashlight_dev,
+                                    int timeout)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       int sel;
+
+       return info->hal->fled_set_strobe_timeout(info, timeout, timeout, &sel);
+}
+
+static int rtfled_list_strobe_timeout(struct flashlight_device *flashlight_dev,
+                                     int selector)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       return info->hal->fled_strobe_timeout_list(info, selector);
+}
+
+static int rtfled_set_mode(struct flashlight_device *flashlight_dev, int mode)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       return info->hal->fled_set_mode(info, mode);
+}
+
+static int rtfled_strobe(struct flashlight_device *flashlight_dev)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       return info->hal->fled_strobe(info);
+}
+
+static int rtfled_set_color_temperature(struct flashlight_device
+                                       *flashlight_dev, int color_temp)
+{
+       /* Doesn't support color temperature */
+       return -EINVAL;
+}
+
+static int rtfled_list_color_temperature(struct flashlight_device
+                                        *flashlight_dev, int selector)
+{
+       /* Doesn't support color temperature */
+       return -EINVAL;
+}
+
+static int rtfled_suspend(struct flashlight_device *flashlight_dev,
+                         pm_message_t state)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       if (info->hal->fled_suspend)
+               return info->hal->fled_suspend(info, state);
+       return 0;
+}
+
+static int rtfled_resume(struct flashlight_device *flashlight_dev)
+{
+       rt_fled_info_t *info = flashlight_get_data(flashlight_dev);
+
+       if (info->hal->fled_resume)
+               return info->hal->fled_resume(info);
+       return 0;
+}
+
+static struct flashlight_ops rtfled_impl_ops = {
+       .set_torch_brightness = rtfled_set_torch_brightness,
+       .set_strobe_brightness = rtfled_set_strobe_brightness,
+       .set_strobe_timeout = rtfled_set_strobe_timeout,
+       .list_strobe_timeout = rtfled_list_strobe_timeout,
+       .set_mode = rtfled_set_mode,
+       .strobe = rtfled_strobe,
+       .set_color_temperature = rtfled_set_color_temperature,
+       .list_color_temperature = rtfled_list_color_temperature,
+       .suspend = rtfled_suspend,
+       .resume = rtfled_resume,
+};
+
+static void rfled_shutdown(struct platform_device *pdev)
+{
+       struct rt_fled_info *info = platform_get_drvdata(pdev);
+
+       if (info->hal->fled_shutdown)
+               info->hal->fled_shutdown(info);
+}
+
+static int rtled_impl_set_torch_current(struct rt_fled_info *info,
+                                       int min_uA, int max_uA, int *selector)
+{
+       int sel = 0;
+       int rc;
+
+       for (sel = 0;; sel++) {
+               rc = info->hal->fled_torch_current_list(info, sel);
+               if (rc < 0)
+                       return rc;
+               if (rc >= min_uA && rc <= max_uA) {
+                       *selector = sel;
+                       return info->hal->fled_set_torch_current_sel(info, sel);
+               }
+       }
+       return -EINVAL;
+}
+
+static int rtled_impl_set_strobe_current(struct rt_fled_info *info,
+                                        int min_uA, int max_uA, int *selector)
+{
+       int sel = 0;
+       int rc;
+
+       for (sel = 0;; sel++) {
+               rc = info->hal->fled_strobe_current_list(info, sel);
+               if (rc < 0)
+                       return rc;
+               if (rc >= min_uA && rc <= max_uA) {
+                       *selector = sel;
+                       return info->hal->fled_set_strobe_current_sel(info,
+                                                                     sel);
+               }
+       }
+       return -EINVAL;
+}
+
+static int rtled_impl_set_timeout_level(struct rt_fled_info *info,
+                                       int min_uA, int max_uA, int *selector)
+{
+       int sel = 0;
+       int rc;
+
+       for (sel = 0;; sel++) {
+               rc = info->hal->fled_timeout_level_list(info, sel);
+               if (rc < 0)
+                       return rc;
+               if (rc >= min_uA && rc <= max_uA) {
+                       *selector = sel;
+                       return info->hal->fled_set_timeout_level_sel(info, sel);
+               }
+       }
+       return -EINVAL;
+}
+
+static int rtled_impl_set_lv_protection(struct rt_fled_info *info,
+                                       int min_mV, int max_mV, int *selector)
+{
+       int sel = 0;
+       int rc;
+
+       for (sel = 0;; sel++) {
+               rc = info->hal->fled_lv_protection_list(info, sel);
+               if (rc < 0)
+                       return rc;
+               if (rc >= min_mV && rc <= max_mV) {
+                       *selector = sel;
+                       return info->hal->fled_set_lv_protection_sel(info, sel);
+               }
+       }
+       return -EINVAL;
+}
+
+static int rtled_impl_set_strobe_timeout(struct rt_fled_info *info,
+                                        int min_ms, int max_ms, int *selector)
+{
+       int sel = 0;
+       int rc;
+
+       for (sel = 0;; sel++) {
+               rc = info->hal->fled_strobe_timeout_list(info, sel);
+               if (rc < 0)
+                       return rc;
+               if (rc >= min_ms && rc <= max_ms) {
+                       *selector = sel;
+                       return info->hal->fled_set_strobe_timeout_sel(info,
+                                                                     sel);
+               }
+       }
+       return -EINVAL;
+}
+
+static int rtled_impl_get_torch_current(struct rt_fled_info *info)
+{
+       int sel = info->hal->fled_get_torch_current_sel(info);
+
+       if (sel < 0)
+               return sel;
+       return info->hal->fled_torch_current_list(info, sel);
+}
+
+static int rtled_impl_get_strobe_current(struct rt_fled_info *info)
+{
+       int sel = info->hal->fled_get_strobe_current_sel(info);
+
+       if (sel < 0)
+               return sel;
+       return info->hal->fled_strobe_current_list(info, sel);
+}
+
+static int rtled_impl_get_timeout_level(struct rt_fled_info *info)
+{
+       int sel = info->hal->fled_get_timeout_level_sel(info);
+
+       if (sel < 0)
+               return sel;
+       return info->hal->fled_timeout_level_list(info, sel);
+}
+
+static int rtled_impl_get_lv_protection(struct rt_fled_info *info)
+{
+       int sel = info->hal->fled_get_lv_protection_sel(info);
+
+       if (sel < 0)
+               return sel;
+       return info->hal->fled_lv_protection_list(info, sel);
+}
+
+static int rtled_impl_get_strobe_timeout(struct rt_fled_info *info)
+{
+       int sel = info->hal->fled_get_strobe_timeout_sel(info);
+
+       if (sel < 0)
+               return sel;
+       return info->hal->fled_strobe_timeout_list(info, sel);
+}
+
+#define HAL_NOT_IMPLEMENTED(x) (hal->x == NULL)
+#define CHECK_HAL_IMPLEMENTED(x)       \
+       do {                            \
+               if (hal->x == NULL)     \
+                       return -EINVAL; \
+       } while (0)
+
+static int rtfled_check_hal_implement(struct rt_fled_hal *hal)
+{
+       if (HAL_NOT_IMPLEMENTED(fled_set_torch_current))
+               hal->fled_set_torch_current = rtled_impl_set_torch_current;
+       if (HAL_NOT_IMPLEMENTED(fled_set_strobe_current))
+               hal->fled_set_strobe_current = rtled_impl_set_strobe_current;
+       if (HAL_NOT_IMPLEMENTED(fled_set_timeout_level))
+               hal->fled_set_timeout_level = rtled_impl_set_timeout_level;
+       if (HAL_NOT_IMPLEMENTED(fled_set_lv_protection))
+               hal->fled_set_lv_protection = rtled_impl_set_lv_protection;
+       if (HAL_NOT_IMPLEMENTED(fled_set_strobe_timeout))
+               hal->fled_set_strobe_timeout = rtled_impl_set_strobe_timeout;
+       if (HAL_NOT_IMPLEMENTED(fled_get_torch_current))
+               hal->fled_get_torch_current = rtled_impl_get_torch_current;
+       if (HAL_NOT_IMPLEMENTED(fled_get_strobe_current))
+               hal->fled_get_strobe_current = rtled_impl_get_strobe_current;
+       if (HAL_NOT_IMPLEMENTED(fled_get_timeout_level))
+               hal->fled_get_timeout_level = rtled_impl_get_timeout_level;
+       if (HAL_NOT_IMPLEMENTED(fled_get_lv_protection))
+               hal->fled_get_lv_protection = rtled_impl_get_lv_protection;
+       if (HAL_NOT_IMPLEMENTED(fled_get_strobe_timeout))
+               hal->fled_get_strobe_timeout = rtled_impl_get_strobe_timeout;
+       CHECK_HAL_IMPLEMENTED(fled_set_mode);
+       CHECK_HAL_IMPLEMENTED(fled_get_mode);
+       CHECK_HAL_IMPLEMENTED(fled_strobe);
+       CHECK_HAL_IMPLEMENTED(fled_torch_current_list);
+       CHECK_HAL_IMPLEMENTED(fled_strobe_current_list);
+       CHECK_HAL_IMPLEMENTED(fled_timeout_level_list);
+       CHECK_HAL_IMPLEMENTED(fled_lv_protection_list);
+       CHECK_HAL_IMPLEMENTED(fled_strobe_timeout_list);
+       CHECK_HAL_IMPLEMENTED(fled_set_torch_current_sel);
+       CHECK_HAL_IMPLEMENTED(fled_set_strobe_current_sel);
+       CHECK_HAL_IMPLEMENTED(fled_set_timeout_level_sel);
+       CHECK_HAL_IMPLEMENTED(fled_set_lv_protection_sel);
+       CHECK_HAL_IMPLEMENTED(fled_set_strobe_timeout_sel);
+       CHECK_HAL_IMPLEMENTED(fled_get_torch_current_sel);
+       CHECK_HAL_IMPLEMENTED(fled_get_strobe_current_sel);
+       CHECK_HAL_IMPLEMENTED(fled_get_timeout_level_sel);
+       CHECK_HAL_IMPLEMENTED(fled_get_lv_protection_sel);
+       CHECK_HAL_IMPLEMENTED(fled_get_strobe_timeout_sel);
+       return 0;
+}
+
+static int rtfled_probe(struct platform_device *pdev)
+{
+       rt_fled_info_t *info = dev_get_drvdata(pdev->dev.parent);
+       int rc;
+
+       BUG_ON(info == NULL);
+       BUG_ON(info->hal == NULL);
+
+       RTFLED_INFO("Richtek FlashLED Driver is probing\n");
+       rc = rtfled_check_hal_implement(info->hal);
+       if (rc < 0) {
+               RTFLED_ERR("HAL implemented uncompletedly\n");
+               goto err_check_hal;
+       }
+       platform_set_drvdata(pdev, info);
+       info->flashlight_dev =
+           flashlight_device_register(info->name ? info->name : RT_FLED_DEVICE,
+                                      &pdev->dev, info, &rtfled_impl_ops,
+                                      info->init_props);
+       if (info->hal->fled_init) {
+               rc = info->hal->fled_init(info);
+               if (rc < 0) {
+                       RTFLED_ERR("Initialization failed\n");
+                       goto err_init;
+               }
+       }
+       RTFLED_INFO("Richtek FlashLED Driver initialized successfully\n");
+       return 0;
+err_init:
+       flashlight_device_unregister(info->flashlight_dev);
+err_check_hal:
+       return rc;
+}
+
+static int rtfled_remove(struct platform_device *pdev)
+{
+       rt_fled_info_t *info = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       flashlight_device_unregister(info->flashlight_dev);
+       return 0;
+}
+
+static struct platform_driver rt_flash_led_driver = {
+       .driver = {
+                  .name = RT_FLED_DEVICE,
+                  .owner = THIS_MODULE,
+                  },
+       .shutdown = rfled_shutdown,
+       .probe = rtfled_probe,
+       .remove = rtfled_remove,
+};
+
+static int rtfled_init(void)
+{
+       return platform_driver_register(&rt_flash_led_driver);
+}
+subsys_initcall(rtfled_init);
+
+static void rtfled_exit(void)
+{
+       platform_driver_unregister(&rt_flash_led_driver);
+}
+module_exit(rtfled_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick Chang <patrick_chang@richtek.com");
+MODULE_VERSION("1.0.0_G");
+MODULE_DESCRIPTION("Richtek Flash LED Driver");
diff --git a/drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.h b/drivers/media/video/rk_camsys/ext_flashled_drv/rtfled.h
new file mode 100755 (executable)
index 0000000..0f8815e
--- /dev/null
@@ -0,0 +1,147 @@
+/*include/linux/leds/rtfled.h
+ *Header of Richtek Flash LED Driver
+ *
+ *Copyright (C) 2013 Richtek Technology Corp.
+ *Author: Patrick Chang <patrick_chang@richtek.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; either version 2
+ *of the License, or (at your option) any later version.
+ */
+
+#ifndef LINUX_LEDS_RTFLED_H
+#define LINUX_LEDS_RTFLED_H
+#include "flashlight.h"
+
+struct rt_fled_info;
+typedef int (*rt_hal_fled_init) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_suspend) (struct rt_fled_info *info,
+                                   pm_message_t state);
+typedef int (*rt_hal_fled_resume) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_set_mode) (struct rt_fled_info *info,
+                                    flashlight_mode_t mode);
+typedef int (*rt_hal_fled_get_mode) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_strobe) (struct rt_fled_info *info);
+
+/*
+ *Return value : -EINVAL => selector parameter is out of range,
+ *otherwise current in uA
+ */
+typedef int (*rt_hal_fled_torch_current_list) (struct rt_fled_info *info,
+                                              int selector);
+typedef int (*rt_hal_fled_strobe_current_list) (struct rt_fled_info *info,
+                                               int selector);
+typedef int (*rt_hal_fled_timeout_level_list) (struct rt_fled_info *info,
+                                              int selector);
+/*
+ *Return value : -EINVAL => selector parameter is out of range,
+ *otherwise voltage in mV
+ */
+typedef int (*rt_hal_fled_lv_protection_list) (struct rt_fled_info *info,
+                                              int selector);
+/*
+ *Return value : -EINVAL => selector parameter is out of range,
+ *otherwise time in ms
+ */
+typedef int (*rt_hal_fled_strobe_timeout_list) (struct rt_fled_info *info,
+                                               int selector);
+typedef int (*rt_hal_fled_set_torch_current) (struct rt_fled_info *info,
+                                             int min_uA, int max_uA,
+                                             int *selector);
+typedef int (*rt_hal_fled_set_strobe_current) (struct rt_fled_info *info,
+                                              int min_uA, int max_uA,
+                                              int *selector);
+typedef int (*rt_hal_fled_set_timeout_level) (struct rt_fled_info *info,
+                                             int min_uA, int max_uA,
+                                             int *selector);
+typedef int (*rt_hal_fled_set_lv_protection) (struct rt_fled_info *info,
+                                             int min_mV, int max_mV,
+                                             int *selector);
+typedef int (*rt_hal_fled_set_strobe_timeout) (struct rt_fled_info *info,
+                                              int min_ms, int max_ms,
+                                              int *selector);
+typedef int (*rt_hal_fled_set_torch_current_sel) (struct rt_fled_info *info,
+                                                 int selector);
+typedef int (*rt_hal_fled_set_strobe_current_sel) (struct rt_fled_info *info,
+                                                  int selector);
+typedef int (*rt_hal_fled_set_timeout_level_sel) (struct rt_fled_info *info,
+                                                 int selector);
+typedef int (*rt_hal_fled_set_lv_protection_sel) (struct rt_fled_info *info,
+                                                 int selector);
+typedef int (*rt_hal_fled_set_strobe_timeout_sel) (struct rt_fled_info *info,
+                                                  int selector);
+typedef int (*rt_hal_fled_get_torch_current_sel) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_strobe_current_sel) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_timeout_level_sel) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_lv_protection_sel) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_strobe_timeout_sel) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_torch_current) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_strobe_current) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_timeout_level) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_lv_protection) (struct rt_fled_info *info);
+typedef int (*rt_hal_fled_get_strobe_timeout) (struct rt_fled_info *info);
+typedef void (*rt_hal_fled_shutdown) (struct rt_fled_info *info);
+
+struct rt_fled_hal {
+       rt_hal_fled_init fled_init;
+       rt_hal_fled_suspend fled_suspend;
+       rt_hal_fled_resume fled_resume;
+       rt_hal_fled_set_mode fled_set_mode;
+       rt_hal_fled_get_mode fled_get_mode;
+       rt_hal_fled_strobe fled_strobe;
+       rt_hal_fled_torch_current_list fled_torch_current_list;
+       rt_hal_fled_strobe_current_list fled_strobe_current_list;
+       rt_hal_fled_timeout_level_list fled_timeout_level_list;
+       rt_hal_fled_lv_protection_list fled_lv_protection_list;
+       rt_hal_fled_strobe_timeout_list fled_strobe_timeout_list;
+       /*method to set */
+       rt_hal_fled_set_torch_current_sel fled_set_torch_current_sel;
+       rt_hal_fled_set_strobe_current_sel fled_set_strobe_current_sel;
+       rt_hal_fled_set_timeout_level_sel fled_set_timeout_level_sel;
+       rt_hal_fled_set_lv_protection_sel fled_set_lv_protection_sel;
+       rt_hal_fled_set_strobe_timeout_sel fled_set_strobe_timeout_sel;
+       /*method to set, optional */
+       rt_hal_fled_set_torch_current fled_set_torch_current;
+       rt_hal_fled_set_strobe_current fled_set_strobe_current;
+       rt_hal_fled_set_timeout_level fled_set_timeout_level;
+       rt_hal_fled_set_lv_protection fled_set_lv_protection;
+       rt_hal_fled_set_strobe_timeout fled_set_strobe_timeout;
+       /*method to get */
+       rt_hal_fled_get_torch_current_sel fled_get_torch_current_sel;
+       rt_hal_fled_get_strobe_current_sel fled_get_strobe_current_sel;
+       rt_hal_fled_get_timeout_level_sel fled_get_timeout_level_sel;
+       rt_hal_fled_get_lv_protection_sel fled_get_lv_protection_sel;
+       rt_hal_fled_get_strobe_timeout_sel fled_get_strobe_timeout_sel;
+       /*method to get, optional */
+       rt_hal_fled_get_torch_current fled_get_torch_current;
+       rt_hal_fled_get_strobe_current fled_get_strobe_current;
+       rt_hal_fled_get_timeout_level fled_get_timeout_level;
+       rt_hal_fled_get_lv_protection fled_get_lv_protection;
+       rt_hal_fled_get_strobe_timeout fled_get_strobe_timeout;
+       /*PM shutdown, optional */
+       rt_hal_fled_shutdown fled_shutdown;
+};
+
+typedef struct rt_fled_info {
+       struct rt_fled_hal *hal;
+       struct flashlight_device *flashlight_dev;
+       const struct flashlight_properties *init_props;
+       char *name;
+       char *chip_name;
+} rt_fled_info_t;
+
+/*Public funtions
+ *argument
+ *  @name : Flash LED's name;pass NULL menas "rt-flash-led"
+ */
+
+rt_fled_info_t *rt_fled_get_info_by_name(char *name);
+
+/*Usage :
+ *fled_info = rt_fled_get_info_by_name("FlashLED1");
+ *fled_info->hal->fled_set_strobe_current(fled_info,
+ *                                       150, 200);
+ */
+
+#endif /*LINUX_LEDS_RTFLED_H */
index 02446ee4bcfe4c973ba224c1dd6036953abc7a73..eaf83c93cee58b028ccce758de68e86ef37c3c71 100755 (executable)
@@ -969,7 +969,7 @@ static ssize_t rk808_test_store(struct kobject *kobj, struct kobj_attribute *att
                                 const char *buf, size_t n)
 {
     u32 getdata[8];
-    u16 regAddr;
+    u8 regAddr;
     u8 data;
     char cmd;
     const char *buftmp = buf;
@@ -980,45 +980,32 @@ static ssize_t rk808_test_store(struct kobject *kobj, struct kobj_attribute *att
      * R regAddr(8Bit)
      * C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
      */
-        regAddr = (u16)(getdata[0] & 0xff);
-        if (strncmp(buf, "start", 5) == 0) {
-        
-
-    } else if (strncmp(buf, "stop", 4== 0) ){
-    
-    } else{
-        sscanf(buftmp, "%c ", &cmd);
-        printk("------zhangqing: get cmd = %c\n", cmd);
-        switch(cmd) {
-
-        case 'w':
-               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0],&getdata[1]);
-                regAddr = (u16)(getdata[0] & 0xff);
-                data = (u8)(getdata[1] & 0xff);
-                printk("get value = %x\n", data);
-
-             rk808_i2c_write(rk808, regAddr, 1, data);
-            rk808_i2c_read(rk808, regAddr, 1, &data);
-            printk("%x   %x\n", getdata[1],data);
-
-            break;
-
-        case 'r':
-            sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
-            printk("CMD : %c %x\n", cmd, getdata[0]);
-
-            regAddr = (u16)(getdata[0] & 0xff);
-            rk808_i2c_read(rk808, regAddr, 1, &data);
-               printk("%x %x\n", getdata[0],data);
-
-            break;
+       sscanf(buftmp, "%c ", &cmd);
+       printk("------zhangqing: get cmd = %c\n", cmd);
+       switch (cmd) {
+       case 'w':
+               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
+               regAddr = (u8)(getdata[0] & 0xff);
+               data = (u8)(getdata[1] & 0xff);
+               printk("get value = %x\n", data);
+
+               rk808_i2c_write(rk808, regAddr, 1, data);
+               rk808_i2c_read(rk808, regAddr, 1, &data);
+               printk("%x   %x\n", getdata[1], data);
+               break;
+       case 'r':
+               sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
+               printk("CMD : %c %x\n", cmd, getdata[0]);
 
-        default:
-            printk("Unknown command\n");
-            break;
-        }
-}
-    return n;
+               regAddr = (u8)(getdata[0] & 0xff);
+               rk808_i2c_read(rk808, regAddr, 1, &data);
+               printk("%x %x\n", getdata[0], data);
+               break;
+       default:
+               printk("Unknown command\n");
+               break;
+       }
+       return n;
 
 }
 static ssize_t rk808_test_show(struct kobject *kobj, struct kobj_attribute *attr,
index 19f4e9df6f117d05688d8beabb8478213607b35a..f3ccb1188ac5ce46f7c24cc043ce4221a951e0b5 100755 (executable)
@@ -862,7 +862,7 @@ static ssize_t rk818_test_store(struct kobject *kobj, struct kobj_attribute *att
                                 const char *buf, size_t n)
 {
     u32 getdata[8];
-    u16 regAddr;
+    u8 regAddr;
     u8 data;
     char cmd;
     const char *buftmp = buf;
@@ -873,45 +873,32 @@ static ssize_t rk818_test_store(struct kobject *kobj, struct kobj_attribute *att
      * R regAddr(8Bit)
      * C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
      */
-        regAddr = (u16)(getdata[0] & 0xff);
-        if (strncmp(buf, "start", 5) == 0) {
-        
-
-    } else if (strncmp(buf, "stop", 4== 0) ){
-    
-    } else{
-        sscanf(buftmp, "%c ", &cmd);
-        printk("------zhangqing: get cmd = %c\n", cmd);
-        switch(cmd) {
-
-        case 'w':
-               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0],&getdata[1]);
-                regAddr = (u16)(getdata[0] & 0xff);
-                data = (u8)(getdata[1] & 0xff);
-                printk("get value = %x\n", data);
-
-             rk818_i2c_write(rk818, regAddr, 1, data);
-            rk818_i2c_read(rk818, regAddr, 1, &data);
-            printk("%x   %x\n", getdata[1],data);
-
-            break;
-
-        case 'r':
-            sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
-            printk("CMD : %c %x\n", cmd, getdata[0]);
-
-            regAddr = (u16)(getdata[0] & 0xff);
-            rk818_i2c_read(rk818, regAddr, 1, &data);
-               printk("%x %x\n", getdata[0],data);
-
-            break;
+       sscanf(buftmp, "%c ", &cmd);
+       printk("------zhangqing: get cmd = %c\n", cmd);
+       switch (cmd) {
+       case 'w':
+               sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
+               regAddr = (u8)(getdata[0] & 0xff);
+               data = (u8)(getdata[1] & 0xff);
+               printk("get value = %x\n", data);
+
+               rk818_i2c_write(rk818, regAddr, 1, data);
+               rk818_i2c_read(rk818, regAddr, 1, &data);
+               printk("%x   %x\n", getdata[1], data);
+               break;
+       case 'r':
+               sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
+               printk("CMD : %c %x\n", cmd, getdata[0]);
 
-        default:
-            printk("Unknown command\n");
-            break;
-        }
-}
-    return n;
+               regAddr = (u8)(getdata[0] & 0xff);
+               rk818_i2c_read(rk818, regAddr, 1, &data);
+               printk("%x %x\n", getdata[0], data);
+               break;
+       default:
+               printk("Unknown command\n");
+               break;
+       }
+       return n;
 
 }
 static ssize_t rk818_test_show(struct kobject *kobj, struct kobj_attribute *attr,
index 9dd6ad6db022b26c6dc20500493541fc0545dbdd..3a3bd7c2df07d052815b6189630774c9d9f0cd3f 100755 (executable)
@@ -25,6 +25,7 @@
 
 #include <linux/mfd/rt5036/rt5036.h>
 #include <linux/mfd/rt5036/rt5036-misc.h>
+#include <asm/system_misc.h>
 
 static struct i2c_client *g_shdn;
 
@@ -71,9 +72,17 @@ EXPORT_SYMBOL(rt5036_vin_exist);
 static bool rt_pm_off;
 void rt5036_chip_shutdown(void)
 {
-       if (g_shdn) {
-               rt5036_set_bits(g_shdn, RT5036_REG_MISC3, RT5036_CHIPSHDN_MASK);
-               rt5036_clr_bits(g_shdn, RT5036_REG_MISC3, RT5036_CHIPSHDN_MASK);
+       pr_info("%s\n", __func__);
+       if (rt5036_vin_exist()) {
+               arm_pm_restart('h', "charge");
+       } else {
+               if (g_shdn) {
+                       pr_info("chip enter shutdown process\n");
+                       rt5036_set_bits(g_shdn, RT5036_REG_MISC3,
+                                       RT5036_CHIPSHDN_MASK);
+                       rt5036_clr_bits(g_shdn, RT5036_REG_MISC3,
+                                       RT5036_CHIPSHDN_MASK);
+               }
        }
 }
 EXPORT_SYMBOL(rt5036_chip_shutdown);
index dba448bf52f439fc92ecd1008348c8a5c8d21c2f..62c18d898fe5e20049dc104901b2b0414f52a459 100755 (executable)
@@ -30,6 +30,7 @@
 #include <linux/stat.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
+#include <linux/suspend.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sd.h>
@@ -1544,10 +1545,10 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
                 (mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)) {
                 gpio_cd = slot->cd_gpio;
                 if (gpio_is_valid(gpio_cd)) {
-                        gpio_val = gpio_get_value_cansleep(gpio_cd);
+                        gpio_val = gpio_get_value(gpio_cd);
                         msleep(10);
-                        if (gpio_val == gpio_get_value_cansleep(gpio_cd)) {
-                                gpio_cd = gpio_get_value_cansleep(gpio_cd) == 0 ? 1 : 0;
+                        if (gpio_val == gpio_get_value(gpio_cd)) {
+                                gpio_cd = gpio_get_value(gpio_cd) == 0 ? 1 : 0;
                                 if (gpio_cd == 0) {
                                         /* Enable force_jtag wihtout card in slot, ONLY for NCD-package */
                                         grf_writel((0x1 << 24) | (1 << 8), RK312X_GRF_SOC_CON0);
@@ -2965,11 +2966,6 @@ static void dw_mci_work_routine_card(struct work_struct *work)
 
                present = dw_mci_get_cd(mmc);
 
-                /* Stop edma when rountine card triggered */
-                if(cpu_is_rk3036() || cpu_is_rk312x())
-                       if(host->dma_ops && host->dma_ops->stop)
-                               host->dma_ops->stop(host);
-
                 /* Card insert, switch data line to uart function, and vice verse.
                  * ONLY audi chip need switched by software, using udbg tag in dts!
                  */
@@ -2992,6 +2988,10 @@ static void dw_mci_work_routine_card(struct work_struct *work)
                                present ? "inserted" : "removed.", mmc_hostname(mmc));
        
                        dw_mci_ctrl_all_reset(host);
+                       /* Stop edma when rountine card triggered */
+                       if(cpu_is_rk3036() || cpu_is_rk312x())
+                               if(host->dma_ops && host->dma_ops->stop)
+                                       host->dma_ops->stop(host);
                        rk_send_wakeup_key();//wake up system
                        spin_lock_bh(&host->lock);
 
@@ -3205,17 +3205,19 @@ static irqreturn_t dw_mci_gpio_cd_irqt(int irq, void *dev_id)
         struct dw_mci_slot *slot = mmc_priv(mmc);
         struct dw_mci *host = slot->host;
 
-        #if 0
-        if (mmc->ops->card_event)
-                mmc->ops->card_event(mmc);
-
-        mmc_detect_change(mmc, msecs_to_jiffies(200));
-        #endif
-
         /* wakeup system whether gpio debounce or not */
         rk_send_wakeup_key();
-        queue_work(host->card_workqueue, &host->card_work);
-        return IRQ_HANDLED;
+
+       /* no need to trigger detect flow when rescan is disabled.
+           This case happended in dpm, that we just wakeup system and
+           let suspend_post notify callback handle it.
+        */
+       if(mmc->rescan_disable == 0)
+               queue_work(host->card_workqueue, &host->card_work);
+       else
+               printk("%s: rescan been disabled!\n", __FUNCTION__);
+
+       return IRQ_HANDLED;
 }
 
 static void dw_mci_of_set_cd_gpio_irq(struct device *dev, u32 gpio,
@@ -3333,13 +3335,44 @@ static void dw_mci_init_pinctrl(struct dw_mci *host)
                         dev_warn(host->dev, "%s: No udbg pinctrl found!\n",
                                         mmc_hostname(host->mmc));
                 } else {
-                        if (pinctrl_select_state(host->pinctrl, host->pins_udbg) < 0)
-                                dev_err(host->dev, "%s: Udbg pinctrl setting failed!\n",
-                                        mmc_hostname(host->mmc));
+                        if (!dw_mci_get_cd(host->mmc))
+                               if (pinctrl_select_state(host->pinctrl, host->pins_udbg) < 0)
+                                       dev_err(host->dev, "%s: Udbg pinctrl setting failed!\n",
+                                               mmc_hostname(host->mmc));
                 }
         }
 }
 
+static int dw_mci_pm_notify(struct notifier_block *notify_block,
+                                       unsigned long mode, void *unused)
+{
+       struct mmc_host *host = container_of(
+               notify_block, struct mmc_host, pm_notify);
+       unsigned long flags;
+
+       switch (mode) {
+       case PM_HIBERNATION_PREPARE:
+       case PM_SUSPEND_PREPARE:
+               dev_err(host->parent, "dw_mci_pm_notify:  suspend prepare\n");
+               spin_lock_irqsave(&host->lock, flags);
+               host->rescan_disable = 1;
+               spin_unlock_irqrestore(&host->lock, flags);
+               if (cancel_delayed_work(&host->detect))
+                        wake_unlock(&host->detect_wake_lock);
+               break;
+
+       case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+       case PM_POST_RESTORE:
+               dev_err(host->parent, "dw_mci_pm_notify:  post suspend\n");
+               spin_lock_irqsave(&host->lock, flags);
+               host->rescan_disable = 0;
+               spin_unlock_irqrestore(&host->lock, flags);
+               mmc_detect_change(host, 10);
+       }
+
+       return 0;
+}
 
 static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 {
@@ -3392,6 +3425,13 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
         if (of_find_property(host->dev->of_node, "supports-tSD", NULL))
                mmc->restrict_caps |= RESTRICT_CARD_TYPE_TSD;
 
+        if (mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
+                mmc->pm_notify.notifier_call = dw_mci_pm_notify;
+                if (register_pm_notifier(&mmc->pm_notify)) {
+                        printk(KERN_ERR "dw_mci: register_pm_notifier failed\n");
+                        goto err_pm_notifier;
+                }
+        }
 
         /* We assume only low-level chip use gpio_cd */
         if (cpu_is_rk312x() &&
@@ -3557,6 +3597,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
        slot->last_detect_state = 1;
 
        return 0;
+err_pm_notifier:
+        unregister_pm_notifier(&mmc->pm_notify);
 
 err_setup_bus:
         if (gpio_is_valid(slot->cd_gpio))
@@ -3766,8 +3808,9 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
 static void dw_mci_dealwith_timeout(struct dw_mci *host)
 {
         u32 regs;
-       u32 sdio_int;
+        u32 sdio_int;
 
+        dev_err(host->dev, "host->state = 0x%x\n", host->state);
         switch(host->state){
                 case STATE_IDLE:
                         break;
@@ -3777,8 +3820,9 @@ static void dw_mci_dealwith_timeout(struct dw_mci *host)
                        mci_writel(host, RINTSTS, SDMMC_INT_DRTO);  // clear interrupt
                         set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
                         host->state = STATE_DATA_BUSY;
-                       if (!dw_mci_ctrl_all_reset(host)) {
-                                return ;
+                        if (!dw_mci_ctrl_all_reset(host)) {
+                               dev_err(host->dev, "dto: ctrl_all_reset failed!\n");
+                               return ;
                         }
 
                         /* NO requirement to reclaim slave chn using external dmac */
@@ -3834,16 +3878,6 @@ static void dw_mci_dto_timeout(unsigned long host_data)
        enable_irq(host->irq);
 }
 
-
-void resume_rescan_enable(struct work_struct *work)
-{
-       struct dw_mci *host =
-               container_of(work, struct dw_mci, resume_rescan.work);
-       host->mmc->rescan_disable = 0;
-       mmc_detect_change(host->mmc, 10);
-}
-
-
 int dw_mci_probe(struct dw_mci *host)
 {
        const struct dw_mci_drv_data *drv_data = host->drv_data;
@@ -3934,7 +3968,6 @@ int dw_mci_probe(struct dw_mci *host)
        spin_lock_init(&host->slock);
 
        INIT_LIST_HEAD(&host->queue);
-       INIT_DELAYED_WORK(&host->resume_rescan, resume_rescan_enable);
        /*
         * Get the host data width - this assumes that HCON has been set with
         * the correct values.
@@ -4092,7 +4125,6 @@ void dw_mci_remove(struct dw_mci *host)
        int i;
 
        del_timer_sync(&host->dto_timer);
-       cancel_delayed_work(&host->resume_rescan);
 
         mci_writel(host, RINTSTS, 0xFFFFFFFF);
         mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
@@ -4108,6 +4140,8 @@ void dw_mci_remove(struct dw_mci *host)
         mci_writel(host, CLKSRC, 0);
 
         destroy_workqueue(host->card_workqueue);
+        if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
+                unregister_pm_notifier(&host->mmc->pm_notify);
 
         if(host->use_dma && host->dma_ops->exit)
                 host->dma_ops->exit(host);
@@ -4145,11 +4179,6 @@ int dw_mci_suspend(struct dw_mci *host)
 
         /*only for sdmmc controller*/
         if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
-                host->mmc->rescan_disable = 1;
-
-                if(cancel_delayed_work(&host->mmc->detect))
-                        wake_unlock(&host->mmc->detect_wake_lock);
-
                 disable_irq(host->irq);
                 if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0)
                         MMC_DBG_ERR_FUNC(host->mmc, "Idle pinctrl setting failed! [%s]",
@@ -4197,7 +4226,7 @@ int dw_mci_resume(struct dw_mci *host)
                if(pinctrl_select_state(host->pinctrl, host->pins_default) < 0)
                         MMC_DBG_ERR_FUNC(host->mmc, "Default pinctrl setting failed! [%s]",
                                                 mmc_hostname(host->mmc));
-               host->mmc->rescan_disable = 1;
+
                /* Disable jtag*/
                if(cpu_is_rk3288())
                         grf_writel(((1 << 12) << 16) | (0 << 12), RK3288_GRF_SOC_CON0);
@@ -4256,9 +4285,6 @@ int dw_mci_resume(struct dw_mci *host)
                }
        }
 
-       if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD))
-               schedule_delayed_work(&host->resume_rescan, msecs_to_jiffies(2000));
-
        return 0;
 }
 EXPORT_SYMBOL(dw_mci_resume);
index 402c9891863eb3e19685e77f08ccd29a44d33417..9ef481cd8a4ff5dc34ba1e1eda8feeb3080790ed 100755 (executable)
@@ -10858,8 +10858,8 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
        DNGL_FUNC(dhd_cfg80211_down, (wl));
        wl_flush_eq(wl);
        wl_link_down(wl);
-       if (wl->p2p_supported)
-               wl_cfgp2p_down(wl);
+       //if (wl->p2p_supported)
+       //      wl_cfgp2p_down(wl);
        dhd_monitor_uninit();
 
        return err;
index ce2aefa4fc3f47109cca40c2139815e37d3a4ebf..ed1225347806984bf2b6809c6cb79b2cedaf1f05 100755 (executable)
 #define CONFIG_LAYER2_ROAMING
 #define CONFIG_LAYER2_ROAMING_RESUME
 //#define CONFIG_ADAPTOR_INFO_CACHING_FILE // now just applied on 8192cu only, should make it general...
-//#define CONFIG_RESUME_IN_WORKQUEUE
+#define CONFIG_RESUME_IN_WORKQUEUE
 //#define CONFIG_SET_SCAN_DENY_TIMER
 #define CONFIG_LONG_DELAY_ISSUE
 #define CONFIG_NEW_SIGNAL_STAT_PROCESS
index 33a42836e9277347e468cd35a767ddc29709de75..0ac76f61716a3a5da8c1154aa78ce2ba0f093fbd 100755 (executable)
 
 #define USB_INTERFERENCE_ISSUE // this should be checked in all usb interface
 //#define CONFIG_ADAPTOR_INFO_CACHING_FILE // now just applied on 8192cu only, should make it general...
-//#define CONFIG_RESUME_IN_WORKQUEUE
+#define CONFIG_RESUME_IN_WORKQUEUE
 //#define CONFIG_SET_SCAN_DENY_TIMER
 #define CONFIG_LONG_DELAY_ISSUE
 #define CONFIG_NEW_SIGNAL_STAT_PROCESS
index 96d0ea09cd7784334f5081d0b4d6b1cc9e24b97a..c4d937281763bfd8392140bbcf81688993090771 100644 (file)
 #define CONFIG_LAYER2_ROAMING
 #define CONFIG_LAYER2_ROAMING_RESUME
 //#define CONFIG_ADAPTOR_INFO_CACHING_FILE // now just applied on 8192cu only, should make it general...
-//#define CONFIG_RESUME_IN_WORKQUEUE
+#define CONFIG_RESUME_IN_WORKQUEUE
 //#define CONFIG_SET_SCAN_DENY_TIMER
 #define CONFIG_LONG_DELAY_ISSUE
 #define CONFIG_NEW_SIGNAL_STAT_PROCESS
index c198c016b4ae7276ca12e3d8c3cc166c6b66b864..d4da2416ea91ad2136b0be585fef0e683437c047 100755 (executable)
@@ -92,7 +92,7 @@ enum int_type {
 #define RICOH619_OCV_OFFSET_BOUND      3
 #define RICOH619_OCV_OFFSET_RATIO      2
 
-#define RICOH619_VADP_DROP_WORK 1
+#define RICOH619_VADP_DROP_WORK
 #define RICOH619_TIME_CHG_STEP (1*HZ)// unit:secound
 #define RICOH619_TIME_CHG_COUNT        15*60//only for test //15*60 
 
@@ -767,7 +767,14 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
        j = info->soca->soc - info->soca->soc/1000*1000;
        Ocv_now_table = ocv_table[i]*100+(ocv_table[i+1]-ocv_table[i])*j/10;
 
-               Rsys_now = (info->soca->Vsys_ave - Ocv_now_table) / info->soca->Ibat_ave;       
+       Rsys_now = (info->soca->Vsys_ave - Ocv_now_table) / info->soca->Ibat_ave;
+       if (((abs(info->soca->soc - info->soca->displayed_soc)) > 10)
+               && (info->soca->Ibat_ave > -250)) {
+               if (Rsys_now < 0)
+                       Rsys_now = max(-info->soca->Rbat, Rsys_now);
+               else
+                       Rsys_now = min(info->soca->Rbat, Rsys_now);
+       }
 
        Ocv_ZeroPer_now = info->soca->target_vsys * 1000 - Ibat_now * Rsys_now;
 
@@ -795,8 +802,8 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
 
        FA_CAP_now = fa_cap * ((10000 - start_per) / 100 ) / 100;
 
-       RICOH_FG_DBG("PMU: -------  Target_Cutoff_Vol= %d: Ocv_ZeroPer_now= %d: start_per= %d =======\n",
-              Target_Cutoff_Vol, Ocv_ZeroPer_now, start_per);
+       RICOH_FG_DBG("PMU: -------Ocv_ZeroPer_now= %d: start_per= %d =======\n",
+               Ocv_ZeroPer_now, start_per);
 
        /* get RE_CAP_now */
        RE_CAP_now = FA_CAP_now - use_cap;
@@ -1587,7 +1594,8 @@ end_flow:
 
        info->soca->last_displayed_soc = info->soca->displayed_soc+50;
 
-       if((info->soca->displayed_soc >= 9850) && (info->soca->Ibat_ave > -20) && (info->capacity < 100))
+       if ((info->soca->displayed_soc >= 9850) && (info->soca->Ibat_ave > -20) && (info->capacity < 100)
+               && (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING))
        {
                if(info->chg_complete_rd_flag == 0)
                {
@@ -1997,7 +2005,6 @@ static void ricoh619_charging_complete_work(struct work_struct *work)
        RICOH_FG_DBG("info->chg_complete_rd_cnt = %d\n", info->chg_complete_rd_cnt);
        RICOH_FG_DBG("info->chg_complete_rd_flag = %d\n", info->chg_complete_rd_flag);
        RICOH_FG_DBG("info->chg_complete_tm_ov_flag = %d\n", info->chg_complete_tm_ov_flag);
-       RICOH_FG_DBG("time_ov_flag = %d\n", time_ov_flag);
        
        if(info->chg_complete_rd_flag == 1)
        {
@@ -2031,7 +2038,7 @@ static void ricoh619_charging_complete_work(struct work_struct *work)
                }
        }
 
-       if(time_ov_flag == 0)
+       if ((time_ov_flag == 0) && (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING))
        {
                info->chg_complete_rd_cnt++;
                queue_delayed_work(info->monitor_wqueue, &info->charge_complete_ready, 
@@ -2039,7 +2046,7 @@ static void ricoh619_charging_complete_work(struct work_struct *work)
        }
        else
        {
-               time_ov_flag = 0;
+               info->chg_complete_rd_flag = 0;
        }
 
        RICOH_FG_DBG("PMU2: %s return\n", __func__);
@@ -3245,8 +3252,7 @@ static void charger_irq_work(struct work_struct *work)
                                ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3); 
                        }
                        #endif
-               }       
-               else if (reg_val & 0x80) { /* USE USB */
+               } else if (reg_val & 0x80) { /* USE ONLY USB */
                        queue_work(info->usb_workqueue, &info->usb_irq_work);
                }
        }
@@ -3314,7 +3320,7 @@ static void usb_det_irq_work(struct work_struct *work)
 {
        struct ricoh619_battery_info *info = container_of(work,
                 struct ricoh619_battery_info, usb_irq_work);
-       int ret = 0,i;
+       int ret = 0;
        uint8_t sts;
 
        RICOH_FG_DBG("PMU:%s In\n", __func__);
@@ -3339,16 +3345,8 @@ static void usb_det_irq_work(struct work_struct *work)
                dev_err(info->dev, "Error in reading the control register\n");
 
        sts &= 0x02;
-       if (sts) {
-               for(i =0;i<60;i++){
+       if (sts)
                ricoh619_usb_charge_det();
-               mdelay(10);
-               }
-       } else {
-               /*********************/
-               /* No process ??     */
-               /*********************/
-       }
        
        RICOH_FG_DBG("PMU:%s Out\n", __func__);
 }
@@ -4737,7 +4735,7 @@ static int ricoh619_battery_suspend(struct device *dev)
 #ifdef ENABLE_LOW_BATTERY_DETECTION
        cancel_delayed_work(&info->low_battery_work);
 #endif
-       cancel_delayed_work(&info->charge_complete_ready);
+/*     cancel_delayed_work(&info->charge_complete_ready);*/
 #ifdef ENABLE_FACTORY_MODE
        cancel_delayed_work(&info->factory_mode_work);
 #endif
@@ -4745,8 +4743,8 @@ static int ricoh619_battery_suspend(struct device *dev)
 #ifdef RICOH619_VADP_DROP_WORK
        cancel_delayed_work(&info->vadp_drop_work);
 #endif
-       info->chg_complete_rd_cnt = 0;
-       info->chg_complete_rd_flag = 0;
+/*     info->chg_complete_rd_cnt = 0;*/
+/*     info->chg_complete_rd_flag = 0;*/
 
        if(info->capacity == 100)
        {
@@ -4804,7 +4802,7 @@ static int ricoh619_battery_resume(struct device *dev)
                printk("chg_complete_rd_cnt suspend: %d\n", info->chg_complete_rd_cnt);
                info->chg_complete_rd_cnt += (tv.tv_sec - ts_suspend.tv_sec);
                printk("chg_complete_rd_cnt resume: %d\n", info->chg_complete_rd_cnt);
-               cancel_delayed_work(&info->charge_complete_ready);
+               flush_work(&info->charge_complete_ready.work);
        }
 
        RICOH_FG_DBG(KERN_INFO "PMU: %s: \n", __func__);
@@ -4818,6 +4816,7 @@ static int ricoh619_battery_resume(struct device *dev)
                info->soca->displayed_soc = -EINVAL;
        } else if (RICOH619_SOCA_ZERO == info->soca->status) {
                if (calc_ocv(info) > get_OCV_voltage(info, 0)) {
+                       RICOH_FG_DBG(KERN_INFO "PMU: %s: RICOH619_SOCA_ZERO if ()...\n", __func__);
                        ret = ricoh619_read(info->dev->parent, PSWR_REG, &val);
                        val &= 0x7f;
                        info->soca->soc = val * 100;
@@ -4850,8 +4849,11 @@ static int ricoh619_battery_resume(struct device *dev)
                                dev_err(info->dev, "Error in writing the control register\n");
                        info->soca->status = RICOH619_SOCA_FG_RESET;
 
-               } else
-                       info->soca->displayed_soc = 0;
+               } else {
+                       RICOH_FG_DBG(KERN_INFO "PMU: %s: RICOH619_SOCA_ZERO else()...\n", __func__);
+                       /*info->soca->displayed_soc = 0;*/
+                       info->soca->displayed_soc  = info->soca->suspend_soc;
+               }
        } else {
                info->soca->soc = info->soca->suspend_soc;
 
index 2e3cbde221727dbe9505c43f13a585c6bfda0c4d..4621ff8507d4bb835d34ed6fc26a9ff01c3012d9 100755 (executable)
@@ -753,41 +753,50 @@ static int rk30_adc_battery_status_samples(struct rk30_adc_battery_data *bat)
 
        return charge_level;
 }
+
+static int rk_adc_battery_iio_read_refvol(struct rk30_adc_battery_platform_data *data)
+{
+       struct iio_channel *channel = data->ref_voltage_chan;
+       int val, ret;
+
+       ret = iio_read_channel_raw(channel, &val);
+       if (ret < 0) {
+               pr_err("read channel() error: %d\n", ret);
+               return ret;
+       }
+       return val;
+}
+
+static int get_ref_voltage(struct rk30_adc_battery_data *bat)
+{
+       int data_value;
+       struct regulator *logic;
+       int voltage, ref_voltage;
+
+       logic = regulator_get(NULL, "vdd_arm");
+       voltage = regulator_get_voltage(logic);
+       data_value = rk_adc_battery_iio_read_refvol(bat->pdata);
+       ref_voltage = voltage*1024/data_value/1000;
+
+       return ref_voltage;
+}
 static int rk_adc_voltage(struct rk30_adc_battery_data *bat, int value)
 {
        int voltage;
-
-       int ref_voltage; //reference_voltage
-       int pullup_res;
-       int pulldown_res;
+       int ref_voltage;
 
        ref_voltage = bat ->pdata->reference_voltage;
-       pullup_res = bat ->pdata->pull_up_res;
-       pulldown_res = bat ->pdata->pull_down_res;
-
-       if(ref_voltage && pullup_res && pulldown_res){
-#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
-               ref_voltage = adc_get_curr_ref_volt();
-#endif 
-               voltage =  ((value * ref_voltage * (pullup_res + pulldown_res)) / (1024 * pulldown_res));
-               DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage);
+
+       if (ref_voltage) {
+               if (bat->pdata->auto_calibration == 1)
+                       ref_voltage = get_ref_voltage(bat);
+               voltage = (value * ref_voltage * (batt_table[4] + batt_table[5])) / (1024 * batt_table[5]);
+               DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage);
                
        }else{
-#if 0
-               if(bat ->capacitytmp < 5)
-                       ref_voltage = adc_get_curr_ref_volt();
-               else
-                       ref_voltage = adc_get_def_ref_volt();
-#endif
-#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
-               ref_voltage = adc_get_curr_ref_volt();
-               voltage = (value * ref_voltage * (batt_table[4] +batt_table[5])) / (1024 *batt_table[5]); 
-#else
                voltage = adc_to_voltage(value);
-#endif
        }
-       
-       DBG("ref_voltage =%d, voltage=%d \n", ref_voltage,voltage);
+       DBG("ref_voltage =%d, voltage=%d\n", ref_voltage, voltage);
        return voltage;
 
 }
@@ -1355,16 +1364,9 @@ static void rk30_adc_battery_poweron_capacity_check(struct rk30_adc_battery_data
        }
        else if (bat ->bat_status != POWER_SUPPLY_STATUS_NOT_CHARGING){
        //chargeing state
-
-               if( bat  ->pdata->is_reboot_charging == 1)
-                       bat ->bat_capacity = (old_capacity < 10) ?(old_capacity+2):old_capacity;
-               else
-                       bat ->bat_capacity = (new_capacity > old_capacity) ? new_capacity : old_capacity;
+               bat->bat_capacity = (old_capacity < 10) ? (old_capacity + 2) : old_capacity;
        }else{
-               if(new_capacity > old_capacity + 50 )
                        bat ->bat_capacity = old_capacity + 5;
-               else
-                       bat ->bat_capacity = (new_capacity < old_capacity) ? new_capacity : old_capacity;  //avoid the value of capacity increase 
                if(bat->bat_capacity == 100)
                        bat->bat_capacity = 99;
                if(bat->bat_capacity == 0)
@@ -2111,15 +2113,31 @@ rk30_adc_battery_platform_data *data)
        int ret;
        int i;
        size_t size;
-        struct iio_channel *chan;
 
-       if (!node)
-               return -ENODEV;
+       struct iio_channel *channels;
+       int num = 0;
+
+       channels = iio_channel_get_all(&pdev->dev);
+       if (IS_ERR(channels))
+               pr_err("get adc channels fails\n");
+       while (channels[num].indio_dev)
+               num++;
+       data->chan = &channels[0];
+       if (num > 1)
+               data->ref_voltage_chan = &channels[1];
+       ret = of_property_read_u32(node, "auto_calibration", &value);
+       if (ret < 0) {
+               pr_info("%s:unsupport auto_calibration\n", __func__);
+               value = 0;
+       }
+       data->auto_calibration = value;
 
-       chan = iio_channel_get(&pdev->dev, NULL);
-       if (IS_ERR(chan))
-               pr_err("iio_channel_get fail\n");
-       data->chan = chan;
+       ret = of_property_read_u32(node, "ref_voltage", &value);
+       if (ret < 0) {
+               pr_info("%s:unsupport ref_voltage\n", __func__);
+               value = 0;
+       }
+       data->reference_voltage = value;
 
        /* determine the number of config info */
        prop = of_find_property(node, "bat_table", &length);
index 137b58ab230d4d54567a12893e2a60a2e55c6c9c..d44f1fa47cda1873823c24d840c0beb62d762f7b 100644 (file)
@@ -81,7 +81,7 @@ module_param_named(dbg_level, pwm_dbg_level, int, 0644);
 #define PWMCR_MIN_PRESCALE     0x00
 #define PWMCR_MAX_PRESCALE     0x07
 
-#define PWMDCR_MIN_DUTY                0x0001
+#define PWMDCR_MIN_DUTY                0x0000
 #define PWMDCR_MAX_DUTY                0xFFFF
 
 #define PWMPCR_MIN_PERIOD              0x0001
index 22b218987bf47bc554dd21baa262fb970ec6a89f..460dd7a686fcc624134abd7443d75b4afa1b895b 100755 (executable)
@@ -1362,9 +1362,22 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
                pr_err("%s: failure mapping buffer to userspace\n",
                       __func__);
 
+       trace_ion_buffer_mmap("", (unsigned int)buffer, buffer->size,
+               vma->vm_start, vma->vm_end);
+
        return ret;
 }
 
+int ion_munmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+       struct ion_buffer *buffer = dmabuf->priv;
+
+       trace_ion_buffer_munmap("", (unsigned int)buffer, buffer->size,
+               vma->vm_start, vma->vm_end);
+
+       return 0;
+}
+
 static void ion_dma_buf_release(struct dma_buf *dmabuf)
 {
        struct ion_buffer *buffer = dmabuf->priv;
index 47af2919cb390de778811ce3c07c631376584bda..67bf9d322d46cae973efb655d244b71a6a52abc3 100644 (file)
@@ -146,7 +146,38 @@ DEFINE_EVENT(ion_kmap_op, ion_kernel_map,
        TP_PROTO(const char* client, void* buffer, unsigned int size, void* kaddr),
        TP_ARGS(client, buffer, size, kaddr));
 
+DECLARE_EVENT_CLASS(ion_mmap_op,
+       TP_PROTO(const char* client, unsigned int buf, unsigned int size,
+               unsigned long vm_start, unsigned long vm_end),
+       TP_ARGS(client, buf, size, vm_start, vm_end),
+       TP_STRUCT__entry(
+               __string(client, client)
+               __field(unsigned int, buf)
+               __field(unsigned int, size)
+               __field(unsigned long, vm_start)
+               __field(unsigned long, vm_end)
+       ),
+       TP_fast_assign(
+               __assign_str(client, client);
+               __entry->buf = buf;
+               __entry->size = size;
+               __entry->vm_start = vm_start;
+               __entry->vm_end = vm_end;
+       ),
+       TP_printk("client=%s,buffer=%08x:%d,vma[%08lx:%08lx]",
+                 __get_str(client), __entry->buf, __entry->size,
+                 __entry->vm_start, __entry->vm_end)
+);
+
+DEFINE_EVENT(ion_mmap_op, ion_buffer_mmap,
+       TP_PROTO(const char* client, unsigned int buf, unsigned int size,
+               unsigned long vm_start, unsigned long vm_end),
+       TP_ARGS(client, buf, size, vm_start, vm_end));
 
+DEFINE_EVENT(ion_mmap_op, ion_buffer_munmap,
+       TP_PROTO(const char* client, unsigned int buf, unsigned int size,
+               unsigned long vm_start, unsigned long vm_end),
+       TP_ARGS(client, buf, size, vm_start, vm_end));
 
 #endif /* _TRACE_ION_H */
 
index a38cd0b6751bd29ece48c9a7572a275ecc1e097c..f071bf401473ed0d021f6ab88d710bb13cfae4fc 100755 (executable)
 #include "dwc_otg_core_if.h"
 #include "dwc_otg_pcd_if.h"
 #include "dwc_otg_hcd_if.h"
+#include "dwc_otg_regs.h"
+#include "dwc_otg_cil.h"
+#include "usbdev_rk.h"
 
 /*
  * MACROs for defining sysfs attribute
@@ -577,10 +580,15 @@ static ssize_t buspower_store(struct device *_dev,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
-
        dwc_otg_device_t *otg_dev = _dev->platform_data;
+       struct dwc_otg_platform_data *pldata = otg_dev->pldata;
        uint32_t on = simple_strtoul(buf, NULL, 16);
+
+       if (on != 0 && on != 1)
+               return -EINVAL;
+
        dwc_otg_set_prtpower(otg_dev->core_if, on);
+       pldata->power_enable(on);
        return count;
 }
 
@@ -1075,6 +1083,85 @@ DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
 
 #endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
 
+static int test_sq(dwc_otg_core_if_t *core_if)
+{
+       hprt0_data_t hprt0 = { .d32 = 0 };
+       dctl_data_t dctl = { .d32 = 0 };
+       dsts_data_t dsts = { .d32 = 0 };
+
+       /**
+       * Step.1 check current mode
+       * Step.2 check connection
+       * Step.3 enter test packet mode
+       */
+
+       if (dwc_otg_is_host_mode(core_if)) {
+               DWC_PRINTF("Host Mode\n");
+               hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
+
+               if (hprt0.b.prtena && !hprt0.b.prtsusp &&
+                   hprt0.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) {
+                       hprt0.d32 = 0;
+                       hprt0.b.prttstctl = 0x4;
+                       DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
+                       DWC_PRINTF("Start packet test\n");
+                       return 0;
+
+               } else
+                       DWC_PRINTF("Invalid connect status HPRT0 = 0x%08x\n",
+                                  hprt0.d32);
+       } else {
+               DWC_PRINTF("Device Mode\n");
+               dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
+
+               if (!dsts.b.suspsts &&
+                   dsts.b.enumspd == DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) {
+                       dctl.b.tstctl = 0x4;
+                       DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
+                                       dctl.d32);
+                       DWC_PRINTF("Start packet test\n");
+                       return 0;
+
+               } else
+                       DWC_PRINTF("Invalid connect status DSTS = 0x%08x\n",
+                                  dsts.d32);
+       }
+
+       return -1;
+
+}
+
+/**
+* Show the usage of usb controler test_sq attribute.
+*/
+static ssize_t test_sq_show(struct device *_dev,
+                               struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf,
+       "USAGE : echo anything to \"test\" to start test packet pattern\n");
+}
+
+static ssize_t test_sq_store(struct device *_dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+
+{
+       dwc_otg_device_t *otg_dev = _dev->platform_data;
+       struct dwc_otg_platform_data *pldata = otg_dev->pldata;
+
+       if (pldata->phy_status == USB_PHY_SUSPEND) {
+               DWC_PRINTF("Invalid status : SUSPEND\n");
+               return -EBUSY;
+       }
+
+       if (test_sq(otg_dev->core_if))
+               return -EBUSY;
+       else
+               return count;
+}
+
+DEVICE_ATTR(test_sq, S_IWUSR | S_IRUSR, test_sq_show, test_sq_store);
+
 /**@}*/
 
 /**
@@ -1118,6 +1205,7 @@ void dwc_otg_attr_create(struct platform_device *dev)
        error = device_create_file(&dev->dev, &dev_attr_besl_reject);
        error = device_create_file(&dev->dev, &dev_attr_hird_thres);
 #endif
+       error = device_create_file(&dev->dev, &dev_attr_test_sq);
 }
 
 /**
@@ -1159,4 +1247,5 @@ void dwc_otg_attr_remove(struct platform_device *dev)
        device_remove_file(&dev->dev, &dev_attr_besl_reject);
        device_remove_file(&dev->dev, &dev_attr_hird_thres);
 #endif
+       device_remove_file(&dev->dev, &dev_attr_test_sq);
 }
index 0e9676a79e2f4aae833ba95a59fada145cb087ce..653b2b600f91fe44936fa728cbd8381809dd09e4 100755 (executable)
@@ -1394,7 +1394,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t *core_if)
                DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
                /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
                   Host mode ISOC in issue fix - vahrama */
-               ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
+               ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR8;
                core_if->dma_enable = (core_if->core_params->dma_enable != 0);
                core_if->dma_desc_enable =
                    (core_if->core_params->dma_desc_enable != 0);
@@ -1714,7 +1714,7 @@ void dwc_otg_core_init_no_reset(dwc_otg_core_if_t *core_if)
                DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
                /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
                   Host mode ISOC in issue fix - vahrama */
-               ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
+               ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR8;
                core_if->dma_enable = (core_if->core_params->dma_enable != 0);
                core_if->dma_desc_enable =
                    (core_if->core_params->dma_desc_enable != 0);
@@ -1973,7 +1973,7 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *core_if)
        DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
        dwc_udelay(10);
 
-       gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
+       gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR8;
        DWC_MODIFY_REG32(&global_regs->gahbcfg, 0, gahbcfg.b.hburstlen);
 
        /* Device configuration register */
index 2befa34ec6af82438130dfd924da0ef85c7eb579..1279c0d623d89b2f2095a0a9c02dbf728f7cb9c4 100755 (executable)
@@ -120,9 +120,7 @@ static struct usb20host_pdata_id usb20host_pdata[] = {
 };
 #endif
 
-#ifdef CONFIG_RK_USB_UART
 static u32 usb_to_uart_status;
-#endif
 /*-------------------------------------------------------------------------*/
 /* Encapsulate the module parameter settings */
 
@@ -1620,7 +1618,11 @@ void rk_usb_power_up(void)
        struct dwc_otg_platform_data *pldata_otg;
        struct dwc_otg_platform_data *pldata_host;
        struct rkehci_platform_data *pldata_ehci;
-
+       if (cpu_is_rk312x()) {
+               pldata_otg = &usb20otg_pdata_rk3126;
+               if (usb_to_uart_status)
+                       pldata_otg->dwc_otg_uart_mode(pldata_otg, PHY_UART_MODE);
+       }
        if (cpu_is_rk3288()) {
 #ifdef CONFIG_RK_USB_UART
                /* enable USB bypass UART function  */
@@ -1666,6 +1668,11 @@ void rk_usb_power_down(void)
        struct dwc_otg_platform_data *pldata_host;
        struct rkehci_platform_data *pldata_ehci;
 
+       if (cpu_is_rk312x()) {
+               pldata_otg = &usb20otg_pdata_rk3126;
+               usb_to_uart_status = pldata_otg->get_status(USB_STATUS_UARTMODE);
+               pldata_otg->dwc_otg_uart_mode(pldata_otg, PHY_USB_MODE);
+       }
        if (cpu_is_rk3288()) {
 #ifdef CONFIG_RK_USB_UART
                /* disable USB bypass UART function */
index ccc817b7d25eb0301eed9a37f318ecb430d14078..a6f174cc322dbe44ac16c4c65945a120a38f4e16 100755 (executable)
@@ -127,6 +127,9 @@ static int usb20otg_get_status(int id)
                /* id in grf */
                ret = soc_status0 & (0x1 << 8);
                break;
+       case USB_STATUS_UARTMODE:
+               ret = readl(RK_GRF_VIRT + RK312X_GRF_UOC1_CON4) & (1 << 12);
+               break;
        case USB_CHIP_ID:
                ret = control_usb->chip_id;
                break;
index e0394614614afe430df67f98140c8f5af1a135dd..84894be0ed0aa1b37c511b74e683f9e776bb4281 100755 (executable)
@@ -337,7 +337,8 @@ static void usb20host_power_enable(int enable)
 {
        if (0 == enable) {
                /* disable host_drv power */
-               /* do not disable power in default */
+               if (gpio_is_valid(control_usb->host_gpios->gpio))
+                       gpio_set_value(control_usb->host_gpios->gpio, 0);
        } else if (1 == enable) {
                /* enable host_drv power */
                if (gpio_is_valid(control_usb->host_gpios->gpio))
index 70df7c8c6bcd586cb4dfabf755b125a7ed6bdb3a..14b0259379b0920f0d8ffa6586bab6fca1811964 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_USB_EHCI_S5P)    += ehci-s5p.o
 obj-$(CONFIG_USB_EHCI_HCD_SYNOPSYS)    += ehci-h20ahb.o
 obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
 obj-$(CONFIG_USB_EHCI_MSM)     += ehci-msm.o
+obj-$(CONFIG_USB_EHCI_RK)   += ehci-rockchip.o
 
 obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
 obj-$(CONFIG_USB_ISP116X_HCD)  += isp116x-hcd.o
old mode 100644 (file)
new mode 100755 (executable)
index f7e5e14..248bd46
@@ -1273,11 +1273,6 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_hcd_tilegx_driver
 #endif
 
-#ifdef CONFIG_USB_EHCI_RK
-#include "ehci-rockchip.c"
-#define PLATFORM_DRIVER         ehci_rk_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_RKHSIC
 #include "ehci-rkhsic.c"
 #define ROCKCHIP_PLATFORM_DRIVER         ehci_rkhsic_driver
index 207d6f5301f85bc4f1826a0b4652589425d8c0b9..c6f20a235d058ed9d1f60ad9f78e0c75aae0940a 100755 (executable)
 # include <linux/device.h>
 # include <linux/of.h>
 # include <linux/of_platform.h>
-# include "ehci.h"
+# include <linux/usb.h>
+# include <linux/usb/hcd.h>
+# include <linux/usb/otg.h>
+
 # include "../dwc_otg_310/usbdev_rk.h"
+# include "ehci.h"
 
 static int rkehci_status = 1;
-static struct ehci_hcd *g_ehci;
+static struct hc_driver rk_ehci_hc_driver;
+
 struct rk_ehci_hcd {
        struct ehci_hcd *ehci;
        uint8_t host_enabled;
@@ -48,24 +53,6 @@ static struct rkehci_pdata_id rkehci_pdata[] = {
        {},
 };
 
-static void ehci_port_power(struct ehci_hcd *ehci, int is_on)
-{
-       unsigned port;
-
-       if (!HCS_PPC(ehci->hcs_params))
-               return;
-
-       ehci_dbg(ehci, "...power%s ports...\n", is_on ? "up" : "down");
-       for (port = HCS_N_PORTS(ehci->hcs_params); port > 0;)
-               (void)ehci_hub_control(ehci_to_hcd(ehci),
-                                      is_on ? SetPortFeature :
-                                      ClearPortFeature, USB_PORT_FEAT_POWER,
-                                      port--, NULL, 0);
-       /* Flush those writes */
-       ehci_readl(ehci, &ehci->regs->command);
-       msleep(20);
-}
-
 static void rk_ehci_hcd_enable(struct work_struct *work)
 {
        struct rk_ehci_hcd *rk_ehci;
@@ -79,7 +66,7 @@ static void rk_ehci_hcd_enable(struct work_struct *work)
        hcd = ehci_to_hcd(ehci);
 
        if (rk_ehci->host_enabled == rk_ehci->host_setenable) {
-               printk("%s, enable flag %d\n", __func__,
+               EHCI_PRINT("%s, enable flag %d\n", __func__,
                       rk_ehci->host_setenable);
                goto out;
        }
@@ -92,8 +79,7 @@ static void rk_ehci_hcd_enable(struct work_struct *work)
                        goto out;
                }
 
-               printk("%s, disable host controller\n", __func__);
-               ehci_port_power(ehci, 0);
+               EHCI_PRINT("%s, disable host controller\n", __func__);
                usb_remove_hcd(hcd);
 
                /* reset cru and reinitialize EHCI controller */
@@ -110,8 +96,7 @@ static void rk_ehci_hcd_enable(struct work_struct *work)
                if (pldata->phy_suspend)
                        pldata->phy_suspend(pldata, USB_PHY_ENABLED);
                mdelay(5);
-               ehci_port_power(ehci, 1);
-               printk("%s, enable host controller\n", __func__);
+               EHCI_PRINT("%s, enable host controller\n", __func__);
        }
        rk_ehci->host_enabled = rk_ehci->host_setenable;
 
@@ -153,54 +138,6 @@ static void rk_ehci_hcd_connect_detect(unsigned long pdata)
        return;
 }
 
-static struct hc_driver rk_ehci_hc_driver = {
-       .description = hcd_name,
-       .product_desc = "Rockchip On-Chip EHCI Host Controller",
-       .hcd_priv_size = sizeof(struct ehci_hcd),
-
-       /*
-        * generic hardware linkage
-        */
-       .irq = ehci_irq,
-       .flags = HCD_USB2 | HCD_MEMORY,
-
-       .reset = ehci_init,
-       .start = ehci_run,
-
-       .stop = ehci_stop,
-       .shutdown = ehci_shutdown,
-
-       /*
-        * managing i/o requests and associated device resources
-        */
-       .urb_enqueue = ehci_urb_enqueue,
-       .urb_dequeue = ehci_urb_dequeue,
-       .endpoint_disable = ehci_endpoint_disable,
-       .endpoint_reset = ehci_endpoint_reset,
-       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-
-       /*
-        * scheduling support
-        */
-       .get_frame_number = ehci_get_frame,
-
-       /*
-        * root hub support
-        */
-       .hub_status_data = ehci_hub_status_data,
-       .hub_control = ehci_hub_control,
-       .relinquish_port = ehci_relinquish_port,
-       .port_handed_over = ehci_port_handed_over,
-
-       /*
-        * PM support
-        */
-#ifdef CONFIG_PM
-       .bus_suspend = ehci_bus_suspend,
-       .bus_resume = ehci_bus_resume,
-#endif
-};
-
 static ssize_t ehci_power_show(struct device *_dev,
                               struct device_attribute *attr, char *buf)
 {
@@ -213,24 +150,24 @@ static ssize_t ehci_power_store(struct device *_dev,
 {
        uint32_t val = simple_strtoul(buf, NULL, 16);
        struct usb_hcd *hcd = dev_get_drvdata(_dev);
-       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
        struct rkehci_platform_data *pldata = _dev->platform_data;
+       struct rk_ehci_hcd *rk_ehci = (struct rk_ehci_hcd *)hcd_to_ehci(hcd)->priv;
 
-       printk("%s: %d setting to: %d\n", __func__, rkehci_status, val);
+       EHCI_PRINT("%s: %d setting to: %d\n", __func__, rkehci_status, val);
        if (val == rkehci_status)
                goto out;
 
        rkehci_status = val;
        switch (val) {
        case 0: /* power down */
-               ehci_port_power(ehci, 0);
+               rk_ehci->host_enabled = 0;
                msleep(5);
                usb_remove_hcd(hcd);
                break;
        case 1: /*  power on */
                pldata->soft_reset(pldata, RST_POR);
                usb_add_hcd(hcd, hcd->irq, IRQF_DISABLED | IRQF_SHARED);
-               ehci_port_power(ehci, 1);
+               rk_ehci->host_enabled = 2;
                break;
        default:
                break;
@@ -241,54 +178,88 @@ out:
 
 static DEVICE_ATTR(ehci_power, S_IRUGO | S_IWUSR, ehci_power_show,
                   ehci_power_store);
-static ssize_t debug_show(struct device *_dev, struct device_attribute *attr,
+static ssize_t debug_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
+       struct ehci_hcd *ehci = hcd_to_ehci(dev_get_drvdata(dev));
        volatile uint32_t *addr;
 
        EHCI_PRINT("******** EHCI Capability Registers **********\n");
-       addr = &g_ehci->caps->hc_capbase;
-       EHCI_PRINT("HCIVERSION / CAPLENGTH  @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->caps->hcs_params;
-       EHCI_PRINT("HCSPARAMS               @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->caps->hcc_params;
-       EHCI_PRINT("HCCPARAMS               @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
+       addr = &ehci->caps->hc_capbase;
+       EHCI_PRINT("HCIVERSION / CAPLENGTH  @0z%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->caps->hcs_params;
+       EHCI_PRINT("HCSPARAMS               @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->caps->hcc_params;
+       EHCI_PRINT("HCCPARAMS               @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
        EHCI_PRINT("********* EHCI Operational Registers *********\n");
-       addr = &g_ehci->regs->command;
-       EHCI_PRINT("USBCMD                  @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->status;
-       EHCI_PRINT("USBSTS                  @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->intr_enable;
-       EHCI_PRINT("USBINTR                 @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->frame_index;
-       EHCI_PRINT("FRINDEX                 @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->segment;
-       EHCI_PRINT("CTRLDSSEGMENT           @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->frame_list;
-       EHCI_PRINT("PERIODICLISTBASE        @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->async_next;
-       EHCI_PRINT("ASYNCLISTADDR           @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = &g_ehci->regs->configured_flag;
-       EHCI_PRINT("CONFIGFLAG              @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
-       addr = g_ehci->regs->port_status;
-       EHCI_PRINT("PORTSC                  @0x%08x:  0x%08x\n",
-                  (uint32_t) addr, readl_relaxed(addr));
+       addr = &ehci->regs->command;
+       EHCI_PRINT("USBCMD                  @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->status;
+       EHCI_PRINT("USBSTS                  @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->intr_enable;
+       EHCI_PRINT("USBINTR                 @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->frame_index;
+       EHCI_PRINT("FRINDEX                 @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->segment;
+       EHCI_PRINT("CTRLDSSEGMENT           @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->frame_list;
+       EHCI_PRINT("PERIODICLISTBASE        @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->async_next;
+       EHCI_PRINT("ASYNCLISTADDR           @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->configured_flag;
+       EHCI_PRINT("CONFIGFLAG              @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
+       addr = &ehci->regs->port_status[0];
+       EHCI_PRINT("PORTSC                  @0x%p:  0x%08x\n",
+                  addr, readl_relaxed(addr));
        return sprintf(buf, "EHCI Registers Dump\n");
 }
 
 static DEVICE_ATTR(debug_ehci, S_IRUGO, debug_show, NULL);
 
+static int test_sq(struct ehci_hcd *ehci)
+{
+       u32 portc = readl(&ehci->regs->port_status);
+
+       if ((portc & PORT_PE) && !(portc & PORT_SUSPEND)) {
+               writel(PORT_TEST_PKT, &ehci->regs->port_status);
+               EHCI_PRINT("Start packet test\n");
+               return 0;
+
+       } else
+               EHCI_PRINT("Invalid connect status PORTC = 0x%08x\n", portc);
+
+       return -1;
+}
+
+static ssize_t test_sq_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t count)
+
+{
+       struct rkehci_platform_data *pldata = dev->platform_data;
+       struct ehci_hcd *ehci = hcd_to_ehci(dev_get_drvdata(dev));
+
+       if (pldata->phy_status == USB_PHY_SUSPEND) {
+               EHCI_PRINT("Invalid status : SUSPEND\n");
+               return -EBUSY;
+       }
+
+       return (test_sq(ehci)) ? -EBUSY : count;
+}
+
+static DEVICE_ATTR(test_sq, S_IWUSR, NULL, test_sq_store);
+
 static struct of_device_id rk_ehci_of_match[] = {
        {
         .compatible = "rockchip,rk3288_rk_ehci_host",
@@ -307,15 +278,13 @@ static int ehci_rk_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct rkehci_platform_data *pldata;
        int ret;
-       int retval = 0;
-       static u64 usb_dmamask = 0xffffffffUL;
        struct device_node *node = pdev->dev.of_node;
        struct rkehci_pdata_id *p;
        struct rk_ehci_hcd *rk_ehci;
        const struct of_device_id *match =
            of_match_device(of_match_ptr(rk_ehci_of_match), &pdev->dev);
 
-       dev_dbg(&pdev->dev, "ehci_rk proble\n");
+       dev_dbg(&pdev->dev, "ehci_rk probe!\n");
 
        if (match) {
                p = (struct rkehci_pdata_id *)match->data;
@@ -333,10 +302,15 @@ static int ehci_rk_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       dev->dma_mask = &usb_dmamask;
+       if (!pdev->dev.dma_mask)
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+       if (!pdev->dev.coherent_dma_mask)
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+       device_create_file(dev, &dev_attr_ehci_power);
+       device_create_file(dev, &dev_attr_debug_ehci);
+       device_create_file(dev, &dev_attr_test_sq);
 
-       retval = device_create_file(dev, &dev_attr_ehci_power);
-       retval = device_create_file(dev, &dev_attr_debug_ehci);
        hcd =
            usb_create_hcd(&rk_ehci_hc_driver, &pdev->dev,
                           dev_name(&pdev->dev));
@@ -369,7 +343,6 @@ static int ehci_rk_probe(struct platform_device *pdev)
        hcd->rsrc_start = res->start;
        hcd->rsrc_len = resource_size(res);
        hcd->regs = devm_ioremap_resource(dev, res);
-
        if (!hcd->regs) {
                dev_err(&pdev->dev, "ioremap failed\n");
                ret = -ENOMEM;
@@ -386,10 +359,7 @@ static int ehci_rk_probe(struct platform_device *pdev)
        ehci = hcd_to_ehci(hcd);
        ehci->caps = hcd->regs;
        ehci->regs = hcd->regs + 0x10;
-       printk("%s %p %p\n", __func__, ehci->caps, ehci->regs);
-
-       dbg_hcs_params(ehci, "reset");
-       dbg_hcc_params(ehci, "reset");
+       EHCI_PRINT("%s %p %p\n", __func__, ehci->caps, ehci->regs);
 
        ehci->hcs_params = readl(&ehci->caps->hcs_params);
 
@@ -399,10 +369,8 @@ static int ehci_rk_probe(struct platform_device *pdev)
                goto put_hcd;
        }
 
-       g_ehci = ehci;
+       rk_ehci = (struct rk_ehci_hcd *)hcd_to_ehci(hcd)->priv;
 
-       rk_ehci = devm_kzalloc(&pdev->dev, sizeof(struct rk_ehci_hcd),
-                              GFP_KERNEL);
        if (!rk_ehci) {
                ret = -ENOMEM;
                goto put_hcd;
@@ -418,8 +386,6 @@ static int ehci_rk_probe(struct platform_device *pdev)
        mod_timer(&rk_ehci->connect_detect_timer, jiffies + (HZ << 1));
        INIT_DELAYED_WORK(&rk_ehci->host_enable_work, rk_ehci_hcd_enable);
 
-       ehci_port_power(ehci, 0);
-
        if (pldata->phy_suspend) {
                if (pldata->phy_status == USB_PHY_ENABLED) {
                        pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
@@ -431,7 +397,7 @@ static int ehci_rk_probe(struct platform_device *pdev)
                }
        }
 
-       printk("%s ok\n", __func__);
+       EHCI_PRINT("%s ok\n", __func__);
 
        return 0;
 
@@ -446,6 +412,11 @@ put_hcd:
 static int ehci_rk_remove(struct platform_device *pdev)
 {
        struct usb_hcd *hcd = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
+
+       device_remove_file(dev, &dev_attr_ehci_power);
+       device_remove_file(dev, &dev_attr_debug_ehci);
+       device_remove_file(dev, &dev_attr_test_sq);
 
        usb_put_hcd(hcd);
 
@@ -485,7 +456,7 @@ static const struct dev_pm_ops ehci_rk_dev_pm_ops = {
        .resume = ehci_rk_pm_resume,
 };
 
-static struct platform_driver ehci_rk_driver = {
+static struct platform_driver rk_ehci_driver = {
        .probe = ehci_rk_probe,
        .remove = ehci_rk_remove,
        .driver = {
@@ -496,3 +467,26 @@ static struct platform_driver ehci_rk_driver = {
 #endif
                   },
 };
+
+static const struct ehci_driver_overrides rk_overrides __initdata = {
+       .extra_priv_size = sizeof(struct rk_ehci_hcd),
+};
+
+static int __init ehci_rk_init(void)
+{
+       if (usb_disabled())
+               return -ENODEV;
+
+       ehci_init_driver(&rk_ehci_hc_driver, &rk_overrides);
+       return platform_driver_register(&rk_ehci_driver);
+}
+module_init(ehci_rk_init);
+
+static void __exit ehci_rk_cleanup(void)
+{
+       platform_driver_unregister(&rk_ehci_driver);
+}
+module_exit(ehci_rk_cleanup);
+MODULE_AUTHOR("Rockchip");
+MODULE_LICENSE("GPL v2");
+
index f6d1888637e3e3c698094601be6989e88e7b11b6..8c48563e0dae334d555184e07f58293315b38333 100755 (executable)
@@ -513,6 +513,8 @@ static void rk3036_hdmi_shutdown(struct platform_device *pdev)
                if (hdmi_drv->irq)
                        disable_irq(hdmi_drv->irq);
                mutex_unlock(&hdmi_drv->enable_mutex);
+               if (hdmi_drv->hotplug == HDMI_HPD_ACTIVED)
+                       rk3036_hdmi_control_output(hdmi_drv, 0);
        }
        hdmi_dbg(hdmi_drv->dev, "rk3036 hdmi shut down.\n");
 }
index b3419b930148859368a52853bdde62cc4c9dbd61..7c7b2770468bd1a4142025657f3754548c8ad4ea 100755 (executable)
@@ -51,9 +51,16 @@ static void rk3036_hdmi_av_mute(struct hdmi *hdmi_drv, bool enable)
        struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
                                                       struct rk_hdmi_device,
                                                       driver);
-
-       hdmi_writel(hdmi_dev, AV_MUTE,
-                   v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable));
+       if (enable) {
+               hdmi_msk_reg(hdmi_dev, AV_MUTE,
+                            m_AVMUTE_CLEAR | m_AVMUTE_ENABLE,
+                            v_AVMUTE_CLEAR(0) | v_AVMUTE_ENABLE(1));
+       } else {
+               hdmi_msk_reg(hdmi_dev, AV_MUTE,
+                            m_AVMUTE_CLEAR | m_AVMUTE_ENABLE,
+                            v_AVMUTE_CLEAR(1) | v_AVMUTE_ENABLE(0));
+       }
+       hdmi_writel(hdmi_dev, PACKET_SEND_AUTO, m_PACKET_GCP_EN);
 }
 
 static void rk3036_hdmi_sys_power(struct hdmi *hdmi_drv, bool enable)
@@ -100,14 +107,12 @@ static void rk3036_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
                hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f);
                hdmi_writel(hdmi_dev, 0xce, 0x00);
                hdmi_writel(hdmi_dev, 0xce, 0x01);
-               rk3036_hdmi_av_mute(hdmi_drv, 1);
                rk3036_hdmi_sys_power(hdmi_drv, true);
                break;
        case LOWER_PWR:
                hdmi_dbg(hdmi_drv->dev,
                         "%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n",
                         __func__, hdmi_drv->pwr_mode, mode);
-               rk3036_hdmi_av_mute(hdmi_drv, 0);
                rk3036_hdmi_sys_power(hdmi_drv, false);
                hdmi_writel(hdmi_dev, PHY_DRIVER, 0x00);
                hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x00);
@@ -526,11 +531,13 @@ static int rk3036_hdmi_config_video(struct hdmi *hdmi_drv,
                        vpara->output_color = VIDEO_OUTPUT_RGB444;*/
        }
 
-       if (hdmi_drv->pwr_mode == LOWER_PWR)
+/*     if (hdmi_drv->pwr_mode == LOWER_PWR)
                rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
-
+*/
        /* Disable video and audio output */
-       hdmi_writel(hdmi_dev, AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
+       hdmi_msk_reg(hdmi_dev, AV_MUTE,
+                    m_AUDIO_MUTE | m_VIDEO_BLACK,
+                    v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
 
        /* Input video mode is SDR RGB24bit, Data enable signal from external */
        hdmi_writel(hdmi_dev, VIDEO_CONTRL1,
@@ -601,7 +608,6 @@ static int rk3036_hdmi_config_video(struct hdmi *hdmi_drv,
        value = mode->vsync_len;
        hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF);
 #endif
-
        if (vpara->output_mode == OUTPUT_HDMI) {
                rk3036_hdmi_config_avi(hdmi_drv, vpara->vic,
                                        vpara->output_color);
@@ -740,11 +746,7 @@ void rk3036_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
        if (enable) {
                if (hdmi_drv->pwr_mode == LOWER_PWR)
                        rk3036_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
-               hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus);
-               if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
-                       hdmi_writel(hdmi_dev, AV_MUTE,
-                                   v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
-               }
+
                rk3036_hdmi_sys_power(hdmi_drv, true);
                rk3036_hdmi_sys_power(hdmi_drv, false);
                delay100us();
@@ -752,9 +754,21 @@ void rk3036_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
                hdmi_writel(hdmi_dev, 0xce, 0x00);
                delay100us();
                hdmi_writel(hdmi_dev, 0xce, 0x01);
+
+               hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus);
+               if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
+                       hdmi_msk_reg(hdmi_dev, AV_MUTE,
+                                    m_AUDIO_MUTE | m_VIDEO_BLACK,
+                                    v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
+               }
+               rk3036_hdmi_av_mute(hdmi_drv, 0);
        } else {
-               hdmi_writel(hdmi_dev, AV_MUTE,
-                           v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
+               hdmi_msk_reg(hdmi_dev, AV_MUTE,
+                            m_AUDIO_MUTE | m_VIDEO_BLACK,
+                            v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
+               rk3036_hdmi_av_mute(hdmi_drv, 1);
+               msleep(100);
+               rk3036_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
        }
 }
 
index 7f70adbb11044c9d57a7d31da8be1cbb887e4c9c..20b326653e6c44589209d0ff92d26275a72137fe 100755 (executable)
@@ -124,6 +124,8 @@ enum {
 #define m_AVMUTE_ENABLE                (1 << 6)
 #define m_AUDIO_MUTE           (1 << 1)
 #define m_VIDEO_BLACK          (1 << 0)
+#define v_AVMUTE_CLEAR(n)      (n << 7)
+#define v_AVMUTE_ENABLE(n)     (n << 6)
 #define v_AUDIO_MUTE(n)                (n << 1)
 #define v_VIDEO_MUTE(n)                (n << 0)
 
@@ -230,6 +232,10 @@ enum {
 #define EDID_FIFO_OFFSET               0x4f
 #define EDID_FIFO_ADDR                 0x50
 
+
+#define PACKET_SEND_MANUAL             0x9c
+#define PACKET_SEND_AUTO               0x9d
+       #define m_PACKET_GCP_EN         (1 << 7)
 /* CONTROL_PACKET_BUF_INDEX */
 #define CONTROL_PACKET_BUF_INDEX       0x9f
 enum {
index b7d96ffd3373b94f80e196a67348802999b09275..1f68cc909bb85ab242a926ba49660b602beb119a 100755 (executable)
@@ -97,7 +97,8 @@ void hdmi_sys_remove(struct hdmi *hdmi)
        kobject_uevent_env(&hdmi->ddev->dev->kobj, KOBJ_REMOVE, envp);
 
 #ifdef CONFIG_SWITCH
-       if (audio_need)
+       if (audio_need ||
+           rk_fb_get_display_policy() == DISPLAY_POLICY_BOX)
                switch_set_state(&(hdmi->switch_hdmi), 0);
 #endif
        rockchip_clear_system_status(SYS_STATUS_HDMI);
@@ -129,6 +130,7 @@ static int hdmi_process_command(struct hdmi *hdmi)
                        if (!hdmi->enable || hdmi->suspend) {
                                if (hdmi->hotplug != HDMI_HPD_REMOVED) {
                                        hdmi->hotplug = HDMI_HPD_REMOVED;
+                                       hdmi->control_output(hdmi, HDMI_DISABLE);
                                        hdmi_sys_remove(hdmi);
                                }
                                hdmi->state = HDMI_SLEEP;
@@ -157,6 +159,8 @@ static int hdmi_process_command(struct hdmi *hdmi)
                default:
                        if (state > SYSTEM_CONFIG) {
                                state = SYSTEM_CONFIG;
+                               hdmi->control_output(hdmi, HDMI_DISABLE);
+                               msleep(2000);
                        } else {
                                if (hdmi->wait == 1) {
                                        complete(&hdmi->complete);
@@ -221,7 +225,7 @@ void hdmi_work(struct work_struct *work)
                hdmi->hotplug = hotplug;
        } else if (hotplug == HDMI_HPD_REMOVED) {
                hdmi_sys_sleep(hdmi);
-       }else if (hotplug == HDMI_HPD_ACTIVED) {
+       } else if (hotplug == HDMI_HPD_ACTIVED) {
                if (hdmi->uboot_logo) {
                        if (hdmi->insert)
                                hdmi->insert(hdmi);
@@ -249,8 +253,10 @@ void hdmi_work(struct work_struct *work)
                                         hdmi->edid.base_audio_support,
                                         hdmi->edid.sink_hdmi);
 #ifdef CONFIG_SWITCH
-                               if (hdmi->edid.base_audio_support == 1 &&
-                                   hdmi->edid.sink_hdmi == 1)
+                               if ((hdmi->edid.base_audio_support == 1 &&
+                                    hdmi->edid.sink_hdmi == 1) ||
+                                    (rk_fb_get_display_policy() ==
+                                     DISPLAY_POLICY_BOX))
                                        switch_set_state(&(hdmi->switch_hdmi),
                                                         1);
 #endif
index c278bb51d82f4910b91836e1091d481a5e074e16..aeb0b353af5b678a91aebe0b3efa277a180b0350 100755 (executable)
@@ -349,9 +349,9 @@ static void lcdc_layer_enable(struct lcdc_device *lcdc_dev,
                                         "wakeup from standby!\n");
                                lcdc_dev->standby = 0;
                        }
-                       lcdc_dev->atv_layer_cnt++;
-               } else if ((lcdc_dev->atv_layer_cnt > 0) && (!open)) {
-                       lcdc_dev->atv_layer_cnt--;
+                       lcdc_dev->atv_layer_cnt |= (1 << win_id);
+               } else if ((lcdc_dev->atv_layer_cnt & (1 << win_id)) && (!open)) {
+                       lcdc_dev->atv_layer_cnt &= ~(1 << win_id);
                }
                lcdc_dev->driver.win[win_id]->state = open;
                if (!open) {
index 3b5619b44a27c19607b7e9fb44dac2c24c893cd2..a7076a3d86cf2d44ff1c7f294e0215c8250124c3 100755 (executable)
@@ -322,8 +322,14 @@ static int rk312x_lcdc_alpha_cfg(struct lcdc_device *lcdc_dev)
 
                mask = m_WIN1_ALPHA_MODE |
                                m_ALPHA_MODE_SEL0 | m_ALPHA_MODE_SEL1;
-               val = v_WIN1_ALPHA_MODE(1) |
-                               v_ALPHA_MODE_SEL0(1) | v_ALPHA_MODE_SEL1(0);
+               if (lcdc_dev->driver.overlay_mode == VOP_YUV_DOMAIN)
+                       val = v_WIN0_ALPHA_MODE(1) |
+                             v_ALPHA_MODE_SEL0(0) |
+                             v_ALPHA_MODE_SEL1(0);
+               else
+                       val = v_WIN1_ALPHA_MODE(1) |
+                             v_ALPHA_MODE_SEL0(1) |
+                             v_ALPHA_MODE_SEL1(0);
                lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val);
                /*this vop bg layer not support yuv domain overlay,so bg val
                have to set 0x800a80 equeal to 0x000000 at rgb domian,after
@@ -657,7 +663,8 @@ static int rk312x_lcdc_set_lut(struct rk_lcdc_driver *dev_drv)
        return 0;
 }
 
-static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
+static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv,
+                                   int reset_rate)
 {
 #ifdef CONFIG_RK_FPGA
        return 0;
@@ -667,7 +674,8 @@ static int rk312x_lcdc_set_dclk(struct rk_lcdc_driver *dev_drv)
            container_of(dev_drv, struct lcdc_device, driver);
        struct rk_screen *screen = dev_drv->cur_screen;
 
-       ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
+       if (reset_rate)
+               ret = clk_set_rate(lcdc_dev->dclk, screen->mode.pixclock);
        if (ret)
                dev_err(dev_drv->dev, "set lcdc%d dclk failed\n", lcdc_dev->id);
        lcdc_dev->pixclock =
@@ -725,8 +733,12 @@ static int rk312x_lcdc_pre_init(struct rk_lcdc_driver *dev_drv)
                lcdc_cfg_done(lcdc_dev);
                while(lcdc_readl(lcdc_dev, SYS_CTRL) & (m_WIN0_EN | m_WIN1_EN));
        }*/
-       if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR))
-               dev_drv->ops->open_bcsh(dev_drv, 1);
+       if ((dev_drv->ops->open_bcsh) && (dev_drv->output_color == COLOR_YCBCR)) {
+               if (support_uboot_display())
+                       dev_drv->bcsh_init_status = 1;
+               else
+                       dev_drv->ops->open_bcsh(dev_drv, 1);
+       }
        lcdc_dev->pre_init = true;
 
        return 0;
@@ -1017,6 +1029,7 @@ static int rk312x_lcdc_set_scaler(struct rk_lcdc_driver *dev_drv,
 static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
                                    struct lcdc_device *lcdc_dev)
 {
+       u32 bcsh_ctrl;
        if (dev_drv->overlay_mode == VOP_YUV_DOMAIN) {
                if (dev_drv->output_color == COLOR_YCBCR)/* bypass */
                        lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
@@ -1030,11 +1043,18 @@ static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv,
                             v_BCSH_Y2R_CSC_MODE(VOP_Y2R_CSC_MPEG) |
                             v_BCSH_R2Y_EN(0));
        } else {        /* overlay_mode=VOP_RGB_DOMAIN */
-               if (dev_drv->output_color == COLOR_RGB) /* bypass */
-                       lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
-                                    m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
-                                    v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
-               else    /* RGB2YUV */
+               if (dev_drv->output_color == COLOR_RGB) {
+                       /* bypass */
+                       bcsh_ctrl = lcdc_readl(lcdc_dev, BCSH_CTRL);
+                       if ((bcsh_ctrl&m_BCSH_EN) == 1)/*bcsh enabled*/
+                               lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                       m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
+                                       v_BCSH_R2Y_EN(1) | v_BCSH_Y2R_EN(1));
+                       else/*bcsh disabled*/
+                               lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
+                                       m_BCSH_R2Y_EN | m_BCSH_Y2R_EN,
+                                       v_BCSH_R2Y_EN(0) | v_BCSH_Y2R_EN(0));
+               } else  /* RGB2YUV */
                        lcdc_msk_reg(lcdc_dev, BCSH_CTRL,
                                     m_BCSH_R2Y_EN |
                                        m_BCSH_R2Y_CSC_MODE | m_BCSH_Y2R_EN,
@@ -1167,7 +1187,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                        break;
                }
                if (lcdc_dev->soc_type == VOP_RK312X) {
-                       switch (screen->face) {
+                       switch (dev_drv->screen0->face) {
                        case OUT_P565:
                                face = OUT_P565;
                                mask = m_DITHER_DOWN_EN |
@@ -1335,7 +1355,7 @@ static int rk312x_load_screen(struct rk_lcdc_driver *dev_drv, bool initscreen)
                }
        }
        spin_unlock(&lcdc_dev->reg_lock);
-       rk312x_lcdc_set_dclk(dev_drv);
+       rk312x_lcdc_set_dclk(dev_drv, 1);
        lcdc_msk_reg(lcdc_dev, SYS_CTRL, m_LCDC_STANDBY, v_LCDC_STANDBY(0));
        lcdc_cfg_done(lcdc_dev);
        if (dev_drv->trsm_ops && dev_drv->trsm_ops->enable)
@@ -1379,7 +1399,7 @@ static int rk312x_lcdc_open(struct rk_lcdc_driver *dev_drv, int win_id,
                /*if (dev_drv->iommu_enabled)
                        rk312x_lcdc_mmu_en(dev_drv);*/
                if ((support_uboot_display() && (lcdc_dev->prop == PRMRY))) {
-                       /*rk312x_lcdc_set_dclk(dev_drv);*/
+                       rk312x_lcdc_set_dclk(dev_drv, 0);
                        rk312x_lcdc_enable_irq(dev_drv);
                } else {
                        rk312x_load_screen(dev_drv, 1);
@@ -1996,7 +2016,10 @@ static int rk312x_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
        u32 mask, val;
-
+       if (dev_drv->bcsh_init_status && open) {
+               dev_drv->bcsh_init_status = 0;
+               return 0;
+       }
        spin_lock(&lcdc_dev->reg_lock);
        if (lcdc_dev->clk_on) {
                rk312x_lcdc_select_bcsh(dev_drv,  lcdc_dev);
index ba279f51555991adc8a45eb92d3fc1dc240af6b7..78ccdba29fffb7a50b451315740bb6b7af5ed6b3 100755 (executable)
@@ -29,6 +29,7 @@
 #include <linux/rk_fb.h>
 #include <linux/linux_logo.h>
 #include <linux/dma-mapping.h>
+#include <linux/regulator/consumer.h>
 
 #if defined(CONFIG_RK_HDMI)
 #include "hdmi/rk_hdmi.h"
@@ -76,6 +77,18 @@ int support_uboot_display(void)
        return uboot_logo_on;
 }
 
+int rk_fb_get_display_policy(void)
+{
+       struct rk_fb *rk_fb;
+
+       if (fb_pdev) {
+               rk_fb = platform_get_drvdata(fb_pdev);
+               return rk_fb->disp_policy;
+       } else {
+               return DISPLAY_POLICY_SDK;
+       }
+}
+
 int rk_fb_trsm_ops_register(struct rk_fb_trsm_ops *ops, int type)
 {
        switch (type) {
@@ -264,11 +277,22 @@ int rk_disp_pwr_ctr_parse_dt(struct rk_lcdc_driver *dev_drv)
 
                        } else {
                                pwr_ctr->pwr_ctr.type = REGULATOR;
-
+                               pwr_ctr->pwr_ctr.rgl_name = NULL;
+                               ret = of_property_read_string(child, "rockchip,regulator_name",
+                                                            &(pwr_ctr->pwr_ctr.rgl_name));
+                               if (ret || IS_ERR_OR_NULL(pwr_ctr->pwr_ctr.rgl_name))
+                                       dev_err(dev_drv->dev, "get regulator name failed!\n");
+                               if (!of_property_read_u32(child, "rockchip,regulator_voltage", &val))
+                                       pwr_ctr->pwr_ctr.volt = val;
+                               else
+                                       pwr_ctr->pwr_ctr.volt = 0;
                        }
                };
-               of_property_read_u32(child, "rockchip,delay", &val);
-               pwr_ctr->pwr_ctr.delay = val;
+
+               if (!of_property_read_u32(child, "rockchip,delay", &val))
+                       pwr_ctr->pwr_ctr.delay = val;
+               else
+                       pwr_ctr->pwr_ctr.delay = 0;
                list_add_tail(&pwr_ctr->list, &dev_drv->pwrlist_head);
        }
 
@@ -300,6 +324,9 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
        struct list_head *pos;
        struct rk_disp_pwr_ctr_list *pwr_ctr_list;
        struct pwr_ctr *pwr_ctr;
+       struct regulator *regulator_lcd = NULL;
+       int count = 10;
+
        if (list_empty(&dev_drv->pwrlist_head))
                return 0;
        list_for_each(pos, &dev_drv->pwrlist_head) {
@@ -309,6 +336,27 @@ int rk_disp_pwr_enable(struct rk_lcdc_driver *dev_drv)
                if (pwr_ctr->type == GPIO) {
                        gpio_direction_output(pwr_ctr->gpio, pwr_ctr->atv_val);
                        mdelay(pwr_ctr->delay);
+               } else if (pwr_ctr->type == REGULATOR) {
+                       if (pwr_ctr->rgl_name)
+                               regulator_lcd = regulator_get(NULL, pwr_ctr->rgl_name);
+                       if (regulator_lcd == NULL) {
+                               dev_err(dev_drv->dev,
+                                       "%s: regulator get failed,regulator name:%s\n",
+                                       __func__, pwr_ctr->rgl_name);
+                               continue;
+                       }
+                       regulator_set_voltage(regulator_lcd, pwr_ctr->volt, pwr_ctr->volt);
+                       while (!regulator_is_enabled(regulator_lcd)) {
+                               if (regulator_enable(regulator_lcd) == 0 || count == 0)
+                                       break;
+                               else
+                                       dev_err(dev_drv->dev,
+                                               "regulator_enable failed,count=%d\n",
+                                               count);
+                               count--;
+                       }
+                       regulator_put(regulator_lcd);
+                       msleep(pwr_ctr->delay);
                }
        }
 
@@ -320,14 +368,37 @@ int rk_disp_pwr_disable(struct rk_lcdc_driver *dev_drv)
        struct list_head *pos;
        struct rk_disp_pwr_ctr_list *pwr_ctr_list;
        struct pwr_ctr *pwr_ctr;
+       struct regulator *regulator_lcd = NULL;
+       int count = 10;
+
        if (list_empty(&dev_drv->pwrlist_head))
                return 0;
        list_for_each(pos, &dev_drv->pwrlist_head) {
                pwr_ctr_list = list_entry(pos, struct rk_disp_pwr_ctr_list,
                                          list);
                pwr_ctr = &pwr_ctr_list->pwr_ctr;
-               if (pwr_ctr->type == GPIO)
+               if (pwr_ctr->type == GPIO) {
                        gpio_set_value(pwr_ctr->gpio, !pwr_ctr->atv_val);
+               } else if (pwr_ctr->type == REGULATOR) {
+                       if (pwr_ctr->rgl_name)
+                               regulator_lcd = regulator_get(NULL, pwr_ctr->rgl_name);
+                       if (regulator_lcd == NULL) {
+                               dev_err(dev_drv->dev,
+                                       "%s: regulator get failed,regulator name:%s\n",
+                                       __func__, pwr_ctr->rgl_name);
+                               continue;
+                       }
+                       while (regulator_is_enabled(regulator_lcd) > 0) {
+                               if (regulator_disable(regulator_lcd) == 0 || count == 0)
+                                       break;
+                               else
+                                       dev_err(dev_drv->dev,
+                                               "regulator_disable failed,count=%d\n",
+                                               count);
+                               count--;
+                       }
+                       regulator_put(regulator_lcd);
+               }
        }
        return 0;
 }
@@ -1770,6 +1841,25 @@ static void rk_fb_update_win(struct rk_lcdc_driver *dev_drv,
                                                 reg_win_data->reg_area_data[i].ysize *
                                                 cur_screen->mode.yres /
                                                 primary_screen.mode.yres;
+
+                                       /* recalc display size if set hdmi scaler when at ONE_DUAL mode */
+                                       if (inf->disp_mode == ONE_DUAL && hdmi_switch_complete) {
+                                               if (cur_screen->xsize > 0 &&
+                                                   cur_screen->xsize <= cur_screen->mode.xres) {
+                                                       win->area[i].xpos =
+                                                               ((cur_screen->mode.xres - cur_screen->xsize) >> 1) +
+                                                               cur_screen->xsize * win->area[i].xpos / cur_screen->mode.xres;
+                                                       win->area[i].xsize =
+                                                               win->area[i].xsize * cur_screen->xsize / cur_screen->mode.xres;
+                                               }
+                                               if (cur_screen->ysize > 0 && cur_screen->ysize <= cur_screen->mode.yres) {
+                                                       win->area[i].ypos =
+                                                               ((cur_screen->mode.yres - cur_screen->ysize) >> 1) +
+                                                               cur_screen->ysize * win->area[i].ypos / cur_screen->mode.yres;
+                                                       win->area[i].ysize =
+                                                               win->area[i].ysize * cur_screen->ysize / cur_screen->mode.yres;
+                                               }
+                                       }
                                 }
                                win->area[i].xact =
                                    reg_win_data->reg_area_data[i].xact;
@@ -1842,7 +1932,8 @@ static void rk_fb_update_reg(struct rk_lcdc_driver *dev_drv,
                win_data = rk_fb_get_win_data(regs, i);
                if (win_data) {
                        if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
-                            win_data->data_format == YUV420)
+                           (win_data->data_format == YUV420 ||
+                            win_data->data_format == YUV420_A))
                                continue;
                        rk_fb_update_win(dev_drv, win, win_data);
                        win->state = 1;
@@ -1907,12 +1998,26 @@ ext_win_exit:
                timeout = wait_event_interruptible_timeout(dev_drv->vsync_info.wait,
                                ktime_compare(dev_drv->vsync_info.timestamp, timestamp) > 0,
                                msecs_to_jiffies(25));
+               if ((rk_fb->disp_mode == DUAL) &&
+                   (hdmi_get_hotplug() == HDMI_HPD_ACTIVED) &&
+                   hdmi_switch_complete) {
+                       /*
+                        * If dual output, we need make sure the extend display
+                        * cfg take effect before release fence.
+                        */
+                       ext_dev_drv = rk_get_extend_lcdc_drv();
+                       timeout = wait_event_interruptible_timeout(ext_dev_drv->vsync_info.wait,
+                                       ktime_compare(ext_dev_drv->vsync_info.timestamp, timestamp) > 0,
+                                       msecs_to_jiffies(25));
+               }
+
                dev_drv->ops->get_dsp_addr(dev_drv, dsp_addr);
                wait_for_vsync = false;
                for (i = 0; i < dev_drv->lcdc_win_num; i++) {
                        if (dev_drv->win[i]->state == 1) {
                                if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
                                    (dev_drv->win[i]->format == YUV420 ||
+                                    dev_drv->win[i]->format == YUV420_A ||
                                     !strcmp(dev_drv->win[i]->name, "hwc"))) {
                                        continue;
                                } else {
@@ -1921,8 +2026,10 @@ ext_win_exit:
                                            dev_drv->win[i]->area[0].y_offset;
                                        u32 reg_start = dsp_addr[i];
 
-                                       if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
-                                           new_start==0x0)
+                                       if ((rk_fb->disp_policy ==
+                                            DISPLAY_POLICY_BOX) &&
+                                           (new_start == 0x0 ||
+                                            dev_drv->suspend_flag))
                                                continue;
                                        if (unlikely(new_start != reg_start)) {
                                                wait_for_vsync = true;
@@ -2243,6 +2350,12 @@ static int rk_fb_set_win_buffer(struct fb_info *info,
                        }
                }
        }
+
+       /* record buffer information for rk_fb_disp_scale to prevent fence timeout
+        * because rk_fb_disp_scale will call function info->fbops->fb_set_par(info);
+        */
+       info->var.yoffset = yoffset;
+       info->var.xoffset = xoffset;
        return 0;
 }
 
@@ -3153,6 +3266,9 @@ static int rk_fb_set_par(struct fb_info *info)
                         (win->format == ABGR888)) ? 1 : 0;
        win->g_alpha_val = 0;
 
+       if (rk_fb->disp_policy == DISPLAY_POLICY_BOX &&
+           (win->format == YUV420 || win->format == YUV420_A))
+           win->state = 1;
        if (rk_fb->disp_mode == DUAL) {
                if (extend_win->state && hdmi_switch_complete) {
                        if (info != extend_info) {
index d9d35d2650e3712823a7723be252cea6651dcde3..d9e4352c0ab0fda81c64d4fba859158d3a333751 100755 (executable)
@@ -285,7 +285,8 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
        struct list_head *pos;
        struct property *prop;
        enum of_gpio_flags flags;
-       u32 value, i, debug, gpio, ret, cmds[25], length;
+       u32 value, i, debug, gpio, ret, length;
+       u32 cmds[sizeof(dcs_cmd->dcs_cmd.cmds) / sizeof(u32)];
 
        memset(screen, 0, sizeof(*screen));
 
@@ -426,6 +427,11 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
                                return -EINVAL;
                        }
 
+                       if (length > sizeof(dcs_cmd->dcs_cmd.cmds)) {
+                               /* the length can not longer than the cmds arrary in struct dcs_cmds */
+                               MIPI_SCREEN_DBG("error: the dcs cmd length is %d, but the max length supported is %d\n",
+                                               length / sizeof(u32), sizeof(dcs_cmd->dcs_cmd.cmds) / sizeof(32));
+                       }
                        MIPI_SCREEN_DBG("\n childnode->name =%s:length=%d\n", childnode->name, (length / sizeof(u32)));
 
                        ret = of_property_read_u32_array(childnode,  "rockchip,cmd", cmds, (length / sizeof(u32)));
@@ -434,7 +440,8 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
                                return ret;
                        } else {
                                dcs_cmd->dcs_cmd.cmd_len =  length / sizeof(u32);
-                               for (i = 0; i < (length / sizeof(u32)); i++) {
+                               for (i = 0; (i < (length / sizeof(u32))) && (i < (sizeof(dcs_cmd->dcs_cmd.cmds) / sizeof(u32))); i++) {
+                                       /* avoid the array out of range */
                                        MIPI_SCREEN_DBG("cmd[%d]=%02x£¬", i+1, cmds[i]);
                                        dcs_cmd->dcs_cmd.cmds[i] = cmds[i];
                                }
index e2f0cbe5a3b131be137a97f620770fd03c7ed003..a7f5bd1cb8e65a75f61ae1584e197e827bc6facb 100755 (executable)
@@ -147,7 +147,7 @@ static int rk32_dsi_set_bits(struct dsi *dsi, u32 data, u32 reg)
        val |= (data & bits) << offset;
        rk32_dsi_write_reg(dsi, reg_addr, &val);
 
-       if (data > bits) {
+       if(data > ((1 << (bits+1)) - 1)) {
                MIPI_TRACE("%s error reg_addr:0x%04x, offset:%d, bits:0x%04x, value:0x%04x\n",
                                __func__, reg_addr, offset, bits, data);
        }
@@ -877,10 +877,11 @@ static int rk32_mipi_dsi_host_init(struct dsi *dsi)
        rk32_dsi_set_bits(dsi, 1000, lprx_to_cnt);
        rk32_dsi_set_bits(dsi, 100, phy_stop_wait_time);
 
-       /*
-       rk32_dsi_set_bits(dsi, 0, outvact_lpcmd_time);
-       rk32_dsi_set_bits(dsi, 0, invact_lpcmd_time);
-       */
+       /* enable send command in low power mode */
+       rk32_dsi_set_bits(dsi, 4, outvact_lpcmd_time);
+       rk32_dsi_set_bits(dsi, 4, invact_lpcmd_time);
+       rk32_dsi_set_bits(dsi, 1, lp_cmd_en);
+       
        rk32_dsi_set_bits(dsi, 20, phy_hs2lp_time);
        rk32_dsi_set_bits(dsi, 16, phy_lp2hs_time);
        /*
@@ -899,6 +900,9 @@ static int rk32_mipi_dsi_host_init(struct dsi *dsi)
        /* rk32_dsi_set_bits(dsi, 1, frame_bta_ack_en); */
        rk32_dsi_set_bits(dsi, 1, phy_enableclk);
        rk32_dsi_set_bits(dsi, 0, phy_tx_triggers);
+       
+       /* enable non-continued function */
+       rk32_dsi_set_bits(dsi, 1, auto_clklane_ctrl);
        /*
        rk32_dsi_set_bits(dsi, 1, phy_txexitulpslan);
        rk32_dsi_set_bits(dsi, 1, phy_txexitulpsclk);
@@ -1120,8 +1124,20 @@ static int rk32_mipi_dsi_send_packet(void *arg, unsigned char cmds[], u32 length
                data = (dsi->vid << 6) | type;
                data |= (liTmp & 0xffff) << 8;
                break;
-       case DTYPE_GEN_SWRITE_2P:
+       case DTYPE_GEN_SWRITE_2P: /* one command and one parameter */
                rk32_dsi_set_bits(dsi, regs[0], gen_sw_2p_tx);
+               if (liTmp <= 2) {
+                       /* It is used for normal Generic Short WRITE Packet with 2 parameters. */
+                       data = type;
+                       data |= regs[2] << 8;   /* dcs command */
+                       data |= regs[3] << 16;  /* parameter of command */
+                       break;  
+               }
+
+               /* The below is used for Generic Short WRITE Packet with 2 parameters
+                * that more than 2 parameters. Though it is illegal dcs command, we can't
+                * make sure the users do not send that command.
+                */
                for (i = 0; i < liTmp; i++) {
                        regs[i] = regs[i+2];
                }
@@ -1141,16 +1157,14 @@ static int rk32_mipi_dsi_send_packet(void *arg, unsigned char cmds[], u32 length
                data = type;
                data |= (liTmp & 0xffff) << 8;
                break;
-       case DTYPE_GEN_SWRITE_1P:
+       case DTYPE_GEN_SWRITE_1P: /* one command without parameter */
                rk32_dsi_set_bits(dsi, regs[0], gen_sw_1p_tx);
                data = type;
                data |= regs[2] << 8;
-               data |= regs[3] << 16;
                break;
-       case DTYPE_GEN_SWRITE_0P:
+       case DTYPE_GEN_SWRITE_0P: /* nop packet without command and parameter */
                rk32_dsi_set_bits(dsi, regs[0], gen_sw_0p_tx);
                data =  type;
-               data |= regs[2] << 8;
                break;
        default:
                printk("0x%x:this type not suppport!\n", type);
@@ -1353,25 +1367,23 @@ reg_proc_write_exit:
        return count;
 }
 
-int reg_proc_read(struct file *file, char __user *buff, size_t count,
-                                       loff_t *offp)
+int reg_proc_read(struct seq_file *s, void *v)
 {
        int i = 0;
        u32 val = 0;
-
+       struct dsi *dsi = s->private;
+       
        for (i = VERSION; i < (VERSION + (0xdc << 16)); i += 4<<16) {
-               val = rk32_dsi_get_bits(dsi0, i);
-               MIPI_TRACE("%04x: %08x\n", i>>16, val);
-               msleep(1);
+               val = rk32_dsi_get_bits(dsi, i);
+               seq_printf(s, "%04x: %08x\n", i>>16, val);
        }
-
-       MIPI_TRACE("\n");
-       return -1;
+       return 0;
 }
-
-int reg_proc_open(struct inode *inode, struct file *file)
+static int reg_proc_open(struct inode *inode, struct file *file)
 {
-       return 0;
+       struct dsi *dsi = inode->i_private;
+
+       return single_open(file, reg_proc_read, dsi);
 }
 
 int reg_proc_close(struct inode *inode, struct file *file)
@@ -1384,7 +1396,7 @@ struct file_operations reg_proc_fops = {
        .open = reg_proc_open,
        .release = reg_proc_close,
        .write = reg_proc_write,
-       .read = reg_proc_read,
+       .read = seq_read,
 };
 
 int reg_proc_write1(struct file *file, const char __user *buff, size_t count, loff_t *offp)
@@ -1484,27 +1496,6 @@ reg_proc_write_exit:
        return count;
 }
 
-int reg_proc_read1(struct file *file, char __user *buff, size_t count,
-                                       loff_t *offp)
-{
-       int i = 0;
-       u32 val = 0;
-
-       for (i = VERSION; i < (VERSION + (0xdc<<16)); i += 4<<16) {
-               val = rk32_dsi_get_bits(dsi1, i);
-               MIPI_TRACE("%04x: %08x\n", i>>16, val);
-               msleep(1);
-       }
-
-       MIPI_TRACE("\n");
-       return -1;
-}
-
-int reg_proc_open1(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
 int reg_proc_close1(struct inode *inode, struct file *file)
 {
        return 0;
@@ -1512,10 +1503,10 @@ int reg_proc_close1(struct inode *inode, struct file *file)
 
 struct file_operations reg_proc_fops1 = {
        .owner = THIS_MODULE,
-       .open = reg_proc_open1,
+       .open = reg_proc_open,
        .release = reg_proc_close1,
        .write = reg_proc_write1,
-       .read = reg_proc_read1,
+       .read = seq_read,
 };
 #endif
 #if 0/* def CONFIG_MIPI_DSI_LINUX */
old mode 100644 (file)
new mode 100755 (executable)
index 79118f6..73ba636
@@ -418,6 +418,7 @@ static int rk3036_tve_probe(struct platform_device *pdev)
        rk_display_device_enable(rk3036_tve->ddev);
 
        fb_register_client(&tve_fb_notifier);
+       cvbsformat = -1;
        dev_info(&pdev->dev, "%s tv encoder probe ok\n", match->compatible);
        return 0;
 }
index b7fc0e128bde6fc916ba7b7fa81572261cc3f0d2..a8127dda1f8c83d236fb510514940cb1529b035e 100755 (executable)
@@ -142,7 +142,6 @@ struct dw_mci {
        unsigned int            prev_blksz;
        unsigned char           timing;
        struct workqueue_struct *card_workqueue;
-       struct delayed_work     resume_rescan;
 
        /* DMA interface members*/
        int                     use_dma;
index d6e7f6290020f4fd1d734c151bea4ad5a193063f..353403a9e52fd471539ce39a66265646fce11d72 100755 (executable)
@@ -73,6 +73,8 @@ struct rk30_adc_battery_platform_data {
 
        int is_dc_charge;
        int is_usb_charge;
+       int auto_calibration;
        struct iio_channel *chan;
+       struct iio_channel *ref_voltage_chan;
 };
 #endif
index 85959bace47dfeafd3a0ce89bd75faa5fcdc9c8a..1c4ec6d791e665578b2412a5b96a492222a213e6 100755 (executable)
@@ -273,7 +273,7 @@ struct pwr_ctr {
        int is_rst;
        int gpio;
        int atv_val;
-       char rgl_name[32];
+       const char *rgl_name;
        int volt;
        int delay;
 };
@@ -593,6 +593,7 @@ struct rk_lcdc_driver {
        struct rk_lcdc_bcsh bcsh;
        int *hwc_lut;
        int uboot_logo;
+       int bcsh_init_status;
 };
 
 struct rk_fb_par {
@@ -665,4 +666,5 @@ extern int rk_get_real_fps(int time);
 extern struct device *rk_fb_get_sysmmu_device_by_compatible(const char *compt);
 extern void rk_fb_platform_set_sysmmu(struct device *sysmmu,
                                       struct device *dev);
+int rk_fb_get_display_policy(void);
 #endif
index 986943afa2f148d45ee0c4320c60cac3df63a395..cf51a1ce95c1b4d3bdcc4b95e8bf37deb4c01b78 100644 (file)
@@ -76,6 +76,7 @@ int rockchip_unregister_system_status_notifier(struct notifier_block *nb);
 int rockchip_set_system_status(unsigned long status);
 int rockchip_clear_system_status(unsigned long status);
 unsigned long rockchip_get_system_status(void);
+u32 pvtm_get_value(u32 ch, u32 time_us);
 
 #define INVALID_TEMP INT_MAX
 #if IS_ENABLED(CONFIG_SENSORS_ROCKCHIP_TSADC)
index 209374a211825590c0448694b63e19f98f3b5391..594f9986cbd3512a424218e80c05b87e77d8c6e6 100644 (file)
 #include <linux/device.h>
 #include <linux/clk-provider.h>
 
+#define ARM_DVFS_CH    0
+#define GPU_DVFS_CH    1
+#define LOG_DVFS_CH    2
+
 struct dvfs_node;
 typedef int (*dvfs_set_rate_callback)(struct dvfs_node *clk_dvfs_node, unsigned long rate);
 typedef int (*clk_set_rate_callback)(struct clk *clk, unsigned long rate);
@@ -76,6 +80,32 @@ struct pd_node {
        unsigned int            regu_mode;
 };
 
+struct pvtm_info {
+       const char *compatible;
+       struct cpufreq_frequency_table *pvtm_table;
+       int channel;
+       int process_version;
+       int scan_rate_hz;
+       int sample_time_us;
+       int volt_step_uv;
+       int delta_pvtm_by_volt;
+       int delta_pvtm_by_temp;
+       int volt_margin_uv;
+       int min_volt_uv;
+       int max_volt_uv;
+};
+
+struct lkg_adjust_volt_table {
+       int     lkg;
+       int     dlt_volt;
+};
+
+struct lkg_info {
+       int     def_table_lkg;
+       int     min_adjust_freq;
+       struct  lkg_adjust_volt_table *table;
+};
+
 /**
  * struct dvfs_node:   To Store All dvfs clocks' info
  * @name:              Dvfs clock's Name
@@ -96,9 +126,11 @@ struct dvfs_node {
        int                     set_volt;       //MV
        int                     enable_count;
        int                     freq_limit_en;  //sign if use limit frequency
+       int                     support_pvtm;
        unsigned int            min_rate;       //limit min frequency
        unsigned int            max_rate;       //limit max frequency
        unsigned long           last_set_rate;
+       unsigned int            channel;
        unsigned int            temp_channel;
        unsigned long           temp_limit_rate;
        struct clk              *clk;
@@ -107,6 +139,7 @@ struct dvfs_node {
        struct list_head        node;
        struct notifier_block   *dvfs_nb;
        struct cpufreq_frequency_table  *dvfs_table;
+       struct cpufreq_frequency_table  *pvtm_table;
        struct cpufreq_frequency_table  *per_temp_limit_table;
        struct cpufreq_frequency_table  *nor_temp_limit_table;
        struct cpufreq_frequency_table  *virt_temp_limit_table[4];
@@ -114,6 +147,9 @@ struct dvfs_node {
        struct cpufreq_frequency_table  *regu_mode_table;
        int                     regu_mode_en;
        unsigned int            regu_mode;
+       struct pvtm_info        *pvtm_info;
+       int                 lkg_adjust_volt_en;
+       struct lkg_info         lkg_info;
 };
 
 
index 28dcc5b01a13a6d19b20f0097048c08d2257375f..31a828f7bebf7300ed71076260b2648767e8662e 100755 (executable)
                 1) support isp iommu
 *v0.9.0:
          1) add dev_name in struct camsys_devio_name_s;
+*v0.a.0:
+         1) support external flash IC
 */
-#define CAMSYS_HEAD_VERSION           KERNEL_VERSION(0,9,0)
+#define CAMSYS_HEAD_VERSION           KERNEL_VERSION(0,0xa,0)
 
 #define CAMSYS_MARVIN_DEVNAME         "camsys_marvin"           
 #define CAMSYS_CIF0_DEVNAME           "camsys_cif0"
@@ -152,7 +154,9 @@ typedef struct camsys_sysctrl_s {
 } camsys_sysctrl_t;
 
 typedef struct camsys_flash_info_s {
-    camsys_gpio_info_t        fl;
+    unsigned char     fl_drv_name[CAMSYS_NAME_LEN];
+    camsys_gpio_info_t        fl; //fl_trig
+    camsys_gpio_info_t        fl_en;
 } camsys_flash_info_t;
 
 typedef struct camsys_mipiphy_s {
old mode 100644 (file)
new mode 100755 (executable)
index 37ae12e..3aa1e07
@@ -354,4 +354,7 @@ params_period_bytes(const struct snd_pcm_hw_params *p)
                params_channels(p)) / 8;
 }
 
+#define HW_PARAMS_FLAG_LPCM 0
+#define HW_PARAMS_FLAG_NLPCM 1
+
 #endif /* __SOUND_PCM_PARAMS_H */
index 9aa554b7e620e1c0596a45035fbf0ebc3372dd0e..2e768e37c2a78ba4e56b5c26c7c72829cc271996 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2571,6 +2571,16 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
        detach_vmas_to_be_unmapped(mm, vma, prev, end);
        unmap_region(mm, vma, prev, start, end);
 
+#ifdef CONFIG_ARCH_ROCKCHIP
+       {
+               extern int ion_munmap(void *dmabuf, struct vm_area_struct *vma);
+               extern int dma_buf_is_dma_buf(struct file *file);
+               if (vma->vm_file && dma_buf_is_dma_buf(vma->vm_file)) {
+                       ion_munmap(vma->vm_file->private_data, vma);
+               }
+       }
+#endif
+
        /* Fix up all other VM information */
        remove_vma_list(mm, vma);
 
old mode 100644 (file)
new mode 100755 (executable)
index ac55278..2d790ee
@@ -29,7 +29,8 @@ struct snd_soc_dai_driver hdmi_i2s_dai = {
                .rates = (SNDRV_PCM_RATE_32000 |
                        SNDRV_PCM_RATE_44100 |
                        SNDRV_PCM_RATE_48000 |
-                       SNDRV_PCM_RATE_96000),
+                       SNDRV_PCM_RATE_96000 |
+                       SNDRV_PCM_RATE_192000),
                .formats = (SNDRV_PCM_FMTBIT_S16_LE |
                        SNDRV_PCM_FMTBIT_S20_3LE |
                        SNDRV_PCM_FMTBIT_S24_LE),
index a58cf54cbbcacba3ea5a057d05291f61f983ae28..b7900973db9c2af59e5f33857f2c35f1619ecfda 100755 (executable)
@@ -1910,6 +1910,7 @@ static int rk312x_startup(struct snd_pcm_substream *substream,
                                rk312x_codec_power_up(RK312x_CODEC_PLAYBACK);
                                snd_soc_write(rk312x_priv->codec, 0xb4, rk312x_priv->spk_volume);
                                snd_soc_write(rk312x_priv->codec, 0xb8, rk312x_priv->spk_volume);
+                               msleep(rk312x_priv->spk_mute_delay);
                                rk312x_codec_ctl_gpio(CODEC_SET_SPK, rk312x_priv->spk_active_level);
                        }
        } else {
@@ -1995,7 +1996,8 @@ static void rk312x_shutdown(struct snd_pcm_substream *substream,
                              SNDRV_PCM_RATE_32000 |    \
                              SNDRV_PCM_RATE_44100 |    \
                              SNDRV_PCM_RATE_48000 |    \
-                             SNDRV_PCM_RATE_96000)
+                             SNDRV_PCM_RATE_96000 |    \
+                             SNDRV_PCM_RATE_192000)
 
 #define RK312x_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
                              SNDRV_PCM_RATE_16000 |    \
old mode 100644 (file)
new mode 100755 (executable)
index b89339f..fe9c716
@@ -30,6 +30,7 @@ static int hdmi_i2s_hifi_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        unsigned int pll_out = 0, dai_fmt = rtd->dai_link->dai_fmt;
+       int div_bclk,div_mclk;
        int ret;
 
        DBG("Enter::%s----%d\n", __func__, __LINE__);
@@ -48,13 +49,21 @@ static int hdmi_i2s_hifi_hw_params(struct snd_pcm_substream *substream,
        case 24000:
        case 32000:
        case 48000:
+       case 96000:
                pll_out = 12288000;
                break;
        case 11025:
        case 22050:
        case 44100:
+       case 88200:
                pll_out = 11289600;
                break;
+       case 176400:
+               pll_out = 11289600*2;
+               break;
+       case 192000:
+               pll_out = 12288000*2;
+               break;
        default:
                pr_err("Enter:%s, %d, Error rate=%d\n",
                        __func__, __LINE__, params_rate(params));
@@ -66,13 +75,15 @@ static int hdmi_i2s_hifi_hw_params(struct snd_pcm_substream *substream,
                __func__, __LINE__,
                params_rate(params));
 
+       div_bclk = 63;
+       div_mclk = pll_out/(params_rate(params)*(div_bclk+1))-1;
+
        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);
+       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
+       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
 
-       DBG("Enter:%s, %d, pll_out / 4 / params_rate(params) = %d\n",
-               __func__, __LINE__, (pll_out / 4) / params_rate(params));
+       DBG("Enter:%s, %d, div_bclk: %d, div_mclk: %d\n",
+               __func__, __LINE__, div_bclk, div_mclk);
 
        return 0;
 }
index d90c142967adb202815d62598f387c02d98ba7e9..dad8e63e34dd1c7ee6a86daa4c6350248a4e1d88 100755 (executable)
@@ -36,7 +36,7 @@ static const struct snd_pcm_hardware rockchip_pcm_hardware = {
        .channels_max           = 8,
        .buffer_bytes_max       = 128*1024,
        .period_bytes_min       = 64,
-       .period_bytes_max       = 2048*4,
+       .period_bytes_max       = 32*1024,//2048*4,///PAGE_SIZE*2,
        .periods_min            = 3,
        .periods_max            = 128,
        .fifo_size              = 16,
@@ -46,7 +46,7 @@ static const struct snd_dmaengine_pcm_config rockchip_dmaengine_pcm_config = {
        .pcm_hardware = &rockchip_pcm_hardware,
        .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
        .compat_filter_fn = NULL,
-       .prealloc_buffer_size = PAGE_SIZE * 8,
+       .prealloc_buffer_size = PAGE_SIZE * 32,
 };
 
 int rockchip_pcm_platform_register(struct device *dev)
index da0cf7bbbd4c2f8dba9d8b5777ec241e8bed062c..0113e74529425d5f43cee46386fd7c33519473a0 100755 (executable)
@@ -43,7 +43,7 @@
 #include "rk_pcm.h"
 
 #undef  DEBUG_SPDIF
-#define DEBUG_SPDIF 1
+#define DEBUG_SPDIF 0
 
 #if DEBUG_SPDIF
 #define RK_SPDIF_DBG(x...) pr_info("rk_spdif:"x)
index f00b15a7301fe5bf520bc1f0563c77caa5902988..21a4e03e80dda7fe5b4a02f4c0dada264f8808c3 100644 (file)
@@ -45,7 +45,9 @@
 #include <linux/usb/audio.h>
 #include <linux/usb/audio-v2.h>
 #include <linux/module.h>
+#ifdef CONFIG_SWITCH
 #include <linux/switch.h>
+#endif
 
 #include <sound/control.h>
 #include <sound/core.h>
@@ -114,10 +116,39 @@ static DEFINE_MUTEX(register_mutex);
 static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
 static struct usb_driver usb_audio_driver;
 #ifdef CONFIG_SND_RK_SOC
-#define USB_AUDIO_CARD_NUM 2
+#define USB_AUDIO_CARD_NUM     3
 struct switch_dev *usb_audio_sdev;
 #endif
 
+#ifdef CONFIG_SWITCH
+//usb audio card will begin from RBASE_USB_AUDIO_IDX.
+#define RBASE_USB_AUDIO_IDX    (3)
+#define NO_USBAUDIO_PLAYBACK   (-1)
+#define NO_USBAUDIO_CAPTURE    (-1)
+
+struct usb_audio_switch {
+       int playback_switch_cur_state;
+       int capture_switch_cur_state;
+       struct switch_dev sUsbaudio_Playback;
+       struct switch_dev sUsbaudio_Capture;
+};
+
+// state: card*10 + device
+static struct usb_audio_switch sUsbaudio_Switch = {
+       .playback_switch_cur_state = NO_USBAUDIO_PLAYBACK,
+       .capture_switch_cur_state = NO_USBAUDIO_CAPTURE,
+       .sUsbaudio_Playback = {
+               .name = "usb_audio_playback",
+               .state = NO_USBAUDIO_PLAYBACK, //this means no usb audio playback available
+       },
+
+       .sUsbaudio_Capture = {
+               .name = "usb_audio_capture",
+               .state = NO_USBAUDIO_CAPTURE, //this means no usb audio capture available
+       },
+};
+#endif
+
 /*
  * disconnect streams
  * called from snd_usb_audio_disconnect()
@@ -466,6 +497,65 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
        return 0;
 }
 
+#ifdef CONFIG_SWITCH
+static int usb_audio_card_switch_state_update(struct snd_card *card, bool force){
+       struct snd_device *dev;
+    struct snd_pcm *pcm;
+    struct snd_pcm_str *pstr;
+
+       if (snd_BUG_ON(!card))
+               return -EINVAL;
+       //we use the latest devices
+       list_for_each_entry(dev, &card->devices, list) {
+               if (dev->type == SNDRV_DEV_PCM && dev->state == SNDRV_DEV_REGISTERED) {
+                       pcm = (struct snd_pcm*)dev->device_data;
+                       if (NULL != pcm) {
+                               //playback available?
+                               pstr = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
+                               snd_printdd(KERN_INFO "playback substream_count: 0x%x\n", pstr->substream_count);
+                               if (pstr->substream_count > 0) {
+                                       sUsbaudio_Switch.playback_switch_cur_state = card->number * 10;
+                               }
+                               //capture available?
+                               pstr = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
+                               snd_printdd(KERN_INFO "capture substream_count: 0x%x\n", pstr->substream_count);
+                               if (pstr->substream_count > 0) {
+                                       sUsbaudio_Switch.capture_switch_cur_state = card->number * 10;
+                               }
+                       }
+               }
+       }
+       if (force) {
+               switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback, sUsbaudio_Switch.playback_switch_cur_state);
+               switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture, sUsbaudio_Switch.capture_switch_cur_state);
+       }
+       return 0;
+
+}
+
+static void usb_audio_switch_state_update_all(void)
+{
+       int index = 0;
+       struct snd_card *card;
+
+       sUsbaudio_Switch.playback_switch_cur_state = NO_USBAUDIO_PLAYBACK;
+       sUsbaudio_Switch.capture_switch_cur_state = NO_USBAUDIO_CAPTURE;
+
+       for (index = 0; index < SNDRV_CARDS; ++index) {
+               if (NULL != usb_chip[index]) {
+                       card = usb_chip[index]->card;
+                       usb_audio_card_switch_state_update(card, false);
+               }
+       }
+
+       switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback,
+                        sUsbaudio_Switch.playback_switch_cur_state);
+       switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture,
+                        sUsbaudio_Switch.capture_switch_cur_state);
+}
+#endif
+
+
 /*
  * probe the active usb device
  *
@@ -520,6 +610,7 @@ snd_usb_audio_probe(struct usb_device *dev,
                /* it's a fresh one.
                 * now look for an empty slot and create a new card instance
                 */
+               // use RBASE_USB_AUDIO_IDX instead of zero, modify by zxg.
                for (i = 0; i < SNDRV_CARDS; i++)
                        if (enable[i] && ! usb_chip[i] &&
                            (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
@@ -565,7 +656,12 @@ snd_usb_audio_probe(struct usb_device *dev,
        if (snd_card_register(chip->card) < 0) {
                goto __error;
        }
-
+#ifdef CONFIG_SWITCH
+       if (usb_audio_card_switch_state_update(chip->card, true) < 0) {
+               printk(KERN_ERR "usb_audio_card_switch_state_update failed!!!\n");
+       goto __error;
+       }
+#endif
        usb_chip[chip->index] = chip;
        chip->num_interfaces++;
        chip->probing = 0;
@@ -627,6 +723,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
        } else {
                mutex_unlock(&register_mutex);
        }
+#ifdef CONFIG_SWITCH
+       usb_audio_switch_state_update_all();
+#endif
 }
 
 /*
@@ -770,11 +869,24 @@ static struct usb_driver usb_audio_driver = {
 
 static int __init snd_usb_audio_init(void)
 {
+       int ret;
+#ifdef CONFIG_SWITCH
+       int i;
+       ret = switch_dev_register(&sUsbaudio_Switch.sUsbaudio_Playback);
+       if (ret)
+               goto err;
+       ret = switch_dev_register(&sUsbaudio_Switch.sUsbaudio_Capture);
+       if (ret)
+               goto err_drv;
+
+       switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback, NO_USBAUDIO_PLAYBACK);
+       switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture, NO_USBAUDIO_CAPTURE);
+#endif
+
        if (nrpacks < 1 || nrpacks > MAX_PACKS) {
                printk(KERN_WARNING "invalid nrpacks value.\n");
                return -EINVAL;
        }
-
 #ifdef CONFIG_SND_RK_SOC
        usb_audio_sdev = kzalloc(sizeof(usb_audio_sdev), GFP_KERNEL);
        usb_audio_sdev->name = "usb_audio";
@@ -785,7 +897,20 @@ static int __init snd_usb_audio_init(void)
        }
 #endif
 
+    //re initial array index for rebasing usb audio cards create, modify by zxg.
+    for(i=0; i<SNDRV_CARDS; ++i){
+        index[i] = i;
+    }
+
        return usb_register(&usb_audio_driver);
+
+err_drv:
+#ifdef CONFIG_SWITCH
+       switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Playback);
+#endif
+err:
+    return ret;
+
 }
 
 static void __exit snd_usb_audio_cleanup(void)
@@ -794,7 +919,14 @@ static void __exit snd_usb_audio_cleanup(void)
 #ifdef CONFIG_SND_RK_SOC
        kfree(usb_audio_sdev);
 #endif
+       switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Capture);
+       switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Playback);
 }
 
-module_init(snd_usb_audio_init);
+/*module_init(snd_usb_audio_init);*/
+/* use late initcall_sync instead of module_init,
+ * make sure that usbaudio probe after board codec.
+ * added by zxg@rock-chips.com
+ */
+late_initcall_sync(snd_usb_audio_init);
 module_exit(snd_usb_audio_cleanup);