From 3047f3f98eabd655ca2db4e42219a2990052f73a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Mar 2016 05:04:03 -0700 Subject: [media] media-device: Fix a comment The comment is for the wrong function. Fix it. Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index df74cfa7da4a..6d2860657021 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -494,7 +494,7 @@ int __must_check __media_device_register(struct media_device *mdev, #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) /** - * __media_device_unregister() - Unegisters a media device element + * media_device_unregister() - Unregisters a media device element * * @mdev: pointer to struct &media_device * -- cgit v1.2.3 From 952f8eef901b170dbe6b48e80f098be5d835a82c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Mar 2016 05:34:39 -0700 Subject: [media] media-device: make topology_version u64 The uAPI defines it with 64 bits. Let's change the Kernel implementation too. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 6d2860657021..07809f698464 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -357,7 +357,7 @@ struct media_device { u32 hw_revision; u32 driver_version; - u32 topology_version; + u64 topology_version; u32 id; struct ida entity_internal_idx; -- cgit v1.2.3 From 7bbe7813290df9fda0c175b7a703325720594912 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Mar 2016 11:57:23 -0300 Subject: [media] v4l2: add device_caps to struct video_device Instead of letting drivers fill in device_caps at querycap time, let them fill it in when the video device is registered. This has the advantage that in the future the v4l2 core can access the video device's capabilities and take decisions based on that. Signed-off-by: Hans Verkuil Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dev.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 76056ab5c5bd..25a3190308fb 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -92,6 +92,9 @@ struct video_device /* device ops */ const struct v4l2_file_operations *fops; + /* device capabilities as used in v4l2_capabilities */ + u32 device_caps; + /* sysfs */ struct device dev; /* v4l device */ struct cdev *cdev; /* character device */ -- cgit v1.2.3 From b76a2a8cb6f6d9da711305d805156b40c698e94f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 29 Feb 2016 08:45:44 -0300 Subject: [media] media: Add obj_type field to struct media_entity Code that processes media entities can require knowledge of the structure type that embeds a particular media entity instance in order to cast the entity to the proper object type. This needs is shown by the presence of the is_media_entity_v4l2_io and is_media_entity_v4l2_subdev functions. The implementation of those two functions relies on the entity function field, which is both a wrong and an inefficient design, without even mentioning the maintenance issue involved in updating the functions every time a new entity function is added. Fix this by adding add an obj_type field to the media entity structure to carry the information. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 76 +++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 6dc9e4e8cbd4..1986340a8cf2 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -187,11 +187,39 @@ struct media_entity_operations { int (*link_validate)(struct media_link *link); }; +/** + * enum media_entity_type - Media entity type + * + * @MEDIA_ENTITY_TYPE_BASE: + * The entity isn't embedded in another subsystem structure. + * @MEDIA_ENTITY_TYPE_VIDEO_DEVICE: + * The entity is embedded in a struct video_device instance. + * @MEDIA_ENTITY_TYPE_V4L2_SUBDEV: + * The entity is embedded in a struct v4l2_subdev instance. + * + * Media entity objects are often not instantiated directly, but the media + * entity structure is inherited by (through embedding) other subsystem-specific + * structures. The media entity type identifies the type of the subclass + * structure that implements a media entity instance. + * + * This allows runtime type identification of media entities and safe casting to + * the correct object type. For instance, a media entity structure instance + * embedded in a v4l2_subdev structure instance will have the type + * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a v4l2_subdev + * structure using the container_of() macro. + */ +enum media_entity_type { + MEDIA_ENTITY_TYPE_BASE, + MEDIA_ENTITY_TYPE_VIDEO_DEVICE, + MEDIA_ENTITY_TYPE_V4L2_SUBDEV, +}; + /** * struct media_entity - A media entity graph object. * * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. + * @obj_type: Type of the object that implements the media_entity. * @function: Entity main function, as defined in uapi/media.h * (MEDIA_ENT_F_*) * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) @@ -220,6 +248,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; + enum media_entity_type obj_type; u32 function; unsigned long flags; @@ -329,56 +358,29 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) } /** - * is_media_entity_v4l2_io() - identify if the entity main function - * is a V4L2 I/O - * + * is_media_entity_v4l2_io() - Check if the entity is a video_device * @entity: pointer to entity * - * Return: true if the entity main function is one of the V4L2 I/O types - * (video, VBI or SDR radio); false otherwise. + * Return: true if the entity is an instance of a video_device object and can + * safely be cast to a struct video_device using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_IO_V4L: - case MEDIA_ENT_F_IO_VBI: - case MEDIA_ENT_F_IO_SWRADIO: - return true; - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; } /** - * is_media_entity_v4l2_subdev - return true if the entity main function is - * associated with the V4L2 API subdev usage - * + * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev * @entity: pointer to entity * - * This is an ancillary function used by subdev-based V4L2 drivers. - * It checks if the entity function is one of functions used by a V4L2 subdev, - * e. g. camera-relatef functions, analog TV decoder, TV tuner, V4L2 DSPs. + * Return: true if the entity is an instance of a v4l2_subdev object and can + * safely be cast to a struct v4l2_subdev using the container_of() macro, or + * false otherwise. */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { - if (!entity) - return false; - - switch (entity->function) { - case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: - case MEDIA_ENT_F_CAM_SENSOR: - case MEDIA_ENT_F_FLASH: - case MEDIA_ENT_F_LENS: - case MEDIA_ENT_F_ATV_DECODER: - case MEDIA_ENT_F_TUNER: - return true; - - default: - return false; - } + return entity && entity->obj_type == MEDIA_ENTITY_TYPE_V4L2_SUBDEV; } /** -- cgit v1.2.3 From 45b46879a785678e08953c8f97df945bf634e472 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 29 Feb 2016 08:45:45 -0300 Subject: [media] media: Rename is_media_entity_v4l2_io to is_media_entity_v4l2_video_device All users of is_media_entity_v4l2_io() (the exynos4-is, omap3isp, davince_vpfe and omap4iss drivers and the v4l2-mc power management code) use the function to check whether entities are video_device instances, either to ensure they can cast the entity to a struct video_device, or to count the number of video nodes users. The purpose of the function is thus to identify whether the media entity instance is an instance of the video_device object, not to check whether it can perform I/O. Rename it accordingly, we will introduce a more specific is_media_entity_v4l2_io() check when needed. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 1986340a8cf2..e0295eefd702 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -358,14 +358,14 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) } /** - * is_media_entity_v4l2_io() - Check if the entity is a video_device + * is_media_entity_v4l2_video_device() - Check if the entity is a video_device * @entity: pointer to entity * * Return: true if the entity is an instance of a video_device object and can * safely be cast to a struct video_device using the container_of() macro, or * false otherwise. */ -static inline bool is_media_entity_v4l2_io(struct media_entity *entity) +static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity) { return entity && entity->obj_type == MEDIA_ENTITY_TYPE_VIDEO_DEVICE; } -- cgit v1.2.3 From 9b02cbb3ede89b5cd84bbe4ef493bd130d76b070 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 24 Apr 2015 20:06:31 -0300 Subject: [media] v4l: subdev: Add pad config allocator and init Add a new subdev operation to initialize a subdev pad config array, and a helper function to allocate and initialize the array. This can be used by bridge drivers to implement try format based on subdev pad operations. Signed-off-by: Laurent Pinchart Acked-by: Vaibhav Hiremath Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 11e2dfec0198..32fc7a4beb5e 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -572,6 +572,7 @@ struct v4l2_subdev_pad_config { /** * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations * + * @init_cfg: initialize the pad config to default values * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler * code. * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler @@ -607,6 +608,8 @@ struct v4l2_subdev_pad_config { * may be adjusted by the subdev driver to device capabilities. */ struct v4l2_subdev_pad_ops { + int (*init_cfg)(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg); int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code); @@ -801,7 +804,12 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, struct v4l2_subdev_format *source_fmt, struct v4l2_subdev_format *sink_fmt); int v4l2_subdev_link_validate(struct media_link *link); + +struct v4l2_subdev_pad_config * +v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd); +void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg); #endif /* CONFIG_MEDIA_CONTROLLER */ + void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops); -- cgit v1.2.3 From fa369c9366c1c695a02ccd88abd76d7f68162810 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 19 Feb 2016 23:12:26 -0200 Subject: [media] v4l: vsp1: Fix vsp1_du_atomic_(begin|flush) declarations The functions are void, make the declaration match the definition. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index cc541753896f..d01f7cb8f691 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -23,11 +23,11 @@ int vsp1_du_init(struct device *dev); int vsp1_du_setup_lif(struct device *dev, unsigned int width, unsigned int height); -int vsp1_du_atomic_begin(struct device *dev); +void vsp1_du_atomic_begin(struct device *dev); int vsp1_du_atomic_update(struct device *dev, unsigned int rpf, u32 pixelformat, unsigned int pitch, dma_addr_t mem[2], const struct v4l2_rect *src, const struct v4l2_rect *dst); -int vsp1_du_atomic_flush(struct device *dev); +void vsp1_du_atomic_flush(struct device *dev); #endif /* __MEDIA_VSP1_H__ */ -- cgit v1.2.3 From f5e04e7ea7bebbed77c6438c7f007c354a40ce22 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 24 Mar 2016 05:15:59 -0300 Subject: [media] v4l: vsp1: Add Z-order support for DRM pipeline Make the Z-order of planes configurable by assigning RPFs to BRU inputs dynamically based on the Z-order position. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index d01f7cb8f691..e54a493bd3ff 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -24,10 +24,20 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, unsigned int height); void vsp1_du_atomic_begin(struct device *dev); -int vsp1_du_atomic_update(struct device *dev, unsigned int rpf, u32 pixelformat, - unsigned int pitch, dma_addr_t mem[2], - const struct v4l2_rect *src, - const struct v4l2_rect *dst); +int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf, + u32 pixelformat, unsigned int pitch, + dma_addr_t mem[2], const struct v4l2_rect *src, + const struct v4l2_rect *dst, unsigned int zpos); void vsp1_du_atomic_flush(struct device *dev); +static inline int vsp1_du_atomic_update(struct device *dev, + unsigned int rpf_index, u32 pixelformat, + unsigned int pitch, dma_addr_t mem[2], + const struct v4l2_rect *src, + const struct v4l2_rect *dst) +{ + return vsp1_du_atomic_update_ext(dev, rpf_index, pixelformat, pitch, + mem, src, dst, 0); +} + #endif /* __MEDIA_VSP1_H__ */ -- cgit v1.2.3 From 04738e7f336376f28adb6c0cad2a5788dcbc8e1d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 24 Mar 2016 05:15:59 -0300 Subject: [media] v4l: vsp1: Add global alpha support for DRM pipeline Make the global alpha multiplier of DRM planes configurable. All the necessary infrastructure is there, we just need to store the alpha value passed through the DRM API. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/vsp1.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/vsp1.h b/include/media/vsp1.h index e54a493bd3ff..3e654a0455bd 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -27,7 +27,8 @@ void vsp1_du_atomic_begin(struct device *dev); int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf, u32 pixelformat, unsigned int pitch, dma_addr_t mem[2], const struct v4l2_rect *src, - const struct v4l2_rect *dst, unsigned int zpos); + const struct v4l2_rect *dst, unsigned int alpha, + unsigned int zpos); void vsp1_du_atomic_flush(struct device *dev); static inline int vsp1_du_atomic_update(struct device *dev, @@ -37,7 +38,7 @@ static inline int vsp1_du_atomic_update(struct device *dev, const struct v4l2_rect *dst) { return vsp1_du_atomic_update_ext(dev, rpf_index, pixelformat, pitch, - mem, src, dst, 0); + mem, src, dst, 255, 0); } #endif /* __MEDIA_VSP1_H__ */ -- cgit v1.2.3 From e2c91d4d78ee3a69ad634bc7ef90688704baab9d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Apr 2016 10:55:24 -0300 Subject: [media] media-device: get rid of the spinlock Right now, the lock schema for media_device struct is messy, since sometimes, it is protected via a spin lock, while, for media graph traversal, it is protected by a mutex. Solve this conflict by always using a mutex. As a side effect, this prevents a bug when the media notifiers is called at atomic context, while running the notifier callback: BUG: sleeping function called from invalid context at mm/slub.c:1289 in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe 4 locks held by modprobe/3479: #0: (&dev->mutex){......}, at: [] __driver_attach+0xa3/0x160 #1: (&dev->mutex){......}, at: [] __driver_attach+0xb1/0x160 #2: (register_mutex#5){+.+.+.}, at: [] usb_audio_probe+0x257/0x1c90 [snd_usb_audio] #3: (&(&mdev->lock)->rlock){+.+.+.}, at: [] media_device_register_entity+0x1cb/0x700 [media] CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49 Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015 0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000 ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000 ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5 Call Trace: [] dump_stack+0x85/0xc4 [] ___might_sleep+0x245/0x3a0 [] __might_sleep+0x95/0x1a0 [] kmem_cache_alloc_trace+0x20e/0x300 [] ? media_add_link+0x4d/0x140 [media] [] media_add_link+0x4d/0x140 [media] [] media_create_pad_link+0xa1/0x600 [media] [] au0828_media_graph_notify+0x173/0x360 [au0828] [] ? media_gobj_create+0x1ba/0x480 [media] [] media_device_register_entity+0x3ab/0x700 [media] Reviewed-by: Javier Martinez Canillas Acked-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 07809f698464..b21ef244ad3e 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -25,7 +25,6 @@ #include #include -#include #include #include @@ -304,8 +303,7 @@ struct media_entity_notify { * @pads: List of registered pads * @links: List of registered links * @entity_notify: List of registered entity_notify callbacks - * @lock: Entities list lock - * @graph_mutex: Entities graph operation lock + * @graph_mutex: Protects access to struct media_device data * @pm_count_walk: Graph walk for power state walk. Access serialised using * graph_mutex. * @@ -371,8 +369,6 @@ struct media_device { /* notify callback list invoked when a new entity is registered */ struct list_head entity_notify; - /* Protects the graph objects creation/removal */ - spinlock_t lock; /* Serializes graph operations. */ struct mutex graph_mutex; struct media_entity_graph pm_count_walk; -- cgit v1.2.3 From 5ed470feb9a121582dbd455c72b133dc1a856a0a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 6 Apr 2016 10:55:25 -0300 Subject: [media] media: Improve documentation for link_setup/link_modify Those callbacks are called with the media_device.graph_mutex held. Add a note about that, as the code called by those notifiers should not be touching in the mutex. Acked-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 3 ++- include/media/media-entity.h | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index b21ef244ad3e..a9b33c47310d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -311,7 +311,8 @@ struct media_entity_notify { * @enable_source: Enable Source Handler function pointer * @disable_source: Disable Source Handler function pointer * - * @link_notify: Link state change notification callback + * @link_notify: Link state change notification callback. This callback is + * called with the graph_mutex held. * * This structure represents an abstract high-level media device. It allows easy * access to entities and provides basic media device-level support. The diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e0295eefd702..cbb266f7f2b5 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -179,6 +179,9 @@ struct media_pad { * @link_validate: Return whether a link is valid from the entity point of * view. The media_entity_pipeline_start() function * validates all links by calling this operation. Optional. + * + * Note: Those these callbacks are called with struct media_device.@graph_mutex + * mutex held. */ struct media_entity_operations { int (*link_setup)(struct media_entity *entity, -- cgit v1.2.3 From 96655553e5f9af6a8d908386685b7c865a138283 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 3 Apr 2016 17:44:16 -0300 Subject: [media] v4l2-device.h: add v4l2_device_mask_ variants The v4l2_device_call_* defines filter subdevs based on the grp_id value. But some drivers use a bitmask, so instead of filtering by grp_id == value, you want to filter by grp_id & value. Make variants of these defines to do this. The 'has_op' define has been extended to have a grp_id argument as well, and a mask variant has been added. This extra argument required a change to go7007. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-device.h | 55 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 9c581578783f..d5d45a8d3998 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -196,11 +196,64 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, ##args); \ }) -#define v4l2_device_has_op(v4l2_dev, o, f) \ +/* + * Call the specified callback for all subdevs where grp_id & grpmsk != 0 + * (if grpmsk == `0, then match them all). Ignore any errors. Note that you + * cannot add or delete a subdev while walking the subdevs list. + */ +#define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...) \ + do { \ + struct v4l2_subdev *__sd; \ + \ + __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ + !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f , \ + ##args); \ + } while (0) + +/* + * Call the specified callback for all subdevs where grp_id & grpmsk != 0 + * (if grpmsk == `0, then match them all). If the callback returns an error + * other than 0 or -ENOIOCTLCMD, then return with that error code. Note that + * you cannot add or delete a subdev while walking the subdevs list. + */ +#define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \ +({ \ + struct v4l2_subdev *__sd; \ + __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ + !(grpmsk) || (__sd->grp_id & (grpmsk)), o, f , \ + ##args); \ +}) + +/* + * Does any subdev with matching grpid (or all if grpid == 0) has the given + * op? + */ +#define v4l2_device_has_op(v4l2_dev, grpid, o, f) \ +({ \ + struct v4l2_subdev *__sd; \ + bool __result = false; \ + list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) { \ + if ((grpid) && __sd->grp_id != (grpid)) \ + continue; \ + if (v4l2_subdev_has_op(__sd, o, f)) { \ + __result = true; \ + break; \ + } \ + } \ + __result; \ +}) + +/* + * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given + * op? + */ +#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f) \ ({ \ struct v4l2_subdev *__sd; \ bool __result = false; \ list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) { \ + if ((grpmsk) && !(__sd->grp_id & (grpmsk))) \ + continue; \ if (v4l2_subdev_has_op(__sd, o, f)) { \ __result = true; \ break; \ -- cgit v1.2.3 From ac49de8c49d770b5ded5c717c1eaf339d7649da1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 3 Apr 2016 16:42:42 -0300 Subject: [media] v4l2-rect.h: new header with struct v4l2_rect helper functions This makes it easier to share this code with any driver that needs to manipulate the v4l2_rect datastructure. Signed-off-by: Hans Verkuil Acked-by: Sakari Ailus Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-rect.h | 173 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 include/media/v4l2-rect.h (limited to 'include') diff --git a/include/media/v4l2-rect.h b/include/media/v4l2-rect.h new file mode 100644 index 000000000000..d2125f0cc7cd --- /dev/null +++ b/include/media/v4l2-rect.h @@ -0,0 +1,173 @@ +/* + * v4l2-rect.h - v4l2_rect helper functions + * + * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _V4L2_RECT_H_ +#define _V4L2_RECT_H_ + +#include + +/** + * v4l2_rect_set_size_to() - copy the width/height values. + * @r: rect whose width and height fields will be set + * @size: rect containing the width and height fields you need. + */ +static inline void v4l2_rect_set_size_to(struct v4l2_rect *r, + const struct v4l2_rect *size) +{ + r->width = size->width; + r->height = size->height; +} + +/** + * v4l2_rect_set_min_size() - width and height of r should be >= min_size. + * @r: rect whose width and height will be modified + * @min_size: rect containing the minimal width and height + */ +static inline void v4l2_rect_set_min_size(struct v4l2_rect *r, + const struct v4l2_rect *min_size) +{ + if (r->width < min_size->width) + r->width = min_size->width; + if (r->height < min_size->height) + r->height = min_size->height; +} + +/** + * v4l2_rect_set_max_size() - width and height of r should be <= max_size + * @r: rect whose width and height will be modified + * @max_size: rect containing the maximum width and height + */ +static inline void v4l2_rect_set_max_size(struct v4l2_rect *r, + const struct v4l2_rect *max_size) +{ + if (r->width > max_size->width) + r->width = max_size->width; + if (r->height > max_size->height) + r->height = max_size->height; +} + +/** + * v4l2_rect_map_inside()- r should be inside boundary. + * @r: rect that will be modified + * @boundary: rect containing the boundary for @r + */ +static inline void v4l2_rect_map_inside(struct v4l2_rect *r, + const struct v4l2_rect *boundary) +{ + v4l2_rect_set_max_size(r, boundary); + if (r->left < boundary->left) + r->left = boundary->left; + if (r->top < boundary->top) + r->top = boundary->top; + if (r->left + r->width > boundary->width) + r->left = boundary->width - r->width; + if (r->top + r->height > boundary->height) + r->top = boundary->height - r->height; +} + +/** + * v4l2_rect_same_size() - return true if r1 has the same size as r2 + * @r1: rectangle. + * @r2: rectangle. + * + * Return true if both rectangles have the same size. + */ +static inline bool v4l2_rect_same_size(const struct v4l2_rect *r1, + const struct v4l2_rect *r2) +{ + return r1->width == r2->width && r1->height == r2->height; +} + +/** + * v4l2_rect_intersect() - calculate the intersection of two rects. + * @r: intersection of @r1 and @r2. + * @r1: rectangle. + * @r2: rectangle. + */ +static inline void v4l2_rect_intersect(struct v4l2_rect *r, + const struct v4l2_rect *r1, + const struct v4l2_rect *r2) +{ + int right, bottom; + + r->top = max(r1->top, r2->top); + r->left = max(r1->left, r2->left); + bottom = min(r1->top + r1->height, r2->top + r2->height); + right = min(r1->left + r1->width, r2->left + r2->width); + r->height = max(0, bottom - r->top); + r->width = max(0, right - r->left); +} + +/** + * v4l2_rect_scale() - scale rect r by to/from + * @r: rect to be scaled. + * @from: from rectangle. + * @to: to rectangle. + * + * This scales rectangle @r horizontally by @to->width / @from->width and + * vertically by @to->height / @from->height. + * + * Typically @r is a rectangle inside @from and you want the rectangle as + * it would appear after scaling @from to @to. So the resulting @r will + * be the scaled rectangle inside @to. + */ +static inline void v4l2_rect_scale(struct v4l2_rect *r, + const struct v4l2_rect *from, + const struct v4l2_rect *to) +{ + if (from->width == 0 || from->height == 0) { + r->left = r->top = r->width = r->height = 0; + return; + } + r->left = (((r->left - from->left) * to->width) / from->width) & ~1; + r->width = ((r->width * to->width) / from->width) & ~1; + r->top = ((r->top - from->top) * to->height) / from->height; + r->height = (r->height * to->height) / from->height; +} + +/** + * v4l2_rect_overlap() - do r1 and r2 overlap? + * @r1: rectangle. + * @r2: rectangle. + * + * Returns true if @r1 and @r2 overlap. + */ +static inline bool v4l2_rect_overlap(const struct v4l2_rect *r1, + const struct v4l2_rect *r2) +{ + /* + * IF the left side of r1 is to the right of the right side of r2 OR + * the left side of r2 is to the right of the right side of r1 THEN + * they do not overlap. + */ + if (r1->left >= r2->left + r2->width || + r2->left >= r1->left + r1->width) + return false; + /* + * IF the top side of r1 is below the bottom of r2 OR + * the top side of r2 is below the bottom of r1 THEN + * they do not overlap. + */ + if (r1->top >= r2->top + r2->height || + r2->top >= r1->top + r1->height) + return false; + return true; +} + +#endif -- cgit v1.2.3 From e07d46e7e0da86c146f199dae76f879096bc436a Mon Sep 17 00:00:00 2001 From: Helen Mae Koike Fornazier Date: Fri, 8 Apr 2016 17:28:58 -0300 Subject: [media] tpg: Export the tpg code from vivid as a module The test pattern generator will be used by other drivers as the virtual media controller (vimc) Signed-off-by: Helen Mae Koike Fornazier Acked-by: Laurent Pinchart Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-tpg-colors.h | 68 +++++ include/media/v4l2-tpg.h | 597 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 665 insertions(+) create mode 100644 include/media/v4l2-tpg-colors.h create mode 100644 include/media/v4l2-tpg.h (limited to 'include') diff --git a/include/media/v4l2-tpg-colors.h b/include/media/v4l2-tpg-colors.h new file mode 100644 index 000000000000..2a88d1fae0cd --- /dev/null +++ b/include/media/v4l2-tpg-colors.h @@ -0,0 +1,68 @@ +/* + * v4l2-tpg-colors.h - Color definitions for the test pattern generator + * + * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _V4L2_TPG_COLORS_H_ +#define _V4L2_TPG_COLORS_H_ + +struct color { + unsigned char r, g, b; +}; + +struct color16 { + int r, g, b; +}; + +enum tpg_color { + TPG_COLOR_CSC_WHITE, + TPG_COLOR_CSC_YELLOW, + TPG_COLOR_CSC_CYAN, + TPG_COLOR_CSC_GREEN, + TPG_COLOR_CSC_MAGENTA, + TPG_COLOR_CSC_RED, + TPG_COLOR_CSC_BLUE, + TPG_COLOR_CSC_BLACK, + TPG_COLOR_75_YELLOW, + TPG_COLOR_75_CYAN, + TPG_COLOR_75_GREEN, + TPG_COLOR_75_MAGENTA, + TPG_COLOR_75_RED, + TPG_COLOR_75_BLUE, + TPG_COLOR_100_WHITE, + TPG_COLOR_100_YELLOW, + TPG_COLOR_100_CYAN, + TPG_COLOR_100_GREEN, + TPG_COLOR_100_MAGENTA, + TPG_COLOR_100_RED, + TPG_COLOR_100_BLUE, + TPG_COLOR_100_BLACK, + TPG_COLOR_TEXTFG, + TPG_COLOR_TEXTBG, + TPG_COLOR_RANDOM, + TPG_COLOR_RAMP, + TPG_COLOR_MAX = TPG_COLOR_RAMP + 256 +}; + +extern const struct color tpg_colors[TPG_COLOR_MAX]; +extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1]; +extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1]; +extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1] + [V4L2_XFER_FUNC_SMPTE2084 + 1] + [TPG_COLOR_CSC_BLACK + 1]; + +#endif diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h new file mode 100644 index 000000000000..329bebfa930c --- /dev/null +++ b/include/media/v4l2-tpg.h @@ -0,0 +1,597 @@ +/* + * v4l2-tpg.h - Test Pattern Generator + * + * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _V4L2_TPG_H_ +#define _V4L2_TPG_H_ + +#include +#include +#include +#include +#include +#include +#include + +enum tpg_pattern { + TPG_PAT_75_COLORBAR, + TPG_PAT_100_COLORBAR, + TPG_PAT_CSC_COLORBAR, + TPG_PAT_100_HCOLORBAR, + TPG_PAT_100_COLORSQUARES, + TPG_PAT_BLACK, + TPG_PAT_WHITE, + TPG_PAT_RED, + TPG_PAT_GREEN, + TPG_PAT_BLUE, + TPG_PAT_CHECKERS_16X16, + TPG_PAT_CHECKERS_2X2, + TPG_PAT_CHECKERS_1X1, + TPG_PAT_COLOR_CHECKERS_2X2, + TPG_PAT_COLOR_CHECKERS_1X1, + TPG_PAT_ALTERNATING_HLINES, + TPG_PAT_ALTERNATING_VLINES, + TPG_PAT_CROSS_1_PIXEL, + TPG_PAT_CROSS_2_PIXELS, + TPG_PAT_CROSS_10_PIXELS, + TPG_PAT_GRAY_RAMP, + + /* Must be the last pattern */ + TPG_PAT_NOISE, +}; + +extern const char * const tpg_pattern_strings[]; + +enum tpg_quality { + TPG_QUAL_COLOR, + TPG_QUAL_GRAY, + TPG_QUAL_NOISE +}; + +enum tpg_video_aspect { + TPG_VIDEO_ASPECT_IMAGE, + TPG_VIDEO_ASPECT_4X3, + TPG_VIDEO_ASPECT_14X9_CENTRE, + TPG_VIDEO_ASPECT_16X9_CENTRE, + TPG_VIDEO_ASPECT_16X9_ANAMORPHIC, +}; + +enum tpg_pixel_aspect { + TPG_PIXEL_ASPECT_SQUARE, + TPG_PIXEL_ASPECT_NTSC, + TPG_PIXEL_ASPECT_PAL, +}; + +enum tpg_move_mode { + TPG_MOVE_NEG_FAST, + TPG_MOVE_NEG, + TPG_MOVE_NEG_SLOW, + TPG_MOVE_NONE, + TPG_MOVE_POS_SLOW, + TPG_MOVE_POS, + TPG_MOVE_POS_FAST, +}; + +extern const char * const tpg_aspect_strings[]; + +#define TPG_MAX_PLANES 3 +#define TPG_MAX_PAT_LINES 8 + +struct tpg_data { + /* Source frame size */ + unsigned src_width, src_height; + /* Buffer height */ + unsigned buf_height; + /* Scaled output frame size */ + unsigned scaled_width; + u32 field; + bool field_alternate; + /* crop coordinates are frame-based */ + struct v4l2_rect crop; + /* compose coordinates are format-based */ + struct v4l2_rect compose; + /* border and square coordinates are frame-based */ + struct v4l2_rect border; + struct v4l2_rect square; + + /* Color-related fields */ + enum tpg_quality qual; + unsigned qual_offset; + u8 alpha_component; + bool alpha_red_only; + u8 brightness; + u8 contrast; + u8 saturation; + s16 hue; + u32 fourcc; + bool is_yuv; + u32 colorspace; + u32 xfer_func; + u32 ycbcr_enc; + /* + * Stores the actual transfer function, i.e. will never be + * V4L2_XFER_FUNC_DEFAULT. + */ + u32 real_xfer_func; + /* + * Stores the actual Y'CbCr encoding, i.e. will never be + * V4L2_YCBCR_ENC_DEFAULT. + */ + u32 real_ycbcr_enc; + u32 quantization; + /* + * Stores the actual quantization, i.e. will never be + * V4L2_QUANTIZATION_DEFAULT. + */ + u32 real_quantization; + enum tpg_video_aspect vid_aspect; + enum tpg_pixel_aspect pix_aspect; + unsigned rgb_range; + unsigned real_rgb_range; + unsigned buffers; + unsigned planes; + bool interleaved; + u8 vdownsampling[TPG_MAX_PLANES]; + u8 hdownsampling[TPG_MAX_PLANES]; + /* + * horizontal positions must be ANDed with this value to enforce + * correct boundaries for packed YUYV values. + */ + unsigned hmask[TPG_MAX_PLANES]; + /* Used to store the colors in native format, either RGB or YUV */ + u8 colors[TPG_COLOR_MAX][3]; + u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; + /* size in bytes for two pixels in each plane */ + unsigned twopixelsize[TPG_MAX_PLANES]; + unsigned bytesperline[TPG_MAX_PLANES]; + + /* Configuration */ + enum tpg_pattern pattern; + bool hflip; + bool vflip; + unsigned perc_fill; + bool perc_fill_blank; + bool show_border; + bool show_square; + bool insert_sav; + bool insert_eav; + + /* Test pattern movement */ + enum tpg_move_mode mv_hor_mode; + int mv_hor_count; + int mv_hor_step; + enum tpg_move_mode mv_vert_mode; + int mv_vert_count; + int mv_vert_step; + + bool recalc_colors; + bool recalc_lines; + bool recalc_square_border; + + /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ + unsigned max_line_width; + u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; + u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; + u8 *random_line[TPG_MAX_PLANES]; + u8 *contrast_line[TPG_MAX_PLANES]; + u8 *black_line[TPG_MAX_PLANES]; +}; + +void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h); +int tpg_alloc(struct tpg_data *tpg, unsigned max_w); +void tpg_free(struct tpg_data *tpg); +void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, + u32 field); +void tpg_log_status(struct tpg_data *tpg); + +void tpg_set_font(const u8 *f); +void tpg_gen_text(const struct tpg_data *tpg, + u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); +void tpg_calc_text_basep(struct tpg_data *tpg, + u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); +unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line); +void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, + unsigned p, u8 *vbuf); +void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, + unsigned p, u8 *vbuf); +bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); +void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, + const struct v4l2_rect *compose); + +static inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern) +{ + if (tpg->pattern == pattern) + return; + tpg->pattern = pattern; + tpg->recalc_colors = true; +} + +static inline void tpg_s_quality(struct tpg_data *tpg, + enum tpg_quality qual, unsigned qual_offset) +{ + if (tpg->qual == qual && tpg->qual_offset == qual_offset) + return; + tpg->qual = qual; + tpg->qual_offset = qual_offset; + tpg->recalc_colors = true; +} + +static inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg) +{ + return tpg->qual; +} + +static inline void tpg_s_alpha_component(struct tpg_data *tpg, + u8 alpha_component) +{ + if (tpg->alpha_component == alpha_component) + return; + tpg->alpha_component = alpha_component; + tpg->recalc_colors = true; +} + +static inline void tpg_s_alpha_mode(struct tpg_data *tpg, + bool red_only) +{ + if (tpg->alpha_red_only == red_only) + return; + tpg->alpha_red_only = red_only; + tpg->recalc_colors = true; +} + +static inline void tpg_s_brightness(struct tpg_data *tpg, + u8 brightness) +{ + if (tpg->brightness == brightness) + return; + tpg->brightness = brightness; + tpg->recalc_colors = true; +} + +static inline void tpg_s_contrast(struct tpg_data *tpg, + u8 contrast) +{ + if (tpg->contrast == contrast) + return; + tpg->contrast = contrast; + tpg->recalc_colors = true; +} + +static inline void tpg_s_saturation(struct tpg_data *tpg, + u8 saturation) +{ + if (tpg->saturation == saturation) + return; + tpg->saturation = saturation; + tpg->recalc_colors = true; +} + +static inline void tpg_s_hue(struct tpg_data *tpg, + s16 hue) +{ + if (tpg->hue == hue) + return; + tpg->hue = hue; + tpg->recalc_colors = true; +} + +static inline void tpg_s_rgb_range(struct tpg_data *tpg, + unsigned rgb_range) +{ + if (tpg->rgb_range == rgb_range) + return; + tpg->rgb_range = rgb_range; + tpg->recalc_colors = true; +} + +static inline void tpg_s_real_rgb_range(struct tpg_data *tpg, + unsigned rgb_range) +{ + if (tpg->real_rgb_range == rgb_range) + return; + tpg->real_rgb_range = rgb_range; + tpg->recalc_colors = true; +} + +static inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace) +{ + if (tpg->colorspace == colorspace) + return; + tpg->colorspace = colorspace; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_colorspace(const struct tpg_data *tpg) +{ + return tpg->colorspace; +} + +static inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc) +{ + if (tpg->ycbcr_enc == ycbcr_enc) + return; + tpg->ycbcr_enc = ycbcr_enc; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) +{ + return tpg->ycbcr_enc; +} + +static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) +{ + if (tpg->xfer_func == xfer_func) + return; + tpg->xfer_func = xfer_func; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_xfer_func(const struct tpg_data *tpg) +{ + return tpg->xfer_func; +} + +static inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization) +{ + if (tpg->quantization == quantization) + return; + tpg->quantization = quantization; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_quantization(const struct tpg_data *tpg) +{ + return tpg->quantization; +} + +static inline unsigned tpg_g_buffers(const struct tpg_data *tpg) +{ + return tpg->buffers; +} + +static inline unsigned tpg_g_planes(const struct tpg_data *tpg) +{ + return tpg->interleaved ? 1 : tpg->planes; +} + +static inline bool tpg_g_interleaved(const struct tpg_data *tpg) +{ + return tpg->interleaved; +} + +static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) +{ + return tpg->twopixelsize[plane]; +} + +static inline unsigned tpg_hdiv(const struct tpg_data *tpg, + unsigned plane, unsigned x) +{ + return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) * + tpg->twopixelsize[plane] / 2; +} + +static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x) +{ + return (x * tpg->scaled_width) / tpg->src_width; +} + +static inline unsigned tpg_hscale_div(const struct tpg_data *tpg, + unsigned plane, unsigned x) +{ + return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x)); +} + +static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) +{ + return tpg->bytesperline[plane]; +} + +static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) +{ + unsigned p; + + if (tpg->buffers > 1) { + tpg->bytesperline[plane] = bpl; + return; + } + + for (p = 0; p < tpg_g_planes(tpg); p++) { + unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; + + tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p]; + } + if (tpg_g_interleaved(tpg)) + tpg->bytesperline[1] = tpg->bytesperline[0]; +} + + +static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane) +{ + unsigned w = 0; + unsigned p; + + if (tpg->buffers > 1) + return tpg_g_bytesperline(tpg, plane); + for (p = 0; p < tpg_g_planes(tpg); p++) { + unsigned plane_w = tpg_g_bytesperline(tpg, p); + + w += plane_w / tpg->vdownsampling[p]; + } + return w; +} + +static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, + unsigned plane, unsigned bpl) +{ + unsigned w = 0; + unsigned p; + + if (tpg->buffers > 1) + return bpl; + for (p = 0; p < tpg_g_planes(tpg); p++) { + unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; + + plane_w /= tpg->hdownsampling[p]; + w += plane_w / tpg->vdownsampling[p]; + } + return w; +} + +static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane) +{ + if (plane >= tpg_g_planes(tpg)) + return 0; + + return tpg_g_bytesperline(tpg, plane) * tpg->buf_height / + tpg->vdownsampling[plane]; +} + +static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) +{ + tpg->buf_height = h; +} + +static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate) +{ + tpg->field = field; + tpg->field_alternate = alternate; +} + +static inline void tpg_s_perc_fill(struct tpg_data *tpg, + unsigned perc_fill) +{ + tpg->perc_fill = perc_fill; +} + +static inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg) +{ + return tpg->perc_fill; +} + +static inline void tpg_s_perc_fill_blank(struct tpg_data *tpg, + bool perc_fill_blank) +{ + tpg->perc_fill_blank = perc_fill_blank; +} + +static inline void tpg_s_video_aspect(struct tpg_data *tpg, + enum tpg_video_aspect vid_aspect) +{ + if (tpg->vid_aspect == vid_aspect) + return; + tpg->vid_aspect = vid_aspect; + tpg->recalc_square_border = true; +} + +static inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg) +{ + return tpg->vid_aspect; +} + +static inline void tpg_s_pixel_aspect(struct tpg_data *tpg, + enum tpg_pixel_aspect pix_aspect) +{ + if (tpg->pix_aspect == pix_aspect) + return; + tpg->pix_aspect = pix_aspect; + tpg->recalc_square_border = true; +} + +static inline void tpg_s_show_border(struct tpg_data *tpg, + bool show_border) +{ + tpg->show_border = show_border; +} + +static inline void tpg_s_show_square(struct tpg_data *tpg, + bool show_square) +{ + tpg->show_square = show_square; +} + +static inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav) +{ + tpg->insert_sav = insert_sav; +} + +static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav) +{ + tpg->insert_eav = insert_eav; +} + +void tpg_update_mv_step(struct tpg_data *tpg); + +static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg, + enum tpg_move_mode mv_hor_mode) +{ + tpg->mv_hor_mode = mv_hor_mode; + tpg_update_mv_step(tpg); +} + +static inline void tpg_s_mv_vert_mode(struct tpg_data *tpg, + enum tpg_move_mode mv_vert_mode) +{ + tpg->mv_vert_mode = mv_vert_mode; + tpg_update_mv_step(tpg); +} + +static inline void tpg_init_mv_count(struct tpg_data *tpg) +{ + tpg->mv_hor_count = tpg->mv_vert_count = 0; +} + +static inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field) +{ + tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2); + tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2); +} + +static inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip) +{ + if (tpg->hflip == hflip) + return; + tpg->hflip = hflip; + tpg_update_mv_step(tpg); + tpg->recalc_lines = true; +} + +static inline bool tpg_g_hflip(const struct tpg_data *tpg) +{ + return tpg->hflip; +} + +static inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip) +{ + tpg->vflip = vflip; +} + +static inline bool tpg_g_vflip(const struct tpg_data *tpg) +{ + return tpg->vflip; +} + +static inline bool tpg_pattern_is_static(const struct tpg_data *tpg) +{ + return tpg->pattern != TPG_PAT_NOISE && + tpg->mv_hor_mode == TPG_MOVE_NONE && + tpg->mv_vert_mode == TPG_MOVE_NONE; +} + +#endif -- cgit v1.2.3 From 57c7598711b820b4253bcee94ec750ebc1c63af6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 22 Apr 2016 06:06:58 -0300 Subject: [media] videodev2.h: remove 'experimental' annotations Most of what is marked as 'experimental' has been around for years. Time to drop that annotation. The only remaining 'experimental' bits of the API are the debug ioctls and structs: these should remain experimental since the only application that should use this is v4l2-dbg. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index e895975c5b0e..8f951917be74 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -138,10 +138,7 @@ enum v4l2_buf_type { V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, -#if 1 - /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, -#endif V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, V4L2_BUF_TYPE_SDR_CAPTURE = 11, @@ -657,8 +654,7 @@ struct v4l2_fmtdesc { #define V4L2_FMT_FLAG_COMPRESSED 0x0001 #define V4L2_FMT_FLAG_EMULATED 0x0002 -#if 1 - /* Experimental Frame Size and frame rate enumeration */ + /* Frame Size and frame rate enumeration */ /* * F R A M E S I Z E E N U M E R A T I O N */ @@ -724,7 +720,6 @@ struct v4l2_frmivalenum { __u32 reserved[2]; /* Reserved space for future use */ }; -#endif /* * T I M E C O D E @@ -1728,8 +1723,6 @@ struct v4l2_audioout { /* * M P E G S E R V I C E S - * - * NOTE: EXPERIMENTAL API */ #if 1 #define V4L2_ENC_IDX_FRAME_I (0) @@ -2259,46 +2252,35 @@ struct v4l2_create_buffers { #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) -/* Experimental, meant for debugging, testing and internal use. - Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. - You must be root to use these ioctls. Never use these in applications! */ +/* + * Experimental, meant for debugging, testing and internal use. + * Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + * You must be root to use these ioctls. Never use these in applications! + */ #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) - #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) #define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) - -/* Experimental, the below two ioctls may change over the next couple of kernel - versions */ #define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) #define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) - -/* Experimental selection API */ #define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) #define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) - -/* Experimental, these two ioctls may change over the next couple of kernel - versions. */ #define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) #define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) - -/* Experimental, these three ioctls may change over the next couple of kernel - versions. */ #define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) #define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) #define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) - -/* Experimental, this ioctl may change over the next couple of kernel - versions. */ #define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band) -/* Experimental, meant for debugging, testing and internal use. - Never use these in applications! */ +/* + * Experimental, meant for debugging, testing and internal use. + * Never use this in applications! + */ #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info) #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl) -- cgit v1.2.3 From 5f61ff86116cf637ae926f44c1857716ec89e9fb Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 17 Mar 2016 16:39:13 -0300 Subject: [media] media: rc: reduce size of struct ir_raw_event struct ir_raw_event currently has a size of 12 bytes on most (all?) architectures. This can be reduced to 8 bytes whilst maintaining full backwards compatibility. This saves 2KB in size of struct ir_raw_event_ctrl (as element kfifo is reduced by 512 * 4 bytes) and it allows to copy the full struct ir_raw_event with a single 64 bit operation. Successfully tested with the Nuvoton driver and successfully compile-tested with the ene_ir driver (as it uses the carrier / duty_cycle elements). Signed-off-by: Heiner Kallweit Signed-off-by: Mauro Carvalho Chehab --- include/media/rc-core.h | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 0f77b3dffb37..b6586a91129c 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -215,12 +215,9 @@ enum raw_event_type { struct ir_raw_event { union { u32 duration; - - struct { - u32 carrier; - u8 duty_cycle; - }; + u32 carrier; }; + u8 duty_cycle; unsigned pulse:1; unsigned reset:1; @@ -228,13 +225,7 @@ struct ir_raw_event { unsigned carrier_report:1; }; -#define DEFINE_IR_RAW_EVENT(event) \ - struct ir_raw_event event = { \ - { .duration = 0 } , \ - .pulse = 0, \ - .reset = 0, \ - .timeout = 0, \ - .carrier_report = 0 } +#define DEFINE_IR_RAW_EVENT(event) struct ir_raw_event event = {} static inline void init_ir_raw_event(struct ir_raw_event *ev) { @@ -256,8 +247,7 @@ void ir_raw_event_set_idle(struct rc_dev *dev, bool idle); static inline void ir_raw_event_reset(struct rc_dev *dev) { - DEFINE_IR_RAW_EVENT(ev); - ev.reset = true; + struct ir_raw_event ev = { .reset = true }; ir_raw_event_store(dev, &ev); ir_raw_event_handle(dev); -- cgit v1.2.3