static int mx1_camera_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx1_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long common_flags; unsigned int csicr1; int ret; /* MX1 supports only 8bit buswidth */ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); if (!ret) { common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS); if (!common_flags) { dev_warn(icd->parent, "Flags incompatible: camera 0x%x, host 0x%x\n", cfg.flags, CSI_BUS_FLAGS); return -EINVAL; } } else if (ret != -ENOIOCTLCMD) { return ret; } else { common_flags = CSI_BUS_FLAGS; } /* Make choises, based on platform choice */ if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { if (!pcdev->pdata || pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH) common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; else common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; } if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { if (!pcdev->pdata || pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING) common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; else common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; } if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) && (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) { if (!pcdev->pdata || pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH) common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW; else common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH; } cfg.flags = common_flags; ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n", common_flags, ret); return ret; } csicr1 = __raw_readl(pcdev->base + CSICR1); if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW) csicr1 |= CSICR1_DATA_POL; __raw_writel(csicr1, pcdev->base + CSICR1); return 0; }
/* Maybe belong platform code fix me */ static int ak_camera_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct ak_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long common_flags; int ret; CAMDBG("entry %s\n", __func__); /* AK39 supports 8bit and 10bit buswidth */ ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); if (!ret) { common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS); if (!common_flags) { dev_warn(icd->parent, "Flags incompatible: camera 0x%x, host 0x%x\n", cfg.flags, CSI_BUS_FLAGS); return -EINVAL; } } else if (ret != -ENOIOCTLCMD) { return ret; } else { common_flags = CSI_BUS_FLAGS; } /* Make choises, based on platform choice */ if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { if (!pcdev->pdata || pcdev->pdata->flags & AK_CAMERA_VSYNC_HIGH) common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; else common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; } if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { if (!pcdev->pdata || pcdev->pdata->flags & AK_CAMERA_PCLK_RISING) common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; else common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; } if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) && (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) { if (!pcdev->pdata || pcdev->pdata->flags & AK_CAMERA_DATA_HIGH) common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW; else common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH; } cfg.flags = common_flags; ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n", common_flags, ret); return ret; } CAMDBG("leave %s\n", __func__); return 0; }
static int mx2_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long common_flags; int ret; int bytesperline; u32 csicr1 = pcdev->csicr1; ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); if (!ret) { common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS); if (!common_flags) { dev_warn(icd->parent, "Flags incompatible: camera 0x%x, host 0x%x\n", cfg.flags, MX2_BUS_FLAGS); return -EINVAL; } } else if (ret != -ENOIOCTLCMD) { return ret; } else { common_flags = MX2_BUS_FLAGS; } if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH) common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; else common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; } if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING) common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; else common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; } cfg.flags = common_flags; ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n", common_flags, ret); return ret; } if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_HSYNC_POL; if (pcdev->platform_flags & MX2_CAMERA_SWAP16) csicr1 |= CSICR1_SWAP16_EN; if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC) csicr1 |= CSICR1_EXT_VSYNC; if (pcdev->platform_flags & MX2_CAMERA_CCIR) csicr1 |= CSICR1_CCIR_EN; if (pcdev->platform_flags & MX2_CAMERA_CCIR_INTERLACE) csicr1 |= CSICR1_CCIR_MODE; if (pcdev->platform_flags & MX2_CAMERA_GATED_CLOCK) csicr1 |= CSICR1_GCLK_MODE; if (pcdev->platform_flags & MX2_CAMERA_INV_DATA) csicr1 |= CSICR1_INV_DATA; if (pcdev->platform_flags & MX2_CAMERA_PACK_DIR_MSB) csicr1 |= CSICR1_PACK_DIR; pcdev->csicr1 = csicr1; bytesperline = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); if (bytesperline < 0) return bytesperline; if (mx27_camera_emma(pcdev)) { ret = mx27_camera_emma_prp_reset(pcdev); if (ret) return ret; if (pcdev->discard_buffer) dma_free_coherent(ici->v4l2_dev.dev, pcdev->discard_size, pcdev->discard_buffer, pcdev->discard_buffer_dma); /* * I didn't manage to properly enable/disable the prp * on a per frame basis during running transfers, * thus we allocate a buffer here and use it to * discard frames when no buffer is available. * Feel free to work on this ;) */ pcdev->discard_size = icd->user_height * bytesperline; pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, pcdev->discard_size, &pcdev->discard_buffer_dma, GFP_KERNEL); if (!pcdev->discard_buffer) return -ENOMEM; mx27_camera_emma_buf_init(icd, bytesperline); } else if (cpu_is_mx25()) { writel((bytesperline * icd->user_height) >> 2, pcdev->base_csi + CSIRXCNT); writel((bytesperline << 16) | icd->user_height, pcdev->base_csi + CSIIMAG_PARA); } writel(pcdev->csicr1, pcdev->base_csi + CSICR1); return 0; }
static int omap1_cam_set_bus_param(struct soc_camera_device *icd) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct omap1_cam_dev *pcdev = ici->priv; u32 pixfmt = icd->current_fmt->host_fmt->fourcc; const struct soc_camera_format_xlate *xlate; const struct soc_mbus_pixelfmt *fmt; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long common_flags; u32 ctrlclock, mode; int ret; ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); if (!ret) { common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS); if (!common_flags) { dev_warn(dev, "Flags incompatible: camera 0x%x, host 0x%x\n", cfg.flags, SOCAM_BUS_FLAGS); return -EINVAL; } } else if (ret != -ENOIOCTLCMD) { return ret; } else { common_flags = SOCAM_BUS_FLAGS; } /* Make choices, possibly based on platform configuration */ if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { if (!pcdev->pdata || pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING) common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; else common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; } cfg.flags = common_flags; ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); if (ret < 0 && ret != -ENOIOCTLCMD) { dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n", common_flags, ret); return ret; } ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); if (ctrlclock & LCLK_EN) CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) { dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n"); ctrlclock |= POLCLK; } else { dev_dbg(dev, "CTRLCLOCK_REG &= ~POLCLK\n"); ctrlclock &= ~POLCLK; } CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); if (ctrlclock & LCLK_EN) CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock); /* select bus endianness */ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); fmt = xlate->host_fmt; mode = CAM_READ(pcdev, MODE) & ~(RAZ_FIFO | IRQ_MASK | DMA); if (fmt->order == SOC_MBUS_ORDER_LE) { dev_dbg(dev, "MODE_REG &= ~ORDERCAMD\n"); CAM_WRITE(pcdev, MODE, mode & ~ORDERCAMD); } else { dev_dbg(dev, "MODE_REG |= ORDERCAMD\n"); CAM_WRITE(pcdev, MODE, mode | ORDERCAMD); } return 0; }