switch (mbus_cfg->type) {
case V4L2_MBUS_PARALLEL:
csicfg->ext_vsync = 1;
- csicfg->vsync_pol = (mbus_cfg->flags &
+ csicfg->vsync_pol = (mbus_cfg->bus.parallel.flags &
V4L2_MBUS_VSYNC_ACTIVE_LOW) ? 1 : 0;
- csicfg->hsync_pol = (mbus_cfg->flags &
+ csicfg->hsync_pol = (mbus_cfg->bus.parallel.flags &
V4L2_MBUS_HSYNC_ACTIVE_LOW) ? 1 : 0;
- csicfg->pixclk_pol = (mbus_cfg->flags &
+ csicfg->pixclk_pol = (mbus_cfg->bus.parallel.flags &
V4L2_MBUS_PCLK_SAMPLE_FALLING) ? 1 : 0;
csicfg->clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
break;
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
cfg->type = V4L2_MBUS_CSI2_DPHY;
- cfg->flags = V4L2_MBUS_CSI2_1_LANE |
+ cfg->bus.mipi_csi2.num_data_lanes = 1;
+ cfg->bus.mipi_csi2.flags =
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
} else {
* The ADV7180 sensor supports BT.601/656 output modes.
* The BT.656 is default and not yet configurable by s/w.
*/
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+ V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
cfg->type = V4L2_MBUS_BT656;
}
return -EINVAL;
config->type = V4L2_MBUS_CSI2_DPHY;
- switch (tx->active_lanes) {
- case 1:
- config->flags = V4L2_MBUS_CSI2_1_LANE;
- break;
-
- case 2:
- config->flags = V4L2_MBUS_CSI2_2_LANE;
- break;
-
- case 3:
- config->flags = V4L2_MBUS_CSI2_3_LANE;
- break;
-
- case 4:
- config->flags = V4L2_MBUS_CSI2_4_LANE;
- break;
- }
+ config->bus.mipi_csi2.num_data_lanes = tx->active_lanes;
return 0;
}
unsigned int pad,
struct v4l2_mbus_config *cfg)
{
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
cfg->type = V4L2_MBUS_BT656;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+ V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
return 0;
}
struct v4l2_mbus_config *cfg)
{
/* MT9M001 has all capture_format parameters fixed */
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
cfg->type = V4L2_MBUS_PARALLEL;
+ cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+ V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_DATA_ACTIVE_HIGH |
+ V4L2_MBUS_MASTER;
return 0;
}
{
struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
- cfg->flags = V4L2_MBUS_MASTER |
- V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->type = V4L2_MBUS_PARALLEL;
- cfg->flags |= mt9m111->pclk_sample ? V4L2_MBUS_PCLK_SAMPLE_RISING :
- V4L2_MBUS_PCLK_SAMPLE_FALLING;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER |
+ V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
- cfg->type = V4L2_MBUS_PARALLEL;
+ cfg->bus.parallel.flags |= mt9m111->pclk_sample ?
+ V4L2_MBUS_PCLK_SAMPLE_RISING :
+ V4L2_MBUS_PCLK_SAMPLE_FALLING;
return 0;
}
if (ret)
return ret;
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH
- | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
- : V4L2_MBUS_VSYNC_ACTIVE_LOW)
- | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW
- : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
- | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
- : V4L2_MBUS_PCLK_SAMPLE_FALLING);
cfg->type = V4L2_MBUS_PARALLEL;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH
+ | ((comj & COMJ_VSYNC_HIGH) ? V4L2_MBUS_VSYNC_ACTIVE_HIGH
+ : V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ | ((comf & COMF_HREF_LOW) ? V4L2_MBUS_HSYNC_ACTIVE_LOW
+ : V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ | ((comj & COMJ_PCLK_RISING) ? V4L2_MBUS_PCLK_SAMPLE_RISING
+ : V4L2_MBUS_PCLK_SAMPLE_FALLING);
return 0;
}
unsigned int pad,
struct v4l2_mbus_config *cfg)
{
- cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
- V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
- V4L2_MBUS_DATA_ACTIVE_HIGH;
cfg->type = V4L2_MBUS_PARALLEL;
+ cfg->bus.parallel.flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+ V4L2_MBUS_MASTER |
+ V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+ V4L2_MBUS_DATA_ACTIVE_HIGH;
return 0;
}
cfg->type = V4L2_MBUS_CSI2_DPHY;
/* Support for non-continuous CSI-2 clock is missing in the driver */
- cfg->flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
-
- switch (state->csi_lanes_in_use) {
- case 1:
- cfg->flags |= V4L2_MBUS_CSI2_1_LANE;
- break;
- case 2:
- cfg->flags |= V4L2_MBUS_CSI2_2_LANE;
- break;
- case 3:
- cfg->flags |= V4L2_MBUS_CSI2_3_LANE;
- break;
- case 4:
- cfg->flags |= V4L2_MBUS_CSI2_4_LANE;
- break;
- default:
- return -EINVAL;
- }
+ cfg->bus.mipi_csi2.flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
+ cfg->bus.mipi_csi2.num_data_lanes = state->csi_lanes_in_use;
return 0;
}
struct tvp5150 *decoder = to_tvp5150(sd);
cfg->type = decoder->mbus_type;
- cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING
- | V4L2_MBUS_FIELD_EVEN_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH;
+ cfg->bus.parallel.flags = V4L2_MBUS_MASTER
+ | V4L2_MBUS_PCLK_SAMPLE_RISING
+ | V4L2_MBUS_FIELD_EVEN_LOW
+ | V4L2_MBUS_DATA_ACTIVE_HIGH;
return 0;
}
dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc);
- csi2dc->clk_gated = mbus_config.flags &
+ csi2dc->clk_gated = mbus_config.bus.parallel.flags &
V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
dev_dbg(csi2dc->dev, "mbus_config: %s clock\n",
* PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering
* roles should match.
*/
- if (cfg.flags != mbus_config) {
+ if (cfg.bus.parallel.flags != mbus_config) {
unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER |
V4L2_MBUS_SLAVE);
- if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER |
- V4L2_MBUS_SLAVE))) {
+ unsigned int flags = cfg.bus.parallel.flags;
+
+ if (pxa_mbus_role != (flags & (V4L2_MBUS_MASTER |
+ V4L2_MBUS_SLAVE))) {
dev_err(pcdev_to_dev(pcdev),
"Unsupported mbus configuration: bus mastering\n");
return -EINVAL;
}
- if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
+ if (flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
dev_err(pcdev_to_dev(pcdev),
"Unsupported mbus configuration: DATA_ACTIVE_LOW\n");
return -EINVAL;
}
}
- pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt);
+ pxa_camera_setup_cicr(pcdev, cfg.bus.parallel.flags, pixfmt);
return 0;
}
unsigned int *lanes)
{
struct v4l2_mbus_config mbus_config = { 0 };
- unsigned int num_lanes = UINT_MAX;
int ret;
*lanes = priv->lanes;
return -EINVAL;
}
- if (mbus_config.flags & V4L2_MBUS_CSI2_1_LANE)
- num_lanes = 1;
- else if (mbus_config.flags & V4L2_MBUS_CSI2_2_LANE)
- num_lanes = 2;
- else if (mbus_config.flags & V4L2_MBUS_CSI2_3_LANE)
- num_lanes = 3;
- else if (mbus_config.flags & V4L2_MBUS_CSI2_4_LANE)
- num_lanes = 4;
-
- if (num_lanes > priv->lanes) {
+ if (mbus_config.bus.mipi_csi2.num_data_lanes > priv->lanes) {
dev_err(priv->dev,
"Unsupported mbus config: too many data lanes %u\n",
- num_lanes);
+ mbus_config.bus.mipi_csi2.num_data_lanes);
return -EINVAL;
}
- *lanes = num_lanes;
+ *lanes = mbus_config.bus.mipi_csi2.num_data_lanes;
return 0;
}
/* compose mbus_config from the upstream endpoint */
mbus_cfg.type = priv->upstream_ep.bus_type;
- mbus_cfg.flags = is_parallel_bus(&priv->upstream_ep) ?
- priv->upstream_ep.bus.parallel.flags :
- priv->upstream_ep.bus.mipi_csi2.flags;
+ if (is_parallel_bus(&priv->upstream_ep))
+ mbus_cfg.bus.parallel = priv->upstream_ep.bus.parallel;
+ else
+ mbus_cfg.bus.mipi_csi2 = priv->upstream_ep.bus.mipi_csi2;
if_fmt = *infmt;
crop = priv->crop;
static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
{
struct v4l2_mbus_config mbus_config = { 0 };
- unsigned int num_lanes = UINT_MAX;
int ret;
*lanes = csi2->data_lanes;
return -EINVAL;
}
- switch (mbus_config.flags & V4L2_MBUS_CSI2_LANES) {
- case V4L2_MBUS_CSI2_1_LANE:
- num_lanes = 1;
- break;
- case V4L2_MBUS_CSI2_2_LANE:
- num_lanes = 2;
- break;
- case V4L2_MBUS_CSI2_3_LANE:
- num_lanes = 3;
- break;
- case V4L2_MBUS_CSI2_4_LANE:
- num_lanes = 4;
- break;
- default:
- num_lanes = csi2->data_lanes;
- break;
- }
-
- if (num_lanes > csi2->data_lanes) {
+ if (mbus_config.bus.mipi_csi2.num_data_lanes > csi2->data_lanes) {
dev_err(csi2->dev,
"Unsupported mbus config: too many data lanes %u\n",
- num_lanes);
+ mbus_config.bus.mipi_csi2.num_data_lanes);
return -EINVAL;
}
- *lanes = num_lanes;
+ *lanes = mbus_config.bus.mipi_csi2.num_data_lanes;
return 0;
}
/**
* struct v4l2_mbus_config - media bus configuration
- * @type: in: interface type
- * @flags: in / out: configuration flags, depending on @type
+ * @type: interface type
+ * @bus: bus configuration data structure
+ * @bus.parallel: embedded &struct v4l2_mbus_config_parallel.
+ * Used if the bus is parallel or BT.656.
+ * @bus.mipi_csi1: embedded &struct v4l2_mbus_config_mipi_csi1.
+ * Used if the bus is MIPI Alliance's Camera Serial
+ * Interface version 1 (MIPI CSI1) or Standard
+ * Mobile Imaging Architecture's Compact Camera Port 2
+ * (SMIA CCP2).
+ * @bus.mipi_csi2: embedded &struct v4l2_mbus_config_mipi_csi2.
+ * Used if the bus is MIPI Alliance's Camera Serial
+ * Interface version 2 (MIPI CSI2).
*/
struct v4l2_mbus_config {
enum v4l2_mbus_type type;
- unsigned int flags;
+ union {
+ struct v4l2_mbus_config_parallel parallel;
+ struct v4l2_mbus_config_mipi_csi1 mipi_csi1;
+ struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+ } bus;
};
/**