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