camsys_drv: v0.7.0 camsys_head: v0.6.0
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_drv.c
1 #include <media/camsys_head.h>
2
3 #include "camsys_cif.h"
4 #include "camsys_marvin.h"
5 #include "camsys_mipicsi_phy.h"
6 #include "camsys_gpio.h"
7 #include "camsys_soc_priv.h"
8
9 unsigned int camsys_debug=1;
10 module_param(camsys_debug, int, S_IRUGO|S_IWUSR);
11
12 static int drv_version = CAMSYS_DRIVER_VERSION;
13 module_param(drv_version, int, S_IRUGO);
14 static int head_version = CAMSYS_HEAD_VERSION;
15 module_param(head_version, int, S_IRUGO);
16
17
18 typedef struct camsys_devs_s {
19     spinlock_t lock;
20     struct list_head devs;
21 } camsys_devs_t;
22
23 static camsys_devs_t camsys_devs;
24
25 static int camsys_i2c_write(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
26 {
27     int err = 0,i,j;
28     unsigned char buf[8],*bufp;
29     unsigned short msg_times,totallen,onelen;
30     struct i2c_msg msg[1];
31     struct i2c_adapter *adapter;
32     
33     adapter = i2c_get_adapter(i2cinfo->bus_num);
34     if (adapter == NULL) {
35         camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
36         err = -EINVAL;
37         goto end;
38     }
39     
40     if (i2cinfo->i2cbuf_directly) {
41         if (camsys_dev->devmems.i2cmem == NULL) {
42             camsys_err("%s has not i2c mem, it isn't support i2c buf write!",dev_name(camsys_dev->miscdev.this_device));
43             err = -EINVAL;
44             goto end;
45         }
46         totallen = (i2cinfo->i2cbuf_bytes&0xffff);
47         onelen = (i2cinfo->i2cbuf_bytes&0xffff0000)>>16;
48         msg_times = totallen/onelen;
49         if (totallen > camsys_dev->devmems.i2cmem->size) {
50             camsys_err("Want to write 0x%x bytes, i2c memory(size: 0x%x) is overlap",totallen,camsys_dev->devmems.i2cmem->size);
51             err = -EINVAL;
52             goto end;
53         }
54         bufp = (unsigned char*)camsys_dev->devmems.i2cmem->vir_base;        
55     } else {
56         for (i=0; i<i2cinfo->reg_size; i++) {
57             buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
58         }
59         for (j=0; j<i2cinfo->val_size; j++) {
60             buf[i+j] = (i2cinfo->val>>(i2cinfo->val_size-1-j))&0xff;
61         }
62         bufp = buf;
63         onelen = i2cinfo->val_size + i2cinfo->reg_size;
64         msg_times = 1;
65     }
66     
67         err = -EAGAIN;    
68     msg->addr = (i2cinfo->slave_addr>>1);
69     msg->flags = 0;
70     msg->scl_rate = i2cinfo->speed;
71    // msg->read_type = 0; 
72     msg->len = onelen;
73     for (i=0; i<msg_times; i++) {        
74         msg->buf = bufp+i*onelen;        
75                 err = i2c_transfer(adapter, msg, 1);            
76                 if (err < 0) {
77             camsys_err("i2c write dev(addr:0x%x) failed!",i2cinfo->slave_addr);
78                         udelay(10);
79                 }
80     }
81
82 end:
83     return err;
84 }
85
86 static int camsys_i2c_read(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
87 {
88     int err = 0,i,retry=2,tmp;
89     unsigned char buf[8];
90     struct i2c_msg msg[2];
91     struct i2c_adapter *adapter;
92     
93     adapter = i2c_get_adapter(i2cinfo->bus_num);
94     if (adapter == NULL) {
95         camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
96         err = -EINVAL;
97         goto end;
98     }
99     
100     for (i=0; i<i2cinfo->reg_size; i++) {
101         buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
102     }
103
104     msg[0].addr = (i2cinfo->slave_addr>>1);
105         msg[0].flags = 0;
106         msg[0].scl_rate = i2cinfo->speed;
107         //msg[0].read_type = 0;
108     msg[0].buf = buf;
109     msg[0].len = i2cinfo->reg_size;
110     
111     msg[1].addr = (i2cinfo->slave_addr>>1);
112         msg[1].flags = I2C_M_RD;
113         msg[1].scl_rate = i2cinfo->speed;
114 //      msg[1].read_type = 0;
115     msg[1].buf = buf;
116     msg[1].len = (unsigned short)i2cinfo->val_size;
117         err = -EAGAIN;    
118
119         while ((retry-- > 0) && (err < 0)) {                                             /* ddl@rock-chips.com :  Transfer again if transent is failed   */
120                 err = i2c_transfer(adapter, msg, 2);
121         
122                 if (err >= 0) {
123             err = 0;
124                 } else {
125                         camsys_err("i2c read dev(addr:0x%x) failed,try again-%d!",i2cinfo->slave_addr,retry);
126                         udelay(10);
127                 }
128         }
129
130     if (err==0) {        
131         i2cinfo->val = 0x00;
132         for(i=0; i<i2cinfo->val_size; i++) {
133             tmp = buf[i];
134             i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
135         }
136     }
137     
138 end:
139     return err;
140 }
141
142
143 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *camsys_dev)
144 {
145     int err = 0,i;
146     camsys_extdev_t *extdev;
147     camsys_regulator_info_t *regulator_info;
148     camsys_regulator_t *regulator;
149     camsys_gpio_info_t *gpio_info;
150     camsys_gpio_t *gpio;
151     
152     if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
153         err = -EINVAL;
154         camsys_err("dev_id: 0x%x is not support for camsys!",devio->dev_id);
155         goto end;
156     }  
157
158     extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
159     if (extdev != NULL) {
160         err = 0;
161         camsys_warn("Extdev(dev_id: 0x%x) has been registered in %s!",
162             devio->dev_id, dev_name(camsys_dev->miscdev.this_device));
163         goto end;
164     }
165
166     extdev = kzalloc(sizeof(camsys_extdev_t),GFP_KERNEL);
167     if (extdev == NULL) {
168         camsys_err("alloc camsys_extdev_t failed!");
169         err = -ENOMEM;
170         goto end;
171     }
172     
173     extdev->dev_cfg = devio->dev_cfg;
174     
175     regulator_info = &devio->avdd;
176     regulator = &extdev->avdd;
177     for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
178         if (strcmp(regulator_info->name,"NC")) {
179             regulator->ldo = regulator_get(NULL,regulator_info->name);
180             if (IS_ERR_OR_NULL(regulator->ldo)) {
181                 camsys_err("Get %s regulator for dev_id 0x%x failed!",regulator_info->name,devio->dev_id);
182                 err = -EINVAL;
183                 goto fail;
184             }
185             
186             regulator->min_uv = regulator_info->min_uv;
187             regulator->max_uv = regulator_info->max_uv;
188             camsys_trace(1,"Get %s regulator(min: %duv  max: %duv) for dev_id 0x%x success",
189                         regulator_info->name,regulator->min_uv,regulator->max_uv,
190                         devio->dev_id);
191         } else {
192             regulator->ldo = NULL;
193             regulator->min_uv = 0;
194             regulator->max_uv = 0;
195         }
196
197         regulator++;
198         regulator_info++;
199     }
200
201     gpio_info = &devio->pwrdn;
202     gpio = &extdev->pwrdn;
203     for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
204         if (strcmp(gpio_info->name,"NC")) {
205             gpio->io = camsys_gpio_get(gpio_info->name);
206             if (gpio->io < 0) {
207                 camsys_err("Get %s gpio for dev_id 0x%x failed!",gpio_info->name,devio->dev_id);
208                 err = -EINVAL;
209                 goto fail;
210             }
211             if (gpio_request(gpio->io,"camsys_gpio")<0) {
212                 camsys_err("Request %s(%d) failed",gpio_info->name,gpio->io);
213             }
214             gpio->active = gpio_info->active;
215             camsys_trace(1,"Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
216                         gpio_info->name,gpio->io,gpio->active,devio->dev_id);
217         } else {
218             gpio->io = 0xffffffff;
219             gpio->active = 0xffffffff;
220         }
221
222         gpio++;
223         gpio_info++;
224     }
225
226     extdev->pdev = camsys_dev->pdev;
227     extdev->phy = devio->phy;
228     extdev->clk = devio->clk;
229     extdev->dev_id = devio->dev_id;
230     //spin_lock(&camsys_dev->lock);
231     mutex_lock(&camsys_dev->extdevs.mut);
232     list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
233     //spin_unlock(&camsys_dev->lock);
234     mutex_unlock(&camsys_dev->extdevs.mut);
235
236     camsys_dev->iomux(extdev, (void*)camsys_dev);
237
238     camsys_trace(1,"Extdev(dev_id: 0x%x) register success",extdev->dev_id);
239
240     return 0;
241 fail:
242     if (extdev) { 
243         kfree(extdev);
244         extdev = NULL;
245     }
246 end:
247     
248     return err;
249 }
250
251 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
252 {
253     int err = 0,i;
254     camsys_extdev_t *extdev;
255     camsys_regulator_t *regulator;
256     camsys_gpio_t *gpio;
257
258     if (all == false) {
259         if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
260             err = -EINVAL;
261             camsys_err("dev_id: 0x%x is not support for %s!",dev_id, dev_name(camsys_dev->miscdev.this_device));
262             goto end;
263         }
264
265         extdev = camsys_find_extdev(dev_id, camsys_dev);
266         if (extdev != NULL) {
267             err = -EINVAL;
268             camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
269                 dev_id, dev_name(camsys_dev->miscdev.this_device));
270             goto end;
271         }
272
273         regulator = &extdev->avdd;
274         for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
275             if (!IS_ERR_OR_NULL(regulator->ldo)) {
276                 while(regulator_is_enabled(regulator->ldo)>0)   
277                             regulator_disable(regulator->ldo);
278                         regulator_put(regulator->ldo);
279             }
280             regulator++;
281         }
282
283         gpio = &extdev->pwrdn;
284         for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
285             if (gpio->io!=0xffffffff) {                    
286                 gpio_free(gpio->io);
287             }
288             gpio++;
289         }
290
291         //spin_lock(&camsys_dev->lock);
292         mutex_lock(&camsys_dev->extdevs.mut);
293         list_del_init(&extdev->list);
294         list_del_init(&extdev->active);
295         //spin_unlock(&camsys_dev->lock);
296         mutex_unlock(&camsys_dev->extdevs.mut);
297         kfree(extdev);
298         extdev = NULL;
299         camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
300     } else {
301         //spin_lock(&camsys_dev->lock);
302         mutex_lock(&camsys_dev->extdevs.mut);
303         while (!list_empty(&camsys_dev->extdevs.list)) {
304
305             extdev = list_first_entry(&camsys_dev->extdevs.list, camsys_extdev_t, list);
306             if (extdev) {
307                 regulator = &extdev->avdd;
308                 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
309                     if (!IS_ERR(regulator->ldo)) {
310                         while(regulator_is_enabled(regulator->ldo)>0)   
311                                     regulator_disable(regulator->ldo);
312                                 regulator_put(regulator->ldo);
313                     }
314                     regulator++; 
315                 }
316
317                 gpio = &extdev->pwrdn;
318                 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
319                     if (gpio->io!=0xffffffff) {                    
320                         gpio_free(gpio->io);
321                     }
322                     gpio++;
323                 }
324                 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
325                 list_del_init(&extdev->list);
326                 list_del_init(&extdev->active);
327                 kfree(extdev);
328                 extdev=NULL;
329             }
330         }
331         //spin_unlock(&camsys_dev->lock);        
332         mutex_unlock(&camsys_dev->extdevs.mut);
333         camsys_trace(1, "All extdev is deregister success!");
334     }
335     
336
337 end:    
338     return err;
339
340 }
341
342 static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
343 {
344     int i;
345     int err = 0;    
346     camsys_extdev_t *extdev,*extdev2;
347
348     //spin_lock(&camsys_dev->lock);
349     mutex_lock(&camsys_dev->extdevs.mut);
350         if(devctl->ops == 0xaa){
351                 dump_stack();
352                 return 0;
353         }
354     //Internal 
355     if (camsys_dev->dev_id & devctl->dev_mask) {
356         switch (devctl->ops)
357         {
358             case CamSys_ClkIn:
359             {
360                 camsys_dev->clkin_cb(camsys_dev,devctl->on);
361                 break;
362             }
363
364             case CamSys_Rst:
365             {
366                 camsys_dev->reset_cb(camsys_dev, devctl->on);
367                 break;
368             }            
369             default:
370                 break;
371
372         }
373     }
374
375     //External
376     for (i=0; i<8; i++) {
377         if (devctl->dev_mask & (1<<(i+24))) {
378             extdev = camsys_find_extdev((1<<(i+24)), camsys_dev);
379             if (extdev) {
380                 camsys_sysctl_extdev(extdev, devctl, camsys_dev);
381
382                 if (devctl->ops == CamSys_ClkIn) {
383                     if (devctl->on) {
384                         list_add_tail(&extdev->active,&camsys_dev->extdevs.active);
385                     } else {
386                         if (!list_empty(&camsys_dev->extdevs.active)) {    /* ddla@rock-chips.com: v0.0.7 */
387                             list_for_each_entry(extdev2, &camsys_dev->extdevs.active, active) {
388                                 if (extdev2 == extdev) {
389                                     list_del_init(&extdev->active);
390                                     break;
391                                 }
392                             }
393                         }
394                     }
395                 }
396                 
397             } else {
398                 camsys_err("Can not find dev_id 0x%x device in %s!", (1<<(i+24)), dev_name(camsys_dev->miscdev.this_device));
399             }
400         }
401     }
402
403     //spin_unlock(&camsys_dev->lock);
404     mutex_unlock(&camsys_dev->extdevs.mut);
405     return err;
406 }
407 static int camsys_phy_ops (camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, void *ptr)
408 {
409     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
410     camsys_mipiphy_t *mipiphy;
411     int err = 0;
412     
413     if (extdev->phy.type == CamSys_Phy_Mipi) {
414         mipiphy = (camsys_mipiphy_t*)devctl->rev;
415         if (devctl->on == 0) {
416             mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
417             mipiphy->bit_rate = 0;
418             mipiphy->data_en_bit = 0x00;
419         } else {
420             if ((mipiphy->bit_rate == 0) || (mipiphy->data_en_bit == 0)) {
421                 *mipiphy = extdev->phy.info.mipi;
422             }
423             if (mipiphy->phy_index != extdev->phy.info.mipi.phy_index) {
424                 camsys_warn("mipiphy->phy_index(%d) != extdev->phy.info.mipi.phy_index(%d)!",
425                     mipiphy->phy_index,extdev->phy.info.mipi.phy_index);
426                 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
427                 
428             }
429         }
430         err = camsys_dev->mipiphy[mipiphy->phy_index].ops(ptr,mipiphy);
431         if (err < 0) {
432             camsys_err("extdev(0x%x) mipi phy ops config failed!",extdev->dev_id);
433         }
434     }
435
436     return err;
437 }
438 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev)
439 {
440     int err = 0,i;
441     camsys_irqpool_t *irqpool; 
442     unsigned long int flags;
443
444     if ((irqcnnt->mis != MRV_ISP_MIS) &&
445         (irqcnnt->mis != MRV_MIPI_MIS) &&
446         (irqcnnt->mis != MRV_MI_MIS)) {
447
448         camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate, irq connect failed!",
449             irqcnnt->pid, irqcnnt->mis);
450
451         err = -EINVAL;
452         goto end;
453     }   
454
455     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
456     if (!list_empty(&camsys_dev->irq.irq_pool)) {
457         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
458             if (irqpool->pid == irqcnnt->pid) {
459                 camsys_warn("this thread(pid: %d) had been connect irq!",current->pid);
460                 spin_unlock(&camsys_dev->irq.lock);
461                 goto end;
462             }
463         }
464     }
465     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
466     
467     irqpool = kzalloc(sizeof(camsys_irqpool_t),GFP_KERNEL);
468     if (irqpool) {
469         spin_lock_init(&irqpool->lock);
470         irqpool->pid = irqcnnt->pid;
471         irqpool->timeout = irqcnnt->timeout;
472         irqpool->mis = irqcnnt->mis;
473         irqpool->icr = irqcnnt->icr;
474         INIT_LIST_HEAD(&irqpool->active);
475         INIT_LIST_HEAD(&irqpool->deactive);
476         init_waitqueue_head(&irqpool->done);
477         for (i=0; i<CAMSYS_IRQPOOL_NUM; i++) {
478             list_add_tail(&irqpool->pool[i].list, &irqpool->deactive);
479         }
480     }
481     
482     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
483     //camsys_dev->irq.timeout = irqcnnt->timeout;
484     list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
485     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
486     camsys_trace(1, "Thread(pid: %d) connect %s irq success! mis: 0x%x icr: 0x%x ", irqpool->pid, dev_name(camsys_dev->miscdev.this_device),
487         irqpool->mis,irqpool->icr);
488
489 end:
490     return err;
491 }
492 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
493 {
494     int err;
495     unsigned long int flags;
496     
497     spin_lock_irqsave(&irqpool->lock,flags);
498     err = list_empty(&irqpool->active);
499     spin_unlock_irqrestore(&irqpool->lock,flags);
500
501     return !err;
502     
503 }
504 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
505 {
506     int err = 0;
507     bool find_pool = false;
508     camsys_irqstas_t *irqstas;
509     camsys_irqpool_t *irqpool;
510     unsigned long int flags;
511     
512     spin_lock_irqsave(&camsys_dev->irq.lock,flags);
513     if (!list_empty(&camsys_dev->irq.irq_pool)) {
514         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
515             if (irqpool->pid == current->pid) {
516                 find_pool = true;
517                 break;
518             }
519         }
520     }
521     spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
522
523     if (find_pool == false) {
524         camsys_err("this thread(pid: %d) hasn't been connect irq, so wait irq failed!",current->pid);
525         err = -EINVAL;
526         goto end;
527     }
528     
529     
530     spin_lock_irqsave(&irqpool->lock,flags);
531     if (!list_empty(&irqpool->active)) {
532         irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
533         *irqsta = irqstas->sta;
534         list_del_init(&irqstas->list);
535         list_add_tail(&irqstas->list,&irqpool->deactive);
536         spin_unlock_irqrestore(&irqpool->lock,flags);
537     } else {
538         spin_unlock_irqrestore(&irqpool->lock,flags);
539         
540         wait_event_interruptible_timeout(irqpool->done,
541             active_list_isnot_empty(irqpool),
542             usecs_to_jiffies(irqpool->timeout));
543
544         if (irqpool->pid == current->pid) {
545             if (active_list_isnot_empty(irqpool)) {
546                 spin_lock_irqsave(&irqpool->lock,flags);
547                 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
548                 *irqsta = irqstas->sta;
549                 list_del_init(&irqstas->list);
550                 list_add_tail(&irqstas->list,&irqpool->deactive);
551                 spin_unlock_irqrestore(&irqpool->lock,flags);
552             } else {
553                 err = -EAGAIN;
554             }
555         } else {
556             camsys_warn("Thread(pid: %d) has been disconnect!",current->pid);
557             err = -EAGAIN;
558         }
559     }
560
561     if (err == 0) {
562         camsys_trace(3,"Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
563                      current->pid, irqsta->mis, irqsta->ris);
564     }
565
566 end:
567     return err;
568 }
569
570 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev, bool all)
571 {
572     int err = 0;
573     bool find_pool = false;
574     camsys_irqpool_t *irqpool;    
575     unsigned long int flags;
576     
577     if (all == false) {
578         spin_lock_irqsave(&camsys_dev->irq.lock,flags);
579                 if (!list_empty(&camsys_dev->irq.irq_pool)) {
580             list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
581                 if (irqpool->pid == irqcnnt->pid) {
582                     find_pool = true;
583                     irqpool->pid = 0;
584                     break;
585                 }
586             }
587         }
588         spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
589
590         if (find_pool == false) {
591             camsys_err("this thread(pid: %d) have not been connect irq!, disconnect failed",current->pid);         
592         } else {
593             wake_up_all(&irqpool->done);
594         }
595
596         camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!", irqcnnt->pid, dev_name(camsys_dev->miscdev.this_device));
597    } else {
598         spin_lock_irqsave(&camsys_dev->irq.lock,flags);
599         while (!list_empty(&camsys_dev->irq.irq_pool)) {
600             irqpool = list_first_entry(&camsys_dev->irq.irq_pool, camsys_irqpool_t, list);
601             list_del_init(&irqpool->list);
602             irqpool->pid = 0;
603             wake_up_all(&irqpool->done);
604             kfree(irqpool);
605             irqpool = NULL;
606         }
607         spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
608
609         camsys_trace(1, "All thread disconnect %s irq success!", dev_name(camsys_dev->miscdev.this_device));
610    }
611
612
613     return err;
614 }
615
616 static int camsys_querymem (camsys_dev_t *camsys_dev,  camsys_querymem_t *qmem)
617 {
618     int err = 0;
619     
620     if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
621         if (camsys_dev->devmems.registermem == NULL) {
622             camsys_err("%s register memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
623             err = -EINVAL;
624             goto end;
625         }
626
627         qmem->mem_size = camsys_dev->devmems.registermem->size;
628         qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
629     } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
630         if (camsys_dev->devmems.i2cmem== NULL) {
631             camsys_err("%s i2c memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
632             err = -EINVAL;
633             goto end;
634         }
635
636         qmem->mem_size = camsys_dev->devmems.i2cmem->size;
637         qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
638     } else {
639         camsys_err("%d memory type have not in %s memory list",qmem->mem_type,dev_name(camsys_dev->miscdev.this_device));
640         err = -EINVAL;
641         goto end;
642     }
643     
644
645     return 0;
646 end: 
647     return err;
648 }
649 static int camsys_open(struct inode *inode, struct file *file)
650 {
651     int err = 0;
652     int minor = iminor(inode);
653     camsys_dev_t *camsys_dev;
654     unsigned int i,phycnt;
655
656     spin_lock(&camsys_devs.lock);
657     list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
658         if (camsys_dev->miscdev.minor == minor) {
659             file->private_data = (void*)(camsys_dev);
660             break;
661         }
662     }
663     spin_unlock(&camsys_devs.lock);
664
665     //zyc add
666     INIT_LIST_HEAD(&camsys_dev->extdevs.active);
667     
668     if (camsys_dev->mipiphy != NULL) {
669         phycnt = camsys_dev->mipiphy[0].phycnt;
670          
671         for (i=0; i<phycnt; i++) {
672             if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
673                 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,1);
674             }
675         }
676     }
677
678     
679     if (file->private_data == NULL) {
680         camsys_err("Cann't find camsys_dev!");
681         err = -ENODEV;
682         goto end;
683     } else {     
684         camsys_trace(1,"%s(%p) is opened!",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
685     }
686
687 end:
688     return err;
689 }
690
691 static int camsys_release(struct inode *inode, struct file *file)
692 {
693     camsys_dev_t *camsys_dev = (camsys_dev_t*)file->private_data;
694     unsigned int i,phycnt;
695     
696     camsys_irq_disconnect(NULL,camsys_dev, true);
697
698     if (camsys_dev->mipiphy != NULL) {
699         phycnt = camsys_dev->mipiphy[0].phycnt;
700          
701         for (i=0; i<phycnt; i++) {
702             if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
703                 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,0);
704             }
705         }
706     }
707
708     camsys_trace(1,"%s(%p) is closed",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
709
710     return 0;
711 }
712
713 /*
714 * The ioctl() implementation
715 */
716
717 static long camsys_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
718 {
719         long err = 0;
720     camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data; 
721     
722         if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) { 
723         camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
724         err = -ENOTTY;
725         goto end;
726         }
727         if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
728         camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
729         err = -ENOTTY;
730         goto end;
731         }
732
733     if (_IOC_DIR(cmd) & _IOC_READ)
734         err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));     
735     else if (_IOC_DIR(cmd) & _IOC_WRITE)
736         err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
737
738     if (err) {
739         camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
740         err = -EFAULT;
741         goto end;
742     }
743
744         switch (cmd) {
745
746             case CAMSYS_VERCHK:
747             {
748                 camsys_version_t camsys_ver;
749                 
750             camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
751             camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
752             if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
753                 return -EFAULT;
754             break;
755             }
756
757             case CAMSYS_I2CRD:
758             {
759                 camsys_i2c_info_t i2cinfo;
760                 
761             if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t))) 
762                 return -EFAULT;
763
764             err = camsys_i2c_read(&i2cinfo,camsys_dev);
765             if (err==0) {
766                 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
767                     return -EFAULT;
768             }
769             break;
770             }
771
772             case CAMSYS_I2CWR:
773             {
774             camsys_i2c_info_t i2cinfo;
775                 
776             if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t))) 
777                 return -EFAULT;
778
779             err = camsys_i2c_write(&i2cinfo,camsys_dev);
780             break;
781             }
782
783         case CAMSYS_SYSCTRL:
784         {
785             camsys_sysctrl_t devctl;
786
787             if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t))) 
788                 return -EFAULT;
789
790             err = camsys_sysctl(&devctl, camsys_dev);
791             break;
792         }
793
794         case CAMSYS_REGRD:
795         {
796
797             break;
798         }
799
800         case CAMSYS_REGWR:
801         {
802
803             break;
804         }
805
806         case CAMSYS_REGISTER_DEVIO:
807         {
808             camsys_devio_name_t devio;
809
810             if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t))) 
811                 return -EFAULT;
812
813             err = camsys_extdev_register(&devio,camsys_dev);
814             break;
815         }
816
817         case CAMSYS_DEREGISTER_DEVIO:
818         {
819             unsigned int dev_id;
820
821             if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
822                 return -EFAULT;
823
824             err = camsys_extdev_deregister(dev_id, camsys_dev, false);
825             break;
826         }
827
828         case CAMSYS_IRQCONNECT:
829         {
830             camsys_irqcnnt_t irqcnnt;
831
832             if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t))) 
833                 return -EFAULT;
834             
835             err = camsys_irq_connect(&irqcnnt, camsys_dev);
836             
837             break;
838         }
839
840         case CAMSYS_IRQWAIT:
841         {
842             camsys_irqsta_t irqsta;
843
844             err = camsys_irq_wait(&irqsta, camsys_dev);
845             if (err==0) {
846                 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t))) 
847                     return -EFAULT;
848             }
849             break;
850         }
851
852         case CAMSYS_IRQDISCONNECT:
853         {
854             camsys_irqcnnt_t irqcnnt;
855
856             if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t))) 
857                 return -EFAULT;
858             err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
859                         break;
860         }
861
862         
863         case CAMSYS_QUREYMEM:
864         {
865             camsys_querymem_t qmem;
866
867             if (copy_from_user((void*)&qmem,(void __user *)arg, sizeof(camsys_querymem_t))) 
868                 return -EFAULT;
869             
870             err = camsys_querymem(camsys_dev,&qmem);
871             if (err == 0) {
872                 if (copy_to_user((void __user *)arg,(void*)&qmem, sizeof(camsys_querymem_t))) 
873                     return -EFAULT;
874             }
875             break;
876         }
877        
878         default :
879             break;
880         }
881
882 end:    
883         return err;
884
885 }
886 /*
887  * VMA operations.
888  */
889 static void camsys_vm_open(struct vm_area_struct *vma)
890 {
891     camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
892
893     meminfo->vmas++;
894     return;
895 }
896
897 static void camsys_vm_close(struct vm_area_struct *vma)
898 {
899     camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
900
901     meminfo->vmas--;
902     return;
903 }
904
905 static const struct vm_operations_struct camsys_vm_ops = {
906         .open           = camsys_vm_open,
907         .close          = camsys_vm_close,
908 };
909
910 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
911 {
912     camsys_dev_t *camsys_dev = (camsys_dev_t*)flip->private_data;
913         unsigned long addr, start, size;    
914         camsys_mmap_type_t mem_type;
915         camsys_meminfo_t *meminfo;              
916         int ret = 0;
917
918     mem_type = vma->vm_pgoff;     
919     
920     if (mem_type == CamSys_Mmap_RegisterMem) {
921         if (camsys_dev->devmems.registermem != NULL) {
922             meminfo = camsys_dev->devmems.registermem;
923         } else {
924             camsys_err("this camsys device has not register mem!");
925             ret = -EINVAL;
926             goto done;
927         }
928     } else if (mem_type == CamSys_Mmap_I2cMem) {
929         if (camsys_dev->devmems.i2cmem != NULL) {
930             meminfo = camsys_dev->devmems.i2cmem;
931         } else {
932             camsys_err("this camsys device has not i2c mem!");
933             ret = -EINVAL;
934             goto done;
935         }
936     } else {
937         camsys_err("mmap buffer type %d is invalidate!",mem_type);
938         ret = -EINVAL;
939         goto done;
940     }
941     
942     size = vma->vm_end - vma->vm_start;
943     if (size > meminfo->size) {
944         ret = -ENOMEM;
945         camsys_err("mmap size(0x%lx) > memory size(0x%x), so failed!",size,meminfo->size);
946         goto done;
947     }
948     
949         start = vma->vm_start;
950         addr = __phys_to_pfn(meminfo->phy_base);    
951         
952     if (remap_pfn_range(vma, start, addr,size,pgprot_noncached(vma->vm_page_prot))) { 
953         
954         ret = -EAGAIN;
955         goto done;
956     }
957     
958     vma->vm_ops = &camsys_vm_ops;
959     vma->vm_flags |= VM_IO;
960     vma->vm_flags |=VM_ACCOUNT;//same as VM_RESERVED;
961     vma->vm_private_data = (void*)meminfo;
962     camsys_vm_open(vma);
963
964 done:
965         return ret;
966 }
967
968 struct file_operations camsys_fops = {
969         .owner =            THIS_MODULE,
970     .open =             camsys_open,
971     .release =          camsys_release,
972         .unlocked_ioctl =   camsys_ioctl,
973         .mmap =             camsys_mmap,
974 };
975
976 static int camsys_platform_probe(struct platform_device *pdev){
977     int err = 0;
978         camsys_dev_t *camsys_dev;
979     struct resource register_res ;
980     struct device *dev = &pdev->dev;
981     unsigned long i2cmem;
982         camsys_meminfo_t *meminfo;
983     unsigned int irq_id;
984     
985     err = of_address_to_resource(dev->of_node, 0, &register_res);
986     if (err < 0){
987         camsys_err("Get register resource from %s platform device failed!",pdev->name);
988         err = -ENODEV;
989         goto fail_end;
990     }
991
992  
993     //map irqs
994     irq_id = irq_of_parse_and_map(dev->of_node, 0);
995     if (irq_id < 0) {
996         camsys_err("Get irq resource from %s platform device failed!",pdev->name);
997         err = -ENODEV;
998         goto fail_end;
999     }
1000
1001     camsys_dev = (camsys_dev_t*)devm_kzalloc(&pdev->dev,sizeof(camsys_dev_t), GFP_KERNEL);
1002     if (camsys_dev == NULL) {
1003         camsys_err("Allocate camsys_dev for %s platform device failed",pdev->name);
1004         err = -ENOMEM;
1005         goto fail_end;
1006     }
1007
1008     //spin_lock_init(&camsys_dev->lock);
1009     mutex_init(&camsys_dev->extdevs.mut);
1010     INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1011     INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1012     INIT_LIST_HEAD(&camsys_dev->list);
1013     
1014
1015     //IRQ init
1016     camsys_dev->irq.irq_id = irq_id;  
1017     spin_lock_init(&camsys_dev->irq.lock);
1018     INIT_LIST_HEAD(&camsys_dev->irq.irq_pool); 
1019     //init_waitqueue_head(&camsys_dev->irq.irq_done);
1020     
1021     INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1022
1023     // get soc operation
1024     camsys_dev->soc = (void*)camsys_soc_get();
1025     if (camsys_dev->soc == NULL) {
1026         err = -ENODEV;
1027         goto fail_end;
1028     }
1029
1030     //Register mem init
1031     meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1032     if (meminfo == NULL) {
1033         err = -ENOMEM;
1034         goto request_mem_fail;
1035     }
1036
1037     meminfo->vir_base = (unsigned int)devm_ioremap_resource(dev, &register_res);
1038     if (!meminfo->vir_base){
1039         camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), CAMSYS_REGISTER_MEM_NAME);
1040         err = -ENXIO;
1041         goto request_mem_fail;
1042     }
1043
1044     strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME,sizeof(meminfo->name));
1045     meminfo->phy_base = register_res.start;
1046     meminfo->size = register_res.end - register_res.start + 1;  
1047     list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1048
1049
1050     //I2c mem init
1051     i2cmem = __get_free_page(GFP_KERNEL);
1052     if (i2cmem == 0) {
1053         camsys_err("Allocate i2cmem failed!");
1054         err = -ENOMEM;
1055         goto request_mem_fail;
1056     }
1057     SetPageReserved(virt_to_page(i2cmem));
1058     
1059     meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1060     if (meminfo == NULL) {
1061         err = -ENOMEM;
1062         goto request_mem_fail;
1063     }
1064     strlcpy(meminfo->name,CAMSYS_I2C_MEM_NAME,sizeof(meminfo->name));
1065     meminfo->vir_base = i2cmem;
1066     meminfo->phy_base = virt_to_phys((void*)i2cmem);
1067     meminfo->size = PAGE_SIZE;
1068     list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1069
1070     {
1071         unsigned int *tmpp;
1072
1073         tmpp = (unsigned int*)meminfo->vir_base;
1074         *tmpp = 0xfa561243;
1075     }
1076
1077     //Special init
1078
1079     {        
1080         if (camsys_mipiphy_probe_cb(pdev, camsys_dev) <0) {
1081             camsys_err("Mipi phy probe failed!");
1082         }
1083     }
1084
1085 #if 0
1086     if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_MARVIN_NAME) == 0) {
1087         #if (defined(CONFIG_CAMSYS_MRV))
1088         camsys_mrv_probe_cb(pdev, camsys_dev);        
1089         #else
1090         camsys_err("Marvin controller camsys driver haven't been complie!!!");
1091         #endif
1092     } else {
1093         #if (defined(CONFIG_CAMSYS_CIF))
1094         camsys_cif_probe_cb(pdev,camsys_dev);
1095         #else
1096         camsys_err("CIF controller camsys driver haven't been complie!!!");
1097         #endif
1098     }
1099 #else
1100         #if (defined(CONFIG_CAMSYS_MRV))
1101         camsys_mrv_probe_cb(pdev, camsys_dev);        
1102         #elif (defined(CONFIG_CAMSYS_CIF))
1103         camsys_cif_probe_cb(pdev,camsys_dev);
1104         #else
1105         camsys_err("camsys driver haven't been complie!!!");
1106         #endif
1107 #endif
1108     camsys_trace(1, "%s memory:",dev_name(&pdev->dev));
1109     list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1110         if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME) == 0) {
1111             camsys_dev->devmems.i2cmem = meminfo;
1112             camsys_trace(1,"    I2c memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1113                         meminfo->phy_base,meminfo->vir_base,meminfo->size);
1114         }
1115         if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME) == 0) {
1116             camsys_dev->devmems.registermem = meminfo;
1117             camsys_trace(1,"    Register memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1118                         meminfo->phy_base,meminfo->vir_base,meminfo->size);
1119         }
1120     }
1121
1122
1123     camsys_dev->phy_cb = camsys_phy_ops;
1124     camsys_dev->pdev    =   pdev;
1125
1126     platform_set_drvdata(pdev,(void*)camsys_dev);
1127     //Camsys_devs list add    
1128     spin_lock(&camsys_devs.lock);    
1129     list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1130     spin_unlock(&camsys_devs.lock);
1131
1132     
1133     camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1134     return 0;
1135 request_mem_fail:
1136     if (camsys_dev != NULL) {
1137     
1138         while(!list_empty(&camsys_dev->devmems.memslist)) {
1139             meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1140             if (meminfo) {
1141                 list_del_init(&meminfo->list);
1142                 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1143                     iounmap((void __iomem *)meminfo->vir_base);
1144                     release_mem_region(meminfo->phy_base,meminfo->size);
1145                 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1146                     kfree((void*)meminfo->vir_base);
1147                 }
1148                 kfree(meminfo);
1149                 meminfo = NULL;
1150             }
1151         } 
1152     
1153         kfree(camsys_dev);
1154         camsys_dev = NULL;
1155     }
1156 fail_end:
1157     return -1;
1158
1159     
1160 }
1161 static int  camsys_platform_remove(struct platform_device *pdev)
1162 {
1163     camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1164     camsys_meminfo_t *meminfo;
1165     
1166     if (camsys_dev) {
1167
1168         //Mem deinit
1169         while(!list_empty(&camsys_dev->devmems.memslist)) {
1170             meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1171             if (meminfo) {
1172                 list_del_init(&meminfo->list);
1173                 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1174                     iounmap((void __iomem *)meminfo->vir_base);
1175                     release_mem_region(meminfo->phy_base,meminfo->size);
1176                 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1177                     kfree((void*)meminfo->vir_base);
1178                 }
1179                 kfree(meminfo);
1180                 meminfo = NULL;
1181             }
1182         }        
1183
1184         //Irq deinit
1185         if (camsys_dev->irq.irq_id) {
1186             free_irq(camsys_dev->irq.irq_id, camsys_dev);
1187             camsys_irq_disconnect(NULL,camsys_dev,true);
1188         }
1189
1190         //Extdev deinit
1191         if (!list_empty(&camsys_dev->extdevs.list)) {
1192             camsys_extdev_deregister(0,camsys_dev,true);
1193         }
1194         if (camsys_dev->mipiphy != NULL) {
1195             camsys_dev->mipiphy->remove(pdev);
1196         }
1197         if (camsys_dev->cifphy.remove)
1198             camsys_dev->cifphy.remove(pdev);
1199         camsys_dev->platform_remove(pdev);
1200
1201         misc_deregister(&camsys_dev->miscdev);
1202         
1203         spin_lock(&camsys_devs.lock);
1204         list_del_init(&camsys_dev->list);
1205         spin_unlock(&camsys_devs.lock);
1206
1207         kfree(camsys_dev);
1208         camsys_dev=NULL;
1209     } else {
1210         camsys_err("This platform device havn't obtain camsys_dev!");
1211     }
1212
1213     return 0;
1214 }
1215
1216
1217 static const struct of_device_id cif_of_match[] = {
1218     { .compatible = "rockchip,isp" },
1219 };
1220 MODULE_DEVICE_TABLE(of, cif_of_match);
1221
1222 static struct platform_driver camsys_platform_driver =
1223 {
1224     .driver     = {
1225         .name   = CAMSYS_PLATFORM_DRV_NAME,
1226         .of_match_table = of_match_ptr(cif_of_match),
1227     },
1228     .probe              = camsys_platform_probe,
1229     .remove             = (camsys_platform_remove),
1230 };
1231
1232 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1233 static int __init camsys_platform_init(void)  
1234 {
1235     printk("CamSys driver version: v%d.%d.%d,  CamSys head file version: v%d.%d.%d\n",
1236         (CAMSYS_DRIVER_VERSION&0xff0000)>>16, (CAMSYS_DRIVER_VERSION&0xff00)>>8,
1237         CAMSYS_DRIVER_VERSION&0xff,
1238         (CAMSYS_HEAD_VERSION&0xff0000)>>16, (CAMSYS_HEAD_VERSION&0xff00)>>8,
1239         CAMSYS_HEAD_VERSION&0xff);
1240
1241     spin_lock_init(&camsys_devs.lock);
1242     INIT_LIST_HEAD(&camsys_devs.devs);
1243     camsys_soc_init();
1244     platform_driver_register(&camsys_platform_driver);
1245    // platform_driver_probe(&camsys_platform_driver, camsys_platform_probe_new);
1246     
1247     return 0;
1248 }  
1249   
1250 static void __exit camsys_platform_exit(void)  
1251 {
1252     platform_driver_unregister(&camsys_platform_driver);
1253     camsys_soc_deinit();
1254
1255
1256 module_init(camsys_platform_init);              
1257 module_exit(camsys_platform_exit);      
1258
1259 MODULE_DESCRIPTION("RockChip Camera System");
1260 MODULE_AUTHOR("<ddl@rock-chips>");
1261 MODULE_LICENSE("GPL");
1262