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"
7 #include "camsys_soc_priv.h"
9 unsigned int camsys_debug=1;
10 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);
18 typedef struct camsys_devs_s {
20 struct list_head devs;
23 static camsys_devs_t camsys_devs;
25 static int camsys_i2c_write(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
28 unsigned char buf[8],*bufp;
29 unsigned short msg_times,totallen,onelen;
30 struct i2c_msg msg[1];
31 struct i2c_adapter *adapter;
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)*8))&0xff; /* ddl@rock-chips.com: v0.a.0 */
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);
86 static int camsys_i2c_read(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
88 int err = 0,i,retry=2,tmp, num_msg;
90 struct i2c_msg msg[2];
91 struct i2c_adapter *adapter;
93 adapter = i2c_get_adapter(i2cinfo->bus_num);
94 if (adapter == NULL) {
95 camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
101 if (i2cinfo->reg_size) { /* ddl@rock-chips.com: v0.a.0 */
102 for (i=0; i<i2cinfo->reg_size; i++) {
103 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
106 msg[0].addr = (i2cinfo->slave_addr>>1);
108 msg[0].scl_rate = i2cinfo->speed;
109 //msg[0].read_type = 0;
111 msg[0].len = i2cinfo->reg_size;
115 msg[1].addr = (i2cinfo->slave_addr>>1);
116 msg[1].flags = I2C_M_RD;
117 msg[1].scl_rate = i2cinfo->speed;
118 // msg[1].read_type = 0;
120 msg[1].len = (unsigned short)i2cinfo->val_size;
124 while ((retry-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */
126 err = i2c_transfer(adapter, &msg[1], num_msg);
128 err = i2c_transfer(adapter, msg, num_msg);
134 camsys_err("i2c read dev(addr:0x%x) failed,try again-%d!",i2cinfo->slave_addr,retry);
142 for(i=0; i<i2cinfo->val_size; i++) {
144 i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
153 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *camsys_dev)
156 camsys_extdev_t *extdev;
157 camsys_regulator_info_t *regulator_info;
158 camsys_regulator_t *regulator;
159 camsys_gpio_info_t *gpio_info;
162 if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
164 camsys_err("dev_id: 0x%x is not support for camsys!",devio->dev_id);
168 extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
169 if (extdev != NULL) {
170 err = -EBUSY; /* ddl@rock-chips.com: v0.0x13.0 */
171 camsys_warn("Extdev(dev_id: 0x%x) has been registered in %s!",
172 devio->dev_id, dev_name(camsys_dev->miscdev.this_device));
176 extdev = kzalloc(sizeof(camsys_extdev_t),GFP_KERNEL);
177 if (extdev == NULL) {
178 camsys_err("alloc camsys_extdev_t failed!");
183 extdev->dev_cfg = devio->dev_cfg;
184 extdev->fl.fl.active = devio->fl.fl.active;
185 regulator_info = &devio->avdd;
186 regulator = &extdev->avdd;
187 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
188 if (strcmp(regulator_info->name,"NC")) {
189 regulator->ldo = regulator_get(NULL,regulator_info->name);
190 if (IS_ERR_OR_NULL(regulator->ldo)) {
191 camsys_err("Get %s regulator for dev_id 0x%x failed!",regulator_info->name,devio->dev_id);
196 regulator->min_uv = regulator_info->min_uv;
197 regulator->max_uv = regulator_info->max_uv;
198 camsys_trace(1,"Get %s regulator(min: %duv max: %duv) for dev_id 0x%x success",
199 regulator_info->name,regulator->min_uv,regulator->max_uv,
202 regulator->ldo = NULL;
203 regulator->min_uv = 0;
204 regulator->max_uv = 0;
211 gpio_info = &devio->pwrdn;
212 gpio = &extdev->pwrdn;
213 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
214 if (strcmp(gpio_info->name,"NC")) {
215 gpio->io = camsys_gpio_get(gpio_info->name);
217 camsys_err("Get %s gpio for dev_id 0x%x failed!",gpio_info->name,devio->dev_id);
221 if (gpio_request(gpio->io,"camsys_gpio")<0) {
222 camsys_err("Request %s(%d) failed",gpio_info->name,gpio->io);
224 gpio->active = gpio_info->active;
225 camsys_trace(1,"Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
226 gpio_info->name,gpio->io,gpio->active,devio->dev_id);
228 gpio->io = 0xffffffff;
229 gpio->active = 0xffffffff;
236 extdev->pdev = camsys_dev->pdev;
237 extdev->phy = devio->phy;
238 extdev->clk = devio->clk;
239 extdev->dev_id = devio->dev_id;
240 //spin_lock(&camsys_dev->lock);
241 mutex_lock(&camsys_dev->extdevs.mut);
242 list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
243 //spin_unlock(&camsys_dev->lock);
244 mutex_unlock(&camsys_dev->extdevs.mut);
246 camsys_dev->iomux(extdev, (void*)camsys_dev);
248 camsys_trace(1,"Extdev(dev_id: 0x%x) register success",extdev->dev_id);
261 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
264 camsys_extdev_t *extdev;
265 camsys_regulator_t *regulator;
269 if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
271 camsys_err("dev_id: 0x%x is not support for %s!",dev_id, dev_name(camsys_dev->miscdev.this_device));
275 extdev = camsys_find_extdev(dev_id, camsys_dev);
276 if (extdev == NULL) {
278 camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
279 dev_id, dev_name(camsys_dev->miscdev.this_device));
283 regulator = &extdev->avdd;
284 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
285 if (!IS_ERR_OR_NULL(regulator->ldo)) {
286 while(regulator_is_enabled(regulator->ldo)>0)
287 regulator_disable(regulator->ldo);
288 regulator_put(regulator->ldo);
293 gpio = &extdev->pwrdn;
294 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
295 if (gpio->io!=0xffffffff) {
301 //spin_lock(&camsys_dev->lock);
302 mutex_lock(&camsys_dev->extdevs.mut);
303 list_del_init(&extdev->list);
304 list_del_init(&extdev->active);
305 //spin_unlock(&camsys_dev->lock);
306 mutex_unlock(&camsys_dev->extdevs.mut);
308 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
313 //spin_lock(&camsys_dev->lock);
314 mutex_lock(&camsys_dev->extdevs.mut);
315 while (!list_empty(&camsys_dev->extdevs.list)) {
317 extdev = list_first_entry(&camsys_dev->extdevs.list, camsys_extdev_t, list);
319 regulator = &extdev->avdd;
320 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
321 if (!IS_ERR(regulator->ldo)) {
322 while(regulator_is_enabled(regulator->ldo)>0)
323 regulator_disable(regulator->ldo);
324 regulator_put(regulator->ldo);
329 gpio = &extdev->pwrdn;
330 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
331 if (gpio->io!=0xffffffff) {
336 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
337 list_del_init(&extdev->list);
338 list_del_init(&extdev->active);
343 //spin_unlock(&camsys_dev->lock);
344 mutex_unlock(&camsys_dev->extdevs.mut);
345 camsys_trace(1, "All extdev is deregister success!");
354 static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
358 camsys_extdev_t *extdev,*extdev2;
360 //spin_lock(&camsys_dev->lock);
361 mutex_lock(&camsys_dev->extdevs.mut);
362 if(devctl->ops == 0xaa){
367 if (camsys_dev->dev_id & devctl->dev_mask) {
372 camsys_dev->clkin_cb(camsys_dev,devctl->on);
378 camsys_dev->reset_cb(camsys_dev, devctl->on);
381 case CamSys_Flash_Trigger:
383 camsys_dev->flash_trigger_cb(camsys_dev, devctl->on);
388 if(camsys_dev->iommu_cb(camsys_dev, devctl) < 0){
400 for (i=0; i<8; i++) {
401 if (devctl->dev_mask & (1<<(i+24))) {
402 extdev = camsys_find_extdev((1<<(i+24)), camsys_dev);
404 camsys_sysctl_extdev(extdev, devctl, camsys_dev);
406 if (devctl->ops == CamSys_ClkIn) {
408 list_add_tail(&extdev->active,&camsys_dev->extdevs.active);
410 if (!list_empty(&camsys_dev->extdevs.active)) { /* ddla@rock-chips.com: v0.0.7 */
411 list_for_each_entry(extdev2, &camsys_dev->extdevs.active, active) {
412 if (extdev2 == extdev) {
413 list_del_init(&extdev->active);
422 camsys_err("Can not find dev_id 0x%x device in %s!", (1<<(i+24)), dev_name(camsys_dev->miscdev.this_device));
427 //spin_unlock(&camsys_dev->lock);
428 mutex_unlock(&camsys_dev->extdevs.mut);
431 static int camsys_phy_ops (camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, void *ptr)
433 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
434 camsys_mipiphy_t *mipiphy;
437 if (extdev->phy.type == CamSys_Phy_Mipi) {
438 mipiphy = (camsys_mipiphy_t*)devctl->rev;
439 if (devctl->on == 0) {
440 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
441 mipiphy->bit_rate = 0;
442 mipiphy->data_en_bit = 0x00;
444 if ((mipiphy->bit_rate == 0) || (mipiphy->data_en_bit == 0)) {
445 *mipiphy = extdev->phy.info.mipi;
447 if (mipiphy->phy_index != extdev->phy.info.mipi.phy_index) {
448 camsys_warn("mipiphy->phy_index(%d) != extdev->phy.info.mipi.phy_index(%d)!",
449 mipiphy->phy_index,extdev->phy.info.mipi.phy_index);
450 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
454 err = camsys_dev->mipiphy[mipiphy->phy_index].ops(ptr,mipiphy);
456 camsys_err("extdev(0x%x) mipi phy ops config failed!",extdev->dev_id);
462 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev)
465 camsys_irqpool_t *irqpool;
466 unsigned long int flags;
468 if ((irqcnnt->mis != MRV_ISP_MIS) &&
469 (irqcnnt->mis != MRV_MIPI_MIS) &&
470 (irqcnnt->mis != MRV_MI_MIS) &&
471 (irqcnnt->mis != MRV_JPG_MIS) &&
472 (irqcnnt->mis != MRV_JPG_ERR_MIS)) {
474 camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate, irq connect failed!",
475 irqcnnt->pid, irqcnnt->mis);
481 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
482 if (!list_empty(&camsys_dev->irq.irq_pool)) {
483 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
484 if (irqpool->pid == irqcnnt->pid) {
485 camsys_warn("this thread(pid: %d) had been connect irq!",current->pid);
486 spin_unlock(&camsys_dev->irq.lock);
491 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
493 irqpool = kzalloc(sizeof(camsys_irqpool_t),GFP_KERNEL);
495 spin_lock_init(&irqpool->lock);
496 irqpool->pid = irqcnnt->pid;
497 irqpool->timeout = irqcnnt->timeout;
498 irqpool->mis = irqcnnt->mis;
499 irqpool->icr = irqcnnt->icr;
500 INIT_LIST_HEAD(&irqpool->active);
501 INIT_LIST_HEAD(&irqpool->deactive);
502 init_waitqueue_head(&irqpool->done);
503 for (i=0; i<CAMSYS_IRQPOOL_NUM; i++) {
504 list_add_tail(&irqpool->pool[i].list, &irqpool->deactive);
508 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
509 //camsys_dev->irq.timeout = irqcnnt->timeout;
510 list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
511 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
512 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),
513 irqpool->mis,irqpool->icr);
518 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
521 unsigned long int flags;
523 spin_lock_irqsave(&irqpool->lock,flags);
524 err = list_empty(&irqpool->active);
525 spin_unlock_irqrestore(&irqpool->lock,flags);
530 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
533 bool find_pool = false;
534 camsys_irqstas_t *irqstas;
535 camsys_irqpool_t *irqpool;
536 unsigned long int flags;
538 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
539 if (!list_empty(&camsys_dev->irq.irq_pool)) {
540 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
541 if (irqpool->pid == current->pid) {
547 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
549 if (find_pool == false) {
550 camsys_err("this thread(pid: %d) hasn't been connect irq, so wait irq failed!",current->pid);
556 spin_lock_irqsave(&irqpool->lock,flags);
557 if (!list_empty(&irqpool->active)) {
558 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
559 *irqsta = irqstas->sta;
560 list_del_init(&irqstas->list);
561 list_add_tail(&irqstas->list,&irqpool->deactive);
562 spin_unlock_irqrestore(&irqpool->lock,flags);
564 spin_unlock_irqrestore(&irqpool->lock,flags);
566 wait_event_interruptible_timeout(irqpool->done,
567 active_list_isnot_empty(irqpool),
568 usecs_to_jiffies(irqpool->timeout));
570 if (irqpool->pid == current->pid) {
571 if (active_list_isnot_empty(irqpool)) {
572 spin_lock_irqsave(&irqpool->lock,flags);
573 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
574 *irqsta = irqstas->sta;
575 list_del_init(&irqstas->list);
576 list_add_tail(&irqstas->list,&irqpool->deactive);
577 spin_unlock_irqrestore(&irqpool->lock,flags);
582 camsys_warn("Thread(pid: %d) has been disconnect!",current->pid);
588 camsys_trace(3,"Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
589 current->pid, irqsta->mis, irqsta->ris);
596 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev, bool all)
599 bool find_pool = false;
600 camsys_irqpool_t *irqpool;
601 unsigned long int flags;
604 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
605 if (!list_empty(&camsys_dev->irq.irq_pool)) {
606 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
607 if (irqpool->pid == irqcnnt->pid) {
614 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
616 if (find_pool == false) {
617 camsys_err("this thread(pid: %d) have not been connect irq!, disconnect failed",current->pid);
619 wake_up_all(&irqpool->done);
622 camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!", irqcnnt->pid, dev_name(camsys_dev->miscdev.this_device));
624 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
625 while (!list_empty(&camsys_dev->irq.irq_pool)) {
626 irqpool = list_first_entry(&camsys_dev->irq.irq_pool, camsys_irqpool_t, list);
627 list_del_init(&irqpool->list);
629 wake_up_all(&irqpool->done);
633 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
635 camsys_trace(1, "All thread disconnect %s irq success!", dev_name(camsys_dev->miscdev.this_device));
642 static int camsys_querymem (camsys_dev_t *camsys_dev, camsys_querymem_t *qmem)
646 if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
647 if (camsys_dev->devmems.registermem == NULL) {
648 camsys_err("%s register memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
653 qmem->mem_size = camsys_dev->devmems.registermem->size;
654 qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
655 } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
656 if (camsys_dev->devmems.i2cmem== NULL) {
657 camsys_err("%s i2c memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
662 qmem->mem_size = camsys_dev->devmems.i2cmem->size;
663 qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
665 camsys_err("%d memory type have not in %s memory list",qmem->mem_type,dev_name(camsys_dev->miscdev.this_device));
675 static int camsys_open(struct inode *inode, struct file *file)
678 int minor = iminor(inode);
679 camsys_dev_t *camsys_dev;
680 unsigned int i,phycnt;
682 spin_lock(&camsys_devs.lock);
683 list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
684 if (camsys_dev->miscdev.minor == minor) {
685 file->private_data = (void*)(camsys_dev);
689 spin_unlock(&camsys_devs.lock);
692 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
694 if (camsys_dev->mipiphy != NULL) {
695 phycnt = camsys_dev->mipiphy[0].phycnt;
697 for (i=0; i<phycnt; i++) {
698 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
699 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,1);
705 if (file->private_data == NULL) {
706 camsys_err("Cann't find camsys_dev!");
710 camsys_trace(1,"%s(%p) is opened!",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
717 static int camsys_release(struct inode *inode, struct file *file)
719 camsys_dev_t *camsys_dev = (camsys_dev_t*)file->private_data;
720 unsigned int i,phycnt;
722 camsys_irq_disconnect(NULL,camsys_dev, true);
724 if (camsys_dev->mipiphy != NULL) {
725 phycnt = camsys_dev->mipiphy[0].phycnt;
727 for (i=0; i<phycnt; i++) {
728 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
729 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,0);
734 camsys_trace(1,"%s(%p) is closed",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
740 * The ioctl() implementation
743 static long camsys_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
746 camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data;
748 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
749 camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
753 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
754 camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
759 if (_IOC_DIR(cmd) & _IOC_READ)
760 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
761 else if (_IOC_DIR(cmd) & _IOC_WRITE)
762 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
765 camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
774 camsys_version_t camsys_ver;
776 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
777 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
778 if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
782 case CAMSYS_QUREYIOMMU:
784 int iommu_enabled = 0;
785 #ifdef CONFIG_ROCKCHIP_IOMMU
786 of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled);
788 if (copy_to_user((void __user *)arg,(void*)&iommu_enabled, sizeof(iommu_enabled)))
794 camsys_i2c_info_t i2cinfo;
796 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
799 err = camsys_i2c_read(&i2cinfo,camsys_dev);
801 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
809 camsys_i2c_info_t i2cinfo;
811 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
814 err = camsys_i2c_write(&i2cinfo,camsys_dev);
820 camsys_sysctrl_t devctl;
822 if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t)))
825 err = camsys_sysctl(&devctl, camsys_dev);
826 if ((err==0) && (devctl.ops == CamSys_IOMMU)){
827 if (copy_to_user((void __user *)arg,(void*)&devctl, sizeof(camsys_sysctrl_t)))
845 case CAMSYS_REGISTER_DEVIO:
847 camsys_devio_name_t devio;
849 if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t)))
852 err = camsys_extdev_register(&devio,camsys_dev);
856 case CAMSYS_DEREGISTER_DEVIO:
860 if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
863 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
867 case CAMSYS_IRQCONNECT:
869 camsys_irqcnnt_t irqcnnt;
871 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
874 err = camsys_irq_connect(&irqcnnt, camsys_dev);
881 camsys_irqsta_t irqsta;
883 err = camsys_irq_wait(&irqsta, camsys_dev);
885 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t)))
891 case CAMSYS_IRQDISCONNECT:
893 camsys_irqcnnt_t irqcnnt;
895 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
897 err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
902 case CAMSYS_QUREYMEM:
904 camsys_querymem_t qmem;
906 if (copy_from_user((void*)&qmem,(void __user *)arg, sizeof(camsys_querymem_t)))
909 err = camsys_querymem(camsys_dev,&qmem);
911 if (copy_to_user((void __user *)arg,(void*)&qmem, sizeof(camsys_querymem_t)))
928 static void camsys_vm_open(struct vm_area_struct *vma)
930 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
936 static void camsys_vm_close(struct vm_area_struct *vma)
938 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
944 static const struct vm_operations_struct camsys_vm_ops = {
945 .open = camsys_vm_open,
946 .close = camsys_vm_close,
949 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
951 camsys_dev_t *camsys_dev = (camsys_dev_t*)flip->private_data;
952 unsigned long addr, start, size;
953 camsys_mmap_type_t mem_type;
954 camsys_meminfo_t *meminfo;
957 mem_type = vma->vm_pgoff;
959 if (mem_type == CamSys_Mmap_RegisterMem) {
960 if (camsys_dev->devmems.registermem != NULL) {
961 meminfo = camsys_dev->devmems.registermem;
963 camsys_err("this camsys device has not register mem!");
967 } else if (mem_type == CamSys_Mmap_I2cMem) {
968 if (camsys_dev->devmems.i2cmem != NULL) {
969 meminfo = camsys_dev->devmems.i2cmem;
971 camsys_err("this camsys device has not i2c mem!");
976 camsys_err("mmap buffer type %d is invalidate!",mem_type);
981 size = vma->vm_end - vma->vm_start;
982 if (size > meminfo->size) {
984 camsys_err("mmap size(0x%lx) > memory size(0x%x), so failed!",size,meminfo->size);
988 start = vma->vm_start;
989 addr = __phys_to_pfn(meminfo->phy_base);
991 if (remap_pfn_range(vma, start, addr,size,pgprot_noncached(vma->vm_page_prot))) {
997 vma->vm_ops = &camsys_vm_ops;
998 vma->vm_flags |= VM_IO;
999 vma->vm_flags |=VM_ACCOUNT;//same as VM_RESERVED;
1000 vma->vm_private_data = (void*)meminfo;
1001 camsys_vm_open(vma);
1007 struct file_operations camsys_fops = {
1008 .owner = THIS_MODULE,
1009 .open = camsys_open,
1010 .release = camsys_release,
1011 .unlocked_ioctl = camsys_ioctl,
1012 .mmap = camsys_mmap,
1015 static int camsys_platform_probe(struct platform_device *pdev){
1017 camsys_dev_t *camsys_dev;
1018 struct resource register_res ;
1019 struct device *dev = &pdev->dev;
1020 unsigned long i2cmem;
1021 camsys_meminfo_t *meminfo;
1022 unsigned int irq_id;
1024 err = of_address_to_resource(dev->of_node, 0, ®ister_res);
1026 camsys_err("Get register resource from %s platform device failed!",pdev->name);
1033 irq_id = irq_of_parse_and_map(dev->of_node, 0);
1035 camsys_err("Get irq resource from %s platform device failed!",pdev->name);
1040 camsys_dev = (camsys_dev_t*)devm_kzalloc(&pdev->dev,sizeof(camsys_dev_t), GFP_KERNEL);
1041 if (camsys_dev == NULL) {
1042 camsys_err("Allocate camsys_dev for %s platform device failed",pdev->name);
1047 //spin_lock_init(&camsys_dev->lock);
1048 mutex_init(&camsys_dev->extdevs.mut);
1049 INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1050 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1051 INIT_LIST_HEAD(&camsys_dev->list);
1055 camsys_dev->irq.irq_id = irq_id;
1056 spin_lock_init(&camsys_dev->irq.lock);
1057 INIT_LIST_HEAD(&camsys_dev->irq.irq_pool);
1058 //init_waitqueue_head(&camsys_dev->irq.irq_done);
1060 INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1062 // get soc operation
1063 camsys_dev->soc = (void*)camsys_soc_get();
1064 if (camsys_dev->soc == NULL) {
1070 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1071 if (meminfo == NULL) {
1073 goto request_mem_fail;
1076 meminfo->vir_base = (unsigned int)devm_ioremap_resource(dev, ®ister_res);
1077 if (!meminfo->vir_base){
1078 camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), CAMSYS_REGISTER_MEM_NAME);
1080 goto request_mem_fail;
1083 strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME,sizeof(meminfo->name));
1084 meminfo->phy_base = register_res.start;
1085 meminfo->size = register_res.end - register_res.start + 1;
1086 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1090 i2cmem = __get_free_page(GFP_KERNEL);
1092 camsys_err("Allocate i2cmem failed!");
1094 goto request_mem_fail;
1096 SetPageReserved(virt_to_page(i2cmem));
1098 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1099 if (meminfo == NULL) {
1101 goto request_mem_fail;
1103 strlcpy(meminfo->name,CAMSYS_I2C_MEM_NAME,sizeof(meminfo->name));
1104 meminfo->vir_base = i2cmem;
1105 meminfo->phy_base = virt_to_phys((void*)i2cmem);
1106 meminfo->size = PAGE_SIZE;
1107 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1112 tmpp = (unsigned int*)meminfo->vir_base;
1119 if (camsys_mipiphy_probe_cb(pdev, camsys_dev) <0) {
1120 camsys_err("Mipi phy probe failed!");
1125 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_MARVIN_NAME) == 0) {
1126 #if (defined(CONFIG_CAMSYS_MRV))
1127 camsys_mrv_probe_cb(pdev, camsys_dev);
1129 camsys_err("Marvin controller camsys driver haven't been complie!!!");
1132 #if (defined(CONFIG_CAMSYS_CIF))
1133 camsys_cif_probe_cb(pdev,camsys_dev);
1135 camsys_err("CIF controller camsys driver haven't been complie!!!");
1139 #if (defined(CONFIG_CAMSYS_MRV))
1140 camsys_mrv_probe_cb(pdev, camsys_dev);
1141 #elif (defined(CONFIG_CAMSYS_CIF))
1142 camsys_cif_probe_cb(pdev,camsys_dev);
1144 camsys_err("camsys driver haven't been complie!!!");
1147 camsys_trace(1, "%s memory:",dev_name(&pdev->dev));
1148 list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1149 if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME) == 0) {
1150 camsys_dev->devmems.i2cmem = meminfo;
1151 camsys_trace(1," I2c memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1152 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1154 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME) == 0) {
1155 camsys_dev->devmems.registermem = meminfo;
1156 camsys_trace(1," Register memory (phy: 0x%x vir: 0x%x size: 0x%x)",
1157 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1162 camsys_dev->phy_cb = camsys_phy_ops;
1163 camsys_dev->pdev = pdev;
1165 platform_set_drvdata(pdev,(void*)camsys_dev);
1166 //Camsys_devs list add
1167 spin_lock(&camsys_devs.lock);
1168 list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1169 spin_unlock(&camsys_devs.lock);
1172 camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1175 if (camsys_dev != NULL) {
1177 while(!list_empty(&camsys_dev->devmems.memslist)) {
1178 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1180 list_del_init(&meminfo->list);
1181 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1182 iounmap((void __iomem *)meminfo->vir_base);
1183 release_mem_region(meminfo->phy_base,meminfo->size);
1184 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1185 kfree((void*)meminfo->vir_base);
1200 static int camsys_platform_remove(struct platform_device *pdev)
1202 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1203 camsys_meminfo_t *meminfo;
1208 while(!list_empty(&camsys_dev->devmems.memslist)) {
1209 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1211 list_del_init(&meminfo->list);
1212 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1213 iounmap((void __iomem *)meminfo->vir_base);
1214 release_mem_region(meminfo->phy_base,meminfo->size);
1215 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1216 kfree((void*)meminfo->vir_base);
1224 if (camsys_dev->irq.irq_id) {
1225 free_irq(camsys_dev->irq.irq_id, camsys_dev);
1226 camsys_irq_disconnect(NULL,camsys_dev,true);
1230 if (!list_empty(&camsys_dev->extdevs.list)) {
1231 camsys_extdev_deregister(0,camsys_dev,true);
1233 if (camsys_dev->mipiphy != NULL) {
1234 camsys_dev->mipiphy->remove(pdev);
1236 if (camsys_dev->cifphy.remove)
1237 camsys_dev->cifphy.remove(pdev);
1238 camsys_dev->platform_remove(pdev);
1240 misc_deregister(&camsys_dev->miscdev);
1242 spin_lock(&camsys_devs.lock);
1243 list_del_init(&camsys_dev->list);
1244 spin_unlock(&camsys_devs.lock);
1249 camsys_err("This platform device havn't obtain camsys_dev!");
1256 static const struct of_device_id cif_of_match[] = {
1257 { .compatible = "rockchip,isp" },
1259 MODULE_DEVICE_TABLE(of, cif_of_match);
1261 static struct platform_driver camsys_platform_driver =
1264 .name = CAMSYS_PLATFORM_DRV_NAME,
1265 .of_match_table = of_match_ptr(cif_of_match),
1267 .probe = camsys_platform_probe,
1268 .remove = (camsys_platform_remove),
1271 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1272 static int __init camsys_platform_init(void)
1274 printk("CamSys driver version: v%d.%d.%d, CamSys head file version: v%d.%d.%d\n",
1275 (CAMSYS_DRIVER_VERSION&0xff0000)>>16, (CAMSYS_DRIVER_VERSION&0xff00)>>8,
1276 CAMSYS_DRIVER_VERSION&0xff,
1277 (CAMSYS_HEAD_VERSION&0xff0000)>>16, (CAMSYS_HEAD_VERSION&0xff00)>>8,
1278 CAMSYS_HEAD_VERSION&0xff);
1280 spin_lock_init(&camsys_devs.lock);
1281 INIT_LIST_HEAD(&camsys_devs.devs);
1283 platform_driver_register(&camsys_platform_driver);
1284 // platform_driver_probe(&camsys_platform_driver, camsys_platform_probe_new);
1289 static void __exit camsys_platform_exit(void)
1291 platform_driver_unregister(&camsys_platform_driver);
1292 camsys_soc_deinit();
1295 module_init(camsys_platform_init);
1296 module_exit(camsys_platform_exit);
1298 MODULE_DESCRIPTION("RockChip Camera System");
1299 MODULE_AUTHOR("<ddl@rock-chips>");
1300 MODULE_LICENSE("GPL");