camsys: v0.e.0
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_marvin.c
index 5db6e547bf1ce42969a8a71a9d86ae537581149e..07e5f124123afb89993b526890e60a30e9b45296 100755 (executable)
@@ -1,8 +1,16 @@
 #include "camsys_marvin.h"
 #include "camsys_soc_priv.h"
+#include "camsys_gpio.h"
+
+#include <linux/rockchip/common.h> 
+#include <dt-bindings/clock/rk_system_status.h>
+
+extern int rockchip_set_system_status(unsigned long status);
+extern int rockchip_clear_system_status(unsigned long status);
 
 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
 
+
 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
 {
     struct pinctrl      *pinctrl;
@@ -104,11 +112,75 @@ fail:
     return -1;
 }
 
+static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on)
+{
+    camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
+    struct device *dev = &(camsys_dev->pdev->dev);
+    int flash_trigger_io ;
+    struct pinctrl      *pinctrl;
+    struct pinctrl_state    *state;
+    char state_str[20] = {0};
+    int retval = 0;
+    enum of_gpio_flags flags;
+
+    if(!on){
+        strcpy(state_str,"isp_flash_as_gpio");
+        pinctrl = devm_pinctrl_get(dev);
+        if (IS_ERR(pinctrl)) {
+            camsys_err("devm_pinctrl_get failed!");
+        }
+        state = pinctrl_lookup_state(pinctrl,
+                             state_str);
+        if (IS_ERR(state)){
+            camsys_err("pinctrl_lookup_state failed!");
+        }
+
+        if (!IS_ERR(state)) {
+            retval = pinctrl_select_state(pinctrl, state);
+            if (retval){
+                camsys_err("pinctrl_select_state failed!");
+            }
+
+        }
+
+        //get gpio index
+        flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
+        if(gpio_is_valid(flash_trigger_io)){
+            flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
+            gpio_request(flash_trigger_io,"camsys_gpio");
+            gpio_direction_output(flash_trigger_io, 1);
+            }
+
+    }else{
+        strcpy(state_str,"isp_flash_as_trigger_out");
+        pinctrl = devm_pinctrl_get(dev);
+        if (IS_ERR(pinctrl)) {
+            camsys_err("devm_pinctrl_get failed!");
+        }
+        state = pinctrl_lookup_state(pinctrl,
+                             state_str);
+        if (IS_ERR(state)){
+            camsys_err("pinctrl_lookup_state failed!");
+        }
+
+        if (!IS_ERR(state)) {
+            retval = pinctrl_select_state(pinctrl, state);
+            if (retval){
+                camsys_err("pinctrl_select_state failed!");
+            }
+
+        }
+    }
+    return retval;
+}
+
+
 static int camsys_mrv_reset_cb(void *ptr,unsigned int on)
 {
     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
     camsys_soc_priv_t *soc;
 
+
     if (camsys_dev->soc) {
         soc = (camsys_soc_priv_t*)camsys_dev->soc;
         if (soc->soc_cfg) {
@@ -127,8 +199,19 @@ static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
 {
     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
+    unsigned long isp_clk;
        
     if (on && !clk->in_on) {
+               rockchip_set_system_status(SYS_STATUS_ISP);
+
+               if (on == 1) {
+                   isp_clk = 210000000;           
+               } else {
+                   isp_clk = 420000000;            
+               }
+
+               clk_set_rate(clk->isp,isp_clk);
+        clk_set_rate(clk->isp_jpe, isp_clk);
 
         clk_prepare_enable(clk->aclk_isp);
         clk_prepare_enable(clk->hclk_isp);
@@ -137,17 +220,16 @@ static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
         clk_prepare_enable(clk->clk_mipi_24m); 
         clk_prepare_enable(clk->pclkin_isp); 
                clk_prepare_enable(clk->pd_isp);
-       
+
         clk->in_on = true;
 
-        camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
+        camsys_trace(1, "%s clock(f: %ld Hz) in turn on",dev_name(camsys_dev->miscdev.this_device),isp_clk);
         camsys_mrv_reset_cb(ptr,1);
         udelay(100);
         camsys_mrv_reset_cb(ptr,0);
         
     } else if (!on && clk->in_on) {
 
-
         clk_disable_unprepare(clk->aclk_isp);
         clk_disable_unprepare(clk->hclk_isp);
         clk_disable_unprepare(clk->isp);
@@ -156,6 +238,7 @@ static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
         clk_disable_unprepare(clk->pclkin_isp); 
                clk_disable_unprepare(clk->pd_isp);
 
+               rockchip_clear_system_status(SYS_STATUS_ISP);
         clk->in_on = false;
         camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
     }
@@ -336,8 +419,8 @@ int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
         goto clk_failed;
     }
     
-    clk_set_rate(mrv_clk->isp,384000000);
-    clk_set_rate(mrv_clk->isp_jpe, 384000000);
+    clk_set_rate(mrv_clk->isp,210000000);
+    clk_set_rate(mrv_clk->isp_jpe, 210000000);
     
     mutex_init(&mrv_clk->lock);
     
@@ -349,6 +432,7 @@ int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
     camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
     camsys_dev->reset_cb = camsys_mrv_reset_cb;
     camsys_dev->iomux = camsys_mrv_iomux_cb;
+    camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb;
     
     camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
     camsys_dev->miscdev.name = miscdev_name;