2019-05-27 08:55:06 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-04-16 15:20:36 -07:00
/*
*
* ( c ) 2004 Gerd Knorr < kraxel @ bytesex . org > [ SuSE Labs ]
*/
2015-04-30 06:44:56 -03:00
# include "saa7134.h"
# include "saa7134-reg.h"
2005-04-16 15:20:36 -07:00
# include <linux/init.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/delay.h>
2006-01-09 15:32:31 -02:00
# include <media/v4l2-common.h>
2013-12-14 08:28:28 -03:00
# include <media/v4l2-event.h>
2005-04-16 15:20:36 -07:00
/* ------------------------------------------------------------------ */
MODULE_AUTHOR ( " Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] " ) ;
2024-06-09 14:58:06 -07:00
MODULE_DESCRIPTION ( " Philips SAA7134 empress support " ) ;
2005-04-16 15:20:36 -07:00
MODULE_LICENSE ( " GPL " ) ;
static unsigned int empress_nr [ ] = { [ 0 . . . ( SAA7134_MAXBOARDS - 1 ) ] = UNSET } ;
2005-12-12 00:37:28 -08:00
2005-04-16 15:20:36 -07:00
module_param_array ( empress_nr , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( empress_nr , " ts device number " ) ;
/* ------------------------------------------------------------------ */
2014-04-17 07:30:53 -03:00
static int start_streaming ( struct vb2_queue * vq , unsigned int count )
2005-04-16 15:20:36 -07:00
{
2014-04-17 07:30:53 -03:00
struct saa7134_dmaqueue * dmaq = vq - > drv_priv ;
struct saa7134_dev * dev = dmaq - > dev ;
2008-08-26 13:44:40 -03:00
u32 leading_null_bytes = 0 ;
2014-04-17 07:30:53 -03:00
int err ;
err = saa7134_ts_start_streaming ( vq , count ) ;
if ( err )
return err ;
2006-06-18 16:40:10 -03:00
2008-08-26 13:44:40 -03:00
/* If more cards start to need this, then this
should probably be added to the card definitions . */
switch ( dev - > board ) {
case SAA7134_BOARD_BEHOLD_M6 :
case SAA7134_BOARD_BEHOLD_M63 :
case SAA7134_BOARD_BEHOLD_M6_EXTRA :
leading_null_bytes = 1 ;
break ;
}
2009-01-17 12:17:14 -03:00
saa_call_all ( dev , core , init , leading_null_bytes ) ;
2014-04-17 07:30:53 -03:00
/* Unmute audio */
saa_writeb ( SAA7134_AUDIO_MUTE_CTRL ,
saa_readb ( SAA7134_AUDIO_MUTE_CTRL ) & ~ ( 1 < < 6 ) ) ;
2005-04-16 15:20:36 -07:00
dev - > empress_started = 1 ;
2005-11-08 21:37:43 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
2014-04-17 07:30:53 -03:00
static void stop_streaming ( struct vb2_queue * vq )
2014-04-17 04:23:07 -03:00
{
2014-04-17 07:30:53 -03:00
struct saa7134_dmaqueue * dmaq = vq - > drv_priv ;
struct saa7134_dev * dev = dmaq - > dev ;
2014-04-17 04:23:07 -03:00
2014-04-17 07:30:53 -03:00
saa7134_ts_stop_streaming ( vq ) ;
2014-04-17 04:23:07 -03:00
saa_writeb ( SAA7134_SPECIAL_MODE , 0x00 ) ;
2014-04-17 07:30:53 -03:00
msleep ( 20 ) ;
2014-04-17 04:23:07 -03:00
saa_writeb ( SAA7134_SPECIAL_MODE , 0x01 ) ;
msleep ( 100 ) ;
2014-04-17 07:30:53 -03:00
/* Mute audio */
2007-06-20 05:37:27 -03:00
saa_writeb ( SAA7134_AUDIO_MUTE_CTRL ,
2014-04-17 07:30:53 -03:00
saa_readb ( SAA7134_AUDIO_MUTE_CTRL ) | ( 1 < < 6 ) ) ;
dev - > empress_started = 0 ;
2005-04-16 15:20:36 -07:00
}
2016-09-08 20:59:18 -03:00
static const struct vb2_ops saa7134_empress_qops = {
2014-04-17 07:30:53 -03:00
. queue_setup = saa7134_ts_queue_setup ,
. buf_init = saa7134_ts_buffer_init ,
. buf_prepare = saa7134_ts_buffer_prepare ,
. buf_queue = saa7134_vb2_buffer_queue ,
. wait_prepare = vb2_ops_wait_prepare ,
. wait_finish = vb2_ops_wait_finish ,
. start_streaming = start_streaming ,
. stop_streaming = stop_streaming ,
} ;
2005-04-16 15:20:36 -07:00
2014-04-17 07:30:53 -03:00
/* ------------------------------------------------------------------ */
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_enum_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_fmtdesc * f )
{
if ( f - > index ! = 0 )
return - EINVAL ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
f - > pixelformat = V4L2_PIX_FMT_MPEG ;
return 0 ;
}
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_g_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_format * f )
{
2013-12-14 08:28:26 -03:00
struct saa7134_dev * dev = video_drvdata ( file ) ;
2015-04-09 04:02:34 -03:00
struct v4l2_subdev_format fmt = {
. which = V4L2_SUBDEV_FORMAT_ACTIVE ,
} ;
struct v4l2_mbus_framefmt * mbus_fmt = & fmt . format ;
2005-04-16 15:20:36 -07:00
2015-04-09 04:02:34 -03:00
saa_call_all ( dev , pad , get_fmt , NULL , & fmt ) ;
2005-04-16 15:20:36 -07:00
2015-04-09 04:02:34 -03:00
v4l2_fill_pix_format ( & f - > fmt . pix , mbus_fmt ) ;
2007-12-11 12:56:23 -03:00
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
2013-06-01 10:02:38 -03:00
f - > fmt . pix . bytesperline = 0 ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_s_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_format * f )
{
2013-12-14 08:28:26 -03:00
struct saa7134_dev * dev = video_drvdata ( file ) ;
2015-04-09 04:05:59 -03:00
struct v4l2_subdev_format format = {
. which = V4L2_SUBDEV_FORMAT_ACTIVE ,
} ;
2005-04-16 15:20:36 -07:00
2015-04-09 04:05:59 -03:00
v4l2_fill_mbus_format ( & format . format , & f - > fmt . pix , MEDIA_BUS_FMT_FIXED ) ;
saa_call_all ( dev , pad , set_fmt , NULL , & format ) ;
v4l2_fill_pix_format ( & f - > fmt . pix , & format . format ) ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
2013-06-01 10:02:38 -03:00
f - > fmt . pix . bytesperline = 0 ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2009-05-28 01:58:57 -03:00
static int empress_try_fmt_vid_cap ( struct file * file , void * priv ,
struct v4l2_format * f )
{
2013-12-14 08:28:26 -03:00
struct saa7134_dev * dev = video_drvdata ( file ) ;
2015-04-09 04:05:35 -03:00
struct v4l2_subdev_pad_config pad_cfg ;
media: v4l2-subdev: add subdev-wide state struct
We have 'struct v4l2_subdev_pad_config' which contains configuration for
a single pad used for the TRY functionality, and an array of those
structs is passed to various v4l2_subdev_pad_ops.
I was working on subdev internal routing between pads, and realized that
there's no way to add TRY functionality for routes, which is not pad
specific configuration. Adding a separate struct for try-route config
wouldn't work either, as e.g. set-fmt needs to know the try-route
configuration to propagate the settings.
This patch adds a new struct, 'struct v4l2_subdev_state' (which at the
moment only contains the v4l2_subdev_pad_config array) and the new
struct is used in most of the places where v4l2_subdev_pad_config was
used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config
are changed to instead take v4l2_subdev_state.
The changes to drivers/media/v4l2-core/v4l2-subdev.c and
include/media/v4l2-subdev.h were written by hand, and all the driver
changes were done with the semantic patch below. The spatch needs to be
applied to a select list of directories. I used the following shell
commands to apply the spatch:
dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media"
for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done
Note that Coccinelle chokes on a few drivers (gcc extensions?). With
minor changes we can make Coccinelle run fine, and these changes can be
reverted after spatch. The diff for these changes is:
For drivers/media/i2c/s5k5baf.c:
@@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
&s5k5baf_cis_rect,
v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
- v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
+ v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT),
};
s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
return 0;
For drivers/media/platform/s3c-camif/camif-capture.c:
@@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
*mf = camif->mbus_fmt;
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* crop rectangle at camera interface input */
mf->width = camif->camif_crop.width;
mf->height = camif->camif_crop.height;
@@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
}
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* Pixel format can be only changed on the sink pad. */
mf->code = camif->mbus_fmt.code;
mf->width = crop->width;
The semantic patch is:
// <smpl>
// Change function parameter
@@
identifier func;
identifier cfg;
@@
func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...)
{
<...
- cfg
+ sd_state
...>
}
// Change function declaration parameter
@@
identifier func;
identifier cfg;
type T;
@@
T func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...);
// Change function return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...)
{
...
}
// Change function declaration return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...);
// Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it
// inside a pad_state.
@@
identifier func;
identifier pad_cfg;
@@
func(...)
{
...
struct v4l2_subdev_pad_config pad_cfg;
+ struct v4l2_subdev_state pad_state = { .pads = &pad_cfg };
<+...
(
v4l2_subdev_call
|
sensor_call
|
isi_try_fse
|
isc_try_fse
|
saa_call_all
)
(...,
- &pad_cfg
+ &pad_state
,...)
...+>
}
// If the function uses fields from pad_config, access via state->pads
@@
identifier func;
identifier state;
@@
func(...,
struct v4l2_subdev_state *state
, ...)
{
<...
(
- state->try_fmt
+ state->pads->try_fmt
|
- state->try_crop
+ state->pads->try_crop
|
- state->try_compose
+ state->pads->try_compose
)
...>
}
// If the function accesses the filehandle, use fh->state instead
@@
struct v4l2_subdev_fh *fh;
@@
- fh->pad
+ fh->state
@@
struct v4l2_subdev_fh fh;
@@
- fh.pad
+ fh.state
// Start of vsp1 specific
@@
@@
struct vsp1_entity {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
};
@@
symbol entity;
@@
vsp1_entity_init(...)
{
...
entity->config =
- v4l2_subdev_alloc_pad_config
+ v4l2_subdev_alloc_state
(&entity->subdev);
...
}
@@
symbol entity;
@@
vsp1_entity_destroy(...)
{
...
- v4l2_subdev_free_pad_config
+ v4l2_subdev_free_state
(entity->config);
...
}
@exists@
identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)";
symbol config;
@@
func(...) {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
}
// End of vsp1 specific
// Start of rcar specific
@@
identifier sd;
identifier pad_cfg;
@@
rvin_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
// End of rcar specific
// Start of rockchip specific
@@
identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)";
symbol rsz;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = rsz->pad_cfg };
...
- rsz->pad_cfg
+ &state
...
}
@@
identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)";
symbol isp;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = isp->pad_cfg };
...
- isp->pad_cfg
+ &state
...
}
@@
symbol rkisp1;
symbol isp;
symbol pad_cfg;
@@
rkisp1_isp_register(...)
{
+ struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg };
...
- rkisp1->isp.pad_cfg
+ &state
...
}
// End of rockchip specific
// Start of tegra-video specific
@@
identifier sd;
identifier pad_cfg;
@@
__tegra_channel_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
@@
identifier sd_state;
@@
__tegra_channel_try_format(...)
{
...
struct v4l2_subdev_state *sd_state;
<...
- sd_state->try_crop
+ sd_state->pads->try_crop
...>
}
// End of tegra-video specific
// </smpl>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-06-10 17:55:58 +03:00
struct v4l2_subdev_state pad_state = {
2023-02-15 17:24:57 +02:00
. pads = & pad_cfg ,
} ;
2015-04-09 04:05:35 -03:00
struct v4l2_subdev_format format = {
. which = V4L2_SUBDEV_FORMAT_TRY ,
} ;
2013-06-01 10:02:38 -03:00
2015-04-09 04:05:35 -03:00
v4l2_fill_mbus_format ( & format . format , & f - > fmt . pix , MEDIA_BUS_FMT_FIXED ) ;
media: v4l2-subdev: add subdev-wide state struct
We have 'struct v4l2_subdev_pad_config' which contains configuration for
a single pad used for the TRY functionality, and an array of those
structs is passed to various v4l2_subdev_pad_ops.
I was working on subdev internal routing between pads, and realized that
there's no way to add TRY functionality for routes, which is not pad
specific configuration. Adding a separate struct for try-route config
wouldn't work either, as e.g. set-fmt needs to know the try-route
configuration to propagate the settings.
This patch adds a new struct, 'struct v4l2_subdev_state' (which at the
moment only contains the v4l2_subdev_pad_config array) and the new
struct is used in most of the places where v4l2_subdev_pad_config was
used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config
are changed to instead take v4l2_subdev_state.
The changes to drivers/media/v4l2-core/v4l2-subdev.c and
include/media/v4l2-subdev.h were written by hand, and all the driver
changes were done with the semantic patch below. The spatch needs to be
applied to a select list of directories. I used the following shell
commands to apply the spatch:
dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media"
for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done
Note that Coccinelle chokes on a few drivers (gcc extensions?). With
minor changes we can make Coccinelle run fine, and these changes can be
reverted after spatch. The diff for these changes is:
For drivers/media/i2c/s5k5baf.c:
@@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
&s5k5baf_cis_rect,
v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
- v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
+ v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT),
};
s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
return 0;
For drivers/media/platform/s3c-camif/camif-capture.c:
@@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
*mf = camif->mbus_fmt;
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* crop rectangle at camera interface input */
mf->width = camif->camif_crop.width;
mf->height = camif->camif_crop.height;
@@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
}
break;
- case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
+ case CAMIF_SD_PAD_SOURCE_C:
/* Pixel format can be only changed on the sink pad. */
mf->code = camif->mbus_fmt.code;
mf->width = crop->width;
The semantic patch is:
// <smpl>
// Change function parameter
@@
identifier func;
identifier cfg;
@@
func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...)
{
<...
- cfg
+ sd_state
...>
}
// Change function declaration parameter
@@
identifier func;
identifier cfg;
type T;
@@
T func(...,
- struct v4l2_subdev_pad_config *cfg
+ struct v4l2_subdev_state *sd_state
, ...);
// Change function return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...)
{
...
}
// Change function declaration return value
@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
*func(...);
// Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it
// inside a pad_state.
@@
identifier func;
identifier pad_cfg;
@@
func(...)
{
...
struct v4l2_subdev_pad_config pad_cfg;
+ struct v4l2_subdev_state pad_state = { .pads = &pad_cfg };
<+...
(
v4l2_subdev_call
|
sensor_call
|
isi_try_fse
|
isc_try_fse
|
saa_call_all
)
(...,
- &pad_cfg
+ &pad_state
,...)
...+>
}
// If the function uses fields from pad_config, access via state->pads
@@
identifier func;
identifier state;
@@
func(...,
struct v4l2_subdev_state *state
, ...)
{
<...
(
- state->try_fmt
+ state->pads->try_fmt
|
- state->try_crop
+ state->pads->try_crop
|
- state->try_compose
+ state->pads->try_compose
)
...>
}
// If the function accesses the filehandle, use fh->state instead
@@
struct v4l2_subdev_fh *fh;
@@
- fh->pad
+ fh->state
@@
struct v4l2_subdev_fh fh;
@@
- fh.pad
+ fh.state
// Start of vsp1 specific
@@
@@
struct vsp1_entity {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
};
@@
symbol entity;
@@
vsp1_entity_init(...)
{
...
entity->config =
- v4l2_subdev_alloc_pad_config
+ v4l2_subdev_alloc_state
(&entity->subdev);
...
}
@@
symbol entity;
@@
vsp1_entity_destroy(...)
{
...
- v4l2_subdev_free_pad_config
+ v4l2_subdev_free_state
(entity->config);
...
}
@exists@
identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)";
symbol config;
@@
func(...) {
...
- struct v4l2_subdev_pad_config *config;
+ struct v4l2_subdev_state *config;
...
}
// End of vsp1 specific
// Start of rcar specific
@@
identifier sd;
identifier pad_cfg;
@@
rvin_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
// End of rcar specific
// Start of rockchip specific
@@
identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)";
symbol rsz;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = rsz->pad_cfg };
...
- rsz->pad_cfg
+ &state
...
}
@@
identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)";
symbol isp;
symbol pad_cfg;
@@
func(...)
{
+ struct v4l2_subdev_state state = { .pads = isp->pad_cfg };
...
- isp->pad_cfg
+ &state
...
}
@@
symbol rkisp1;
symbol isp;
symbol pad_cfg;
@@
rkisp1_isp_register(...)
{
+ struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg };
...
- rkisp1->isp.pad_cfg
+ &state
...
}
// End of rockchip specific
// Start of tegra-video specific
@@
identifier sd;
identifier pad_cfg;
@@
__tegra_channel_try_format(...)
{
...
- struct v4l2_subdev_pad_config *pad_cfg;
+ struct v4l2_subdev_state *sd_state;
...
- pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+ sd_state = v4l2_subdev_alloc_state(sd);
<...
- pad_cfg
+ sd_state
...>
- v4l2_subdev_free_pad_config(pad_cfg);
+ v4l2_subdev_free_state(sd_state);
...
}
@@
identifier sd_state;
@@
__tegra_channel_try_format(...)
{
...
struct v4l2_subdev_state *sd_state;
<...
- sd_state->try_crop
+ sd_state->pads->try_crop
...>
}
// End of tegra-video specific
// </smpl>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-06-10 17:55:58 +03:00
saa_call_all ( dev , pad , set_fmt , & pad_state , & format ) ;
2015-04-09 04:05:35 -03:00
v4l2_fill_pix_format ( & f - > fmt . pix , & format . format ) ;
2009-05-28 01:58:57 -03:00
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
2013-06-01 10:02:38 -03:00
f - > fmt . pix . bytesperline = 0 ;
2009-05-28 01:58:57 -03:00
return 0 ;
}
2007-12-11 12:56:23 -03:00
2008-12-30 06:58:20 -03:00
static const struct v4l2_file_operations ts_fops =
2005-04-16 15:20:36 -07:00
{
. owner = THIS_MODULE ,
2014-04-17 07:30:53 -03:00
. open = v4l2_fh_open ,
. release = vb2_fop_release ,
. read = vb2_fop_read ,
. poll = vb2_fop_poll ,
. mmap = vb2_fop_mmap ,
2014-06-16 04:32:37 -03:00
. unlocked_ioctl = video_ioctl2 ,
2005-04-16 15:20:36 -07:00
} ;
2008-07-21 02:57:38 -03:00
static const struct v4l2_ioctl_ops ts_ioctl_ops = {
2013-12-14 08:28:25 -03:00
. vidioc_querycap = saa7134_querycap ,
2008-05-28 12:16:41 -03:00
. vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap ,
2009-05-28 01:58:57 -03:00
. vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap ,
2008-05-28 12:16:41 -03:00
. vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap ,
. vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap ,
2014-04-17 07:30:53 -03:00
. vidioc_reqbufs = vb2_ioctl_reqbufs ,
. vidioc_querybuf = vb2_ioctl_querybuf ,
. vidioc_qbuf = vb2_ioctl_qbuf ,
. vidioc_dqbuf = vb2_ioctl_dqbuf ,
2015-12-14 08:17:00 -02:00
. vidioc_expbuf = vb2_ioctl_expbuf ,
2014-04-17 07:30:53 -03:00
. vidioc_streamon = vb2_ioctl_streamon ,
. vidioc_streamoff = vb2_ioctl_streamoff ,
2013-12-14 08:28:25 -03:00
. vidioc_g_frequency = saa7134_g_frequency ,
. vidioc_s_frequency = saa7134_s_frequency ,
. vidioc_g_tuner = saa7134_g_tuner ,
. vidioc_s_tuner = saa7134_s_tuner ,
. vidioc_enum_input = saa7134_enum_input ,
. vidioc_g_input = saa7134_g_input ,
. vidioc_s_input = saa7134_s_input ,
. vidioc_s_std = saa7134_s_std ,
. vidioc_g_std = saa7134_g_std ,
2014-04-01 09:28:17 -03:00
. vidioc_querystd = saa7134_querystd ,
2013-12-14 08:28:28 -03:00
. vidioc_log_status = v4l2_ctrl_log_status ,
. vidioc_subscribe_event = v4l2_ctrl_subscribe_event ,
. vidioc_unsubscribe_event = v4l2_event_unsubscribe ,
2008-07-21 02:57:38 -03:00
} ;
/* ----------------------------------------------------------- */
2017-08-26 09:08:11 -04:00
static const struct video_device saa7134_empress_template = {
2008-07-21 02:57:38 -03:00
. name = " saa7134-empress " ,
. fops = & ts_fops ,
. ioctl_ops = & ts_ioctl_ops ,
2007-12-11 12:56:23 -03:00
. tvnorms = SAA7134_NORMS ,
2005-04-16 15:20:36 -07:00
} ;
2006-11-22 14:57:56 +00:00
static void empress_signal_update ( struct work_struct * work )
2005-04-16 15:20:36 -07:00
{
2006-11-22 14:57:56 +00:00
struct saa7134_dev * dev =
container_of ( work , struct saa7134_dev , empress_workqueue ) ;
2005-04-16 15:20:36 -07:00
if ( dev - > nosignal ) {
2015-04-30 07:12:19 -03:00
pr_debug ( " no video signal \n " ) ;
2005-04-16 15:20:36 -07:00
} else {
2015-04-30 07:12:19 -03:00
pr_debug ( " video signal acquired \n " ) ;
2005-04-16 15:20:36 -07:00
}
}
static void empress_signal_change ( struct saa7134_dev * dev )
{
schedule_work ( & dev - > empress_workqueue ) ;
}
2013-12-14 08:28:24 -03:00
static bool empress_ctrl_filter ( const struct v4l2_ctrl * ctrl )
{
switch ( ctrl - > id ) {
case V4L2_CID_BRIGHTNESS :
case V4L2_CID_HUE :
case V4L2_CID_CONTRAST :
case V4L2_CID_SATURATION :
case V4L2_CID_AUDIO_MUTE :
case V4L2_CID_AUDIO_VOLUME :
case V4L2_CID_PRIVATE_INVERT :
case V4L2_CID_PRIVATE_AUTOMUTE :
return true ;
default :
return false ;
}
}
2005-04-16 15:20:36 -07:00
static int empress_init ( struct saa7134_dev * dev )
{
2013-12-14 08:28:24 -03:00
struct v4l2_ctrl_handler * hdl = & dev - > empress_ctrl_handler ;
2014-04-17 07:30:53 -03:00
struct vb2_queue * q ;
2005-04-16 15:20:36 -07:00
int err ;
2015-05-13 14:09:42 -03:00
pr_debug ( " %s: %s \n " , dev - > name , __func__ ) ;
2005-04-16 15:20:36 -07:00
dev - > empress_dev = video_device_alloc ( ) ;
if ( NULL = = dev - > empress_dev )
return - ENOMEM ;
* ( dev - > empress_dev ) = saa7134_empress_template ;
2013-06-20 10:57:10 -03:00
dev - > empress_dev - > v4l2_dev = & dev - > v4l2_dev ;
2005-04-16 15:20:36 -07:00
dev - > empress_dev - > release = video_device_release ;
2014-04-17 07:30:53 -03:00
dev - > empress_dev - > lock = & dev - > lock ;
2005-04-16 15:20:36 -07:00
snprintf ( dev - > empress_dev - > name , sizeof ( dev - > empress_dev - > name ) ,
" %s empress (%s) " , dev - > name ,
saa7134_boards [ dev - > board ] . name ) ;
2013-12-14 08:28:24 -03:00
v4l2_ctrl_handler_init ( hdl , 21 ) ;
2018-05-21 04:54:36 -04:00
v4l2_ctrl_add_handler ( hdl , & dev - > ctrl_handler , empress_ctrl_filter , false ) ;
2013-12-14 08:28:24 -03:00
if ( dev - > empress_sd )
2018-05-21 04:54:36 -04:00
v4l2_ctrl_add_handler ( hdl , dev - > empress_sd - > ctrl_handler , NULL , true ) ;
2013-12-14 08:28:24 -03:00
if ( hdl - > error ) {
video_device_release ( dev - > empress_dev ) ;
return hdl - > error ;
}
dev - > empress_dev - > ctrl_handler = hdl ;
2005-04-16 15:20:36 -07:00
2006-11-22 14:57:56 +00:00
INIT_WORK ( & dev - > empress_workqueue , empress_signal_update ) ;
2005-04-16 15:20:36 -07:00
2014-04-17 07:30:53 -03:00
q = & dev - > empress_vbq ;
q - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
/*
* Do not add VB2_USERPTR : the saa7134 DMA engine cannot handle
* transfers that do not start at the beginning of a page . A USERPTR
* can start anywhere in a page , so USERPTR support is a no - go .
*/
2015-12-14 08:17:00 -02:00
q - > io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ ;
2014-04-17 07:30:53 -03:00
q - > drv_priv = & dev - > ts_q ;
q - > ops = & saa7134_empress_qops ;
q - > gfp_flags = GFP_DMA32 ;
q - > mem_ops = & vb2_dma_sg_memops ;
q - > buf_struct_size = sizeof ( struct saa7134_buf ) ;
q - > timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC ;
q - > lock = & dev - > lock ;
2016-09-18 11:24:50 -03:00
q - > dev = & dev - > pci - > dev ;
2014-04-17 07:30:53 -03:00
err = vb2_queue_init ( q ) ;
2021-01-02 07:27:22 +01:00
if ( err ) {
video_device_release ( dev - > empress_dev ) ;
dev - > empress_dev = NULL ;
2014-04-17 07:30:53 -03:00
return err ;
2021-01-02 07:27:22 +01:00
}
2014-04-17 07:30:53 -03:00
dev - > empress_dev - > queue = q ;
2019-06-17 05:36:16 -04:00
dev - > empress_dev - > device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
V4L2_CAP_VIDEO_CAPTURE ;
if ( dev - > tuner_type ! = TUNER_ABSENT & & dev - > tuner_type ! = UNSET )
dev - > empress_dev - > device_caps | = V4L2_CAP_TUNER ;
2014-04-17 07:30:53 -03:00
2009-12-10 11:44:04 -02:00
video_set_drvdata ( dev - > empress_dev , dev ) ;
2020-02-03 12:41:17 +01:00
err = video_register_device ( dev - > empress_dev , VFL_TYPE_VIDEO ,
2005-04-16 15:20:36 -07:00
empress_nr [ dev - > nr ] ) ;
if ( err < 0 ) {
[media] saa7134: instead of using printk KERN_foo, use pr_foo
Replaces all occurrences of printk with KERN_INFO, KERN_WARNING
and KERN_ERR to pr_info/pr_warning, pr_err, using this small
shell script:
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_INFO ','pr_info(',g <$i >a && mv a $i; done
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_ERR ','pr_err(',g <$i >a && mv a $i; done
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_WARNING ','pr_warn(',g <$i >a && mv a $i; done
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2015-04-30 06:46:34 -03:00
pr_info ( " %s: can't register video device \n " ,
2005-04-16 15:20:36 -07:00
dev - > name ) ;
video_device_release ( dev - > empress_dev ) ;
dev - > empress_dev = NULL ;
return err ;
}
[media] saa7134: instead of using printk KERN_foo, use pr_foo
Replaces all occurrences of printk with KERN_INFO, KERN_WARNING
and KERN_ERR to pr_info/pr_warning, pr_err, using this small
shell script:
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_INFO ','pr_info(',g <$i >a && mv a $i; done
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_ERR ','pr_err(',g <$i >a && mv a $i; done
for i in drivers/media/pci/saa7134/*.[ch]; do sed s,'printk(KERN_WARNING ','pr_warn(',g <$i >a && mv a $i; done
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2015-04-30 06:46:34 -03:00
pr_info ( " %s: registered device %s [mpeg] \n " ,
2009-11-27 13:57:15 -03:00
dev - > name , video_device_node_name ( dev - > empress_dev ) ) ;
2005-04-16 15:20:36 -07:00
2006-11-22 14:57:56 +00:00
empress_signal_update ( & dev - > empress_workqueue ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
static int empress_fini ( struct saa7134_dev * dev )
{
2015-05-13 14:09:42 -03:00
pr_debug ( " %s: %s \n " , dev - > name , __func__ ) ;
2005-04-16 15:20:36 -07:00
if ( NULL = = dev - > empress_dev )
return 0 ;
2012-08-20 14:51:24 -07:00
flush_work ( & dev - > empress_workqueue ) ;
2020-07-13 13:30:44 +02:00
vb2_video_unregister_device ( dev - > empress_dev ) ;
2013-12-14 08:28:24 -03:00
v4l2_ctrl_handler_free ( & dev - > empress_ctrl_handler ) ;
2005-04-16 15:20:36 -07:00
dev - > empress_dev = NULL ;
return 0 ;
}
static struct saa7134_mpeg_ops empress_ops = {
. type = SAA7134_MPEG_EMPRESS ,
. init = empress_init ,
. fini = empress_fini ,
. signal_change = empress_signal_change ,
} ;
static int __init empress_register ( void )
{
return saa7134_ts_register ( & empress_ops ) ;
}
static void __exit empress_unregister ( void )
{
saa7134_ts_unregister ( & empress_ops ) ;
}
module_init ( empress_register ) ;
module_exit ( empress_unregister ) ;