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"
8 #include "ext_flashled_drv/rk_ext_fshled_ctl.h"
10 unsigned int camsys_debug=1;
11 module_param(camsys_debug, int, S_IRUGO|S_IWUSR);
13 static int drv_version = CAMSYS_DRIVER_VERSION;
14 module_param(drv_version, int, S_IRUGO);
15 static int head_version = CAMSYS_HEAD_VERSION;
16 module_param(head_version, int, S_IRUGO);
19 typedef struct camsys_devs_s {
21 struct list_head devs;
24 static camsys_devs_t camsys_devs;
26 static int camsys_i2c_write(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
29 unsigned char buf[8],*bufp;
30 unsigned short msg_times,totallen,onelen;
31 struct i2c_msg msg[1];
32 struct i2c_adapter *adapter;
34 adapter = i2c_get_adapter(i2cinfo->bus_num);
35 if (adapter == NULL) {
36 camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
41 if (i2cinfo->i2cbuf_directly) {
42 if (camsys_dev->devmems.i2cmem == NULL) {
43 camsys_err("%s has not i2c mem, it isn't support i2c buf write!",dev_name(camsys_dev->miscdev.this_device));
47 totallen = (i2cinfo->i2cbuf_bytes&0xffff);
48 onelen = (i2cinfo->i2cbuf_bytes&0xffff0000)>>16;
49 msg_times = totallen/onelen;
50 if (totallen > camsys_dev->devmems.i2cmem->size) {
51 camsys_err("Want to write 0x%x bytes, i2c memory(size: 0x%x) is overlap",totallen,camsys_dev->devmems.i2cmem->size);
55 bufp = (unsigned char*)camsys_dev->devmems.i2cmem->vir_base;
57 for (i=0; i<i2cinfo->reg_size; i++) {
58 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
60 for (j=0; j<i2cinfo->val_size; j++) {
61 buf[i+j] = (i2cinfo->val>>((i2cinfo->val_size-1-j)*8))&0xff; /* ddl@rock-chips.com: v0.a.0 */
64 onelen = i2cinfo->val_size + i2cinfo->reg_size;
69 msg->addr = (i2cinfo->slave_addr>>1);
71 msg->scl_rate = i2cinfo->speed;
72 // msg->read_type = 0;
74 for (i=0; i<msg_times; i++) {
75 msg->buf = bufp+i*onelen;
76 err = i2c_transfer(adapter, msg, 1);
78 camsys_err("i2c write dev(addr:0x%x) failed!",i2cinfo->slave_addr);
87 static int camsys_i2c_read(camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
89 int err = 0,i,retry=2,tmp, num_msg;
91 struct i2c_msg msg[2];
92 struct i2c_adapter *adapter;
94 adapter = i2c_get_adapter(i2cinfo->bus_num);
95 if (adapter == NULL) {
96 camsys_err("Get %d i2c adapter is failed!",i2cinfo->bus_num);
102 if (i2cinfo->reg_size) { /* ddl@rock-chips.com: v0.a.0 */
103 for (i=0; i<i2cinfo->reg_size; i++) {
104 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
107 msg[0].addr = (i2cinfo->slave_addr>>1);
109 msg[0].scl_rate = i2cinfo->speed;
110 //msg[0].read_type = 0;
112 msg[0].len = i2cinfo->reg_size;
116 msg[1].addr = (i2cinfo->slave_addr>>1);
117 msg[1].flags = I2C_M_RD;
118 msg[1].scl_rate = i2cinfo->speed;
119 // msg[1].read_type = 0;
121 msg[1].len = (unsigned short)i2cinfo->val_size;
125 while ((retry-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */
127 err = i2c_transfer(adapter, &msg[1], num_msg);
129 err = i2c_transfer(adapter, msg, num_msg);
135 camsys_err("i2c read dev(addr:0x%x) failed,try again-%d!",i2cinfo->slave_addr,retry);
143 for(i=0; i<i2cinfo->val_size; i++) {
145 i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
154 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t *camsys_dev)
157 camsys_extdev_t *extdev;
158 camsys_regulator_info_t *regulator_info;
159 camsys_regulator_t *regulator;
160 camsys_gpio_info_t *gpio_info;
163 if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
165 camsys_err("dev_id: 0x%x is not support for camsys!",devio->dev_id);
169 extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
170 if (extdev != NULL) {
171 if (strcmp(extdev->dev_name, devio->dev_name) == 0) {
174 err = -EINVAL; /* ddl@rock-chips.com: v0.0x13.0 */
175 camsys_warn("Extdev(dev_id: 0x%x dev_name: %s) has been registered in %s!",
176 extdev->dev_id, extdev->dev_name,dev_name(camsys_dev->miscdev.this_device));
181 extdev = kzalloc(sizeof(camsys_extdev_t),GFP_KERNEL);
182 if (extdev == NULL) {
183 camsys_err("alloc camsys_extdev_t failed!");
188 extdev->dev_cfg = devio->dev_cfg;
189 extdev->fl.fl.active = devio->fl.fl.active;
190 extdev->fl.ext_fsh_dev = NULL;
191 //should register external flash device ?
192 if(strlen(devio->fl.fl_drv_name) && (strcmp(devio->fl.fl_drv_name,"Internal") != 0)
193 && (strcmp(devio->fl.fl_drv_name,"NC") != 0)){
194 //register flash device
195 extdev->fl.ext_fsh_dev = camsys_register_ext_fsh_dev(&devio->fl);
196 if(extdev->fl.ext_fsh_dev == NULL){
197 camsys_err("register ext flash %s failed!",devio->fl.fl_drv_name);
202 regulator_info = &devio->avdd;
203 regulator = &extdev->avdd;
204 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
205 if (strcmp(regulator_info->name,"NC")) {
206 regulator->ldo = regulator_get(NULL,regulator_info->name);
207 if (IS_ERR_OR_NULL(regulator->ldo)) {
208 camsys_err("Get %s regulator for dev_id 0x%x failed!",regulator_info->name,devio->dev_id);
213 regulator->min_uv = regulator_info->min_uv;
214 regulator->max_uv = regulator_info->max_uv;
215 camsys_trace(1,"Get %s regulator(min: %duv max: %duv) for dev_id 0x%x success",
216 regulator_info->name,regulator->min_uv,regulator->max_uv,
219 regulator->ldo = NULL;
220 regulator->min_uv = 0;
221 regulator->max_uv = 0;
228 gpio_info = &devio->pwrdn;
229 gpio = &extdev->pwrdn;
230 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
231 if (strcmp(gpio_info->name,"NC")) {
232 gpio->io = camsys_gpio_get(gpio_info->name);
234 camsys_err("Get %s gpio for dev_id 0x%x failed!",gpio_info->name,devio->dev_id);
238 if (gpio_request(gpio->io,"camsys_gpio")<0) {
239 camsys_err("Request %s(%d) failed",gpio_info->name,gpio->io);
241 gpio->active = gpio_info->active;
242 camsys_trace(1,"Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
243 gpio_info->name,gpio->io,gpio->active,devio->dev_id);
245 gpio->io = 0xffffffff;
246 gpio->active = 0xffffffff;
253 extdev->pdev = camsys_dev->pdev;
254 extdev->phy = devio->phy;
255 extdev->clk = devio->clk;
256 extdev->dev_id = devio->dev_id;
257 //spin_lock(&camsys_dev->lock);
258 mutex_lock(&camsys_dev->extdevs.mut);
259 list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
260 //spin_unlock(&camsys_dev->lock);
261 mutex_unlock(&camsys_dev->extdevs.mut);
263 camsys_dev->iomux(extdev, (void*)camsys_dev);
265 memcpy(extdev->dev_name,devio->dev_name, sizeof(extdev->dev_name));
266 camsys_trace(1,"Extdev(dev_id: 0x%x dev_name: %s) register success",
281 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
284 camsys_extdev_t *extdev;
285 camsys_regulator_t *regulator;
289 if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
291 camsys_err("dev_id: 0x%x is not support for %s!",dev_id, dev_name(camsys_dev->miscdev.this_device));
295 extdev = camsys_find_extdev(dev_id, camsys_dev);
296 if (extdev == NULL) {
298 camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
299 dev_id, dev_name(camsys_dev->miscdev.this_device));
303 regulator = &extdev->avdd;
304 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
305 if (!IS_ERR_OR_NULL(regulator->ldo)) {
306 while(regulator_is_enabled(regulator->ldo)>0)
307 regulator_disable(regulator->ldo);
308 regulator_put(regulator->ldo);
313 gpio = &extdev->pwrdn;
314 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
315 if (gpio->io!=0xffffffff) {
321 if(extdev->fl.ext_fsh_dev != NULL){
322 camsys_deregister_ext_fsh_dev(extdev->fl.ext_fsh_dev);
324 //spin_lock(&camsys_dev->lock);
325 mutex_lock(&camsys_dev->extdevs.mut);
326 list_del_init(&extdev->list);
327 list_del_init(&extdev->active);
328 //spin_unlock(&camsys_dev->lock);
329 mutex_unlock(&camsys_dev->extdevs.mut);
331 camsys_trace(1,"Extdev(dev_id: 0x%x) is deregister success", extdev->dev_id);
336 //spin_lock(&camsys_dev->lock);
337 mutex_lock(&camsys_dev->extdevs.mut);
338 while (!list_empty(&camsys_dev->extdevs.list)) {
340 extdev = list_first_entry(&camsys_dev->extdevs.list, camsys_extdev_t, list);
342 regulator = &extdev->avdd;
343 for (i=(CamSys_Vdd_Start_Tag+1); i<CamSys_Vdd_End_Tag; i++) {
344 if (!IS_ERR(regulator->ldo)) {
345 while(regulator_is_enabled(regulator->ldo)>0)
346 regulator_disable(regulator->ldo);
347 regulator_put(regulator->ldo);
352 gpio = &extdev->pwrdn;
353 for (i=(CamSys_Gpio_Start_Tag+1); i<CamSys_Gpio_End_Tag; i++) {
354 if (gpio->io!=0xffffffff) {
360 if(extdev->fl.ext_fsh_dev != NULL){
361 camsys_deregister_ext_fsh_dev(extdev->fl.ext_fsh_dev);
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, devctl->on);
408 case CamSys_Flash_Trigger:
410 camsys_dev->flash_trigger_cb(camsys_dev,devctl->rev[0], devctl->on);
415 if(camsys_dev->iommu_cb(camsys_dev, devctl) < 0){
427 for (i=0; i<8; i++) {
428 if (devctl->dev_mask & (1<<(i+24))) {
429 extdev = camsys_find_extdev((1<<(i+24)), camsys_dev);
431 camsys_sysctl_extdev(extdev, devctl, camsys_dev);
433 if (devctl->ops == CamSys_ClkIn) {
435 list_add_tail(&extdev->active,&camsys_dev->extdevs.active);
437 if (!list_empty(&camsys_dev->extdevs.active)) { /* ddla@rock-chips.com: v0.0.7 */
438 list_for_each_entry(extdev2, &camsys_dev->extdevs.active, active) {
439 if (extdev2 == extdev) {
440 list_del_init(&extdev->active);
446 }else if(devctl->ops == CamSys_Flash_Trigger){
447 err = camsys_ext_fsh_ctrl(extdev->fl.ext_fsh_dev,devctl->rev[0],devctl->on);
451 camsys_err("Can not find dev_id 0x%x device in %s!", (1<<(i+24)), dev_name(camsys_dev->miscdev.this_device));
456 //spin_unlock(&camsys_dev->lock);
457 mutex_unlock(&camsys_dev->extdevs.mut);
460 static int camsys_phy_ops (camsys_extdev_t *extdev, camsys_sysctrl_t *devctl, void *ptr)
462 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
463 camsys_mipiphy_t *mipiphy;
466 if (extdev->phy.type == CamSys_Phy_Mipi) {
467 mipiphy = (camsys_mipiphy_t*)devctl->rev;
468 if (devctl->on == 0) {
469 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
470 mipiphy->bit_rate = 0;
471 mipiphy->data_en_bit = 0x00;
473 if ((mipiphy->bit_rate == 0) || (mipiphy->data_en_bit == 0)) {
474 *mipiphy = extdev->phy.info.mipi;
476 if (mipiphy->phy_index != extdev->phy.info.mipi.phy_index) {
477 camsys_warn("mipiphy->phy_index(%d) != extdev->phy.info.mipi.phy_index(%d)!",
478 mipiphy->phy_index,extdev->phy.info.mipi.phy_index);
479 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
483 err = camsys_dev->mipiphy[mipiphy->phy_index].ops(ptr,mipiphy);
485 camsys_err("extdev(0x%x) mipi phy ops config failed!",extdev->dev_id);
491 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev)
494 camsys_irqpool_t *irqpool;
495 unsigned long int flags;
497 if ((irqcnnt->mis != MRV_ISP_MIS) &&
498 (irqcnnt->mis != MRV_MIPI_MIS) &&
499 (irqcnnt->mis != MRV_MI_MIS) &&
500 (irqcnnt->mis != MRV_JPG_MIS) &&
501 (irqcnnt->mis != MRV_JPG_ERR_MIS)) {
503 camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate, irq connect failed!",
504 irqcnnt->pid, irqcnnt->mis);
510 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
511 if (!list_empty(&camsys_dev->irq.irq_pool)) {
512 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
513 if (irqpool->pid == irqcnnt->pid) {
514 camsys_warn("this thread(pid: %d) had been connect irq!",current->pid);
515 spin_unlock(&camsys_dev->irq.lock);
520 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
522 irqpool = kzalloc(sizeof(camsys_irqpool_t),GFP_KERNEL);
524 spin_lock_init(&irqpool->lock);
525 irqpool->pid = irqcnnt->pid;
526 irqpool->timeout = irqcnnt->timeout;
527 irqpool->mis = irqcnnt->mis;
528 irqpool->icr = irqcnnt->icr;
529 INIT_LIST_HEAD(&irqpool->active);
530 INIT_LIST_HEAD(&irqpool->deactive);
531 init_waitqueue_head(&irqpool->done);
532 for (i=0; i<CAMSYS_IRQPOOL_NUM; i++) {
533 list_add_tail(&irqpool->pool[i].list, &irqpool->deactive);
537 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
538 //camsys_dev->irq.timeout = irqcnnt->timeout;
539 list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
540 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
541 camsys_trace(1, "Thread(pid: %d) connect %s irq success! mis: 0x%x icr: 0x%x ", irqpool->pid, dev_name(camsys_dev->miscdev.this_device),
542 irqpool->mis,irqpool->icr);
547 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
550 unsigned long int flags;
552 spin_lock_irqsave(&irqpool->lock,flags);
553 err = list_empty(&irqpool->active);
554 spin_unlock_irqrestore(&irqpool->lock,flags);
559 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
562 bool find_pool = false;
563 camsys_irqstas_t *irqstas;
564 camsys_irqpool_t *irqpool;
565 unsigned long int flags;
567 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
568 if (!list_empty(&camsys_dev->irq.irq_pool)) {
569 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
570 if (irqpool->pid == current->pid) {
576 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
578 if (find_pool == false) {
579 camsys_err("this thread(pid: %d) hasn't been connect irq, so wait irq failed!",current->pid);
585 spin_lock_irqsave(&irqpool->lock,flags);
586 if (!list_empty(&irqpool->active)) {
587 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
588 *irqsta = irqstas->sta;
589 list_del_init(&irqstas->list);
590 list_add_tail(&irqstas->list,&irqpool->deactive);
591 spin_unlock_irqrestore(&irqpool->lock,flags);
593 spin_unlock_irqrestore(&irqpool->lock,flags);
595 wait_event_interruptible_timeout(irqpool->done,
596 active_list_isnot_empty(irqpool),
597 usecs_to_jiffies(irqpool->timeout));
599 if (irqpool->pid == current->pid) {
600 if (active_list_isnot_empty(irqpool)) {
601 spin_lock_irqsave(&irqpool->lock,flags);
602 irqstas = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
603 *irqsta = irqstas->sta;
604 list_del_init(&irqstas->list);
605 list_add_tail(&irqstas->list,&irqpool->deactive);
606 spin_unlock_irqrestore(&irqpool->lock,flags);
611 camsys_warn("Thread(pid: %d) has been disconnect!",current->pid);
617 camsys_trace(3,"Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
618 current->pid, irqsta->mis, irqsta->ris);
625 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t *camsys_dev, bool all)
628 bool find_pool = false;
629 camsys_irqpool_t *irqpool;
630 unsigned long int flags;
633 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
634 if (!list_empty(&camsys_dev->irq.irq_pool)) {
635 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
636 if (irqpool->pid == irqcnnt->pid) {
643 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
645 if (find_pool == false) {
646 camsys_err("this thread(pid: %d) have not been connect irq!, disconnect failed",current->pid);
648 wake_up_all(&irqpool->done);
651 camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!", irqcnnt->pid, dev_name(camsys_dev->miscdev.this_device));
653 spin_lock_irqsave(&camsys_dev->irq.lock,flags);
654 while (!list_empty(&camsys_dev->irq.irq_pool)) {
655 irqpool = list_first_entry(&camsys_dev->irq.irq_pool, camsys_irqpool_t, list);
656 list_del_init(&irqpool->list);
658 wake_up_all(&irqpool->done);
662 spin_unlock_irqrestore(&camsys_dev->irq.lock,flags);
664 camsys_trace(1, "All thread disconnect %s irq success!", dev_name(camsys_dev->miscdev.this_device));
671 static int camsys_querymem (camsys_dev_t *camsys_dev, camsys_querymem_t *qmem)
675 if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
676 if (camsys_dev->devmems.registermem == NULL) {
677 camsys_err("%s register memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
682 qmem->mem_size = camsys_dev->devmems.registermem->size;
683 qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
684 } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
685 if (camsys_dev->devmems.i2cmem== NULL) {
686 camsys_err("%s i2c memory isn't been register!", dev_name(camsys_dev->miscdev.this_device));
691 qmem->mem_size = camsys_dev->devmems.i2cmem->size;
692 qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
694 camsys_err("%d memory type have not in %s memory list",qmem->mem_type,dev_name(camsys_dev->miscdev.this_device));
704 static int camsys_open(struct inode *inode, struct file *file)
707 int minor = iminor(inode);
708 camsys_dev_t *camsys_dev;
709 unsigned int i,phycnt;
711 spin_lock(&camsys_devs.lock);
712 list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
713 if (camsys_dev->miscdev.minor == minor) {
714 file->private_data = (void*)(camsys_dev);
718 spin_unlock(&camsys_devs.lock);
721 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
723 if (camsys_dev->mipiphy != NULL) {
724 phycnt = camsys_dev->mipiphy[0].phycnt;
726 for (i=0; i<phycnt; i++) {
727 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
728 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,1);
734 if (file->private_data == NULL) {
735 camsys_err("Cann't find camsys_dev!");
739 camsys_trace(1,"%s(%p) is opened!",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
746 static int camsys_release(struct inode *inode, struct file *file)
748 camsys_dev_t *camsys_dev = (camsys_dev_t*)file->private_data;
749 unsigned int i,phycnt;
751 camsys_irq_disconnect(NULL,camsys_dev, true);
753 if (camsys_dev->mipiphy != NULL) {
754 phycnt = camsys_dev->mipiphy[0].phycnt;
756 for (i=0; i<phycnt; i++) {
757 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
758 camsys_dev->mipiphy[i].clkin_cb(camsys_dev,0);
763 camsys_trace(1,"%s(%p) is closed",dev_name(camsys_dev->miscdev.this_device),camsys_dev);
769 * The ioctl() implementation
772 typedef struct camsys_querymem_s_32 {
773 camsys_mmap_type_t mem_type;
774 unsigned int mem_offset;
776 unsigned int mem_size;
777 } camsys_querymem_32_t;
779 #define CAMSYS_QUREYMEM_32 _IOR(CAMSYS_IOC_MAGIC, 11, camsys_querymem_32_t)
781 static long camsys_ioctl_compat(struct file *filp,unsigned int cmd, unsigned long arg)
784 camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data;
786 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
787 camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
791 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
792 camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
797 if (_IOC_DIR(cmd) & _IOC_READ)
798 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
799 else if (_IOC_DIR(cmd) & _IOC_WRITE)
800 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
803 camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
812 camsys_version_t camsys_ver;
814 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
815 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
816 if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
820 case CAMSYS_QUREYIOMMU:
822 int iommu_enabled = 0;
823 #ifdef CONFIG_ROCKCHIP_IOMMU
824 struct device_node * vpu_node =NULL;
825 int vpu_iommu_enabled = 0;
826 vpu_node = of_find_node_by_name(NULL, "vpu_service");
828 of_property_read_u32(vpu_node, "iommu_enabled", &vpu_iommu_enabled);
829 of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled);
830 of_node_put(vpu_node);
831 if(iommu_enabled != vpu_iommu_enabled){
832 camsys_err("iommu status not consistent,check the dts file ! isp:%d,vpu:%d",iommu_enabled,vpu_iommu_enabled);
837 if (copy_to_user((void __user *)arg,(void*)&iommu_enabled, sizeof(iommu_enabled)))
843 camsys_i2c_info_t i2cinfo;
845 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
848 err = camsys_i2c_read(&i2cinfo,camsys_dev);
850 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
858 camsys_i2c_info_t i2cinfo;
860 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
863 err = camsys_i2c_write(&i2cinfo,camsys_dev);
869 camsys_sysctrl_t devctl;
871 if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t)))
874 err = camsys_sysctl(&devctl, camsys_dev);
875 if ((err==0) && (devctl.ops == CamSys_IOMMU)){
876 if (copy_to_user((void __user *)arg,(void*)&devctl, sizeof(camsys_sysctrl_t)))
894 case CAMSYS_REGISTER_DEVIO:
896 camsys_devio_name_t devio;
898 if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t)))
901 err = camsys_extdev_register(&devio,camsys_dev);
905 case CAMSYS_DEREGISTER_DEVIO:
909 if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
912 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
916 case CAMSYS_IRQCONNECT:
918 camsys_irqcnnt_t irqcnnt;
920 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
923 err = camsys_irq_connect(&irqcnnt, camsys_dev);
930 camsys_irqsta_t irqsta;
932 err = camsys_irq_wait(&irqsta, camsys_dev);
934 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t)))
940 case CAMSYS_IRQDISCONNECT:
942 camsys_irqcnnt_t irqcnnt;
944 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
946 err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
950 case CAMSYS_QUREYMEM_32:
952 camsys_querymem_t qmem;
953 camsys_querymem_32_t qmem32;
955 if (copy_from_user((void*)&qmem32,(void __user *)arg, sizeof(camsys_querymem_32_t)))
958 qmem.mem_type = qmem32.mem_type;
959 err = camsys_querymem(camsys_dev,&qmem);
961 qmem32.mem_offset = (unsigned int)qmem.mem_offset;
962 qmem32.mem_size = qmem.mem_size;
963 if (copy_to_user((void __user *)arg,(void*)&qmem32, sizeof(camsys_querymem_32_t)))
977 static long camsys_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
980 camsys_dev_t *camsys_dev = (camsys_dev_t*)filp->private_data;
982 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
983 camsys_err("ioctl type(%c!=%c) is invalidate\n",_IOC_TYPE(cmd),CAMSYS_IOC_MAGIC);
987 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
988 camsys_err("ioctl index(%d>%d) is invalidate\n",_IOC_NR(cmd),CAMSYS_IOC_MAXNR);
993 if (_IOC_DIR(cmd) & _IOC_READ)
994 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
995 else if (_IOC_DIR(cmd) & _IOC_WRITE)
996 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
999 camsys_err("ioctl(0x%x) operation not permitted for %s",cmd,dev_name(camsys_dev->miscdev.this_device));
1008 camsys_version_t camsys_ver;
1010 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
1011 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
1012 if (copy_to_user((void __user *)arg,(void*)&camsys_ver, sizeof(camsys_version_t)))
1016 case CAMSYS_QUREYIOMMU:
1018 int iommu_enabled = 0;
1019 #ifdef CONFIG_ROCKCHIP_IOMMU
1020 struct device_node * vpu_node =NULL;
1021 int vpu_iommu_enabled = 0;
1022 vpu_node = of_find_node_by_name(NULL, "vpu_service");
1024 of_property_read_u32(vpu_node, "iommu_enabled", &vpu_iommu_enabled);
1025 of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled);
1026 of_node_put(vpu_node);
1027 if(iommu_enabled != vpu_iommu_enabled){
1028 camsys_err("iommu status not consistent,check the dts file ! isp:%d,vpu:%d",iommu_enabled,vpu_iommu_enabled);
1033 if (copy_to_user((void __user *)arg,(void*)&iommu_enabled, sizeof(iommu_enabled)))
1039 camsys_i2c_info_t i2cinfo;
1041 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
1044 err = camsys_i2c_read(&i2cinfo,camsys_dev);
1046 if (copy_to_user((void __user *)arg,(void*)&i2cinfo, sizeof(camsys_i2c_info_t)))
1054 camsys_i2c_info_t i2cinfo;
1056 if (copy_from_user((void*)&i2cinfo,(void __user *)arg, sizeof(camsys_i2c_info_t)))
1059 err = camsys_i2c_write(&i2cinfo,camsys_dev);
1063 case CAMSYS_SYSCTRL:
1065 camsys_sysctrl_t devctl;
1067 if (copy_from_user((void*)&devctl,(void __user *)arg, sizeof(camsys_sysctrl_t)))
1070 err = camsys_sysctl(&devctl, camsys_dev);
1071 if ((err==0) && (devctl.ops == CamSys_IOMMU)){
1072 if (copy_to_user((void __user *)arg,(void*)&devctl, sizeof(camsys_sysctrl_t)))
1090 case CAMSYS_REGISTER_DEVIO:
1092 camsys_devio_name_t devio;
1094 if (copy_from_user((void*)&devio,(void __user *)arg, sizeof(camsys_devio_name_t)))
1097 err = camsys_extdev_register(&devio,camsys_dev);
1101 case CAMSYS_DEREGISTER_DEVIO:
1103 unsigned int dev_id;
1105 if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
1108 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
1112 case CAMSYS_IRQCONNECT:
1114 camsys_irqcnnt_t irqcnnt;
1116 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
1119 err = camsys_irq_connect(&irqcnnt, camsys_dev);
1124 case CAMSYS_IRQWAIT:
1126 camsys_irqsta_t irqsta;
1128 err = camsys_irq_wait(&irqsta, camsys_dev);
1130 if (copy_to_user((void __user *)arg,(void*)&irqsta, sizeof(camsys_irqsta_t)))
1136 case CAMSYS_IRQDISCONNECT:
1138 camsys_irqcnnt_t irqcnnt;
1140 if (copy_from_user((void*)&irqcnnt,(void __user *)arg, sizeof(camsys_irqcnnt_t)))
1142 err = camsys_irq_disconnect(&irqcnnt,camsys_dev,false);
1147 case CAMSYS_QUREYMEM:
1149 camsys_querymem_t qmem;
1151 if (copy_from_user((void*)&qmem,(void __user *)arg, sizeof(camsys_querymem_t)))
1154 err = camsys_querymem(camsys_dev,&qmem);
1156 if (copy_to_user((void __user *)arg,(void*)&qmem, sizeof(camsys_querymem_t)))
1175 static void camsys_vm_open(struct vm_area_struct *vma)
1177 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
1183 static void camsys_vm_close(struct vm_area_struct *vma)
1185 camsys_meminfo_t *meminfo = (camsys_meminfo_t*)vma->vm_private_data;
1191 static const struct vm_operations_struct camsys_vm_ops = {
1192 .open = camsys_vm_open,
1193 .close = camsys_vm_close,
1196 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
1198 camsys_dev_t *camsys_dev = (camsys_dev_t*)flip->private_data;
1199 unsigned long addr, start, size;
1200 camsys_mmap_type_t mem_type;
1201 camsys_meminfo_t *meminfo;
1204 mem_type = vma->vm_pgoff;
1206 if (mem_type == CamSys_Mmap_RegisterMem) {
1207 if (camsys_dev->devmems.registermem != NULL) {
1208 meminfo = camsys_dev->devmems.registermem;
1210 camsys_err("this camsys device has not register mem!");
1214 } else if (mem_type == CamSys_Mmap_I2cMem) {
1215 if (camsys_dev->devmems.i2cmem != NULL) {
1216 meminfo = camsys_dev->devmems.i2cmem;
1218 camsys_err("this camsys device has not i2c mem!");
1223 camsys_err("mmap buffer type %d is invalidate!",mem_type);
1228 size = vma->vm_end - vma->vm_start;
1229 if (size > meminfo->size) {
1231 camsys_err("mmap size(0x%lx) > memory size(0x%x), so failed!",size,meminfo->size);
1235 start = vma->vm_start;
1236 addr = __phys_to_pfn(meminfo->phy_base);
1238 if (remap_pfn_range(vma, start, addr,size,pgprot_noncached(vma->vm_page_prot))) {
1244 vma->vm_ops = &camsys_vm_ops;
1245 vma->vm_flags |= VM_IO;
1246 vma->vm_flags |=VM_ACCOUNT;//same as VM_RESERVED;
1247 vma->vm_private_data = (void*)meminfo;
1248 camsys_vm_open(vma);
1254 struct file_operations camsys_fops = {
1255 .owner = THIS_MODULE,
1256 .open = camsys_open,
1257 .release = camsys_release,
1258 .unlocked_ioctl = camsys_ioctl,
1259 .mmap = camsys_mmap,
1260 .compat_ioctl = camsys_ioctl_compat,
1263 static int camsys_platform_probe(struct platform_device *pdev){
1265 camsys_dev_t *camsys_dev;
1266 struct resource register_res ;
1267 struct device *dev = &pdev->dev;
1268 unsigned long i2cmem;
1269 camsys_meminfo_t *meminfo;
1270 unsigned int irq_id;
1272 err = of_address_to_resource(dev->of_node, 0, ®ister_res);
1274 camsys_err("Get register resource from %s platform device failed!",pdev->name);
1280 irq_id = irq_of_parse_and_map(dev->of_node, 0);
1282 camsys_err("Get irq resource from %s platform device failed!",pdev->name);
1287 camsys_dev = (camsys_dev_t*)devm_kzalloc(&pdev->dev,sizeof(camsys_dev_t), GFP_KERNEL);
1288 if (camsys_dev == NULL) {
1289 camsys_err("Allocate camsys_dev for %s platform device failed",pdev->name);
1294 //spin_lock_init(&camsys_dev->lock);
1295 mutex_init(&camsys_dev->extdevs.mut);
1296 INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1297 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1298 INIT_LIST_HEAD(&camsys_dev->list);
1302 camsys_dev->irq.irq_id = irq_id;
1303 spin_lock_init(&camsys_dev->irq.lock);
1304 INIT_LIST_HEAD(&camsys_dev->irq.irq_pool);
1305 //init_waitqueue_head(&camsys_dev->irq.irq_done);
1307 INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1309 // get soc operation
1310 camsys_dev->soc = (void*)camsys_soc_get();
1311 if (camsys_dev->soc == NULL) {
1317 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1318 if (meminfo == NULL) {
1320 goto request_mem_fail;
1323 meminfo->vir_base = (unsigned long)devm_ioremap_resource(dev, ®ister_res);
1324 if (!meminfo->vir_base){
1325 camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), CAMSYS_REGISTER_MEM_NAME);
1327 goto request_mem_fail;
1329 rk_isp_base = meminfo->vir_base;
1330 strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME,sizeof(meminfo->name));
1331 meminfo->phy_base = register_res.start;
1332 meminfo->size = register_res.end - register_res.start + 1;
1333 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1337 i2cmem = __get_free_page(GFP_KERNEL);
1339 camsys_err("Allocate i2cmem failed!");
1341 goto request_mem_fail;
1343 SetPageReserved(virt_to_page(i2cmem));
1345 meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
1346 if (meminfo == NULL) {
1348 goto request_mem_fail;
1350 strlcpy(meminfo->name,CAMSYS_I2C_MEM_NAME,sizeof(meminfo->name));
1351 meminfo->vir_base = i2cmem;
1352 meminfo->phy_base = virt_to_phys((void*)i2cmem);
1353 meminfo->size = PAGE_SIZE;
1354 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1359 tmpp = (unsigned int*)meminfo->vir_base;
1366 if (camsys_mipiphy_probe_cb(pdev, camsys_dev) <0) {
1367 camsys_err("Mipi phy probe failed!");
1372 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_MARVIN_NAME) == 0) {
1373 #if (defined(CONFIG_CAMSYS_MRV))
1374 camsys_mrv_probe_cb(pdev, camsys_dev);
1376 camsys_err("Marvin controller camsys driver haven't been complie!!!");
1379 #if (defined(CONFIG_CAMSYS_CIF))
1380 camsys_cif_probe_cb(pdev,camsys_dev);
1382 camsys_err("CIF controller camsys driver haven't been complie!!!");
1386 #if (defined(CONFIG_CAMSYS_MRV))
1387 camsys_mrv_probe_cb(pdev, camsys_dev);
1388 #elif (defined(CONFIG_CAMSYS_CIF))
1389 camsys_cif_probe_cb(pdev,camsys_dev);
1391 camsys_err("camsys driver haven't been complie!!!");
1394 camsys_trace(1, "%s memory:",dev_name(&pdev->dev));
1395 list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1396 if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME) == 0) {
1397 camsys_dev->devmems.i2cmem = meminfo;
1398 camsys_trace(1," I2c memory (phy: 0x%lx vir: 0x%lx size: 0x%x)",
1399 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1401 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME) == 0) {
1402 camsys_dev->devmems.registermem = meminfo;
1403 camsys_trace(1," Register memory (phy: 0x%lx vir: 0x%lx size: 0x%x)",
1404 meminfo->phy_base,meminfo->vir_base,meminfo->size);
1409 camsys_dev->phy_cb = camsys_phy_ops;
1410 camsys_dev->pdev = pdev;
1412 platform_set_drvdata(pdev,(void*)camsys_dev);
1413 //Camsys_devs list add
1414 spin_lock(&camsys_devs.lock);
1415 list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1416 spin_unlock(&camsys_devs.lock);
1418 camsys_init_ext_fsh_module();
1419 camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1422 if (camsys_dev != NULL) {
1424 while(!list_empty(&camsys_dev->devmems.memslist)) {
1425 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1427 list_del_init(&meminfo->list);
1428 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1429 iounmap((void __iomem *)meminfo->vir_base);
1430 release_mem_region(meminfo->phy_base,meminfo->size);
1431 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1432 kfree((void*)meminfo->vir_base);
1447 static int camsys_platform_remove(struct platform_device *pdev)
1449 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1450 camsys_meminfo_t *meminfo;
1455 while(!list_empty(&camsys_dev->devmems.memslist)) {
1456 meminfo = list_first_entry(&camsys_dev->devmems.memslist, camsys_meminfo_t, list);
1458 list_del_init(&meminfo->list);
1459 if (strcmp(meminfo->name,CAMSYS_REGISTER_MEM_NAME)==0) {
1460 iounmap((void __iomem *)meminfo->vir_base);
1461 release_mem_region(meminfo->phy_base,meminfo->size);
1462 } else if (strcmp(meminfo->name,CAMSYS_I2C_MEM_NAME)==0) {
1463 kfree((void*)meminfo->vir_base);
1471 if (camsys_dev->irq.irq_id) {
1472 free_irq(camsys_dev->irq.irq_id, camsys_dev);
1473 camsys_irq_disconnect(NULL,camsys_dev,true);
1477 if (!list_empty(&camsys_dev->extdevs.list)) {
1478 camsys_extdev_deregister(0,camsys_dev,true);
1480 if (camsys_dev->mipiphy != NULL) {
1481 camsys_dev->mipiphy->remove(pdev);
1483 if (camsys_dev->cifphy.remove)
1484 camsys_dev->cifphy.remove(pdev);
1485 camsys_dev->platform_remove(pdev);
1487 misc_deregister(&camsys_dev->miscdev);
1489 spin_lock(&camsys_devs.lock);
1490 list_del_init(&camsys_dev->list);
1491 spin_unlock(&camsys_devs.lock);
1493 camsys_deinit_ext_fsh_module();
1498 camsys_err("This platform device havn't obtain camsys_dev!");
1505 static const struct of_device_id cif_of_match[] = {
1506 { .compatible = "rockchip,isp" },
1508 MODULE_DEVICE_TABLE(of, cif_of_match);
1510 static struct platform_driver camsys_platform_driver =
1513 .name = CAMSYS_PLATFORM_DRV_NAME,
1514 .of_match_table = of_match_ptr(cif_of_match),
1516 .probe = camsys_platform_probe,
1517 .remove = (camsys_platform_remove),
1520 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1521 static int __init camsys_platform_init(void)
1523 printk("CamSys driver version: v%d.%d.%d, CamSys head file version: v%d.%d.%d\n",
1524 (CAMSYS_DRIVER_VERSION&0xff0000)>>16, (CAMSYS_DRIVER_VERSION&0xff00)>>8,
1525 CAMSYS_DRIVER_VERSION&0xff,
1526 (CAMSYS_HEAD_VERSION&0xff0000)>>16, (CAMSYS_HEAD_VERSION&0xff00)>>8,
1527 CAMSYS_HEAD_VERSION&0xff);
1529 spin_lock_init(&camsys_devs.lock);
1530 INIT_LIST_HEAD(&camsys_devs.devs);
1532 platform_driver_register(&camsys_platform_driver);
1533 // platform_driver_probe(&camsys_platform_driver, camsys_platform_probe_new);
1538 static void __exit camsys_platform_exit(void)
1540 platform_driver_unregister(&camsys_platform_driver);
1541 camsys_soc_deinit();
1544 module_init(camsys_platform_init);
1545 module_exit(camsys_platform_exit);
1547 MODULE_DESCRIPTION("RockChip Camera System");
1548 MODULE_AUTHOR("<ddl@rock-chips>");
1549 MODULE_LICENSE("GPL");