rk3288:enable front camera
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_marvin.c
1 #include "camsys_marvin.h"
2
3 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
4
5 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
6 {  
7     unsigned int cif_vol_sel;
8 #if 0    
9     if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
10         iomux_set(ISP_FLASH_TRIG);  
11         if (extdev->fl.fl.io != 0xffffffff) {
12             iomux_set(ISP_FL_TRIG);
13         }
14     } 
15
16     if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
17         iomux_set(ISP_PRELIGHT_TRIG);
18     }
19     
20     if (extdev->dev_cfg & CAMSYS_DEVCFG_SHUTTER) {
21         iomux_set(ISP_SHUTTER_OPEN);
22         iomux_set(ISP_SHUTTER_TRIG);
23     }
24
25     iomux_set(CIF0_CLKOUT);
26 #endif
27
28     struct pinctrl      *pinctrl;
29     struct pinctrl_state    *state;
30     int retval = 0;
31     char state_str[20] = {0};
32
33     struct device *dev = &(extdev->pdev->dev);
34     
35     if (extdev->phy.type == CamSys_Phy_Cif) {
36         if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_8b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
37
38            strcpy(state_str,"isp_dvp8bit");
39
40         }
41
42         if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
43            strcpy(state_str,"isp_dvp10bit");
44         }
45
46         if (extdev->phy.info.cif.fmt == CamSys_Fmt_Raw_12b) {
47            strcpy(state_str,"isp_dvp12bit");
48
49         }
50     }else{
51            strcpy(state_str,"default");
52     }
53
54     //mux CIF0_CLKOUT
55
56     pinctrl = devm_pinctrl_get(dev);
57     if (IS_ERR(pinctrl)) {
58         camsys_err("%s:Get pinctrl failed!\n",__func__);
59         return -1;
60     }
61     state = pinctrl_lookup_state(pinctrl,
62                          state_str);
63     if (IS_ERR(state)){
64         dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
65         return -1;
66         }
67
68     if (!IS_ERR(state)) {
69         retval = pinctrl_select_state(pinctrl, state);
70         if (retval){
71             dev_err(dev,
72                 "%s:could not set %s pins\n",__func__,state_str);
73                 return -1;
74
75                 }
76     }
77
78     //set 1.8v vol domain for rk32
79     __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
80    __raw_writel(0xffffffff, RK_GRF_VIRT+0x01d4);   
81
82     //set cif vol domain
83     if (extdev->phy.type == CamSys_Phy_Cif) {
84
85         #if 0
86         if (!IS_ERR_OR_NULL(extdev->dovdd.ldo)) {
87             if (extdev->dovdd.max_uv >= 25000000) {
88                 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
89             } else {
90                 __raw_writel((1<<(1+16)),RK30_GRF_BASE+0x018c);
91             }
92         } else {
93             __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
94         }
95         #else
96
97         //set 1.8v vol domain
98         __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
99         #endif
100         
101         //set driver strength
102       //  __raw_writel(0xffffffff, RK_GRF_VIRT+0x01dc);   
103     }
104     
105     return 0;
106 }
107
108 static int camsys_mrv_reset_cb(void *ptr)
109 {
110     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
111     #if 0 //do nothing ,zyc
112     cru_set_soft_reset(SOFT_RST_ISP,true);
113     udelay(100);
114     cru_set_soft_reset(SOFT_RST_ISP,false);
115     #endif
116     camsys_trace(1, "%s soft reset\n",dev_name(camsys_dev->miscdev.this_device));
117     return 0;
118 }
119
120 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
121 {
122     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
123     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
124     
125   //  spin_lock(&clk->lock);
126     if (on && !clk->in_on) {
127         clk_set_rate(clk->isp,180000000);
128         clk_set_rate(clk->isp_jpe, 180000000);
129    //     clk_set_rate(clk->aclk_isp,24000000);
130    //     clk_set_rate(clk->hclk_isp,24000000);
131
132
133         clk_prepare_enable(clk->aclk_isp);
134         clk_prepare_enable(clk->hclk_isp);
135         clk_prepare_enable(clk->isp);
136         clk_prepare_enable(clk->isp_jpe);
137         clk_prepare_enable(clk->clk_mipi_24m); 
138         clk_prepare_enable(clk->pclkin_isp); 
139
140
141
142  //       clk_enable(clk->pd_isp);
143   //      clk_enable(clk->aclk_isp);
144   //    clk_enable(clk->hclk_isp);      
145   //    clk_enable(clk->isp);
146  //     clk_enable(clk->isp_jpe);
147  //     clk_enable(clk->pclkin_isp);
148         
149         clk->in_on = true;
150
151         camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
152         camsys_mrv_reset_cb(ptr);       
153         
154     } else if (!on && clk->in_on) {
155
156
157         clk_disable_unprepare(clk->aclk_isp);
158         clk_disable_unprepare(clk->hclk_isp);
159         clk_disable_unprepare(clk->isp);
160         clk_disable_unprepare(clk->isp_jpe);
161         clk_disable_unprepare(clk->clk_mipi_24m); 
162         clk_disable_unprepare(clk->pclkin_isp); 
163
164   //      clk_disable(clk->pd_isp);
165   //      clk_disable(clk->aclk_isp);
166    //   clk_disable(clk->hclk_isp);
167   //    clk_disable(clk->isp);
168   //    clk_disable(clk->isp_jpe);
169  //     clk_disable(clk->pclkin_isp);
170
171         clk->in_on = false;
172         camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
173     }
174   //  spin_unlock(&clk->lock);
175     return 0;
176 }
177
178 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
179 {
180     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
181     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
182     struct clk *cif_clk_out_div;
183     
184     spin_lock(&clk->lock);
185     if (on && (clk->out_on != on)) {  
186         clk_prepare_enable(clk->cif_clk_out);
187
188 //        clk_enable(clk->cif_clk_out);
189         clk_set_rate(clk->cif_clk_out,on);
190         
191         clk->out_on = on;
192         camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
193                     clk->out_on);
194     } else if (!on && clk->out_on) {
195         cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
196         if(IS_ERR_OR_NULL(cif_clk_out_div)) {
197             cif_clk_out_div =  clk_get(NULL, "cif_out_div");
198         }
199
200         if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
201             clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
202             clk_put(cif_clk_out_div);
203         } else {
204             camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
205         }
206
207         clk_disable_unprepare( clk->cif_clk_out);
208 //        clk_disable(clk->cif_clk_out);
209
210         clk->out_on = 0;
211
212         camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
213     }
214     spin_unlock(&clk->lock);    
215
216     return 0;
217 }
218 static irqreturn_t camsys_mrv_irq(int irq, void *data)
219 {
220     camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
221     camsys_irqstas_t *irqsta;
222     camsys_irqpool_t *irqpool;
223     unsigned int isp_mis,mipi_mis,mi_mis,*mis;
224
225     isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
226     mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
227     mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));    
228
229     __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR)); 
230     __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR)); 
231     __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR)); 
232
233     spin_lock(&camsys_dev->irq.lock);
234     if (!list_empty(&camsys_dev->irq.irq_pool)) {
235         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
236             if (irqpool->pid != 0) {
237                 switch(irqpool->mis)
238                 {
239                     case MRV_ISP_MIS:
240                     {
241                         mis = &isp_mis;
242                         break;
243                     }
244
245                     case MRV_MIPI_MIS:
246                     {
247                         mis = &mipi_mis;
248                         break;
249                     }
250                     case MRV_MI_MIS:
251                     {
252                         mis = &mi_mis;
253                         break;
254                     }
255
256                     default:     
257                     {
258                         camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
259                         goto end;
260                     }
261                 }
262
263                 if (*mis != 0) {
264                     spin_lock(&irqpool->lock);
265                     if (!list_empty(&irqpool->deactive)) {
266                         irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
267                         irqsta->sta.mis = *mis;                                                 
268                         list_del_init(&irqsta->list);            
269                         list_add_tail(&irqsta->list,&irqpool->active);                        
270                         wake_up(&irqpool->done);
271                     }
272                     spin_unlock(&irqpool->lock);
273                 }
274             }
275         }
276     }
277 end:    
278     spin_unlock(&camsys_dev->irq.lock);
279
280     return IRQ_HANDLED;
281 }
282 static int camsys_mrv_remove_cb(struct platform_device *pdev)
283 {
284     camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
285     camsys_mrv_clk_t *mrv_clk=NULL;
286
287     if (camsys_dev->clk != NULL) {
288
289         mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
290         if (mrv_clk->out_on)
291             camsys_mrv_clkout_cb(mrv_clk,0);
292         if (mrv_clk->in_on)
293             camsys_mrv_clkin_cb(mrv_clk,0);
294     
295         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
296             clk_put(mrv_clk->pd_isp);
297         }
298         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
299             clk_put(mrv_clk->aclk_isp);
300         }
301         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
302             clk_put(mrv_clk->hclk_isp);
303         }
304         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
305             clk_put(mrv_clk->isp);
306         }
307         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
308             clk_put(mrv_clk->isp_jpe);
309         }
310         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
311             clk_put(mrv_clk->pclkin_isp);
312         }
313         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
314             clk_put(mrv_clk->cif_clk_out);
315         }
316
317         kfree(mrv_clk);
318         mrv_clk = NULL;
319     }
320
321     return 0;
322 }
323 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
324 {
325     int err = 0;   
326     camsys_mrv_clk_t *mrv_clk=NULL;
327     //struct clk *clk_parent;
328     
329     err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
330     if (err) {
331         camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
332         goto end;
333     }
334
335     //Clk and Iomux init
336     mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
337     if (mrv_clk == NULL) {
338         camsys_err("Allocate camsys_mrv_clk_t failed!");
339         err = -EINVAL;
340         goto clk_failed;
341     }
342      
343    // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
344     mrv_clk->pd_isp = NULL;
345     mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
346     mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
347     mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
348     mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
349     mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
350     mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_vipout");
351     mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m"); 
352     if (/*IS_ERR_OR_NULL(mrv_clk->pd_isp) ||*/ IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) ||
353         IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || 
354         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
355         camsys_err("Get %s clock resouce failed!\n",miscdev_name);
356         err = -EINVAL;
357         goto clk_failed;
358     }
359
360     
361 //    clk_set_rate(mrv_clk->isp,1800000000);
362 //    clk_set_rate(mrv_clk->isp_jpe,180000000);
363     
364     spin_lock_init(&mrv_clk->lock);
365     
366     mrv_clk->in_on = false;
367     mrv_clk->out_on = 0;
368         
369     camsys_dev->clk = (void*)mrv_clk;
370     camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
371     camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
372     camsys_dev->reset_cb = camsys_mrv_reset_cb;
373     camsys_dev->iomux = camsys_mrv_iomux_cb;
374     
375     camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
376     camsys_dev->miscdev.name = miscdev_name;
377     camsys_dev->miscdev.nodename = miscdev_name;
378     camsys_dev->miscdev.fops = &camsys_fops;
379
380     err = misc_register(&camsys_dev->miscdev);
381     if (err < 0) {
382         camsys_err("misc register %s failed!",miscdev_name);
383         goto misc_register_failed;
384     }   
385
386     //Variable init
387     camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
388     camsys_dev->platform_remove = camsys_mrv_remove_cb;
389     
390     return 0;
391 misc_register_failed:
392     if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
393         misc_deregister(&camsys_dev->miscdev);
394     }
395
396 clk_failed:
397     if (mrv_clk != NULL) {
398         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
399             clk_put(mrv_clk->pd_isp);
400         }
401         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
402             clk_put(mrv_clk->aclk_isp);
403         }
404         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
405             clk_put(mrv_clk->hclk_isp);
406         }
407         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
408             clk_put(mrv_clk->isp);
409         }
410         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
411             clk_put(mrv_clk->isp_jpe);
412         }
413         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
414             clk_put(mrv_clk->pclkin_isp);
415         }
416         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
417             clk_put(mrv_clk->cif_clk_out);
418         }
419
420         kfree(mrv_clk);
421         mrv_clk = NULL;
422     }
423     
424 end:
425     return err;
426 }
427 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);
428