diff options
author | Yunke Cao <yunkec@google.com> | 2022-06-28 01:53:52 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-07-15 14:40:09 +0100 |
commit | d534b9520a128d20d81d6dcf95441e806bdeb20f (patch) | |
tree | 19320bbdc445f9033cec0fd154276cb9daccfeb0 /drivers/media/test-drivers/vimc/vimc-core.c | |
parent | 46347e3ec61660562d4a4a933713e2c2b74598e2 (diff) | |
download | linux-d534b9520a128d20d81d6dcf95441e806bdeb20f.tar.gz linux-d534b9520a128d20d81d6dcf95441e806bdeb20f.tar.bz2 linux-d534b9520a128d20d81d6dcf95441e806bdeb20f.zip |
media: vimc: add ancillary lens
Add lens to vimc driver and link them with sensors using ancillary links.
Provides an example of ancillary link usage.The lens supports
FOCUS_ABSOLUTE control.
Test example: With default vimc topology
> media-ctl -p
Media controller API version 5.18.0
...
- entity 28: Lens A (0 pad, 0 link)
type V4L2 subdev subtype Lens flags 0
device node name /dev/v4l-subdev6
- entity 29: Lens B (0 pad, 0 link)
type V4L2 subdev subtype Lens flags 0
device node name /dev/v4l-subdev7
> v4l2-ctl -d /dev/v4l-subdev7 -C focus_absolute
focus_absolute: 0
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Yunke Cao <yunkec@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/test-drivers/vimc/vimc-core.c')
-rw-r--r-- | drivers/media/test-drivers/vimc/vimc-core.c | 86 |
1 files changed, 66 insertions, 20 deletions
diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c index 06edf9d4d92c..166323406c6b 100644 --- a/drivers/media/test-drivers/vimc/vimc-core.c +++ b/drivers/media/test-drivers/vimc/vimc-core.c @@ -24,7 +24,7 @@ MODULE_PARM_DESC(allocator, " memory allocator selection, default is 0.\n" #define VIMC_MDEV_MODEL_NAME "VIMC MDEV" -#define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) { \ +#define VIMC_DATA_LINK(src, srcpad, sink, sinkpad, link_flags) { \ .src_ent = src, \ .src_pad = srcpad, \ .sink_ent = sink, \ @@ -32,8 +32,13 @@ MODULE_PARM_DESC(allocator, " memory allocator selection, default is 0.\n" .flags = link_flags, \ } -/* Structure which describes links between entities */ -struct vimc_ent_link { +#define VIMC_ANCILLARY_LINK(primary, ancillary) { \ + .primary_ent = primary, \ + .ancillary_ent = ancillary \ +} + +/* Structure which describes data links between entities */ +struct vimc_data_link { unsigned int src_ent; u16 src_pad; unsigned int sink_ent; @@ -41,12 +46,20 @@ struct vimc_ent_link { u32 flags; }; +/* Structure which describes ancillary links between entities */ +struct vimc_ancillary_link { + unsigned int primary_ent; + unsigned int ancillary_ent; +}; + /* Structure which describes the whole topology */ struct vimc_pipeline_config { const struct vimc_ent_config *ents; size_t num_ents; - const struct vimc_ent_link *links; - size_t num_links; + const struct vimc_data_link *data_links; + size_t num_data_links; + const struct vimc_ancillary_link *ancillary_links; + size_t num_ancillary_links; }; /* -------------------------------------------------------------------------- @@ -91,32 +104,49 @@ static struct vimc_ent_config ent_config[] = { .name = "RGB/YUV Capture", .type = &vimc_cap_type }, + { + .name = "Lens A", + .type = &vimc_len_type + }, + { + .name = "Lens B", + .type = &vimc_len_type + }, }; -static const struct vimc_ent_link ent_links[] = { +static const struct vimc_data_link data_links[] = { /* Link: Sensor A (Pad 0)->(Pad 0) Debayer A */ - VIMC_ENT_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), + VIMC_DATA_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), /* Link: Sensor A (Pad 0)->(Pad 0) Raw Capture 0 */ - VIMC_ENT_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), + VIMC_DATA_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), /* Link: Sensor B (Pad 0)->(Pad 0) Debayer B */ - VIMC_ENT_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), + VIMC_DATA_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), /* Link: Sensor B (Pad 0)->(Pad 0) Raw Capture 1 */ - VIMC_ENT_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), + VIMC_DATA_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), /* Link: Debayer A (Pad 1)->(Pad 0) Scaler */ - VIMC_ENT_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED), + VIMC_DATA_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED), /* Link: Debayer B (Pad 1)->(Pad 0) Scaler */ - VIMC_ENT_LINK(3, 1, 7, 0, 0), + VIMC_DATA_LINK(3, 1, 7, 0, 0), /* Link: RGB/YUV Input (Pad 0)->(Pad 0) Scaler */ - VIMC_ENT_LINK(6, 0, 7, 0, 0), + VIMC_DATA_LINK(6, 0, 7, 0, 0), /* Link: Scaler (Pad 1)->(Pad 0) RGB/YUV Capture */ - VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), + VIMC_DATA_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), +}; + +static const struct vimc_ancillary_link ancillary_links[] = { + /* Link: Sensor A -> Lens A */ + VIMC_ANCILLARY_LINK(0, 9), + /* Link: Sensor B -> Lens B */ + VIMC_ANCILLARY_LINK(1, 10), }; static struct vimc_pipeline_config pipe_cfg = { - .ents = ent_config, - .num_ents = ARRAY_SIZE(ent_config), - .links = ent_links, - .num_links = ARRAY_SIZE(ent_links) + .ents = ent_config, + .num_ents = ARRAY_SIZE(ent_config), + .data_links = data_links, + .num_data_links = ARRAY_SIZE(data_links), + .ancillary_links = ancillary_links, + .num_ancillary_links = ARRAY_SIZE(ancillary_links), }; /* -------------------------------------------------------------------------- */ @@ -135,8 +165,8 @@ static int vimc_create_links(struct vimc_device *vimc) int ret; /* Initialize the links between entities */ - for (i = 0; i < vimc->pipe_cfg->num_links; i++) { - const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i]; + for (i = 0; i < vimc->pipe_cfg->num_data_links; i++) { + const struct vimc_data_link *link = &vimc->pipe_cfg->data_links[i]; struct vimc_ent_device *ved_src = vimc->ent_devs[link->src_ent]; @@ -150,6 +180,22 @@ static int vimc_create_links(struct vimc_device *vimc) goto err_rm_links; } + for (i = 0; i < vimc->pipe_cfg->num_ancillary_links; i++) { + const struct vimc_ancillary_link *link = &vimc->pipe_cfg->ancillary_links[i]; + + struct vimc_ent_device *ved_primary = + vimc->ent_devs[link->primary_ent]; + struct vimc_ent_device *ved_ancillary = + vimc->ent_devs[link->ancillary_ent]; + struct media_link *ret_link = + media_create_ancillary_link(ved_primary->ent, ved_ancillary->ent); + + if (IS_ERR(ret_link)) { + ret = PTR_ERR(link); + goto err_rm_links; + } + } + return 0; err_rm_links: |