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