isp:camsys_head ver:v0.0.5
[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         
138
139  //       clk_enable(clk->pd_isp);
140   //      clk_enable(clk->aclk_isp);
141   //    clk_enable(clk->hclk_isp);      
142   //    clk_enable(clk->isp);
143  //     clk_enable(clk->isp_jpe);
144  //     clk_enable(clk->pclkin_isp);
145         
146         clk->in_on = true;
147
148         camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
149         camsys_mrv_reset_cb(ptr);       
150         
151     } else if (!on && clk->in_on) {
152
153
154          clk_disable_unprepare(clk->aclk_isp);
155         clk_disable_unprepare(clk->hclk_isp);
156         clk_disable_unprepare(clk->isp);
157         clk_disable_unprepare( clk->isp_jpe);
158
159   //      clk_disable(clk->pd_isp);
160   //      clk_disable(clk->aclk_isp);
161    //   clk_disable(clk->hclk_isp);
162   //    clk_disable(clk->isp);
163   //    clk_disable(clk->isp_jpe);
164  //     clk_disable(clk->pclkin_isp);
165
166         clk->in_on = false;
167         camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
168     }
169   //  spin_unlock(&clk->lock);
170     return 0;
171 }
172
173 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
174 {
175     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
176     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
177     struct clk *cif_clk_out_div;
178     
179     spin_lock(&clk->lock);
180     if (on && (clk->out_on != on)) {  
181         clk_prepare_enable(clk->cif_clk_out);
182
183 //        clk_enable(clk->cif_clk_out);
184         clk_set_rate(clk->cif_clk_out,on);
185         
186         clk->out_on = on;
187         camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
188                     clk->out_on);
189     } else if (!on && clk->out_on) {
190         cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
191         if(IS_ERR_OR_NULL(cif_clk_out_div)) {
192             cif_clk_out_div =  clk_get(NULL, "cif_out_div");
193         }
194
195         if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
196             clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
197             clk_put(cif_clk_out_div);
198         } else {
199             camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
200         }
201
202         clk_disable_unprepare( clk->cif_clk_out);
203 //        clk_disable(clk->cif_clk_out);
204
205         clk->out_on = 0;
206
207         camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
208     }
209     spin_unlock(&clk->lock);    
210
211     return 0;
212 }
213 static irqreturn_t camsys_mrv_irq(int irq, void *data)
214 {
215     camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
216     camsys_irqstas_t *irqsta;
217     camsys_irqpool_t *irqpool;
218     unsigned int isp_mis,mipi_mis,mi_mis,*mis;
219
220     isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
221     mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
222     mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));    
223
224     __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR)); 
225     __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR)); 
226     __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR)); 
227
228     spin_lock(&camsys_dev->irq.lock);
229     if (!list_empty(&camsys_dev->irq.irq_pool)) {
230         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
231             if (irqpool->pid != 0) {
232                 switch(irqpool->mis)
233                 {
234                     case MRV_ISP_MIS:
235                     {
236                         mis = &isp_mis;
237                         break;
238                     }
239
240                     case MRV_MIPI_MIS:
241                     {
242                         mis = &mipi_mis;
243                         break;
244                     }
245                     case MRV_MI_MIS:
246                     {
247                         mis = &mi_mis;
248                         break;
249                     }
250
251                     default:     
252                     {
253                         camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
254                         goto end;
255                     }
256                 }
257
258                 if (*mis != 0) {
259                     spin_lock(&irqpool->lock);
260                     if (!list_empty(&irqpool->deactive)) {
261                         irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
262                         irqsta->sta.mis = *mis;                                                 
263                         list_del_init(&irqsta->list);            
264                         list_add_tail(&irqsta->list,&irqpool->active);                        
265                         wake_up(&irqpool->done);
266                     }
267                     spin_unlock(&irqpool->lock);
268                 }
269             }
270         }
271     }
272 end:    
273     spin_unlock(&camsys_dev->irq.lock);
274
275     return IRQ_HANDLED;
276 }
277 static int camsys_mrv_remove_cb(struct platform_device *pdev)
278 {
279     camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
280     camsys_mrv_clk_t *mrv_clk=NULL;
281
282     if (camsys_dev->clk != NULL) {
283
284         mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
285         if (mrv_clk->out_on)
286             camsys_mrv_clkout_cb(mrv_clk,0);
287         if (mrv_clk->in_on)
288             camsys_mrv_clkin_cb(mrv_clk,0);
289     
290         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
291             clk_put(mrv_clk->pd_isp);
292         }
293         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
294             clk_put(mrv_clk->aclk_isp);
295         }
296         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
297             clk_put(mrv_clk->hclk_isp);
298         }
299         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
300             clk_put(mrv_clk->isp);
301         }
302         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
303             clk_put(mrv_clk->isp_jpe);
304         }
305         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
306             clk_put(mrv_clk->pclkin_isp);
307         }
308         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
309             clk_put(mrv_clk->cif_clk_out);
310         }
311
312         kfree(mrv_clk);
313         mrv_clk = NULL;
314     }
315
316     return 0;
317 }
318 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
319 {
320     int err = 0;   
321     camsys_mrv_clk_t *mrv_clk=NULL;
322     //struct clk *clk_parent;
323     
324     err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
325     if (err) {
326         camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
327         goto end;
328     }
329
330     //Clk and Iomux init
331     mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
332     if (mrv_clk == NULL) {
333         camsys_err("Allocate camsys_mrv_clk_t failed!");
334         err = -EINVAL;
335         goto clk_failed;
336     }
337      
338    // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
339     mrv_clk->pd_isp = NULL;
340     mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "g_aclk_isp");
341     mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "g_hclk_isp");
342     mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
343     mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
344     mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
345     mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
346     
347     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) ||
348         IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) /*|| IS_ERR_OR_NULL(mrv_clk->pclkin_isp)*/ || 
349         IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
350         camsys_err("Get %s clock resouce failed!\n",miscdev_name);
351         err = -EINVAL;
352         goto clk_failed;
353     }
354
355     
356 //    clk_set_rate(mrv_clk->isp,1800000000);
357 //    clk_set_rate(mrv_clk->isp_jpe,180000000);
358     
359     spin_lock_init(&mrv_clk->lock);
360     
361     mrv_clk->in_on = false;
362     mrv_clk->out_on = 0;
363         
364     camsys_dev->clk = (void*)mrv_clk;
365     camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
366     camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
367     camsys_dev->reset_cb = camsys_mrv_reset_cb;
368     camsys_dev->iomux = camsys_mrv_iomux_cb;
369     
370     camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
371     camsys_dev->miscdev.name = miscdev_name;
372     camsys_dev->miscdev.nodename = miscdev_name;
373     camsys_dev->miscdev.fops = &camsys_fops;
374
375     err = misc_register(&camsys_dev->miscdev);
376     if (err < 0) {
377         camsys_err("misc register %s failed!",miscdev_name);
378         goto misc_register_failed;
379     }   
380
381     //Variable init
382     camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
383     camsys_dev->platform_remove = camsys_mrv_remove_cb;
384     
385     return 0;
386 misc_register_failed:
387     if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
388         misc_deregister(&camsys_dev->miscdev);
389     }
390
391 clk_failed:
392     if (mrv_clk != NULL) {
393         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
394             clk_put(mrv_clk->pd_isp);
395         }
396         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
397             clk_put(mrv_clk->aclk_isp);
398         }
399         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
400             clk_put(mrv_clk->hclk_isp);
401         }
402         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
403             clk_put(mrv_clk->isp);
404         }
405         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
406             clk_put(mrv_clk->isp_jpe);
407         }
408         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
409             clk_put(mrv_clk->pclkin_isp);
410         }
411         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
412             clk_put(mrv_clk->cif_clk_out);
413         }
414
415         kfree(mrv_clk);
416         mrv_clk = NULL;
417     }
418     
419 end:
420     return err;
421 }
422 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);
423