@@ -1214,6 +1214,9 @@ static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
.s_ctrl = tvp5150_s_ctrl,
};
+static int tvp5150_mc_probe(struct v4l2_subdev *sd);
+
+
static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
.log_status = tvp5150_log_status,
.reset = tvp5150_reset,
@@ -1221,6 +1224,9 @@ static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
.g_register = tvp5150_g_register,
.s_register = tvp5150_s_register,
#endif
+#ifdef CONFIG_MEDIA_CONTROLLER
+ .mc_probe = tvp5150_mc_probe,
+#endif
.registered_async = tvp5150_registered_async,
};
@@ -1438,11 +1444,33 @@ static const char * const tvp5150_test_patterns[2] = {
"Black screen"
};
-static int tvp5150_probe(struct i2c_client *c,
- const struct i2c_device_id *id)
+static int __maybe_unused tvp5150_mc_probe(struct v4l2_subdev *sd)
+{
+ struct tvp5150 *core = to_tvp5150(sd);
+ int res;
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+ core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+ core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+
+ sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
+
+ res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
+ if (res < 0)
+ return res;
+
+ sd->entity.ops = &tvp5150_sd_media_ops;
+#endif
+ return 0;
+}
+
+static int __tvp5150_probe(struct i2c_client *c,
+ const struct i2c_device_id *id,
+ struct v4l2_subdev **sd_store)
{
struct tvp5150 *core;
- struct v4l2_subdev *sd;
+ struct v4l2_subdev *sd; /* FIXME: get rid of it */
struct device_node *np = c->dev.of_node;
int res;
@@ -1460,6 +1488,7 @@ static int tvp5150_probe(struct i2c_client *c,
return -ENOMEM;
sd = &core->sd;
+ *sd_store = sd;
if (IS_ENABLED(CONFIG_OF) && np) {
res = tvp5150_parse_dt(core, np);
@@ -1475,20 +1504,6 @@ static int tvp5150_probe(struct i2c_client *c,
v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-#if defined(CONFIG_MEDIA_CONTROLLER)
- core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
- core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
- core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
-
- sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
-
- res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
- if (res < 0)
- return res;
-
- sd->entity.ops = &tvp5150_sd_media_ops;
-#endif
-
res = tvp5150_detect_version(core);
if (res < 0)
return res;
@@ -1542,6 +1557,8 @@ err:
return res;
}
+DECLARE_SUBDEV_PROBE(tvp5150_probe, __tvp5150_probe);
+
static int tvp5150_remove(struct i2c_client *c)
{
struct v4l2_subdev *sd = i2c_get_clientdata(c);
@@ -183,6 +183,8 @@ struct v4l2_subdev_io_pin_config {
* @registered_async: the subdevice has been registered async.
*/
struct v4l2_subdev_core_ops {
+ int (*mc_probe)(struct v4l2_subdev *sd);
+
int (*log_status)(struct v4l2_subdev *sd);
int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
struct v4l2_subdev_io_pin_config *pincfg);
@@ -795,6 +797,23 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
return sd->host_priv;
}
+
+/* FIXME: need an #if defined(MEDIA_CONTROLLER) */
+#define DECLARE_SUBDEV_PROBE(name, probe_fn) \
+static int __subdev_probe(struct i2c_client *c, \
+ const struct i2c_device_id *id) \
+{ \
+ int __rc; \
+ struct v4l2_subdev *__sd; \
+ \
+ __rc = probe_fn(c, id, &__sd); \
+ \
+ if (!__rc && __sd->v4l2_dev->mdev && __sd->ops->core.mc_probe) \
+ __rc = __sd->ops->core.mc_probe(__sd); \
+ \
+ return __rc; \
+}
+
#ifdef CONFIG_MEDIA_CONTROLLER
int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
struct media_link *link,