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