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