Hi Sakari On Mon, Apr 29, 2024 at 10:08:49PM +0300, Sakari Ailus wrote: > v4l2_get_link_freq() accepts a V4L2 control handler for now, but it needs > to take struct v4l2_subdev argument in order to obtain the link frequency > using get_mbus_config() pad op. Prepare for this by allowing struct > v4l2_subdev as well. > > Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> Nice! I need exactly something like this to avoid pre-computing a lot a frequencies in a driver I'm working on. > --- > drivers/media/v4l2-core/v4l2-common.c | 19 ++++++++++++++++--- > include/media/v4l2-common.h | 14 +++++++++++--- > 2 files changed, 27 insertions(+), 6 deletions(-) > > diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c > index 4165c815faef..7f69b5a025fa 100644 > --- a/drivers/media/v4l2-core/v4l2-common.c > +++ b/drivers/media/v4l2-core/v4l2-common.c > @@ -464,8 +464,8 @@ int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, > } > EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); > > -s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, > - unsigned int div) > +s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, > + unsigned int mul, unsigned int div) > { > struct v4l2_ctrl *ctrl; > s64 freq; > @@ -500,7 +500,20 @@ s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, > > return freq > 0 ? freq : -EINVAL; > } > -EXPORT_SYMBOL_GPL(v4l2_get_link_freq); > +EXPORT_SYMBOL_GPL(__v4l2_get_link_freq_ctrl); > + > +s64 __v4l2_get_link_freq_pad(struct media_pad *pad, unsigned int mul, > + unsigned int div) > +{ > + struct v4l2_subdev *sd; > + > + sd = media_entity_to_v4l2_subdev(pad->entity); > + if (!sd) > + return -ENODEV; > + > + return __v4l2_get_link_freq_ctrl(sd->ctrl_handler, mul, div); > +} > +EXPORT_SYMBOL_GPL(__v4l2_get_link_freq_pad); > > /* > * Simplify a fraction using a simple continued fraction decomposition. The > diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h > index 63ad36f04f72..d7115cd61a38 100644 > --- a/include/media/v4l2-common.h > +++ b/include/media/v4l2-common.h > @@ -525,7 +525,8 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, > /** > * v4l2_get_link_freq - Get link rate from transmitter > * > - * @handler: The transmitter's control handler > + * @pad: The transmitter's media pad (or control handler for compatibility > + * reasons, don't use in new code) > * @mul: The multiplier between pixel rate and link frequency. Bits per pixel on > * D-PHY, samples per clock on parallel. 0 otherwise. > * @div: The divisor between pixel rate and link frequency. Number of data lanes > @@ -541,8 +542,15 @@ int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, u32 pixelformat, > * * %-ENOENT: Link frequency or pixel rate control not found > * * %-EINVAL: Invalid link frequency value > */ > -s64 v4l2_get_link_freq(struct v4l2_ctrl_handler *handler, unsigned int mul, > - unsigned int div); > +#define v4l2_get_link_freq(pad, mul, div) \ > + _Generic(pad, \ > + struct media_pad *: __v4l2_get_link_freq_pad, \ > + struct v4l2_ctrl_handler *: __v4l2_get_link_freq_ctrl) \ > + (pad, mul, div) That's nice and elegant, but given that I count 10 drivers in mainline using this function, wouldn't it be better to make them use a pad and remove the ctrl_handler version completely to avoid it being used in future ? > +s64 __v4l2_get_link_freq_pad(struct media_pad *pad, unsigned int mul, > + unsigned int div); > +s64 __v4l2_get_link_freq_ctrl(struct v4l2_ctrl_handler *handler, > + unsigned int mul, unsigned int div); > > void v4l2_simplify_fraction(u32 *numerator, u32 *denominator, > unsigned int n_terms, unsigned int threshold); > -- > 2.39.2 > >