static int __init mx1_camera_probe(struct platform_device *pdev) { struct mx1_camera_dev *pcdev; struct resource *res; struct pt_regs regs; struct clk *clk; void __iomem *base; unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || (int)irq <= 0) { err = -ENODEV; goto exit; } clk = clk_get(&pdev->dev, "csi_clk"); if (IS_ERR(clk)) { err = PTR_ERR(clk); goto exit; } pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); err = -ENOMEM; goto exit_put_clk; } pcdev->res = res; pcdev->clk = clk; pcdev->pdata = pdev->dev.platform_data; if (pcdev->pdata) pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; if (!pcdev->mclk) { dev_warn(&pdev->dev, "mclk_10khz == 0! Please, fix your platform data. " "Using default 20MHz\n"); pcdev->mclk = 20000000; } INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); /* * Request the regions. */ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { err = -EBUSY; goto exit_kfree; } base = ioremap(res->start, resource_size(res)); if (!base) { err = -ENOMEM; goto exit_release; } pcdev->irq = irq; pcdev->base = base; /* request dma */ pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH); if (pcdev->dma_chan < 0) { dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n"); err = -EBUSY; goto exit_iounmap; } dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan); imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL, pcdev); imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO, IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0); /* burst length : 16 words = 64 bytes */ imx_dma_config_burstlen(pcdev->dma_chan, 0); /* request irq */ err = claim_fiq(&fh); if (err) { dev_err(&pdev->dev, "Camera interrupt register failed\n"); goto exit_free_dma; } set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end - &mx1_camera_sof_fiq_start); regs.ARM_r8 = (long)MX1_DMA_DIMR; regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan); regs.ARM_r10 = (long)pcdev->base + CSICR1; regs.ARM_fp = (long)pcdev->base + CSISR; regs.ARM_sp = 1 << pcdev->dma_chan; set_fiq_regs(®s); mxc_set_irq_fiq(irq, 1); enable_fiq(irq); pcdev->soc_host.drv_name = DRIVER_NAME; pcdev->soc_host.ops = &mx1_soc_camera_host_ops; pcdev->soc_host.priv = pcdev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); if (err) goto exit_free_irq; dev_info(&pdev->dev, "MX1 Camera driver loaded\n"); return 0; exit_free_irq: disable_fiq(irq); mxc_set_irq_fiq(irq, 0); release_fiq(&fh); exit_free_dma: imx_dma_free(pcdev->dma_chan); exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); exit_put_clk: clk_put(clk); exit: return err; }
static int __init omap1_cam_probe(struct platform_device *pdev) { struct omap1_cam_dev *pcdev; struct resource *res; struct clk *clk; void __iomem *base; unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || (int)irq <= 0) { err = -ENODEV; goto exit; } clk = clk_get(&pdev->dev, "armper_ck"); if (IS_ERR(clk)) { err = PTR_ERR(clk); goto exit; } pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); err = -ENOMEM; goto exit_put_clk; } pcdev->res = res; pcdev->clk = clk; pcdev->pdata = pdev->dev.platform_data; pcdev->pflags = pcdev->pdata->flags; if (pcdev->pdata) pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000; switch (pcdev->camexclk) { case 6000000: case 8000000: case 9600000: case 12000000: case 24000000: break; default: dev_warn(&pdev->dev, "Incorrect sensor clock frequency %ld kHz, " "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, " "please correct your platform data\n", pcdev->pdata->camexclk_khz); pcdev->camexclk = 0; case 0: dev_info(&pdev->dev, "Not providing sensor clock\n"); } INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); /* * Request the region. */ if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) { err = -EBUSY; goto exit_kfree; } base = ioremap(res->start, resource_size(res)); if (!base) { err = -ENOMEM; goto exit_release; } pcdev->irq = irq; pcdev->base = base; sensor_reset(pcdev, true); err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME, dma_isr, (void *)pcdev, &pcdev->dma_ch); if (err < 0) { dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n"); err = -EBUSY; goto exit_iounmap; } dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch); /* preconfigure DMA */ omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA, 0, 0); omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4); /* setup DMA autoinitialization */ omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch); err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev); if (err) { dev_err(&pdev->dev, "Camera interrupt register failed\n"); goto exit_free_dma; } pcdev->soc_host.drv_name = DRIVER_NAME; pcdev->soc_host.ops = &omap1_host_ops; pcdev->soc_host.priv = pcdev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); if (err) goto exit_free_irq; dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n"); return 0; exit_free_irq: free_irq(pcdev->irq, pcdev); exit_free_dma: omap_free_dma(pcdev->dma_ch); exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); exit_put_clk: clk_put(clk); exit: return err; }
static int __devinit mx3_camera_probe(struct platform_device *pdev) { struct mx3_camera_dev *mx3_cam; struct resource *res; void __iomem *base; int err = 0; struct soc_camera_host *soc_host; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { err = -ENODEV; goto egetres; } mx3_cam = vzalloc(sizeof(*mx3_cam)); if (!mx3_cam) { dev_err(&pdev->dev, "Could not allocate mx3 camera object\n"); err = -ENOMEM; goto ealloc; } mx3_cam->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(mx3_cam->clk)) { err = PTR_ERR(mx3_cam->clk); goto eclkget; } mx3_cam->pdata = pdev->dev.platform_data; mx3_cam->platform_flags = mx3_cam->pdata->flags; if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15))) { /* * Platform hasn't set available data widths. This is bad. * Warn and use a default. */ dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " "data widths, using default 8 bit\n"); mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; } mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; if (!mx3_cam->mclk) { dev_warn(&pdev->dev, "mclk_10khz == 0! Please, fix your platform data. " "Using default 20MHz\n"); mx3_cam->mclk = 20000000; } /* list of video-buffers */ INIT_LIST_HEAD(&mx3_cam->capture); spin_lock_init(&mx3_cam->lock); base = ioremap(res->start, resource_size(res)); if (!base) { pr_err("Couldn't map %x@%x\n", resource_size(res), res->start); err = -ENOMEM; goto eioremap; } mx3_cam->base = base; soc_host = &mx3_cam->soc_host; soc_host->drv_name = MX3_CAM_DRV_NAME; soc_host->ops = &mx3_soc_camera_host_ops; soc_host->priv = mx3_cam; soc_host->v4l2_dev.dev = &pdev->dev; soc_host->nr = pdev->id; mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); if (IS_ERR(mx3_cam->alloc_ctx)) { err = PTR_ERR(mx3_cam->alloc_ctx); goto eallocctx; } err = soc_camera_host_register(soc_host); if (err) goto ecamhostreg; /* IDMAC interface */ dmaengine_get(); return 0; ecamhostreg: vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx); eallocctx: iounmap(base); eioremap: clk_put(mx3_cam->clk); eclkget: vfree(mx3_cam); ealloc: egetres: return err; }
static int ak_camera_probe(struct platform_device *pdev) { struct ak_camera_dev *pcdev; struct resource *res; struct clk *clk, *cis_sclk; void __iomem *base; unsigned int irq, rfled_irq; int err = 0; CAMDBG("entry %s\n", __func__); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || irq < 0) { printk("platform_get_irq | platform_get_resource\n"); err = -ENODEV; goto exit; } /* * @get isp working clock */ clk = clk_get(&pdev->dev, "camera"); if (IS_ERR(clk)) { err = PTR_ERR(clk); goto exit; } /* * @get cis_sclk for sensor */ cis_sclk = clk_get(&pdev->dev, "sensor"); if (IS_ERR(cis_sclk)) { err = PTR_ERR(cis_sclk); goto exit_put_clk; } /* ** @allocate memory to struct ak_camera, including struct soc_camera_host ** @and struct v4l2_device */ pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); if (!pcdev) { err = -ENOMEM; goto exit_put_cisclk; } /* @initailization for struct pcdev */ pcdev->res = res; pcdev->clk = clk; pcdev->cis_sclk = cis_sclk; pcdev->dma_running = 0; pcdev->pdata = pdev->dev.platform_data; if (!pcdev->pdata) { err = -ENODEV; goto exit_put_cisclk; } if (pcdev->mclk > 0) pcdev->mclk = pcdev->pdata->mclk; else { dev_warn(&pdev->dev, "Platform mclk == 0! Please, fix your platform data. " "Using default 24MHz\n"); pcdev->mclk = 24; } if (pcdev->pdata->rf_led.pin > 0) pcdev->pdata->gpio_set(&pcdev->pdata->rf_led); INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); /* * Request the regions. */ if (!request_mem_region(res->start, resource_size(res), AK_CAM_DRV_NAME)) { err = -EBUSY; goto exit_kfree; } base = ioremap_nocache(res->start, resource_size(res)); if (!base) { err = -ENOMEM; goto exit_release; } pcdev->irq = irq; pcdev->base = base; /* * @initialize pcdev->isp_struct */ pcdev->isp.base = base; if (isp_module_init(&pcdev->isp) < 0) { err = -ENOMEM; goto exit_iounmap; } if (pcdev->pdata->rf_led.pin > 0) { setup_timer(&pcdev->timer, rfled_timer, (unsigned long)pcdev); rfled_irq = ak_gpio_to_irq(pcdev->pdata->rf_led.pin); err = request_irq(rfled_irq, ak_rfled_isr, IRQF_DISABLED, "rfled", pcdev); if (err) { err = -ENODEV; goto exit_iounmap; } } /* * request irq */ err = request_irq(irq, ak_camera_dma_irq, IRQF_DISABLED, "ak_camera", pcdev); if (err) { err = -EBUSY; goto exit_freeisp; } /* init auto white balance*/ INIT_DELAYED_WORK(&pcdev->isp.awb_work, isp_awb_work); /* init auto exposure*/ INIT_DELAYED_WORK(&pcdev->isp.ae_work, isp_ae_work); /* ** @register soc_camera_host */ pcdev->soc_host.drv_name = AK_CAM_DRV_NAME; pcdev->soc_host.ops = &ak_soc_camera_host_ops; pcdev->soc_host.priv = pcdev; pcdev->soc_host.v4l2_dev.dev = &pdev->dev; pcdev->soc_host.nr = pdev->id; err = soc_camera_host_register(&pcdev->soc_host); if (err) { goto exit_freeirq; } dev_info(&pdev->dev, "AK Camera driver loaded\n"); return 0; exit_freeirq: free_irq(irq, pcdev); exit_freeisp: isp_module_fini(&pcdev->isp); exit_iounmap: iounmap(base); exit_release: release_mem_region(res->start, resource_size(res)); exit_kfree: kfree(pcdev); exit_put_cisclk: clk_put(cis_sclk); exit_put_clk: clk_put(clk); exit: return err; }
static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) { struct sh_mobile_ceu_dev *pcdev; struct resource *res; void __iomem *base; unsigned int irq; int err = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!res || !irq) { dev_err(&pdev->dev, "Not enough CEU platform resources.\n"); err = -ENODEV; goto exit; } pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); if (!pcdev) { dev_err(&pdev->dev, "Could not allocate pcdev\n"); err = -ENOMEM; goto exit; } INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); pcdev->pdata = pdev->dev.platform_data; if (!pcdev->pdata) { err = -EINVAL; dev_err(&pdev->dev, "CEU platform data not set.\n"); goto exit_kfree; } base = ioremap_nocache(res->start, resource_size(res)); if (!base) { err = -ENXIO; dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); goto exit_kfree; } pcdev->irq = irq; pcdev->base = base; pcdev->video_limit = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (res) { err = dma_declare_coherent_memory(&pdev->dev, res->start, res->start, resource_size(res), DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); if (!err) { dev_err(&pdev->dev, "Unable to declare CEU memory.\n"); err = -ENXIO; goto exit_iounmap; } pcdev->video_limit = resource_size(res); } err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED, dev_name(&pdev->dev), pcdev); if (err) { dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); goto exit_release_mem; } pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); pcdev->ici.priv = pcdev; pcdev->ici.v4l2_dev.dev = &pdev->dev; pcdev->ici.nr = pdev->id; pcdev->ici.drv_name = dev_name(&pdev->dev); pcdev->ici.ops = &sh_mobile_ceu_host_ops; err = soc_camera_host_register(&pcdev->ici); if (err) goto exit_free_clk; return 0; exit_free_clk: pm_runtime_disable(&pdev->dev); free_irq(pcdev->irq, pcdev); exit_release_mem: if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) dma_release_declared_memory(&pdev->dev); exit_iounmap: iounmap(base); exit_kfree: kfree(pcdev); exit: return err; }