mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
media: v4l: async: Obtain async connection based on sub-device
Add v4l2_async_connection_unique() function for obtaining a struct v4l2_async_connection, typically allocated by drivers together with their own information on an external sub-device. The relation between connections and sub-devices still remains 1:1 but this code becomes more complex when the relation soon changes. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Tested-by: Philipp Zabel <p.zabel@pengutronix.de> # imx6qp Tested-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> # rcar + adv746x Tested-by: Aishwarya Kothari <aishwarya.kothari@toradex.com> # Apalis i.MX6Q with TC358743 Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> # Renesas RZ/G2L SMARC Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
parent
9bf19fbf0c
commit
c91fd7b7a8
@ -381,6 +381,7 @@ static int rkisp1_csi_s_stream(struct v4l2_subdev *sd, int enable)
|
|||||||
struct rkisp1_csi *csi = to_rkisp1_csi(sd);
|
struct rkisp1_csi *csi = to_rkisp1_csi(sd);
|
||||||
struct rkisp1_device *rkisp1 = csi->rkisp1;
|
struct rkisp1_device *rkisp1 = csi->rkisp1;
|
||||||
struct rkisp1_sensor_async *source_asd;
|
struct rkisp1_sensor_async *source_asd;
|
||||||
|
struct v4l2_async_connection *asc;
|
||||||
struct media_pad *source_pad;
|
struct media_pad *source_pad;
|
||||||
struct v4l2_subdev *source;
|
struct v4l2_subdev *source;
|
||||||
int ret;
|
int ret;
|
||||||
@ -406,7 +407,11 @@ static int rkisp1_csi_s_stream(struct v4l2_subdev *sd, int enable)
|
|||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
source_asd = container_of(source->asd, struct rkisp1_sensor_async, asd);
|
asc = v4l2_async_connection_unique(source);
|
||||||
|
if (!asc)
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
|
source_asd = container_of(asc, struct rkisp1_sensor_async, asd);
|
||||||
if (source_asd->mbus_type != V4L2_MBUS_CSI2_DPHY)
|
if (source_asd->mbus_type != V4L2_MBUS_CSI2_DPHY)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -868,9 +868,13 @@ static int rkisp1_isp_s_stream(struct v4l2_subdev *sd, int enable)
|
|||||||
mbus_flags = 0;
|
mbus_flags = 0;
|
||||||
} else {
|
} else {
|
||||||
const struct rkisp1_sensor_async *asd;
|
const struct rkisp1_sensor_async *asd;
|
||||||
|
struct v4l2_async_connection *asc;
|
||||||
|
|
||||||
asd = container_of(rkisp1->source->asd,
|
asc = v4l2_async_connection_unique(rkisp1->source);
|
||||||
struct rkisp1_sensor_async, asd);
|
if (!asc)
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
|
asd = container_of(asc, struct rkisp1_sensor_async, asd);
|
||||||
|
|
||||||
mbus_type = asd->mbus_type;
|
mbus_type = asd->mbus_type;
|
||||||
mbus_flags = asd->mbus_flags;
|
mbus_flags = asd->mbus_flags;
|
||||||
|
@ -224,8 +224,17 @@ struct isp_async_subdev {
|
|||||||
struct isp_bus_cfg bus;
|
struct isp_bus_cfg bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define v4l2_subdev_to_bus_cfg(sd) \
|
static inline struct isp_bus_cfg *
|
||||||
(&container_of((sd)->asd, struct isp_async_subdev, asd)->bus)
|
v4l2_subdev_to_bus_cfg(struct v4l2_subdev *sd)
|
||||||
|
{
|
||||||
|
struct v4l2_async_connection *asc;
|
||||||
|
|
||||||
|
asc = v4l2_async_connection_unique(sd);
|
||||||
|
if (!asc)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &container_of(asc, struct isp_async_subdev, asd)->bus;
|
||||||
|
}
|
||||||
|
|
||||||
#define v4l2_dev_to_isp_device(dev) \
|
#define v4l2_dev_to_isp_device(dev) \
|
||||||
container_of(dev, struct isp_device, v4l2_dev)
|
container_of(dev, struct isp_device, v4l2_dev)
|
||||||
|
@ -1140,8 +1140,13 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
|
|||||||
if (ccdc->input == CCDC_INPUT_PARALLEL) {
|
if (ccdc->input == CCDC_INPUT_PARALLEL) {
|
||||||
struct v4l2_subdev *sd =
|
struct v4l2_subdev *sd =
|
||||||
to_isp_pipeline(&ccdc->subdev.entity)->external;
|
to_isp_pipeline(&ccdc->subdev.entity)->external;
|
||||||
|
struct isp_bus_cfg *bus_cfg;
|
||||||
|
|
||||||
parcfg = &v4l2_subdev_to_bus_cfg(sd)->bus.parallel;
|
bus_cfg = v4l2_subdev_to_bus_cfg(sd);
|
||||||
|
if (WARN_ON(!bus_cfg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
parcfg = &bus_cfg->bus.parallel;
|
||||||
ccdc->bt656 = parcfg->bt656;
|
ccdc->bt656 = parcfg->bt656;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2436,7 +2441,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
|
|||||||
if (ccdc->input == CCDC_INPUT_PARALLEL) {
|
if (ccdc->input == CCDC_INPUT_PARALLEL) {
|
||||||
struct v4l2_subdev *sd =
|
struct v4l2_subdev *sd =
|
||||||
media_entity_to_v4l2_subdev(link->source->entity);
|
media_entity_to_v4l2_subdev(link->source->entity);
|
||||||
struct isp_bus_cfg *bus_cfg = v4l2_subdev_to_bus_cfg(sd);
|
struct isp_bus_cfg *bus_cfg;
|
||||||
|
|
||||||
|
bus_cfg = v4l2_subdev_to_bus_cfg(sd);
|
||||||
|
if (WARN_ON(!bus_cfg))
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
parallel_shift = bus_cfg->bus.parallel.data_lane_shift;
|
parallel_shift = bus_cfg->bus.parallel.data_lane_shift;
|
||||||
} else {
|
} else {
|
||||||
|
@ -360,6 +360,8 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
|
|||||||
pad = media_pad_remote_pad_first(&ccp2->pads[CCP2_PAD_SINK]);
|
pad = media_pad_remote_pad_first(&ccp2->pads[CCP2_PAD_SINK]);
|
||||||
sensor = media_entity_to_v4l2_subdev(pad->entity);
|
sensor = media_entity_to_v4l2_subdev(pad->entity);
|
||||||
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
||||||
|
if (WARN_ON(!buscfg))
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);
|
ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -564,6 +564,8 @@ static int csi2_configure(struct isp_csi2_device *csi2)
|
|||||||
pad = media_pad_remote_pad_first(&csi2->pads[CSI2_PAD_SINK]);
|
pad = media_pad_remote_pad_first(&csi2->pads[CSI2_PAD_SINK]);
|
||||||
sensor = media_entity_to_v4l2_subdev(pad->entity);
|
sensor = media_entity_to_v4l2_subdev(pad->entity);
|
||||||
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
||||||
|
if (WARN_ON(!buscfg))
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
csi2->frame_skip = 0;
|
csi2->frame_skip = 0;
|
||||||
v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
|
v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
|
||||||
|
@ -163,13 +163,17 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
|
|||||||
static int omap3isp_csiphy_config(struct isp_csiphy *phy)
|
static int omap3isp_csiphy_config(struct isp_csiphy *phy)
|
||||||
{
|
{
|
||||||
struct isp_pipeline *pipe = to_isp_pipeline(phy->entity);
|
struct isp_pipeline *pipe = to_isp_pipeline(phy->entity);
|
||||||
struct isp_bus_cfg *buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
struct isp_bus_cfg *buscfg;
|
||||||
struct isp_csiphy_lanes_cfg *lanes;
|
struct isp_csiphy_lanes_cfg *lanes;
|
||||||
int csi2_ddrclk_khz;
|
int csi2_ddrclk_khz;
|
||||||
unsigned int num_data_lanes, used_lanes = 0;
|
unsigned int num_data_lanes, used_lanes = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
||||||
|
if (WARN_ON(!buscfg))
|
||||||
|
return -EPIPE;
|
||||||
|
|
||||||
if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
|
if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
|
||||||
|| buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) {
|
|| buscfg->interface == ISP_INTERFACE_CCP2B_PHY2) {
|
||||||
lanes = &buscfg->bus.ccp2.lanecfg;
|
lanes = &buscfg->bus.ccp2.lanecfg;
|
||||||
@ -306,8 +310,13 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy)
|
|||||||
mutex_lock(&phy->mutex);
|
mutex_lock(&phy->mutex);
|
||||||
if (phy->entity) {
|
if (phy->entity) {
|
||||||
struct isp_pipeline *pipe = to_isp_pipeline(phy->entity);
|
struct isp_pipeline *pipe = to_isp_pipeline(phy->entity);
|
||||||
struct isp_bus_cfg *buscfg =
|
struct isp_bus_cfg *buscfg;
|
||||||
v4l2_subdev_to_bus_cfg(pipe->external);
|
|
||||||
|
buscfg = v4l2_subdev_to_bus_cfg(pipe->external);
|
||||||
|
if (WARN_ON(!buscfg)) {
|
||||||
|
mutex_unlock(&phy->mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
csiphy_routing_cfg(phy, buscfg->interface, false,
|
csiphy_routing_cfg(phy, buscfg->interface, false,
|
||||||
buscfg->bus.ccp2.phy_layer);
|
buscfg->bus.ccp2.phy_layer);
|
||||||
|
@ -751,6 +751,13 @@ __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier, int adapter_id,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c);
|
EXPORT_SYMBOL_GPL(__v4l2_async_nf_add_i2c);
|
||||||
|
|
||||||
|
struct v4l2_async_connection *
|
||||||
|
v4l2_async_connection_unique(struct v4l2_subdev *sd)
|
||||||
|
{
|
||||||
|
return sd->asd;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(v4l2_async_connection_unique);
|
||||||
|
|
||||||
int v4l2_async_register_subdev(struct v4l2_subdev *sd)
|
int v4l2_async_register_subdev(struct v4l2_subdev *sd)
|
||||||
{
|
{
|
||||||
struct v4l2_async_notifier *subdev_notifier;
|
struct v4l2_async_notifier *subdev_notifier;
|
||||||
|
@ -210,6 +210,17 @@ __v4l2_async_nf_add_i2c(struct v4l2_async_notifier *notifier,
|
|||||||
((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \
|
((type *)__v4l2_async_nf_add_i2c(notifier, adapter, address, \
|
||||||
sizeof(type)))
|
sizeof(type)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* v4l2_async_connection_unique - return a unique &struct v4l2_async_connection
|
||||||
|
* for a sub-device
|
||||||
|
* @sd: the sub-device
|
||||||
|
*
|
||||||
|
* Return an async connection for a sub-device, when there is a single
|
||||||
|
* one only.
|
||||||
|
*/
|
||||||
|
struct v4l2_async_connection *
|
||||||
|
v4l2_async_connection_unique(struct v4l2_subdev *sd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v4l2_async_nf_register - registers a subdevice asynchronous notifier
|
* v4l2_async_nf_register - registers a subdevice asynchronous notifier
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user