162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * VIDEO MOTION CODECs internal API for video devices
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's
662306a36Sopenharmony_ci * bound to a master device.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * (c) 2002 Wolfgang Scherr <scherr@net4you.at>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* =================== */
1262306a36Sopenharmony_ci/* general description */
1362306a36Sopenharmony_ci/* =================== */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ci * Should ease the (re-)usage of drivers supporting cards with (different)
1762306a36Sopenharmony_ci * video codecs. The codecs register to this module their functionality,
1862306a36Sopenharmony_ci * and the processors (masters) can attach to them if they fit.
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci * The codecs are typically have a "strong" binding to their master - so I
2162306a36Sopenharmony_ci * don't think it makes sense to have a full blown interfacing as with e.g.
2262306a36Sopenharmony_ci * i2c. If you have an other opinion, let's discuss & implement it :-)))
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Usage:
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * The slave has just to setup the videocodec structure and use two functions:
2762306a36Sopenharmony_ci * videocodec_register(codecdata);
2862306a36Sopenharmony_ci * videocodec_unregister(codecdata);
2962306a36Sopenharmony_ci * The best is just calling them at module (de-)initialisation.
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci * The master sets up the structure videocodec_master and calls:
3262306a36Sopenharmony_ci * codecdata=videocodec_attach(master_codecdata);
3362306a36Sopenharmony_ci * videocodec_detach(codecdata);
3462306a36Sopenharmony_ci *
3562306a36Sopenharmony_ci * The slave is called during attach/detach via functions setup previously
3662306a36Sopenharmony_ci * during register. At that time, the master_data pointer is set up
3762306a36Sopenharmony_ci * and the slave can access any io registers of the master device (in the case
3862306a36Sopenharmony_ci * the slave is bound to it). Otherwise it doesn't need this functions and
3962306a36Sopenharmony_ci * therefor they may not be initialized.
4062306a36Sopenharmony_ci *
4162306a36Sopenharmony_ci * The other functions are just for convenience, as they are for sure used by
4262306a36Sopenharmony_ci * most/all of the codecs. The last ones may be omitted, too.
4362306a36Sopenharmony_ci *
4462306a36Sopenharmony_ci * See the structure declaration below for more information and which data has
4562306a36Sopenharmony_ci * to be set up for the master and the slave.
4662306a36Sopenharmony_ci *
4762306a36Sopenharmony_ci * ----------------------------------------------------------------------------
4862306a36Sopenharmony_ci * The master should have "knowledge" of the slave and vice versa.  So the data
4962306a36Sopenharmony_ci * structures sent to/from slave via set_data/get_data set_image/get_image are
5062306a36Sopenharmony_ci * device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!)
5162306a36Sopenharmony_ci * ----------------------------------------------------------------------------
5262306a36Sopenharmony_ci */
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* ========================================== */
5562306a36Sopenharmony_ci/* description of the videocodec_io structure */
5662306a36Sopenharmony_ci/* ========================================== */
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/*
5962306a36Sopenharmony_ci * ==== master setup ====
6062306a36Sopenharmony_ci * name -> name of the device structure for reference and debugging
6162306a36Sopenharmony_ci * master_data ->  data ref. for the master (e.g. the zr36055,57,67)
6262306a36Sopenharmony_ci * readreg -> ref. to read-fn from register (setup by master, used by slave)
6362306a36Sopenharmony_ci * writereg -> ref. to write-fn to register (setup by master, used by slave)
6462306a36Sopenharmony_ci *	       this two functions do the lowlevel I/O job
6562306a36Sopenharmony_ci *
6662306a36Sopenharmony_ci * ==== slave functionality setup ====
6762306a36Sopenharmony_ci * slave_data -> data ref. for the slave (e.g. the zr36050,60)
6862306a36Sopenharmony_ci * check -> fn-ref. checks availability of an device, returns -EIO on failure or
6962306a36Sopenharmony_ci *	    the type on success
7062306a36Sopenharmony_ci *	    this makes espcecially sense if a driver module supports more than
7162306a36Sopenharmony_ci *	    one codec which may be quite similar to access, nevertheless it
7262306a36Sopenharmony_ci *	    is good for a first functionality check
7362306a36Sopenharmony_ci *
7462306a36Sopenharmony_ci * -- main functions you always need for compression/decompression --
7562306a36Sopenharmony_ci *
7662306a36Sopenharmony_ci * set_mode -> this fn-ref. resets the entire codec, and sets up the mode
7762306a36Sopenharmony_ci *	       with the last defined norm/size (or device default if not
7862306a36Sopenharmony_ci *	       available) - it returns 0 if the mode is possible
7962306a36Sopenharmony_ci * set_size -> this fn-ref. sets the norm and image size for
8062306a36Sopenharmony_ci *	       compression/decompression (returns 0 on success)
8162306a36Sopenharmony_ci *	       the norm param is defined in videodev2.h (V4L2_STD_*)
8262306a36Sopenharmony_ci *
8362306a36Sopenharmony_ci * additional setup may be available, too - but the codec should work with
8462306a36Sopenharmony_ci * some default values even without this
8562306a36Sopenharmony_ci *
8662306a36Sopenharmony_ci * set_data -> sets device-specific data (tables, quality etc.)
8762306a36Sopenharmony_ci * get_data -> query device-specific data (tables, quality etc.)
8862306a36Sopenharmony_ci *
8962306a36Sopenharmony_ci * if the device delivers interrupts, they may be setup/handled here
9062306a36Sopenharmony_ci * setup_interrupt -> codec irq setup (not needed for 36050/60)
9162306a36Sopenharmony_ci * handle_interrupt -> codec irq handling (not needed for 36050/60)
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci * if the device delivers pictures, they may be handled here
9462306a36Sopenharmony_ci * put_image -> puts image data to the codec (not needed for 36050/60)
9562306a36Sopenharmony_ci * get_image -> gets image data from the codec (not needed for 36050/60)
9662306a36Sopenharmony_ci *		the calls include frame numbers and flags (even/odd/...)
9762306a36Sopenharmony_ci *		if needed and a flag which allows blocking until its ready
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* ============== */
10162306a36Sopenharmony_ci/* user interface */
10262306a36Sopenharmony_ci/* ============== */
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/*
10562306a36Sopenharmony_ci * Currently there is only a information display planned, as the layer
10662306a36Sopenharmony_ci * is not visible for the user space at all.
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci * Information is available via procfs. The current entry is "/proc/videocodecs"
10962306a36Sopenharmony_ci * but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--.
11062306a36Sopenharmony_ci *
11162306a36Sopenharmony_ci * A example for such an output is:
11262306a36Sopenharmony_ci *
11362306a36Sopenharmony_ci * <S>lave or attached <M>aster name  type flags    magic    (connected as)
11462306a36Sopenharmony_ci * S                          zr36050 0002 0000d001 00000000 (TEMPLATE)
11562306a36Sopenharmony_ci * M                       zr36055[0] 0001 0000c001 00000000 (zr36050[0])
11662306a36Sopenharmony_ci * M                       zr36055[1] 0001 0000c001 00000000 (zr36050[1])
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* =============================================== */
12062306a36Sopenharmony_ci/* special defines for the videocodec_io structure */
12162306a36Sopenharmony_ci/* =============================================== */
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#ifndef __LINUX_VIDEOCODEC_H
12462306a36Sopenharmony_ci#define __LINUX_VIDEOCODEC_H
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#include <linux/debugfs.h>
12762306a36Sopenharmony_ci#include <linux/videodev2.h>
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#define CODEC_DO_COMPRESSION 0
13062306a36Sopenharmony_ci#define CODEC_DO_EXPANSION   1
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/* this are the current codec flags I think they are needed */
13362306a36Sopenharmony_ci/*  -> type value in structure */
13462306a36Sopenharmony_ci#define CODEC_FLAG_JPEG      0x00000001L	// JPEG codec
13562306a36Sopenharmony_ci#define CODEC_FLAG_MPEG      0x00000002L	// MPEG1/2/4 codec
13662306a36Sopenharmony_ci#define CODEC_FLAG_DIVX      0x00000004L	// DIVX codec
13762306a36Sopenharmony_ci#define CODEC_FLAG_WAVELET   0x00000008L	// WAVELET codec
13862306a36Sopenharmony_ci					  // room for other types
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#define CODEC_FLAG_MAGIC     0x00000800L	// magic key must match
14162306a36Sopenharmony_ci#define CODEC_FLAG_HARDWARE  0x00001000L	// is a hardware codec
14262306a36Sopenharmony_ci#define CODEC_FLAG_VFE       0x00002000L	// has direct video frontend
14362306a36Sopenharmony_ci#define CODEC_FLAG_ENCODER   0x00004000L	// compression capability
14462306a36Sopenharmony_ci#define CODEC_FLAG_DECODER   0x00008000L	// decompression capability
14562306a36Sopenharmony_ci#define CODEC_FLAG_NEEDIRQ   0x00010000L	// needs irq handling
14662306a36Sopenharmony_ci#define CODEC_FLAG_RDWRPIC   0x00020000L	// handles picture I/O
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* a list of modes, some are just examples (is there any HW?) */
14962306a36Sopenharmony_ci#define CODEC_MODE_BJPG      0x0001	// Baseline JPEG
15062306a36Sopenharmony_ci#define CODEC_MODE_LJPG      0x0002	// Lossless JPEG
15162306a36Sopenharmony_ci#define CODEC_MODE_MPEG1     0x0003	// MPEG 1
15262306a36Sopenharmony_ci#define CODEC_MODE_MPEG2     0x0004	// MPEG 2
15362306a36Sopenharmony_ci#define CODEC_MODE_MPEG4     0x0005	// MPEG 4
15462306a36Sopenharmony_ci#define CODEC_MODE_MSDIVX    0x0006	// MS DivX
15562306a36Sopenharmony_ci#define CODEC_MODE_ODIVX     0x0007	// Open DivX
15662306a36Sopenharmony_ci#define CODEC_MODE_WAVELET   0x0008	// Wavelet
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci/* this are the current codec types I want to implement */
15962306a36Sopenharmony_ci/*  -> type value in structure */
16062306a36Sopenharmony_ci#define CODEC_TYPE_NONE    0
16162306a36Sopenharmony_ci#define CODEC_TYPE_L64702  1
16262306a36Sopenharmony_ci#define CODEC_TYPE_ZR36050 2
16362306a36Sopenharmony_ci#define CODEC_TYPE_ZR36016 3
16462306a36Sopenharmony_ci#define CODEC_TYPE_ZR36060 4
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci/* the type of data may be enhanced by future implementations (data-fn.'s) */
16762306a36Sopenharmony_ci/*  -> used in command                                                     */
16862306a36Sopenharmony_ci#define CODEC_G_STATUS         0x0000	/* codec status (query only) */
16962306a36Sopenharmony_ci#define CODEC_S_CODEC_MODE     0x0001	/* codec mode (baseline JPEG, MPEG1,... */
17062306a36Sopenharmony_ci#define CODEC_G_CODEC_MODE     0x8001
17162306a36Sopenharmony_ci#define CODEC_S_VFE            0x0002	/* additional video frontend setup */
17262306a36Sopenharmony_ci#define CODEC_G_VFE            0x8002
17362306a36Sopenharmony_ci#define CODEC_S_MMAP           0x0003	/* MMAP setup (if available) */
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci#define CODEC_S_JPEG_TDS_BYTE  0x0010	/* target data size in bytes */
17662306a36Sopenharmony_ci#define CODEC_G_JPEG_TDS_BYTE  0x8010
17762306a36Sopenharmony_ci#define CODEC_S_JPEG_SCALE     0x0011	/* scaling factor for quant. tables */
17862306a36Sopenharmony_ci#define CODEC_G_JPEG_SCALE     0x8011
17962306a36Sopenharmony_ci#define CODEC_S_JPEG_HDT_DATA  0x0018	/* huffman-tables */
18062306a36Sopenharmony_ci#define CODEC_G_JPEG_HDT_DATA  0x8018
18162306a36Sopenharmony_ci#define CODEC_S_JPEG_QDT_DATA  0x0019	/* quantizing-tables */
18262306a36Sopenharmony_ci#define CODEC_G_JPEG_QDT_DATA  0x8019
18362306a36Sopenharmony_ci#define CODEC_S_JPEG_APP_DATA  0x001A	/* APP marker */
18462306a36Sopenharmony_ci#define CODEC_G_JPEG_APP_DATA  0x801A
18562306a36Sopenharmony_ci#define CODEC_S_JPEG_COM_DATA  0x001B	/* COM marker */
18662306a36Sopenharmony_ci#define CODEC_G_JPEG_COM_DATA  0x801B
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci#define CODEC_S_PRIVATE        0x1000	/* "private" commands start here */
18962306a36Sopenharmony_ci#define CODEC_G_PRIVATE        0x9000
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci#define CODEC_G_FLAG           0x8000	/* this is how 'get' is detected */
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci/* types of transfer, directly user space or a kernel buffer (image-fn.'s) */
19462306a36Sopenharmony_ci/*  -> used in get_image, put_image */
19562306a36Sopenharmony_ci#define CODEC_TRANSFER_KERNEL 0	/* use "memcopy" */
19662306a36Sopenharmony_ci#define CODEC_TRANSFER_USER   1	/* use "to/from_user" */
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci/* ========================= */
19962306a36Sopenharmony_ci/* the structures itself ... */
20062306a36Sopenharmony_ci/* ========================= */
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistruct vfe_polarity {
20362306a36Sopenharmony_ci	unsigned int vsync_pol:1;
20462306a36Sopenharmony_ci	unsigned int hsync_pol:1;
20562306a36Sopenharmony_ci	unsigned int field_pol:1;
20662306a36Sopenharmony_ci	unsigned int blank_pol:1;
20762306a36Sopenharmony_ci	unsigned int subimg_pol:1;
20862306a36Sopenharmony_ci	unsigned int poe_pol:1;
20962306a36Sopenharmony_ci	unsigned int pvalid_pol:1;
21062306a36Sopenharmony_ci	unsigned int vclk_pol:1;
21162306a36Sopenharmony_ci};
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistruct vfe_settings {
21462306a36Sopenharmony_ci	__u32 x, y;		/* Offsets into image */
21562306a36Sopenharmony_ci	__u32 width, height;	/* Area to capture */
21662306a36Sopenharmony_ci	__u16 decimation;	/* Decimation divider */
21762306a36Sopenharmony_ci	__u16 flags;		/* Flags for capture */
21862306a36Sopenharmony_ci	__u16 quality;		/* quality of the video */
21962306a36Sopenharmony_ci};
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_cistruct tvnorm {
22262306a36Sopenharmony_ci	u16 wt, wa, h_start, h_sync_start, ht, ha, v_start;
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistruct jpeg_com_marker {
22662306a36Sopenharmony_ci	int len; /* number of usable bytes in data */
22762306a36Sopenharmony_ci	char data[60];
22862306a36Sopenharmony_ci};
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_cistruct jpeg_app_marker {
23162306a36Sopenharmony_ci	int appn; /* number app segment */
23262306a36Sopenharmony_ci	int len; /* number of usable bytes in data */
23362306a36Sopenharmony_ci	char data[60];
23462306a36Sopenharmony_ci};
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistruct videocodec {
23762306a36Sopenharmony_ci	/* -- filled in by slave device during register -- */
23862306a36Sopenharmony_ci	char name[32];
23962306a36Sopenharmony_ci	unsigned long magic;	/* may be used for client<->master attaching */
24062306a36Sopenharmony_ci	unsigned long flags;	/* functionality flags */
24162306a36Sopenharmony_ci	unsigned int type;	/* codec type */
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	/* -- these is filled in later during master device attach -- */
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci	struct videocodec_master *master_data;
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	/* -- these are filled in by the slave device during register -- */
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci	void *data;		/* private slave data */
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	/* attach/detach client functions (indirect call) */
25262306a36Sopenharmony_ci	int (*setup)(struct videocodec *codec);
25362306a36Sopenharmony_ci	int (*unset)(struct videocodec *codec);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/* main functions, every client needs them for sure! */
25662306a36Sopenharmony_ci	// set compression or decompression (or freeze, stop, standby, etc)
25762306a36Sopenharmony_ci	int (*set_mode)(struct videocodec *codec, int mode);
25862306a36Sopenharmony_ci	// setup picture size and norm (for the codec's video frontend)
25962306a36Sopenharmony_ci	int (*set_video)(struct videocodec *codec, const struct tvnorm *norm,
26062306a36Sopenharmony_ci			 struct vfe_settings *cap, struct vfe_polarity *pol);
26162306a36Sopenharmony_ci	// other control commands, also mmap setup etc.
26262306a36Sopenharmony_ci	int (*control)(struct videocodec *codec, int type, int size, void *data);
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	/* additional setup/query/processing (may be NULL pointer) */
26562306a36Sopenharmony_ci	// interrupt setup / handling (for irq's delivered by master)
26662306a36Sopenharmony_ci	int (*setup_interrupt)(struct videocodec *codec, long mode);
26762306a36Sopenharmony_ci	int (*handle_interrupt)(struct videocodec *codec, int source, long flag);
26862306a36Sopenharmony_ci	// picture interface (if any)
26962306a36Sopenharmony_ci	long (*put_image)(struct videocodec *codec, int tr_type, int block,
27062306a36Sopenharmony_ci			  long *fr_num, long *flag, long size, void *buf);
27162306a36Sopenharmony_ci	long (*get_image)(struct videocodec *codec, int tr_type, int block,
27262306a36Sopenharmony_ci			  long *fr_num, long *flag, long size, void *buf);
27362306a36Sopenharmony_ci};
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistruct videocodec_master {
27662306a36Sopenharmony_ci	/* -- filled in by master device for registration -- */
27762306a36Sopenharmony_ci	char name[32];
27862306a36Sopenharmony_ci	unsigned long magic;	/* may be used for client<->master attaching */
27962306a36Sopenharmony_ci	unsigned long flags;	/* functionality flags */
28062306a36Sopenharmony_ci	unsigned int type;	/* master type */
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	void *data;		/* private master data */
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	__u32 (*readreg)(struct videocodec *codec, __u16 reg);
28562306a36Sopenharmony_ci	void (*writereg)(struct videocodec *codec, __u16 reg, __u32 value);
28662306a36Sopenharmony_ci};
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/* ================================================= */
28962306a36Sopenharmony_ci/* function prototypes of the master/slave interface */
29062306a36Sopenharmony_ci/* ================================================= */
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci/* attach and detach commands for the master */
29362306a36Sopenharmony_ci// * master structure needs to be kmalloc'ed before calling attach
29462306a36Sopenharmony_ci//   and free'd after calling detach
29562306a36Sopenharmony_ci// * returns pointer on success, NULL on failure
29662306a36Sopenharmony_cistruct videocodec *videocodec_attach(struct videocodec_master *master);
29762306a36Sopenharmony_ci// * 0 on success, <0 (errno) on failure
29862306a36Sopenharmony_ciint videocodec_detach(struct videocodec *codec);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* register and unregister commands for the slaves */
30162306a36Sopenharmony_ci// * 0 on success, <0 (errno) on failure
30262306a36Sopenharmony_ciint videocodec_register(const struct videocodec *codec);
30362306a36Sopenharmony_ci// * 0 on success, <0 (errno) on failure
30462306a36Sopenharmony_ciint videocodec_unregister(const struct videocodec *codec);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/* the other calls are directly done via the videocodec structure! */
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciint videocodec_debugfs_show(struct seq_file *m);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci#include "zoran.h"
31162306a36Sopenharmony_cistatic inline struct zoran *videocodec_master_to_zoran(struct videocodec_master *master)
31262306a36Sopenharmony_ci{
31362306a36Sopenharmony_ci	struct zoran *zr = master->data;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	return zr;
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic inline struct zoran *videocodec_to_zoran(struct videocodec *codec)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	struct videocodec_master *master = codec->master_data;
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	return videocodec_master_to_zoran(master);
32362306a36Sopenharmony_ci}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci#endif				/*ifndef __LINUX_VIDEOCODEC_H */
326