1 #include <media/camsys_head.h>
3 #include "camsys_cif.h"
4 #include "camsys_marvin.h"
5 #include "camsys_mipicsi_phy.h"
6 #include "camsys_gpio.h"
8 unsigned int camsys_debug=1;
9 module_param(camsys_debug, int, S_IRUGO|S_IWUSR);
11 static int drv_version = CAMSYS_DRIVER_VERSION;
12 module_param(drv_version, int, S_IRUGO);
13 static int head_version = CAMSYS_HEAD_VERSION;
14 module_param(head_version, int, S_IRUGO);
17 typedef struct camsys_devs_s {
19 struct list_head devs;
22 static camsys_devs_t camsys_devs;
24 static int camsys_i2c_write(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
27 unsigned char buf[8],*bufp;
28 unsigned short msg_times,totallen,onelen;
29 struct i2c_msg msg[1];
30 struct i2c_adapter *adapter;
31 camsys_extdev_t *extdev;
33 adapter = i2c_get_adapter(i2cinfo->bus_num);
34 if (adapter == NULL) {
35 camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
40 if (i2cinfo->i2cbuf_directly) {
41 if (camsys_dev->devmems.i2cmem == NULL) {
42 camsys_err("%s has not i2c mem, it isn't support i2c buf write!",dev_name(camsys_dev->miscdev.this_device));
46 totallen = (i2cinfo->i2cbuf_bytes&0xffff);
47 onelen = (i2cinfo->i2cbuf_bytes&0xffff0000)>>16;
48 msg_times = totallen/onelen;
49 if (totallen > camsys_dev->devmems.i2cmem->size) {
50 camsys_err("Want to write 0x%x bytes, i2c memory(size: 0x%x) is overlap",totallen,camsys_dev->devmems.i2cmem->size);
54 bufp = (unsigned char*)camsys_dev->devmems.i2cmem->vir_base;
56 for (i=0; i<i2cinfo->reg_size; i++) {
57 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
59 for (j=0; j<i2cinfo->val_size; j++) {
60 buf[i+j] = (i2cinfo->val>>(i2cinfo->val_size-1-j))&0xff;
63 onelen = i2cinfo->val_size + i2cinfo->reg_size;
68 msg->addr = (i2cinfo->slave_addr>>1);
70 msg->scl_rate = i2cinfo->speed;
71 // msg->read_type = 0;
73 for (i=0; i<msg_times; i++) {
74 msg->buf = bufp+i*onelen;
75 err = i2c_transfer(adapter, msg, 1);
77 camsys_err("i2c write dev(addr:0x%x) failed!",i2cinfo->slave_addr);
84 #if ((defined CONFIG_ARCH_RK319X) || (CONFIG_ARCH_ROCKCHIP))
85 if (!list_empty(&camsys_dev->extdevs.active)) {
86 list_for_each_entry(extdev, &camsys_dev->extdevs.active, active) {
87 if (extdev->phy.type == CamSys_Phy_Cif) {
88 if (extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b) {
89 //iomux_set(CIF0_D0); // ZYC FOR 32
90 //iomux_set(CIF0_D1); // ZYC FOR 32
100 static int camsys_i2c_read(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
102 int err = 0,i,retry=2,tmp;
103 unsigned char buf[8];
104 struct i2c_msg msg[2];
105 struct i2c_adapter *adapter;
106 camsys_extdev_t *extdev;
108 adapter = i2c_get_adapter(i2cinfo->bus_num);
109 if (adapter == NULL) {
110 camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
115 for (i=0; i<i2cinfo->reg_size; i++) {
116 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
119 msg[0].addr = (i2cinfo->slave_addr>>1);
121 msg[0].scl_rate = i2cinfo->speed;
122 //msg[0].read_type = 0;
124 msg[0].len = i2cinfo->reg_size;
126 msg[1].addr = (i2cinfo->slave_addr>>1);
127 msg[1].flags = I2C_M_RD;
128 msg[1].scl_rate = i2cinfo->speed;
129 // msg[1].read_type = 0;
131 msg[1].len = (unsigned short)i2cinfo->val_size;
134 while ((retry-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */
135 err = i2c_transfer(adapter, msg, 2);
140 camsys_err("i2c read dev(addr:0x%x) failed,try again-%d!",i2cinfo->slave_addr,retry);
147 for(i=0; i<i2cinfo->val_size; i++) {
149 i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
155 #if ((defined CONFIG_ARCH_RK319X) || (CONFIG_ARCH_ROCKCHIP))
156 if (!list_empty(&camsys_dev->extdevs.active)) {
157 list_for_each_entry(extdev, &camsys_dev->extdevs.active, active) {
158 if (extdev->phy.type == CamSys_Phy_Cif) {
159 if (extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b) {
160 //iomux_set(CIF0_D0);//ZYC FOR 32
161 //iomux_set(CIF0_D1);//ZYC FOR 32
172 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *camsys_dev)
175 camsys_extdev_t *extdev;
176 camsys_regulator_info_t *regulator_info;
177 camsys_regulator_t *regulator;
178 camsys_gpio_info_t *gpio_info;
181 if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
183 camsys_err("dev_id: 0x%x is not support for camsys!",devio->dev_id);
188 if (devio->phy.type == CamSys_Phy_Mipi) {
189 if (camsys_find_devmem(CAMSYS_REGISTER_MIPIPHY_RES_NAME, camsys_dev) == NULL) {
190 camsys_err("dev_id: 0x%x is connect to MIPI CSI, but %s isn't support",devio->dev_id,
191 dev_name(camsys_dev->miscdev.this_device));
199 extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
200 if (extdev != NULL) {
202 camsys_warn("Extdev(dev_id: 0x%x) has been registered in %s!",
203 devio->dev_id, dev_name(camsys_dev->miscdev.this_device));
207 extdev = kzalloc(sizeof(camsys_extdev_t),GFP_KERNEL);
208 if (extdev == NULL) {
209 camsys_err("alloc camsys_extdev_t failed!");
214 regulator_info = &devio->avdd;
215 regulator = &extdev->avdd;
216 for (i=0; i<4; i++) {
217 if (strcmp(regulator_info->name,"NC")) {
218 regulator->ldo = regulator_get(NULL,regulator_info->name);
219 if (IS_ERR(regulator->ldo)) {
220 camsys_err("Get %s regulator for dev_id 0x%x failed!",regulator_info->name,devio->dev_id);
225 regulator->min_uv = regulator_info->min_uv;
226 regulator->max_uv = regulator_info->max_uv;
227 camsys_trace(1,"Get %s regulator(min: %duv max: %duv) for dev_id 0x%x success",
228 regulator_info->name,regulator->min_uv,regulator->max_uv,
231 regulator->ldo = NULL;
232 regulator->min_uv = 0;
233 regulator->max_uv = 0;
240 gpio_info = &devio->pwrdn;
241 gpio = &extdev->pwrdn;
242 for (i=0; i<5; i++) {
243 if (strcmp(gpio_info->name,"NC")) {
244 gpio->io = camsys_gpio_get(gpio_info->name);
246 camsys_err("Get %s gpio for dev_id 0x%x failed!",gpio_info->name,devio->dev_id);
250 if (gpio_request(gpio->io,"camsys_gpio")<0) {
251 camsys_err("Request %s(%d) failed",gpio_info->name,gpio->io);
253 gpio->active = gpio_info->active;
254 camsys_trace(1,"Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
255 gpio_info->name,gpio->io,gpio->active,devio->dev_id);
257 gpio->io = 0xffffffff;
258 gpio->active = 0xffffffff;
265 extdev->pdev = camsys_dev->pdev;
266 extdev->phy = devio->phy;
267 extdev->clk = devio->clk;
268 extdev->dev_id = devio->dev_id;
269 //spin_lock(&camsys_dev->lock);
270 mutex_lock(&camsys_dev->extdevs.mut);
271 list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
272 //spin_unlock(&camsys_dev->lock);
273 mutex_unlock(&camsys_dev->extdevs.mut);
275 camsys_dev->iomux(extdev, (void*)camsys_dev);
277 camsys_trace(1,"Extdev(dev_id: 0x%x) register success",extdev->dev_id);
290 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
293 camsys_extdev_t *extdev;
294 camsys_regulator_t *regulator;
298 if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
300 camsys_err("dev_id: 0x%x is not support for %s!",dev_id, dev_name(camsys_dev->miscdev.this_device));
304 extdev = camsys_find_extdev(dev_id, camsys_dev);
305 if (extdev != NULL) {
307 camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
308 dev_id, dev_name(camsys_dev->miscdev.this_device));
312 regulator = &extdev->avdd;
313 for (i=0; i<4; i++) {
314 if (!IS_ERR_OR_NULL(regulator->ldo)) {
315 while(regulator_is_enabled(regulator->ldo)>0)
316 regulator_disable(regulator->ldo);
317 regulator_put(regulator->ldo);
322 gpio = &extdev->pwrdn;
323 for (i=0; i<5; i++) {
324 if (gpio->io!=0xffffffff) {
330 //spin_lock(&camsys_dev->lock);
331 mutex_lock(&camsys_dev->extdevs.mut);
332 list_del_init(&extdev->list);
333 list_del_init(&extdev->active);
334 //spin_unlock(&camsys_dev->lock);
335 mutex_unlock(&camsys_dev->extdevs.mut);
338 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
340 //spin_lock(&camsys_dev->lock);
341 mutex_lock(&camsys_dev->extdevs.mut);
342 while (!list_empty(&camsys_dev->extdevs.list)) {
344 extdev = list_first_entry(&camsys_dev->extdevs.list, camsys_extdev_t, list);
346 regulator = &extdev->avdd;
347 for (i=0; i<4; i++) {
348 if (!IS_ERR(regulator->ldo)) {
349 while(regulator_is_enabled(regulator->ldo)>0)
350 regulator_disable(regulator->ldo);
351 regulator_put(regulator->ldo);
356 gpio = &extdev->pwrdn;
357 for (i=0; i<5; i++) {
358 if (gpio->io!=0xffffffff) {
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);
370 //spin_unlock(&camsys_dev->lock);
371 mutex_unlock(&camsys_dev->extdevs.mut);
372 camsys_trace(1, "All extdev is deregister success!");
381 static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
385 camsys_extdev_t *extdev,*extdev2;
387 //spin_lock(&camsys_dev->lock);
388 mutex_lock(&camsys_dev->extdevs.mut);
389 if(devctl->ops == 0xaa){
394 if (camsys_dev->dev_id & devctl->dev_mask) {
399 camsys_dev->clkin_cb(camsys_dev,devctl->on);
405 camsys_dev->reset_cb(camsys_dev);
410 case CamSys_Gpio_Tag:
412 if((camsys_dev->mipiphy.ops )){
413 camsys_dev->mipiphy.ops(NULL,NULL,devctl->on);
424 for (i=0; i<8; i++) {
425 if (devctl->dev_mask & (1<<(i+24))) {
426 extdev = camsys_find_extdev((1<<(i+24)), camsys_dev);
428 camsys_sysctl_extdev(extdev, devctl, camsys_dev);
430 if (devctl->ops == CamSys_ClkIn) {
432 list_add_tail(&extdev->active,&camsys_dev->extdevs.active);
434 if (!list_empty(&camsys_dev->extdevs.active)) { /* ddla@rock-chips.com: v0.0.7 */
435 list_for_each_entry(extdev2, &camsys_dev->extdevs.active, active) {
436 if (extdev2 == extdev) {
437 list_del_init(&extdev->active);
446 camsys_err("Can not find dev_id 0x%x device in %s!", (1<<(i+24)), dev_name(camsys_dev->miscdev.this_device));
451 //spin_unlock(&camsys_dev->lock);
452 mutex_unlock(&camsys_dev->extdevs.mut);
455 static int camsys_phy_ops (camsys_extdev_phy_t *phy, void* ptr, unsigned int on)
457 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
460 if (phy->type == CamSys_Phy_Mipi) {
461 if (camsys_dev->mipiphy.ops && camsys_dev->mipiphy.clkin_cb) {
462 err = camsys_dev->mipiphy.clkin_cb(camsys_dev,on);
463 err = camsys_dev->mipiphy.ops(&phy->info.mipi,&camsys_dev->mipiphy, on);
465 camsys_err("%s isn't support mipi phy",dev_name(camsys_dev->miscdev.this_device));
468 } else if (phy->type == CamSys_Phy_Cif) {
469 if (camsys_dev->cifphy.ops && camsys_dev->cifphy.clkin_cb) {
470 err = camsys_dev->cifphy.clkin_cb(camsys_dev,on);
471 err = camsys_dev->cifphy.ops(&phy->info.cif,&camsys_dev->cifphy, on);
473 //camsys_err("%s isn't support cif phy",dev_name(camsys_dev->miscdev.this_device));
480 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev)
483 camsys_irqpool_t *irqpool;
484 unsigned long int flags;
486 if ((irqcnnt->mis != MRV_ISP_MIS) &&
487 (irqcnnt->mis != MRV_MIPI_MIS) &&
488 (irqcnnt->mis != MRV_MI_MIS)) {
490 camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate, irq connect failed!",
491 irqcnnt->pid, irqcnnt->mis);
498 if((camsys_dev->mipiphy.ops ) && (irqcnnt->mis == MRV_ISP_MIS)){
499 camsys_dev->mipiphy.ops(NULL,NULL,0);
503 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
504 if (!list_empty(&camsys_dev->irq.irq_pool)) {
505 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
506 if (irqpool->pid == irqcnnt->pid) {
507 camsys_warn("this thread(pid: %d) had been connect irq!",current->pid);
508 spin_unlock(&camsys_dev->irq.lock);
513 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
515 irqpool = kzalloc(sizeof(camsys_irqpool_t),GFP_KERNEL);
517 spin_lock_init(&irqpool->lock);
518 irqpool->pid = irqcnnt->pid;
519 irqpool->timeout = irqcnnt->timeout;
520 irqpool->mis = irqcnnt->mis;
521 irqpool->icr = irqcnnt->icr;
522 INIT_LIST_HEAD(&irqpool->active);
523 INIT_LIST_HEAD(&irqpool->deactive);
524 init_waitqueue_head(&irqpool->done);
525 for (i=0; i<CAMSYS_IRQPOOL_NUM; i++) {
526 list_add_tail(&irqpool->pool[i].list, &irqpool->deactive);
530 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
531 //camsys_dev->irq.timeout = irqcnnt->timeout;
532 list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
533 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
534 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),
535 irqpool->mis,irqpool->icr);
540 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
543 unsigned long int flags;
545 spin_lock_irqsave(&irqpool->lock,flags);
546 err = list_empty(&irqpool->active);
547 spin_unlock_irqrestore(&irqpool->lock,flags);
552 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
555 bool find_pool = false;
556 camsys_irqstas_t *irqstas;
557 camsys_irqpool_t *irqpool;
558 unsigned long int flags;
560 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
561 if (!list_empty(&camsys_dev->irq.irq_pool)) {
562 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
563 if (irqpool->pid == current->pid) {
569 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
571 if (find_pool == false) {
572 camsys_err("this thread(pid: %d) hasn't been connect irq, so wait irq failed!",current->pid);
578 spin_lock_irqsave(&irqpool->lock,flags);
579 if (!list_empty(&irqpool->active)) {
580 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
581 *irqsta = irqstas->sta;
582 list_del_init(&irqstas->list);
583 list_add_tail(&irqstas->list,&irqpool->deactive);
584 spin_unlock_irqrestore(&irqpool->lock,flags);
586 spin_unlock_irqrestore(&irqpool->lock,flags);
588 wait_event_interruptible_timeout(irqpool->done,
589 active_list_isnot_empty(irqpool),
590 usecs_to_jiffies(irqpool->timeout));
592 if (irqpool->pid == current->pid) {
593 if (active_list_isnot_empty(irqpool)) {
594 spin_lock_irqsave(&irqpool->lock,flags);
595 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
596 *irqsta = irqstas->sta;
597 list_del_init(&irqstas->list);
598 list_add_tail(&irqstas->list,&irqpool->deactive);
599 spin_unlock_irqrestore(&irqpool->lock,flags);
601 // camsys_warn("Thread(pid: %d) wait irq timeout!!",current->pid);
605 camsys_warn("Thread(pid: %d) has been disconnect!",current->pid);
611 camsys_trace(3,"Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
612 current->pid, irqsta->mis, irqsta->ris);
619 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev, bool all)
622 bool find_pool = false;
623 camsys_irqpool_t *irqpool;
624 unsigned long int flags;
627 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
628 if (!list_empty(&camsys_dev->irq.irq_pool)) {
629 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
630 if (irqpool->pid == irqcnnt->pid) {
637 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
639 if (find_pool == false) {
640 camsys_err("this thread(pid: %d) have not been connect irq!, disconnect failed",current->pid);
642 wake_up_all(&irqpool->done);
645 camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!", irqcnnt->pid, dev_name(camsys_dev->miscdev.this_device));
647 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
648 while (!list_empty(&camsys_dev->irq.irq_pool)) {
649 irqpool = list_first_entry(&camsys_dev->irq.irq_pool, camsys_irqpool_t, list);
650 list_del_init(&irqpool->list);
652 wake_up_all(&irqpool->done);
656 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
658 camsys_trace(1, "All thread disconnect %s irq success!", dev_name(camsys_dev->miscdev.this_device));
665 static int camsys_querymem (camsys_dev_t *camsys_dev, camsys_querymem_t *qmem)
669 if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
670 if (camsys_dev->devmems.registermem == NULL) {
671 camsys_err("%s register memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
676 qmem->mem_size = camsys_dev->devmems.registermem->size;
677 qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
678 } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
679 if (camsys_dev->devmems.i2cmem== NULL) {
680 camsys_err("%s i2c memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
685 qmem->mem_size = camsys_dev->devmems.i2cmem->size;
686 qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
688 camsys_err("%d memory type have not in %s memory list",qmem->mem_type,dev_name(camsys_dev->miscdev.this_device));
698 static int camsys_open(struct inode *inode, struct file *file)
701 int minor = iminor(inode);
702 camsys_dev_t *camsys_dev;
704 spin_lock(&camsys_devs.lock);
705 list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
706 if (camsys_dev->miscdev.minor == minor) {
707 file->private_data = (void*)(camsys_dev);
711 spin_unlock(&camsys_devs.lock);
714 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
717 if (file->private_data == NULL) {
718 camsys_err("Cann't find camsys_dev!");
722 camsys_trace(1,"%s(%p) is opened!",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
729 static int camsys_release(struct inode *inode, struct file *file)
731 camsys_dev_t *camsys_dev = (camsys_dev_t*)file->private_data;
733 camsys_irq_disconnect(NULL,camsys_dev, true);
735 camsys_trace(1,"%s(%p) is closed",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
741 * The ioctl() implementation
744 static long camsys_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
747 camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data;
749 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
750 camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
754 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
755 camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
760 if (_IOC_DIR(cmd) & _IOC_READ)
761 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
762 else if (_IOC_DIR(cmd) & _IOC_WRITE)
763 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
766 camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
775 camsys_version_t camsys_ver;
777 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
778 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
779 if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
786 camsys_i2c_info_t i2cinfo;
788 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
791 err = camsys_i2c_read(&i2cinfo,camsys_dev);
793 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
801 camsys_i2c_info_t i2cinfo;
803 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
806 err = camsys_i2c_write(&i2cinfo,camsys_dev);
812 camsys_sysctrl_t devctl;
814 if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t)))
817 err = camsys_sysctl(&devctl, camsys_dev);
833 case CAMSYS_REGISTER_DEVIO:
835 camsys_devio_name_t devio;
837 if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t)))
840 err = camsys_extdev_register(&devio,camsys_dev);
844 case CAMSYS_DEREGISTER_DEVIO:
848 if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
851 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
855 case CAMSYS_IRQCONNECT:
857 camsys_irqcnnt_t irqcnnt;
859 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
862 err = camsys_irq_connect(&irqcnnt, camsys_dev);
869 camsys_irqsta_t irqsta;
871 err = camsys_irq_wait(&irqsta, camsys_dev);
873 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t)))
879 case CAMSYS_IRQDISCONNECT:
881 camsys_irqcnnt_t irqcnnt;
883 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
885 err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
890 case CAMSYS_QUREYMEM:
892 camsys_querymem_t qmem;
894 if (copy_from_user((void*)&qmem,(void __user *)arg, sizeof(camsys_querymem_t)))
897 err = camsys_querymem(camsys_dev,&qmem);
899 if (copy_to_user((void __user *)arg,(void*)&qmem, sizeof(camsys_querymem_t)))
916 static void camsys_vm_open(struct vm_area_struct *vma)
918 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
924 static void camsys_vm_close(struct vm_area_struct *vma)
926 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
932 static const struct vm_operations_struct camsys_vm_ops = {
933 .open = camsys_vm_open,
934 .close = camsys_vm_close,
937 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
939 camsys_dev_t *camsys_dev = (camsys_dev_t*)flip->private_data;
940 unsigned long addr, start, size;
941 camsys_mmap_type_t mem_type;
942 camsys_meminfo_t *meminfo;
945 mem_type = vma->vm_pgoff;
947 if (mem_type == CamSys_Mmap_RegisterMem) {
948 if (camsys_dev->devmems.registermem != NULL) {
949 meminfo = camsys_dev->devmems.registermem;
951 camsys_err("this camsys device has not register mem!");
955 } else if (mem_type == CamSys_Mmap_I2cMem) {
956 if (camsys_dev->devmems.i2cmem != NULL) {
957 meminfo = camsys_dev->devmems.i2cmem;
959 camsys_err("this camsys device has not i2c mem!");
964 camsys_err("mmap buffer type %d is invalidate!",mem_type);
969 size = vma->vm_end - vma->vm_start;
970 if (size > meminfo->size) {
972 camsys_err("mmap size(0x%lx) > memory size(0x%x), so failed!",size,meminfo->size);
976 start = vma->vm_start;
977 addr = __phys_to_pfn(meminfo->phy_base);
979 if (remap_pfn_range(vma, start, addr,size,pgprot_noncached(vma->vm_page_prot))) {
985 vma->vm_ops = &camsys_vm_ops;
986 vma->vm_flags |= VM_IO;
987 vma->vm_flags |=VM_ACCOUNT;//same as VM_RESERVED;
988 vma->vm_private_data = (void*)meminfo;
995 struct file_operations camsys_fops = {
996 .owner = THIS_MODULE,
998 .release = camsys_release,
999 .unlocked_ioctl = camsys_ioctl,
1000 .mmap = camsys_mmap,
1003 static int camsys_platform_probe(struct platform_device *pdev){
1005 camsys_dev_t *camsys_dev;
1006 struct resource register_res ;
1007 struct device *dev = &pdev->dev;
1008 unsigned long i2cmem;
1009 camsys_meminfo_t *meminfo;
1010 unsigned int irq_id;
1011 err = of_address_to_resource(dev->of_node, 0, ®ister_res);
1013 camsys_err("Get register resource from %s platform device failed!",pdev->name);
1020 irq_id = irq_of_parse_and_map(dev->of_node, 0);
1022 camsys_err("Get irq resource from %s platform device failed!",pdev->name);
1027 camsys_dev = (camsys_dev_t*)devm_kzalloc(&pdev->dev,sizeof(camsys_dev_t), GFP_KERNEL);
1028 if (camsys_dev == NULL) {
1029 camsys_err("Allocate camsys_dev for %s platform device failed",pdev->name);
1034 //spin_lock_init(&camsys_dev->lock);
1035 mutex_init(&camsys_dev->extdevs.mut);
1036 INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1037 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1038 INIT_LIST_HEAD(&camsys_dev->list);
1042 camsys_dev->irq.irq_id = irq_id;
1043 spin_lock_init(&camsys_dev->irq.lock);
1044 INIT_LIST_HEAD(&camsys_dev->irq.irq_pool);
1045 //init_waitqueue_head(&camsys_dev->irq.irq_done);
1047 INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1051 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1052 if (meminfo == NULL) {
1054 goto request_mem_fail;
1057 meminfo->vir_base = (unsigned int)devm_ioremap_resource(dev, ®ister_res);
1058 if (!meminfo->vir_base){
1059 camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), CAMSYS_REGISTER_MEM_NAME);
1061 goto request_mem_fail;
1064 strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME,sizeof(meminfo->name));
1065 meminfo->phy_base = register_res.start;
1066 meminfo->size = register_res.end - register_res.start + 1;
1067 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1071 i2cmem = __get_free_page(GFP_KERNEL);
1073 camsys_err("Allocate i2cmem failed!");
1075 goto request_mem_fail;
1077 SetPageReserved(virt_to_page(i2cmem));
1079 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1080 if (meminfo == NULL) {
1082 goto request_mem_fail;
1084 strlcpy(meminfo->name,CAMSYS_I2C_MEM_NAME,sizeof(meminfo->name));
1085 meminfo->vir_base = i2cmem;
1086 meminfo->phy_base = virt_to_phys((void*)i2cmem);
1087 meminfo->size = PAGE_SIZE;
1088 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1093 tmpp = (unsigned int*)meminfo->vir_base;
1100 if (camsys_mipiphy_probe_cb(pdev, camsys_dev) <0) {
1101 camsys_err("Mipi phy probe failed!");
1106 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_MARVIN_NAME) == 0) {
1107 #if (defined(CONFIG_CAMSYS_MRV))
1108 camsys_mrv_probe_cb(pdev, camsys_dev);
1110 camsys_err("Marvin controller camsys driver haven't been complie!!!");
1113 #if (defined(CONFIG_CAMSYS_CIF))
1114 camsys_cif_probe_cb(pdev,camsys_dev);
1116 camsys_err("CIF controller camsys driver haven't been complie!!!");
1120 #if (defined(CONFIG_CAMSYS_MRV))
1121 camsys_mrv_probe_cb(pdev, camsys_dev);
1122 #elif (defined(CONFIG_CAMSYS_CIF))
1123 camsys_cif_probe_cb(pdev,camsys_dev);
1125 camsys_err("camsys driver haven't been complie!!!");
1128 camsys_trace(1, "%s memory:",dev_name(&pdev->dev));
1129 list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1130 if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME) == 0) {
1131 camsys_dev->devmems.i2cmem = meminfo;
1132 camsys_trace(1," I2c memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1133 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1135 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME) == 0) {
1136 camsys_dev->devmems.registermem = meminfo;
1137 camsys_trace(1," Register memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1138 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1143 camsys_dev->phy_cb = camsys_phy_ops;
1144 camsys_dev->pdev = pdev;
1146 platform_set_drvdata(pdev,(void*)camsys_dev);
1147 //Camsys_devs list add
1148 spin_lock(&camsys_devs.lock);
1149 list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1150 spin_unlock(&camsys_devs.lock);
1153 camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1156 if (camsys_dev != NULL) {
1158 while(!list_empty(&camsys_dev->devmems.memslist)) {
1159 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1161 list_del_init(&meminfo->list);
1162 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1163 iounmap((void __iomem *)meminfo->vir_base);
1164 release_mem_region(meminfo->phy_base,meminfo->size);
1165 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1166 kfree((void*)meminfo->vir_base);
1181 static int camsys_platform_remove(struct platform_device *pdev)
1183 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1184 camsys_meminfo_t *meminfo;
1189 while(!list_empty(&camsys_dev->devmems.memslist)) {
1190 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1192 list_del_init(&meminfo->list);
1193 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1194 iounmap((void __iomem *)meminfo->vir_base);
1195 release_mem_region(meminfo->phy_base,meminfo->size);
1196 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1197 kfree((void*)meminfo->vir_base);
1205 if (camsys_dev->irq.irq_id) {
1206 free_irq(camsys_dev->irq.irq_id, camsys_dev);
1207 camsys_irq_disconnect(NULL,camsys_dev,true);
1211 if (!list_empty(&camsys_dev->extdevs.list)) {
1212 camsys_extdev_deregister(0,camsys_dev,true);
1215 if (camsys_dev->mipiphy.remove)
1216 camsys_dev->mipiphy.remove(pdev);
1217 if (camsys_dev->cifphy.remove)
1218 camsys_dev->cifphy.remove(pdev);
1219 camsys_dev->platform_remove(pdev);
1221 misc_deregister(&camsys_dev->miscdev);
1223 spin_lock(&camsys_devs.lock);
1224 list_del_init(&camsys_dev->list);
1225 spin_unlock(&camsys_devs.lock);
1230 camsys_err("This platform device havn't obtain camsys_dev!");
1237 static const struct of_device_id cif_of_match[] = {
1238 { .compatible = "rockchip,isp" },
1240 MODULE_DEVICE_TABLE(of, cif_of_match);
1242 static struct platform_driver camsys_platform_driver =
1245 .name = CAMSYS_PLATFORM_DRV_NAME,
1246 .of_match_table = of_match_ptr(cif_of_match),
1248 .probe = camsys_platform_probe,
1249 .remove = (camsys_platform_remove),
1252 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1253 static int __init camsys_platform_init(void)
1255 printk("CamSys driver version: v%d.%d.%d, CamSys head file version: v%d.%d.%d\n",
1256 (CAMSYS_DRIVER_VERSION&0xff0000)>>16, (CAMSYS_DRIVER_VERSION&0xff00)>>8,
1257 CAMSYS_DRIVER_VERSION&0xff,
1258 (CAMSYS_HEAD_VERSION&0xff0000)>>16, (CAMSYS_HEAD_VERSION&0xff00)>>8,
1259 CAMSYS_HEAD_VERSION&0xff);
1260 spin_lock_init(&camsys_devs.lock);
1261 INIT_LIST_HEAD(&camsys_devs.devs);
1262 platform_driver_register(&camsys_platform_driver);
1263 // platform_driver_probe(&camsys_platform_driver, camsys_platform_probe_new);
1268 static void __exit camsys_platform_exit(void)
1270 platform_driver_unregister(&camsys_platform_driver);
1273 module_init(camsys_platform_init);
1274 module_exit(camsys_platform_exit);
1276 MODULE_DESCRIPTION("RockChip Camera System");
1277 MODULE_AUTHOR("<ddl@rock-chips>");
1278 MODULE_LICENSE("GPL");