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);
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
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!",
44 dev_name(camsys_dev->miscdev.this_device));
48 totallen = (i2cinfo->i2cbuf_bytes & 0xffff);
49 onelen = (i2cinfo->i2cbuf_bytes & 0xffff0000)>>16;
50 msg_times = totallen/onelen;
51 if (totallen > camsys_dev->devmems.i2cmem->size) {
53 "Want to write 0x%x bytes, i2c memory(size: 0x%x) is overlap",
54 totallen, camsys_dev->devmems.i2cmem->size);
58 bufp = (unsigned char *)camsys_dev->devmems.i2cmem->vir_base;
60 for (i = 0; i < i2cinfo->reg_size; i++) {
61 buf[i] = (i2cinfo->reg_addr >>
62 ((i2cinfo->reg_size-1-i)*8))&0xff;
64 for (j = 0; j < i2cinfo->val_size; j++) {
65 /* ddl@rock-chips.com: v0.a.0 */
66 buf[i+j] = (i2cinfo->val >>
67 ((i2cinfo->val_size-1-j)*8))&0xff;
70 onelen = i2cinfo->val_size + i2cinfo->reg_size;
75 msg->addr = (i2cinfo->slave_addr >> 1);
78 for (i = 0; i < msg_times; i++) {
79 msg->buf = bufp + i * onelen;
80 err = i2c_transfer(adapter, msg, 1);
82 camsys_err("i2c write dev(addr:0x%x) failed!,err = %d",
83 i2cinfo->slave_addr, err);
92 static int camsys_i2c_read(
93 camsys_i2c_info_t *i2cinfo, camsys_dev_t *camsys_dev)
95 int err = 0, i, retry = 2, tmp, num_msg;
97 struct i2c_msg msg[2];
98 struct i2c_adapter *adapter;
100 adapter = i2c_get_adapter(i2cinfo->bus_num);
101 if (adapter == NULL) {
102 camsys_err("Get %d i2c adapter is failed!", i2cinfo->bus_num);
108 if (i2cinfo->reg_size) {
109 for (i = 0; i < i2cinfo->reg_size; i++) {
110 buf[i] = (i2cinfo->reg_addr>>((i2cinfo->reg_size-1-i)*8))&0xff;
113 msg[0].addr = (i2cinfo->slave_addr>>1);
116 msg[0].len = i2cinfo->reg_size;
120 msg[1].addr = (i2cinfo->slave_addr>>1);
121 msg[1].flags = I2C_M_RD;
123 msg[1].len = (unsigned short)i2cinfo->val_size;
127 while ((retry-- > 0) && (err < 0)) {
129 err = i2c_transfer(adapter, &msg[1], num_msg);
131 err = i2c_transfer(adapter, msg, num_msg);
137 camsys_err("i2c read dev(addr:0x%x) failed,try"
138 "again-%d!", i2cinfo->slave_addr, retry);
145 for (i = 0; i < i2cinfo->val_size; i++) {
147 i2cinfo->val |= (tmp<<((i2cinfo->val_size-1-i)*8));
155 static int camsys_extdev_register(camsys_devio_name_t *devio, camsys_dev_t
159 camsys_extdev_t *extdev;
160 camsys_regulator_info_t *regulator_info;
161 camsys_regulator_t *regulator;
162 camsys_gpio_info_t *gpio_info;
165 if ((devio->dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
167 camsys_err("dev_id: 0x%x is not support for camsys!",
172 extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
173 if (extdev != NULL) {
174 if (strcmp(extdev->dev_name, devio->dev_name) == 0) {
179 "Extdev(dev_id: 0x%x dev_name: %s) has been registered in %s!",
182 dev_name(camsys_dev->miscdev.this_device));
187 extdev = kzalloc(sizeof(camsys_extdev_t), GFP_KERNEL);
188 if (extdev == NULL) {
189 camsys_err("alloc camsys_extdev_t failed!");
194 extdev->dev_cfg = devio->dev_cfg;
195 extdev->fl.fl.active = devio->fl.fl.active;
196 extdev->fl.ext_fsh_dev = NULL;
198 if (strlen(devio->fl.fl_drv_name) &&
199 (strcmp(devio->fl.fl_drv_name, "Internal") != 0)
200 && (strcmp(devio->fl.fl_drv_name, "NC") != 0)) {
202 extdev->fl.ext_fsh_dev =
203 camsys_register_ext_fsh_dev(&devio->fl);
204 if (extdev->fl.ext_fsh_dev == NULL) {
205 camsys_err("register ext flash %s failed!",
206 devio->fl.fl_drv_name);
211 regulator_info = &devio->avdd;
212 regulator = &extdev->avdd;
213 for (i = (CamSys_Vdd_Start_Tag+1); i < CamSys_Vdd_End_Tag; i++) {
214 if (strcmp(regulator_info->name, "NC")) {
216 regulator_get(NULL, regulator_info->name);
217 if (IS_ERR_OR_NULL(regulator->ldo)) {
219 "Get %s regulator for dev_id 0x%x failed!",
220 regulator_info->name, devio->dev_id);
225 regulator->min_uv = regulator_info->min_uv;
226 regulator->max_uv = regulator_info->max_uv;
228 "Get %s regulator(min: %duv max: %duv) for dev_id 0x%x success",
229 regulator_info->name, regulator->min_uv,
233 regulator->ldo = NULL;
234 regulator->min_uv = 0;
235 regulator->max_uv = 0;
242 gpio_info = &devio->pwrdn;
243 gpio = &extdev->pwrdn;
244 for (i = (CamSys_Gpio_Start_Tag+1); i < CamSys_Gpio_End_Tag; i++) {
245 if (strcmp(gpio_info->name, "NC")) {
246 gpio->io = camsys_gpio_get(gpio_info->name);
249 "Get %s gpio for dev_id 0x%x failed!",
255 if (gpio_request(gpio->io, "camsys_gpio") < 0) {
256 camsys_err("Request %s(%d) failed",
257 gpio_info->name, gpio->io);
259 gpio->active = gpio_info->active;
261 "Get %s(%d) gpio(active: %d) for dev_id 0x%x success!",
262 gpio_info->name, gpio->io,
263 gpio->active, devio->dev_id);
265 gpio->io = 0xffffffff;
266 gpio->active = 0xffffffff;
273 extdev->pdev = camsys_dev->pdev;
274 extdev->phy = devio->phy;
275 extdev->clk = devio->clk;
276 extdev->dev_id = devio->dev_id;
277 mutex_lock(&camsys_dev->extdevs.mut);
278 list_add_tail(&extdev->list, &camsys_dev->extdevs.list);
279 mutex_unlock(&camsys_dev->extdevs.mut);
281 camsys_dev->iomux(extdev, (void *)camsys_dev);
283 memcpy(extdev->dev_name, devio->dev_name, sizeof(extdev->dev_name));
284 camsys_trace(1, "Extdev(dev_id: 0x%x dev_name: %s) register success",
299 static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t
300 *camsys_dev, bool all)
303 camsys_extdev_t *extdev;
304 camsys_regulator_t *regulator;
308 if ((dev_id & CAMSYS_DEVID_EXTERNAL) == 0) {
310 camsys_err("dev_id: 0x%x is not support for %s!",
312 dev_name(camsys_dev->miscdev.this_device));
316 extdev = camsys_find_extdev(dev_id, camsys_dev);
317 if (extdev == NULL) {
319 camsys_warn("Extdev(dev_id: 0x%x) isn't registered in %s!",
321 dev_name(camsys_dev->miscdev.this_device));
325 regulator = &extdev->avdd;
326 for (i = (CamSys_Vdd_Start_Tag + 1);
327 i < CamSys_Vdd_End_Tag; i++) {
328 if (!IS_ERR_OR_NULL(regulator->ldo)) {
329 while (regulator_is_enabled(regulator->ldo) > 0)
330 regulator_disable(regulator->ldo);
331 regulator_put(regulator->ldo);
336 gpio = &extdev->pwrdn;
337 for (i = (CamSys_Gpio_Start_Tag + 1);
338 i < CamSys_Gpio_End_Tag; i++) {
339 if (gpio->io != 0xffffffff) {
345 if (extdev->fl.ext_fsh_dev != NULL) {
346 camsys_deregister_ext_fsh_dev(extdev->fl.ext_fsh_dev);
348 /* spin_lock(&camsys_dev->lock); */
349 mutex_lock(&camsys_dev->extdevs.mut);
350 list_del_init(&extdev->list);
351 list_del_init(&extdev->active);
352 /* spin_unlock(&camsys_dev->lock); */
353 mutex_unlock(&camsys_dev->extdevs.mut);
355 camsys_trace(1, "Extdev(dev_id: 0x%x) is deregister success",
361 /* spin_lock(&camsys_dev->lock); */
362 mutex_lock(&camsys_dev->extdevs.mut);
363 while (!list_empty(&camsys_dev->extdevs.list)) {
364 extdev = list_first_entry(&camsys_dev->extdevs.list,
368 regulator = &extdev->avdd;
369 for (i = (CamSys_Vdd_Start_Tag+1);
370 i < CamSys_Vdd_End_Tag; i++) {
371 if (!IS_ERR(regulator->ldo)) {
373 regulator_is_enabled(
383 gpio = &extdev->pwrdn;
384 for (i = (CamSys_Gpio_Start_Tag+1);
385 i < CamSys_Gpio_End_Tag; i++) {
386 if (gpio->io != 0xffffffff) {
392 if (extdev->fl.ext_fsh_dev != NULL) {
393 camsys_deregister_ext_fsh_dev(
394 extdev->fl.ext_fsh_dev);
397 "Extdev(dev_id: 0x%x) is deregister success",
399 list_del_init(&extdev->list);
400 list_del_init(&extdev->active);
405 /* spin_unlock(&camsys_dev->lock); */
406 mutex_unlock(&camsys_dev->extdevs.mut);
407 camsys_trace(1, "All extdev is deregister success!");
414 static int camsys_sysctl_external(camsys_sysctrl_t *devctl,
415 camsys_dev_t *camsys_dev)
419 camsys_extdev_t *extdev, *extdev2;
422 for (i = 0; i < 8; i++) {
423 if ((devctl->dev_mask & (1<<(i+24))) == 0)
426 extdev = camsys_find_extdev((1 << (i+24)), camsys_dev);
428 camsys_err("Can not find dev_id 0x%x device in %s!",
430 dev_name(camsys_dev->miscdev.this_device));
432 camsys_sysctl_extdev(
433 extdev, devctl, camsys_dev);
435 if (devctl->ops == CamSys_ClkIn) {
437 list_add_tail(&extdev->active,
438 &camsys_dev->extdevs.active);
441 &camsys_dev->extdevs.active))
444 list_for_each_entry(extdev2,
445 &camsys_dev->extdevs.active,
447 if (extdev2 == extdev) {
448 list_del_init(&extdev->active);
453 } else if (devctl->ops == CamSys_Flash_Trigger) {
454 err = camsys_ext_fsh_ctrl(extdev->fl.ext_fsh_dev,
455 devctl->rev[0], devctl->on);
461 static int camsys_sysctl(camsys_sysctrl_t *devctl, camsys_dev_t *camsys_dev)
465 /* spin_lock(&camsys_dev->lock); */
466 mutex_lock(&camsys_dev->extdevs.mut);
467 if (devctl->ops == 0xaa) {
472 if (camsys_dev->dev_id & devctl->dev_mask) {
473 switch (devctl->ops) {
475 camsys_dev->clkin_cb(camsys_dev, devctl->on);
480 camsys_dev->reset_cb(camsys_dev, devctl->on);
483 case CamSys_Flash_Trigger: {
484 camsys_dev->flash_trigger_cb(
485 camsys_dev, devctl->rev[0], devctl->on);
489 if (camsys_dev->iommu_cb(camsys_dev, devctl) < 0) {
500 camsys_sysctl_external(devctl, camsys_dev);
502 /* spin_unlock(&camsys_dev->lock); */
503 mutex_unlock(&camsys_dev->extdevs.mut);
507 static int camsys_phy_ops(camsys_extdev_t *extdev, camsys_sysctrl_t *devctl,
510 camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
511 camsys_mipiphy_t *mipiphy;
514 if (extdev->phy.type == CamSys_Phy_Mipi) {
515 mipiphy = (camsys_mipiphy_t *)devctl->rev;
516 if (devctl->on == 0) {
517 mipiphy->phy_index = extdev->phy.info.mipi.phy_index;
518 mipiphy->bit_rate = 0;
519 mipiphy->data_en_bit = 0x00;
521 if ((mipiphy->bit_rate == 0) ||
522 (mipiphy->data_en_bit == 0)) {
523 *mipiphy = extdev->phy.info.mipi;
525 if (mipiphy->phy_index !=
526 extdev->phy.info.mipi.phy_index) {
528 "mipiphy->phy_index(%d) != "
529 "extdev->phy.info.mipi.phy_index(%d)!",
531 extdev->phy.info.mipi.phy_index);
533 extdev->phy.info.mipi.phy_index;
536 err = camsys_dev->mipiphy[mipiphy->phy_index].ops(ptr, mipiphy);
538 camsys_err("extdev(0x%x) mipi phy ops config failed!",
546 static int camsys_irq_connect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t
550 camsys_irqpool_t *irqpool;
551 unsigned long int flags;
553 if ((irqcnnt->mis != MRV_ISP_MIS) &&
554 (irqcnnt->mis != MRV_MIPI_MIS) &&
555 (irqcnnt->mis != MRV_MI_MIS) &&
556 (irqcnnt->mis != MRV_JPG_MIS) &&
557 (irqcnnt->mis != MRV_JPG_ERR_MIS)) {
559 camsys_err("this thread(pid: %d) irqcnnt->mis(0x%x) is invalidate,"
560 "irq connect failed!",
561 irqcnnt->pid, irqcnnt->mis);
567 spin_lock_irqsave(&camsys_dev->irq.lock, flags);
568 if (!list_empty(&camsys_dev->irq.irq_pool)) {
569 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
570 if (irqpool->pid == irqcnnt->pid) {
571 camsys_warn("this thread(pid: %d) had been connect irq!",
573 spin_unlock(&camsys_dev->irq.lock);
578 spin_unlock_irqrestore(&camsys_dev->irq.lock, flags);
580 irqpool = kzalloc(sizeof(camsys_irqpool_t), GFP_KERNEL);
582 spin_lock_init(&irqpool->lock);
583 irqpool->pid = irqcnnt->pid;
584 irqpool->timeout = irqcnnt->timeout;
585 irqpool->mis = irqcnnt->mis;
586 irqpool->icr = irqcnnt->icr;
587 INIT_LIST_HEAD(&irqpool->active);
588 INIT_LIST_HEAD(&irqpool->deactive);
589 init_waitqueue_head(&irqpool->done);
591 i < CAMSYS_IRQPOOL_NUM;
593 list_add_tail(&irqpool->pool[i].list,
598 spin_lock_irqsave(&camsys_dev->irq.lock, flags);
599 list_add_tail(&irqpool->list, &camsys_dev->irq.irq_pool);
600 spin_unlock_irqrestore(&camsys_dev->irq.lock, flags);
602 "Thread(pid: %d) connect %s irq success! mis: 0x%x icr: 0x%x",
603 irqpool->pid, dev_name(camsys_dev->miscdev.this_device),
604 irqpool->mis, irqpool->icr);
609 static int active_list_isnot_empty(camsys_irqpool_t *irqpool)
612 unsigned long int flags;
614 spin_lock_irqsave(&irqpool->lock, flags);
615 err = list_empty(&irqpool->active);
616 spin_unlock_irqrestore(&irqpool->lock, flags);
620 static int camsys_irq_wait(camsys_irqsta_t *irqsta, camsys_dev_t *camsys_dev)
623 bool find_pool = false;
624 camsys_irqstas_t *irqstas;
625 camsys_irqpool_t *irqpool;
626 unsigned long int flags;
628 spin_lock_irqsave(&camsys_dev->irq.lock, flags);
629 if (!list_empty(&camsys_dev->irq.irq_pool)) {
630 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
631 if (irqpool->pid == current->pid) {
637 spin_unlock_irqrestore(&camsys_dev->irq.lock, flags);
639 if (find_pool == false) {
641 "this thread(pid: %d) hasn't been connect irq, so wait irq failed!",
647 spin_lock_irqsave(&irqpool->lock, flags);
648 if (!list_empty(&irqpool->active)) {
649 irqstas = list_first_entry(&irqpool->active,
650 camsys_irqstas_t, list);
651 *irqsta = irqstas->sta;
652 list_del_init(&irqstas->list);
653 list_add_tail(&irqstas->list, &irqpool->deactive);
654 spin_unlock_irqrestore(&irqpool->lock, flags);
656 spin_unlock_irqrestore(&irqpool->lock, flags);
658 wait_event_interruptible_timeout(irqpool->done,
659 active_list_isnot_empty(irqpool),
660 usecs_to_jiffies(irqpool->timeout));
662 if (irqpool->pid == current->pid) {
663 if (active_list_isnot_empty(irqpool)) {
664 spin_lock_irqsave(&irqpool->lock, flags);
665 irqstas = list_first_entry(
667 camsys_irqstas_t, list);
668 *irqsta = irqstas->sta;
669 list_del_init(&irqstas->list);
673 spin_unlock_irqrestore(&irqpool->lock, flags);
679 "Thread(pid: %d) has been disconnect!",
687 "Thread(pid: %d) has been wake up for irq(mis: 0x%x ris:0x%x)!",
688 current->pid, irqsta->mis, irqsta->ris);
695 static int camsys_irq_disconnect(camsys_irqcnnt_t *irqcnnt, camsys_dev_t
696 *camsys_dev, bool all)
699 bool find_pool = false;
700 camsys_irqpool_t *irqpool;
701 unsigned long int flags;
704 spin_lock_irqsave(&camsys_dev->irq.lock, flags);
705 if (!list_empty(&camsys_dev->irq.irq_pool)) {
706 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
707 if (irqpool->pid == irqcnnt->pid) {
714 spin_unlock_irqrestore(&camsys_dev->irq.lock, flags);
716 if (find_pool == false) {
718 "this thread(pid: %d) have not been connect irq!"
722 wake_up_all(&irqpool->done);
725 camsys_trace(1, "Thread(pid: %d) disconnect %s irq success!",
727 dev_name(camsys_dev->miscdev.this_device));
729 spin_lock_irqsave(&camsys_dev->irq.lock, flags);
730 while (!list_empty(&camsys_dev->irq.irq_pool)) {
731 irqpool = list_first_entry(&camsys_dev->irq.irq_pool,
732 camsys_irqpool_t, list);
733 list_del_init(&irqpool->list);
735 wake_up_all(&irqpool->done);
739 spin_unlock_irqrestore(&camsys_dev->irq.lock, flags);
741 camsys_trace(1, "All thread disconnect %s irq success!",
742 dev_name(camsys_dev->miscdev.this_device));
748 static int camsys_querymem(camsys_dev_t *camsys_dev, camsys_querymem_t *qmem)
752 if (qmem->mem_type == CamSys_Mmap_RegisterMem) {
753 if (camsys_dev->devmems.registermem == NULL) {
754 camsys_err("%s register memory isn't been register!",
755 dev_name(camsys_dev->miscdev.this_device));
760 qmem->mem_size = camsys_dev->devmems.registermem->size;
761 qmem->mem_offset = CamSys_Mmap_RegisterMem*PAGE_SIZE;
762 } else if (qmem->mem_type == CamSys_Mmap_I2cMem) {
763 if (camsys_dev->devmems.i2cmem == NULL) {
764 camsys_err("%s i2c memory isn't been register!",
765 dev_name(camsys_dev->miscdev.this_device));
770 qmem->mem_size = camsys_dev->devmems.i2cmem->size;
771 qmem->mem_offset = CamSys_Mmap_I2cMem*PAGE_SIZE;
774 "%d memory type have not in %s memory list",
776 dev_name(camsys_dev->miscdev.this_device));
785 static int camsys_open(struct inode *inode, struct file *file)
788 int minor = iminor(inode);
789 camsys_dev_t *camsys_dev;
790 unsigned int i, phycnt;
792 spin_lock(&camsys_devs.lock);
793 list_for_each_entry(camsys_dev, &camsys_devs.devs, list) {
794 if (camsys_dev->miscdev.minor == minor) {
795 file->private_data = (void *)(camsys_dev);
799 spin_unlock(&camsys_devs.lock);
801 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
803 if (camsys_dev->mipiphy != NULL) {
804 phycnt = camsys_dev->mipiphy[0].phycnt;
806 for (i = 0; i < phycnt; i++) {
807 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
808 camsys_dev->mipiphy[i].clkin_cb(camsys_dev, 1);
814 if (file->private_data == NULL) {
815 camsys_err("Cann't find camsys_dev!");
821 dev_name(camsys_dev->miscdev.this_device), camsys_dev);
828 static int camsys_release(struct inode *inode, struct file *file)
830 camsys_dev_t *camsys_dev = (camsys_dev_t *)file->private_data;
831 unsigned int i, phycnt;
833 camsys_irq_disconnect(NULL, camsys_dev, true);
835 if (camsys_dev->mipiphy != NULL) {
836 phycnt = camsys_dev->mipiphy[0].phycnt;
838 for (i = 0; i < phycnt; i++) {
839 if (camsys_dev->mipiphy[i].clkin_cb != NULL) {
840 camsys_dev->mipiphy[i].clkin_cb(camsys_dev, 0);
847 dev_name(camsys_dev->miscdev.this_device),
854 * The ioctl() implementation
857 typedef struct camsys_querymem_s_32 {
858 camsys_mmap_type_t mem_type;
859 unsigned int mem_offset;
860 unsigned int mem_size;
861 } camsys_querymem_32_t;
863 #define CAMSYS_QUREYMEM_32 \
864 _IOR(CAMSYS_IOC_MAGIC, 11, camsys_querymem_32_t)
866 static long camsys_ioctl_compat(struct file *filp, unsigned int cmd, unsigned
870 camsys_dev_t *camsys_dev = (camsys_dev_t *)filp->private_data;
872 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
874 "ioctl type(%c!=%c) is invalidate\n",
875 _IOC_TYPE(cmd), CAMSYS_IOC_MAGIC);
879 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
880 camsys_err("ioctl index(%d>%d) is invalidate\n",
881 _IOC_NR(cmd), CAMSYS_IOC_MAXNR);
886 if (_IOC_DIR(cmd) & _IOC_READ)
891 else if (_IOC_DIR(cmd) & _IOC_WRITE)
899 "ioctl(0x%x) operation not permitted for %s",
900 cmd, dev_name(camsys_dev->miscdev.this_device));
907 case CAMSYS_VERCHK: {
908 camsys_version_t camsys_ver;
910 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
911 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
912 if (copy_to_user((void __user *)arg,
914 sizeof(camsys_version_t)))
917 case CAMSYS_QUREYIOMMU: {
918 int iommu_enabled = 0;
919 struct device_node *vpu_node = NULL;
920 int vpu_iommu_enabled = 0;
922 vpu_node = of_find_node_by_name(NULL, "vpu_service");
924 of_property_read_u32(vpu_node,
925 "iommu_enabled", &vpu_iommu_enabled);
926 of_property_read_u32(camsys_dev->pdev->dev.of_node,
927 "rockchip,isp,iommu-enable", &iommu_enabled);
928 of_node_put(vpu_node);
929 if (iommu_enabled != vpu_iommu_enabled) {
931 "iommu status not consistent,"
932 "check the dts file !isp:%d,vpu:%d",
933 iommu_enabled, vpu_iommu_enabled);
939 if (copy_to_user((void __user *)arg,
940 (void *)&iommu_enabled,
941 sizeof(iommu_enabled)))
947 camsys_i2c_info_t i2cinfo;
949 if (copy_from_user((void *)&i2cinfo,
951 sizeof(camsys_i2c_info_t)))
954 err = camsys_i2c_read(&i2cinfo, camsys_dev);
956 if (copy_to_user((void __user *)arg, (void *)&i2cinfo,
957 sizeof(camsys_i2c_info_t)))
964 camsys_i2c_info_t i2cinfo;
966 if (copy_from_user((void *)&i2cinfo, (void __user *)arg,
967 sizeof(camsys_i2c_info_t)))
970 err = camsys_i2c_write(&i2cinfo, camsys_dev);
974 case CAMSYS_SYSCTRL: {
975 camsys_sysctrl_t devctl;
977 if (copy_from_user((void *)&devctl, (void __user *)arg,
978 sizeof(camsys_sysctrl_t)))
981 err = camsys_sysctl(&devctl, camsys_dev);
982 if ((err == 0) && (devctl.ops == CamSys_IOMMU)) {
983 if (copy_to_user((void __user *)arg, (void *)&devctl,
984 sizeof(camsys_sysctrl_t)))
998 case CAMSYS_REGISTER_DEVIO: {
999 camsys_devio_name_t devio;
1001 if (copy_from_user((void *)&devio, (void __user *)arg,
1002 sizeof(camsys_devio_name_t)))
1005 err = camsys_extdev_register(&devio, camsys_dev);
1009 case CAMSYS_DEREGISTER_DEVIO: {
1010 unsigned int dev_id;
1012 if (copy_from_user((void *)&dev_id, (void __user *)arg,
1013 sizeof(unsigned int)))
1016 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
1020 case CAMSYS_IRQCONNECT: {
1021 camsys_irqcnnt_t irqcnnt;
1023 if (copy_from_user((void *)&irqcnnt, (void __user *)arg,
1024 sizeof(camsys_irqcnnt_t)))
1027 err = camsys_irq_connect(&irqcnnt, camsys_dev);
1032 case CAMSYS_IRQWAIT: {
1033 camsys_irqsta_t irqsta;
1035 err = camsys_irq_wait(&irqsta, camsys_dev);
1037 if (copy_to_user((void __user *)arg, (void *)&irqsta,
1038 sizeof(camsys_irqsta_t)))
1044 case CAMSYS_IRQDISCONNECT: {
1045 camsys_irqcnnt_t irqcnnt;
1047 if (copy_from_user((void *)&irqcnnt, (void __user *)arg,
1048 sizeof(camsys_irqcnnt_t)))
1050 err = camsys_irq_disconnect(&irqcnnt, camsys_dev, false);
1054 case CAMSYS_QUREYMEM_32: {
1055 camsys_querymem_t qmem;
1056 camsys_querymem_32_t qmem32;
1058 if (copy_from_user((void *)&qmem32, (void __user *)arg,
1059 sizeof(camsys_querymem_32_t)))
1062 qmem.mem_type = qmem32.mem_type;
1063 err = camsys_querymem(camsys_dev, &qmem);
1065 qmem32.mem_offset = (unsigned int)qmem.mem_offset;
1066 qmem32.mem_size = qmem.mem_size;
1067 if (copy_to_user((void __user *)arg, (void *)&qmem32,
1068 sizeof(camsys_querymem_32_t)))
1082 static long camsys_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1085 camsys_dev_t *camsys_dev = (camsys_dev_t *)filp->private_data;
1087 if (_IOC_TYPE(cmd) != CAMSYS_IOC_MAGIC) {
1088 camsys_err("ioctl type(%c!=%c) is invalidate\n",
1089 _IOC_TYPE(cmd), CAMSYS_IOC_MAGIC);
1093 if (_IOC_NR(cmd) > CAMSYS_IOC_MAXNR) {
1094 camsys_err("ioctl index(%d>%d) is invalidate\n",
1095 _IOC_NR(cmd), CAMSYS_IOC_MAXNR);
1100 if (_IOC_DIR(cmd) & _IOC_READ)
1101 err = !access_ok(VERIFY_WRITE,
1102 (void __user *)arg, _IOC_SIZE(cmd));
1103 else if (_IOC_DIR(cmd) & _IOC_WRITE)
1104 err = !access_ok(VERIFY_READ,
1105 (void __user *)arg, _IOC_SIZE(cmd));
1108 camsys_err("ioctl(0x%x) operation not permitted for %s",
1109 cmd, dev_name(camsys_dev->miscdev.this_device));
1115 case CAMSYS_VERCHK: {
1116 camsys_version_t camsys_ver;
1118 camsys_ver.drv_ver = CAMSYS_DRIVER_VERSION;
1119 camsys_ver.head_ver = CAMSYS_HEAD_VERSION;
1120 if (copy_to_user((void __user *)arg, (void *)&camsys_ver,
1121 sizeof(camsys_version_t)))
1125 case CAMSYS_QUREYIOMMU: {
1126 int iommu_enabled = 0;
1127 struct device_node *vpu_node = NULL;
1128 int vpu_iommu_enabled = 0;
1130 vpu_node = of_find_node_by_name(NULL, "vpu_service");
1132 of_property_read_u32(vpu_node,
1133 "iommu_enabled", &vpu_iommu_enabled);
1134 of_property_read_u32(camsys_dev->pdev->dev.of_node,
1135 "rockchip,isp,iommu-enable", &iommu_enabled);
1136 of_node_put(vpu_node);
1137 if (iommu_enabled != vpu_iommu_enabled) {
1139 "iommu status not consistent,"
1140 "check the dts file !isp:%d,vpu:%d",
1141 iommu_enabled, vpu_iommu_enabled);
1146 if (copy_to_user((void __user *)arg, (void *)&iommu_enabled,
1147 sizeof(iommu_enabled)))
1151 case CAMSYS_I2CRD: {
1152 camsys_i2c_info_t i2cinfo;
1154 if (copy_from_user((void *)&i2cinfo, (void __user *)arg,
1155 sizeof(camsys_i2c_info_t)))
1158 err = camsys_i2c_read(&i2cinfo, camsys_dev);
1160 if (copy_to_user((void __user *)arg, (void *)&i2cinfo,
1161 sizeof(camsys_i2c_info_t)))
1167 case CAMSYS_I2CWR: {
1168 camsys_i2c_info_t i2cinfo;
1170 if (copy_from_user((void *)&i2cinfo, (void __user *)arg,
1171 sizeof(camsys_i2c_info_t)))
1174 err = camsys_i2c_write(&i2cinfo, camsys_dev);
1178 case CAMSYS_SYSCTRL: {
1179 camsys_sysctrl_t devctl;
1181 if (copy_from_user((void *)&devctl, (void __user *)arg,
1182 sizeof(camsys_sysctrl_t)))
1185 err = camsys_sysctl(&devctl, camsys_dev);
1186 if ((err == 0) && (devctl.ops == CamSys_IOMMU)) {
1187 if (copy_to_user((void __user *)arg, (void *)&devctl,
1188 sizeof(camsys_sysctrl_t)))
1194 case CAMSYS_REGRD: {
1199 case CAMSYS_REGWR: {
1204 case CAMSYS_REGISTER_DEVIO:
1206 camsys_devio_name_t devio;
1208 if (copy_from_user((void *)&devio, (void __user *)arg,
1209 sizeof(camsys_devio_name_t)))
1212 err = camsys_extdev_register(&devio, camsys_dev);
1216 case CAMSYS_DEREGISTER_DEVIO:
1218 unsigned int dev_id;
1220 if (copy_from_user((void *)&dev_id,
1222 sizeof(unsigned int)))
1225 err = camsys_extdev_deregister(dev_id, camsys_dev, false);
1229 case CAMSYS_IRQCONNECT:
1231 camsys_irqcnnt_t irqcnnt;
1233 if (copy_from_user((void *)&irqcnnt, (void __user *)arg,
1234 sizeof(camsys_irqcnnt_t)))
1237 err = camsys_irq_connect(&irqcnnt, camsys_dev);
1242 case CAMSYS_IRQWAIT:
1244 camsys_irqsta_t irqsta;
1246 err = camsys_irq_wait(&irqsta, camsys_dev);
1248 if (copy_to_user((void __user *)arg, (void *)&irqsta,
1249 sizeof(camsys_irqsta_t)))
1255 case CAMSYS_IRQDISCONNECT:
1257 camsys_irqcnnt_t irqcnnt;
1259 if (copy_from_user((void *)&irqcnnt, (void __user *)arg,
1260 sizeof(camsys_irqcnnt_t)))
1262 err = camsys_irq_disconnect(&irqcnnt, camsys_dev, false);
1266 case CAMSYS_QUREYMEM:
1268 camsys_querymem_t qmem;
1270 if (copy_from_user((void *)&qmem, (void __user *)arg,
1271 sizeof(camsys_querymem_t)))
1274 err = camsys_querymem(camsys_dev, &qmem);
1276 if (copy_to_user((void __user *)arg, (void *)&qmem,
1277 sizeof(camsys_querymem_t)))
1294 static void camsys_vm_open(struct vm_area_struct *vma)
1296 camsys_meminfo_t *meminfo = (camsys_meminfo_t *)vma->vm_private_data;
1302 static void camsys_vm_close(struct vm_area_struct *vma)
1304 camsys_meminfo_t *meminfo = (camsys_meminfo_t *)vma->vm_private_data;
1310 static const struct vm_operations_struct camsys_vm_ops = {
1311 .open = camsys_vm_open,
1312 .close = camsys_vm_close,
1315 int camsys_mmap(struct file *flip, struct vm_area_struct *vma)
1317 camsys_dev_t *camsys_dev = (camsys_dev_t *)flip->private_data;
1318 unsigned long addr, start, size;
1319 camsys_mmap_type_t mem_type;
1320 camsys_meminfo_t *meminfo;
1323 mem_type = vma->vm_pgoff;
1325 if (mem_type == CamSys_Mmap_RegisterMem) {
1326 if (camsys_dev->devmems.registermem != NULL) {
1327 meminfo = camsys_dev->devmems.registermem;
1329 camsys_err("this camsys device has not register mem!");
1333 } else if (mem_type == CamSys_Mmap_I2cMem) {
1334 if (camsys_dev->devmems.i2cmem != NULL) {
1335 meminfo = camsys_dev->devmems.i2cmem;
1337 camsys_err("this camsys device has not i2c mem!");
1342 camsys_err("mmap buffer type %d is invalidate!", mem_type);
1347 size = vma->vm_end - vma->vm_start;
1348 if (size > meminfo->size) {
1351 "mmap size(0x%lx) > memory size(0x%x), so failed!",
1352 size, meminfo->size);
1356 start = vma->vm_start;
1357 addr = __phys_to_pfn(meminfo->phy_base);
1359 if (remap_pfn_range(vma, start,
1360 addr, size, pgprot_noncached(vma->vm_page_prot))) {
1365 vma->vm_ops = &camsys_vm_ops;
1366 vma->vm_flags |= VM_IO;
1367 vma->vm_flags |= VM_ACCOUNT;
1368 vma->vm_private_data = (void *)meminfo;
1369 camsys_vm_open(vma);
1375 struct file_operations camsys_fops = {
1376 .owner = THIS_MODULE,
1377 .open = camsys_open,
1378 .release = camsys_release,
1379 .unlocked_ioctl = camsys_ioctl,
1380 .mmap = camsys_mmap,
1381 .compat_ioctl = camsys_ioctl_compat,
1384 static int camsys_platform_probe(struct platform_device *pdev)
1387 camsys_dev_t *camsys_dev;
1388 struct resource register_res;
1389 struct device *dev = &pdev->dev;
1390 unsigned long i2cmem;
1391 camsys_meminfo_t *meminfo;
1392 unsigned int irq_id;
1393 const char *compatible = NULL;
1395 err = of_property_read_string(dev->of_node, "compatible", &compatible);
1397 camsys_err("get compatible failed!");
1399 camsys_trace(1, "compatible is %s\n", compatible);
1401 if (strstr(compatible, "rk3368"))
1403 else if (strstr(compatible, "rk3288"))
1405 else if (strstr(compatible, "rk3366"))
1407 else if (strstr(compatible, "rk3399"))
1410 camsys_soc_init(CHIP_TYPE);
1412 err = of_address_to_resource(dev->of_node, 0, ®ister_res);
1415 "Get register resource from %s platform device failed!",
1422 irq_id = irq_of_parse_and_map(dev->of_node, 0);
1424 camsys_err("Get irq resource from %s platform device failed!",
1430 camsys_dev = (camsys_dev_t *)devm_kzalloc(&pdev->dev,
1431 sizeof(camsys_dev_t),
1433 if (camsys_dev == NULL) {
1434 camsys_err("Allocate camsys_dev for %s platform device failed",
1440 /* spin_lock_init(&camsys_dev->lock); */
1441 mutex_init(&camsys_dev->extdevs.mut);
1442 INIT_LIST_HEAD(&camsys_dev->extdevs.list);
1443 INIT_LIST_HEAD(&camsys_dev->extdevs.active);
1444 INIT_LIST_HEAD(&camsys_dev->list);
1447 camsys_dev->irq.irq_id = irq_id;
1448 spin_lock_init(&camsys_dev->irq.lock);
1449 INIT_LIST_HEAD(&camsys_dev->irq.irq_pool);
1450 /* init_waitqueue_head(&camsys_dev->irq.irq_done); */
1452 INIT_LIST_HEAD(&camsys_dev->devmems.memslist);
1454 /* get soc operation */
1455 camsys_dev->soc = (void *)camsys_soc_get();
1456 if (camsys_dev->soc == NULL) {
1461 /* Register mem init */
1462 meminfo = kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
1463 if (meminfo == NULL) {
1465 goto request_mem_fail;
1469 (unsigned long)devm_ioremap_resource(dev, ®ister_res);
1470 if (!meminfo->vir_base) {
1471 camsys_err("%s ioremap %s failed",
1472 dev_name(&pdev->dev),
1473 CAMSYS_REGISTER_MEM_NAME);
1475 goto request_mem_fail;
1477 camsys_dev->rk_isp_base = meminfo->vir_base;
1479 strlcpy(meminfo->name, CAMSYS_REGISTER_MEM_NAME, sizeof(meminfo->name));
1480 meminfo->phy_base = register_res.start;
1481 meminfo->size = register_res.end - register_res.start + 1;
1482 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1485 i2cmem = __get_free_page(GFP_KERNEL);
1487 camsys_err("Allocate i2cmem failed!");
1489 goto request_mem_fail;
1491 SetPageReserved(virt_to_page(i2cmem));
1493 meminfo = kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
1494 if (meminfo == NULL) {
1496 goto request_mem_fail;
1498 strlcpy(meminfo->name, CAMSYS_I2C_MEM_NAME, sizeof(meminfo->name));
1499 meminfo->vir_base = i2cmem;
1500 meminfo->phy_base = virt_to_phys((void *)i2cmem);
1501 meminfo->size = PAGE_SIZE;
1502 list_add_tail(&meminfo->list, &camsys_dev->devmems.memslist);
1507 tmpp = (unsigned int *)meminfo->vir_base;
1513 if (camsys_mipiphy_probe_cb(pdev, camsys_dev) < 0) {
1514 camsys_err("Mipi phy probe failed!");
1518 #if (defined(CONFIG_CAMSYS_MRV))
1519 camsys_mrv_probe_cb(pdev, camsys_dev);
1520 #elif (defined(CONFIG_CAMSYS_CIF))
1521 camsys_cif_probe_cb(pdev, camsys_dev);
1523 camsys_err("camsys driver haven't been complie!!!");
1527 "%s memory:", dev_name(&pdev->dev));
1528 list_for_each_entry(meminfo, &camsys_dev->devmems.memslist, list) {
1529 if (strcmp(meminfo->name, CAMSYS_I2C_MEM_NAME) == 0) {
1530 camsys_dev->devmems.i2cmem = meminfo;
1532 " I2c memory (phy: 0x%lx vir: 0x%lx size: 0x%x)",
1537 if (strcmp(meminfo->name, CAMSYS_REGISTER_MEM_NAME) == 0) {
1538 camsys_dev->devmems.registermem = meminfo;
1540 " Register memory (phy: 0x%lx vir: 0x%lx size: 0x%x)",
1547 camsys_dev->phy_cb = camsys_phy_ops;
1548 camsys_dev->pdev = pdev;
1550 platform_set_drvdata(pdev, (void *)camsys_dev);
1551 /* Camsys_devs list add */
1552 spin_lock(&camsys_devs.lock);
1553 list_add_tail(&camsys_dev->list, &camsys_devs.devs);
1554 spin_unlock(&camsys_devs.lock);
1556 camsys_init_ext_fsh_module();
1557 camsys_trace(1, "Probe %s device success ", dev_name(&pdev->dev));
1560 if (camsys_dev != NULL) {
1561 while (!list_empty(&camsys_dev->devmems.memslist)) {
1562 meminfo = list_first_entry(
1563 &camsys_dev->devmems.memslist,
1564 camsys_meminfo_t, list);
1568 list_del_init(&meminfo->list);
1569 if (strcmp(meminfo->name,
1570 CAMSYS_REGISTER_MEM_NAME) == 0) {
1571 iounmap((void __iomem *)meminfo->vir_base);
1575 } else if (strcmp(meminfo->name,
1576 CAMSYS_I2C_MEM_NAME) == 0) {
1577 kfree((void *)meminfo->vir_base);
1589 static int camsys_platform_remove(struct platform_device *pdev)
1591 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
1592 camsys_meminfo_t *meminfo;
1595 while (!list_empty(&camsys_dev->devmems.memslist)) {
1596 meminfo = list_first_entry(
1597 &camsys_dev->devmems.memslist,
1598 camsys_meminfo_t, list);
1602 list_del_init(&meminfo->list);
1603 if (strcmp(meminfo->name,
1604 CAMSYS_REGISTER_MEM_NAME) == 0) {
1605 iounmap((void __iomem *)meminfo->vir_base);
1606 release_mem_region(meminfo->phy_base,
1608 } else if (strcmp(meminfo->name,
1609 CAMSYS_I2C_MEM_NAME) == 0) {
1610 kfree((void *)meminfo->vir_base);
1615 if (camsys_dev->irq.irq_id) {
1616 free_irq(camsys_dev->irq.irq_id, camsys_dev);
1617 camsys_irq_disconnect(NULL, camsys_dev, true);
1620 if (!list_empty(&camsys_dev->extdevs.list)) {
1621 camsys_extdev_deregister(0, camsys_dev, true);
1623 if (camsys_dev->mipiphy != NULL) {
1624 camsys_dev->mipiphy->remove(pdev);
1626 if (camsys_dev->cifphy.remove)
1627 camsys_dev->cifphy.remove(pdev);
1628 camsys_dev->platform_remove(pdev);
1630 misc_deregister(&camsys_dev->miscdev);
1632 spin_lock(&camsys_devs.lock);
1633 list_del_init(&camsys_dev->list);
1634 spin_unlock(&camsys_devs.lock);
1636 camsys_deinit_ext_fsh_module();
1641 camsys_err("This platform device havn't obtain camsys_dev!");
1648 static const struct of_device_id cif_of_match[] = {
1649 { .compatible = "rockchip,isp" },
1651 MODULE_DEVICE_TABLE(of, cif_of_match);
1653 static struct platform_driver camsys_platform_driver = {
1655 .name = CAMSYS_PLATFORM_DRV_NAME,
1656 .of_match_table = of_match_ptr(cif_of_match),
1658 .probe = camsys_platform_probe,
1659 .remove = (camsys_platform_remove),
1662 MODULE_ALIAS(CAMSYS_PLATFORM_DRV_NAME);
1663 static int __init camsys_platform_init(void)
1665 printk("CamSys driver version: v%d.%d.%d, "
1666 "CamSys head file version: v%d.%d.%d\n",
1667 (CAMSYS_DRIVER_VERSION&0xff0000) >> 16,
1668 (CAMSYS_DRIVER_VERSION&0xff00) >> 8,
1669 CAMSYS_DRIVER_VERSION&0xff,
1670 (CAMSYS_HEAD_VERSION&0xff0000) >> 16,
1671 (CAMSYS_HEAD_VERSION&0xff00) >> 8,
1672 CAMSYS_HEAD_VERSION&0xff);
1674 spin_lock_init(&camsys_devs.lock);
1675 INIT_LIST_HEAD(&camsys_devs.devs);
1676 platform_driver_register(&camsys_platform_driver);
1681 static void __exit camsys_platform_exit(void)
1683 platform_driver_unregister(&camsys_platform_driver);
1684 camsys_soc_deinit();
1687 module_init(camsys_platform_init);
1688 module_exit(camsys_platform_exit);
1690 MODULE_DESCRIPTION("RockChip Camera System");
1691 MODULE_AUTHOR("<ddl@rock-chips>");
1692 MODULE_LICENSE("GPL");