struct list_head video_buffer_list;
struct frame_buffer *active;
- struct soc_camera_device *icd;
struct soc_camera_host soc_host;
};
/* Check if already in a frame */
if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
- dev_err(isi->icd->parent, "Already in frame handling.\n");
+ dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
return;
}
struct atmel_isi *isi = ici->priv;
int ret;
- if (isi->icd)
- return -EBUSY;
-
ret = clk_enable(isi->pclk);
if (ret)
return ret;
return ret;
}
- isi->icd = icd;
dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
icd->devnum);
return 0;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
- BUG_ON(icd != isi->icd);
-
clk_disable(isi->mck);
clk_disable(isi->pclk);
- isi->icd = NULL;
dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
icd->devnum);
*/
struct mx1_camera_dev {
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct mx1_camera_pdata *pdata;
struct mx1_buffer *active;
struct resource *res;
static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
{
struct videobuf_buffer *vbuf = &pcdev->active->vb;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
int ret;
if (unlikely(!pcdev->active)) {
static void mx1_camera_dma_irq(int channel, void *data)
{
struct mx1_camera_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
struct mx1_buffer *buf;
struct videobuf_buffer *vb;
unsigned long flags;
*/
div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
- dev_dbg(pcdev->icd->parent,
+ dev_dbg(pcdev->soc_host.icd->parent,
"System clock %lukHz, target freq %dkHz, divisor %lu\n",
lcdclk / 1000, mclk / 1000, div);
{
unsigned int csicr1 = CSICR1_EN;
- dev_dbg(pcdev->icd->parent, "Activate device\n");
+ dev_dbg(pcdev->soc_host.icd->parent, "Activate device\n");
clk_prepare_enable(pcdev->clk);
static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
{
- dev_dbg(pcdev->icd->parent, "Deactivate device\n");
+ dev_dbg(pcdev->soc_host.icd->parent, "Deactivate device\n");
/* Disable all CSI interface */
__raw_writel(0x00, pcdev->base + CSICR1);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx1_camera_dev *pcdev = ici->priv;
- if (pcdev->icd)
- return -EBUSY;
-
dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
icd->devnum);
mx1_camera_activate(pcdev);
- pcdev->icd = icd;
-
return 0;
}
struct mx1_camera_dev *pcdev = ici->priv;
unsigned int csicr1;
- BUG_ON(icd != pcdev->icd);
-
/* disable interrupts */
csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
__raw_writel(csicr1, pcdev->base + CSICR1);
icd->devnum);
mx1_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
struct mx2_camera_dev {
struct device *dev;
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct clk *clk_emma_ahb, *clk_emma_ipg;
struct clk *clk_csi_ahb, *clk_csi_per;
writel(phys, pcdev->base_emma +
PRP_DEST_Y_PTR - 0x14 * bufnum);
if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
- u32 imgsize = pcdev->icd->user_height *
- pcdev->icd->user_width;
+ u32 imgsize = pcdev->soc_host.icd->user_height *
+ pcdev->soc_host.icd->user_width;
writel(phys + imgsize, pcdev->base_emma +
PRP_DEST_CB_PTR - 0x14 * bufnum);
int ret;
u32 csicr1;
- if (pcdev->icd)
- return -EBUSY;
-
ret = clk_prepare_enable(pcdev->clk_csi_ahb);
if (ret < 0)
return ret;
pcdev->csicr1 = csicr1;
writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
- pcdev->icd = icd;
pcdev->frame_count = 0;
dev_info(icd->parent, "Camera driver attached to camera %d\n",
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
- BUG_ON(icd != pcdev->icd);
-
dev_info(icd->parent, "Camera driver detached from camera %d\n",
icd->devnum);
mx2_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
/*
* Interface. If anyone ever builds hardware to enable more than one
* camera _simultaneously_, they will have to modify this driver too
*/
- struct soc_camera_device *icd;
struct clk *clk;
void __iomem *base;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx3_camera_dev *mx3_cam = ici->priv;
- if (mx3_cam->icd)
- return -EBUSY;
-
mx3_camera_activate(mx3_cam, icd);
mx3_cam->buf_total = 0;
- mx3_cam->icd = icd;
dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
icd->devnum);
struct mx3_camera_dev *mx3_cam = ici->priv;
struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
- BUG_ON(icd != mx3_cam->icd);
-
if (*ichan) {
dma_release_channel(&(*ichan)->dma_chan);
*ichan = NULL;
clk_disable_unprepare(mx3_cam->clk);
- mx3_cam->icd = NULL;
-
dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
icd->devnum);
}
struct omap1_cam_dev {
struct soc_camera_host soc_host;
- struct soc_camera_device *icd;
struct clk *clk;
unsigned int irq;
{
struct omap1_cam_buf *buf = pcdev->active;
struct videobuf_buffer *vb;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
if (WARN_ON(!buf)) {
suspend_capture(pcdev);
static irqreturn_t cam_isr(int irq, void *data)
{
struct omap1_cam_dev *pcdev = data;
- struct device *dev = pcdev->icd->parent;
+ struct device *dev = pcdev->soc_host.icd->parent;
struct omap1_cam_buf *buf = pcdev->active;
u32 it_status;
unsigned long flags;
struct omap1_cam_dev *pcdev = ici->priv;
u32 ctrlclock;
- if (pcdev->icd)
- return -EBUSY;
-
clk_enable(pcdev->clk);
/* setup sensor clock */
sensor_reset(pcdev, false);
- pcdev->icd = icd;
-
dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
icd->devnum);
return 0;
struct omap1_cam_dev *pcdev = ici->priv;
u32 ctrlclock;
- BUG_ON(icd != pcdev->icd);
-
suspend_capture(pcdev);
disable_capture(pcdev);
clk_disable(pcdev->clk);
- pcdev->icd = NULL;
-
dev_dbg(icd->parent,
"OMAP1 Camera driver detached from camera %d\n", icd->devnum);
}
* interface. If anyone ever builds hardware to enable more than
* one camera, they will have to modify this driver too
*/
- struct soc_camera_device *icd;
struct clk *clk;
unsigned int irq;
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct pxa_camera_dev *pcdev = ici->priv;
- if (pcdev->icd)
- return -EBUSY;
-
pxa_camera_activate(pcdev);
- pcdev->icd = icd;
-
dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
icd->devnum);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct pxa_camera_dev *pcdev = ici->priv;
- BUG_ON(icd != pcdev->icd);
-
dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
icd->devnum);
DCSR(pcdev->dma_chans[2]) = 0;
pxa_camera_deactivate(pcdev);
-
- pcdev->icd = NULL;
}
static int test_platform_param(struct pxa_camera_dev *pcdev,
pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+ if (pcdev->soc_host.icd) {
+ struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
ret = v4l2_subdev_call(sd, core, s_power, 0);
if (ret == -ENOIOCTLCMD)
ret = 0;
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
- if (pcdev->icd) {
- struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+ if (pcdev->soc_host.icd) {
+ struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
ret = v4l2_subdev_call(sd, core, s_power, 1);
if (ret == -ENOIOCTLCMD)
ret = 0;
struct sh_mobile_ceu_dev {
struct soc_camera_host ici;
- struct soc_camera_device *icd;
struct platform_device *csi2_pdev;
unsigned int irq;
static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
{
int i, success = 0;
- struct soc_camera_device *icd = pcdev->icd;
+ struct soc_camera_device *icd = pcdev->ici.icd;
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
*/
static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
{
- struct soc_camera_device *icd = pcdev->icd;
+ struct soc_camera_device *icd = pcdev->ici.icd;
dma_addr_t phys_addr_top, phys_addr_bottom;
unsigned long top1, top2;
unsigned long bottom1, bottom2;
struct v4l2_subdev *csi2_sd;
int ret;
- if (pcdev->icd)
- return -EBUSY;
-
dev_info(icd->parent,
"SuperH Mobile CEU driver attached to camera %d\n",
icd->devnum);
*/
if (ret == -ENODEV && csi2_sd)
csi2_sd->grp_id = 0;
- pcdev->icd = icd;
return 0;
}
struct sh_mobile_ceu_dev *pcdev = ici->priv;
struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
- BUG_ON(icd != pcdev->icd);
-
v4l2_subdev_call(csi2_sd, core, s_power, 0);
if (csi2_sd)
csi2_sd->grp_id = 0;
dev_info(icd->parent,
"SuperH Mobile CEU driver detached from camera %d\n",
icd->devnum);
-
- pcdev->icd = NULL;
}
/*
return ici->ops->set_bus_param(icd);
}
+static int soc_camera_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+ int ret;
+
+ if (ici->icd)
+ return -EBUSY;
+
+ ret = ici->ops->add(icd);
+ if (!ret)
+ ici->icd = icd;
+
+ return ret;
+}
+
+static void soc_camera_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+ if (WARN_ON(icd != ici->icd))
+ return;
+
+ ici->ops->remove(icd);
+ ici->icd = NULL;
+}
+
static int soc_camera_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
if (sdesc->subdev_desc.reset)
sdesc->subdev_desc.reset(icd->pdev);
- ret = ici->ops->add(icd);
+ ret = soc_camera_add_device(icd);
if (ret < 0) {
dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
goto eiciadd;
eresume:
__soc_camera_power_off(icd);
epower:
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
eiciadd:
icd->use_count--;
mutex_unlock(&ici->host_lock);
vb2_queue_release(&icd->vb2_vidq);
__soc_camera_power_off(icd);
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
}
if (icd->streamer == file)
ssdd->reset(icd->pdev);
mutex_lock(&ici->host_lock);
- ret = ici->ops->add(icd);
+ ret = soc_camera_add_device(icd);
mutex_unlock(&ici->host_lock);
if (ret < 0)
goto eadd;
icd->field = mf.field;
}
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
mutex_unlock(&ici->host_lock);
icd->vdev = NULL;
evdc:
mutex_lock(&ici->host_lock);
- ici->ops->remove(icd);
+ soc_camera_remove_device(icd);
mutex_unlock(&ici->host_lock);
eadd:
v4l2_ctrl_handler_free(&icd->ctrl_handler);
struct mutex host_lock; /* Protect pipeline modifications */
unsigned char nr; /* Host number */
u32 capabilities;
+ struct soc_camera_device *icd; /* Currently attached client */
void *priv;
const char *drv_name;
struct soc_camera_host_ops *ops;