From 75b63b6d43c650fa4878b2c1671956c657dd0108 Mon Sep 17 00:00:00 2001 From: cvs Date: Wed, 27 Sep 2000 14:54:19 -0300 Subject: Initial revision --- dvb-spec/README.CABLE | 5 +++ dvb-spec/README.EON | 7 ++++ dvb-spec/channel | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 dvb-spec/README.CABLE create mode 100644 dvb-spec/README.EON create mode 100644 dvb-spec/channel diff --git a/dvb-spec/README.CABLE b/dvb-spec/README.CABLE new file mode 100644 index 000000000..de13af020 --- /dev/null +++ b/dvb-spec/README.CABLE @@ -0,0 +1,5 @@ +- The analog module is not fully supported yet. + The MSP3400 module will have to be extended to handle then audio and + video switching for the module. + If you want sound you will have to remove the module for now. + diff --git a/dvb-spec/README.EON b/dvb-spec/README.EON new file mode 100644 index 000000000..df5098132 --- /dev/null +++ b/dvb-spec/README.EON @@ -0,0 +1,7 @@ +- If you do not receive any packets over the dvb0 device the reason could + be the rp_filter. + Check if your distribution enables this or disable it with: + + "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter" + + This disables source validation by reversed path lookup. \ No newline at end of file diff --git a/dvb-spec/channel b/dvb-spec/channel new file mode 100644 index 000000000..f17e8cb19 --- /dev/null +++ b/dvb-spec/channel @@ -0,0 +1,104 @@ +This file describes the format of the new channel config file. + +Comments start with # +Each section starts with one of the identifiers: LNB, DISEQC, ROTOR, ... + +IDs are either the official transponder, network, etc. id if it exists +and is unique, otherwise it is just a consecutive number assigned by +the application. +An LNB can also describe a cable TV outlet or a terrestrial antenna. +Names (as all parameters in brackets) are optional. In this case the +application should use the ID as name. + +The application should offer selection sorted by channel number, network, +satellite, bouquet. + + +# satellite definition +SAT + ID satid # ID = xxxy, sat is at position xxx.y degrees + [NAME name] + LNBID lnbid # LNB this sat is received with + [ROTORID rotorid] # rotor commands to position it on this sat + +# LNB definition +LNB + ID lnbid + [NAME name] + [INPUT input] # input of card which the lnb is connected to (default 0) + TYPE type # LNB, CATV or terrestrial antenna? + LOF1 offset1 # local oscillator frequency 1 + LOF2 offset2 # local oscillator frequency 2 + SLOF switchfreq # switching frequency + [DISEQCNR diseqcnr] # simple 2- or 4-switch DiSEqC + [DISEQCID diseqcid] + [INPUT input] + [SWITCHID switchid] + +# A transponder definition +TRANSPONDER + ID tpid + TYPE type # digital (DVB-S(1), C(2) or T(3)) or analog(0) ? + SATID satid + [NAME name] # if analog this is the channel name + FREQ freq + POL H/V + [QAM qam] # only needed if DVB-C + [SRATE sr] # only if DVB + [FEC fec] # only if DVB + [PICID picid] # picture attributes for all channels on this transponder + +# channel definition (only if DVB) +CHANNEL + ID channelid + [NAME name] + TPID tpid + TYPE type + PNR pnr + VPID vpid + APID apid + TPID tpid + [PMTPID pmtpid] + [PCRPID pcrpid] + [APID apid2 APID apid3 ... APID apidn] # more audio PIDs for several languages + [AC3PID ac3] + [NETWID networkid] + [BOUQID bouquetid] + [PICID picid] + +# network definition +NETWORK + ID nwid + [NAME name] + +# bouquet definition +BOUQUET + ID bqid + [NAME name] + + + +# These will be implemented later + +# DiSEqC command sequence +DISEQC + ID disid + [NAME name] + MESSAGE data1 [ ... datan ] BURST 0/1 END + [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] + +# DiSEqC switch +SWITCH + ID switchid + SWITCHID switchid # next "higher" switch + [NAME name] + MESSAGE data1 [ ... datan ] BURST 0/1 END + + +# DiSEqC rotor command sequence leading to a certain rotor position +ROTOR + ID rotid + POS degrees + MESSAGE data1 [ ... datan ] BURST 0/1 END + [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] + -- cgit v1.2.3 From 38d73cf52c0df17ed6f3c7c505e2ab06b04e3b2f Mon Sep 17 00:00:00 2001 From: cvs Date: Wed, 18 Oct 2000 20:20:47 -0200 Subject: added HTML documentation of new API --- dvb-spec/API/dvb_api.xml | 233 +++++++ dvb-spec/API/dvb_api/audio.h | 69 ++ dvb-spec/API/dvb_api/audio.xml | 571 +++++++++++++++++ dvb-spec/API/dvb_api/demux.h | 295 +++++++++ dvb-spec/API/dvb_api/demux.xml | 568 +++++++++++++++++ dvb-spec/API/dvb_api/demux_mod.xml | 1215 ++++++++++++++++++++++++++++++++++++ dvb-spec/API/dvb_api/dmx.h | 130 ++++ dvb-spec/API/dvb_api/frontend.h | 96 +++ dvb-spec/API/dvb_api/frontend.xml | 843 +++++++++++++++++++++++++ dvb-spec/API/dvb_api/sec.h | 116 ++++ dvb-spec/API/dvb_api/sec.xml | 430 +++++++++++++ dvb-spec/API/dvb_api/video.h | 95 +++ dvb-spec/API/dvb_api/video.xml | 666 ++++++++++++++++++++ 13 files changed, 5327 insertions(+) create mode 100644 dvb-spec/API/dvb_api.xml create mode 100644 dvb-spec/API/dvb_api/audio.h create mode 100644 dvb-spec/API/dvb_api/audio.xml create mode 100644 dvb-spec/API/dvb_api/demux.h create mode 100644 dvb-spec/API/dvb_api/demux.xml create mode 100644 dvb-spec/API/dvb_api/demux_mod.xml create mode 100644 dvb-spec/API/dvb_api/dmx.h create mode 100644 dvb-spec/API/dvb_api/frontend.h create mode 100644 dvb-spec/API/dvb_api/frontend.xml create mode 100644 dvb-spec/API/dvb_api/sec.h create mode 100644 dvb-spec/API/dvb_api/sec.xml create mode 100644 dvb-spec/API/dvb_api/video.h create mode 100644 dvb-spec/API/dvb_api/video.xml diff --git a/dvb-spec/API/dvb_api.xml b/dvb-spec/API/dvb_api.xml new file mode 100644 index 000000000..bd2302551 --- /dev/null +++ b/dvb-spec/API/dvb_api.xml @@ -0,0 +1,233 @@ + + + linuxtv.org|Linux DVB API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

Linux DVB API

+ +

+ Part of the DVB API builds upon the + Video4Linux + (V4L) API. + The Siemens DVB card uses the SAA7146 as PCI bridge. A generic SAA7146 Linux driver for this + chip implements the basic V4L interface. +

+ +

+ An older version of the API included the DVB specific calls + into the V4L interface. This turned out to be very cumbersome to + program. Since we also hoped to arrive at a common standard for all + Linux platforms, especially those in embedded consumer devices, we + were happy to find + Nokia + as a partner in this effort. + They will be using the same API in their upcoming + + Media Terminal. +

+ +

+ In the new version of the API only display and grabbing of the + already decompressed images is handled through the V4L device. + All other DVB features like tuning, filtering and playback/recording + of the compressed data stream are accessed through separate devices. +

+ +

+ DVB devices + +

+ There are currently 5 DVB devices: Video, Audio, Frontend, SEC and Demux. + The APIs of those devices are described in the documents below. + They contain links to the include files and to detailed descriptions + of all commands (the latter are still under construction). +

+ +

+ DVB Video API +

+ +

+ DVB Audio API +

+ +

+ DVB Frontend API +

+ +

+ DVB SEC API +

+ +

+ DVB Demux API +

+ +

+ + +

+ DVB Demux Kernel Module + +

+ The demux device accesses the actual demux hardware through a + demux kernel module. + This way other kernel modules (e.g. a generic DVB network device) + and not only the demux device can access the demux hardware. +

+ +

+ DVB Demux Kernel Module API +

+ +

+ + +

+ First implementations of the API for the Siemens DVB card will be made + available in the download section during September 2000. +

+ +
+ + diff --git a/dvb-spec/API/dvb_api/audio.h b/dvb-spec/API/dvb_api/audio.h new file mode 100644 index 000000000..8a98f2f98 --- /dev/null +++ b/dvb-spec/API/dvb_api/audio.h @@ -0,0 +1,69 @@ +/* + * audio.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_AUDIO_H_ +#define _OST_AUDIO_H_ + +#define boolean int +#define true 1 +#define false 0 + +typedef enum { + AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ + AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */ +} audioStreamSource_t; + +typedef enum { + AUDIO_STOPPED, /* Device is stopped */ + AUDIO_PLAYING, /* Device is currently playing */ + AUDIO_PAUSED /* Device is paused */ +} audioPlayState_t; + +typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, +} audioChannelSelect_t; + +struct audioStatus { + boolean AVSyncState; + boolean muteState; + audioPlayState_t playState; + audioStreamSource_t streamSource; + audioChannelSelect_t channelSelect; + boolean bypassMode; +}; + + +#define AUDIO_STOP _IOW('o',1,void) +#define AUDIO_PLAY _IOW('o',2,void) +#define AUDIO_PAUSE _IOW('o',3,void) +#define AUDIO_CONTINUE _IOW('o',4,void) +#define AUDIO_SELECT_SOURCE _IOW('o',5,audioStreamSource_t) +#define AUDIO_SET_MUTE _IOW('o',6,boolean) +#define AUDIO_SET_AV_SYNC _IOW('o',7,boolean) +#define AUDIO_SET_BYPASS_MODE _IOW('o',8,boolean) +#define AUDIO_CHANNEL_SELECT _IOW('o',9,audioChannelSelect_t) +#define AUDIO_GET_STATUS _IOR('o',10,struct audioStatus *) + +#endif /* _OST_AUDIO_H_ */ diff --git a/dvb-spec/API/dvb_api/audio.xml b/dvb-spec/API/dvb_api/audio.xml new file mode 100644 index 000000000..4d6f31575 --- /dev/null +++ b/dvb-spec/API/dvb_api/audio.xml @@ -0,0 +1,571 @@ + + + linuxtv.org|DVB Audio API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB Audio API

+ +

+ The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. + It can be accessed through /dev/ost/audio. +

+ +

+ The function calls defined in the include file + audio.h are described in detail below: +

+

+ Audio API IO control calls + + +

+

+
+int open(const char *deviceName, int flags);
+
+    DESCRIPTION
+    
+	This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent
+        use. When an open() call has succeeded, the device will be ready for use.
+        The significance of blocking or non-blocking mode is described in the 
+	documentation for functions where there is a difference. It does not affect 
+	the semantics of the open() call itself. A device opened in blocking mode can
+	later be put into non-blocking mode (and vice versa) using the F_SETFL command
+	of the fcntl system call.  This is a standard system call, documented in the 
+	Linux manual page for fcntl.
+        Only one user can open the Audio  Device in O_RDWR mode. All other attempts to
+        open the device in this mode will fail, and an errorcode will be returned.
+        If the Audio Device is opened in O_RDONLY mode, the only ioctl call that can 
+	be used is AUDIO_GET_STATUS. All other call will return with an error code.
+
+
+    PARAMETERS
+
+	const char *deviceName		Name of specific audio device.
+
+	int flags           		A bit-wise OR of the following flags:
+                                        
+					O_RDONLY read-only access
+
+                                        O_RDWR read/write access
+
+                                        O_NONBLOCK open in non-blocking mode
+                                                   (blocking mode is the default)
+
+    RETURNS
+
+	ENODEV                          Device driver not loaded/available.
+
+	EINTERNAL			Internal error
+
+        EBUSY                           Device or resource busy.
+
+        EINVAL                          Invalid argument.
+
+
+
+
+

+ +

+

+
+int close(int fd);
+
+    DESCRIPTION
+	
+	This system call closes a previously opened audio device
+
+    PARAMETERS
+	
+	int fd			File descriptor returned by a previous call to open().
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+size_t write(int fd, const void *buf, size_t count);
+
+    DESCRIPTION
+
+	This system call can only be used if AUDIO_SOURCE_MEMORY is selected in the 
+	ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in PES format.
+        If O_NONBLOCK is not specified the function will block until buffer space is
+	available. The amount of data to be transferred is implied by count.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	void *buf		Pointer to the buffer containing the PES data.
+
+	size_t count		Size of buf.
+
+    RETURNS
+
+	EPERM			Mode VIDEO_SOURCE_INTERNAL not selected.
+
+	ENOMEM			Attempted to write more data than the internal
+                                buffer can hold.
+
+	EBADF			fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_STOP);
+
+    DESCRIPTION
+
+	This ioctl call asks the Audio Device to stop playing the current stream.
+
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request             Equals AUDIO_STOP for this command.
+
+    RETURNS
+
+	EBADF                   fd is not a valid open file descriptor
+
+	EINTERNAL		Internal error
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_PLAY);
+
+    DESCRIPTION
+
+	This ioctl call asks the Audio Device to start playing an audio stream from the
+        selected source.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_PLAY for this command.
+
+    RETURNS
+	
+        EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL               Internal error
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_PAUSE);
+
+    DESCRIPTION
+
+	This ioctl call suspends the audio stream being played. Decoding and playing are
+	paused. It is then possible to restart again decoding and playing process of the
+        audio stream using AUDIO_CONTINUE command.
+        If  AUDIO_SOURCE_MEMORY is selected in the ioctl call AUDIO_SELECT_SOURCE, the
+        DVB-subsystem will not decode (consume) any more data until the ioctl  call
+        AUDIO_CONTINUE or AUDIO_PLAY is performed.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_PAUSE for this command.
+
+    RETURNS
+           
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_CONTINUE);
+
+    DESCRIPTION
+
+	This ioctl call restarts decoding and playing processes of the audio stream,
+	 which was played before, a call to AUDIO_PAUSE was made.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_CONTINUE for this command.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL               Internal error, possibly in the communication
+                                with the DVB subsystem.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_SELECT_SOURCE, audioStreamSource_t source);
+
+    DESCRIPTION
+
+	This ioctl call informs the audio device which source shall be used for the 
+	input data. The possible sources are demux or memory. If AUDIO_SOURCE_MEMORY 
+	is selected, the data is fed to the Audio Device through the write command.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_SELECT_SOURCE for this command.
+
+	audioStreamSource_t source	Indicates the source that shall be used for the
+             			        Audio stream.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_SET_MUTE, boolean state);
+
+    DESCRIPTION
+    
+	This ioctl call asks the audio device to mute the stream that is currently being
+        played.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_SET_MUTE for this command.
+
+	boolean state		Indicates if audio device shall mute or not.
+                                TRUE     Audio Mute
+                                FALSE   Audio Unmute
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error,
+
+        EINVAL                  Illegal input parameter.
+
+
+

+ +

+

+int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, boolean state);
+
+    DESCRIPTION
+
+	This ioctl call asks the Audio Device to turn ON or OFF A/V synchronisation.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_AV_SYNC for this command.
+
+	boolean state		Tells the DVB subsystem if A/V synchronisation shall be ON or OFF.
+                                TRUE    AV-sync ON
+                                FALSE  AV-sync OFF
+
+    RETURNS
+
+    	EBADF			fd is not a valid open file descriptor.
+        
+	EINTERNAL		Internal error
+
+	EINVAL                                  Illegal input parameter.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, boolean mode);
+
+    DESCRIPTION
+
+	This ioctl call asks the Audio Device to bypass the Audio decoder and forward
+	the stream without decoding. This mode shall be used if streams that can't be
+	handled by the DVB system shall be decoded. Dolby DigitalTM streams are 
+	automatically forwarded by the DVB subsystem.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_SET_BYPASS_MODE for this command.
+
+	boolean mode		Enables or disables the decoding of the current
+                                Audio stream in the DVB subsystem.
+                                TRUE    Bypass is disabled
+                                FALSE  Bypass is enabled
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+        
+	EINTERNAL               Internal error
+
+        EINVAL                  Illegal pointer mode.
+
+
+
+

+ +

+

+int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT, audioChannelSelect_t)
+
+    DESCRIPTION
+    
+	This ioctl call asks the Audio Device to select the requested channel if possible.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals AUDIO_CHANNEL_SELECT for this command.
+
+	audioChannelSelect_t ch Select the output format of the audio (Mono, stereo)
+
+    RETURNS
+	
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+        EINVAL			Illegal pointer ch.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = AUDIO_GET_STATUS, struct audioStatus *status)
+
+    DESCRIPTION
+
+	This ioctl call asks the Audio Device to return the current state of the Audio
+	Device.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+        int request		Equals AUDIO_GET_STATUS for this command.
+
+        struct audioStatus *status 	Returns the current state of Audio Device
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+        EFAULT			status points to invalid address
+
+
+
+
+

+ +

+
+ + diff --git a/dvb-spec/API/dvb_api/demux.h b/dvb-spec/API/dvb_api/demux.h new file mode 100644 index 000000000..62cbf0a58 --- /dev/null +++ b/dvb-spec/API/dvb_api/demux.h @@ -0,0 +1,295 @@ +/* * demux.h * * Copyright (c) 2000 Nokia Research Center + * Tampere, FINLAND + * + * Project: + * Universal Broadcast Access + * + * Contains: + * Type definitions of a Linux kernel-level API for filtering MPEG-2 TS + * packets and MPEG-2 sections. Support for PES packet filtering will be + * added later. + * + * History: + * 12.01.2000/JPL File created - Initial version. + * 18.02.2000/JPL Minor corrections. + * 21.02.2000/JPL DMX_NAME_SIZE and dmx_in_use() removed, typos fixed, + * some names changed. + * 23.02.2000/JPL Added a parameter indicating the callback source in + * the callback functions. + * 10.03.2000/JPL Added the macros DMX_DIR_ENTRY() and DMX_FE_ENTRY(). + * 15.03.2000/JPL Added the capabilities field to dmx_demux_t. + * 22.03.2000/JPL Corrected the callback parameter in the + * allocate_x_feed() functions. + * 03.04.2000/JPL Added support for optional resource conflict resolution + * and scarce resource handling. + * 05.04.2000/JPL Changed the dmx_resolve_conflict() to use resource + * type as a parameter. + * 12.04.2000/JPL Added a second buffer parameter for dmx_x_callback() + * functions to better handle buffer wrapping. + * 26.04.2000/JPL Added functions for section-level descrambling. + * 03.09.2000/JPL Removed support for conflict resolution and scarce + * resource handling. Otherwise only minor changes to + * data structures and function prototypes. + * + * + * Author: + * Juha-Pekka Luoma (JPL) + * Nokia Research Center + * + * Notes: + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +/* $Id$ */ + +#ifndef __DEMUX_H +#define __DEMUX_H + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + +#include /* __u8, __u16, ... */ +#include /* list_entry(), struct list_head */ +#include /* struct timespec */ +#include /* Function return values */ + +/*--------------------------------------------------------------------------*/ +/* Common definitions */ +/*--------------------------------------------------------------------------*/ + +/* + * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter. + */ + +#ifndef DMX_MAX_FILTER_SIZE +#define DMX_MAX_FILTER_SIZE 16 +#endif +/* + * dmx_success_t: Success codes for the Demux Callback API. + */ + +typedef enum { + DMX_OK = 0, /* Received Ok */ + DMX_LENGTH_ERROR, /* Incorrect length */ + DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ + DMX_CRC_ERROR, /* Incorrect CRC */ + DMX_FRAME_ERROR, /* Frame alignment error */ + DMX_FIFO_ERROR, /* Receiver FIFO overrun */ + DMX_MISSED_ERROR /* Receiver missed packet */ +} dmx_success_t; + +/*--------------------------------------------------------------------------*/ +/* TS packet reception */ +/*--------------------------------------------------------------------------*/ + +struct dmx_ts_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_ts_feed_s* feed, + __u16 pid, + size_t callback_length, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_ts_feed_s* feed); + int (*stop_filtering) (struct dmx_ts_feed_s* feed); +}; +typedef struct dmx_ts_feed_s dmx_ts_feed_t; + +/*--------------------------------------------------------------------------*/ +/* PES packet reception (not supported yet) */ +/*--------------------------------------------------------------------------*/ + +typedef void dmx_pes_feed_t; +typedef void dmx_pes_filter_t; + +/*--------------------------------------------------------------------------*/ +/* Section reception */ +/*--------------------------------------------------------------------------*/ + +typedef struct { + __u8 filter_value [DMX_MAX_FILTER_SIZE]; + __u8 filter_mask [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_section_filter_t; + +struct dmx_section_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_section_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + int check_crc); + int (*allocate_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t** filter); + int (*release_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t* filter); + int (*start_filtering) (struct dmx_section_feed_s* feed); + int (*stop_filtering) (struct dmx_section_feed_s* feed); +}; +typedef struct dmx_section_feed_s dmx_section_feed_t; + +/*--------------------------------------------------------------------------*/ +/* Callback functions */ +/*--------------------------------------------------------------------------*/ + +typedef int (*dmx_ts_cb) ( __u8 * buffer1, + size_t buffer1_length, + __u8 * buffer2, + size_t buffer2_length, + dmx_ts_feed_t* source, + dmx_success_t success); + +typedef int (*dmx_section_cb) ( __u8 * buffer1, + size_t buffer_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_section_filter_t * source, + dmx_success_t success); + +typedef int (*dmx_pes_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_pes_filter_t* source, + dmx_success_t success); + +/*--------------------------------------------------------------------------*/ +/* DVB Front-End */ +/*--------------------------------------------------------------------------*/ + +typedef enum { + DMX_OTHER_FE = 0, + DMX_SATELLITE_FE, + DMX_CABLE_FE, + DMX_TERRESTRIAL_FE, + DMX_LVDS_FE, + DMX_ASI_FE /* DVB-ASI interface */ +} dmx_frontend_source_t; + +typedef struct { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique front-end identifier */ + char* vendor; /* Name of the front-end vendor */ + char* model; /* Name of the front-end model */ + struct list_head connectivity_list; /* List of front-ends that can + be connected to a particular + demux */ + void* priv; /* Pointer to private data of the API client */ +} dmx_frontend_t; + +/*--------------------------------------------------------------------------*/ +/* MPEG-2 TS Demux */ +/*--------------------------------------------------------------------------*/ + +/* + * Flags OR'ed in the capabilites field of struct dmx_demux_s. + */ + +#define DMX_TS_FILTERING 1 +#define DMX_PES_FILTERING 2 +#define DMX_SECTION_FILTERING 4 +#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ +#define DMX_CRC_CHECKING 16 +#define DMX_TS_DESCRAMBLING 32 +#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 +#define DMX_MAC_ADDRESS_DESCRAMBLING 128 + +/* + * Demux resource type identifier. +*/ + +/* + * DMX_FE_ENTRY(): Casts elements in the list of registered + * front-ends from the generic type struct list_head + * to the type * dmx_frontend_t + *. +*/ + +#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) + +struct dmx_demux_s { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique demux identifier */ + char* vendor; /* Name of the demux vendor */ + char* model; /* Name of the demux model */ + __u32 capabilites; /* Bitfield of capability flags */ + dmx_frontend_t* frontend; /* Front-end connected to the demux */ + struct list_head reg_list; /* List of registered demuxes */ + void* priv; /* Pointer to private data of the API client */ + int (*open) (struct dmx_demux_s* demux); + int (*close) (struct dmx_demux_s* demux); + int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); + int (*allocate_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t** feed, + dmx_ts_cb callback); + int (*release_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t* feed); + int (*allocate_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t** feed, + dmx_pes_cb callback); + int (*release_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t* feed); + int (*allocate_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t** feed, + dmx_section_cb callback); + int (*release_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t* feed); + int (*descramble_mac_address) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, + size_t buffer2_length, + __u16 pid); + int (*descramble_section_payload) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, size_t buffer2_length, + __u16 pid); + int (*add_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*remove_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + struct list_head* (*get_frontends) (struct dmx_demux_s* demux); + int (*connect_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*disconnect_frontend) (struct dmx_demux_s* demux); +}; +typedef struct dmx_demux_s dmx_demux_t; + +/*--------------------------------------------------------------------------*/ +/* Demux directory */ +/*--------------------------------------------------------------------------*/ + +/* + * DMX_DIR_ENTRY(): Casts elements in the list of registered + * demuxes from the generic type struct list_head* to the type dmx_demux_t + *. + */ + +#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) + +int dmx_register_demux (dmx_demux_t* demux); +int dmx_unregister_demux (dmx_demux_t* demux); +struct list_head* dmx_get_demuxes (void); + +#endif /* #ifndef __DEMUX_H */ + diff --git a/dvb-spec/API/dvb_api/demux.xml b/dvb-spec/API/dvb_api/demux.xml new file mode 100644 index 000000000..b15824d0b --- /dev/null +++ b/dvb-spec/API/dvb_api/demux.xml @@ -0,0 +1,568 @@ + + + linuxtv.org|DVB Demux API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB Demux API

+ +

+ The DVB demux device lets you set TS, PID and section filters in the DVB + device. This is internally accomplished through calls to the + demux kernel module. + The demux device can be accessed through /dev/ost/demux. +

+ +

+ The function calls defined in the include file + dmx.h are described in detail below: +

+ +

+ Demux API IO control calls + +

+

+
+int open(const char *deviceName, int flags);
+ 
+    DESCRIPTION
+ 
+	This system call, used with a device name of /dev/ost/demuxn, where n 
+	denotes the specific demux device to be opened, allocates a new filter 
+	and returns a handle which can be used for subsequent control of that 
+	filter. This call has to be made for each filter to be used, i.e. every
+	returned file descriptor is a reference to a single filter.
+        /dev/ost/dvrn is a logical device to be used for retrieving Transport 
+	Streams for digital video recording. n identifies the physical demux 
+	device that provides the actual DVR functionlaity. When reading from  
+	this device a transport stream containing the packets from all PES
+	filters set in the corresponfing demux device (/dev/osst/demuxn)             	having the output set to DMX_OUT_TS_TAP.  A recorded Transport Stream 
+	is replayed by writing to this device.
+	This device can only be opened in read-write mode.
+        The significance of blocking or non-blocking mode is described in the
+	documentation for functions where there is a difference. It does not 
+	affect the semantics of the open() call itself. A device opened in 
+	blocking mode can later be put into non-blocking mode
+        (and vice versa) using the F_SETFL command of the fcntl system call.
+
+ 
+    PARAMETERS
+
+	const char *deviceName	     I Name of the demux device, which should be
+	                               /dev/ost/demuxn where  n denotes the
+                                       specific demux device to be opened, or the
+                                       name of a logical DVR device, /dev/ost/dvrn.
+
+	int flags                    I A bit-wise OR of the following flags:
+                                       O_RDWR read/write access.
+                                       O_NONBLOCK open in non-blocking mode
+                                                 (blocking mode is the default).
+
+    RETURNS
+    
+	ENODEV				Device driver not loaded/available.
+
+        EINVAL 	                        Invalid argument.
+
+        EMFILE                          "Too many open files", i.e. no more filters available.
+
+        ENOMEM                          The driver failed to allocate enough memory.
+
+
+
+
+

+ +

+

+
+int close(int fd);
+
+    DESCRIPTION
+
+	This system call deactivates and deallocates a filter that was previously
+	allocated via the open() call.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+size_t read(int fd, void *buf, size_t count);
+
+    DESCRIPTION
+
+	This system call returns filtered data, which might be section or PES 
+	data. The filtered data is transferred from the driver's internal circular
+	buffer to buf. The maximum amount of data to be transferred is implied by
+	count.
+
+        When returning section data the driver always tries to return a complete 
+	single section (even though buf would provide buffer space for more data).
+	If the size of the buffer is smaller than the section as much as possible
+	will be returned, and the remaining data will be provided in subsequent 
+	calls.
+        The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
+	sized sections) by default. The size of this buffer may be changed by 
+	using the DMX_SET_BUFFER_SIZE function. If the buffer is not large enough,
+	or if the read operations are not performed fast enough, this may result 
+	in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned,
+	and the circular buffer will be emptied.
+        This call is blocking if there is no data to return, i.e. the process 
+	will be put to sleep waiting for data, unless the O_NONBLOCK flag is 
+	specified.
+        Note that in order to be able to read, the filtering process has to be
+	started by defining either a section or a PES filter by means of the 
+	ioctl functions, and then starting the filtering process via the DMX_START
+	ioctl function or by setting the DMX_IMMEDIATE_START flag.
+        If the reading is done from a logical DVR demux device, the data will 
+	constitute a Transport Stream including the packets from all PES filters
+	in the corresponding demux device /dev/ost/demuxn having the output set 
+	to DMX_OUT_TS_TAP.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	void *buf             O Pointer to the buffer to be used for returned filtered data.
+
+	size_t count          I Size of buf.
+
+    RETURNS
+
+	EWOULDBLOCK		No data to return and O_NONBLOCK was specified.
+
+        EBADF                   fd is not a valid open file descriptor
+
+        ECRC                    Last section had a CRC error ­ no data
+	                        returned. The buffer is flushed.
+
+        EBUFFEROVERFLOW         The filtered data was not read from the buffer in
+                                due time, resulting in non-read data being lost.
+                                The buffer is flushed.
+
+        ETIMEDOUT               The section was not loaded within the stated
+                                timeout period. See ioctl DMX_SET_FILTER for
+                                how to set a timeout.
+
+        EFAULT                  The driver failed to write to the callers buffer
+				due to an invalid *buf pointer.
+
+
+
+
+

+ +

+

+
+ssize_t write(int fd, const void *buf, size_t count);
+
+    DESCRIPTION
+
+	This system call is only provided by the logical device /dev/ost/dvrn, 
+	where n identifies the physical demux device that provides the actual 
+	DVR  functionality.  It is used for replay of a digitally recorded 
+	Transport Stream. Matching filters have to be defined in the 
+	corresponding physical demux device, /dev/ost/demuxn.
+	The amount of data to be transferred is implied by count.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	void *buf             I Pointer to the buffer containing the Transport Stream.
+
+        size_t count          I Size of buf.
+
+    RETURNS
+
+	EWOULDBLOCK             No data was written. This might happen if
+                                O_NONBLOCK was specified and there is no more
+                                buffer space available (if O_NONBLOCK is not
+                                specified the function will block until buffer 
+				space is available).
+
+	EBUSY                   This error code indicates that there are
+                                conflicting requests. The corresponding demux
+                                device is setup to receive data from the front-
+                                end. Make sure that these filters are stopped
+                                and that the filters with input set to DMX_IN_DVR
+                                are started.
+
+	EBADF                   fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_START);
+
+    DESCRIPTION
+
+	This ioctl call is used to start the actual filtering operation 
+	defined via the ioctl  calls DMX_SET_FILTER or DMX_SET_PES_FILTER.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	int request           I Equals DMX_START for this command.
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor
+
+        EINVAL                  Invalid argument, i.e. no filtering parameters
+                                provided via the DMX_SET_FILTER or
+                                DMX_SET_PES_FILTER functions.
+
+        EBUSY                   This error code indicates that there are
+                                conflicting requests. There are active filters
+                                filtering data from another input source. Make
+                                sure that these filters are stopped before starting
+                                this filter.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_STOP);
+
+    DESCRIPTION
+
+	This  ioctl call is used to stop the actual filtering operation defined 
+	via the ioctl  calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
+	the DMX_START command.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals DMX_STOP for this command.
+ 
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_SET_FILTER, struct dmxSctFilterParams *params);
+
+    DESCRIPTION
+
+	This ioctl call sets up a filter according to the filter and mask 
+	parameters provided. A timeout may be defined stating number of seconds 
+	to wait for a section to be loaded. A value of 0 means that no timeout 
+	should be applied. Finally there is a flag field where it is possible to
+	state whether a section should be CRC-checked, whether the filter should
+        be a "one-shot" filter, i.e. if the filtering operation should be stopped
+	after the first section is received, and whether the filtering operation 
+	should be started immediately (without waiting for a DMX_START ioctl call).
+        If a filter was previously set-up, this filter will be cancelled, and the
+	receive buffer will be flushed.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals DMX_SET_FILTER for this command.
+
+        struct                I Pointer to structure containing filter
+
+        dmxSctFilterParams      parameters.
+               *params
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor
+
+        EINVAL                  Invalid argument.
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_SET_PES_FILTER, struct dmxPesFilterParams *params);
+
+    DESCRIPTION
+
+	This ioctl call sets up a PES filter according to the parameters provided.
+	By a PES filter is meant a filter that is based just on the packet 
+	identifier (PID), i.e. no PES header or payload filtering capability is 
+	supported.
+        The transport stream destination for the filtered output may be set. Also
+	the PES type may be stated in order to be able to e.g. direct a video 
+	stream directly to the video decoder. Finally there is a flag field where
+	it is possible to state whether the filtering operation should be started
+	immediately (without waiting for a DMX_START ioctl call).
+        If a filter was previously set-up, this filter will be cancelled, and the
+	receive buffer will be flushed.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	int request           I Equals DMX_SET_PES_FILTER for this command.
+
+        struct                I Pointer to structure containing filter
+
+        dmxPesFilterParams      parameters.
+               *params
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor
+
+        EINVAL                  Invalid argument.
+
+        EBUSY                   This error code indicates that there are
+                                conflicting requests. There are active filters
+                                filtering data from another input source. Make
+                                sure that these filters are stopped before starting
+                                this filter.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_SET_BUFFER_SIZE, unsigned long size);
+
+    DESCRIPTION
+
+	This ioctl call is used to set the size of the circular buffer used
+	for filtered data. The default size is two maximum sized sections, i.e. 
+	if this function is not called a buffer size of 2 * 4096 bytes will be
+	used.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals DMX_SET_BUFFER_SIZE for this command.
+
+        unsigned long size    I Size of circular buffer.
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor.
+
+        ENOMEM                  The driver was not able to allocate a buffer of the requested size.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = DMX_GET_EVENT, struct dmxEvent *ev);
+
+    DESCRIPTION
+
+	This  ioctl call returns an event if available. If an event is not 
+	available, the behavior depends on whether the device is in blocking or 
+	non-blocking mode.  In the latter case, the call fails immediately with
+	errno set to EWOULDBLOCK. In the former case, the call blocks until an
+	event becomes available.
+        The standard Linux poll() and/or select() system calls can be used with
+	the device file descriptor to watch for new events.  For select(), the 
+	file descriptor should be included in the exceptfds argument, and for 
+	poll(), POLLPRI should be specified as the wake-up condition.
+        Only the latest event for each filter is saved.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	int request           I Equals DMX_SET_BUFFER_SIZE for this command.
+
+        struct dmxEvent *ev   O Pointer to the location where the event is to be stored.
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor.
+        
+	EFAULT                  ev points to an invalid address.
+
+	EWOULDBLOCK             There is no event pending, and the device is in non-blocking mode.
+
+
+
+
+

+

+ +
+ + diff --git a/dvb-spec/API/dvb_api/demux_mod.xml b/dvb-spec/API/dvb_api/demux_mod.xml new file mode 100644 index 000000000..c36467977 --- /dev/null +++ b/dvb-spec/API/dvb_api/demux_mod.xml @@ -0,0 +1,1215 @@ + + + linuxtv.org|DVB Demux Kernel API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB Demux Kernel API

+ +

+ The demux kernel API gives access to the demuxer of the DVB hardware + to other kernel modules which implement devices like the + demux device or generic DVB network devices. +

+ +

+ The function calls defined in the include file + demux.h are described in detail below: +

+ +

+ Demux Directory API + +

+ The demux directory is a Linux kernel-wide facility for registering and + accessing the MPEG-2 TS demuxes in the system. Run-time registering and + unregistering of demux drivers is possible using this API. +

+

+ All demux drivers in the directory implement the abstract interface dmx_demux_t. +

+ +

+

+int dmx_register_demux ( dmx_demux_t* demux )
+
+    Description
+
+	This function makes a demux driver interface available to the Linux kernel. 
+	It is usually called by the init_module() function of the kernel module that
+	contains the demux driver. The caller of this function is responsible for 
+	allocating dynamic or static memory for the demux structure and for initializing
+	its fields before calling this function. 
+	The memory allocated for the demux structure must not be freed before calling
+        dmx_unregister_demux(),
+
+    Returns
+    
+	0				The command was successfully performed.
+
+        -EEXIST                         A demux with the same value of the id field
+                                        already stored in the directory.
+
+        -ENOSPC                         No space left in the directory.
+
+
+
+
+

+

+

+
+int dmx_unregister_demux ( dmx_demux_t* demux )
+
+    Parameters
+
+	dmx_demux_t* demux	    I/O Pointer to the demux API and instance variables.
+
+    Description
+
+	This function is called to indicate that the given demux interface is no longer
+	available. The caller of this function is responsible for freeing the memory of
+	the demux structure, if it was dynamically allocated before calling 
+	dmx_register_demux().
+	The cleanup_module() function of the kernel module that contains the demux 
+	driver should call this function. Note that this function fails if the demux 
+	is currently in use, i.e., release_demux() has not been called for the 
+	interface.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -ENODEV                         No such demux registered.
+
+        -EBUSY                          Demux is currently in use.
+
+
+
+
+

+

+

+
+struct list_head* dmx_get_demuxes ()
+
+    Description
+
+	Provides the caller with the list of registered demux interfaces, using the 
+	standard list structure defined in the include file linux/list.h. 
+	The include file demux.h defines the macro DMX_DIR_ENTRY() for converting an 
+	element of the generic type struct list_head* to the type dmx_demux_t*.
+        The caller must not free the memory of any of the elements obtained via this
+	function call.
+
+    Returns
+
+	A list of demux interfaces, or NULL in the case of an empty list.
+
+
+
+
+

+

+ + +

+Demux API +

+ The demux API should be implemented for each demux in the system. It is used to + select the TS source of a demux and to manage the demux resources. When the + demux client allocates a resource via the demux API, it receives a pointer + to the API of that resource. +

+

+ Each demux receives its TS input from a DVB front-end or from the memory, as + set via the demux API. In a system with more than one front-end, the API can + be used to select one of the DVB front-ends as a TS source for a demux, unless + this is fixed in the HW platform. The demux API only controls front-ends + regarding their connections with demuxes; the APIs used to set the other + front-end parameters, such as tuning, are not defined in this document. +

+

+ The functions that implement the abstract interface demux_t should be defined + static or module private and registered to the Demux Directory for external + access. It is not necessary to implement every function in the demux_t struct, + however (for example, a demux interface might support Section filtering, but + not TS or PES filtering). The API client is expected to check the value of any + function pointer before calling the function: the value of NULL means "function + not available". +

+

+ Whenever the functions of the demux API modify shared data, the possibilities + of lost update and race condition problems should be addressed, e.g. by + protecting parts of code with mutexes. This is especially important on + multi-processor hosts. +

+

+ Note that functions called from a bottom half context must not sleep, at least + in the 2.2.x kernels. Even a simple memory allocation can result in a kernel + thread being put to sleep if swapping is needed. For example, the Linux kernel + calls the functions of a network device interface from a bottom half context. + Thus, if a demux API function is called from network device code, the function + must not sleep. +

+

+

+
+int open ( demux_t* demux )
+
+
+    Parameters
+    
+	demux_t* demux		      I Pointer to the demux API and instance data.
+
+    Description
+
+	This function reserves the demux for use by the caller and, if necessary, 
+	initializes the demux. When the demux is no longer needed, the function close()
+	should be called.
+        It should be possible for multiple clients to access the demux at the same time.
+	Thus, the function implementation should increment the demux usage count when 
+	open() is called and decrement it when close() is called.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -EUSERS                         Maximum usage count reached.
+
+        -EINVAL                         Bad parameter.
+
+
+
+
+

+

+

+
+int close ( demux_t* demux )
+
+    Parameters
+
+	demux_t* demux		      I Pointer to the demux API and instance data.
+
+    Description
+
+	The function is called to indicate that the API client does not need to use 
+	the demux anymore. As a result of this function, the demux usage count is 
+	decremented by one.
+        When the usage count drops to zero, any demux resources can be released.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -ENODEV                         The demux was not in use.
+
+        -EINVAL                         Bad parameter.
+
+
+
+
+

+

+

+
+int write ( demux_t* demux, const char* buf, size_t count)    
+
+    Parameters
+
+	demux_t* demux		    I/O Pointer to the demux API and instance data.
+
+        const char* buf               I Pointer to the TS data in kernel-space memory.
+
+        size_t length                 I Length of the TS data.
+
+
+
+    Description
+
+	This function provides the demux driver with a memory buffer containing TS 
+	packets. Instead of receiving TS packets from the DVB front-end, the demux 
+	driver software will read packets from the memory. Any clients of this demux 
+	with active TS, PES or Section filters will receive filtered data via the Demux
+	callback API (see 0). The function returns when all the data in the buffer has
+	been consumed by the demux.
+	Demux hardware typically cannot read TS from the memory. If this is the case,
+        memory-based filtering has to be implemented entirely in software.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -ENOSYS                         The command is not implemented.
+
+        -EINVAL                         Bad parameter.
+
+
+
+
+

+

+

+
+int allocate_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t** feed, dmx_ts_cb callback )
+
+    Parameters
+
+	demux_t* demux		    I/O Pointer to the demux API and instance data.
+
+        dmx_ts_feed_t** feed          O Pointer to the TS feed API and instance data.
+
+        dmx_ts_cb callback            I Pointer to the callback function for
+                                        passing received TS packet
+
+    Description
+
+	Allocates a new TS feed, which is used to filter the TS packets carrying a 
+	certain PID.
+        The TS feed normally corresponds to a hardware PID filter on the demux chip.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -EBUSY                          No more TS feeds available.
+ 
+	-ENOSYS                         The command is not implemented.
+
+        -EINVAL                         Bad parameters.
+
+
+
+
+

+

+

+int release_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t* feed)
+
+    Parameters
+
+             dmx_demux_t* demux                        I/O Pointer to the demux API and
+                                                             instance data.
+             dmx_ts_feed_t* feed                       I     Pointer to the TS feed API and
+                                                             instance data.
+
+            Function Detailed Description
+            Releases the resources allocated with allocate_ts_feed(). Any filtering in progress
+            on the TS feed should be stopped before calling this function.
+
+            Function Returns
+             0                                         The command was successfully performed.
+             -EINVAL                                   Bad parameters.
+
+
+

+

+

+allocate_pes_feed()
+
+            TBD
+
+
+
+
+

+

+

+release_pes_feed()
+
+            TBD
+
+
+
+
+

+

+

+int allocate_section_feed ( dmx_demux_t* demux,
+             dmx_section_feed_t** 
+                                                                            feed,
+                                                dmx_section_cb callback )
+
+            Function Parameters
+             demux_t* demux                            I/O Pointer to the demux API and
+                                                             instance data.
+             dmx_section_feed_t** feed                 O     Pointer to the section feed API and
+
+                                                                instance data.
+             dmx_section_cb callback                  I         Pointer to the callback function for
+                                                                passing received sections
+
+            Function Detailed Description
+            Allocates a new section feed, i.e. a demux resource for filtering and receiving sections.
+            On platforms with hardware support for section filtering, a section feed is directly
+            mapped to the demux HW. On other platforms, TS packets are first PID filtered in
+            hardware and a hardware section filter then emulated in software.
+            The caller obtains an API pointer of type dmx_section_feed_t as an out parameter.
+            Using this API the caller can set filtering parameters and start receiving sections.
+
+            Function Returns
+             0                                        The command was successfully performed.
+             -EBUSY                                   No more section feeds available.
+             -ENOSYS                                  The command is not implemented.
+             -EINVAL                                  Bad parameters.
+
+
+

+

+

+
+int release_section_feed ( dmx_demux_t* demux,
+             dmx_section_feed_t* 
+                                                                          feed 
+                                                                                  )
+            Function Parameters
+             dmx_demux_t* demux                            I/O Pointer to the demux API and
+                                                                  instance data.
+             dmx_section_feed_t* feed                      I      Pointer to the section feed API and
+                                                                  instance data.
+
+            Function Detailed Description
+            Releases the resources allocated with allocate_section_feed(), including allocated
+            filters. Any filtering in progress on the section feed should be stopped before calling
+            this function.
+
+            Function Returns
+             0                                        The command was successfully performed.
+             -EINVAL                                  Bad parameters.
+
+
+
+

+

+

+
+int descramble_mac_address ( dmx_demux_t* demux,
+             __u8* 
+                                                            buffer1,
+             size_t 
+                                                             buffer1_length,
+                                                   __u8* buffer2,
+             size_t 
+                                                             buffer2_length,
+                                                   __u16 pid )
+            Function Parameters
+             dmx_demux_t* demux                             I/O Pointer to the demux API and
+                                                                   instance data.
+             __u8* buffer1                                  I      Pointer to the first byte of the
+                                                                   section.
+             size_t buffer1_length                          I      Length of the section data,
+                                                                   including headers and CRC, in
+                                                                   buffer1.
+             __u8* buffer2                                  I      Pointer to the tail of the section
+                                                                   data, or NULL. The pointer has a
+                                                                   non-NULL value if the section wraps
+                                                                   past the end of a cyclic buffer.
+             size_t buffer2_length                          I      Length of the section data,
+                                                                   including headers and CRC, in
+                                                                   buffer2
+             __u16 pid                                      I      The PID on which the section was
+                                                                   received. Useful for obtaining the
+                                                                   descrambling key, e.g. from a DVB
+                                                                   Common Access facility.
+
+            Function Detailed Description
+            This function runs a descrambling algorithm on the destination MAC address field of a
+            DVB Datagram Section, replacing the original address with its unencrypted version.
+            Otherwise, the description on the function descramble_section_payload() applies
+            also to this function.
+
+            Function Returns
+             0                                         The command was successfully performed.
+             -ENOSYS                                   No descrambling facility available.
+             -EINVAL                                   Bad parameters.
+
+
+
+
+
+

+

+

+
+int descramble_section_payload (           dmx_demux_t* demux,
+             __u8* 
+                                                                  buffer1,
+             size_t 
+                                                                   buffer1_length,
+                                                       __u8* buffer2,
+             size_t 
+                                                                   buffer2_length,
+                                                       __u16 pid )
+            Function Parameters
+             dmx_demux_t* demux                            I/O Pointer to the demux API and
+                                                                  instance data.
+             __u8* buffer1                                 I/O Pointer to the first byte of the
+                                                                  section.
+             size_t buffer1_length                         I      Length of the section data,
+                                                                  including headers and CRC, in
+                                                                  buffer1.
+             __u8* buffer2                                 I      Pointer to the tail of the section
+                                                                  data, or NULL. The pointer has a
+                                                                  non-NULL value if the section wraps
+                                                                  past the end of a cyclic buffer.
+             size_t buffer2_length                         I      Length of the section data,
+                                                                  including headers and CRC, in
+                                                                  buffer2
+             __u16 pid                                     I      The PID on which the section was
+                                                                  received. Useful for obtaining the
+                                                                  descrambling key, e.g. from a DVB
+                                                                  Common Access facility.
+
+            Function Detailed Description
+            This function runs a descrambling algorithm on the payload of a DVB Datagram
+            Section, replacing the original payload with its unencrypted version. The function will
+            be called from the demux API implementation; the API client need not call this function
+            directly.
+            Section-level scrambling algorithms are currently standardized only for DVB-RCC
+            (return channel over 2-directional cable TV network) systems. For all other DVB
+            networks, encryption schemes are likely to be proprietary to each data broadcaster.
+            Thus, it is expected that this function pointer will have the value of NULL (i.e., function
+            not available) in most demux API implementations. Nevertheless, it should be possible
+            to use the function pointer as a hook for dynamically adding a "plug-in" descrambling
+            facility to a demux driver.
+
+
+            While this function is not needed with hardware-based section descrambling, the
+            descramble_section_payload function pointer can be used to override the default
+            hardware-based descrambling algorithm: if the function pointer has a non-NULL value,
+            the corresponding function should be used instead of any descrambling hardware.
+
+            Function Returns
+             0                                           The command was successfully performed.
+             -ENOSYS                                     No descrambling facility available.
+             -EINVAL                                     Bad parameters.
+
+
+
+

+

+

+
+int add_frontend ( dmx_demux_t* demux,
+             dmx_frontend_t* 
+                                                          frontend);
+
+            Function Parameters
+             dmx_demux_t* demux                        I/O Pointer to the demux API and instance
+                                                             data.
+             dmx_frontend_t* frontend                  I/O Pointer to the front-end instance data.
+
+            Function Detailed Description
+            Registers a connectivity between a demux and a front-end, i.e., indicates that the
+            demux can be connected via a call to connect_frontend() to use the given front-end
+            as a TS source. The client of this function has to allocate dynamic or static memory for
+            the frontend structure and initialize its fields  before calling this function.
+            This function is normally called during the driver initialization. The caller must not free
+            the memory of the frontend struct before successfully calling remove_frontend().
+
+            Function Returns
+             0                                      The command was successfully performed.
+             -EEXIST                                A front-end with the same value of the id field
+                                                    already registered.
+             -EINUSE                                The demux is in use.
+             -ENOMEM                                No more front-ends can be added.
+             -EINVAL                                Bad parameters.
+
+
+

+

+

+
+int remove_frontend ( dmx_demux_t* demux,
+                                         dmx_frontend_t* frontend )
+            Function Parameters
+             dmx_demux_t* demux                   I/O       Pointer to the demux API and instance
+                                                            data.
+             dmx_frontend_t* frontend             I/O       Pointer to the front-end instance data.
+
+            Function Detailed Description
+            Indicates that the given front-end, registered by a call to add_frontend(), can no
+            longer be connected as a TS source by this demux. The function should be called
+            when a front-end driver or a demux driver is removed from the system. If the front-end
+            is in use, the function fails with the return value of ­EBUSY.
+            After succesfully calling this function, the caller can free the memory of the frontend
+            struct if it was dynamically allocated before the add_frontend() operation.
+
+            Function Returns
+             0                                     The command was successfully performed.
+             -EINVAL                               Bad parameters.
+             -EBUSY                                The front-end is in use, i.e. a call to
+                                                   connect_frontend() has not been followed by
+                                                   a call to disconnect_frontend().
+
+
+
+

+

+

+
+struct list_head* get_frontends ( dmx_demux_t* demux )
+            Function Parameters
+             dmx_demux_t* demux                             I    Pointer to the demux API and
+                                                                 instance data.
+
+            Function Detailed Description
+            Provides the APIs of the front-ends that have been registered for this demux. Any of
+            the front-ends obtained with this call can be used as a parameter for
+            connect_frontend().
+
+
+            The include file demux.h contains the macro DMX_FE_ENTRY() for converting an
+            element of the generic type struct list_head* to the type dmx_frontend_t*.
+            The caller must not free the memory of any of the elements obtained via this function
+            call.
+
+            Function Returns
+            A list of front-end interfaces, or NULL in the case of an empty list.
+
+
+

+

+

+
+int connect_frontend ( dmx_demux_t* demux,
+                                           dmx_frontend_t* frontend )
+            Function Parameters
+             dmx_demux_t* demux                   I/O       Pointer to the demux API and instance
+                                                            data.
+             dmx_frontend_t* frontend             I/O       Pointer to the front-end instance data.
+
+            Function Detailed Description
+            Connects the TS output of the front-end to the input of the demux. A demux can only
+            be connected to a front-end registered to the demux with the function
+            add_frontend().
+            It may or may not be possible to connect multiple demuxes to the same front-end,
+            depending on the capabilities of the HW platform. When not used, the front-end should
+            be released by calling disconnect_frontend().
+
+            Function Returns
+             0                                     The command was successfully performed.
+             -EINVAL                               Bad parameters.
+             -EBUSY                                The front-end is in use.
+
+
+

+

+

+
+int disconnect_frontend ( dmx_demux_t* demux )
+
+
+            Function Parameters
+             dmx_demux_t* demux               I/O Pointer to the demux API and instance data.
+
+            Function Detailed Description
+            Disconnects the demux and a front-end previously connected by a
+            connect_frontend() call.
+
+            Function Returns
+             0                                        The command was successfully performed.
+             -EINVAL                                  Bad parameters.
+
+
+
+

+

+ +

+Demux Callback API +

+ This kernel-space API comprises the callback functions that deliver filtered data to the + demux client. Unlike the other APIs, these API functions are provided by the client and + called from the demux code. +

+

+ The function pointers of this abstract interface are not packed into a structure as in the + other demux APIs, because the callback functions are registered and used + independent of each other. As an example, it is possible for the API client to provide + several callback functions for receiving TS packets and no callbacks for PES packets + or sections. +

+

+ The functions that implement the callback API need not be re-entrant: when a demux + driver calls one of these functions, the driver is not allowed to call the function again + before the original call returns. If a callback is triggered by a hardware interrupt, it is + recommended to use the Linux "bottom half" mechanism or start a tasklet instead of + making the callback function call directly from a hardware interrupt. + +

+

+

+int dmx_ts_cb ( __u8* buffer1, size_t buffer1_length, 
+		__u8* buffer2, size_t buffer2_length,
+                dmx_ts_feed_t* source, dmx_success_t success )
+
+    Parameters
+
+	__u8* buffer1		      I Pointer to the start of the filtered TS packets.
+
+        size_t buffer1_length         I Length of the TS data in buffer1.
+
+        __u8* buffer2                 I Pointer to the tail of the filtered TS packets, or NULL.
+
+        size_t buffer2_length         I Length of the TS data in buffer2.
+
+        dmx_ts_feed_t* source         I Indicates which TS feed is the source of the callback.
+
+        dmx_success_t success         I Indicates if there was an error in TS reception.
+
+    Description
+
+	This function, provided by the client of the demux API, is called from the 
+	demux code. The function is only called when filtering on this TS feed has 
+	been enabled using the start_filtering() function. If conflict resolution 
+	is used (see Error! Reference source not found.), no callbacks are made to 
+	clients that have been put "on hold" regarding a TS Feed resource.
+        Any TS packets that match the filter settings are copied to a cyclic buffer. 
+	The filtered TS packets are delivered to the client using this callback 
+	function. The size of the cyclic buffer is controlled by the 
+	circular_buffer_size parameter of the set() function in the TS Feed API. It is
+	expected that the buffer1 and buffer2 callback parameters point to addresses 
+	within the circular buffer, but other implementations are also
+        possible. Note that the called party should not try to free the memory the
+	buffer1 and buffer2 parameters point to.
+        When this function is called, the buffer1 parameter typically points to the
+	start of the first undelivered TS packet within a cyclic buffer. The buffer2 
+	buffer parameter is normally NULL, except when the received TS packets have
+	crossed the last address of the cyclic buffer and "wrapped" to the beginning
+	of the buffer. In the latter case the buffer1 parameter would contain an 
+	address within the cyclic buffer, while the buffer2 parameter would contain 
+	the first address of the cyclic buffer.
+        The number of bytes delivered with this function (i.e. buffer1_length  +
+        buffer2_length) is usually equal to the value of callback_length parameter given
+        in the set() function, with one exception: if a timeout occurs before receiving
+        callback_length bytes of TS data, any undelivered packets are immediately
+        delivered to the client by calling this function. The timeout duration is 
+	controlled by the set() function in the TS Feed API.
+        If a TS packet is received with errors that could not be fixed by the TS-level
+	forward error correction (FEC), the Transport_error_indicator flag of the TS 
+	packet header should be set. The TS packet should not be discarded, as the 
+	error can possibly be corrected by a higher layer protocol.
+        If the called party is slow in processing the callback, it is possible that 
+	the circular buffer eventually fills up. If this happens, the demux driver 
+	should discard any TS packets received while the buffer is full. The error 
+	should be indicated to the client on the next callback by setting the success
+	parameter to the value of DMX_OVERRUN_ERROR.
+
+    Returns
+
+	0				Continue filtering.
+
+       -1                               Stop filtering - has the same effect as a call
+                                        to stop_filtering() on the TS Feed API.
+
+
+
+
+

+

+

+
+dmx_pes_cb()
+
+	TBD
+
+
+

+

+

+
+int dmx_section_cb ( __u8* buffer1,
+             size_t 
+                                                   buffer1_length,
+             __u8* 
+                                               buffer2,
+                                 size_t buffer2_length,
+             dmx_section_filter_t* 
+                                                                      source,
+                                       dmx_success_t success )
+
+            Function Parameters
+             __u8* buffer1                    I       Pointer to the start of the filtered section, e.g.
+                                                      within the cyclic buffer of the demux driver.
+             size_t buffer1_length            I       Length of the filtered section data in buffer1,
+                                                      including headers and CRC.
+             __u8* buffer2                            Pointer to the tail of the filtered section data, or
+                                                      NULL. Useful to handle the wrapping of a cyclic
+                                                      buffer.
+             size_t buffer2_length                    Length of the filtered section data in buffer2,
+                                                      including headers and CRC.
+             dmx_section_filter_t*            I       Indicates the filter that triggered the callback.
+             filter
+             dmx_success_t success            I       Indicates if there was an error in section
+                                                      reception.
+
+            Function Detailed Description
+            This function, provided by the client of the demux API, is called from the demux code.
+            The function is only called when filtering of sections has been enabled using the
+            function start_filtering() of the section feed API.
+            When the demux driver has received a complete section that matches at least one
+            section filter, the client is notified via this callback function. Normally this function is
+            called for each received section; however, it is also possible to deliver multiple sections
+            with one callback, for example when the system load is high.
+            If an error occurs while receiving a section, this function should be called with the
+            corresponding error type set in the success field, whether or not there is data to
+            deliver.
+            The Section Feed implementation should maintain a cyclic buffer for received sections.
+            However, this is not necessary if the Section Feed API is implemented as a client of
+
+
+            the TS Feed API, because the TS Feed implementation then buffers the
+            received data.
+            The size of the circular buffer can be configured using the set() function in the
+            Section Feed API. If there is no room in the circular buffer when a new section is
+            received, the section must be discarded. If this happens, the value of the success
+            parameter should be DMX_OVERRUN_ERROR on the next callback.
+
+            Function Returns
+             0                                         Continue filtering.
+             -1                                        Stop filtering - has the same effect as a call
+                                                       to stop_filtering() on the Section Feed
+                                                       API.
+
+
+

+ +

+ +

+TS Feed API +

+ A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this + API, the client can set the filtering properties to start/stop filtering TS packets on a + particular TS feed. The API is defined as an abstract interface of the type + dmx_ts_feed_t. +

+

+ The functions that implement the interface should be defined static or module + private. The client can get the handle of a TS feed API by calling the function + allocate_ts_feed() in the demux API. +

+

+

+
+int set ( dmx_ts_feed_t* feed,
+             __u16 
+                                    pid,
+                           size_t callback_length,
+             size_t 
+                                     cyclic_buffer_size,
+             int 
+                               descramble,
+                           struct timespec timeout)
+
+    Parameters
+
+             dmx_ts_feed_t* feed                       I/O Pointer to the TS feed API and
+                                                               instance data.
+             __u16 pid                                 I       PID value to filter. Only the TS
+                                                               packets carrying the specified PID will
+                                                               be passed to the API client.
+             size_t callback_length                    I       Number of bytes to deliver with each
+                                                               call to the dmx_ts_cb() callback
+                                                               function. The value of this
+                                                               parameter should be a multiple of
+                                                               188.
+
+             size_t cyclic_buffer_size                    I     Size of the cyclic buffer for the filtered
+                                                                TS packets.
+             int descramble                               I     If non-zero, descramble the filtered
+                                                                TS packets.
+             struct timespec timeout                      I     Maximum time to wait before
+                                                                delivering received TS packets to the
+                                                                client.
+
+            Function Detailed Description
+            This function sets the parameters of a TS feed. Any filtering in progress on the TS feed
+            must be stopped before calling this function.
+
+            Function Returns
+             0                                            The command was successfully performed.
+             -ENOMEM                                      Not enough memory for the requested
+                                                          buffer size.
+             -ENOSYS                                      No descrambling facility available for TS
+                                                          packets.
+             -EINVAL                                      Bad parameters.
+
+
+

+

+

+
+int start_filtering ( dmx_ts_feed_t* feed )
+
+    Parameters
+ 
+             dmx_ts_feed_t* feed                    I Pointer to the TS feed API and instance data.
+
+            Function Detailed Description
+            Starts filtering TS packets on this TS feed, according to its settings. The PID value to
+            filter can be set by the API client. All matching TS packets are delivered
+            asynchronously to the client, using the callback function registered with
+            allocate_ts_feed().
+
+            Function Returns
+             0                                        The command was successfully performed.
+             -EINVAL                                  Bad parameters.
+
+
+
+

+

+

+
+int stop_filtering ( dmx_ts_feed_t* feed )
+
+    Parameters
+
+	dmx_ts_feed_t* feed	    I/O Pointer to the TS feed API and instance data.
+
+    Description
+
+	Stops filtering TS packets on this TS feed.
+
+    Returns
+
+	0				The command was successfully performed.
+
+        -EINVAL                         Bad parameters.
+
+
+
+
+

+

+ +

+PES Feed API +

+ TBD +

+

+ +

+Section Feed API +

+ A section feed is a resource consisting of a PID filter and a set of section filters. Using + this API, the client can set the properties of a section feed and to start/stop filtering. + The API is defined as an abstract interface of the type dmx_section_feed_t. + The functions that implement the interface should be defined static or module + private. The client can get the handle of a section feed API by calling the function + allocate_section_feed() in the demux API. +

+

+ On demux platforms that provide section filtering in hardware, the Section Feed API + implementation provides a software wrapper for the demux hardware. Other platforms + may support only PID filtering in hardware, requiring that TS packets are converted to + sections in software. In the latter case the Section Feed API implementation can be a + client of the TS Feed API. +

+ +

+

+
+int set ( dmx_section_feed_t* feed, __u16 pid, size_t circular_buffer_size, 
+	  int descramble, int check_crc )
+
+    Parameters
+
+	dmx_section_feed_t* feed                  I/O Pointer to the section feed API and
+                                                                instance data.
+             __u16 pid                                I         PID value to filter; only the TS packets
+                                                                carrying the specified PID will be
+                                                                accepted.
+             size_t circular_buffer_size              I         Size of the cyclic buffer for filtered
+                                                                sections.
+             int descramble                           I         If non-zero, descramble any sections
+                                                                that are scrambled.
+             int check_crc                            I         If non-zero, check  the CRC values of
+                                                                filtered sections.
+
+            Function Detailed Description
+            This function sets the parameters of a section feed. Any filtering in progress on the
+            section feed must be stopped before calling this function.
+            If descrambling is enabled, the payload_scrambling_control and
+            address_scrambling_control fields of received DVB datagram sections should be
+            observed. If either one is non-zero, the section should be descrambled either in
+            hardware or using the functions descramble_mac_address() and
+            descramble_section_payload() of the demux API. Note that according to the
+            MPEG-2 Systems specification [3], only the payloads of private sections can be
+            scrambled while the rest of the section data must be sent in the clear.
+
+            Function Returns
+             0                                     The command was successfully performed.
+             -ENOMEM                               Not enough memory available for the requested
+                                                   buffer size.
+             -ENOSYS                               No descrambling facility available for sections.
+             -EINVAL                               Bad parameters.
+
+
+

+

+

+
+int allocate_filter(dmx_section_feed_t* feed, dmx_section_filter_t** filter)
+
+    Parameters
+             dmx_section_feed_t* feed                      I/O Pointer to the section feed API and
+                                                                 instance data.
+             dmx_section_filter_t** filter                 O     Pointer to the allocated filter.
+
+
+            Function Detailed Description
+            This function is used to allocate a section filter on the demux. It should only be called
+            when no filtering is in progress on this section feed. If a filter cannot be allocated, the
+            function fails with -ENOSPC. See below for the format of the section filter struct provided
+            as an out parameter:
+                   typedef struct {
+                           __u8 filter_value [DMX_MAX_FILTER_SIZE];
+                           __u8 filter_mask [DMX_MAX_FILTER_SIZE];
+                            struct dmx_section_feed_s* parent;  /* Back-pointer */
+                           void* priv; /* Private data of the client */
+                   } dmx_section_filter_t;
+
+            The bitfields filter_mask and filter_value should only be modified when no
+            filtering is in progress on this section feed. filter_mask controls which bits of
+            filter_value are compared with the section headers/payload. On a binary value of 1
+            in filter_mask, the corresponding bits are compared. The filter only accepts sections
+            that are equal to filter_value in all the tested bit positions. Any changes to the
+            values of filter_mask and filter_value are guaranteed to take effect only when
+            the start_filtering()  function is called next time. The parent pointer in the struct
+            is initialized by the API implementation to the value of the feed parameter. The priv
+            pointer is not used by the API implementation, and can thus be freely utilized by the
+            caller of this function. Any data pointed to by the priv pointer is available to the
+            recipient of the dmx_section_cb() function call.
+            While the maximum section filter length (DMX_MAX_FILTER_SIZE) is currently set at 16
+            bytes, hardware filters of that size are not available on all platforms. Therefore, section
+            filtering will often take place first in hardware, followed by filtering in software for the
+            header bytes that were not covered by a hardware filter. The filter_mask field can be
+            checked to determine how many bytes of the section filter are actually used, and if the
+            hardware filter will suffice. Additionally, software-only section filters can optionally be
+            allocated to clients when all hardware section filters are in use.
+            Note that on most demux hardware it is not possible to filter on the section_length field
+            of the section header ­ thus this field is ignored, even though it is included in
+            filter_value and filter_mask fields.
+
+            Function Returns
+             0                                          The command was successfully performed.
+             -ENOSPC                                    No filters of given type and length available.
+             -EINVAL                                    Bad parameters.
+
+
+

+

+

+int release_filter ( dmx_section_feed_t* feed, dmx_section_filter_t* filter)
+
+    Parameters
+             dmx_section_feed_t* feed I/O Pointer to the section feed API and instance
+                                                       data.
+             dmx_section_filter_t*              I/O Pointer to the instance data of a section filter.
+             filter
+
+            Function Detailed Description
+            This function releases all the resources of a previously allocated section filter. The
+            function should not be called while filtering is in progress on this section feed. After
+            calling this function, the caller should not try to dereference the filter pointer.
+
+            Function Returns
+             0                                        The command was successfully performed.
+             -ENODEV                                  No such filter allocated.
+             -EINVAL                                  Bad parameters.
+
+
+

+

+

+int start_filtering ( dmx_section_feed_t* feed )
+
+    Parameters
+             dmx_section_feed_t* feed                     I/O Pointer to the section feed API and
+                                                                instance data.
+
+            Function Detailed Description
+            Starts filtering sections on this section feed, according to its settings. Sections are first
+            filtered based on their PID and then matched with the section filters allocated for this
+            feed. If the section matches the PID filter and at least one section filter, it is delivered
+            to the API client. The section is delivered asynchronously using the callback function
+            registered with allocate_section_feed().
+
+            Function Returns
+             0                                            The command was successfully performed.
+             -EINVAL                                      Bad parameters.
+
+
+

+

+

+int stop_filtering ( dmx_section_feed_t* feed )
+
+    Parameters
+
+	dmx_section_feed_t* feed	    I/O Pointer to the section feed API and instance data.
+
+    Description
+
+	Stops filtering sections on this section feed. Note that any changes to the 
+	filtering parameters (filter_value, filter_mask, etc.) should only be made 
+	when filtering is stopped.
+
+    Returns
+
+	0					The command was successfully performed.
+
+        -EINVAL                                 Bad parameters.
+
+
+
+
+

+

+
+ + diff --git a/dvb-spec/API/dvb_api/dmx.h b/dvb-spec/API/dvb_api/dmx.h new file mode 100644 index 000000000..e12056514 --- /dev/null +++ b/dvb-spec/API/dvb_api/dmx.h @@ -0,0 +1,130 @@ +/* + * dmx.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_DMX_H_ +#define _OST_DMX_H_ + +/* pid_t conflicts with linux/include/linux/types.h !!!*/ + +typedef uint16_t dvb_pid_t; + +#define DMX_FILTER_SIZE 16 + +typedef enum +{ + DMX_OUT_DECODER, /* Streaming directly to decoder. */ + DMX_OUT_TAP, /* Output going to a memory buffer */ + /* (to be retrieved via the read command).*/ + DMX_OUT_TS_TAP /* Output multiplexed into a new TS */ + /* (to be retrieved by reading from the */ + /* logical DVR device). */ +} dmxOutput_t; + + +typedef enum +{ + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ +} dmxInput_t; + + +typedef enum +{ + DMX_PES_AUDIO, + DMX_PES_VIDEO, + DMX_PES_TELETEXT, + DMX_PES_SUBTITLE, + DMX_PES_PCR, + DMX_PES_OTHER +} dmxPesType_t; + + +typedef enum +{ + DMX_SCRAMBLING_EV, + DMX_FRONTEND_EV +} dmxEvent_t; + + +typedef enum +{ + DMX_SCRAMBLING_OFF, + DMX_SCRAMBLING_ON +} dmxScramblingStatus_t; + + +typedef struct dmxFilter +{ + uint8_t filter[DMX_FILTER_SIZE]; + uint8_t mask[DMX_FILTER_SIZE]; +} dmxFilter_t; + +struct dmxFrontEnd +{ + //TBD tbd; +}; + +struct dmxSctFilterParams +{ + dvb_pid_t pid; + dmxFilter_t filter; + uint32_t timeout; + uint32_t flags; +#define DMX_CHECK_CRC 1 +#define DMX_ONESHOT 2 +#define DMX_IMMEDIATE_START 4 +}; + + +struct dmxPesFilterParams +{ + dvb_pid_t pid; + dmxInput_t input; + dmxOutput_t output; + dmxPesType_t pesType; + uint32_t flags; +}; + + +struct dmxEvent +{ + dmxEvent_t event; + time_t timeStamp; + union + { + dmxScramblingStatus_t scrambling; + //TBD; + } u; +}; + + +#define DMX_START _IOW('o',41,void) +#define DMX_STOP _IOW('o',42,void) +#define DMX_SET_FILTER _IOW('o',43,struct dmxSctFilterParams *) +#define DMX_SET_PES_FILTER _IOW('o',44,struct dmxPesFilterParams *) +#define DMX_SET_BUFFER_SIZE _IOW('o',45,unsigned long) +#define DMX_GET_EVENT _IOR('o',46,struct dmxEvent *) + + + +#endif /*_OST_DMX_H_*/ diff --git a/dvb-spec/API/dvb_api/frontend.h b/dvb-spec/API/dvb_api/frontend.h new file mode 100644 index 000000000..534a97175 --- /dev/null +++ b/dvb-spec/API/dvb_api/frontend.h @@ -0,0 +1,96 @@ +/* + * frontend.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_FRONTEND_H_ +#define _OST_FRONTEND_H_ + +typedef uint32_t feStatus; + +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define QPSK_SPECTRUM_INV 4 + +struct qpskParameters { + uint32_t iFrequency; + uint32_t SymbolRate; + uint8_t FEC_inner; +}; + + +struct qpskEvent { + int32_t type; + time_t timestamp; + union { + struct { + feStatus previousStatus; + feStatus currentStatus; + } unexpectedEvent; + struct qpskParameters completionEvent; + feStatus failureEvent; + } u; +}; + + +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; + + +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; + +typedef enum { + OST_POWER_ON, + OST_POWER_STANDBY, + OST_POWER_SUSPEND, + OST_POWER_OFF +} powerState_t; + + +#define OST_SELFTEST _IOWR('o',61,void) +#define OST_SET_POWER_STATE _IOW('o',62,uint32_t) +#define OST_GET_POWER_STATE _IOR('o',63,uint32_t *) +#define FE_READ_STATUS _IOR('o',64,feStatus *) +#define FE_READ_BER _IOW('o',65,uint32_t *) +#define FE_READ_SIGNAL_STRENGTH _IOR('o',66,int32_t *) +#define FE_READ_SNR _IOR('o',67,int32_t *) +#define FE_READ_UNCORRECTED_BLOCKS _IOW('o',68,uint32_t *) +#define FE_GET_NEXT_FREQUENCY _IOW('o',69,uint32_t *) +#define FE_GET_NEXT_SYMBOL_RATE _IOW('o',70,uint32_t *) + +#define QPSK_TUNE _IOW('o',71,struct qpskParameters *) +#define QPSK_GET_EVENT _IOR('o',72,struct qpskEvent *) +#define QPSK_FE_INFO _IOR('o',73,struct qpskFrontendInfo *) +#define QPSK_WRITE_REGISTER _IOW('o',74,struct qpskRegister *) +#define QPSK_READ_REGISTER _IOR('o',75,struct qpskRegister *) + +#endif /*_OST_FRONTEND_H_*/ + diff --git a/dvb-spec/API/dvb_api/frontend.xml b/dvb-spec/API/dvb_api/frontend.xml new file mode 100644 index 000000000..1cd1b0fbd --- /dev/null +++ b/dvb-spec/API/dvb_api/frontend.xml @@ -0,0 +1,843 @@ + + + linuxtv.org|DVB Frontend API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB Frontend API

+ +

+ The DVB frontend device controls the frontend of the DVB hardware, e.g. + tuning, symbol rate, error correction, ... + It is accessed through /dev/ost/qpskfe. +

+ +

+ The function calls defined in the include file + frontend.h are described in detail below: +

+ +

+ Frontend API IO control calls + + +

+

+
+int open(const char *deviceName, int flags);
+
+    DESCRIPTION
+
+	This system call opens a named front-end device (e.g. /dev/qpskfe) for 
+	subsequent use. The device can be opened in read-only mode, which only allows
+	monitoring of device status and statistics, or read/write mode, which allows 
+	any kind of use (e.g. performing tuning operations.)
+
+	In a system with multiple front-ends, it is usually the case that multiple
+	devices cannot be open in read/write mode simultaneously.  As long as a 
+	front-end device is opened in read/write mode, other open() calls in 
+	read/write mode will either fail or block, depending on whether 
+	non-blocking or blocking mode was specified.
+        A front-end device opened in blocking mode can later be put into non-blocking
+	mode (and vice versa) using the F_SETFL command of the fcntl system call.
+	This is a standard system call, documented in the Linux manual page for fcntl.
+        When an open() call has succeeded, the device will be ready for use in the 
+	specified mode. This implies that the corresponding hardware is powered up, 
+	and that other front-ends may have been powered down to make that possible.
+
+    PARAMETERS
+
+	const char *deviceName	      I Name of specific front-end device.  In the
+                                        current implementation, /dev/qpskfe is the
+                                        only one available (QPSK satellite front-end.)
+
+	int flags	              I A bit-wise OR of the following flags:
+                                        O_RDONLY read-only access
+                                        O_RDWR read/write  access
+                                        O_NONBLOCK open in non-blocking mode
+                                                       (blocking mode is the default)
+    RETURNS
+
+	ENODEV				Device driver not loaded/available.
+
+        EBUSY				Device or resource busy.
+
+	EINVAL				Invalid argument.
+
+
+
+
+

+ +

+

+
+int close(int fd);
+
+    DESCRIPTION
+
+	This system call closes a previously opened front-end device.  After closing a 
+	front-end device, its corresponding hardware might be powered down 
+	automatically, but only when this is needed to open another front-end device.
+	To affect an unconditional power down, it should be done explicitly using 
+	the OST_SET_POWER_STATE ioctl.
+
+    PARAMETERS
+
+	int fd                I File descriptor returned by a previous call to open().
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = OST_SELFTEST);
+
+    DESCRIPTION
+
+  	This ioctl call initiates an automatic self-test of the front-end hardware.  
+	This call requires read/write access to the device.
+
+    PARAMETERS
+
+	int fd                I File descriptor returned by a previous call to open().
+
+	int request	      I Equals OST_SELFTEST for this command.
+
+    RETURNS
+	
+	0                       Success
+
+	-1			Failure
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = OST_SET_POWER_STATE, uint32_t state);
+
+    DESCRIPTION
+
+	This ioctl call, implemented in many OST device drivers, enables direct 
+	control over the power state of the hardware device, which may be on, off, 
+	standby, or suspend.  The latter two are low-power modes, which disable all 
+	functionality of the device until turned on again. In contrast to the off 
+	state, however, the standby and suspend states resume operation in the same
+	state as when the device was active.  The only difference between the standby
+	and suspend states is a different tradeoff between resume time and power 
+	consumption ­ power consumption may be lower in the suspend state at the
+        cost of a longer resume time.
+
+        A device that implements this call does not necessarily support two low-power
+	modes. If it only support one low-power state, or none at all, the 
+	OST_SET_POWER_STATE operation for the missing states will still succeed, but 
+	it will be mapped to an existing state as per this table:
+
+        number of low-power	requested state		resulting state
+        states supported
+
+            1                      standby                  suspend
+
+            1                      suspend                  suspend
+
+            0                      standby                    on
+
+            0                      suspend                    on
+
+        For other cases where a required state is missing, an error code will be
+	returned.  This can happen if a device does not support the power-off state, 
+	but nevertheless implements this ioctl operation for control of low-power 
+	states.
+        When opening a device in read/write mode, the driver ensures that the 
+	corresponding hardware device is turned on initially.  If the device is 
+	later turned off or put in suspend mode, it has to be explicitly turned on 
+	again.
+
+        This call requires read/write access to the device.  (Note that the power 
+	management driver can affect the power state of devices without using this 
+	ioctl operation, so having exclusive read/write access to a device does not 
+	imply total control over the power state.)
+
+    PARAMETERS
+    
+	int fd		      I File descriptor returned by a previous call to open().
+
+	int request	      I Equals OST_SET_POWER_STATE for this command.
+
+	uint32_t state        I Requested power state.  One of:
+
+                                OST_POWER_ON:		turn power on
+                                OST_POWER_STANDBY:      set device in standby mode
+                                OST_POWER_SUSPEND:      set device in suspend mode
+                                OST_POWER_OFF:          turn power off
+
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EINVAL                  illegal state, or not available on this device
+
+        EPERM                   permission denied (needs read/write access)
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = OST_GET_POWER_STATE, uint32_t *state);
+
+    DESCRIPTION
+
+	This ioctl call, implemented in many OST device drivers, obtains the power
+	state of the hardware device, which may be on, off, standby, or suspend.
+        A device that implements this call does not necessarily support all four states.
+	If there is only one low-power state, the suspend state will be returned for 
+	that state.  If there is no low-power state, the on state will be reported 
+	standby and suspend states will be equivalent to the on state.
+        For this command, read-only access to the device is sufficient.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+	int request	      I Equals OST_GET_POWER_STATE for this command.
+
+        uint32_t *state	      O Pointer to a variable where the power state is
+                                to be stored.  Possible values are:
+                                OST_POWER_ON                      power is on
+                                OST_POWER_STANDBY                 device in 
+                                                                  standby mode
+                                OST_POWER_SUSPEND:                device in 
+                                                                  suspend mode
+                                OST_POWER_OFF:                    power is off
+
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+        
+	EINVAL                  illegal state, or not available on this device
+
+        EFAULT                  state points to invalid address
+
+        EPERM                   permission denied (needs read/write access)
+
+	ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_READ_STATUS, feStatus *status);
+
+    DESCRIPTION
+
+	This ioctl call returns status information about the front-end.
+	This call only requires read-only access to the device.
+
+    PARAMETERS
+
+	int fd                   I File descriptor returned by a previous call to open().
+
+        int request              I Equals FE_READ_STATUS for this command.
+
+        struct feStatus *status  O Points to the location where the front-end
+                                   status word is to be stored.
+
+    RETURNS
+
+	EBADF                      fd is not a valid open file descriptor
+
+        EFAULT                     status points to invalid address
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = FE_READ_BER, uint32_t *ber);
+
+    DESCRIPTION
+
+	This ioctl call returns the bit error rate for the signal currently 
+	received/demodulated by the front-end. For this command, read-only access 
+	to the device is sufficient.
+
+    FUNCTION PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request	      I Equals FE_READ_BER for this command.
+
+        uint32_t *ber         O The bit error rate, as a multiple of 10-9, is stored into *ber.
+
+                                Example: a value of 2500 corresponds to a bit error 
+					 rate of 2.5 10-6, or 1 error in 400000 bits.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EFAULT			ber points to invalid address
+
+        ENOSIGNAL               There is no signal, thus no meaningful bit error
+                                rate.  Also returned if the front-end is not turned on.
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = FE_READ_SIGNAL_STRENGTH, int32_t *strength);
+
+    DESCRIPTION
+
+	This ioctl call returns the signal strength value for the signal currently 
+	received by the front-end. For this command, read-only access to the device 
+	is sufficient.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals  FE_READ_SIGNAL_STRENGTH for this
+                                                     command.
+        int32_t *strength     O The signal strength value, as a multiple of 10^-6 dBm,
+				is stored into *strength.  
+				Example: a value of ­12,500,000 corresponds to a signal
+                                         strength value of ­12.5 dBm.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  strength points to invalid address
+ 
+        ENOSIGNAL               There is no signal, thus no meaningful signal
+                                strength value.  Also returned if front-end is not
+                                turned on.
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = FE_READ_SNR, int32_t *snr);
+
+    DESCRIPTION
+
+	This ioctl call returns the signal-to-noise ratio for the signal currently 
+	received by the front-end. For this command, read-only access to the device
+	is sufficient.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request	      I Equals FE_READ_SNR for this command.
+
+        int32_t *snr	      O The signal-to-noise ratio, as a multiple of
+                                10^-6 dB, is stored into *snr.
+
+                                Example: a value of 12,300,000 corresponds
+                                         to a signal-to-noise ratio of 12.3 dB.
+
+    RETURNS
+    
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  snr points to invalid address
+
+        ENOSIGNAL               No stable signal, thus no meaningful signal-to-
+                                noise ratio.  Also returned if front-end is not
+                                turned on.
+
+        ENOSYS                  Function not available for this device.
+
+

+ +

+

+int ioctl( int fd, int request = FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks);
+
+
+    DESCRIPTION
+
+	This ioctl call returns the number of uncorrected blocks detected by the device
+	driver during its lifetime.  For meaningful measurements, the increment in 
+	block count during a specific time interval should be calculated2.  For this 
+	command, read-only access to the device is sufficient.
+        
+	2 Note that the counter will wrap to zero after its maximum count has 
+	  been reached (232-1).
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request	      I Equals FE_READ_UNCORRECTED_BLOCKS for this command.
+
+        uint32_t *ublocks     O The total number of uncorrected blocks seen
+                                by the driver so far.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  ublocks points to invalid address
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = FE_GET_NEXT_FREQUENCY, uint32_t *freq);
+
+    DESCRIPTION
+
+	When scanning a frequency range, it is desirable to use a scanning step size 
+	that is as large as possible, yet small enough to be able to lock to any signal 
+	within the range.
+        This  ioctl operation does just that ­ it increments a given frequency by a 
+	step size suitable for efficient3 scanning.
+        The step size used by this function may be a quite complex function of the given
+        frequency, hardware capabilities, and parameter settings of the device.  Thus, a
+        returned result is only valid for the current state of the device.
+        For this command, read-only access to the device is sufficient.
+                                                        
+        3 Note that scanning may still be excruciatingly slow on some hardware, for 
+	  other reasons than a non-optimal scanning step size.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals  FE_GET_NEXT_FREQUENCY for this command.
+
+        uint32_t *freq      I/O Input: a given frequency
+                                Output:  the frequency corresponding to
+	                                 the next higher frequency setting.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  freq points to invalid address
+
+        EINVAL                  maximum frequency reached
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl( int fd, int request = FE_GET_NEXT_SYMBOL_RATE, uint32_t *symbolRate);
+
+    DESCRIPTION
+
+	When scanning a range of symbol rates (e.g. for "blind acquisition") it is 
+	desirable to use a scanning step size that is as large as possible, yet 
+	small enough to detect any valid signal within the range.  This ioctl 
+	operation does just that ­ it increments a given symbol rate by a step size
+	suitable for efficient4 scanning.
+        The step size used by this function may be a quite complex function of the given
+        symbol rate, hardware capabilities, and parameter settings of the device.  
+	Thus, a returned result is only valid for the current state of the device.
+        For this command, read-only access to the device is sufficient.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals  FE_GET_NEXT_SYMBOL_RATE for this command.
+
+        uint32_t *symbolRate  I/O Input:  a given symbol rate                                                             Output: the symbol rate corresponding to the next
+	                                  higher symbol rate setting.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  symbolRate points to invalid address
+
+        EINVAL                  maximum symbol rate reached
+
+        ENOSYS                  Function not available for this device.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_TUNE, struct qpskParameters *p);
+
+    DESCRIPTION
+
+	This ioctl call starts a tuning operation using specified parameters.  
+	The result of this call will be successful if the parameters were valid and 
+	the tuning could be initiated.
+        The result of the tuning operation in itself, however, will arrive 
+	asynchronously as an event (see documentation for QPSK_GET_EVENT and qpskEvent.)
+        If a new QPSK_TUNE operation is initiated before the previous one was completed,
+	the previous operation will be aborted in favor of the new one.
+        This command requires read/write access to the device.
+
+    PARAMETERS
+
+	int fd			 File descriptor returned by a previous call to open(). 
+
+	int request		 Equals QPSK_TUNE for this command.
+
+	struct qpskParameters *p Points to parameters for tuning operation.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+        EFAULT                  p points to invalid address
+        EINVAL                  parameter value(s) not valid
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_GET_EVENT, struct qpskEvent *ev);
+
+    DESCRIPTION
+    
+	This ioctl call returns an event of type qpskEvent if available. If an event
+	is not available, the behavior depends on whether the device is in blocking 
+	or non-blocking mode.  In the latter case, the call fails immediately with 
+	errno set to EWOULDBLOCK. In the former case, the call blocks until an event
+	becomes available.
+        The standard Linux poll() and/or select() system calls can be used with the 
+	device file descriptor to watch for new events.  For select(), the file 
+	descriptor should be included in the exceptfds argument, and for poll(), 
+	POLLPRI should be specified as the wake-up condition.
+        Since the event queue allocated is rather small (room for 8 events), the queue
+	must be serviced regularly to avoid overflow.   If an overflow happens, the 
+	oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs 
+	the next time the queue is read. After reporting the error condition in this 
+	fashion, subsequent QPSK_GET_EVENT calls will return events from the queue as
+	usual.
+        For the sake of implementation simplicity, this command requires read/write 
+	access to the device.
+
+    PARAMETERS
+              
+	int fd			File descriptor returned by a previous call to open().
+
+        int request           I Equals QPSK_GET_EVENT for this command.
+
+        struct qpskEvent *ev  O Points to the location where the event, if any, is to be stored.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  ev points to invalid address
+
+        EWOULDBLOCK             There is no event pending, and the device is in
+                                non-blocking mode.
+
+        EBUFFEROVERFLOW         Overflow in event queue - one or more events were lost.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_FE_INFO, struct qpskFrontendInfo *info);
+
+    DESCRIPTION
+
+	This ioctl call returns information about the front-end.
+	This call only requires read-only access to the device.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals QPSK_FE_INFO for this command.
+
+        struct qpskFrontendInfo *info   O Points to the location where the front-end
+                                          information is to be stored.
+
+    RETURNS
+    
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  info points to invalid address
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_WRITE_REGISTER, struct qpskRegister *reg);
+
+    DESCRIPTION
+ 
+	This ioctl call is intended for hardware-specific diagnostics.  It writes 
+	an 8-bit value at an 8-bit address of a register in a chip identified by an 
+	8-bit index.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals  QPSK_WRITE_REGISTER for this command.
+
+        struct qpskRegister *reg    I Specifies a value that should be written
+                                      into a specified register in a specified chip.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  reg points to and invalid address
+
+        EINVAL                  Register specification invalid.
+
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = QPSK_READ_REGISTER, struct qpskRegister *reg);
+
+    DESCRIPTION
+
+	This ioctl call is intended for hardware-specific diagnostics.  
+	It reads an 8-bit value at an 8-bit address of a register in a chip 
+	identified by an 8-bit index.
+
+    PARAMETERS
+
+	int fd		    I File descriptor returned by a previous call to open().
+
+        int request         I Equals QPSK_READ_REGISTER for this command.
+
+        struct qpskRegister *reg   I/O I:  specifies a register in a specified
+                                           chip from which a value should be read.
+
+                                       O:  the value is read into the
+                                           qpskRegister structure.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor
+
+        EFAULT                  reg points to and invalid address
+
+        EINVAL                  Register specification invalid.
+
+
+
+
+

+ +

+ +
+ + diff --git a/dvb-spec/API/dvb_api/sec.h b/dvb-spec/API/dvb_api/sec.h new file mode 100644 index 000000000..f6eda5a0a --- /dev/null +++ b/dvb-spec/API/dvb_api/sec.h @@ -0,0 +1,116 @@ +/* + * sec.h + * + * Copyright (C) 2000 Ralph Metzler + * & Marcus Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_SEC_H_ +#define _OST_SEC_H_ + +#define SEC_MAX_DISEQC_PARAMS 3 + +struct secDiseqcCmd { + uint8_t addr; + uint8_t cmd; + uint8_t numParams; + uint8_t params[SEC_MAX_DISEQC_PARAMS]; +}; + +typedef uint32_t secVoltage; + +enum { + SEC_VOLTAGE_OFF, + SEC_VOLTAGE_LT, + SEC_VOLTAGE_13, + SEC_VOLTAGE_13_5, + SEC_VOLTAGE_18, + SEC_VOLTAGE_18_5 +}; + + +typedef uint32_t secToneMode; + +typedef enum { + SEC_TONE_ON, + SEC_TONE_OFF +} secToneMode_t; + + +typedef uint32_t secMiniCmd; + +typedef enum { + SEC_MINI_NONE, + SEC_MINI_A, + SEC_MINI_B +} secMiniCmd_t; + +struct secStatus { + int32_t busMode; + secVoltage selVolt; + secToneMode contTone; +}; + +enum { + SEC_BUS_IDLE, + SEC_BUS_BUSY, + SEC_BUS_OFF, + SEC_BUS_OVERLOAD +}; + +struct secCommand { + int32_t type; + union { + struct secDiseqcCmd diseqc; + uint8_t vsec; + uint32_t pause; + } u; +}; + +struct secCmdSequence { + secVoltage voltage; + secMiniCmd miniCommand; + secToneMode continuousTone; + + uint32_t numCommands; + struct secCommand* commands; +}; + +enum { + SEC_CMDTYPE_DISEQC, + SEC_CMDTYPE_VSEC, + SEC_CMDTYPE_PAUSE +}; + + +#define SEC_GET_STATUS _IOR('o',91,struct secStatus *) +#define SEC_RESET_OVERLOAD _IOW('o',92,void) +#define SEC_SEND_SEQUENCE _IOW('o',93,struct secCmdSequence *) +#define SEC_SET_TONE _IOW('o',94,secToneMode) +#define SEC_SET_VOLTAGE _IOW('o',95,secVoltage) + +typedef enum { + SEC_DISEQC_SENT, + SEC_VSEC_SENT, + SEC_PAUSE_COMPLETE, + SEC_CALLBACK_ERROR +} secCallback_t; + + +#endif /*_OST_SEC_H_*/ diff --git a/dvb-spec/API/dvb_api/sec.xml b/dvb-spec/API/dvb_api/sec.xml new file mode 100644 index 000000000..22062d4a9 --- /dev/null +++ b/dvb-spec/API/dvb_api/sec.xml @@ -0,0 +1,430 @@ + + + linuxtv.org|DVB SEC API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB SEC API

+ +

+ The DVB SEC device controls the Satellite Equipment Control of + the DVB hardware, i.e. DiSEqC and V-SEC. + It is accessed through /dev/ost/sec. +

+ +

+ The function calls defined in the include file + sec.h aredescribed in detail below: +

+ +

+ SEC API IO control calls + + +

+

+
+int open(const char *deviceName, int flags);
+
+    DESCRIPTION
+
+	This system call opens a named SEC device for subsequent use.
+        If the device is opened in read-only mode, only status and statistics 
+	monitoring is allowed. If the device is opened in read/write mode, all
+	types of operations can be performed.
+	Any number of applications can have simultaneous access to the device.
+
+    PARAMETERS
+
+	const char *deviceName	I Name of the SEC device.
+
+        int flags		I Valid values are:
+                                  O_RDONLY             read-only access
+                                  O_RDWR               read/write access
+
+	The optional flag O_NONBLOCK is not supported. If O_NONBLOCK is set, 
+	open() and most other subsequent calls to the device will return ­1 and 
+	set errno to EWOULDBLOCK.
+	The communication with the peripheral devices is sequential by nature, 
+	so it is probably preferable to use the device in synchronous mode. 
+	This is the motivation for not going through the extra effort of 
+	implementing asynchronous operation of the device.
+
+    RETURNS
+
+	ENODEV			Device not loaded/available
+        EFAULT                  deviceName does not refer to a valid memory area.
+        EINVAL                  Invalid argument
+
+
+
+
+

+ +

+

+
+int close(int fd);
+
+    DESCRIPTION
+
+	This system call closes a previously opened SEC device.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+    RETURNS
+    
+	EBADF			fd is not a valid file descriptor.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = SEC_GET_STATUS, struct secStatus* status);
+
+    DESCRIPTION
+
+	This call gets the status of the device.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals SEC_GET_STATUS for this command.
+
+        struct secStatus* status   O The status of the device.
+
+    RETURNS
+
+	ENODEV			Device driver not loaded/available
+
+        EFAULT                  status is an invalid pointer
+
+        EBUSY                   Device or resource busy
+
+        EINVAL                  Invalid argument
+
+        EPERM                   File not opened with read permissions
+
+        EINTERNAL               Internal error in the device driver
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = SEC_RESET_OVERLOAD);
+
+    DESCRIPTION
+
+	If the bus has been automatically powered off due to power overload, this
+	ioctl call restores the power to the bus. The call requires read/write 
+	access to the device.
+        This call has no effect if the device is manually powered off.
+
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals SEC_RESET_OVERLOAD for this command.
+
+    RETURNS
+
+	EBADF                   fd is not a valid file descriptor.
+
+        EPERM                   Permission denied (needs read/write access)
+
+        EINTERNAL               Internal error in the device driver
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = SEC_SEND_SEQUENCE, struct secCmdSequence *seq);
+
+    DESCRIPTION
+
+	This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC 
+	commands. The first version of the SEC device does not support V-SEC 
+	signalling and it aborts the operation with an error code if a V-SEC 
+	command is detected in the input data.
+
+        !  The call will fail with errno set to EBUSOVERLOAD if the bus is 
+	   overloaded. If the bus is overloaded, SEC_RESET_OVERLOAD can be 
+           called and the operation can be retried.
+
+        !  If seq.numCommands equals 0 and seq.miniCommand equals SEC_MINI_NONE,
+	   the bus voltage will be switched and the continuous 22kHz tone 
+	   generation enabled/disabled immediately.
+ 
+        This operation is atomic. If several processes calls this ioctl 
+	simultaneously, the operations will be serialised so a complete sequence
+	is sent at a time.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals  SEC_SEND_SEQUENCE for this command.
+
+        struct secCmdSequence *seq    I Pointer to the command sequence to be transmitted.
+
+    RETURNS
+    
+	EBADF			Fd is not a valid file descriptor.
+        
+	EFAULT                  Seq points to an invalid address.
+        
+        EINVAL                  The data structure referred to by seq is invalid in
+                                some way.
+
+        EPERM                   Permission denied (needs read/write access)
+
+        EINTERNAL               Internal error in the device driver
+
+
+        EBUSMODE                The device is not prepared for transmission 
+				(e.g. it might be manually powered off).
+
+        EBUSOVERLOAD                  Bus overload has occurred.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = SEC_SET_TONE, secToneMode tone);
+
+    DESCRIPTION
+
+	This call is used to set the generation of the continuous 22kHz tone. 
+	The possibility to just change the tone mode is already provided by 
+	ioctl SEC_SEND_SEQUENCE, but SEC_SET_TONE is an easier to use interface.
+        To keep the transmission of a command sequence (see section 4.4.5 ) as 
+	an atomic operation, SEC_SET_TONE will block if a transmission is in 
+	progress. This call requires read/write permissions.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals SEC_SET_TONE for this command.
+
+        secToneMode tone      I The requested tone generation mode (on/off).
+
+    RETURNS
+
+	ENODEV			Device driver not loaded/available
+
+        EBUSY                   Device or resource busy
+
+        EINVAL                  Invalid argument
+
+        EPERM                   File not opened with read permissions
+
+        EINTERNAL               Internal error in the device driver
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = SEC_SET_VOLTAGE, secVoltage voltage);
+
+    DESCRIPTION
+    
+	This call is used to set the bus voltage. The possibility to just change
+	the bus voltage is already provided by ioctl SEC_SEND_SEQUENCE, but 
+	SEC_SET_VOLTAGE is an easier to use interface.
+        To keep the transmission of a command sequence (see section 4.4.5 ) as
+	an atomic operation, SEC_SET_VOLTAGE will block if a transmission is in 
+	progress.
+	This call requires read/write permissions.
+
+    PARAMETERS
+
+	int fd		      I File descriptor returned by a previous call to open().
+
+        int request           I Equals SEC_SET_VOLTAGE for this command.
+
+        secVoltage voltage    I The requested bus voltage.
+
+    RETURNS
+
+	ENODEV			Device driver not loaded/available
+        
+	EBUSY                   Device or resource busy
+        
+	EINVAL                  Invalid argument
+        
+	EPERM                   File not opened with read permissions
+
+	EINTERNAL               Internal error in the device driver
+
+
+
+
+

+

+
+ + diff --git a/dvb-spec/API/dvb_api/video.h b/dvb-spec/API/dvb_api/video.h new file mode 100644 index 000000000..de5ac2b19 --- /dev/null +++ b/dvb-spec/API/dvb_api/video.h @@ -0,0 +1,95 @@ +/* + * video.h + * + * Copyright (C) 2000 Marcus Metzler + * & Ralph Metzler + for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _OST_VIDEO_H_ +#define _OST_VIDEO_H_ + +#define boolean int +#define true 1 +#define false 0 + +typedef enum { + VIDEO_FORMAT_4_3, /* Select 4:3 format */ + VIDEO_FORMAT_16_9 /* Select 16:9 format. */ +} videoFormat_t; + + +typedef enum { + VIDEO_PAN_SCAN, + VIDEO_LETTER_BOX, + VIDEO_CENTER_CUT_OUT +} videoDisplayFormat_t; + + +typedef enum { + VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ + VIDEO_SOURCE_MEMORY /* If this source is selected, the stream + comes from the user through the write + system call */ +} videoStreamSource_t; + +typedef enum { + VIDEO_STOPPED, /* Video is stopped */ + VIDEO_PLAYING, /* Video is currently playing */ + VIDEO_FREEZED /* Video is freezed */ +} videoPlayState_t; + + +struct videoEvent { + int32_t type; + time_t timestamp; + + union { + videoFormat_t videoFormat; + } u; +}; + + +struct videoStatus { + boolean videoBlank; + videoPlayState_t playState; + videoStreamSource_t streamSource; + videoFormat_t videoFormat; + videoDisplayFormat_t displayFormat; +}; + + +struct videoDisplayStillPicture { + char *iFrame; + int32_t size; +}; + +#define VIDEO_STOP _IOW('o', 21, boolean) +#define VIDEO_PLAY _IOW('o', 22, void) +#define VIDEO_FREEZE _IOW('o', 23, void) +#define VIDEO_CONTINUE _IOW('o', 24, void) +#define VIDEO_SELECT_SOURCE _IOW('o', 25, videoStreamSource_t) +#define VIDEO_SET_BLANK _IOW('o', 26, boolean) +#define VIDEO_GET_STATUS _IOR('o', 27, struct videoStatus *) +#define VIDEO_GET_EVENT _IOR('o', 28, struct videoEvent *) +#define VIDEO_SET_DIPLAY_FORMAT _IOW('o', 29, videoDisplayFormat_t) +#define VIDEO_STILLPICTURE _IOW('o', 30, struct videoDisplayStillPicture *) +#define VIDEO_FAST_FORWRD _IOW('o', 31, int) +#define VIDEO_SLOWMOTION _IOW('o', 32, int) + +#endif /*_OST_VIDEO_H_*/ diff --git a/dvb-spec/API/dvb_api/video.xml b/dvb-spec/API/dvb_api/video.xml new file mode 100644 index 000000000..18ff9aa28 --- /dev/null +++ b/dvb-spec/API/dvb_api/video.xml @@ -0,0 +1,666 @@ + + + linuxtv.org|DVB Video API
  + +
 
+   +
+  convergence.de +
+  cryptolabs.org
+  directfb.org +
+  linuxtv.org +
+   +
+  linuxtv
+  projects
+  developer
  +  DVB
   + +  API
  +  DVD
  +  Mbone
  +  CVS
+  download
+  contact
+   +

DVB Video API

+ +

+ The DVB video device controls the MPEG2 video decoder of the DVB hardware. + It can be accessed through /dev/ost/audio. +

+ +

+ The include file video.h describes the data + types and lists all i/o calls. + A complete explanation of all calls can be found below: +

+ + +

+ Video API IO control calls + + +

+

+
+int open(const char *deviceName, int flags);
+
+    FUNCTION
+
+	This system call opens a named video device (e.g. /dev/ost/video) for subsequent
+        use.
+        When an open() call has succeeded, the device will be ready for use.
+        The significance of blocking or non-blocking mode is described in the documentation
+        for functions where there is a difference. It does not affect the semantics of the
+        open() call itself. A device opened in blocking mode can later be put into non-
+        blocking mode (and vice versa) using the F_SETFL command of the fcntl system
+        call.  This is a standard system call, documented in the Linux manual page for fcntl.
+        Only one user can open the Video Device in O_RDWR mode. All other attemts to
+        open the device in this mode will fail, and an errorcode will be returned.
+        If the Video Device is opened in O_RDONLY mode, the only ioctl call that can be used
+        is VIDEO_GET_STATUS. All other call will return an error code.
+
+
+    PARAMETERS
+
+	const char *deviceName	Name of specific video device.  In the current
+                      		implementation,  /dev/ost/video is the only
+                                one available.
+	int flags               A bit-wise OR of the following flags:
+
+                                O_RDONLY read-only access
+
+                                O_RDWR read/write access
+
+                                O_NONBLOCK open in non-blocking mode 
+				           (blocking mode is the default)
+    RETURNS
+    
+	ENODEV                  Device driver not loaded/available.
+
+        EINTERNAL               Internal error, possibly in the communication
+                                with the DVB subsystem.
+
+        EBUSY                   Device or resource busy.
+
+        EINVAL                  Invalid argument.
+
+
+
+

+ +

+

+
+int close(int fd);
+
+    DESCRIPTION
+
+	This system call closes a previously opened video device
+
+    PARAMETERS
+
+        int fd			File descriptor returned by a previous call to open().
+
+    RETURNS
+    
+	EBADF                                   fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+size_t write(int fd, const void *buf, size_t count);
+
+    DESCRIPTION
+    
+	This system call is only provided if VIDEO_SOURCE_MEMORY is selected in the 
+	ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in PES format.
+        If O_NONBLOCK is not specified the function will block until buffer space 
+	is available. The amount of data to be transferred is implied by count.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+        void *buf		Pointer to the buffer containing the PES data.
+
+	size_t count		Size of buf.
+
+    RETURNS
+
+	EPERM                   Mode VIDEO_SOURCE_MEMORY not selected.
+        
+	ENOMEM			Attempted to write more data than the internal buffer can hold.
+
+	EBADF			fd is not a valid open file descriptor
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_STOP, boolean mode); 
+
+    FUNCTION
+	
+	This ioctl call asks the Video Device to stop playing the current stream.
+	Depending on the input parameter, the screen can be blanked out or
+	displaying the last decoded frame.
+
+    PARAMETERS
+
+	int fd 		File descriptor returned by a previous call to open(). 
+
+	int request 	Equals VIDEO_STOP for this command. 
+
+	Boolean mode 	Indicates how the screen shall be handled. 
+
+			TRUE: Blank screen when stop. 
+			FALSE: Show last decoded frame.
+
+    RETURNS
+
+	EBADF 		fd is not a valid open file descriptor 
+
+	EINTERNAL 	Internal error, possibly in the communication with 
+			the DVB subsystem.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_PLAY); 
+
+    FUNCTION 
+	
+	This ioctl call asks the Video Device to start playing a video stream 
+	from the selected source.
+
+    PARAMETERS
+
+	int fd 		File descriptor returned by a previous call to open(). 
+
+	int request 	Equals VIDEO_PLAY for this command.
+
+
+    RETURNS
+
+	EBADF 		fd is not a valid open file descriptor 
+
+	EINTERNAL 	Internal error, possibly in the communication with 
+			the DVB subsystem.
+
+
+
+
+

+ + +

+

+int ioctl(int fd, int request = VIDEO_FREEZE); 
+
+    FUNCTION 
+
+	This ioctl call suspends the live video stream being played. 
+	Decoding and playing are frozen. It is then possible to restart 
+	the decoding and playing process of the video stream using 
+	VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the
+	ioctl call VIDEO_SELECT_SOURCE, the DVB-subsystem will not decode 
+	any more data until the ioctl call VIDEO_FREEZE or VIDEO_PLAY is 
+	performed.
+
+    PARAMETERS 
+	
+	int fd 		File descriptor returned by a previous call to open(). 
+
+	int request 	Equals VIDEO_FREEZE for this command. 
+
+    RETURNS 
+
+	EBADF 		fd is not a valid open file descriptor. 
+
+	EINTERNAL 	Internal error, possibly in the communication with
+			the DVB subsystem.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_CONTINUE); 
+
+    FUNCTION 
+
+	This ioctl call restarts decoding and playing processes of the video
+	stream which was played before a call to VIDEO_FREEZE was made.
+
+    PARAMETERS 
+
+	int fd 		File descriptor returned by a previous call to open(). 
+
+	int request 	Equals VIDEO_CONTINUE for this command.
+
+    RETURNS 
+
+	EBADF 		fd is not a valid open file descriptor. 
+
+	EINTERNAL 	Internal error, possibly in the communication with 
+			the DVB subsystem.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_SELECT_SOURCE, videoStreamSource_t source); 
+
+    FUNCTION
+	
+	This ioctl call informs the video device which source shall be used 
+	for the input data. The possible sources are demux or memory. If 
+	internal is selected, the data is feed to the Video Device through 
+	the write command.
+
+    PARAMETERS 
+
+	int fd 		File descriptor returned by a previous call to open(). 
+
+	int request 	Equals VIDEO_SELECT_SOURCE for this command. 
+
+	videoStreamSource_t source 
+			Indicates which source shall be used for the Video stream.
+
+    RETURNS 
+
+	EBADF 		fd is not a valid open file descriptor. 
+	
+	EINTERNAL 	Internal error, possibly in the communication with 
+			the DVB subsystem.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_SET_BLANK, boolean mode);
+
+    DESCRIPTION
+	
+	This ioctl call asks the Video Device to blank out the picture.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+        int request		Equals VIDEO_SET_BLANK for this command.
+
+	boolean mode		TRUE: Blank screen when stop.
+                 		FALSE:  Show last decoded frame.
+
+    RETURNS
+
+	EBADF		      	fd is not a valid open file descriptor.
+
+        EINTERNAL		Internal error
+	
+	EINVAL      		Illegal input parameter.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_GET_STATUS, struct videoStatus *status);
+
+    DESCRIPTION
+    
+	This ioctl call asks the Video Device to return the current status of the device.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals VIDEO_GET_STATUS for this command.
+
+	struct videoStatus      Returns the current status of the Video Device.
+               *status
+
+
+    RETURNS
+
+	EBADF    		fd is not a valid open file descriptor.
+
+	EINTERNAL  		Internal error
+
+	EFAULT                  status points to invalid address
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_GET_EVENT, struct videoEvent *ev);
+
+    DESCRIPTION
+
+	This ioctl call returns an event of type videoEvent if available.
+	If an event is not available, the behavior depends on whether the device is in
+	blocking or non-blocking mode.  In the latter case, the call fails immediately
+	with errno set to EWOULDBLOCK. In the former case, the call blocks until an 
+	event becomes available.
+        The standard Linux poll() and/or select() system calls can be used with the 
+	device file descriptor to watch for new events.  For select(), the file 
+	descriptor should be included in the exceptfds argument, and for poll(), 
+	POLLPRI should be specified as the wake-up condition.
+        Read-only permissions are sufficient for this ioctl call.
+
+    PARAMETERS
+          
+	int fd			File descriptor returned by a previous call to open().
+
+        int request		Equals VIDEO_GET_EVENT for this command.
+
+	struct videoEvent *ev 	Points to the location where the event, if any, is
+                                to be stored.
+
+
+    RETURNS
+    
+	EBADF    		fd is not a valid open file descriptor
+
+	EFAULT                  ev points to invalid address
+
+        EWOULDBLOCK             There is no event pending, and the device is in 
+				non-blocking mode.
+
+        EBUFFEROVERFLOW         Overflow in event queue - one or more events were lost.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_SET_DISPLAY_FORMAT, videoDisplayFormat_t format);
+
+    DESCRIPTION
+
+	This ioctl call asks the Video Device to select the video format to be applied
+	by the MPEG chip on the video.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals  VIDEO_SET_DISPLAY_FORMAT for this command.
+
+	videoDisplayFormat_t	Selects the video format to be used.
+        format
+        
+    RETURNS
+    
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+        EINVAL			Illegal parameter format.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_STILLPICTURE, struct videoDisplayStillPicture *sp);
+
+    DESCRIPTION
+
+	This ioctl call asks the Video Device to display a still picture (I-frame). 
+	The input data shall contain an I-frame. If the pointer is NULL, then the 
+	current displayed still picture is blanked.
+	
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals VIDEO_STILLPICTURE for this command.
+
+        struct videoDisplayStillPicture	*sp	Pointer to a location where an I-frame
+                                        	and size is stored.
+
+    RETURNS
+	
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+	EFAULT			sp points to an invalid iframe.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_FAST_FORWARD, int nFrames);
+
+    DESCRIPTION
+    
+	This ioctl call asks the Video Device to skip decoding of N number of I-frames.
+	This call can only be used if VIDEO_SOURCE_INTRENAL is selected.
+
+    PARAMETERS
+	
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals VIDEO_FAST_FORWARD for this command.
+
+	int nFrames		The number of frames to skip.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL               Internal error
+
+        EPERM			Mode VIDEO_SOURCE_MEMORY not selected.
+
+	EINVAL			Illegal parameter format.
+
+
+
+
+

+ +

+

+
+int ioctl(int fd, int request = VIDEO_SLOWMOTION, int nFrames);
+
+    DESCRIPTION
+
+	This ioctl call asks the Video Device to repeat decoding frames N number of times.
+	This call can only be used if VIDEO_SOURCE_MEMORY is selected.
+
+    PARAMETERS
+
+	int fd			File descriptor returned by a previous call to open().
+
+	int request		Equals VIDEO_SLOWMOTION for this command.
+
+	int nFrames		The number of frames to skip.
+
+    RETURNS
+
+	EBADF			fd is not a valid open file descriptor.
+
+	EINTERNAL		Internal error
+
+        EPERM                   Mode VIDEO_SOURCE_MEMORY not selected.
+
+        EINVAL                  Illegal parameter format.
+
+
+
+
+

+ +

+ +
+ + -- cgit v1.2.3 From fe468b0b8c98736ad218453c397cb062897e8a35 Mon Sep 17 00:00:00 2001 From: rjkm Date: Thu, 8 Feb 2001 01:38:48 -0200 Subject: XML version of full API description --- dvb-spec/API/linux_dvb_api.xml | 3592 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3592 insertions(+) create mode 100644 dvb-spec/API/linux_dvb_api.xml diff --git a/dvb-spec/API/linux_dvb_api.xml b/dvb-spec/API/linux_dvb_api.xml new file mode 100644 index 000000000..b1040ffe5 --- /dev/null +++ b/dvb-spec/API/linux_dvb_api.xml @@ -0,0 +1,3592 @@ + + + +
+ +Linux DVB API + +Documentation + + + + + + Dr. + Ralph + Metzler + rjkm@convergence.de + + + + Andreas + Bogk + bogk@convergence.de + + +feb. 7, 2000 +2000convergence +integrated media GmbH + +
Rosenthalerstr. 51, 10178 Berlin
+ + linux + dvb + api + documentation + + + +About the Linux DVB API + + + +The Linux DVB API is based on a proposal by Nokia. As a commitment to the +development of terminals based on open standards, Nokia and convergence published +it on linuxtv.org. + + + + Convergence is +the maintainer of the Linux DVB API. Together with the LinuxTV community +(i.e. you, the reader of this document), the Linux DVB API will be constantly +reviewed and improved. With the Linux driver for the Siemens/ Hauppauge DVB PCI +card convergence provides a first implementation of the Linux DVB API. + + + + +
+ + + + + Introduction + + + + Part of the DVB API builds upon the Video4Linux + (V4L) API. The Siemens DVB card uses the SAA7146 as PCI bridge. A + generic SAA7146 Linux + driver for this chip implements the basic V4L + interface. + + + An older version of the API included the DVB specific calls into + the V4L interface. This turned out to be very cumbersome to + program. Since we also hoped to arrive at a common standard for all + Linux platforms, especially those in embedded consumer devices, we were + happy to find Nokia + as a partner in this effort. They will be using the same API in their + upcoming + + Media Terminal. + + + In the new version of the API only display and grabbing of the + already decompressed images is handled through the V4L device. All + other DVB features like tuning, filtering and playback/recording of the + compressed data stream are accessed through separate devices. + + + A first implementations of the Linux DVB API for the Siemens/ + Hauppauge DVB PCI card is available in the LinuxTV Public + CVS. + + + + + + DVB Devices + + + There are currently 6 DVB devices: Video, Audio, Frontend, SEC, + Demux and CA. The APIs of those devices are described in the + sections below. + + + + DVB Video API + + + The DVB video device controls the MPEG2 video decoder of the DVB hardware. + It can be accessed through /dev/ost/audio. + + + The include file video.h describes the data + types and lists all i/o calls. A complete explanation of all calls can + be found below: + + + + Video API IO control calls + + +
+ +int open(const char *deviceName, int flags); + + FUNCTION + + This system call opens a named video device (e.g. /dev/ost/video) for subsequent + use. + When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in the documentation + for functions where there is a difference. It does not affect the semantics of the + open() call itself. A device opened in blocking mode can later be put into non- + blocking mode (and vice versa) using the F_SETFL command of the fcntl system + call. This is a standard system call, documented in the Linux manual page for fcntl. + Only one user can open the Video Device in O_RDWR mode. All other attemts to + open the device in this mode will fail, and an errorcode will be returned. + If the Video Device is opened in O_RDONLY mode, the only ioctl call that can be used + is VIDEO_GET_STATUS. All other call will return an error code. + + + PARAMETERS + + const char *deviceName Name of specific video device. In the current + implementation, /dev/ost/video is the only + one available. + int flags A bit-wise OR of the following flags: + + O_RDONLY read-only access + + O_RDWR read/write access + + O_NONBLOCK open in non-blocking mode + (blocking mode is the default) + RETURNS + + ENODEV Device driver not loaded/available. + + EINTERNAL Internal error, possibly in the communication + with the DVB subsystem. + + EBUSY Device or resource busy. + + EINVAL Invalid argument. + + +
+
+ + +
+ +int close(int fd); + + DESCRIPTION + + This system call closes a previously opened video device + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + RETURNS + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+size_t write(int fd, const void *buf, size_t count); + + DESCRIPTION + + This system call is only provided if VIDEO_SOURCE_MEMORY is selected in the + ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in PES format. + If O_NONBLOCK is not specified the function will block until buffer space + is available. The amount of data to be transferred is implied by count. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + void *buf Pointer to the buffer containing the PES data. + + size_t count Size of buf. + + RETURNS + + EPERM Mode VIDEO_SOURCE_MEMORY not selected. + + ENOMEM Attempted to write more data than the internal buffer can hold. + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_STOP, boolean mode); + + FUNCTION + + This ioctl call asks the Video Device to stop playing the current stream. + Depending on the input parameter, the screen can be blanked out or + displaying the last decoded frame. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_STOP for this command. + + Boolean mode Indicates how the screen shall be handled. + + TRUE: Blank screen when stop. + FALSE: Show last decoded frame. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EINTERNAL Internal error, possibly in the communication with + the DVB subsystem. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_PLAY); + + FUNCTION + + This ioctl call asks the Video Device to start playing a video stream + from the selected source. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_PLAY for this command. + + + RETURNS + + EBADF fd is not a valid open file descriptor + + EINTERNAL Internal error, possibly in the communication with + the DVB subsystem. + + + +
+
+ + + +
+int ioctl(int fd, int request = VIDEO_FREEZE); + + FUNCTION + + This ioctl call suspends the live video stream being played. + Decoding and playing are frozen. It is then possible to restart + the decoding and playing process of the video stream using + VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the + ioctl call VIDEO_SELECT_SOURCE, the DVB-subsystem will not decode + any more data until the ioctl call VIDEO_FREEZE or VIDEO_PLAY is + performed. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_FREEZE for this command. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error, possibly in the communication with + the DVB subsystem. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_CONTINUE); + + FUNCTION + + This ioctl call restarts decoding and playing processes of the video + stream which was played before a call to VIDEO_FREEZE was made. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_CONTINUE for this command. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error, possibly in the communication with + the DVB subsystem. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_SELECT_SOURCE, videoStreamSource_t source); + + FUNCTION + + This ioctl call informs the video device which source shall be used + for the input data. The possible sources are demux or memory. If + internal is selected, the data is feed to the Video Device through + the write command. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_SELECT_SOURCE for this command. + + videoStreamSource_t source + Indicates which source shall be used for the Video stream. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error, possibly in the communication with + the DVB subsystem. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_SET_BLANK, boolean mode); + + DESCRIPTION + + This ioctl call asks the Video Device to blank out the picture. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_SET_BLANK for this command. + + boolean mode TRUE: Blank screen when stop. + FALSE: Show last decoded frame. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EINVAL Illegal input parameter. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_GET_STATUS, struct videoStatus *status); + + DESCRIPTION + + This ioctl call asks the Video Device to return the current status of the device. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_GET_STATUS for this command. + + struct videoStatus Returns the current status of the Video Device. + *status + + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EFAULT status points to invalid address + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_GET_EVENT, struct videoEvent *ev); + + DESCRIPTION + + This ioctl call returns an event of type videoEvent if available. + If an event is not available, the behavior depends on whether the device is in + blocking or non-blocking mode. In the latter case, the call fails immediately + with errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available. + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Read-only permissions are sufficient for this ioctl call. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_GET_EVENT for this command. + + struct videoEvent *ev Points to the location where the event, if any, is + to be stored. + + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT ev points to invalid address + + EWOULDBLOCK There is no event pending, and the device is in + non-blocking mode. + + EBUFFEROVERFLOW Overflow in event queue - one or more events were lost. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_SET_DISPLAY_FORMAT, videoDisplayFormat_t format); + + DESCRIPTION + + This ioctl call asks the Video Device to select the video format to be applied + by the MPEG chip on the video. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_SET_DISPLAY_FORMAT for this command. + + videoDisplayFormat_t Selects the video format to be used. + format + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EINVAL Illegal parameter format. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_STILLPICTURE, struct videoDisplayStillPicture *sp); + + DESCRIPTION + + This ioctl call asks the Video Device to display a still picture (I-frame). + The input data shall contain an I-frame. If the pointer is NULL, then the + current displayed still picture is blanked. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_STILLPICTURE for this command. + + struct videoDisplayStillPicture *sp Pointer to a location where an I-frame + and size is stored. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EFAULT sp points to an invalid iframe. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_FAST_FORWARD, int nFrames); + + DESCRIPTION + + This ioctl call asks the Video Device to skip decoding of N number of I-frames. + This call can only be used if VIDEO_SOURCE_INTRENAL is selected. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_FAST_FORWARD for this command. + + int nFrames The number of frames to skip. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EPERM Mode VIDEO_SOURCE_MEMORY not selected. + + EINVAL Illegal parameter format. + + + +
+
+ + +
+ +int ioctl(int fd, int request = VIDEO_SLOWMOTION, int nFrames); + + DESCRIPTION + + This ioctl call asks the Video Device to repeat decoding frames N number of times. + This call can only be used if VIDEO_SOURCE_MEMORY is selected. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals VIDEO_SLOWMOTION for this command. + + int nFrames The number of frames to skip. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EPERM Mode VIDEO_SOURCE_MEMORY not selected. + + EINVAL Illegal parameter format. + +
+
+ +
+ +
+ + + DVB Audio API + + The DVB audio device controls the MPEG2 audio decoder of the + DVB hardware. It can be accessed through /dev/ost/audio. + + + The function calls defined in the include file audio.h are described in + detail below: + + + + Audio API IO control calls + + +
+ +int open(const char *deviceName, int flags); + + DESCRIPTION + + This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + use. When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not affect + the semantics of the open() call itself. A device opened in blocking mode can + later be put into non-blocking mode (and vice versa) using the F_SETFL command + of the fcntl system call. This is a standard system call, documented in the + Linux manual page for fcntl. + Only one user can open the Audio Device in O_RDWR mode. All other attempts to + open the device in this mode will fail, and an errorcode will be returned. + If the Audio Device is opened in O_RDONLY mode, the only ioctl call that can + be used is AUDIO_GET_STATUS. All other call will return with an error code. + + + PARAMETERS + + const char *deviceName Name of specific audio device. + + int flags A bit-wise OR of the following flags: + + O_RDONLY read-only access + + O_RDWR read/write access + + O_NONBLOCK open in non-blocking mode + (blocking mode is the default) + + RETURNS + + ENODEV Device driver not loaded/available. + + EINTERNAL Internal error + + EBUSY Device or resource busy. + + EINVAL Invalid argument. + + + +
+
+ + +
+ +int close(int fd); + + DESCRIPTION + + This system call closes a previously opened audio device + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + RETURNS + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +size_t write(int fd, const void *buf, size_t count); + + DESCRIPTION + + This system call can only be used if AUDIO_SOURCE_MEMORY is selected in the + ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in PES format. + If O_NONBLOCK is not specified the function will block until buffer space is + available. The amount of data to be transferred is implied by count. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + void *buf Pointer to the buffer containing the PES data. + + size_t count Size of buf. + + RETURNS + + EPERM Mode VIDEO_SOURCE_INTERNAL not selected. + + ENOMEM Attempted to write more data than the internal + buffer can hold. + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_STOP); + + DESCRIPTION + + This ioctl call asks the Audio Device to stop playing the current stream. + + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_STOP for this command. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EINTERNAL Internal error + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_PLAY); + + DESCRIPTION + + This ioctl call asks the Audio Device to start playing an audio stream from the + selected source. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_PLAY for this command. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_PAUSE); + + DESCRIPTION + + This ioctl call suspends the audio stream being played. Decoding and playing are + paused. It is then possible to restart again decoding and playing process of the + audio stream using AUDIO_CONTINUE command. + If AUDIO_SOURCE_MEMORY is selected in the ioctl call AUDIO_SELECT_SOURCE, the + DVB-subsystem will not decode (consume) any more data until the ioctl call + AUDIO_CONTINUE or AUDIO_PLAY is performed. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_PAUSE for this command. + + RETURNS + + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_CONTINUE); + + DESCRIPTION + + This ioctl call restarts decoding and playing processes of the audio stream, + which was played before, a call to AUDIO_PAUSE was made. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_CONTINUE for this command. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error, possibly in the communication + with the DVB subsystem. + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_SELECT_SOURCE, audioStreamSource_t source); + + DESCRIPTION + + This ioctl call informs the audio device which source shall be used for the + input data. The possible sources are demux or memory. If AUDIO_SOURCE_MEMORY + is selected, the data is fed to the Audio Device through the write command. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_SELECT_SOURCE for this command. + + audioStreamSource_t source Indicates the source that shall be used for the + Audio stream. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_SET_MUTE, boolean state); + + DESCRIPTION + + This ioctl call asks the audio device to mute the stream that is currently being + played. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_SET_MUTE for this command. + + boolean state Indicates if audio device shall mute or not. + TRUE Audio Mute + FALSE Audio Unmute + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error, + + EINVAL Illegal input parameter. + +
+
+ + +
+int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, boolean state); + + DESCRIPTION + + This ioctl call asks the Audio Device to turn ON or OFF A/V synchronisation. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_AV_SYNC for this command. + + boolean state Tells the DVB subsystem if A/V synchronisation shall be ON or OFF. + TRUE AV-sync ON + FALSE AV-sync OFF + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EINVAL Illegal input parameter. + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, boolean mode); + + DESCRIPTION + + This ioctl call asks the Audio Device to bypass the Audio decoder and forward + the stream without decoding. This mode shall be used if streams that can't be + handled by the DVB system shall be decoded. Dolby DigitalTM streams are + automatically forwarded by the DVB subsystem. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_SET_BYPASS_MODE for this command. + + boolean mode Enables or disables the decoding of the current + Audio stream in the DVB subsystem. + TRUE Bypass is disabled + FALSE Bypass is enabled + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EINVAL Illegal pointer mode. + + +
+
+ + +
+int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT, audioChannelSelect_t) + + DESCRIPTION + + This ioctl call asks the Audio Device to select the requested channel if possible. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_CHANNEL_SELECT for this command. + + audioChannelSelect_t ch Select the output format of the audio (Mono, stereo) + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EINVAL Illegal pointer ch. + + + +
+
+ + +
+ +int ioctl(int fd, int request = AUDIO_GET_STATUS, struct audioStatus *status) + + DESCRIPTION + + This ioctl call asks the Audio Device to return the current state of the Audio + Device. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals AUDIO_GET_STATUS for this command. + + struct audioStatus *status Returns the current state of Audio Device + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EINTERNAL Internal error + + EFAULT status points to invalid address + + + +
+
+ +
+ +
+ + + DVB Frontend API + + + The DVB frontend device controls the frontend of the DVB hardware, e.g. + tuning, symbol rate, error correction, ... + It is accessed through /dev/ost/qpskfe. + + + The function calls defined in the include file frontend.h are described + in detail below: + + + + Frontend API IO control calls + + +
+ +int open(const char *deviceName, int flags); + + DESCRIPTION + + This system call opens a named front-end device (e.g. /dev/qpskfe) for + subsequent use. The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end device opened in blocking mode can later be put into non-blocking + mode (and vice versa) using the F_SETFL command of the fcntl system call. + This is a standard system call, documented in the Linux manual page for fcntl. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + PARAMETERS + + const char *deviceName I Name of specific front-end device. In the + current implementation, /dev/qpskfe is the + only one available (QPSK satellite front-end.) + + int flags I A bit-wise OR of the following flags: + O_RDONLY read-only access + O_RDWR read/write access + O_NONBLOCK open in non-blocking mode + (blocking mode is the default) + RETURNS + + ENODEV Device driver not loaded/available. + + EBUSY Device or resource busy. + + EINVAL Invalid argument. + + + +
+
+ + +
+ +int close(int fd); + + DESCRIPTION + + This system call closes a previously opened front-end device. After closing a + front-end device, its corresponding hardware might be powered down + automatically, but only when this is needed to open another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST_SET_POWER_STATE ioctl. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + RETURNS + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +int ioctl(int fd, int request = OST_SELFTEST); + + DESCRIPTION + + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals OST_SELFTEST for this command. + + RETURNS + + 0 Success + + -1 Failure + + + +
+
+ + +
+ +int ioctl(int fd, int request = OST_SET_POWER_STATE, uint32_t state); + + DESCRIPTION + + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time. + + A device that implements this call does not necessarily support two low-power + modes. If it only support one low-power state, or none at all, the + OST_SET_POWER_STATE operation for the missing states will still succeed, but + it will be mapped to an existing state as per this table: + + number of low-power requested state resulting state + states supported + + 1 standby suspend + + 1 suspend suspend + + 0 standby on + + 0 suspend on + + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again. + + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals OST_SET_POWER_STATE for this command. + + uint32_t state I Requested power state. One of: + + OST_POWER_ON: turn power on + OST_POWER_STANDBY: set device in standby mode + OST_POWER_SUSPEND: set device in suspend mode + OST_POWER_OFF: turn power off + + + RETURNS + + EBADF fd is not a valid open file descriptor + + EINVAL illegal state, or not available on this device + + EPERM permission denied (needs read/write access) + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl(int fd, int request = OST_GET_POWER_STATE, uint32_t *state); + + DESCRIPTION + + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals OST_GET_POWER_STATE for this command. + + uint32_t *state O Pointer to a variable where the power state is + to be stored. Possible values are: + OST_POWER_ON power is on + OST_POWER_STANDBY device in + standby mode + OST_POWER_SUSPEND: device in + suspend mode + OST_POWER_OFF: power is off + + + RETURNS + + EBADF fd is not a valid open file descriptor + + EINVAL illegal state, or not available on this device + + EFAULT state points to invalid address + + EPERM permission denied (needs read/write access) + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_READ_STATUS, feStatus *status); + + DESCRIPTION + + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_READ_STATUS for this command. + + struct feStatus *status O Points to the location where the front-end + status word is to be stored. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT status points to invalid address + + + +
+
+ + +
+ +int ioctl(int fd, int request = FE_READ_BER, uint32_t *ber); + + DESCRIPTION + + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + + FUNCTION PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_READ_BER for this command. + + uint32_t *ber O The bit error rate, as a multiple of 10-9, is stored into *ber. + + Example: a value of 2500 corresponds to a bit error + rate of 2.5 10-6, or 1 error in 400000 bits. + + RETURNS + + EBADF fd is not a valid open file descriptor. + + EFAULT ber points to invalid address + + ENOSIGNAL There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on. + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl( int fd, int request = FE_READ_SIGNAL_STRENGTH, int32_t *strength); + + DESCRIPTION + + This ioctl call returns the signal strength value for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_READ_SIGNAL_STRENGTH for this + command. + int32_t *strength O The signal strength value, as a multiple of 10^-6 dBm, + is stored into *strength. + Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT strength points to invalid address + + ENOSIGNAL There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not + turned on. + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl(int fd, int request = FE_READ_SNR, int32_t *snr); + + DESCRIPTION + + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_READ_SNR for this command. + + int32_t *snr O The signal-to-noise ratio, as a multiple of + 10^-6 dB, is stored into *snr. + + Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT snr points to invalid address + + ENOSIGNAL No stable signal, thus no meaningful signal-to- + noise ratio. Also returned if front-end is not + turned on. + + ENOSYS Function not available for this device. +
+
+ + +
+int ioctl( int fd, int request = FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks); + + + DESCRIPTION + + This ioctl call returns the number of uncorrected blocks detected by the device + driver during its lifetime. For meaningful measurements, the increment in + block count during a specific time interval should be calculated2. For this + command, read-only access to the device is sufficient. + + 2 Note that the counter will wrap to zero after its maximum count has + been reached (232-1). + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_READ_UNCORRECTED_BLOCKS for this command. + + uint32_t *ublocks O The total number of uncorrected blocks seen + by the driver so far. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT ublocks points to invalid address + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl( int fd, int request = FE_GET_NEXT_FREQUENCY, uint32_t *freq); + + DESCRIPTION + + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient3 scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + + 3 Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_GET_NEXT_FREQUENCY for this command. + + uint32_t *freq I/O Input: a given frequency + Output: the frequency corresponding to + the next higher frequency setting. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT freq points to invalid address + + EINVAL maximum frequency reached + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl( int fd, int request = FE_GET_NEXT_SYMBOL_RATE, uint32_t *symbolRate); + + DESCRIPTION + + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient4 scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals FE_GET_NEXT_SYMBOL_RATE for this command. + + uint32_t *symbolRate I/O Input: a given symbol rate + Output: the symbol rate corresponding to the next higher symbol rate setting. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT symbolRate points to invalid address + + EINVAL maximum symbol rate reached + + ENOSYS Function not available for this device. + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_TUNE, struct qpskParameters *p); + + DESCRIPTION + + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for QPSK_GET_EVENT and qpskEvent.) + If a new QPSK_TUNE operation is initiated before the previous one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request Equals QPSK_TUNE for this command. + + struct qpskParameters *p Points to parameters for tuning operation. + + RETURNS + + EBADF fd is not a valid open file descriptor + EFAULT p points to invalid address + EINVAL parameter value(s) not valid + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_GET_EVENT, struct qpskEvent *ev); + + DESCRIPTION + + This ioctl call returns an event of type qpskEvent if available. If an event + is not available, the behavior depends on whether the device is in blocking + or non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an event + becomes available. + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK_GET_EVENT calls will return events from the queue as + usual. + For the sake of implementation simplicity, this command requires read/write + access to the device. + + PARAMETERS + + int fd File descriptor returned by a previous call to open(). + + int request I Equals QPSK_GET_EVENT for this command. + + struct qpskEvent *ev O Points to the location where the event, if any, is to be stored. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT ev points to invalid address + + EWOULDBLOCK There is no event pending, and the device is in + non-blocking mode. + + EBUFFEROVERFLOW Overflow in event queue - one or more events were lost. + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_FE_INFO, struct qpskFrontendInfo *info); + + DESCRIPTION + + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals QPSK_FE_INFO for this command. + + struct qpskFrontendInfo *info O Points to the location where the front-end + information is to be stored. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT info points to invalid address + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_WRITE_REGISTER, struct qpskRegister *reg); + + DESCRIPTION + + This ioctl call is intended for hardware-specific diagnostics. It writes + an 8-bit value at an 8-bit address of a register in a chip identified by an + 8-bit index. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals QPSK_WRITE_REGISTER for this command. + + struct qpskRegister *reg I Specifies a value that should be written + into a specified register in a specified chip. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT reg points to and invalid address + + EINVAL Register specification invalid. + + + + +
+
+ + +
+ +int ioctl(int fd, int request = QPSK_READ_REGISTER, struct qpskRegister *reg); + + DESCRIPTION + + This ioctl call is intended for hardware-specific diagnostics. + It reads an 8-bit value at an 8-bit address of a register in a chip + identified by an 8-bit index. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals QPSK_READ_REGISTER for this command. + + struct qpskRegister *reg I/O I: specifies a register in a specified + chip from which a value should be read. + + O: the value is read into the + qpskRegister structure. + + RETURNS + + EBADF fd is not a valid open file descriptor + + EFAULT reg points to and invalid address + + EINVAL Register specification invalid. + + + +
+
+ +
+ +
+ + + DVB SEC API + + + The DVB SEC device controls the Satellite Equipment Control of + the DVB hardware, i.e. DiSEqC and V-SEC. + It is accessed through /dev/ost/sec. + + + The function calls defined in the include file sec.h aredescribed in detail + below: + + + + SEC API IO control calls + + +
+ +int open(const char *deviceName, int flags); + + DESCRIPTION + + This system call opens a named SEC device for subsequent use. + If the device is opened in read-only mode, only status and statistics + monitoring is allowed. If the device is opened in read/write mode, all + types of operations can be performed. + Any number of applications can have simultaneous access to the device. + + PARAMETERS + + const char *deviceName I Name of the SEC device. + + int flags I Valid values are: + O_RDONLY read-only access + O_RDWR read/write access + + The optional flag O_NONBLOCK is not supported. If O_NONBLOCK is set, + open() and most other subsequent calls to the device will return -1 and + set errno to EWOULDBLOCK. + The communication with the peripheral devices is sequential by nature, + so it is probably preferable to use the device in synchronous mode. + This is the motivation for not going through the extra effort of + implementing asynchronous operation of the device. + + RETURNS + + ENODEV Device not loaded/available + EFAULT deviceName does not refer to a valid memory area. + EINVAL Invalid argument + + + +
+
+ + +
+ +int close(int fd); + + DESCRIPTION + + This system call closes a previously opened SEC device. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + RETURNS + + EBADF fd is not a valid file descriptor. + + + +
+
+ + +
+ +int ioctl(int fd, int request = SEC_GET_STATUS, struct secStatus* status); + + DESCRIPTION + + This call gets the status of the device. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals SEC_GET_STATUS for this command. + + struct secStatus* status O The status of the device. + + RETURNS + + ENODEV Device driver not loaded/available + + EFAULT status is an invalid pointer + + EBUSY Device or resource busy + + EINVAL Invalid argument + + EPERM File not opened with read permissions + + EINTERNAL Internal error in the device driver + + + +
+
+ + +
+ +int ioctl(int fd, int request = SEC_RESET_OVERLOAD); + + DESCRIPTION + + If the bus has been automatically powered off due to power overload, this + ioctl call restores the power to the bus. The call requires read/write + access to the device. + This call has no effect if the device is manually powered off. + + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals SEC_RESET_OVERLOAD for this command. + + RETURNS + + EBADF fd is not a valid file descriptor. + + EPERM Permission denied (needs read/write access) + + EINTERNAL Internal error in the device driver + + + +
+
+ + +
+ +int ioctl(int fd, int request = SEC_SEND_SEQUENCE, struct secCmdSequence *seq); + + DESCRIPTION + + This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC + commands. The first version of the SEC device does not support V-SEC + signalling and it aborts the operation with an error code if a V-SEC + command is detected in the input data. + + ! The call will fail with errno set to EBUSOVERLOAD if the bus is + overloaded. If the bus is overloaded, SEC_RESET_OVERLOAD can be + called and the operation can be retried. + + ! If seq.numCommands equals 0 and seq.miniCommand equals SEC_MINI_NONE, + the bus voltage will be switched and the continuous 22kHz tone + generation enabled/disabled immediately. + + This operation is atomic. If several processes calls this ioctl + simultaneously, the operations will be serialised so a complete sequence + is sent at a time. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals SEC_SEND_SEQUENCE for this command. + + struct secCmdSequence *seq I Pointer to the command sequence to be transmitted. + + RETURNS + + EBADF Fd is not a valid file descriptor. + + EFAULT Seq points to an invalid address. + + EINVAL The data structure referred to by seq is invalid in + some way. + + EPERM Permission denied (needs read/write access) + + EINTERNAL Internal error in the device driver + + + EBUSMODE The device is not prepared for transmission + (e.g. it might be manually powered off). + + EBUSOVERLOAD Bus overload has occurred. + + + +
+
+ + +
+ +int ioctl(int fd, int request = SEC_SET_TONE, secToneMode tone); + + DESCRIPTION + + This call is used to set the generation of the continuous 22kHz tone. + The possibility to just change the tone mode is already provided by + ioctl SEC_SEND_SEQUENCE, but SEC_SET_TONE is an easier to use interface. + To keep the transmission of a command sequence (see section 4.4.5 ) as + an atomic operation, SEC_SET_TONE will block if a transmission is in + progress. This call requires read/write permissions. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals SEC_SET_TONE for this command. + + secToneMode tone I The requested tone generation mode (on/off). + + RETURNS + + ENODEV Device driver not loaded/available + + EBUSY Device or resource busy + + EINVAL Invalid argument + + EPERM File not opened with read permissions + + EINTERNAL Internal error in the device driver + + + +
+
+ + +
+ +int ioctl(int fd, int request = SEC_SET_VOLTAGE, secVoltage voltage); + + DESCRIPTION + + This call is used to set the bus voltage. The possibility to just change + the bus voltage is already provided by ioctl SEC_SEND_SEQUENCE, but + SEC_SET_VOLTAGE is an easier to use interface. + To keep the transmission of a command sequence (see section 4.4.5 ) as + an atomic operation, SEC_SET_VOLTAGE will block if a transmission is in + progress. + This call requires read/write permissions. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals SEC_SET_VOLTAGE for this command. + + secVoltage voltage I The requested bus voltage. + + RETURNS + + ENODEV Device driver not loaded/available + + EBUSY Device or resource busy + + EINVAL Invalid argument + + EPERM File not opened with read permissions + + EINTERNAL Internal error in the device driver + + + +
+
+ +
+ +
+ + + DVB Demux API + + + The DVB demux device lets you set TS, PID and section filters in the DVB + device. This is internally accomplished through calls to the + demux kernel module. + The demux device can be accessed through /dev/ost/demux. + + + The function calls defined in the include file dmx.h are described in detail + below: + + + + Demux API IO control calls + + +
+ +int open(const char *deviceName, int flags); + + DESCRIPTION + + This system call, used with a device name of /dev/ost/demuxn, where n + denotes the specific demux device to be opened, allocates a new filter + and returns a handle which can be used for subsequent control of that + filter. This call has to be made for each filter to be used, i.e. every + returned file descriptor is a reference to a single filter. + /dev/ost/dvrn is a logical device to be used for retrieving Transport + Streams for digital video recording. n identifies the physical demux + device that provides the actual DVR functionlaity. When reading from + this device a transport stream containing the packets from all PES + filters set in the corresponfing demux device (/dev/osst/demuxn) + having the output set to DMX_OUT_TS_TAP. A recorded Transport Stream + is replayed by writing to this device. + This device can only be opened in read-write mode. + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not + affect the semantics of the open() call itself. A device opened in + blocking mode can later be put into non-blocking mode + (and vice versa) using the F_SETFL command of the fcntl system call. + + + PARAMETERS + + const char *deviceName I Name of the demux device, which should be + /dev/ost/demuxn where n denotes the + specific demux device to be opened, or the + name of a logical DVR device, /dev/ost/dvrn. + + int flags I A bit-wise OR of the following flags: + O_RDWR read/write access. + O_NONBLOCK open in non-blocking mode + (blocking mode is the default). + + RETURNS + + ENODEV Device driver not loaded/available. + + EINVAL Invalid argument. + + EMFILE "Too many open files", i.e. no more filters available. + + ENOMEM The driver failed to allocate enough memory. + + + +
+
+ + +
+ +int close(int fd); + + DESCRIPTION + + This system call deactivates and deallocates a filter that was previously + allocated via the open() call. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + RETURNS + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +size_t read(int fd, void *buf, size_t count); + + DESCRIPTION + + This system call returns filtered data, which might be section or PES + data. The filtered data is transferred from the driver's internal circular + buffer to buf. The maximum amount of data to be transferred is implied by + count. + + When returning section data the driver always tries to return a complete + single section (even though buf would provide buffer space for more data). + If the size of the buffer is smaller than the section as much as possible + will be returned, and the remaining data will be provided in subsequent + calls. + The size of the internal buffer is 2 * 4096 bytes (the size of two maximum + sized sections) by default. The size of this buffer may be changed by + using the DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, + or if the read operations are not performed fast enough, this may result + in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, + and the circular buffer will be emptied. + This call is blocking if there is no data to return, i.e. the process + will be put to sleep waiting for data, unless the O_NONBLOCK flag is + specified. + Note that in order to be able to read, the filtering process has to be + started by defining either a section or a PES filter by means of the + ioctl functions, and then starting the filtering process via the DMX_START + ioctl function or by setting the DMX_IMMEDIATE_START flag. + If the reading is done from a logical DVR demux device, the data will + constitute a Transport Stream including the packets from all PES filters + in the corresponding demux device /dev/ost/demuxn having the output set + to DMX_OUT_TS_TAP. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + void *buf O Pointer to the buffer to be used for returned filtered data. + + size_t count I Size of buf. + + RETURNS + + EWOULDBLOCK No data to return and O_NONBLOCK was specified. + + EBADF fd is not a valid open file descriptor + + ECRC Last section had a CRC error - no data + returned. The buffer is flushed. + + EBUFFEROVERFLOW The filtered data was not read from the buffer in + due time, resulting in non-read data being lost. + The buffer is flushed. + + ETIMEDOUT The section was not loaded within the stated + timeout period. See ioctl DMX_SET_FILTER for + how to set a timeout. + + EFAULT The driver failed to write to the callers buffer + due to an invalid *buf pointer. + + + +
+
+ + +
+ +ssize_t write(int fd, const void *buf, size_t count); + + DESCRIPTION + + This system call is only provided by the logical device /dev/ost/dvrn, + where n identifies the physical demux device that provides the actual + DVR functionality. It is used for replay of a digitally recorded + Transport Stream. Matching filters have to be defined in the + corresponding physical demux device, /dev/ost/demuxn. + The amount of data to be transferred is implied by count. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + void *buf I Pointer to the buffer containing the Transport Stream. + + size_t count I Size of buf. + + RETURNS + + EWOULDBLOCK No data was written. This might happen if + O_NONBLOCK was specified and there is no more + buffer space available (if O_NONBLOCK is not + specified the function will block until buffer + space is available). + + EBUSY This error code indicates that there are + conflicting requests. The corresponding demux + device is setup to receive data from the front- + end. Make sure that these filters are stopped + and that the filters with input set to DMX_IN_DVR + are started. + + EBADF fd is not a valid open file descriptor + + + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_START); + + DESCRIPTION + + This ioctl call is used to start the actual filtering operation + defined via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_START for this command. + + RETURNS + + EBADF fd is not a valid file descriptor + + EINVAL Invalid argument, i.e. no filtering parameters + provided via the DMX_SET_FILTER or + DMX_SET_PES_FILTER functions. + + EBUSY This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter. + + + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_STOP); + + DESCRIPTION + + This ioctl call is used to stop the actual filtering operation defined + via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via + the DMX_START command. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_STOP for this command. + + RETURNS + + EBADF fd is not a valid file descriptor + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_SET_FILTER, struct dmxSctFilterParams *params); + + DESCRIPTION + + This ioctl call sets up a filter according to the filter and mask + parameters provided. A timeout may be defined stating number of seconds + to wait for a section to be loaded. A value of 0 means that no timeout + should be applied. Finally there is a flag field where it is possible to + state whether a section should be CRC-checked, whether the filter should + be a "one-shot" filter, i.e. if the filtering operation should be stopped + after the first section is received, and whether the filtering operation + should be started immediately (without waiting for a DMX_START ioctl call). + If a filter was previously set-up, this filter will be cancelled, and the + receive buffer will be flushed. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_SET_FILTER for this command. + + struct I Pointer to structure containing filter + + dmxSctFilterParams parameters. + *params + + RETURNS + + EBADF fd is not a valid file descriptor + + EINVAL Invalid argument. + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_SET_PES_FILTER, struct dmxPesFilterParams *params); + + DESCRIPTION + + This ioctl call sets up a PES filter according to the parameters provided. + By a PES filter is meant a filter that is based just on the packet + identifier (PID), i.e. no PES header or payload filtering capability is + supported. + The transport stream destination for the filtered output may be set. Also + the PES type may be stated in order to be able to e.g. direct a video + stream directly to the video decoder. Finally there is a flag field where + it is possible to state whether the filtering operation should be started + immediately (without waiting for a DMX_START ioctl call). + If a filter was previously set-up, this filter will be cancelled, and the + receive buffer will be flushed. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_SET_PES_FILTER for this command. + + struct I Pointer to structure containing filter + + dmxPesFilterParams parameters. + *params + + RETURNS + + EBADF fd is not a valid file descriptor + + EINVAL Invalid argument. + + EBUSY This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter. + + + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_SET_BUFFER_SIZE, unsigned long size); + + DESCRIPTION + + This ioctl call is used to set the size of the circular buffer used + for filtered data. The default size is two maximum sized sections, i.e. + if this function is not called a buffer size of 2 * 4096 bytes will be + used. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_SET_BUFFER_SIZE for this command. + + unsigned long size I Size of circular buffer. + + RETURNS + + EBADF fd is not a valid file descriptor. + + ENOMEM The driver was not able to allocate a buffer of the requested size. + + + +
+
+ + +
+ +int ioctl( int fd, int request = DMX_GET_EVENT, struct dmxEvent *ev); + + DESCRIPTION + + This ioctl call returns an event if available. If an event is not + available, the behavior depends on whether the device is in blocking or + non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available. + The standard Linux poll() and/or select() system calls can be used with + the device file descriptor to watch for new events. For select(), the + file descriptor should be included in the exceptfds argument, and for + poll(), POLLPRI should be specified as the wake-up condition. + Only the latest event for each filter is saved. + + PARAMETERS + + int fd I File descriptor returned by a previous call to open(). + + int request I Equals DMX_SET_BUFFER_SIZE for this command. + + struct dmxEvent *ev O Pointer to the location where the event is to be stored. + + RETURNS + + EBADF fd is not a valid file descriptor. + + EFAULT ev points to an invalid address. + + EWOULDBLOCK There is no event pending, and the device is in non-blocking mode. + + + +
+
+ +
+ +
+ + + DVB CA API + + The DVB CA device controls the conditional access hardware. + This allows functionalities like display of menues and entering of PIN numbers. + It can be accessed through /dev/ost/ca. + + + The function calls defined in the include file audio.h are described in + detail below: + + + + CA API IO control calls + + The exact io calls for this device have not been decided on yet. + + + + + + + + + + + +
+ + + DVB Demux Kernel Module + + The demux device accesses the actual demux hardware through a + demux kernel module. This way other kernel modules (e.g. a generic DVB + network device) and not only the demux device can access the demux + hardware. + + + + DVB Demux Kernel Module API + + The demux kernel API gives access to the demuxer of the DVB + hardware to other kernel modules which implement devices like the Demux + device or generic DVB network devices. + + + The function calls defined in the include file demux.h are described in + detail below: + + + + Demux Directory API + + + The demux directory is a Linux kernel-wide facility for registering and + accessing the MPEG-2 TS demuxes in the system. Run-time registering and + unregistering of demux drivers is possible using this API. + + + All demux drivers in the directory implement the abstract interface dmx_demux_t. + + + +
+int dmx_register_demux ( dmx_demux_t* demux ) + + Description + + This function makes a demux driver interface available to the Linux kernel. + It is usually called by the init_module() function of the kernel module that + contains the demux driver. The caller of this function is responsible for + allocating dynamic or static memory for the demux structure and for initializing + its fields before calling this function. + The memory allocated for the demux structure must not be freed before calling + dmx_unregister_demux(), + + Returns + + 0 The command was successfully performed. + + -EEXIST A demux with the same value of the id field + already stored in the directory. + + -ENOSPC No space left in the directory. + + + +
+
+ +
+ +int dmx_unregister_demux ( dmx_demux_t* demux ) + + Parameters + + dmx_demux_t* demux I/O Pointer to the demux API and instance variables. + + Description + + This function is called to indicate that the given demux interface is no longer + available. The caller of this function is responsible for freeing the memory of + the demux structure, if it was dynamically allocated before calling + dmx_register_demux(). + The cleanup_module() function of the kernel module that contains the demux + driver should call this function. Note that this function fails if the demux + is currently in use, i.e., release_demux() has not been called for the + interface. + + Returns + + 0 The command was successfully performed. + + -ENODEV No such demux registered. + + -EBUSY Demux is currently in use. + + + +
+
+ +
+ +struct list_head* dmx_get_demuxes () + + Description + + Provides the caller with the list of registered demux interfaces, using the + standard list structure defined in the include file linux/list.h. + The include file demux.h defines the macro DMX_DIR_ENTRY() for converting an + element of the generic type struct list_head* to the type dmx_demux_t*. + The caller must not free the memory of any of the elements obtained via this + function call. + + Returns + + A list of demux interfaces, or NULL in the case of an empty list. + + + +
+
+
+ + + + Demux API + + The demux API should be implemented for each demux in the system. It is used to + select the TS source of a demux and to manage the demux resources. When the + demux client allocates a resource via the demux API, it receives a pointer + to the API of that resource. + + + Each demux receives its TS input from a DVB front-end or from the memory, as + set via the demux API. In a system with more than one front-end, the API can + be used to select one of the DVB front-ends as a TS source for a demux, unless + this is fixed in the HW platform. The demux API only controls front-ends + regarding their connections with demuxes; the APIs used to set the other + front-end parameters, such as tuning, are not defined in this document. + + + The functions that implement the abstract interface demux_t should be defined + static or module private and registered to the Demux Directory for external + access. It is not necessary to implement every function in the demux_t struct, + however (for example, a demux interface might support Section filtering, but + not TS or PES filtering). The API client is expected to check the value of any + function pointer before calling the function: the value of NULL means "function + not available". + + + Whenever the functions of the demux API modify shared data, the possibilities + of lost update and race condition problems should be addressed, e.g. by + protecting parts of code with mutexes. This is especially important on + multi-processor hosts. + + + Note that functions called from a bottom half context must not sleep, at least + in the 2.2.x kernels. Even a simple memory allocation can result in a kernel + thread being put to sleep if swapping is needed. For example, the Linux kernel + calls the functions of a network device interface from a bottom half context. + Thus, if a demux API function is called from network device code, the function + must not sleep. + + +
+ +int open ( demux_t* demux ) + + + Parameters + + demux_t* demux I Pointer to the demux API and instance data. + + Description + + This function reserves the demux for use by the caller and, if necessary, + initializes the demux. When the demux is no longer needed, the function close() + should be called. + It should be possible for multiple clients to access the demux at the same time. + Thus, the function implementation should increment the demux usage count when + open() is called and decrement it when close() is called. + + Returns + + 0 The command was successfully performed. + + -EUSERS Maximum usage count reached. + + -EINVAL Bad parameter. + + + +
+
+ +
+ +int close ( demux_t* demux ) + + Parameters + + demux_t* demux I Pointer to the demux API and instance data. + + Description + + The function is called to indicate that the API client does not need to use + the demux anymore. As a result of this function, the demux usage count is + decremented by one. + When the usage count drops to zero, any demux resources can be released. + + Returns + + 0 The command was successfully performed. + + -ENODEV The demux was not in use. + + -EINVAL Bad parameter. + + + +
+
+ +
+ +int write ( demux_t* demux, const char* buf, size_t count) + + Parameters + + demux_t* demux I/O Pointer to the demux API and instance data. + + const char* buf I Pointer to the TS data in kernel-space memory. + + size_t length I Length of the TS data. + + + + Description + + This function provides the demux driver with a memory buffer containing TS + packets. Instead of receiving TS packets from the DVB front-end, the demux + driver software will read packets from the memory. Any clients of this demux + with active TS, PES or Section filters will receive filtered data via the Demux + callback API (see 0). The function returns when all the data in the buffer has + been consumed by the demux. + Demux hardware typically cannot read TS from the memory. If this is the case, + memory-based filtering has to be implemented entirely in software. + + Returns + + 0 The command was successfully performed. + + -ENOSYS The command is not implemented. + + -EINVAL Bad parameter. + + + +
+
+ +
+ +int allocate_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t** feed, dmx_ts_cb callback ) + + Parameters + + demux_t* demux I/O Pointer to the demux API and instance data. + + dmx_ts_feed_t** feed O Pointer to the TS feed API and instance data. + + dmx_ts_cb callback I Pointer to the callback function for + passing received TS packet + + Description + + Allocates a new TS feed, which is used to filter the TS packets carrying a + certain PID. + The TS feed normally corresponds to a hardware PID filter on the demux chip. + + Returns + + 0 The command was successfully performed. + + -EBUSY No more TS feeds available. + + -ENOSYS The command is not implemented. + + -EINVAL Bad parameters. + + + +
+
+ +
+int release_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t* feed) + + Parameters + + dmx_demux_t* demux I/O Pointer to the demux API and + instance data. + dmx_ts_feed_t* feed I Pointer to the TS feed API and + instance data. + + Function Detailed Description + Releases the resources allocated with allocate_ts_feed(). Any filtering in progress + on the TS feed should be stopped before calling this function. + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + +
+
+ +
+allocate_pes_feed() + + TBD + + + +
+
+ +
+release_pes_feed() + + TBD + + + +
+
+ +
+int allocate_section_feed ( dmx_demux_t* demux, + dmx_section_feed_t** + feed, + dmx_section_cb callback ) + + Function Parameters + demux_t* demux I/O Pointer to the demux API and + instance data. + dmx_section_feed_t** feed O Pointer to the section feed API and + + instance data. + dmx_section_cb callback I Pointer to the callback function for + passing received sections + + Function Detailed Description + Allocates a new section feed, i.e. a demux resource for filtering and receiving sections. + On platforms with hardware support for section filtering, a section feed is directly + mapped to the demux HW. On other platforms, TS packets are first PID filtered in + hardware and a hardware section filter then emulated in software. + The caller obtains an API pointer of type dmx_section_feed_t as an out parameter. + Using this API the caller can set filtering parameters and start receiving sections. + + Function Returns + 0 The command was successfully performed. + -EBUSY No more section feeds available. + -ENOSYS The command is not implemented. + -EINVAL Bad parameters. + +
+
+ +
+ +int release_section_feed ( dmx_demux_t* demux, + dmx_section_feed_t* + feed + ) + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and + instance data. + dmx_section_feed_t* feed I Pointer to the section feed API and + instance data. + + Function Detailed Description + Releases the resources allocated with allocate_section_feed(), including allocated + filters. Any filtering in progress on the section feed should be stopped before calling + this function. + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + + +
+
+ +
+ +int descramble_mac_address ( dmx_demux_t* demux, + __u8* + buffer1, + size_t + buffer1_length, + __u8* buffer2, + size_t + buffer2_length, + __u16 pid ) + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and + instance data. + __u8* buffer1 I Pointer to the first byte of the + section. + size_t buffer1_length I Length of the section data, + including headers and CRC, in + buffer1. + __u8* buffer2 I Pointer to the tail of the section + data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a cyclic buffer. + size_t buffer2_length I Length of the section data, + including headers and CRC, in + buffer2 + __u16 pid I The PID on which the section was + received. Useful for obtaining the + descrambling key, e.g. from a DVB + Common Access facility. + + Function Detailed Description + This function runs a descrambling algorithm on the destination MAC address field of a + DVB Datagram Section, replacing the original address with its unencrypted version. + Otherwise, the description on the function descramble_section_payload() applies + also to this function. + + Function Returns + 0 The command was successfully performed. + -ENOSYS No descrambling facility available. + -EINVAL Bad parameters. + + + + +
+
+ +
+ +int descramble_section_payload ( dmx_demux_t* demux, + __u8* + buffer1, + size_t + buffer1_length, + __u8* buffer2, + size_t + buffer2_length, + __u16 pid ) + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and + instance data. + __u8* buffer1 I/O Pointer to the first byte of the + section. + size_t buffer1_length I Length of the section data, + including headers and CRC, in + buffer1. + __u8* buffer2 I Pointer to the tail of the section + data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a cyclic buffer. + size_t buffer2_length I Length of the section data, + including headers and CRC, in + buffer2 + __u16 pid I The PID on which the section was + received. Useful for obtaining the + descrambling key, e.g. from a DVB + Common Access facility. + + Function Detailed Description + This function runs a descrambling algorithm on the payload of a DVB Datagram + Section, replacing the original payload with its unencrypted version. The function will + be called from the demux API implementation; the API client need not call this function + directly. + Section-level scrambling algorithms are currently standardized only for DVB-RCC + (return channel over 2-directional cable TV network) systems. For all other DVB + networks, encryption schemes are likely to be proprietary to each data broadcaster. + Thus, it is expected that this function pointer will have the value of NULL (i.e., function + not available) in most demux API implementations. Nevertheless, it should be possible + to use the function pointer as a hook for dynamically adding a "plug-in" descrambling + facility to a demux driver. + + + While this function is not needed with hardware-based section descrambling, the + descramble_section_payload function pointer can be used to override the default + hardware-based descrambling algorithm: if the function pointer has a non-NULL value, + the corresponding function should be used instead of any descrambling hardware. + + Function Returns + 0 The command was successfully performed. + -ENOSYS No descrambling facility available. + -EINVAL Bad parameters. + + +
+
+ +
+ +int add_frontend ( dmx_demux_t* demux, + dmx_frontend_t* + frontend); + + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and instance + data. + dmx_frontend_t* frontend I/O Pointer to the front-end instance data. + + Function Detailed Description + Registers a connectivity between a demux and a front-end, i.e., indicates that the + demux can be connected via a call to connect_frontend() to use the given front-end + as a TS source. The client of this function has to allocate dynamic or static memory for + the frontend structure and initialize its fields before calling this function. + This function is normally called during the driver initialization. The caller must not free + the memory of the frontend struct before successfully calling remove_frontend(). + + Function Returns + 0 The command was successfully performed. + -EEXIST A front-end with the same value of the id field + already registered. + -EINUSE The demux is in use. + -ENOMEM No more front-ends can be added. + -EINVAL Bad parameters. + +
+
+ +
+ +int remove_frontend ( dmx_demux_t* demux, + dmx_frontend_t* frontend ) + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and instance + data. + dmx_frontend_t* frontend I/O Pointer to the front-end instance data. + + Function Detailed Description + Indicates that the given front-end, registered by a call to add_frontend(), can no + longer be connected as a TS source by this demux. The function should be called + when a front-end driver or a demux driver is removed from the system. If the front-end + is in use, the function fails with the return value of -EBUSY. + After succesfully calling this function, the caller can free the memory of the frontend + struct if it was dynamically allocated before the add_frontend() operation. + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + -EBUSY The front-end is in use, i.e. a call to + connect_frontend() has not been followed by + a call to disconnect_frontend(). + + +
+
+ +
+ +struct list_head* get_frontends ( dmx_demux_t* demux ) + Function Parameters + dmx_demux_t* demux I Pointer to the demux API and + instance data. + + Function Detailed Description + Provides the APIs of the front-ends that have been registered for this demux. Any of + the front-ends obtained with this call can be used as a parameter for + connect_frontend(). + + + The include file demux.h contains the macro DMX_FE_ENTRY() for converting an + element of the generic type struct list_head* to the type dmx_frontend_t*. + The caller must not free the memory of any of the elements obtained via this function + call. + + Function Returns + A list of front-end interfaces, or NULL in the case of an empty list. + +
+
+ +
+ +int connect_frontend ( dmx_demux_t* demux, + dmx_frontend_t* frontend ) + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and instance + data. + dmx_frontend_t* frontend I/O Pointer to the front-end instance data. + + Function Detailed Description + Connects the TS output of the front-end to the input of the demux. A demux can only + be connected to a front-end registered to the demux with the function + add_frontend(). + It may or may not be possible to connect multiple demuxes to the same front-end, + depending on the capabilities of the HW platform. When not used, the front-end should + be released by calling disconnect_frontend(). + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + -EBUSY The front-end is in use. + +
+
+ +
+ +int disconnect_frontend ( dmx_demux_t* demux ) + + + Function Parameters + dmx_demux_t* demux I/O Pointer to the demux API and instance data. + + Function Detailed Description + Disconnects the demux and a front-end previously connected by a + connect_frontend() call. + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + + +
+
+
+ + + Demux Callback API + + This kernel-space API comprises the callback functions that deliver filtered data to the + demux client. Unlike the other APIs, these API functions are provided by the client and + called from the demux code. + + + The function pointers of this abstract interface are not packed into a structure as in the + other demux APIs, because the callback functions are registered and used + independent of each other. As an example, it is possible for the API client to provide + several callback functions for receiving TS packets and no callbacks for PES packets + or sections. + + + The functions that implement the callback API need not be re-entrant: when a demux + driver calls one of these functions, the driver is not allowed to call the function again + before the original call returns. If a callback is triggered by a hardware interrupt, it is + recommended to use the Linux "bottom half" mechanism or start a tasklet instead of + making the callback function call directly from a hardware interrupt. + + + +
+int dmx_ts_cb ( __u8* buffer1, size_t buffer1_length, + __u8* buffer2, size_t buffer2_length, + dmx_ts_feed_t* source, dmx_success_t success ) + + Parameters + + __u8* buffer1 I Pointer to the start of the filtered TS packets. + + size_t buffer1_length I Length of the TS data in buffer1. + + __u8* buffer2 I Pointer to the tail of the filtered TS packets, or NULL. + + size_t buffer2_length I Length of the TS data in buffer2. + + dmx_ts_feed_t* source I Indicates which TS feed is the source of the callback. + + dmx_success_t success I Indicates if there was an error in TS reception. + + Description + + This function, provided by the client of the demux API, is called from the + demux code. The function is only called when filtering on this TS feed has + been enabled using the start_filtering() function. If conflict resolution + is used (see Error! Reference source not found.), no callbacks are made to + clients that have been put "on hold" regarding a TS Feed resource. + Any TS packets that match the filter settings are copied to a cyclic buffer. + The filtered TS packets are delivered to the client using this callback + function. The size of the cyclic buffer is controlled by the + circular_buffer_size parameter of the set() function in the TS Feed API. It is + expected that the buffer1 and buffer2 callback parameters point to addresses + within the circular buffer, but other implementations are also + possible. Note that the called party should not try to free the memory the + buffer1 and buffer2 parameters point to. + When this function is called, the buffer1 parameter typically points to the + start of the first undelivered TS packet within a cyclic buffer. The buffer2 + buffer parameter is normally NULL, except when the received TS packets have + crossed the last address of the cyclic buffer and "wrapped" to the beginning + of the buffer. In the latter case the buffer1 parameter would contain an + address within the cyclic buffer, while the buffer2 parameter would contain + the first address of the cyclic buffer. + The number of bytes delivered with this function (i.e. buffer1_length + + buffer2_length) is usually equal to the value of callback_length parameter given + in the set() function, with one exception: if a timeout occurs before receiving + callback_length bytes of TS data, any undelivered packets are immediately + delivered to the client by calling this function. The timeout duration is + controlled by the set() function in the TS Feed API. + If a TS packet is received with errors that could not be fixed by the TS-level + forward error correction (FEC), the Transport_error_indicator flag of the TS + packet header should be set. The TS packet should not be discarded, as the + error can possibly be corrected by a higher layer protocol. + If the called party is slow in processing the callback, it is possible that + the circular buffer eventually fills up. If this happens, the demux driver + should discard any TS packets received while the buffer is full. The error + should be indicated to the client on the next callback by setting the success + parameter to the value of DMX_OVERRUN_ERROR. + + The type of data returned to the callback can be selected by the + new function int (*set_type) (struct dmx_ts_feed_s* feed, int type, + dmx_ts_pes_t pes_type) which is part of the dmx_ts_feed_s struct + (also cf. to the include file ost/demux.h) + The type parameter decides if the raw TS packet (TS_PACKET) or just the + payload (TS_PACKET|TS_PAYLOAD_ONLY) should be returned. + If additionally the TS_DECODER bit is set the stream will also be sent + to the hardware MPEG decoder. In this case, the second flag decides + as what kind of data the stream should be interpreted. + The possible choices are one of DMX_TS_PES_AUDIO, DMX_TS_PES_VIDEO, + DMX_TS_PES_TELETEXT, DMX_TS_PES_SUBTITLE, DMX_TS_PES_PCR, or + DMX_TS_PES_OTHER. + + + Returns + + 0 Continue filtering. + + -1 Stop filtering - has the same effect as a call + to stop_filtering() on the TS Feed API. + + + +
+
+ +
+ +dmx_pes_cb() + + TBD + +
+
+ +
+ +int dmx_section_cb ( __u8* buffer1, + size_t + buffer1_length, + __u8* + buffer2, + size_t buffer2_length, + dmx_section_filter_t* + source, + dmx_success_t success ) + + Function Parameters + __u8* buffer1 I Pointer to the start of the filtered section, e.g. + within the cyclic buffer of the demux driver. + size_t buffer1_length I Length of the filtered section data in buffer1, + including headers and CRC. + __u8* buffer2 Pointer to the tail of the filtered section data, or + NULL. Useful to handle the wrapping of a cyclic + buffer. + size_t buffer2_length Length of the filtered section data in buffer2, + including headers and CRC. + dmx_section_filter_t* I Indicates the filter that triggered the callback. + filter + dmx_success_t success I Indicates if there was an error in section + reception. + + Function Detailed Description + This function, provided by the client of the demux API, is called from the demux code. + The function is only called when filtering of sections has been enabled using the + function start_filtering() of the section feed API. + When the demux driver has received a complete section that matches at least one + section filter, the client is notified via this callback function. Normally this function is + called for each received section; however, it is also possible to deliver multiple sections + with one callback, for example when the system load is high. + If an error occurs while receiving a section, this function should be called with the + corresponding error type set in the success field, whether or not there is data to + deliver. + The Section Feed implementation should maintain a cyclic buffer for received sections. + However, this is not necessary if the Section Feed API is implemented as a client of + + + the TS Feed API, because the TS Feed implementation then buffers the + received data. + The size of the circular buffer can be configured using the set() function in the + Section Feed API. If there is no room in the circular buffer when a new section is + received, the section must be discarded. If this happens, the value of the success + parameter should be DMX_OVERRUN_ERROR on the next callback. + + Function Returns + 0 Continue filtering. + -1 Stop filtering - has the same effect as a call + to stop_filtering() on the Section Feed + API. + +
+
+ +
+ + + TS Feed API + + A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this + API, the client can set the filtering properties to start/stop filtering TS packets on a + particular TS feed. The API is defined as an abstract interface of the type + dmx_ts_feed_t. + + + The functions that implement the interface should be defined static or module + private. The client can get the handle of a TS feed API by calling the function + allocate_ts_feed() in the demux API. + + +
+ +int set ( dmx_ts_feed_t* feed, + __u16 + pid, + size_t callback_length, + size_t + cyclic_buffer_size, + int + descramble, + struct timespec timeout) + + Parameters + + dmx_ts_feed_t* feed I/O Pointer to the TS feed API and + instance data. + __u16 pid I PID value to filter. Only the TS + packets carrying the specified PID will + be passed to the API client. + size_t callback_length I Number of bytes to deliver with each + call to the dmx_ts_cb() callback + function. The value of this + parameter should be a multiple of + 188. + + size_t cyclic_buffer_size I Size of the cyclic buffer for the filtered + TS packets. + int descramble I If non-zero, descramble the filtered + TS packets. + struct timespec timeout I Maximum time to wait before + delivering received TS packets to the + client. + + Function Detailed Description + This function sets the parameters of a TS feed. Any filtering in progress on the TS feed + must be stopped before calling this function. + + Function Returns + 0 The command was successfully performed. + -ENOMEM Not enough memory for the requested + buffer size. + -ENOSYS No descrambling facility available for TS + packets. + -EINVAL Bad parameters. + +
+
+ + +
+ +int start_filtering ( dmx_ts_feed_t* feed ) + + Parameters + + dmx_ts_feed_t* feed I Pointer to the TS feed API and instance data. + + Function Detailed Description + Starts filtering TS packets on this TS feed, according to its settings. The PID value to + filter can be set by the API client. All matching TS packets are delivered + asynchronously to the client, using the callback function registered with + allocate_ts_feed(). + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + + +
+
+ +
+ +int stop_filtering ( dmx_ts_feed_t* feed ) + + Parameters + + dmx_ts_feed_t* feed I/O Pointer to the TS feed API and instance data. + + Description + + Stops filtering TS packets on this TS feed. + + Returns + + 0 The command was successfully performed. + + -EINVAL Bad parameters. + + + +
+
+
+ + + PES Feed API + + TBD + + + + + Section Feed API + + A section feed is a resource consisting of a PID filter and a set of section filters. Using + this API, the client can set the properties of a section feed and to start/stop filtering. + The API is defined as an abstract interface of the type dmx_section_feed_t. + The functions that implement the interface should be defined static or module + private. The client can get the handle of a section feed API by calling the function + allocate_section_feed() in the demux API. + + + On demux platforms that provide section filtering in hardware, the Section Feed API + implementation provides a software wrapper for the demux hardware. Other platforms + may support only PID filtering in hardware, requiring that TS packets are converted to + sections in software. In the latter case the Section Feed API implementation can be a + client of the TS Feed API. + + + +
+ +int set ( dmx_section_feed_t* feed, __u16 pid, size_t circular_buffer_size, + int descramble, int check_crc ) + + Parameters + + dmx_section_feed_t* feed I/O Pointer to the section feed API and + instance data. + __u16 pid I PID value to filter; only the TS packets + carrying the specified PID will be + accepted. + size_t circular_buffer_size I Size of the cyclic buffer for filtered + sections. + int descramble I If non-zero, descramble any sections + that are scrambled. + int check_crc I If non-zero, check the CRC values of + filtered sections. + + Function Detailed Description + This function sets the parameters of a section feed. Any filtering in progress on the + section feed must be stopped before calling this function. + If descrambling is enabled, the payload_scrambling_control and + address_scrambling_control fields of received DVB datagram sections should be + observed. If either one is non-zero, the section should be descrambled either in + hardware or using the functions descramble_mac_address() and + descramble_section_payload() of the demux API. Note that according to the + MPEG-2 Systems specification [3], only the payloads of private sections can be + scrambled while the rest of the section data must be sent in the clear. + + Function Returns + 0 The command was successfully performed. + -ENOMEM Not enough memory available for the requested + buffer size. + -ENOSYS No descrambling facility available for sections. + -EINVAL Bad parameters. + +
+
+ +
+ +int allocate_filter(dmx_section_feed_t* feed, dmx_section_filter_t** filter) + + Parameters + dmx_section_feed_t* feed I/O Pointer to the section feed API and + instance data. + dmx_section_filter_t** filter O Pointer to the allocated filter. + + + Function Detailed Description + This function is used to allocate a section filter on the demux. It should only be called + when no filtering is in progress on this section feed. If a filter cannot be allocated, the + function fails with -ENOSPC. See below for the format of the section filter struct provided + as an out parameter: + typedef struct { + __u8 filter_value [DMX_MAX_FILTER_SIZE]; + __u8 filter_mask [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed_s* parent; /* Back-pointer */ + void* priv; /* Private data of the client */ + } dmx_section_filter_t; + + The bitfields filter_mask and filter_value should only be modified when no + filtering is in progress on this section feed. filter_mask controls which bits of + filter_value are compared with the section headers/payload. On a binary value of 1 + in filter_mask, the corresponding bits are compared. The filter only accepts sections + that are equal to filter_value in all the tested bit positions. Any changes to the + values of filter_mask and filter_value are guaranteed to take effect only when + the start_filtering() function is called next time. The parent pointer in the struct + is initialized by the API implementation to the value of the feed parameter. The priv + pointer is not used by the API implementation, and can thus be freely utilized by the + caller of this function. Any data pointed to by the priv pointer is available to the + recipient of the dmx_section_cb() function call. + While the maximum section filter length (DMX_MAX_FILTER_SIZE) is currently set at 16 + bytes, hardware filters of that size are not available on all platforms. Therefore, section + filtering will often take place first in hardware, followed by filtering in software for the + header bytes that were not covered by a hardware filter. The filter_mask field can be + checked to determine how many bytes of the section filter are actually used, and if the + hardware filter will suffice. Additionally, software-only section filters can optionally be + allocated to clients when all hardware section filters are in use. + Note that on most demux hardware it is not possible to filter on the section_length field + of the section header - thus this field is ignored, even though it is included in + filter_value and filter_mask fields. + + Function Returns + 0 The command was successfully performed. + -ENOSPC No filters of given type and length available. + -EINVAL Bad parameters. + +
+
+ +
+int release_filter ( dmx_section_feed_t* feed, dmx_section_filter_t* filter) + + Parameters + dmx_section_feed_t* feed I/O Pointer to the section feed API and instance + data. + dmx_section_filter_t* I/O Pointer to the instance data of a section filter. + filter + + Function Detailed Description + This function releases all the resources of a previously allocated section filter. The + function should not be called while filtering is in progress on this section feed. After + calling this function, the caller should not try to dereference the filter pointer. + + Function Returns + 0 The command was successfully performed. + -ENODEV No such filter allocated. + -EINVAL Bad parameters. + +
+
+ +
+int start_filtering ( dmx_section_feed_t* feed ) + + Parameters + dmx_section_feed_t* feed I/O Pointer to the section feed API and + instance data. + + Function Detailed Description + Starts filtering sections on this section feed, according to its settings. Sections are first + filtered based on their PID and then matched with the section filters allocated for this + feed. If the section matches the PID filter and at least one section filter, it is delivered + to the API client. The section is delivered asynchronously using the callback function + registered with allocate_section_feed(). + + Function Returns + 0 The command was successfully performed. + -EINVAL Bad parameters. + +
+
+ +
+int stop_filtering ( dmx_section_feed_t* feed ) + + Parameters + + dmx_section_feed_t* feed I/O Pointer to the section feed API and instance data. + + Description + + Stops filtering sections on this section feed. Note that any changes to the + filtering parameters (filter_value, filter_mask, etc.) should only be made + when filtering is stopped. + + Returns + + 0 The command was successfully performed. + + -EINVAL Bad parameters. + + + +
+
+ + +
+ +
+ +
+ +
+
-- cgit v1.2.3 From c2ca96fee8c574074c67c9da023e4165f2f9b2e3 Mon Sep 17 00:00:00 2001 From: rjkm Date: Sun, 16 Sep 2001 22:25:40 -0300 Subject: removed old API docs --- dvb-spec/API/dvb_api.xml | 233 --- dvb-spec/API/dvb_api/audio.h | 69 - dvb-spec/API/dvb_api/audio.xml | 571 ------ dvb-spec/API/dvb_api/demux.h | 295 --- dvb-spec/API/dvb_api/demux.xml | 568 ------ dvb-spec/API/dvb_api/demux_mod.xml | 1215 ------------ dvb-spec/API/dvb_api/dmx.h | 130 -- dvb-spec/API/dvb_api/frontend.h | 96 - dvb-spec/API/dvb_api/frontend.xml | 843 --------- dvb-spec/API/dvb_api/sec.h | 116 -- dvb-spec/API/dvb_api/sec.xml | 430 ----- dvb-spec/API/dvb_api/video.h | 95 - dvb-spec/API/dvb_api/video.xml | 666 ------- dvb-spec/API/linux_dvb_api.xml | 3592 ------------------------------------ 14 files changed, 8919 deletions(-) delete mode 100644 dvb-spec/API/dvb_api.xml delete mode 100644 dvb-spec/API/dvb_api/audio.h delete mode 100644 dvb-spec/API/dvb_api/audio.xml delete mode 100644 dvb-spec/API/dvb_api/demux.h delete mode 100644 dvb-spec/API/dvb_api/demux.xml delete mode 100644 dvb-spec/API/dvb_api/demux_mod.xml delete mode 100644 dvb-spec/API/dvb_api/dmx.h delete mode 100644 dvb-spec/API/dvb_api/frontend.h delete mode 100644 dvb-spec/API/dvb_api/frontend.xml delete mode 100644 dvb-spec/API/dvb_api/sec.h delete mode 100644 dvb-spec/API/dvb_api/sec.xml delete mode 100644 dvb-spec/API/dvb_api/video.h delete mode 100644 dvb-spec/API/dvb_api/video.xml delete mode 100644 dvb-spec/API/linux_dvb_api.xml diff --git a/dvb-spec/API/dvb_api.xml b/dvb-spec/API/dvb_api.xml deleted file mode 100644 index bd2302551..000000000 --- a/dvb-spec/API/dvb_api.xml +++ /dev/null @@ -1,233 +0,0 @@ - - - linuxtv.org|Linux DVB API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

Linux DVB API

- -

- Part of the DVB API builds upon the - Video4Linux - (V4L) API. - The Siemens DVB card uses the SAA7146 as PCI bridge. A generic SAA7146 Linux driver for this - chip implements the basic V4L interface. -

- -

- An older version of the API included the DVB specific calls - into the V4L interface. This turned out to be very cumbersome to - program. Since we also hoped to arrive at a common standard for all - Linux platforms, especially those in embedded consumer devices, we - were happy to find - Nokia - as a partner in this effort. - They will be using the same API in their upcoming - - Media Terminal. -

- -

- In the new version of the API only display and grabbing of the - already decompressed images is handled through the V4L device. - All other DVB features like tuning, filtering and playback/recording - of the compressed data stream are accessed through separate devices. -

- -

- DVB devices - -

- There are currently 5 DVB devices: Video, Audio, Frontend, SEC and Demux. - The APIs of those devices are described in the documents below. - They contain links to the include files and to detailed descriptions - of all commands (the latter are still under construction). -

- -

- DVB Video API -

- -

- DVB Audio API -

- -

- DVB Frontend API -

- -

- DVB SEC API -

- -

- DVB Demux API -

- -

- - -

- DVB Demux Kernel Module - -

- The demux device accesses the actual demux hardware through a - demux kernel module. - This way other kernel modules (e.g. a generic DVB network device) - and not only the demux device can access the demux hardware. -

- -

- DVB Demux Kernel Module API -

- -

- - -

- First implementations of the API for the Siemens DVB card will be made - available in the download section during September 2000. -

- -
- - diff --git a/dvb-spec/API/dvb_api/audio.h b/dvb-spec/API/dvb_api/audio.h deleted file mode 100644 index 8a98f2f98..000000000 --- a/dvb-spec/API/dvb_api/audio.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * audio.h - * - * Copyright (C) 2000 Ralph Metzler - * & Marcus Metzler - for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _OST_AUDIO_H_ -#define _OST_AUDIO_H_ - -#define boolean int -#define true 1 -#define false 0 - -typedef enum { - AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ - AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */ -} audioStreamSource_t; - -typedef enum { - AUDIO_STOPPED, /* Device is stopped */ - AUDIO_PLAYING, /* Device is currently playing */ - AUDIO_PAUSED /* Device is paused */ -} audioPlayState_t; - -typedef enum { - AUDIO_STEREO, - AUDIO_MONO_LEFT, - AUDIO_MONO_RIGHT, -} audioChannelSelect_t; - -struct audioStatus { - boolean AVSyncState; - boolean muteState; - audioPlayState_t playState; - audioStreamSource_t streamSource; - audioChannelSelect_t channelSelect; - boolean bypassMode; -}; - - -#define AUDIO_STOP _IOW('o',1,void) -#define AUDIO_PLAY _IOW('o',2,void) -#define AUDIO_PAUSE _IOW('o',3,void) -#define AUDIO_CONTINUE _IOW('o',4,void) -#define AUDIO_SELECT_SOURCE _IOW('o',5,audioStreamSource_t) -#define AUDIO_SET_MUTE _IOW('o',6,boolean) -#define AUDIO_SET_AV_SYNC _IOW('o',7,boolean) -#define AUDIO_SET_BYPASS_MODE _IOW('o',8,boolean) -#define AUDIO_CHANNEL_SELECT _IOW('o',9,audioChannelSelect_t) -#define AUDIO_GET_STATUS _IOR('o',10,struct audioStatus *) - -#endif /* _OST_AUDIO_H_ */ diff --git a/dvb-spec/API/dvb_api/audio.xml b/dvb-spec/API/dvb_api/audio.xml deleted file mode 100644 index 4d6f31575..000000000 --- a/dvb-spec/API/dvb_api/audio.xml +++ /dev/null @@ -1,571 +0,0 @@ - - - linuxtv.org|DVB Audio API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB Audio API

- -

- The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. - It can be accessed through /dev/ost/audio. -

- -

- The function calls defined in the include file - audio.h are described in detail below: -

-

- Audio API IO control calls - - -

-

-
-int open(const char *deviceName, int flags);
-
-    DESCRIPTION
-    
-	This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent
-        use. When an open() call has succeeded, the device will be ready for use.
-        The significance of blocking or non-blocking mode is described in the 
-	documentation for functions where there is a difference. It does not affect 
-	the semantics of the open() call itself. A device opened in blocking mode can
-	later be put into non-blocking mode (and vice versa) using the F_SETFL command
-	of the fcntl system call.  This is a standard system call, documented in the 
-	Linux manual page for fcntl.
-        Only one user can open the Audio  Device in O_RDWR mode. All other attempts to
-        open the device in this mode will fail, and an errorcode will be returned.
-        If the Audio Device is opened in O_RDONLY mode, the only ioctl call that can 
-	be used is AUDIO_GET_STATUS. All other call will return with an error code.
-
-
-    PARAMETERS
-
-	const char *deviceName		Name of specific audio device.
-
-	int flags           		A bit-wise OR of the following flags:
-                                        
-					O_RDONLY read-only access
-
-                                        O_RDWR read/write access
-
-                                        O_NONBLOCK open in non-blocking mode
-                                                   (blocking mode is the default)
-
-    RETURNS
-
-	ENODEV                          Device driver not loaded/available.
-
-	EINTERNAL			Internal error
-
-        EBUSY                           Device or resource busy.
-
-        EINVAL                          Invalid argument.
-
-
-
-
-

- -

-

-
-int close(int fd);
-
-    DESCRIPTION
-	
-	This system call closes a previously opened audio device
-
-    PARAMETERS
-	
-	int fd			File descriptor returned by a previous call to open().
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-size_t write(int fd, const void *buf, size_t count);
-
-    DESCRIPTION
-
-	This system call can only be used if AUDIO_SOURCE_MEMORY is selected in the 
-	ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in PES format.
-        If O_NONBLOCK is not specified the function will block until buffer space is
-	available. The amount of data to be transferred is implied by count.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	void *buf		Pointer to the buffer containing the PES data.
-
-	size_t count		Size of buf.
-
-    RETURNS
-
-	EPERM			Mode VIDEO_SOURCE_INTERNAL not selected.
-
-	ENOMEM			Attempted to write more data than the internal
-                                buffer can hold.
-
-	EBADF			fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_STOP);
-
-    DESCRIPTION
-
-	This ioctl call asks the Audio Device to stop playing the current stream.
-
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request             Equals AUDIO_STOP for this command.
-
-    RETURNS
-
-	EBADF                   fd is not a valid open file descriptor
-
-	EINTERNAL		Internal error
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_PLAY);
-
-    DESCRIPTION
-
-	This ioctl call asks the Audio Device to start playing an audio stream from the
-        selected source.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_PLAY for this command.
-
-    RETURNS
-	
-        EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL               Internal error
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_PAUSE);
-
-    DESCRIPTION
-
-	This ioctl call suspends the audio stream being played. Decoding and playing are
-	paused. It is then possible to restart again decoding and playing process of the
-        audio stream using AUDIO_CONTINUE command.
-        If  AUDIO_SOURCE_MEMORY is selected in the ioctl call AUDIO_SELECT_SOURCE, the
-        DVB-subsystem will not decode (consume) any more data until the ioctl  call
-        AUDIO_CONTINUE or AUDIO_PLAY is performed.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_PAUSE for this command.
-
-    RETURNS
-           
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_CONTINUE);
-
-    DESCRIPTION
-
-	This ioctl call restarts decoding and playing processes of the audio stream,
-	 which was played before, a call to AUDIO_PAUSE was made.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_CONTINUE for this command.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL               Internal error, possibly in the communication
-                                with the DVB subsystem.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_SELECT_SOURCE, audioStreamSource_t source);
-
-    DESCRIPTION
-
-	This ioctl call informs the audio device which source shall be used for the 
-	input data. The possible sources are demux or memory. If AUDIO_SOURCE_MEMORY 
-	is selected, the data is fed to the Audio Device through the write command.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_SELECT_SOURCE for this command.
-
-	audioStreamSource_t source	Indicates the source that shall be used for the
-             			        Audio stream.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_SET_MUTE, boolean state);
-
-    DESCRIPTION
-    
-	This ioctl call asks the audio device to mute the stream that is currently being
-        played.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_SET_MUTE for this command.
-
-	boolean state		Indicates if audio device shall mute or not.
-                                TRUE     Audio Mute
-                                FALSE   Audio Unmute
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error,
-
-        EINVAL                  Illegal input parameter.
-
-
-

- -

-

-int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, boolean state);
-
-    DESCRIPTION
-
-	This ioctl call asks the Audio Device to turn ON or OFF A/V synchronisation.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_AV_SYNC for this command.
-
-	boolean state		Tells the DVB subsystem if A/V synchronisation shall be ON or OFF.
-                                TRUE    AV-sync ON
-                                FALSE  AV-sync OFF
-
-    RETURNS
-
-    	EBADF			fd is not a valid open file descriptor.
-        
-	EINTERNAL		Internal error
-
-	EINVAL                                  Illegal input parameter.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, boolean mode);
-
-    DESCRIPTION
-
-	This ioctl call asks the Audio Device to bypass the Audio decoder and forward
-	the stream without decoding. This mode shall be used if streams that can't be
-	handled by the DVB system shall be decoded. Dolby DigitalTM streams are 
-	automatically forwarded by the DVB subsystem.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_SET_BYPASS_MODE for this command.
-
-	boolean mode		Enables or disables the decoding of the current
-                                Audio stream in the DVB subsystem.
-                                TRUE    Bypass is disabled
-                                FALSE  Bypass is enabled
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-        
-	EINTERNAL               Internal error
-
-        EINVAL                  Illegal pointer mode.
-
-
-
-

- -

-

-int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT, audioChannelSelect_t)
-
-    DESCRIPTION
-    
-	This ioctl call asks the Audio Device to select the requested channel if possible.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals AUDIO_CHANNEL_SELECT for this command.
-
-	audioChannelSelect_t ch Select the output format of the audio (Mono, stereo)
-
-    RETURNS
-	
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-        EINVAL			Illegal pointer ch.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = AUDIO_GET_STATUS, struct audioStatus *status)
-
-    DESCRIPTION
-
-	This ioctl call asks the Audio Device to return the current state of the Audio
-	Device.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-        int request		Equals AUDIO_GET_STATUS for this command.
-
-        struct audioStatus *status 	Returns the current state of Audio Device
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-        EFAULT			status points to invalid address
-
-
-
-
-

- -

-
- - diff --git a/dvb-spec/API/dvb_api/demux.h b/dvb-spec/API/dvb_api/demux.h deleted file mode 100644 index 62cbf0a58..000000000 --- a/dvb-spec/API/dvb_api/demux.h +++ /dev/null @@ -1,295 +0,0 @@ -/* * demux.h * * Copyright (c) 2000 Nokia Research Center - * Tampere, FINLAND - * - * Project: - * Universal Broadcast Access - * - * Contains: - * Type definitions of a Linux kernel-level API for filtering MPEG-2 TS - * packets and MPEG-2 sections. Support for PES packet filtering will be - * added later. - * - * History: - * 12.01.2000/JPL File created - Initial version. - * 18.02.2000/JPL Minor corrections. - * 21.02.2000/JPL DMX_NAME_SIZE and dmx_in_use() removed, typos fixed, - * some names changed. - * 23.02.2000/JPL Added a parameter indicating the callback source in - * the callback functions. - * 10.03.2000/JPL Added the macros DMX_DIR_ENTRY() and DMX_FE_ENTRY(). - * 15.03.2000/JPL Added the capabilities field to dmx_demux_t. - * 22.03.2000/JPL Corrected the callback parameter in the - * allocate_x_feed() functions. - * 03.04.2000/JPL Added support for optional resource conflict resolution - * and scarce resource handling. - * 05.04.2000/JPL Changed the dmx_resolve_conflict() to use resource - * type as a parameter. - * 12.04.2000/JPL Added a second buffer parameter for dmx_x_callback() - * functions to better handle buffer wrapping. - * 26.04.2000/JPL Added functions for section-level descrambling. - * 03.09.2000/JPL Removed support for conflict resolution and scarce - * resource handling. Otherwise only minor changes to - * data structures and function prototypes. - * - * - * Author: - * Juha-Pekka Luoma (JPL) - * Nokia Research Center - * - * Notes: - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ -/* $Id$ */ - -#ifndef __DEMUX_H -#define __DEMUX_H - -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - -#include /* __u8, __u16, ... */ -#include /* list_entry(), struct list_head */ -#include /* struct timespec */ -#include /* Function return values */ - -/*--------------------------------------------------------------------------*/ -/* Common definitions */ -/*--------------------------------------------------------------------------*/ - -/* - * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter. - */ - -#ifndef DMX_MAX_FILTER_SIZE -#define DMX_MAX_FILTER_SIZE 16 -#endif -/* - * dmx_success_t: Success codes for the Demux Callback API. - */ - -typedef enum { - DMX_OK = 0, /* Received Ok */ - DMX_LENGTH_ERROR, /* Incorrect length */ - DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ - DMX_CRC_ERROR, /* Incorrect CRC */ - DMX_FRAME_ERROR, /* Frame alignment error */ - DMX_FIFO_ERROR, /* Receiver FIFO overrun */ - DMX_MISSED_ERROR /* Receiver missed packet */ -} dmx_success_t; - -/*--------------------------------------------------------------------------*/ -/* TS packet reception */ -/*--------------------------------------------------------------------------*/ - -struct dmx_ts_feed_s { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_ts_feed_s* feed, - __u16 pid, - size_t callback_length, - size_t circular_buffer_size, - int descramble, - struct timespec timeout); - int (*start_filtering) (struct dmx_ts_feed_s* feed); - int (*stop_filtering) (struct dmx_ts_feed_s* feed); -}; -typedef struct dmx_ts_feed_s dmx_ts_feed_t; - -/*--------------------------------------------------------------------------*/ -/* PES packet reception (not supported yet) */ -/*--------------------------------------------------------------------------*/ - -typedef void dmx_pes_feed_t; -typedef void dmx_pes_filter_t; - -/*--------------------------------------------------------------------------*/ -/* Section reception */ -/*--------------------------------------------------------------------------*/ - -typedef struct { - __u8 filter_value [DMX_MAX_FILTER_SIZE]; - __u8 filter_mask [DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ -} dmx_section_filter_t; - -struct dmx_section_feed_s { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_section_feed_s* feed, - __u16 pid, - size_t circular_buffer_size, - int descramble, - int check_crc); - int (*allocate_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t** filter); - int (*release_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t* filter); - int (*start_filtering) (struct dmx_section_feed_s* feed); - int (*stop_filtering) (struct dmx_section_feed_s* feed); -}; -typedef struct dmx_section_feed_s dmx_section_feed_t; - -/*--------------------------------------------------------------------------*/ -/* Callback functions */ -/*--------------------------------------------------------------------------*/ - -typedef int (*dmx_ts_cb) ( __u8 * buffer1, - size_t buffer1_length, - __u8 * buffer2, - size_t buffer2_length, - dmx_ts_feed_t* source, - dmx_success_t success); - -typedef int (*dmx_section_cb) ( __u8 * buffer1, - size_t buffer_len, - __u8 * buffer2, - size_t buffer2_len, - dmx_section_filter_t * source, - dmx_success_t success); - -typedef int (*dmx_pes_cb) ( __u8 * buffer1, - size_t buffer1_len, - __u8 * buffer2, - size_t buffer2_len, - dmx_pes_filter_t* source, - dmx_success_t success); - -/*--------------------------------------------------------------------------*/ -/* DVB Front-End */ -/*--------------------------------------------------------------------------*/ - -typedef enum { - DMX_OTHER_FE = 0, - DMX_SATELLITE_FE, - DMX_CABLE_FE, - DMX_TERRESTRIAL_FE, - DMX_LVDS_FE, - DMX_ASI_FE /* DVB-ASI interface */ -} dmx_frontend_source_t; - -typedef struct { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique front-end identifier */ - char* vendor; /* Name of the front-end vendor */ - char* model; /* Name of the front-end model */ - struct list_head connectivity_list; /* List of front-ends that can - be connected to a particular - demux */ - void* priv; /* Pointer to private data of the API client */ -} dmx_frontend_t; - -/*--------------------------------------------------------------------------*/ -/* MPEG-2 TS Demux */ -/*--------------------------------------------------------------------------*/ - -/* - * Flags OR'ed in the capabilites field of struct dmx_demux_s. - */ - -#define DMX_TS_FILTERING 1 -#define DMX_PES_FILTERING 2 -#define DMX_SECTION_FILTERING 4 -#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ -#define DMX_CRC_CHECKING 16 -#define DMX_TS_DESCRAMBLING 32 -#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 -#define DMX_MAC_ADDRESS_DESCRAMBLING 128 - -/* - * Demux resource type identifier. -*/ - -/* - * DMX_FE_ENTRY(): Casts elements in the list of registered - * front-ends from the generic type struct list_head - * to the type * dmx_frontend_t - *. -*/ - -#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) - -struct dmx_demux_s { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique demux identifier */ - char* vendor; /* Name of the demux vendor */ - char* model; /* Name of the demux model */ - __u32 capabilites; /* Bitfield of capability flags */ - dmx_frontend_t* frontend; /* Front-end connected to the demux */ - struct list_head reg_list; /* List of registered demuxes */ - void* priv; /* Pointer to private data of the API client */ - int (*open) (struct dmx_demux_s* demux); - int (*close) (struct dmx_demux_s* demux); - int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); - int (*allocate_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t** feed, - dmx_ts_cb callback); - int (*release_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t* feed); - int (*allocate_pes_feed) (struct dmx_demux_s* demux, - dmx_pes_feed_t** feed, - dmx_pes_cb callback); - int (*release_pes_feed) (struct dmx_demux_s* demux, - dmx_pes_feed_t* feed); - int (*allocate_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t** feed, - dmx_section_cb callback); - int (*release_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t* feed); - int (*descramble_mac_address) (struct dmx_demux_s* demux, - __u8* buffer1, - size_t buffer1_length, - __u8* buffer2, - size_t buffer2_length, - __u16 pid); - int (*descramble_section_payload) (struct dmx_demux_s* demux, - __u8* buffer1, - size_t buffer1_length, - __u8* buffer2, size_t buffer2_length, - __u16 pid); - int (*add_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*remove_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - struct list_head* (*get_frontends) (struct dmx_demux_s* demux); - int (*connect_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*disconnect_frontend) (struct dmx_demux_s* demux); -}; -typedef struct dmx_demux_s dmx_demux_t; - -/*--------------------------------------------------------------------------*/ -/* Demux directory */ -/*--------------------------------------------------------------------------*/ - -/* - * DMX_DIR_ENTRY(): Casts elements in the list of registered - * demuxes from the generic type struct list_head* to the type dmx_demux_t - *. - */ - -#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) - -int dmx_register_demux (dmx_demux_t* demux); -int dmx_unregister_demux (dmx_demux_t* demux); -struct list_head* dmx_get_demuxes (void); - -#endif /* #ifndef __DEMUX_H */ - diff --git a/dvb-spec/API/dvb_api/demux.xml b/dvb-spec/API/dvb_api/demux.xml deleted file mode 100644 index b15824d0b..000000000 --- a/dvb-spec/API/dvb_api/demux.xml +++ /dev/null @@ -1,568 +0,0 @@ - - - linuxtv.org|DVB Demux API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB Demux API

- -

- The DVB demux device lets you set TS, PID and section filters in the DVB - device. This is internally accomplished through calls to the - demux kernel module. - The demux device can be accessed through /dev/ost/demux. -

- -

- The function calls defined in the include file - dmx.h are described in detail below: -

- -

- Demux API IO control calls - -

-

-
-int open(const char *deviceName, int flags);
- 
-    DESCRIPTION
- 
-	This system call, used with a device name of /dev/ost/demuxn, where n 
-	denotes the specific demux device to be opened, allocates a new filter 
-	and returns a handle which can be used for subsequent control of that 
-	filter. This call has to be made for each filter to be used, i.e. every
-	returned file descriptor is a reference to a single filter.
-        /dev/ost/dvrn is a logical device to be used for retrieving Transport 
-	Streams for digital video recording. n identifies the physical demux 
-	device that provides the actual DVR functionlaity. When reading from  
-	this device a transport stream containing the packets from all PES
-	filters set in the corresponfing demux device (/dev/osst/demuxn)             	having the output set to DMX_OUT_TS_TAP.  A recorded Transport Stream 
-	is replayed by writing to this device.
-	This device can only be opened in read-write mode.
-        The significance of blocking or non-blocking mode is described in the
-	documentation for functions where there is a difference. It does not 
-	affect the semantics of the open() call itself. A device opened in 
-	blocking mode can later be put into non-blocking mode
-        (and vice versa) using the F_SETFL command of the fcntl system call.
-
- 
-    PARAMETERS
-
-	const char *deviceName	     I Name of the demux device, which should be
-	                               /dev/ost/demuxn where  n denotes the
-                                       specific demux device to be opened, or the
-                                       name of a logical DVR device, /dev/ost/dvrn.
-
-	int flags                    I A bit-wise OR of the following flags:
-                                       O_RDWR read/write access.
-                                       O_NONBLOCK open in non-blocking mode
-                                                 (blocking mode is the default).
-
-    RETURNS
-    
-	ENODEV				Device driver not loaded/available.
-
-        EINVAL 	                        Invalid argument.
-
-        EMFILE                          "Too many open files", i.e. no more filters available.
-
-        ENOMEM                          The driver failed to allocate enough memory.
-
-
-
-
-

- -

-

-
-int close(int fd);
-
-    DESCRIPTION
-
-	This system call deactivates and deallocates a filter that was previously
-	allocated via the open() call.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-size_t read(int fd, void *buf, size_t count);
-
-    DESCRIPTION
-
-	This system call returns filtered data, which might be section or PES 
-	data. The filtered data is transferred from the driver's internal circular
-	buffer to buf. The maximum amount of data to be transferred is implied by
-	count.
-
-        When returning section data the driver always tries to return a complete 
-	single section (even though buf would provide buffer space for more data).
-	If the size of the buffer is smaller than the section as much as possible
-	will be returned, and the remaining data will be provided in subsequent 
-	calls.
-        The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
-	sized sections) by default. The size of this buffer may be changed by 
-	using the DMX_SET_BUFFER_SIZE function. If the buffer is not large enough,
-	or if the read operations are not performed fast enough, this may result 
-	in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned,
-	and the circular buffer will be emptied.
-        This call is blocking if there is no data to return, i.e. the process 
-	will be put to sleep waiting for data, unless the O_NONBLOCK flag is 
-	specified.
-        Note that in order to be able to read, the filtering process has to be
-	started by defining either a section or a PES filter by means of the 
-	ioctl functions, and then starting the filtering process via the DMX_START
-	ioctl function or by setting the DMX_IMMEDIATE_START flag.
-        If the reading is done from a logical DVR demux device, the data will 
-	constitute a Transport Stream including the packets from all PES filters
-	in the corresponding demux device /dev/ost/demuxn having the output set 
-	to DMX_OUT_TS_TAP.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	void *buf             O Pointer to the buffer to be used for returned filtered data.
-
-	size_t count          I Size of buf.
-
-    RETURNS
-
-	EWOULDBLOCK		No data to return and O_NONBLOCK was specified.
-
-        EBADF                   fd is not a valid open file descriptor
-
-        ECRC                    Last section had a CRC error ­ no data
-	                        returned. The buffer is flushed.
-
-        EBUFFEROVERFLOW         The filtered data was not read from the buffer in
-                                due time, resulting in non-read data being lost.
-                                The buffer is flushed.
-
-        ETIMEDOUT               The section was not loaded within the stated
-                                timeout period. See ioctl DMX_SET_FILTER for
-                                how to set a timeout.
-
-        EFAULT                  The driver failed to write to the callers buffer
-				due to an invalid *buf pointer.
-
-
-
-
-

- -

-

-
-ssize_t write(int fd, const void *buf, size_t count);
-
-    DESCRIPTION
-
-	This system call is only provided by the logical device /dev/ost/dvrn, 
-	where n identifies the physical demux device that provides the actual 
-	DVR  functionality.  It is used for replay of a digitally recorded 
-	Transport Stream. Matching filters have to be defined in the 
-	corresponding physical demux device, /dev/ost/demuxn.
-	The amount of data to be transferred is implied by count.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	void *buf             I Pointer to the buffer containing the Transport Stream.
-
-        size_t count          I Size of buf.
-
-    RETURNS
-
-	EWOULDBLOCK             No data was written. This might happen if
-                                O_NONBLOCK was specified and there is no more
-                                buffer space available (if O_NONBLOCK is not
-                                specified the function will block until buffer 
-				space is available).
-
-	EBUSY                   This error code indicates that there are
-                                conflicting requests. The corresponding demux
-                                device is setup to receive data from the front-
-                                end. Make sure that these filters are stopped
-                                and that the filters with input set to DMX_IN_DVR
-                                are started.
-
-	EBADF                   fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_START);
-
-    DESCRIPTION
-
-	This ioctl call is used to start the actual filtering operation 
-	defined via the ioctl  calls DMX_SET_FILTER or DMX_SET_PES_FILTER.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	int request           I Equals DMX_START for this command.
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor
-
-        EINVAL                  Invalid argument, i.e. no filtering parameters
-                                provided via the DMX_SET_FILTER or
-                                DMX_SET_PES_FILTER functions.
-
-        EBUSY                   This error code indicates that there are
-                                conflicting requests. There are active filters
-                                filtering data from another input source. Make
-                                sure that these filters are stopped before starting
-                                this filter.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_STOP);
-
-    DESCRIPTION
-
-	This  ioctl call is used to stop the actual filtering operation defined 
-	via the ioctl  calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
-	the DMX_START command.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals DMX_STOP for this command.
- 
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_SET_FILTER, struct dmxSctFilterParams *params);
-
-    DESCRIPTION
-
-	This ioctl call sets up a filter according to the filter and mask 
-	parameters provided. A timeout may be defined stating number of seconds 
-	to wait for a section to be loaded. A value of 0 means that no timeout 
-	should be applied. Finally there is a flag field where it is possible to
-	state whether a section should be CRC-checked, whether the filter should
-        be a "one-shot" filter, i.e. if the filtering operation should be stopped
-	after the first section is received, and whether the filtering operation 
-	should be started immediately (without waiting for a DMX_START ioctl call).
-        If a filter was previously set-up, this filter will be cancelled, and the
-	receive buffer will be flushed.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals DMX_SET_FILTER for this command.
-
-        struct                I Pointer to structure containing filter
-
-        dmxSctFilterParams      parameters.
-               *params
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor
-
-        EINVAL                  Invalid argument.
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_SET_PES_FILTER, struct dmxPesFilterParams *params);
-
-    DESCRIPTION
-
-	This ioctl call sets up a PES filter according to the parameters provided.
-	By a PES filter is meant a filter that is based just on the packet 
-	identifier (PID), i.e. no PES header or payload filtering capability is 
-	supported.
-        The transport stream destination for the filtered output may be set. Also
-	the PES type may be stated in order to be able to e.g. direct a video 
-	stream directly to the video decoder. Finally there is a flag field where
-	it is possible to state whether the filtering operation should be started
-	immediately (without waiting for a DMX_START ioctl call).
-        If a filter was previously set-up, this filter will be cancelled, and the
-	receive buffer will be flushed.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	int request           I Equals DMX_SET_PES_FILTER for this command.
-
-        struct                I Pointer to structure containing filter
-
-        dmxPesFilterParams      parameters.
-               *params
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor
-
-        EINVAL                  Invalid argument.
-
-        EBUSY                   This error code indicates that there are
-                                conflicting requests. There are active filters
-                                filtering data from another input source. Make
-                                sure that these filters are stopped before starting
-                                this filter.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_SET_BUFFER_SIZE, unsigned long size);
-
-    DESCRIPTION
-
-	This ioctl call is used to set the size of the circular buffer used
-	for filtered data. The default size is two maximum sized sections, i.e. 
-	if this function is not called a buffer size of 2 * 4096 bytes will be
-	used.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals DMX_SET_BUFFER_SIZE for this command.
-
-        unsigned long size    I Size of circular buffer.
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor.
-
-        ENOMEM                  The driver was not able to allocate a buffer of the requested size.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = DMX_GET_EVENT, struct dmxEvent *ev);
-
-    DESCRIPTION
-
-	This  ioctl call returns an event if available. If an event is not 
-	available, the behavior depends on whether the device is in blocking or 
-	non-blocking mode.  In the latter case, the call fails immediately with
-	errno set to EWOULDBLOCK. In the former case, the call blocks until an
-	event becomes available.
-        The standard Linux poll() and/or select() system calls can be used with
-	the device file descriptor to watch for new events.  For select(), the 
-	file descriptor should be included in the exceptfds argument, and for 
-	poll(), POLLPRI should be specified as the wake-up condition.
-        Only the latest event for each filter is saved.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	int request           I Equals DMX_SET_BUFFER_SIZE for this command.
-
-        struct dmxEvent *ev   O Pointer to the location where the event is to be stored.
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor.
-        
-	EFAULT                  ev points to an invalid address.
-
-	EWOULDBLOCK             There is no event pending, and the device is in non-blocking mode.
-
-
-
-
-

-

- -
- - diff --git a/dvb-spec/API/dvb_api/demux_mod.xml b/dvb-spec/API/dvb_api/demux_mod.xml deleted file mode 100644 index c36467977..000000000 --- a/dvb-spec/API/dvb_api/demux_mod.xml +++ /dev/null @@ -1,1215 +0,0 @@ - - - linuxtv.org|DVB Demux Kernel API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB Demux Kernel API

- -

- The demux kernel API gives access to the demuxer of the DVB hardware - to other kernel modules which implement devices like the - demux device or generic DVB network devices. -

- -

- The function calls defined in the include file - demux.h are described in detail below: -

- -

- Demux Directory API - -

- The demux directory is a Linux kernel-wide facility for registering and - accessing the MPEG-2 TS demuxes in the system. Run-time registering and - unregistering of demux drivers is possible using this API. -

-

- All demux drivers in the directory implement the abstract interface dmx_demux_t. -

- -

-

-int dmx_register_demux ( dmx_demux_t* demux )
-
-    Description
-
-	This function makes a demux driver interface available to the Linux kernel. 
-	It is usually called by the init_module() function of the kernel module that
-	contains the demux driver. The caller of this function is responsible for 
-	allocating dynamic or static memory for the demux structure and for initializing
-	its fields before calling this function. 
-	The memory allocated for the demux structure must not be freed before calling
-        dmx_unregister_demux(),
-
-    Returns
-    
-	0				The command was successfully performed.
-
-        -EEXIST                         A demux with the same value of the id field
-                                        already stored in the directory.
-
-        -ENOSPC                         No space left in the directory.
-
-
-
-
-

-

-

-
-int dmx_unregister_demux ( dmx_demux_t* demux )
-
-    Parameters
-
-	dmx_demux_t* demux	    I/O Pointer to the demux API and instance variables.
-
-    Description
-
-	This function is called to indicate that the given demux interface is no longer
-	available. The caller of this function is responsible for freeing the memory of
-	the demux structure, if it was dynamically allocated before calling 
-	dmx_register_demux().
-	The cleanup_module() function of the kernel module that contains the demux 
-	driver should call this function. Note that this function fails if the demux 
-	is currently in use, i.e., release_demux() has not been called for the 
-	interface.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -ENODEV                         No such demux registered.
-
-        -EBUSY                          Demux is currently in use.
-
-
-
-
-

-

-

-
-struct list_head* dmx_get_demuxes ()
-
-    Description
-
-	Provides the caller with the list of registered demux interfaces, using the 
-	standard list structure defined in the include file linux/list.h. 
-	The include file demux.h defines the macro DMX_DIR_ENTRY() for converting an 
-	element of the generic type struct list_head* to the type dmx_demux_t*.
-        The caller must not free the memory of any of the elements obtained via this
-	function call.
-
-    Returns
-
-	A list of demux interfaces, or NULL in the case of an empty list.
-
-
-
-
-

-

- - -

-Demux API -

- The demux API should be implemented for each demux in the system. It is used to - select the TS source of a demux and to manage the demux resources. When the - demux client allocates a resource via the demux API, it receives a pointer - to the API of that resource. -

-

- Each demux receives its TS input from a DVB front-end or from the memory, as - set via the demux API. In a system with more than one front-end, the API can - be used to select one of the DVB front-ends as a TS source for a demux, unless - this is fixed in the HW platform. The demux API only controls front-ends - regarding their connections with demuxes; the APIs used to set the other - front-end parameters, such as tuning, are not defined in this document. -

-

- The functions that implement the abstract interface demux_t should be defined - static or module private and registered to the Demux Directory for external - access. It is not necessary to implement every function in the demux_t struct, - however (for example, a demux interface might support Section filtering, but - not TS or PES filtering). The API client is expected to check the value of any - function pointer before calling the function: the value of NULL means "function - not available". -

-

- Whenever the functions of the demux API modify shared data, the possibilities - of lost update and race condition problems should be addressed, e.g. by - protecting parts of code with mutexes. This is especially important on - multi-processor hosts. -

-

- Note that functions called from a bottom half context must not sleep, at least - in the 2.2.x kernels. Even a simple memory allocation can result in a kernel - thread being put to sleep if swapping is needed. For example, the Linux kernel - calls the functions of a network device interface from a bottom half context. - Thus, if a demux API function is called from network device code, the function - must not sleep. -

-

-

-
-int open ( demux_t* demux )
-
-
-    Parameters
-    
-	demux_t* demux		      I Pointer to the demux API and instance data.
-
-    Description
-
-	This function reserves the demux for use by the caller and, if necessary, 
-	initializes the demux. When the demux is no longer needed, the function close()
-	should be called.
-        It should be possible for multiple clients to access the demux at the same time.
-	Thus, the function implementation should increment the demux usage count when 
-	open() is called and decrement it when close() is called.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -EUSERS                         Maximum usage count reached.
-
-        -EINVAL                         Bad parameter.
-
-
-
-
-

-

-

-
-int close ( demux_t* demux )
-
-    Parameters
-
-	demux_t* demux		      I Pointer to the demux API and instance data.
-
-    Description
-
-	The function is called to indicate that the API client does not need to use 
-	the demux anymore. As a result of this function, the demux usage count is 
-	decremented by one.
-        When the usage count drops to zero, any demux resources can be released.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -ENODEV                         The demux was not in use.
-
-        -EINVAL                         Bad parameter.
-
-
-
-
-

-

-

-
-int write ( demux_t* demux, const char* buf, size_t count)    
-
-    Parameters
-
-	demux_t* demux		    I/O Pointer to the demux API and instance data.
-
-        const char* buf               I Pointer to the TS data in kernel-space memory.
-
-        size_t length                 I Length of the TS data.
-
-
-
-    Description
-
-	This function provides the demux driver with a memory buffer containing TS 
-	packets. Instead of receiving TS packets from the DVB front-end, the demux 
-	driver software will read packets from the memory. Any clients of this demux 
-	with active TS, PES or Section filters will receive filtered data via the Demux
-	callback API (see 0). The function returns when all the data in the buffer has
-	been consumed by the demux.
-	Demux hardware typically cannot read TS from the memory. If this is the case,
-        memory-based filtering has to be implemented entirely in software.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -ENOSYS                         The command is not implemented.
-
-        -EINVAL                         Bad parameter.
-
-
-
-
-

-

-

-
-int allocate_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t** feed, dmx_ts_cb callback )
-
-    Parameters
-
-	demux_t* demux		    I/O Pointer to the demux API and instance data.
-
-        dmx_ts_feed_t** feed          O Pointer to the TS feed API and instance data.
-
-        dmx_ts_cb callback            I Pointer to the callback function for
-                                        passing received TS packet
-
-    Description
-
-	Allocates a new TS feed, which is used to filter the TS packets carrying a 
-	certain PID.
-        The TS feed normally corresponds to a hardware PID filter on the demux chip.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -EBUSY                          No more TS feeds available.
- 
-	-ENOSYS                         The command is not implemented.
-
-        -EINVAL                         Bad parameters.
-
-
-
-
-

-

-

-int release_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t* feed)
-
-    Parameters
-
-             dmx_demux_t* demux                        I/O Pointer to the demux API and
-                                                             instance data.
-             dmx_ts_feed_t* feed                       I     Pointer to the TS feed API and
-                                                             instance data.
-
-            Function Detailed Description
-            Releases the resources allocated with allocate_ts_feed(). Any filtering in progress
-            on the TS feed should be stopped before calling this function.
-
-            Function Returns
-             0                                         The command was successfully performed.
-             -EINVAL                                   Bad parameters.
-
-
-

-

-

-allocate_pes_feed()
-
-            TBD
-
-
-
-
-

-

-

-release_pes_feed()
-
-            TBD
-
-
-
-
-

-

-

-int allocate_section_feed ( dmx_demux_t* demux,
-             dmx_section_feed_t** 
-                                                                            feed,
-                                                dmx_section_cb callback )
-
-            Function Parameters
-             demux_t* demux                            I/O Pointer to the demux API and
-                                                             instance data.
-             dmx_section_feed_t** feed                 O     Pointer to the section feed API and
-
-                                                                instance data.
-             dmx_section_cb callback                  I         Pointer to the callback function for
-                                                                passing received sections
-
-            Function Detailed Description
-            Allocates a new section feed, i.e. a demux resource for filtering and receiving sections.
-            On platforms with hardware support for section filtering, a section feed is directly
-            mapped to the demux HW. On other platforms, TS packets are first PID filtered in
-            hardware and a hardware section filter then emulated in software.
-            The caller obtains an API pointer of type dmx_section_feed_t as an out parameter.
-            Using this API the caller can set filtering parameters and start receiving sections.
-
-            Function Returns
-             0                                        The command was successfully performed.
-             -EBUSY                                   No more section feeds available.
-             -ENOSYS                                  The command is not implemented.
-             -EINVAL                                  Bad parameters.
-
-
-

-

-

-
-int release_section_feed ( dmx_demux_t* demux,
-             dmx_section_feed_t* 
-                                                                          feed 
-                                                                                  )
-            Function Parameters
-             dmx_demux_t* demux                            I/O Pointer to the demux API and
-                                                                  instance data.
-             dmx_section_feed_t* feed                      I      Pointer to the section feed API and
-                                                                  instance data.
-
-            Function Detailed Description
-            Releases the resources allocated with allocate_section_feed(), including allocated
-            filters. Any filtering in progress on the section feed should be stopped before calling
-            this function.
-
-            Function Returns
-             0                                        The command was successfully performed.
-             -EINVAL                                  Bad parameters.
-
-
-
-

-

-

-
-int descramble_mac_address ( dmx_demux_t* demux,
-             __u8* 
-                                                            buffer1,
-             size_t 
-                                                             buffer1_length,
-                                                   __u8* buffer2,
-             size_t 
-                                                             buffer2_length,
-                                                   __u16 pid )
-            Function Parameters
-             dmx_demux_t* demux                             I/O Pointer to the demux API and
-                                                                   instance data.
-             __u8* buffer1                                  I      Pointer to the first byte of the
-                                                                   section.
-             size_t buffer1_length                          I      Length of the section data,
-                                                                   including headers and CRC, in
-                                                                   buffer1.
-             __u8* buffer2                                  I      Pointer to the tail of the section
-                                                                   data, or NULL. The pointer has a
-                                                                   non-NULL value if the section wraps
-                                                                   past the end of a cyclic buffer.
-             size_t buffer2_length                          I      Length of the section data,
-                                                                   including headers and CRC, in
-                                                                   buffer2
-             __u16 pid                                      I      The PID on which the section was
-                                                                   received. Useful for obtaining the
-                                                                   descrambling key, e.g. from a DVB
-                                                                   Common Access facility.
-
-            Function Detailed Description
-            This function runs a descrambling algorithm on the destination MAC address field of a
-            DVB Datagram Section, replacing the original address with its unencrypted version.
-            Otherwise, the description on the function descramble_section_payload() applies
-            also to this function.
-
-            Function Returns
-             0                                         The command was successfully performed.
-             -ENOSYS                                   No descrambling facility available.
-             -EINVAL                                   Bad parameters.
-
-
-
-
-
-

-

-

-
-int descramble_section_payload (           dmx_demux_t* demux,
-             __u8* 
-                                                                  buffer1,
-             size_t 
-                                                                   buffer1_length,
-                                                       __u8* buffer2,
-             size_t 
-                                                                   buffer2_length,
-                                                       __u16 pid )
-            Function Parameters
-             dmx_demux_t* demux                            I/O Pointer to the demux API and
-                                                                  instance data.
-             __u8* buffer1                                 I/O Pointer to the first byte of the
-                                                                  section.
-             size_t buffer1_length                         I      Length of the section data,
-                                                                  including headers and CRC, in
-                                                                  buffer1.
-             __u8* buffer2                                 I      Pointer to the tail of the section
-                                                                  data, or NULL. The pointer has a
-                                                                  non-NULL value if the section wraps
-                                                                  past the end of a cyclic buffer.
-             size_t buffer2_length                         I      Length of the section data,
-                                                                  including headers and CRC, in
-                                                                  buffer2
-             __u16 pid                                     I      The PID on which the section was
-                                                                  received. Useful for obtaining the
-                                                                  descrambling key, e.g. from a DVB
-                                                                  Common Access facility.
-
-            Function Detailed Description
-            This function runs a descrambling algorithm on the payload of a DVB Datagram
-            Section, replacing the original payload with its unencrypted version. The function will
-            be called from the demux API implementation; the API client need not call this function
-            directly.
-            Section-level scrambling algorithms are currently standardized only for DVB-RCC
-            (return channel over 2-directional cable TV network) systems. For all other DVB
-            networks, encryption schemes are likely to be proprietary to each data broadcaster.
-            Thus, it is expected that this function pointer will have the value of NULL (i.e., function
-            not available) in most demux API implementations. Nevertheless, it should be possible
-            to use the function pointer as a hook for dynamically adding a "plug-in" descrambling
-            facility to a demux driver.
-
-
-            While this function is not needed with hardware-based section descrambling, the
-            descramble_section_payload function pointer can be used to override the default
-            hardware-based descrambling algorithm: if the function pointer has a non-NULL value,
-            the corresponding function should be used instead of any descrambling hardware.
-
-            Function Returns
-             0                                           The command was successfully performed.
-             -ENOSYS                                     No descrambling facility available.
-             -EINVAL                                     Bad parameters.
-
-
-
-

-

-

-
-int add_frontend ( dmx_demux_t* demux,
-             dmx_frontend_t* 
-                                                          frontend);
-
-            Function Parameters
-             dmx_demux_t* demux                        I/O Pointer to the demux API and instance
-                                                             data.
-             dmx_frontend_t* frontend                  I/O Pointer to the front-end instance data.
-
-            Function Detailed Description
-            Registers a connectivity between a demux and a front-end, i.e., indicates that the
-            demux can be connected via a call to connect_frontend() to use the given front-end
-            as a TS source. The client of this function has to allocate dynamic or static memory for
-            the frontend structure and initialize its fields  before calling this function.
-            This function is normally called during the driver initialization. The caller must not free
-            the memory of the frontend struct before successfully calling remove_frontend().
-
-            Function Returns
-             0                                      The command was successfully performed.
-             -EEXIST                                A front-end with the same value of the id field
-                                                    already registered.
-             -EINUSE                                The demux is in use.
-             -ENOMEM                                No more front-ends can be added.
-             -EINVAL                                Bad parameters.
-
-
-

-

-

-
-int remove_frontend ( dmx_demux_t* demux,
-                                         dmx_frontend_t* frontend )
-            Function Parameters
-             dmx_demux_t* demux                   I/O       Pointer to the demux API and instance
-                                                            data.
-             dmx_frontend_t* frontend             I/O       Pointer to the front-end instance data.
-
-            Function Detailed Description
-            Indicates that the given front-end, registered by a call to add_frontend(), can no
-            longer be connected as a TS source by this demux. The function should be called
-            when a front-end driver or a demux driver is removed from the system. If the front-end
-            is in use, the function fails with the return value of ­EBUSY.
-            After succesfully calling this function, the caller can free the memory of the frontend
-            struct if it was dynamically allocated before the add_frontend() operation.
-
-            Function Returns
-             0                                     The command was successfully performed.
-             -EINVAL                               Bad parameters.
-             -EBUSY                                The front-end is in use, i.e. a call to
-                                                   connect_frontend() has not been followed by
-                                                   a call to disconnect_frontend().
-
-
-
-

-

-

-
-struct list_head* get_frontends ( dmx_demux_t* demux )
-            Function Parameters
-             dmx_demux_t* demux                             I    Pointer to the demux API and
-                                                                 instance data.
-
-            Function Detailed Description
-            Provides the APIs of the front-ends that have been registered for this demux. Any of
-            the front-ends obtained with this call can be used as a parameter for
-            connect_frontend().
-
-
-            The include file demux.h contains the macro DMX_FE_ENTRY() for converting an
-            element of the generic type struct list_head* to the type dmx_frontend_t*.
-            The caller must not free the memory of any of the elements obtained via this function
-            call.
-
-            Function Returns
-            A list of front-end interfaces, or NULL in the case of an empty list.
-
-
-

-

-

-
-int connect_frontend ( dmx_demux_t* demux,
-                                           dmx_frontend_t* frontend )
-            Function Parameters
-             dmx_demux_t* demux                   I/O       Pointer to the demux API and instance
-                                                            data.
-             dmx_frontend_t* frontend             I/O       Pointer to the front-end instance data.
-
-            Function Detailed Description
-            Connects the TS output of the front-end to the input of the demux. A demux can only
-            be connected to a front-end registered to the demux with the function
-            add_frontend().
-            It may or may not be possible to connect multiple demuxes to the same front-end,
-            depending on the capabilities of the HW platform. When not used, the front-end should
-            be released by calling disconnect_frontend().
-
-            Function Returns
-             0                                     The command was successfully performed.
-             -EINVAL                               Bad parameters.
-             -EBUSY                                The front-end is in use.
-
-
-

-

-

-
-int disconnect_frontend ( dmx_demux_t* demux )
-
-
-            Function Parameters
-             dmx_demux_t* demux               I/O Pointer to the demux API and instance data.
-
-            Function Detailed Description
-            Disconnects the demux and a front-end previously connected by a
-            connect_frontend() call.
-
-            Function Returns
-             0                                        The command was successfully performed.
-             -EINVAL                                  Bad parameters.
-
-
-
-

-

- -

-Demux Callback API -

- This kernel-space API comprises the callback functions that deliver filtered data to the - demux client. Unlike the other APIs, these API functions are provided by the client and - called from the demux code. -

-

- The function pointers of this abstract interface are not packed into a structure as in the - other demux APIs, because the callback functions are registered and used - independent of each other. As an example, it is possible for the API client to provide - several callback functions for receiving TS packets and no callbacks for PES packets - or sections. -

-

- The functions that implement the callback API need not be re-entrant: when a demux - driver calls one of these functions, the driver is not allowed to call the function again - before the original call returns. If a callback is triggered by a hardware interrupt, it is - recommended to use the Linux "bottom half" mechanism or start a tasklet instead of - making the callback function call directly from a hardware interrupt. - -

-

-

-int dmx_ts_cb ( __u8* buffer1, size_t buffer1_length, 
-		__u8* buffer2, size_t buffer2_length,
-                dmx_ts_feed_t* source, dmx_success_t success )
-
-    Parameters
-
-	__u8* buffer1		      I Pointer to the start of the filtered TS packets.
-
-        size_t buffer1_length         I Length of the TS data in buffer1.
-
-        __u8* buffer2                 I Pointer to the tail of the filtered TS packets, or NULL.
-
-        size_t buffer2_length         I Length of the TS data in buffer2.
-
-        dmx_ts_feed_t* source         I Indicates which TS feed is the source of the callback.
-
-        dmx_success_t success         I Indicates if there was an error in TS reception.
-
-    Description
-
-	This function, provided by the client of the demux API, is called from the 
-	demux code. The function is only called when filtering on this TS feed has 
-	been enabled using the start_filtering() function. If conflict resolution 
-	is used (see Error! Reference source not found.), no callbacks are made to 
-	clients that have been put "on hold" regarding a TS Feed resource.
-        Any TS packets that match the filter settings are copied to a cyclic buffer. 
-	The filtered TS packets are delivered to the client using this callback 
-	function. The size of the cyclic buffer is controlled by the 
-	circular_buffer_size parameter of the set() function in the TS Feed API. It is
-	expected that the buffer1 and buffer2 callback parameters point to addresses 
-	within the circular buffer, but other implementations are also
-        possible. Note that the called party should not try to free the memory the
-	buffer1 and buffer2 parameters point to.
-        When this function is called, the buffer1 parameter typically points to the
-	start of the first undelivered TS packet within a cyclic buffer. The buffer2 
-	buffer parameter is normally NULL, except when the received TS packets have
-	crossed the last address of the cyclic buffer and "wrapped" to the beginning
-	of the buffer. In the latter case the buffer1 parameter would contain an 
-	address within the cyclic buffer, while the buffer2 parameter would contain 
-	the first address of the cyclic buffer.
-        The number of bytes delivered with this function (i.e. buffer1_length  +
-        buffer2_length) is usually equal to the value of callback_length parameter given
-        in the set() function, with one exception: if a timeout occurs before receiving
-        callback_length bytes of TS data, any undelivered packets are immediately
-        delivered to the client by calling this function. The timeout duration is 
-	controlled by the set() function in the TS Feed API.
-        If a TS packet is received with errors that could not be fixed by the TS-level
-	forward error correction (FEC), the Transport_error_indicator flag of the TS 
-	packet header should be set. The TS packet should not be discarded, as the 
-	error can possibly be corrected by a higher layer protocol.
-        If the called party is slow in processing the callback, it is possible that 
-	the circular buffer eventually fills up. If this happens, the demux driver 
-	should discard any TS packets received while the buffer is full. The error 
-	should be indicated to the client on the next callback by setting the success
-	parameter to the value of DMX_OVERRUN_ERROR.
-
-    Returns
-
-	0				Continue filtering.
-
-       -1                               Stop filtering - has the same effect as a call
-                                        to stop_filtering() on the TS Feed API.
-
-
-
-
-

-

-

-
-dmx_pes_cb()
-
-	TBD
-
-
-

-

-

-
-int dmx_section_cb ( __u8* buffer1,
-             size_t 
-                                                   buffer1_length,
-             __u8* 
-                                               buffer2,
-                                 size_t buffer2_length,
-             dmx_section_filter_t* 
-                                                                      source,
-                                       dmx_success_t success )
-
-            Function Parameters
-             __u8* buffer1                    I       Pointer to the start of the filtered section, e.g.
-                                                      within the cyclic buffer of the demux driver.
-             size_t buffer1_length            I       Length of the filtered section data in buffer1,
-                                                      including headers and CRC.
-             __u8* buffer2                            Pointer to the tail of the filtered section data, or
-                                                      NULL. Useful to handle the wrapping of a cyclic
-                                                      buffer.
-             size_t buffer2_length                    Length of the filtered section data in buffer2,
-                                                      including headers and CRC.
-             dmx_section_filter_t*            I       Indicates the filter that triggered the callback.
-             filter
-             dmx_success_t success            I       Indicates if there was an error in section
-                                                      reception.
-
-            Function Detailed Description
-            This function, provided by the client of the demux API, is called from the demux code.
-            The function is only called when filtering of sections has been enabled using the
-            function start_filtering() of the section feed API.
-            When the demux driver has received a complete section that matches at least one
-            section filter, the client is notified via this callback function. Normally this function is
-            called for each received section; however, it is also possible to deliver multiple sections
-            with one callback, for example when the system load is high.
-            If an error occurs while receiving a section, this function should be called with the
-            corresponding error type set in the success field, whether or not there is data to
-            deliver.
-            The Section Feed implementation should maintain a cyclic buffer for received sections.
-            However, this is not necessary if the Section Feed API is implemented as a client of
-
-
-            the TS Feed API, because the TS Feed implementation then buffers the
-            received data.
-            The size of the circular buffer can be configured using the set() function in the
-            Section Feed API. If there is no room in the circular buffer when a new section is
-            received, the section must be discarded. If this happens, the value of the success
-            parameter should be DMX_OVERRUN_ERROR on the next callback.
-
-            Function Returns
-             0                                         Continue filtering.
-             -1                                        Stop filtering - has the same effect as a call
-                                                       to stop_filtering() on the Section Feed
-                                                       API.
-
-
-

- -

- -

-TS Feed API -

- A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this - API, the client can set the filtering properties to start/stop filtering TS packets on a - particular TS feed. The API is defined as an abstract interface of the type - dmx_ts_feed_t. -

-

- The functions that implement the interface should be defined static or module - private. The client can get the handle of a TS feed API by calling the function - allocate_ts_feed() in the demux API. -

-

-

-
-int set ( dmx_ts_feed_t* feed,
-             __u16 
-                                    pid,
-                           size_t callback_length,
-             size_t 
-                                     cyclic_buffer_size,
-             int 
-                               descramble,
-                           struct timespec timeout)
-
-    Parameters
-
-             dmx_ts_feed_t* feed                       I/O Pointer to the TS feed API and
-                                                               instance data.
-             __u16 pid                                 I       PID value to filter. Only the TS
-                                                               packets carrying the specified PID will
-                                                               be passed to the API client.
-             size_t callback_length                    I       Number of bytes to deliver with each
-                                                               call to the dmx_ts_cb() callback
-                                                               function. The value of this
-                                                               parameter should be a multiple of
-                                                               188.
-
-             size_t cyclic_buffer_size                    I     Size of the cyclic buffer for the filtered
-                                                                TS packets.
-             int descramble                               I     If non-zero, descramble the filtered
-                                                                TS packets.
-             struct timespec timeout                      I     Maximum time to wait before
-                                                                delivering received TS packets to the
-                                                                client.
-
-            Function Detailed Description
-            This function sets the parameters of a TS feed. Any filtering in progress on the TS feed
-            must be stopped before calling this function.
-
-            Function Returns
-             0                                            The command was successfully performed.
-             -ENOMEM                                      Not enough memory for the requested
-                                                          buffer size.
-             -ENOSYS                                      No descrambling facility available for TS
-                                                          packets.
-             -EINVAL                                      Bad parameters.
-
-
-

-

-

-
-int start_filtering ( dmx_ts_feed_t* feed )
-
-    Parameters
- 
-             dmx_ts_feed_t* feed                    I Pointer to the TS feed API and instance data.
-
-            Function Detailed Description
-            Starts filtering TS packets on this TS feed, according to its settings. The PID value to
-            filter can be set by the API client. All matching TS packets are delivered
-            asynchronously to the client, using the callback function registered with
-            allocate_ts_feed().
-
-            Function Returns
-             0                                        The command was successfully performed.
-             -EINVAL                                  Bad parameters.
-
-
-
-

-

-

-
-int stop_filtering ( dmx_ts_feed_t* feed )
-
-    Parameters
-
-	dmx_ts_feed_t* feed	    I/O Pointer to the TS feed API and instance data.
-
-    Description
-
-	Stops filtering TS packets on this TS feed.
-
-    Returns
-
-	0				The command was successfully performed.
-
-        -EINVAL                         Bad parameters.
-
-
-
-
-

-

- -

-PES Feed API -

- TBD -

-

- -

-Section Feed API -

- A section feed is a resource consisting of a PID filter and a set of section filters. Using - this API, the client can set the properties of a section feed and to start/stop filtering. - The API is defined as an abstract interface of the type dmx_section_feed_t. - The functions that implement the interface should be defined static or module - private. The client can get the handle of a section feed API by calling the function - allocate_section_feed() in the demux API. -

-

- On demux platforms that provide section filtering in hardware, the Section Feed API - implementation provides a software wrapper for the demux hardware. Other platforms - may support only PID filtering in hardware, requiring that TS packets are converted to - sections in software. In the latter case the Section Feed API implementation can be a - client of the TS Feed API. -

- -

-

-
-int set ( dmx_section_feed_t* feed, __u16 pid, size_t circular_buffer_size, 
-	  int descramble, int check_crc )
-
-    Parameters
-
-	dmx_section_feed_t* feed                  I/O Pointer to the section feed API and
-                                                                instance data.
-             __u16 pid                                I         PID value to filter; only the TS packets
-                                                                carrying the specified PID will be
-                                                                accepted.
-             size_t circular_buffer_size              I         Size of the cyclic buffer for filtered
-                                                                sections.
-             int descramble                           I         If non-zero, descramble any sections
-                                                                that are scrambled.
-             int check_crc                            I         If non-zero, check  the CRC values of
-                                                                filtered sections.
-
-            Function Detailed Description
-            This function sets the parameters of a section feed. Any filtering in progress on the
-            section feed must be stopped before calling this function.
-            If descrambling is enabled, the payload_scrambling_control and
-            address_scrambling_control fields of received DVB datagram sections should be
-            observed. If either one is non-zero, the section should be descrambled either in
-            hardware or using the functions descramble_mac_address() and
-            descramble_section_payload() of the demux API. Note that according to the
-            MPEG-2 Systems specification [3], only the payloads of private sections can be
-            scrambled while the rest of the section data must be sent in the clear.
-
-            Function Returns
-             0                                     The command was successfully performed.
-             -ENOMEM                               Not enough memory available for the requested
-                                                   buffer size.
-             -ENOSYS                               No descrambling facility available for sections.
-             -EINVAL                               Bad parameters.
-
-
-

-

-

-
-int allocate_filter(dmx_section_feed_t* feed, dmx_section_filter_t** filter)
-
-    Parameters
-             dmx_section_feed_t* feed                      I/O Pointer to the section feed API and
-                                                                 instance data.
-             dmx_section_filter_t** filter                 O     Pointer to the allocated filter.
-
-
-            Function Detailed Description
-            This function is used to allocate a section filter on the demux. It should only be called
-            when no filtering is in progress on this section feed. If a filter cannot be allocated, the
-            function fails with -ENOSPC. See below for the format of the section filter struct provided
-            as an out parameter:
-                   typedef struct {
-                           __u8 filter_value [DMX_MAX_FILTER_SIZE];
-                           __u8 filter_mask [DMX_MAX_FILTER_SIZE];
-                            struct dmx_section_feed_s* parent;  /* Back-pointer */
-                           void* priv; /* Private data of the client */
-                   } dmx_section_filter_t;
-
-            The bitfields filter_mask and filter_value should only be modified when no
-            filtering is in progress on this section feed. filter_mask controls which bits of
-            filter_value are compared with the section headers/payload. On a binary value of 1
-            in filter_mask, the corresponding bits are compared. The filter only accepts sections
-            that are equal to filter_value in all the tested bit positions. Any changes to the
-            values of filter_mask and filter_value are guaranteed to take effect only when
-            the start_filtering()  function is called next time. The parent pointer in the struct
-            is initialized by the API implementation to the value of the feed parameter. The priv
-            pointer is not used by the API implementation, and can thus be freely utilized by the
-            caller of this function. Any data pointed to by the priv pointer is available to the
-            recipient of the dmx_section_cb() function call.
-            While the maximum section filter length (DMX_MAX_FILTER_SIZE) is currently set at 16
-            bytes, hardware filters of that size are not available on all platforms. Therefore, section
-            filtering will often take place first in hardware, followed by filtering in software for the
-            header bytes that were not covered by a hardware filter. The filter_mask field can be
-            checked to determine how many bytes of the section filter are actually used, and if the
-            hardware filter will suffice. Additionally, software-only section filters can optionally be
-            allocated to clients when all hardware section filters are in use.
-            Note that on most demux hardware it is not possible to filter on the section_length field
-            of the section header ­ thus this field is ignored, even though it is included in
-            filter_value and filter_mask fields.
-
-            Function Returns
-             0                                          The command was successfully performed.
-             -ENOSPC                                    No filters of given type and length available.
-             -EINVAL                                    Bad parameters.
-
-
-

-

-

-int release_filter ( dmx_section_feed_t* feed, dmx_section_filter_t* filter)
-
-    Parameters
-             dmx_section_feed_t* feed I/O Pointer to the section feed API and instance
-                                                       data.
-             dmx_section_filter_t*              I/O Pointer to the instance data of a section filter.
-             filter
-
-            Function Detailed Description
-            This function releases all the resources of a previously allocated section filter. The
-            function should not be called while filtering is in progress on this section feed. After
-            calling this function, the caller should not try to dereference the filter pointer.
-
-            Function Returns
-             0                                        The command was successfully performed.
-             -ENODEV                                  No such filter allocated.
-             -EINVAL                                  Bad parameters.
-
-
-

-

-

-int start_filtering ( dmx_section_feed_t* feed )
-
-    Parameters
-             dmx_section_feed_t* feed                     I/O Pointer to the section feed API and
-                                                                instance data.
-
-            Function Detailed Description
-            Starts filtering sections on this section feed, according to its settings. Sections are first
-            filtered based on their PID and then matched with the section filters allocated for this
-            feed. If the section matches the PID filter and at least one section filter, it is delivered
-            to the API client. The section is delivered asynchronously using the callback function
-            registered with allocate_section_feed().
-
-            Function Returns
-             0                                            The command was successfully performed.
-             -EINVAL                                      Bad parameters.
-
-
-

-

-

-int stop_filtering ( dmx_section_feed_t* feed )
-
-    Parameters
-
-	dmx_section_feed_t* feed	    I/O Pointer to the section feed API and instance data.
-
-    Description
-
-	Stops filtering sections on this section feed. Note that any changes to the 
-	filtering parameters (filter_value, filter_mask, etc.) should only be made 
-	when filtering is stopped.
-
-    Returns
-
-	0					The command was successfully performed.
-
-        -EINVAL                                 Bad parameters.
-
-
-
-
-

-

-
- - diff --git a/dvb-spec/API/dvb_api/dmx.h b/dvb-spec/API/dvb_api/dmx.h deleted file mode 100644 index e12056514..000000000 --- a/dvb-spec/API/dvb_api/dmx.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * dmx.h - * - * Copyright (C) 2000 Marcus Metzler - * & Ralph Metzler - for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _OST_DMX_H_ -#define _OST_DMX_H_ - -/* pid_t conflicts with linux/include/linux/types.h !!!*/ - -typedef uint16_t dvb_pid_t; - -#define DMX_FILTER_SIZE 16 - -typedef enum -{ - DMX_OUT_DECODER, /* Streaming directly to decoder. */ - DMX_OUT_TAP, /* Output going to a memory buffer */ - /* (to be retrieved via the read command).*/ - DMX_OUT_TS_TAP /* Output multiplexed into a new TS */ - /* (to be retrieved by reading from the */ - /* logical DVR device). */ -} dmxOutput_t; - - -typedef enum -{ - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ -} dmxInput_t; - - -typedef enum -{ - DMX_PES_AUDIO, - DMX_PES_VIDEO, - DMX_PES_TELETEXT, - DMX_PES_SUBTITLE, - DMX_PES_PCR, - DMX_PES_OTHER -} dmxPesType_t; - - -typedef enum -{ - DMX_SCRAMBLING_EV, - DMX_FRONTEND_EV -} dmxEvent_t; - - -typedef enum -{ - DMX_SCRAMBLING_OFF, - DMX_SCRAMBLING_ON -} dmxScramblingStatus_t; - - -typedef struct dmxFilter -{ - uint8_t filter[DMX_FILTER_SIZE]; - uint8_t mask[DMX_FILTER_SIZE]; -} dmxFilter_t; - -struct dmxFrontEnd -{ - //TBD tbd; -}; - -struct dmxSctFilterParams -{ - dvb_pid_t pid; - dmxFilter_t filter; - uint32_t timeout; - uint32_t flags; -#define DMX_CHECK_CRC 1 -#define DMX_ONESHOT 2 -#define DMX_IMMEDIATE_START 4 -}; - - -struct dmxPesFilterParams -{ - dvb_pid_t pid; - dmxInput_t input; - dmxOutput_t output; - dmxPesType_t pesType; - uint32_t flags; -}; - - -struct dmxEvent -{ - dmxEvent_t event; - time_t timeStamp; - union - { - dmxScramblingStatus_t scrambling; - //TBD; - } u; -}; - - -#define DMX_START _IOW('o',41,void) -#define DMX_STOP _IOW('o',42,void) -#define DMX_SET_FILTER _IOW('o',43,struct dmxSctFilterParams *) -#define DMX_SET_PES_FILTER _IOW('o',44,struct dmxPesFilterParams *) -#define DMX_SET_BUFFER_SIZE _IOW('o',45,unsigned long) -#define DMX_GET_EVENT _IOR('o',46,struct dmxEvent *) - - - -#endif /*_OST_DMX_H_*/ diff --git a/dvb-spec/API/dvb_api/frontend.h b/dvb-spec/API/dvb_api/frontend.h deleted file mode 100644 index 534a97175..000000000 --- a/dvb-spec/API/dvb_api/frontend.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * frontend.h - * - * Copyright (C) 2000 Marcus Metzler - * & Ralph Metzler - for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _OST_FRONTEND_H_ -#define _OST_FRONTEND_H_ - -typedef uint32_t feStatus; - -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define QPSK_SPECTRUM_INV 4 - -struct qpskParameters { - uint32_t iFrequency; - uint32_t SymbolRate; - uint8_t FEC_inner; -}; - - -struct qpskEvent { - int32_t type; - time_t timestamp; - union { - struct { - feStatus previousStatus; - feStatus currentStatus; - } unexpectedEvent; - struct qpskParameters completionEvent; - feStatus failureEvent; - } u; -}; - - -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; - - -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; - -typedef enum { - OST_POWER_ON, - OST_POWER_STANDBY, - OST_POWER_SUSPEND, - OST_POWER_OFF -} powerState_t; - - -#define OST_SELFTEST _IOWR('o',61,void) -#define OST_SET_POWER_STATE _IOW('o',62,uint32_t) -#define OST_GET_POWER_STATE _IOR('o',63,uint32_t *) -#define FE_READ_STATUS _IOR('o',64,feStatus *) -#define FE_READ_BER _IOW('o',65,uint32_t *) -#define FE_READ_SIGNAL_STRENGTH _IOR('o',66,int32_t *) -#define FE_READ_SNR _IOR('o',67,int32_t *) -#define FE_READ_UNCORRECTED_BLOCKS _IOW('o',68,uint32_t *) -#define FE_GET_NEXT_FREQUENCY _IOW('o',69,uint32_t *) -#define FE_GET_NEXT_SYMBOL_RATE _IOW('o',70,uint32_t *) - -#define QPSK_TUNE _IOW('o',71,struct qpskParameters *) -#define QPSK_GET_EVENT _IOR('o',72,struct qpskEvent *) -#define QPSK_FE_INFO _IOR('o',73,struct qpskFrontendInfo *) -#define QPSK_WRITE_REGISTER _IOW('o',74,struct qpskRegister *) -#define QPSK_READ_REGISTER _IOR('o',75,struct qpskRegister *) - -#endif /*_OST_FRONTEND_H_*/ - diff --git a/dvb-spec/API/dvb_api/frontend.xml b/dvb-spec/API/dvb_api/frontend.xml deleted file mode 100644 index 1cd1b0fbd..000000000 --- a/dvb-spec/API/dvb_api/frontend.xml +++ /dev/null @@ -1,843 +0,0 @@ - - - linuxtv.org|DVB Frontend API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB Frontend API

- -

- The DVB frontend device controls the frontend of the DVB hardware, e.g. - tuning, symbol rate, error correction, ... - It is accessed through /dev/ost/qpskfe. -

- -

- The function calls defined in the include file - frontend.h are described in detail below: -

- -

- Frontend API IO control calls - - -

-

-
-int open(const char *deviceName, int flags);
-
-    DESCRIPTION
-
-	This system call opens a named front-end device (e.g. /dev/qpskfe) for 
-	subsequent use. The device can be opened in read-only mode, which only allows
-	monitoring of device status and statistics, or read/write mode, which allows 
-	any kind of use (e.g. performing tuning operations.)
-
-	In a system with multiple front-ends, it is usually the case that multiple
-	devices cannot be open in read/write mode simultaneously.  As long as a 
-	front-end device is opened in read/write mode, other open() calls in 
-	read/write mode will either fail or block, depending on whether 
-	non-blocking or blocking mode was specified.
-        A front-end device opened in blocking mode can later be put into non-blocking
-	mode (and vice versa) using the F_SETFL command of the fcntl system call.
-	This is a standard system call, documented in the Linux manual page for fcntl.
-        When an open() call has succeeded, the device will be ready for use in the 
-	specified mode. This implies that the corresponding hardware is powered up, 
-	and that other front-ends may have been powered down to make that possible.
-
-    PARAMETERS
-
-	const char *deviceName	      I Name of specific front-end device.  In the
-                                        current implementation, /dev/qpskfe is the
-                                        only one available (QPSK satellite front-end.)
-
-	int flags	              I A bit-wise OR of the following flags:
-                                        O_RDONLY read-only access
-                                        O_RDWR read/write  access
-                                        O_NONBLOCK open in non-blocking mode
-                                                       (blocking mode is the default)
-    RETURNS
-
-	ENODEV				Device driver not loaded/available.
-
-        EBUSY				Device or resource busy.
-
-	EINVAL				Invalid argument.
-
-
-
-
-

- -

-

-
-int close(int fd);
-
-    DESCRIPTION
-
-	This system call closes a previously opened front-end device.  After closing a 
-	front-end device, its corresponding hardware might be powered down 
-	automatically, but only when this is needed to open another front-end device.
-	To affect an unconditional power down, it should be done explicitly using 
-	the OST_SET_POWER_STATE ioctl.
-
-    PARAMETERS
-
-	int fd                I File descriptor returned by a previous call to open().
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = OST_SELFTEST);
-
-    DESCRIPTION
-
-  	This ioctl call initiates an automatic self-test of the front-end hardware.  
-	This call requires read/write access to the device.
-
-    PARAMETERS
-
-	int fd                I File descriptor returned by a previous call to open().
-
-	int request	      I Equals OST_SELFTEST for this command.
-
-    RETURNS
-	
-	0                       Success
-
-	-1			Failure
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = OST_SET_POWER_STATE, uint32_t state);
-
-    DESCRIPTION
-
-	This ioctl call, implemented in many OST device drivers, enables direct 
-	control over the power state of the hardware device, which may be on, off, 
-	standby, or suspend.  The latter two are low-power modes, which disable all 
-	functionality of the device until turned on again. In contrast to the off 
-	state, however, the standby and suspend states resume operation in the same
-	state as when the device was active.  The only difference between the standby
-	and suspend states is a different tradeoff between resume time and power 
-	consumption ­ power consumption may be lower in the suspend state at the
-        cost of a longer resume time.
-
-        A device that implements this call does not necessarily support two low-power
-	modes. If it only support one low-power state, or none at all, the 
-	OST_SET_POWER_STATE operation for the missing states will still succeed, but 
-	it will be mapped to an existing state as per this table:
-
-        number of low-power	requested state		resulting state
-        states supported
-
-            1                      standby                  suspend
-
-            1                      suspend                  suspend
-
-            0                      standby                    on
-
-            0                      suspend                    on
-
-        For other cases where a required state is missing, an error code will be
-	returned.  This can happen if a device does not support the power-off state, 
-	but nevertheless implements this ioctl operation for control of low-power 
-	states.
-        When opening a device in read/write mode, the driver ensures that the 
-	corresponding hardware device is turned on initially.  If the device is 
-	later turned off or put in suspend mode, it has to be explicitly turned on 
-	again.
-
-        This call requires read/write access to the device.  (Note that the power 
-	management driver can affect the power state of devices without using this 
-	ioctl operation, so having exclusive read/write access to a device does not 
-	imply total control over the power state.)
-
-    PARAMETERS
-    
-	int fd		      I File descriptor returned by a previous call to open().
-
-	int request	      I Equals OST_SET_POWER_STATE for this command.
-
-	uint32_t state        I Requested power state.  One of:
-
-                                OST_POWER_ON:		turn power on
-                                OST_POWER_STANDBY:      set device in standby mode
-                                OST_POWER_SUSPEND:      set device in suspend mode
-                                OST_POWER_OFF:          turn power off
-
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EINVAL                  illegal state, or not available on this device
-
-        EPERM                   permission denied (needs read/write access)
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = OST_GET_POWER_STATE, uint32_t *state);
-
-    DESCRIPTION
-
-	This ioctl call, implemented in many OST device drivers, obtains the power
-	state of the hardware device, which may be on, off, standby, or suspend.
-        A device that implements this call does not necessarily support all four states.
-	If there is only one low-power state, the suspend state will be returned for 
-	that state.  If there is no low-power state, the on state will be reported 
-	standby and suspend states will be equivalent to the on state.
-        For this command, read-only access to the device is sufficient.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-	int request	      I Equals OST_GET_POWER_STATE for this command.
-
-        uint32_t *state	      O Pointer to a variable where the power state is
-                                to be stored.  Possible values are:
-                                OST_POWER_ON                      power is on
-                                OST_POWER_STANDBY                 device in 
-                                                                  standby mode
-                                OST_POWER_SUSPEND:                device in 
-                                                                  suspend mode
-                                OST_POWER_OFF:                    power is off
-
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-        
-	EINVAL                  illegal state, or not available on this device
-
-        EFAULT                  state points to invalid address
-
-        EPERM                   permission denied (needs read/write access)
-
-	ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_READ_STATUS, feStatus *status);
-
-    DESCRIPTION
-
-	This ioctl call returns status information about the front-end.
-	This call only requires read-only access to the device.
-
-    PARAMETERS
-
-	int fd                   I File descriptor returned by a previous call to open().
-
-        int request              I Equals FE_READ_STATUS for this command.
-
-        struct feStatus *status  O Points to the location where the front-end
-                                   status word is to be stored.
-
-    RETURNS
-
-	EBADF                      fd is not a valid open file descriptor
-
-        EFAULT                     status points to invalid address
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = FE_READ_BER, uint32_t *ber);
-
-    DESCRIPTION
-
-	This ioctl call returns the bit error rate for the signal currently 
-	received/demodulated by the front-end. For this command, read-only access 
-	to the device is sufficient.
-
-    FUNCTION PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request	      I Equals FE_READ_BER for this command.
-
-        uint32_t *ber         O The bit error rate, as a multiple of 10-9, is stored into *ber.
-
-                                Example: a value of 2500 corresponds to a bit error 
-					 rate of 2.5 10-6, or 1 error in 400000 bits.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EFAULT			ber points to invalid address
-
-        ENOSIGNAL               There is no signal, thus no meaningful bit error
-                                rate.  Also returned if the front-end is not turned on.
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = FE_READ_SIGNAL_STRENGTH, int32_t *strength);
-
-    DESCRIPTION
-
-	This ioctl call returns the signal strength value for the signal currently 
-	received by the front-end. For this command, read-only access to the device 
-	is sufficient.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals  FE_READ_SIGNAL_STRENGTH for this
-                                                     command.
-        int32_t *strength     O The signal strength value, as a multiple of 10^-6 dBm,
-				is stored into *strength.  
-				Example: a value of ­12,500,000 corresponds to a signal
-                                         strength value of ­12.5 dBm.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  strength points to invalid address
- 
-        ENOSIGNAL               There is no signal, thus no meaningful signal
-                                strength value.  Also returned if front-end is not
-                                turned on.
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = FE_READ_SNR, int32_t *snr);
-
-    DESCRIPTION
-
-	This ioctl call returns the signal-to-noise ratio for the signal currently 
-	received by the front-end. For this command, read-only access to the device
-	is sufficient.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request	      I Equals FE_READ_SNR for this command.
-
-        int32_t *snr	      O The signal-to-noise ratio, as a multiple of
-                                10^-6 dB, is stored into *snr.
-
-                                Example: a value of 12,300,000 corresponds
-                                         to a signal-to-noise ratio of 12.3 dB.
-
-    RETURNS
-    
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  snr points to invalid address
-
-        ENOSIGNAL               No stable signal, thus no meaningful signal-to-
-                                noise ratio.  Also returned if front-end is not
-                                turned on.
-
-        ENOSYS                  Function not available for this device.
-
-

- -

-

-int ioctl( int fd, int request = FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks);
-
-
-    DESCRIPTION
-
-	This ioctl call returns the number of uncorrected blocks detected by the device
-	driver during its lifetime.  For meaningful measurements, the increment in 
-	block count during a specific time interval should be calculated2.  For this 
-	command, read-only access to the device is sufficient.
-        
-	2 Note that the counter will wrap to zero after its maximum count has 
-	  been reached (232-1).
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request	      I Equals FE_READ_UNCORRECTED_BLOCKS for this command.
-
-        uint32_t *ublocks     O The total number of uncorrected blocks seen
-                                by the driver so far.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  ublocks points to invalid address
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = FE_GET_NEXT_FREQUENCY, uint32_t *freq);
-
-    DESCRIPTION
-
-	When scanning a frequency range, it is desirable to use a scanning step size 
-	that is as large as possible, yet small enough to be able to lock to any signal 
-	within the range.
-        This  ioctl operation does just that ­ it increments a given frequency by a 
-	step size suitable for efficient3 scanning.
-        The step size used by this function may be a quite complex function of the given
-        frequency, hardware capabilities, and parameter settings of the device.  Thus, a
-        returned result is only valid for the current state of the device.
-        For this command, read-only access to the device is sufficient.
-                                                        
-        3 Note that scanning may still be excruciatingly slow on some hardware, for 
-	  other reasons than a non-optimal scanning step size.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals  FE_GET_NEXT_FREQUENCY for this command.
-
-        uint32_t *freq      I/O Input: a given frequency
-                                Output:  the frequency corresponding to
-	                                 the next higher frequency setting.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  freq points to invalid address
-
-        EINVAL                  maximum frequency reached
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl( int fd, int request = FE_GET_NEXT_SYMBOL_RATE, uint32_t *symbolRate);
-
-    DESCRIPTION
-
-	When scanning a range of symbol rates (e.g. for "blind acquisition") it is 
-	desirable to use a scanning step size that is as large as possible, yet 
-	small enough to detect any valid signal within the range.  This ioctl 
-	operation does just that ­ it increments a given symbol rate by a step size
-	suitable for efficient4 scanning.
-        The step size used by this function may be a quite complex function of the given
-        symbol rate, hardware capabilities, and parameter settings of the device.  
-	Thus, a returned result is only valid for the current state of the device.
-        For this command, read-only access to the device is sufficient.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals  FE_GET_NEXT_SYMBOL_RATE for this command.
-
-        uint32_t *symbolRate  I/O Input:  a given symbol rate                                                             Output: the symbol rate corresponding to the next
-	                                  higher symbol rate setting.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  symbolRate points to invalid address
-
-        EINVAL                  maximum symbol rate reached
-
-        ENOSYS                  Function not available for this device.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_TUNE, struct qpskParameters *p);
-
-    DESCRIPTION
-
-	This ioctl call starts a tuning operation using specified parameters.  
-	The result of this call will be successful if the parameters were valid and 
-	the tuning could be initiated.
-        The result of the tuning operation in itself, however, will arrive 
-	asynchronously as an event (see documentation for QPSK_GET_EVENT and qpskEvent.)
-        If a new QPSK_TUNE operation is initiated before the previous one was completed,
-	the previous operation will be aborted in favor of the new one.
-        This command requires read/write access to the device.
-
-    PARAMETERS
-
-	int fd			 File descriptor returned by a previous call to open(). 
-
-	int request		 Equals QPSK_TUNE for this command.
-
-	struct qpskParameters *p Points to parameters for tuning operation.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-        EFAULT                  p points to invalid address
-        EINVAL                  parameter value(s) not valid
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_GET_EVENT, struct qpskEvent *ev);
-
-    DESCRIPTION
-    
-	This ioctl call returns an event of type qpskEvent if available. If an event
-	is not available, the behavior depends on whether the device is in blocking 
-	or non-blocking mode.  In the latter case, the call fails immediately with 
-	errno set to EWOULDBLOCK. In the former case, the call blocks until an event
-	becomes available.
-        The standard Linux poll() and/or select() system calls can be used with the 
-	device file descriptor to watch for new events.  For select(), the file 
-	descriptor should be included in the exceptfds argument, and for poll(), 
-	POLLPRI should be specified as the wake-up condition.
-        Since the event queue allocated is rather small (room for 8 events), the queue
-	must be serviced regularly to avoid overflow.   If an overflow happens, the 
-	oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs 
-	the next time the queue is read. After reporting the error condition in this 
-	fashion, subsequent QPSK_GET_EVENT calls will return events from the queue as
-	usual.
-        For the sake of implementation simplicity, this command requires read/write 
-	access to the device.
-
-    PARAMETERS
-              
-	int fd			File descriptor returned by a previous call to open().
-
-        int request           I Equals QPSK_GET_EVENT for this command.
-
-        struct qpskEvent *ev  O Points to the location where the event, if any, is to be stored.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  ev points to invalid address
-
-        EWOULDBLOCK             There is no event pending, and the device is in
-                                non-blocking mode.
-
-        EBUFFEROVERFLOW         Overflow in event queue - one or more events were lost.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_FE_INFO, struct qpskFrontendInfo *info);
-
-    DESCRIPTION
-
-	This ioctl call returns information about the front-end.
-	This call only requires read-only access to the device.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals QPSK_FE_INFO for this command.
-
-        struct qpskFrontendInfo *info   O Points to the location where the front-end
-                                          information is to be stored.
-
-    RETURNS
-    
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  info points to invalid address
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_WRITE_REGISTER, struct qpskRegister *reg);
-
-    DESCRIPTION
- 
-	This ioctl call is intended for hardware-specific diagnostics.  It writes 
-	an 8-bit value at an 8-bit address of a register in a chip identified by an 
-	8-bit index.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals  QPSK_WRITE_REGISTER for this command.
-
-        struct qpskRegister *reg    I Specifies a value that should be written
-                                      into a specified register in a specified chip.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  reg points to and invalid address
-
-        EINVAL                  Register specification invalid.
-
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = QPSK_READ_REGISTER, struct qpskRegister *reg);
-
-    DESCRIPTION
-
-	This ioctl call is intended for hardware-specific diagnostics.  
-	It reads an 8-bit value at an 8-bit address of a register in a chip 
-	identified by an 8-bit index.
-
-    PARAMETERS
-
-	int fd		    I File descriptor returned by a previous call to open().
-
-        int request         I Equals QPSK_READ_REGISTER for this command.
-
-        struct qpskRegister *reg   I/O I:  specifies a register in a specified
-                                           chip from which a value should be read.
-
-                                       O:  the value is read into the
-                                           qpskRegister structure.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor
-
-        EFAULT                  reg points to and invalid address
-
-        EINVAL                  Register specification invalid.
-
-
-
-
-

- -

- -
- - diff --git a/dvb-spec/API/dvb_api/sec.h b/dvb-spec/API/dvb_api/sec.h deleted file mode 100644 index f6eda5a0a..000000000 --- a/dvb-spec/API/dvb_api/sec.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * sec.h - * - * Copyright (C) 2000 Ralph Metzler - * & Marcus Metzler - for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _OST_SEC_H_ -#define _OST_SEC_H_ - -#define SEC_MAX_DISEQC_PARAMS 3 - -struct secDiseqcCmd { - uint8_t addr; - uint8_t cmd; - uint8_t numParams; - uint8_t params[SEC_MAX_DISEQC_PARAMS]; -}; - -typedef uint32_t secVoltage; - -enum { - SEC_VOLTAGE_OFF, - SEC_VOLTAGE_LT, - SEC_VOLTAGE_13, - SEC_VOLTAGE_13_5, - SEC_VOLTAGE_18, - SEC_VOLTAGE_18_5 -}; - - -typedef uint32_t secToneMode; - -typedef enum { - SEC_TONE_ON, - SEC_TONE_OFF -} secToneMode_t; - - -typedef uint32_t secMiniCmd; - -typedef enum { - SEC_MINI_NONE, - SEC_MINI_A, - SEC_MINI_B -} secMiniCmd_t; - -struct secStatus { - int32_t busMode; - secVoltage selVolt; - secToneMode contTone; -}; - -enum { - SEC_BUS_IDLE, - SEC_BUS_BUSY, - SEC_BUS_OFF, - SEC_BUS_OVERLOAD -}; - -struct secCommand { - int32_t type; - union { - struct secDiseqcCmd diseqc; - uint8_t vsec; - uint32_t pause; - } u; -}; - -struct secCmdSequence { - secVoltage voltage; - secMiniCmd miniCommand; - secToneMode continuousTone; - - uint32_t numCommands; - struct secCommand* commands; -}; - -enum { - SEC_CMDTYPE_DISEQC, - SEC_CMDTYPE_VSEC, - SEC_CMDTYPE_PAUSE -}; - - -#define SEC_GET_STATUS _IOR('o',91,struct secStatus *) -#define SEC_RESET_OVERLOAD _IOW('o',92,void) -#define SEC_SEND_SEQUENCE _IOW('o',93,struct secCmdSequence *) -#define SEC_SET_TONE _IOW('o',94,secToneMode) -#define SEC_SET_VOLTAGE _IOW('o',95,secVoltage) - -typedef enum { - SEC_DISEQC_SENT, - SEC_VSEC_SENT, - SEC_PAUSE_COMPLETE, - SEC_CALLBACK_ERROR -} secCallback_t; - - -#endif /*_OST_SEC_H_*/ diff --git a/dvb-spec/API/dvb_api/sec.xml b/dvb-spec/API/dvb_api/sec.xml deleted file mode 100644 index 22062d4a9..000000000 --- a/dvb-spec/API/dvb_api/sec.xml +++ /dev/null @@ -1,430 +0,0 @@ - - - linuxtv.org|DVB SEC API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB SEC API

- -

- The DVB SEC device controls the Satellite Equipment Control of - the DVB hardware, i.e. DiSEqC and V-SEC. - It is accessed through /dev/ost/sec. -

- -

- The function calls defined in the include file - sec.h aredescribed in detail below: -

- -

- SEC API IO control calls - - -

-

-
-int open(const char *deviceName, int flags);
-
-    DESCRIPTION
-
-	This system call opens a named SEC device for subsequent use.
-        If the device is opened in read-only mode, only status and statistics 
-	monitoring is allowed. If the device is opened in read/write mode, all
-	types of operations can be performed.
-	Any number of applications can have simultaneous access to the device.
-
-    PARAMETERS
-
-	const char *deviceName	I Name of the SEC device.
-
-        int flags		I Valid values are:
-                                  O_RDONLY             read-only access
-                                  O_RDWR               read/write access
-
-	The optional flag O_NONBLOCK is not supported. If O_NONBLOCK is set, 
-	open() and most other subsequent calls to the device will return ­1 and 
-	set errno to EWOULDBLOCK.
-	The communication with the peripheral devices is sequential by nature, 
-	so it is probably preferable to use the device in synchronous mode. 
-	This is the motivation for not going through the extra effort of 
-	implementing asynchronous operation of the device.
-
-    RETURNS
-
-	ENODEV			Device not loaded/available
-        EFAULT                  deviceName does not refer to a valid memory area.
-        EINVAL                  Invalid argument
-
-
-
-
-

- -

-

-
-int close(int fd);
-
-    DESCRIPTION
-
-	This system call closes a previously opened SEC device.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-    RETURNS
-    
-	EBADF			fd is not a valid file descriptor.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = SEC_GET_STATUS, struct secStatus* status);
-
-    DESCRIPTION
-
-	This call gets the status of the device.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals SEC_GET_STATUS for this command.
-
-        struct secStatus* status   O The status of the device.
-
-    RETURNS
-
-	ENODEV			Device driver not loaded/available
-
-        EFAULT                  status is an invalid pointer
-
-        EBUSY                   Device or resource busy
-
-        EINVAL                  Invalid argument
-
-        EPERM                   File not opened with read permissions
-
-        EINTERNAL               Internal error in the device driver
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = SEC_RESET_OVERLOAD);
-
-    DESCRIPTION
-
-	If the bus has been automatically powered off due to power overload, this
-	ioctl call restores the power to the bus. The call requires read/write 
-	access to the device.
-        This call has no effect if the device is manually powered off.
-
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals SEC_RESET_OVERLOAD for this command.
-
-    RETURNS
-
-	EBADF                   fd is not a valid file descriptor.
-
-        EPERM                   Permission denied (needs read/write access)
-
-        EINTERNAL               Internal error in the device driver
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = SEC_SEND_SEQUENCE, struct secCmdSequence *seq);
-
-    DESCRIPTION
-
-	This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC 
-	commands. The first version of the SEC device does not support V-SEC 
-	signalling and it aborts the operation with an error code if a V-SEC 
-	command is detected in the input data.
-
-        !  The call will fail with errno set to EBUSOVERLOAD if the bus is 
-	   overloaded. If the bus is overloaded, SEC_RESET_OVERLOAD can be 
-           called and the operation can be retried.
-
-        !  If seq.numCommands equals 0 and seq.miniCommand equals SEC_MINI_NONE,
-	   the bus voltage will be switched and the continuous 22kHz tone 
-	   generation enabled/disabled immediately.
- 
-        This operation is atomic. If several processes calls this ioctl 
-	simultaneously, the operations will be serialised so a complete sequence
-	is sent at a time.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals  SEC_SEND_SEQUENCE for this command.
-
-        struct secCmdSequence *seq    I Pointer to the command sequence to be transmitted.
-
-    RETURNS
-    
-	EBADF			Fd is not a valid file descriptor.
-        
-	EFAULT                  Seq points to an invalid address.
-        
-        EINVAL                  The data structure referred to by seq is invalid in
-                                some way.
-
-        EPERM                   Permission denied (needs read/write access)
-
-        EINTERNAL               Internal error in the device driver
-
-
-        EBUSMODE                The device is not prepared for transmission 
-				(e.g. it might be manually powered off).
-
-        EBUSOVERLOAD                  Bus overload has occurred.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = SEC_SET_TONE, secToneMode tone);
-
-    DESCRIPTION
-
-	This call is used to set the generation of the continuous 22kHz tone. 
-	The possibility to just change the tone mode is already provided by 
-	ioctl SEC_SEND_SEQUENCE, but SEC_SET_TONE is an easier to use interface.
-        To keep the transmission of a command sequence (see section 4.4.5 ) as 
-	an atomic operation, SEC_SET_TONE will block if a transmission is in 
-	progress. This call requires read/write permissions.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals SEC_SET_TONE for this command.
-
-        secToneMode tone      I The requested tone generation mode (on/off).
-
-    RETURNS
-
-	ENODEV			Device driver not loaded/available
-
-        EBUSY                   Device or resource busy
-
-        EINVAL                  Invalid argument
-
-        EPERM                   File not opened with read permissions
-
-        EINTERNAL               Internal error in the device driver
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = SEC_SET_VOLTAGE, secVoltage voltage);
-
-    DESCRIPTION
-    
-	This call is used to set the bus voltage. The possibility to just change
-	the bus voltage is already provided by ioctl SEC_SEND_SEQUENCE, but 
-	SEC_SET_VOLTAGE is an easier to use interface.
-        To keep the transmission of a command sequence (see section 4.4.5 ) as
-	an atomic operation, SEC_SET_VOLTAGE will block if a transmission is in 
-	progress.
-	This call requires read/write permissions.
-
-    PARAMETERS
-
-	int fd		      I File descriptor returned by a previous call to open().
-
-        int request           I Equals SEC_SET_VOLTAGE for this command.
-
-        secVoltage voltage    I The requested bus voltage.
-
-    RETURNS
-
-	ENODEV			Device driver not loaded/available
-        
-	EBUSY                   Device or resource busy
-        
-	EINVAL                  Invalid argument
-        
-	EPERM                   File not opened with read permissions
-
-	EINTERNAL               Internal error in the device driver
-
-
-
-
-

-

-
- - diff --git a/dvb-spec/API/dvb_api/video.h b/dvb-spec/API/dvb_api/video.h deleted file mode 100644 index de5ac2b19..000000000 --- a/dvb-spec/API/dvb_api/video.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * video.h - * - * Copyright (C) 2000 Marcus Metzler - * & Ralph Metzler - for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _OST_VIDEO_H_ -#define _OST_VIDEO_H_ - -#define boolean int -#define true 1 -#define false 0 - -typedef enum { - VIDEO_FORMAT_4_3, /* Select 4:3 format */ - VIDEO_FORMAT_16_9 /* Select 16:9 format. */ -} videoFormat_t; - - -typedef enum { - VIDEO_PAN_SCAN, - VIDEO_LETTER_BOX, - VIDEO_CENTER_CUT_OUT -} videoDisplayFormat_t; - - -typedef enum { - VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ - VIDEO_SOURCE_MEMORY /* If this source is selected, the stream - comes from the user through the write - system call */ -} videoStreamSource_t; - -typedef enum { - VIDEO_STOPPED, /* Video is stopped */ - VIDEO_PLAYING, /* Video is currently playing */ - VIDEO_FREEZED /* Video is freezed */ -} videoPlayState_t; - - -struct videoEvent { - int32_t type; - time_t timestamp; - - union { - videoFormat_t videoFormat; - } u; -}; - - -struct videoStatus { - boolean videoBlank; - videoPlayState_t playState; - videoStreamSource_t streamSource; - videoFormat_t videoFormat; - videoDisplayFormat_t displayFormat; -}; - - -struct videoDisplayStillPicture { - char *iFrame; - int32_t size; -}; - -#define VIDEO_STOP _IOW('o', 21, boolean) -#define VIDEO_PLAY _IOW('o', 22, void) -#define VIDEO_FREEZE _IOW('o', 23, void) -#define VIDEO_CONTINUE _IOW('o', 24, void) -#define VIDEO_SELECT_SOURCE _IOW('o', 25, videoStreamSource_t) -#define VIDEO_SET_BLANK _IOW('o', 26, boolean) -#define VIDEO_GET_STATUS _IOR('o', 27, struct videoStatus *) -#define VIDEO_GET_EVENT _IOR('o', 28, struct videoEvent *) -#define VIDEO_SET_DIPLAY_FORMAT _IOW('o', 29, videoDisplayFormat_t) -#define VIDEO_STILLPICTURE _IOW('o', 30, struct videoDisplayStillPicture *) -#define VIDEO_FAST_FORWRD _IOW('o', 31, int) -#define VIDEO_SLOWMOTION _IOW('o', 32, int) - -#endif /*_OST_VIDEO_H_*/ diff --git a/dvb-spec/API/dvb_api/video.xml b/dvb-spec/API/dvb_api/video.xml deleted file mode 100644 index 18ff9aa28..000000000 --- a/dvb-spec/API/dvb_api/video.xml +++ /dev/null @@ -1,666 +0,0 @@ - - - linuxtv.org|DVB Video API
  - -
 
-   -
-  convergence.de -
-  cryptolabs.org
-  directfb.org -
-  linuxtv.org -
-   -
-  linuxtv
-  projects
-  developer
  -  DVB
   - -  API
  -  DVD
  -  Mbone
  -  CVS
-  download
-  contact
-   -

DVB Video API

- -

- The DVB video device controls the MPEG2 video decoder of the DVB hardware. - It can be accessed through /dev/ost/audio. -

- -

- The include file video.h describes the data - types and lists all i/o calls. - A complete explanation of all calls can be found below: -

- - -

- Video API IO control calls - - -

-

-
-int open(const char *deviceName, int flags);
-
-    FUNCTION
-
-	This system call opens a named video device (e.g. /dev/ost/video) for subsequent
-        use.
-        When an open() call has succeeded, the device will be ready for use.
-        The significance of blocking or non-blocking mode is described in the documentation
-        for functions where there is a difference. It does not affect the semantics of the
-        open() call itself. A device opened in blocking mode can later be put into non-
-        blocking mode (and vice versa) using the F_SETFL command of the fcntl system
-        call.  This is a standard system call, documented in the Linux manual page for fcntl.
-        Only one user can open the Video Device in O_RDWR mode. All other attemts to
-        open the device in this mode will fail, and an errorcode will be returned.
-        If the Video Device is opened in O_RDONLY mode, the only ioctl call that can be used
-        is VIDEO_GET_STATUS. All other call will return an error code.
-
-
-    PARAMETERS
-
-	const char *deviceName	Name of specific video device.  In the current
-                      		implementation,  /dev/ost/video is the only
-                                one available.
-	int flags               A bit-wise OR of the following flags:
-
-                                O_RDONLY read-only access
-
-                                O_RDWR read/write access
-
-                                O_NONBLOCK open in non-blocking mode 
-				           (blocking mode is the default)
-    RETURNS
-    
-	ENODEV                  Device driver not loaded/available.
-
-        EINTERNAL               Internal error, possibly in the communication
-                                with the DVB subsystem.
-
-        EBUSY                   Device or resource busy.
-
-        EINVAL                  Invalid argument.
-
-
-
-

- -

-

-
-int close(int fd);
-
-    DESCRIPTION
-
-	This system call closes a previously opened video device
-
-    PARAMETERS
-
-        int fd			File descriptor returned by a previous call to open().
-
-    RETURNS
-    
-	EBADF                                   fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-size_t write(int fd, const void *buf, size_t count);
-
-    DESCRIPTION
-    
-	This system call is only provided if VIDEO_SOURCE_MEMORY is selected in the 
-	ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in PES format.
-        If O_NONBLOCK is not specified the function will block until buffer space 
-	is available. The amount of data to be transferred is implied by count.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-        void *buf		Pointer to the buffer containing the PES data.
-
-	size_t count		Size of buf.
-
-    RETURNS
-
-	EPERM                   Mode VIDEO_SOURCE_MEMORY not selected.
-        
-	ENOMEM			Attempted to write more data than the internal buffer can hold.
-
-	EBADF			fd is not a valid open file descriptor
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_STOP, boolean mode); 
-
-    FUNCTION
-	
-	This ioctl call asks the Video Device to stop playing the current stream.
-	Depending on the input parameter, the screen can be blanked out or
-	displaying the last decoded frame.
-
-    PARAMETERS
-
-	int fd 		File descriptor returned by a previous call to open(). 
-
-	int request 	Equals VIDEO_STOP for this command. 
-
-	Boolean mode 	Indicates how the screen shall be handled. 
-
-			TRUE: Blank screen when stop. 
-			FALSE: Show last decoded frame.
-
-    RETURNS
-
-	EBADF 		fd is not a valid open file descriptor 
-
-	EINTERNAL 	Internal error, possibly in the communication with 
-			the DVB subsystem.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_PLAY); 
-
-    FUNCTION 
-	
-	This ioctl call asks the Video Device to start playing a video stream 
-	from the selected source.
-
-    PARAMETERS
-
-	int fd 		File descriptor returned by a previous call to open(). 
-
-	int request 	Equals VIDEO_PLAY for this command.
-
-
-    RETURNS
-
-	EBADF 		fd is not a valid open file descriptor 
-
-	EINTERNAL 	Internal error, possibly in the communication with 
-			the DVB subsystem.
-
-
-
-
-

- - -

-

-int ioctl(int fd, int request = VIDEO_FREEZE); 
-
-    FUNCTION 
-
-	This ioctl call suspends the live video stream being played. 
-	Decoding and playing are frozen. It is then possible to restart 
-	the decoding and playing process of the video stream using 
-	VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the
-	ioctl call VIDEO_SELECT_SOURCE, the DVB-subsystem will not decode 
-	any more data until the ioctl call VIDEO_FREEZE or VIDEO_PLAY is 
-	performed.
-
-    PARAMETERS 
-	
-	int fd 		File descriptor returned by a previous call to open(). 
-
-	int request 	Equals VIDEO_FREEZE for this command. 
-
-    RETURNS 
-
-	EBADF 		fd is not a valid open file descriptor. 
-
-	EINTERNAL 	Internal error, possibly in the communication with
-			the DVB subsystem.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_CONTINUE); 
-
-    FUNCTION 
-
-	This ioctl call restarts decoding and playing processes of the video
-	stream which was played before a call to VIDEO_FREEZE was made.
-
-    PARAMETERS 
-
-	int fd 		File descriptor returned by a previous call to open(). 
-
-	int request 	Equals VIDEO_CONTINUE for this command.
-
-    RETURNS 
-
-	EBADF 		fd is not a valid open file descriptor. 
-
-	EINTERNAL 	Internal error, possibly in the communication with 
-			the DVB subsystem.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_SELECT_SOURCE, videoStreamSource_t source); 
-
-    FUNCTION
-	
-	This ioctl call informs the video device which source shall be used 
-	for the input data. The possible sources are demux or memory. If 
-	internal is selected, the data is feed to the Video Device through 
-	the write command.
-
-    PARAMETERS 
-
-	int fd 		File descriptor returned by a previous call to open(). 
-
-	int request 	Equals VIDEO_SELECT_SOURCE for this command. 
-
-	videoStreamSource_t source 
-			Indicates which source shall be used for the Video stream.
-
-    RETURNS 
-
-	EBADF 		fd is not a valid open file descriptor. 
-	
-	EINTERNAL 	Internal error, possibly in the communication with 
-			the DVB subsystem.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_SET_BLANK, boolean mode);
-
-    DESCRIPTION
-	
-	This ioctl call asks the Video Device to blank out the picture.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-        int request		Equals VIDEO_SET_BLANK for this command.
-
-	boolean mode		TRUE: Blank screen when stop.
-                 		FALSE:  Show last decoded frame.
-
-    RETURNS
-
-	EBADF		      	fd is not a valid open file descriptor.
-
-        EINTERNAL		Internal error
-	
-	EINVAL      		Illegal input parameter.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_GET_STATUS, struct videoStatus *status);
-
-    DESCRIPTION
-    
-	This ioctl call asks the Video Device to return the current status of the device.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals VIDEO_GET_STATUS for this command.
-
-	struct videoStatus      Returns the current status of the Video Device.
-               *status
-
-
-    RETURNS
-
-	EBADF    		fd is not a valid open file descriptor.
-
-	EINTERNAL  		Internal error
-
-	EFAULT                  status points to invalid address
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_GET_EVENT, struct videoEvent *ev);
-
-    DESCRIPTION
-
-	This ioctl call returns an event of type videoEvent if available.
-	If an event is not available, the behavior depends on whether the device is in
-	blocking or non-blocking mode.  In the latter case, the call fails immediately
-	with errno set to EWOULDBLOCK. In the former case, the call blocks until an 
-	event becomes available.
-        The standard Linux poll() and/or select() system calls can be used with the 
-	device file descriptor to watch for new events.  For select(), the file 
-	descriptor should be included in the exceptfds argument, and for poll(), 
-	POLLPRI should be specified as the wake-up condition.
-        Read-only permissions are sufficient for this ioctl call.
-
-    PARAMETERS
-          
-	int fd			File descriptor returned by a previous call to open().
-
-        int request		Equals VIDEO_GET_EVENT for this command.
-
-	struct videoEvent *ev 	Points to the location where the event, if any, is
-                                to be stored.
-
-
-    RETURNS
-    
-	EBADF    		fd is not a valid open file descriptor
-
-	EFAULT                  ev points to invalid address
-
-        EWOULDBLOCK             There is no event pending, and the device is in 
-				non-blocking mode.
-
-        EBUFFEROVERFLOW         Overflow in event queue - one or more events were lost.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_SET_DISPLAY_FORMAT, videoDisplayFormat_t format);
-
-    DESCRIPTION
-
-	This ioctl call asks the Video Device to select the video format to be applied
-	by the MPEG chip on the video.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals  VIDEO_SET_DISPLAY_FORMAT for this command.
-
-	videoDisplayFormat_t	Selects the video format to be used.
-        format
-        
-    RETURNS
-    
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-        EINVAL			Illegal parameter format.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_STILLPICTURE, struct videoDisplayStillPicture *sp);
-
-    DESCRIPTION
-
-	This ioctl call asks the Video Device to display a still picture (I-frame). 
-	The input data shall contain an I-frame. If the pointer is NULL, then the 
-	current displayed still picture is blanked.
-	
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals VIDEO_STILLPICTURE for this command.
-
-        struct videoDisplayStillPicture	*sp	Pointer to a location where an I-frame
-                                        	and size is stored.
-
-    RETURNS
-	
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-	EFAULT			sp points to an invalid iframe.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_FAST_FORWARD, int nFrames);
-
-    DESCRIPTION
-    
-	This ioctl call asks the Video Device to skip decoding of N number of I-frames.
-	This call can only be used if VIDEO_SOURCE_INTRENAL is selected.
-
-    PARAMETERS
-	
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals VIDEO_FAST_FORWARD for this command.
-
-	int nFrames		The number of frames to skip.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL               Internal error
-
-        EPERM			Mode VIDEO_SOURCE_MEMORY not selected.
-
-	EINVAL			Illegal parameter format.
-
-
-
-
-

- -

-

-
-int ioctl(int fd, int request = VIDEO_SLOWMOTION, int nFrames);
-
-    DESCRIPTION
-
-	This ioctl call asks the Video Device to repeat decoding frames N number of times.
-	This call can only be used if VIDEO_SOURCE_MEMORY is selected.
-
-    PARAMETERS
-
-	int fd			File descriptor returned by a previous call to open().
-
-	int request		Equals VIDEO_SLOWMOTION for this command.
-
-	int nFrames		The number of frames to skip.
-
-    RETURNS
-
-	EBADF			fd is not a valid open file descriptor.
-
-	EINTERNAL		Internal error
-
-        EPERM                   Mode VIDEO_SOURCE_MEMORY not selected.
-
-        EINVAL                  Illegal parameter format.
-
-
-
-
-

- -

- -
- - diff --git a/dvb-spec/API/linux_dvb_api.xml b/dvb-spec/API/linux_dvb_api.xml deleted file mode 100644 index b1040ffe5..000000000 --- a/dvb-spec/API/linux_dvb_api.xml +++ /dev/null @@ -1,3592 +0,0 @@ - - - -
- -Linux DVB API - -Documentation - - - - - - Dr. - Ralph - Metzler - rjkm@convergence.de - - - - Andreas - Bogk - bogk@convergence.de - - -feb. 7, 2000 -2000convergence -integrated media GmbH - -
Rosenthalerstr. 51, 10178 Berlin
- - linux - dvb - api - documentation - - - -About the Linux DVB API - - - -The Linux DVB API is based on a proposal by Nokia. As a commitment to the -development of terminals based on open standards, Nokia and convergence published -it on linuxtv.org. - - - - Convergence is -the maintainer of the Linux DVB API. Together with the LinuxTV community -(i.e. you, the reader of this document), the Linux DVB API will be constantly -reviewed and improved. With the Linux driver for the Siemens/ Hauppauge DVB PCI -card convergence provides a first implementation of the Linux DVB API. - - - - -
- - - - - Introduction - - - - Part of the DVB API builds upon the Video4Linux - (V4L) API. The Siemens DVB card uses the SAA7146 as PCI bridge. A - generic SAA7146 Linux - driver for this chip implements the basic V4L - interface. - - - An older version of the API included the DVB specific calls into - the V4L interface. This turned out to be very cumbersome to - program. Since we also hoped to arrive at a common standard for all - Linux platforms, especially those in embedded consumer devices, we were - happy to find Nokia - as a partner in this effort. They will be using the same API in their - upcoming - - Media Terminal. - - - In the new version of the API only display and grabbing of the - already decompressed images is handled through the V4L device. All - other DVB features like tuning, filtering and playback/recording of the - compressed data stream are accessed through separate devices. - - - A first implementations of the Linux DVB API for the Siemens/ - Hauppauge DVB PCI card is available in the LinuxTV Public - CVS. - - - - - - DVB Devices - - - There are currently 6 DVB devices: Video, Audio, Frontend, SEC, - Demux and CA. The APIs of those devices are described in the - sections below. - - - - DVB Video API - - - The DVB video device controls the MPEG2 video decoder of the DVB hardware. - It can be accessed through /dev/ost/audio. - - - The include file video.h describes the data - types and lists all i/o calls. A complete explanation of all calls can - be found below: - - - - Video API IO control calls - - -
- -int open(const char *deviceName, int flags); - - FUNCTION - - This system call opens a named video device (e.g. /dev/ost/video) for subsequent - use. - When an open() call has succeeded, the device will be ready for use. - The significance of blocking or non-blocking mode is described in the documentation - for functions where there is a difference. It does not affect the semantics of the - open() call itself. A device opened in blocking mode can later be put into non- - blocking mode (and vice versa) using the F_SETFL command of the fcntl system - call. This is a standard system call, documented in the Linux manual page for fcntl. - Only one user can open the Video Device in O_RDWR mode. All other attemts to - open the device in this mode will fail, and an errorcode will be returned. - If the Video Device is opened in O_RDONLY mode, the only ioctl call that can be used - is VIDEO_GET_STATUS. All other call will return an error code. - - - PARAMETERS - - const char *deviceName Name of specific video device. In the current - implementation, /dev/ost/video is the only - one available. - int flags A bit-wise OR of the following flags: - - O_RDONLY read-only access - - O_RDWR read/write access - - O_NONBLOCK open in non-blocking mode - (blocking mode is the default) - RETURNS - - ENODEV Device driver not loaded/available. - - EINTERNAL Internal error, possibly in the communication - with the DVB subsystem. - - EBUSY Device or resource busy. - - EINVAL Invalid argument. - - -
-
- - -
- -int close(int fd); - - DESCRIPTION - - This system call closes a previously opened video device - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - RETURNS - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
-size_t write(int fd, const void *buf, size_t count); - - DESCRIPTION - - This system call is only provided if VIDEO_SOURCE_MEMORY is selected in the - ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in PES format. - If O_NONBLOCK is not specified the function will block until buffer space - is available. The amount of data to be transferred is implied by count. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - void *buf Pointer to the buffer containing the PES data. - - size_t count Size of buf. - - RETURNS - - EPERM Mode VIDEO_SOURCE_MEMORY not selected. - - ENOMEM Attempted to write more data than the internal buffer can hold. - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_STOP, boolean mode); - - FUNCTION - - This ioctl call asks the Video Device to stop playing the current stream. - Depending on the input parameter, the screen can be blanked out or - displaying the last decoded frame. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_STOP for this command. - - Boolean mode Indicates how the screen shall be handled. - - TRUE: Blank screen when stop. - FALSE: Show last decoded frame. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EINTERNAL Internal error, possibly in the communication with - the DVB subsystem. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_PLAY); - - FUNCTION - - This ioctl call asks the Video Device to start playing a video stream - from the selected source. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_PLAY for this command. - - - RETURNS - - EBADF fd is not a valid open file descriptor - - EINTERNAL Internal error, possibly in the communication with - the DVB subsystem. - - - -
-
- - - -
-int ioctl(int fd, int request = VIDEO_FREEZE); - - FUNCTION - - This ioctl call suspends the live video stream being played. - Decoding and playing are frozen. It is then possible to restart - the decoding and playing process of the video stream using - VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the - ioctl call VIDEO_SELECT_SOURCE, the DVB-subsystem will not decode - any more data until the ioctl call VIDEO_FREEZE or VIDEO_PLAY is - performed. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_FREEZE for this command. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error, possibly in the communication with - the DVB subsystem. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_CONTINUE); - - FUNCTION - - This ioctl call restarts decoding and playing processes of the video - stream which was played before a call to VIDEO_FREEZE was made. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_CONTINUE for this command. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error, possibly in the communication with - the DVB subsystem. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_SELECT_SOURCE, videoStreamSource_t source); - - FUNCTION - - This ioctl call informs the video device which source shall be used - for the input data. The possible sources are demux or memory. If - internal is selected, the data is feed to the Video Device through - the write command. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_SELECT_SOURCE for this command. - - videoStreamSource_t source - Indicates which source shall be used for the Video stream. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error, possibly in the communication with - the DVB subsystem. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_SET_BLANK, boolean mode); - - DESCRIPTION - - This ioctl call asks the Video Device to blank out the picture. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_SET_BLANK for this command. - - boolean mode TRUE: Blank screen when stop. - FALSE: Show last decoded frame. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EINVAL Illegal input parameter. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_GET_STATUS, struct videoStatus *status); - - DESCRIPTION - - This ioctl call asks the Video Device to return the current status of the device. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_GET_STATUS for this command. - - struct videoStatus Returns the current status of the Video Device. - *status - - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EFAULT status points to invalid address - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_GET_EVENT, struct videoEvent *ev); - - DESCRIPTION - - This ioctl call returns an event of type videoEvent if available. - If an event is not available, the behavior depends on whether the device is in - blocking or non-blocking mode. In the latter case, the call fails immediately - with errno set to EWOULDBLOCK. In the former case, the call blocks until an - event becomes available. - The standard Linux poll() and/or select() system calls can be used with the - device file descriptor to watch for new events. For select(), the file - descriptor should be included in the exceptfds argument, and for poll(), - POLLPRI should be specified as the wake-up condition. - Read-only permissions are sufficient for this ioctl call. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_GET_EVENT for this command. - - struct videoEvent *ev Points to the location where the event, if any, is - to be stored. - - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT ev points to invalid address - - EWOULDBLOCK There is no event pending, and the device is in - non-blocking mode. - - EBUFFEROVERFLOW Overflow in event queue - one or more events were lost. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_SET_DISPLAY_FORMAT, videoDisplayFormat_t format); - - DESCRIPTION - - This ioctl call asks the Video Device to select the video format to be applied - by the MPEG chip on the video. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_SET_DISPLAY_FORMAT for this command. - - videoDisplayFormat_t Selects the video format to be used. - format - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EINVAL Illegal parameter format. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_STILLPICTURE, struct videoDisplayStillPicture *sp); - - DESCRIPTION - - This ioctl call asks the Video Device to display a still picture (I-frame). - The input data shall contain an I-frame. If the pointer is NULL, then the - current displayed still picture is blanked. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_STILLPICTURE for this command. - - struct videoDisplayStillPicture *sp Pointer to a location where an I-frame - and size is stored. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EFAULT sp points to an invalid iframe. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_FAST_FORWARD, int nFrames); - - DESCRIPTION - - This ioctl call asks the Video Device to skip decoding of N number of I-frames. - This call can only be used if VIDEO_SOURCE_INTRENAL is selected. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_FAST_FORWARD for this command. - - int nFrames The number of frames to skip. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EPERM Mode VIDEO_SOURCE_MEMORY not selected. - - EINVAL Illegal parameter format. - - - -
-
- - -
- -int ioctl(int fd, int request = VIDEO_SLOWMOTION, int nFrames); - - DESCRIPTION - - This ioctl call asks the Video Device to repeat decoding frames N number of times. - This call can only be used if VIDEO_SOURCE_MEMORY is selected. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals VIDEO_SLOWMOTION for this command. - - int nFrames The number of frames to skip. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EPERM Mode VIDEO_SOURCE_MEMORY not selected. - - EINVAL Illegal parameter format. - -
-
- -
- -
- - - DVB Audio API - - The DVB audio device controls the MPEG2 audio decoder of the - DVB hardware. It can be accessed through /dev/ost/audio. - - - The function calls defined in the include file audio.h are described in - detail below: - - - - Audio API IO control calls - - -
- -int open(const char *deviceName, int flags); - - DESCRIPTION - - This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent - use. When an open() call has succeeded, the device will be ready for use. - The significance of blocking or non-blocking mode is described in the - documentation for functions where there is a difference. It does not affect - the semantics of the open() call itself. A device opened in blocking mode can - later be put into non-blocking mode (and vice versa) using the F_SETFL command - of the fcntl system call. This is a standard system call, documented in the - Linux manual page for fcntl. - Only one user can open the Audio Device in O_RDWR mode. All other attempts to - open the device in this mode will fail, and an errorcode will be returned. - If the Audio Device is opened in O_RDONLY mode, the only ioctl call that can - be used is AUDIO_GET_STATUS. All other call will return with an error code. - - - PARAMETERS - - const char *deviceName Name of specific audio device. - - int flags A bit-wise OR of the following flags: - - O_RDONLY read-only access - - O_RDWR read/write access - - O_NONBLOCK open in non-blocking mode - (blocking mode is the default) - - RETURNS - - ENODEV Device driver not loaded/available. - - EINTERNAL Internal error - - EBUSY Device or resource busy. - - EINVAL Invalid argument. - - - -
-
- - -
- -int close(int fd); - - DESCRIPTION - - This system call closes a previously opened audio device - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - RETURNS - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -size_t write(int fd, const void *buf, size_t count); - - DESCRIPTION - - This system call can only be used if AUDIO_SOURCE_MEMORY is selected in the - ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in PES format. - If O_NONBLOCK is not specified the function will block until buffer space is - available. The amount of data to be transferred is implied by count. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - void *buf Pointer to the buffer containing the PES data. - - size_t count Size of buf. - - RETURNS - - EPERM Mode VIDEO_SOURCE_INTERNAL not selected. - - ENOMEM Attempted to write more data than the internal - buffer can hold. - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_STOP); - - DESCRIPTION - - This ioctl call asks the Audio Device to stop playing the current stream. - - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_STOP for this command. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EINTERNAL Internal error - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_PLAY); - - DESCRIPTION - - This ioctl call asks the Audio Device to start playing an audio stream from the - selected source. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_PLAY for this command. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_PAUSE); - - DESCRIPTION - - This ioctl call suspends the audio stream being played. Decoding and playing are - paused. It is then possible to restart again decoding and playing process of the - audio stream using AUDIO_CONTINUE command. - If AUDIO_SOURCE_MEMORY is selected in the ioctl call AUDIO_SELECT_SOURCE, the - DVB-subsystem will not decode (consume) any more data until the ioctl call - AUDIO_CONTINUE or AUDIO_PLAY is performed. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_PAUSE for this command. - - RETURNS - - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_CONTINUE); - - DESCRIPTION - - This ioctl call restarts decoding and playing processes of the audio stream, - which was played before, a call to AUDIO_PAUSE was made. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_CONTINUE for this command. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error, possibly in the communication - with the DVB subsystem. - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_SELECT_SOURCE, audioStreamSource_t source); - - DESCRIPTION - - This ioctl call informs the audio device which source shall be used for the - input data. The possible sources are demux or memory. If AUDIO_SOURCE_MEMORY - is selected, the data is fed to the Audio Device through the write command. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_SELECT_SOURCE for this command. - - audioStreamSource_t source Indicates the source that shall be used for the - Audio stream. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_SET_MUTE, boolean state); - - DESCRIPTION - - This ioctl call asks the audio device to mute the stream that is currently being - played. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_SET_MUTE for this command. - - boolean state Indicates if audio device shall mute or not. - TRUE Audio Mute - FALSE Audio Unmute - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error, - - EINVAL Illegal input parameter. - -
-
- - -
-int ioctl(int fd, int request = AUDIO_SET_AV_SYNC, boolean state); - - DESCRIPTION - - This ioctl call asks the Audio Device to turn ON or OFF A/V synchronisation. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_AV_SYNC for this command. - - boolean state Tells the DVB subsystem if A/V synchronisation shall be ON or OFF. - TRUE AV-sync ON - FALSE AV-sync OFF - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EINVAL Illegal input parameter. - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_SET_BYPASS_MODE, boolean mode); - - DESCRIPTION - - This ioctl call asks the Audio Device to bypass the Audio decoder and forward - the stream without decoding. This mode shall be used if streams that can't be - handled by the DVB system shall be decoded. Dolby DigitalTM streams are - automatically forwarded by the DVB subsystem. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_SET_BYPASS_MODE for this command. - - boolean mode Enables or disables the decoding of the current - Audio stream in the DVB subsystem. - TRUE Bypass is disabled - FALSE Bypass is enabled - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EINVAL Illegal pointer mode. - - -
-
- - -
-int ioctl(int fd, int request = AUDIO_CHANNEL_SELECT, audioChannelSelect_t) - - DESCRIPTION - - This ioctl call asks the Audio Device to select the requested channel if possible. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_CHANNEL_SELECT for this command. - - audioChannelSelect_t ch Select the output format of the audio (Mono, stereo) - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EINVAL Illegal pointer ch. - - - -
-
- - -
- -int ioctl(int fd, int request = AUDIO_GET_STATUS, struct audioStatus *status) - - DESCRIPTION - - This ioctl call asks the Audio Device to return the current state of the Audio - Device. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals AUDIO_GET_STATUS for this command. - - struct audioStatus *status Returns the current state of Audio Device - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EINTERNAL Internal error - - EFAULT status points to invalid address - - - -
-
- -
- -
- - - DVB Frontend API - - - The DVB frontend device controls the frontend of the DVB hardware, e.g. - tuning, symbol rate, error correction, ... - It is accessed through /dev/ost/qpskfe. - - - The function calls defined in the include file frontend.h are described - in detail below: - - - - Frontend API IO control calls - - -
- -int open(const char *deviceName, int flags); - - DESCRIPTION - - This system call opens a named front-end device (e.g. /dev/qpskfe) for - subsequent use. The device can be opened in read-only mode, which only allows - monitoring of device status and statistics, or read/write mode, which allows - any kind of use (e.g. performing tuning operations.) - - In a system with multiple front-ends, it is usually the case that multiple - devices cannot be open in read/write mode simultaneously. As long as a - front-end device is opened in read/write mode, other open() calls in - read/write mode will either fail or block, depending on whether - non-blocking or blocking mode was specified. - A front-end device opened in blocking mode can later be put into non-blocking - mode (and vice versa) using the F_SETFL command of the fcntl system call. - This is a standard system call, documented in the Linux manual page for fcntl. - When an open() call has succeeded, the device will be ready for use in the - specified mode. This implies that the corresponding hardware is powered up, - and that other front-ends may have been powered down to make that possible. - - PARAMETERS - - const char *deviceName I Name of specific front-end device. In the - current implementation, /dev/qpskfe is the - only one available (QPSK satellite front-end.) - - int flags I A bit-wise OR of the following flags: - O_RDONLY read-only access - O_RDWR read/write access - O_NONBLOCK open in non-blocking mode - (blocking mode is the default) - RETURNS - - ENODEV Device driver not loaded/available. - - EBUSY Device or resource busy. - - EINVAL Invalid argument. - - - -
-
- - -
- -int close(int fd); - - DESCRIPTION - - This system call closes a previously opened front-end device. After closing a - front-end device, its corresponding hardware might be powered down - automatically, but only when this is needed to open another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST_SET_POWER_STATE ioctl. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - RETURNS - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -int ioctl(int fd, int request = OST_SELFTEST); - - DESCRIPTION - - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals OST_SELFTEST for this command. - - RETURNS - - 0 Success - - -1 Failure - - - -
-
- - -
- -int ioctl(int fd, int request = OST_SET_POWER_STATE, uint32_t state); - - DESCRIPTION - - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time. - - A device that implements this call does not necessarily support two low-power - modes. If it only support one low-power state, or none at all, the - OST_SET_POWER_STATE operation for the missing states will still succeed, but - it will be mapped to an existing state as per this table: - - number of low-power requested state resulting state - states supported - - 1 standby suspend - - 1 suspend suspend - - 0 standby on - - 0 suspend on - - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again. - - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals OST_SET_POWER_STATE for this command. - - uint32_t state I Requested power state. One of: - - OST_POWER_ON: turn power on - OST_POWER_STANDBY: set device in standby mode - OST_POWER_SUSPEND: set device in suspend mode - OST_POWER_OFF: turn power off - - - RETURNS - - EBADF fd is not a valid open file descriptor - - EINVAL illegal state, or not available on this device - - EPERM permission denied (needs read/write access) - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl(int fd, int request = OST_GET_POWER_STATE, uint32_t *state); - - DESCRIPTION - - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals OST_GET_POWER_STATE for this command. - - uint32_t *state O Pointer to a variable where the power state is - to be stored. Possible values are: - OST_POWER_ON power is on - OST_POWER_STANDBY device in - standby mode - OST_POWER_SUSPEND: device in - suspend mode - OST_POWER_OFF: power is off - - - RETURNS - - EBADF fd is not a valid open file descriptor - - EINVAL illegal state, or not available on this device - - EFAULT state points to invalid address - - EPERM permission denied (needs read/write access) - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_READ_STATUS, feStatus *status); - - DESCRIPTION - - This ioctl call returns status information about the front-end. - This call only requires read-only access to the device. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_READ_STATUS for this command. - - struct feStatus *status O Points to the location where the front-end - status word is to be stored. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT status points to invalid address - - - -
-
- - -
- -int ioctl(int fd, int request = FE_READ_BER, uint32_t *ber); - - DESCRIPTION - - This ioctl call returns the bit error rate for the signal currently - received/demodulated by the front-end. For this command, read-only access - to the device is sufficient. - - FUNCTION PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_READ_BER for this command. - - uint32_t *ber O The bit error rate, as a multiple of 10-9, is stored into *ber. - - Example: a value of 2500 corresponds to a bit error - rate of 2.5 10-6, or 1 error in 400000 bits. - - RETURNS - - EBADF fd is not a valid open file descriptor. - - EFAULT ber points to invalid address - - ENOSIGNAL There is no signal, thus no meaningful bit error - rate. Also returned if the front-end is not turned on. - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl( int fd, int request = FE_READ_SIGNAL_STRENGTH, int32_t *strength); - - DESCRIPTION - - This ioctl call returns the signal strength value for the signal currently - received by the front-end. For this command, read-only access to the device - is sufficient. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_READ_SIGNAL_STRENGTH for this - command. - int32_t *strength O The signal strength value, as a multiple of 10^-6 dBm, - is stored into *strength. - Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT strength points to invalid address - - ENOSIGNAL There is no signal, thus no meaningful signal - strength value. Also returned if front-end is not - turned on. - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl(int fd, int request = FE_READ_SNR, int32_t *snr); - - DESCRIPTION - - This ioctl call returns the signal-to-noise ratio for the signal currently - received by the front-end. For this command, read-only access to the device - is sufficient. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_READ_SNR for this command. - - int32_t *snr O The signal-to-noise ratio, as a multiple of - 10^-6 dB, is stored into *snr. - - Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT snr points to invalid address - - ENOSIGNAL No stable signal, thus no meaningful signal-to- - noise ratio. Also returned if front-end is not - turned on. - - ENOSYS Function not available for this device. -
-
- - -
-int ioctl( int fd, int request = FE_READ_UNCORRECTED_BLOCKS, uint32_t *ublocks); - - - DESCRIPTION - - This ioctl call returns the number of uncorrected blocks detected by the device - driver during its lifetime. For meaningful measurements, the increment in - block count during a specific time interval should be calculated2. For this - command, read-only access to the device is sufficient. - - 2 Note that the counter will wrap to zero after its maximum count has - been reached (232-1). - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_READ_UNCORRECTED_BLOCKS for this command. - - uint32_t *ublocks O The total number of uncorrected blocks seen - by the driver so far. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT ublocks points to invalid address - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl( int fd, int request = FE_GET_NEXT_FREQUENCY, uint32_t *freq); - - DESCRIPTION - - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient3 scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - - 3 Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_GET_NEXT_FREQUENCY for this command. - - uint32_t *freq I/O Input: a given frequency - Output: the frequency corresponding to - the next higher frequency setting. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT freq points to invalid address - - EINVAL maximum frequency reached - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl( int fd, int request = FE_GET_NEXT_SYMBOL_RATE, uint32_t *symbolRate); - - DESCRIPTION - - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient4 scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals FE_GET_NEXT_SYMBOL_RATE for this command. - - uint32_t *symbolRate I/O Input: a given symbol rate - Output: the symbol rate corresponding to the next higher symbol rate setting. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT symbolRate points to invalid address - - EINVAL maximum symbol rate reached - - ENOSYS Function not available for this device. - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_TUNE, struct qpskParameters *p); - - DESCRIPTION - - This ioctl call starts a tuning operation using specified parameters. - The result of this call will be successful if the parameters were valid and - the tuning could be initiated. - The result of the tuning operation in itself, however, will arrive - asynchronously as an event (see documentation for QPSK_GET_EVENT and qpskEvent.) - If a new QPSK_TUNE operation is initiated before the previous one was completed, - the previous operation will be aborted in favor of the new one. - This command requires read/write access to the device. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request Equals QPSK_TUNE for this command. - - struct qpskParameters *p Points to parameters for tuning operation. - - RETURNS - - EBADF fd is not a valid open file descriptor - EFAULT p points to invalid address - EINVAL parameter value(s) not valid - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_GET_EVENT, struct qpskEvent *ev); - - DESCRIPTION - - This ioctl call returns an event of type qpskEvent if available. If an event - is not available, the behavior depends on whether the device is in blocking - or non-blocking mode. In the latter case, the call fails immediately with - errno set to EWOULDBLOCK. In the former case, the call blocks until an event - becomes available. - The standard Linux poll() and/or select() system calls can be used with the - device file descriptor to watch for new events. For select(), the file - descriptor should be included in the exceptfds argument, and for poll(), - POLLPRI should be specified as the wake-up condition. - Since the event queue allocated is rather small (room for 8 events), the queue - must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs - the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK_GET_EVENT calls will return events from the queue as - usual. - For the sake of implementation simplicity, this command requires read/write - access to the device. - - PARAMETERS - - int fd File descriptor returned by a previous call to open(). - - int request I Equals QPSK_GET_EVENT for this command. - - struct qpskEvent *ev O Points to the location where the event, if any, is to be stored. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT ev points to invalid address - - EWOULDBLOCK There is no event pending, and the device is in - non-blocking mode. - - EBUFFEROVERFLOW Overflow in event queue - one or more events were lost. - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_FE_INFO, struct qpskFrontendInfo *info); - - DESCRIPTION - - This ioctl call returns information about the front-end. - This call only requires read-only access to the device. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals QPSK_FE_INFO for this command. - - struct qpskFrontendInfo *info O Points to the location where the front-end - information is to be stored. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT info points to invalid address - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_WRITE_REGISTER, struct qpskRegister *reg); - - DESCRIPTION - - This ioctl call is intended for hardware-specific diagnostics. It writes - an 8-bit value at an 8-bit address of a register in a chip identified by an - 8-bit index. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals QPSK_WRITE_REGISTER for this command. - - struct qpskRegister *reg I Specifies a value that should be written - into a specified register in a specified chip. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT reg points to and invalid address - - EINVAL Register specification invalid. - - - - -
-
- - -
- -int ioctl(int fd, int request = QPSK_READ_REGISTER, struct qpskRegister *reg); - - DESCRIPTION - - This ioctl call is intended for hardware-specific diagnostics. - It reads an 8-bit value at an 8-bit address of a register in a chip - identified by an 8-bit index. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals QPSK_READ_REGISTER for this command. - - struct qpskRegister *reg I/O I: specifies a register in a specified - chip from which a value should be read. - - O: the value is read into the - qpskRegister structure. - - RETURNS - - EBADF fd is not a valid open file descriptor - - EFAULT reg points to and invalid address - - EINVAL Register specification invalid. - - - -
-
- -
- -
- - - DVB SEC API - - - The DVB SEC device controls the Satellite Equipment Control of - the DVB hardware, i.e. DiSEqC and V-SEC. - It is accessed through /dev/ost/sec. - - - The function calls defined in the include file sec.h aredescribed in detail - below: - - - - SEC API IO control calls - - -
- -int open(const char *deviceName, int flags); - - DESCRIPTION - - This system call opens a named SEC device for subsequent use. - If the device is opened in read-only mode, only status and statistics - monitoring is allowed. If the device is opened in read/write mode, all - types of operations can be performed. - Any number of applications can have simultaneous access to the device. - - PARAMETERS - - const char *deviceName I Name of the SEC device. - - int flags I Valid values are: - O_RDONLY read-only access - O_RDWR read/write access - - The optional flag O_NONBLOCK is not supported. If O_NONBLOCK is set, - open() and most other subsequent calls to the device will return -1 and - set errno to EWOULDBLOCK. - The communication with the peripheral devices is sequential by nature, - so it is probably preferable to use the device in synchronous mode. - This is the motivation for not going through the extra effort of - implementing asynchronous operation of the device. - - RETURNS - - ENODEV Device not loaded/available - EFAULT deviceName does not refer to a valid memory area. - EINVAL Invalid argument - - - -
-
- - -
- -int close(int fd); - - DESCRIPTION - - This system call closes a previously opened SEC device. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - RETURNS - - EBADF fd is not a valid file descriptor. - - - -
-
- - -
- -int ioctl(int fd, int request = SEC_GET_STATUS, struct secStatus* status); - - DESCRIPTION - - This call gets the status of the device. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals SEC_GET_STATUS for this command. - - struct secStatus* status O The status of the device. - - RETURNS - - ENODEV Device driver not loaded/available - - EFAULT status is an invalid pointer - - EBUSY Device or resource busy - - EINVAL Invalid argument - - EPERM File not opened with read permissions - - EINTERNAL Internal error in the device driver - - - -
-
- - -
- -int ioctl(int fd, int request = SEC_RESET_OVERLOAD); - - DESCRIPTION - - If the bus has been automatically powered off due to power overload, this - ioctl call restores the power to the bus. The call requires read/write - access to the device. - This call has no effect if the device is manually powered off. - - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals SEC_RESET_OVERLOAD for this command. - - RETURNS - - EBADF fd is not a valid file descriptor. - - EPERM Permission denied (needs read/write access) - - EINTERNAL Internal error in the device driver - - - -
-
- - -
- -int ioctl(int fd, int request = SEC_SEND_SEQUENCE, struct secCmdSequence *seq); - - DESCRIPTION - - This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC - commands. The first version of the SEC device does not support V-SEC - signalling and it aborts the operation with an error code if a V-SEC - command is detected in the input data. - - ! The call will fail with errno set to EBUSOVERLOAD if the bus is - overloaded. If the bus is overloaded, SEC_RESET_OVERLOAD can be - called and the operation can be retried. - - ! If seq.numCommands equals 0 and seq.miniCommand equals SEC_MINI_NONE, - the bus voltage will be switched and the continuous 22kHz tone - generation enabled/disabled immediately. - - This operation is atomic. If several processes calls this ioctl - simultaneously, the operations will be serialised so a complete sequence - is sent at a time. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals SEC_SEND_SEQUENCE for this command. - - struct secCmdSequence *seq I Pointer to the command sequence to be transmitted. - - RETURNS - - EBADF Fd is not a valid file descriptor. - - EFAULT Seq points to an invalid address. - - EINVAL The data structure referred to by seq is invalid in - some way. - - EPERM Permission denied (needs read/write access) - - EINTERNAL Internal error in the device driver - - - EBUSMODE The device is not prepared for transmission - (e.g. it might be manually powered off). - - EBUSOVERLOAD Bus overload has occurred. - - - -
-
- - -
- -int ioctl(int fd, int request = SEC_SET_TONE, secToneMode tone); - - DESCRIPTION - - This call is used to set the generation of the continuous 22kHz tone. - The possibility to just change the tone mode is already provided by - ioctl SEC_SEND_SEQUENCE, but SEC_SET_TONE is an easier to use interface. - To keep the transmission of a command sequence (see section 4.4.5 ) as - an atomic operation, SEC_SET_TONE will block if a transmission is in - progress. This call requires read/write permissions. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals SEC_SET_TONE for this command. - - secToneMode tone I The requested tone generation mode (on/off). - - RETURNS - - ENODEV Device driver not loaded/available - - EBUSY Device or resource busy - - EINVAL Invalid argument - - EPERM File not opened with read permissions - - EINTERNAL Internal error in the device driver - - - -
-
- - -
- -int ioctl(int fd, int request = SEC_SET_VOLTAGE, secVoltage voltage); - - DESCRIPTION - - This call is used to set the bus voltage. The possibility to just change - the bus voltage is already provided by ioctl SEC_SEND_SEQUENCE, but - SEC_SET_VOLTAGE is an easier to use interface. - To keep the transmission of a command sequence (see section 4.4.5 ) as - an atomic operation, SEC_SET_VOLTAGE will block if a transmission is in - progress. - This call requires read/write permissions. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals SEC_SET_VOLTAGE for this command. - - secVoltage voltage I The requested bus voltage. - - RETURNS - - ENODEV Device driver not loaded/available - - EBUSY Device or resource busy - - EINVAL Invalid argument - - EPERM File not opened with read permissions - - EINTERNAL Internal error in the device driver - - - -
-
- -
- -
- - - DVB Demux API - - - The DVB demux device lets you set TS, PID and section filters in the DVB - device. This is internally accomplished through calls to the - demux kernel module. - The demux device can be accessed through /dev/ost/demux. - - - The function calls defined in the include file dmx.h are described in detail - below: - - - - Demux API IO control calls - - -
- -int open(const char *deviceName, int flags); - - DESCRIPTION - - This system call, used with a device name of /dev/ost/demuxn, where n - denotes the specific demux device to be opened, allocates a new filter - and returns a handle which can be used for subsequent control of that - filter. This call has to be made for each filter to be used, i.e. every - returned file descriptor is a reference to a single filter. - /dev/ost/dvrn is a logical device to be used for retrieving Transport - Streams for digital video recording. n identifies the physical demux - device that provides the actual DVR functionlaity. When reading from - this device a transport stream containing the packets from all PES - filters set in the corresponfing demux device (/dev/osst/demuxn) - having the output set to DMX_OUT_TS_TAP. A recorded Transport Stream - is replayed by writing to this device. - This device can only be opened in read-write mode. - The significance of blocking or non-blocking mode is described in the - documentation for functions where there is a difference. It does not - affect the semantics of the open() call itself. A device opened in - blocking mode can later be put into non-blocking mode - (and vice versa) using the F_SETFL command of the fcntl system call. - - - PARAMETERS - - const char *deviceName I Name of the demux device, which should be - /dev/ost/demuxn where n denotes the - specific demux device to be opened, or the - name of a logical DVR device, /dev/ost/dvrn. - - int flags I A bit-wise OR of the following flags: - O_RDWR read/write access. - O_NONBLOCK open in non-blocking mode - (blocking mode is the default). - - RETURNS - - ENODEV Device driver not loaded/available. - - EINVAL Invalid argument. - - EMFILE "Too many open files", i.e. no more filters available. - - ENOMEM The driver failed to allocate enough memory. - - - -
-
- - -
- -int close(int fd); - - DESCRIPTION - - This system call deactivates and deallocates a filter that was previously - allocated via the open() call. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - RETURNS - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -size_t read(int fd, void *buf, size_t count); - - DESCRIPTION - - This system call returns filtered data, which might be section or PES - data. The filtered data is transferred from the driver's internal circular - buffer to buf. The maximum amount of data to be transferred is implied by - count. - - When returning section data the driver always tries to return a complete - single section (even though buf would provide buffer space for more data). - If the size of the buffer is smaller than the section as much as possible - will be returned, and the remaining data will be provided in subsequent - calls. - The size of the internal buffer is 2 * 4096 bytes (the size of two maximum - sized sections) by default. The size of this buffer may be changed by - using the DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, - or if the read operations are not performed fast enough, this may result - in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, - and the circular buffer will be emptied. - This call is blocking if there is no data to return, i.e. the process - will be put to sleep waiting for data, unless the O_NONBLOCK flag is - specified. - Note that in order to be able to read, the filtering process has to be - started by defining either a section or a PES filter by means of the - ioctl functions, and then starting the filtering process via the DMX_START - ioctl function or by setting the DMX_IMMEDIATE_START flag. - If the reading is done from a logical DVR demux device, the data will - constitute a Transport Stream including the packets from all PES filters - in the corresponding demux device /dev/ost/demuxn having the output set - to DMX_OUT_TS_TAP. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - void *buf O Pointer to the buffer to be used for returned filtered data. - - size_t count I Size of buf. - - RETURNS - - EWOULDBLOCK No data to return and O_NONBLOCK was specified. - - EBADF fd is not a valid open file descriptor - - ECRC Last section had a CRC error - no data - returned. The buffer is flushed. - - EBUFFEROVERFLOW The filtered data was not read from the buffer in - due time, resulting in non-read data being lost. - The buffer is flushed. - - ETIMEDOUT The section was not loaded within the stated - timeout period. See ioctl DMX_SET_FILTER for - how to set a timeout. - - EFAULT The driver failed to write to the callers buffer - due to an invalid *buf pointer. - - - -
-
- - -
- -ssize_t write(int fd, const void *buf, size_t count); - - DESCRIPTION - - This system call is only provided by the logical device /dev/ost/dvrn, - where n identifies the physical demux device that provides the actual - DVR functionality. It is used for replay of a digitally recorded - Transport Stream. Matching filters have to be defined in the - corresponding physical demux device, /dev/ost/demuxn. - The amount of data to be transferred is implied by count. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - void *buf I Pointer to the buffer containing the Transport Stream. - - size_t count I Size of buf. - - RETURNS - - EWOULDBLOCK No data was written. This might happen if - O_NONBLOCK was specified and there is no more - buffer space available (if O_NONBLOCK is not - specified the function will block until buffer - space is available). - - EBUSY This error code indicates that there are - conflicting requests. The corresponding demux - device is setup to receive data from the front- - end. Make sure that these filters are stopped - and that the filters with input set to DMX_IN_DVR - are started. - - EBADF fd is not a valid open file descriptor - - - -
-
- - -
- -int ioctl( int fd, int request = DMX_START); - - DESCRIPTION - - This ioctl call is used to start the actual filtering operation - defined via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_START for this command. - - RETURNS - - EBADF fd is not a valid file descriptor - - EINVAL Invalid argument, i.e. no filtering parameters - provided via the DMX_SET_FILTER or - DMX_SET_PES_FILTER functions. - - EBUSY This error code indicates that there are - conflicting requests. There are active filters - filtering data from another input source. Make - sure that these filters are stopped before starting - this filter. - - - -
-
- - -
- -int ioctl( int fd, int request = DMX_STOP); - - DESCRIPTION - - This ioctl call is used to stop the actual filtering operation defined - via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via - the DMX_START command. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_STOP for this command. - - RETURNS - - EBADF fd is not a valid file descriptor - -
-
- - -
- -int ioctl( int fd, int request = DMX_SET_FILTER, struct dmxSctFilterParams *params); - - DESCRIPTION - - This ioctl call sets up a filter according to the filter and mask - parameters provided. A timeout may be defined stating number of seconds - to wait for a section to be loaded. A value of 0 means that no timeout - should be applied. Finally there is a flag field where it is possible to - state whether a section should be CRC-checked, whether the filter should - be a "one-shot" filter, i.e. if the filtering operation should be stopped - after the first section is received, and whether the filtering operation - should be started immediately (without waiting for a DMX_START ioctl call). - If a filter was previously set-up, this filter will be cancelled, and the - receive buffer will be flushed. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_SET_FILTER for this command. - - struct I Pointer to structure containing filter - - dmxSctFilterParams parameters. - *params - - RETURNS - - EBADF fd is not a valid file descriptor - - EINVAL Invalid argument. - -
-
- - -
- -int ioctl( int fd, int request = DMX_SET_PES_FILTER, struct dmxPesFilterParams *params); - - DESCRIPTION - - This ioctl call sets up a PES filter according to the parameters provided. - By a PES filter is meant a filter that is based just on the packet - identifier (PID), i.e. no PES header or payload filtering capability is - supported. - The transport stream destination for the filtered output may be set. Also - the PES type may be stated in order to be able to e.g. direct a video - stream directly to the video decoder. Finally there is a flag field where - it is possible to state whether the filtering operation should be started - immediately (without waiting for a DMX_START ioctl call). - If a filter was previously set-up, this filter will be cancelled, and the - receive buffer will be flushed. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_SET_PES_FILTER for this command. - - struct I Pointer to structure containing filter - - dmxPesFilterParams parameters. - *params - - RETURNS - - EBADF fd is not a valid file descriptor - - EINVAL Invalid argument. - - EBUSY This error code indicates that there are - conflicting requests. There are active filters - filtering data from another input source. Make - sure that these filters are stopped before starting - this filter. - - - -
-
- - -
- -int ioctl( int fd, int request = DMX_SET_BUFFER_SIZE, unsigned long size); - - DESCRIPTION - - This ioctl call is used to set the size of the circular buffer used - for filtered data. The default size is two maximum sized sections, i.e. - if this function is not called a buffer size of 2 * 4096 bytes will be - used. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_SET_BUFFER_SIZE for this command. - - unsigned long size I Size of circular buffer. - - RETURNS - - EBADF fd is not a valid file descriptor. - - ENOMEM The driver was not able to allocate a buffer of the requested size. - - - -
-
- - -
- -int ioctl( int fd, int request = DMX_GET_EVENT, struct dmxEvent *ev); - - DESCRIPTION - - This ioctl call returns an event if available. If an event is not - available, the behavior depends on whether the device is in blocking or - non-blocking mode. In the latter case, the call fails immediately with - errno set to EWOULDBLOCK. In the former case, the call blocks until an - event becomes available. - The standard Linux poll() and/or select() system calls can be used with - the device file descriptor to watch for new events. For select(), the - file descriptor should be included in the exceptfds argument, and for - poll(), POLLPRI should be specified as the wake-up condition. - Only the latest event for each filter is saved. - - PARAMETERS - - int fd I File descriptor returned by a previous call to open(). - - int request I Equals DMX_SET_BUFFER_SIZE for this command. - - struct dmxEvent *ev O Pointer to the location where the event is to be stored. - - RETURNS - - EBADF fd is not a valid file descriptor. - - EFAULT ev points to an invalid address. - - EWOULDBLOCK There is no event pending, and the device is in non-blocking mode. - - - -
-
- -
- -
- - - DVB CA API - - The DVB CA device controls the conditional access hardware. - This allows functionalities like display of menues and entering of PIN numbers. - It can be accessed through /dev/ost/ca. - - - The function calls defined in the include file audio.h are described in - detail below: - - - - CA API IO control calls - - The exact io calls for this device have not been decided on yet. - - - - - - - - - - - -
- - - DVB Demux Kernel Module - - The demux device accesses the actual demux hardware through a - demux kernel module. This way other kernel modules (e.g. a generic DVB - network device) and not only the demux device can access the demux - hardware. - - - - DVB Demux Kernel Module API - - The demux kernel API gives access to the demuxer of the DVB - hardware to other kernel modules which implement devices like the Demux - device or generic DVB network devices. - - - The function calls defined in the include file demux.h are described in - detail below: - - - - Demux Directory API - - - The demux directory is a Linux kernel-wide facility for registering and - accessing the MPEG-2 TS demuxes in the system. Run-time registering and - unregistering of demux drivers is possible using this API. - - - All demux drivers in the directory implement the abstract interface dmx_demux_t. - - - -
-int dmx_register_demux ( dmx_demux_t* demux ) - - Description - - This function makes a demux driver interface available to the Linux kernel. - It is usually called by the init_module() function of the kernel module that - contains the demux driver. The caller of this function is responsible for - allocating dynamic or static memory for the demux structure and for initializing - its fields before calling this function. - The memory allocated for the demux structure must not be freed before calling - dmx_unregister_demux(), - - Returns - - 0 The command was successfully performed. - - -EEXIST A demux with the same value of the id field - already stored in the directory. - - -ENOSPC No space left in the directory. - - - -
-
- -
- -int dmx_unregister_demux ( dmx_demux_t* demux ) - - Parameters - - dmx_demux_t* demux I/O Pointer to the demux API and instance variables. - - Description - - This function is called to indicate that the given demux interface is no longer - available. The caller of this function is responsible for freeing the memory of - the demux structure, if it was dynamically allocated before calling - dmx_register_demux(). - The cleanup_module() function of the kernel module that contains the demux - driver should call this function. Note that this function fails if the demux - is currently in use, i.e., release_demux() has not been called for the - interface. - - Returns - - 0 The command was successfully performed. - - -ENODEV No such demux registered. - - -EBUSY Demux is currently in use. - - - -
-
- -
- -struct list_head* dmx_get_demuxes () - - Description - - Provides the caller with the list of registered demux interfaces, using the - standard list structure defined in the include file linux/list.h. - The include file demux.h defines the macro DMX_DIR_ENTRY() for converting an - element of the generic type struct list_head* to the type dmx_demux_t*. - The caller must not free the memory of any of the elements obtained via this - function call. - - Returns - - A list of demux interfaces, or NULL in the case of an empty list. - - - -
-
-
- - - - Demux API - - The demux API should be implemented for each demux in the system. It is used to - select the TS source of a demux and to manage the demux resources. When the - demux client allocates a resource via the demux API, it receives a pointer - to the API of that resource. - - - Each demux receives its TS input from a DVB front-end or from the memory, as - set via the demux API. In a system with more than one front-end, the API can - be used to select one of the DVB front-ends as a TS source for a demux, unless - this is fixed in the HW platform. The demux API only controls front-ends - regarding their connections with demuxes; the APIs used to set the other - front-end parameters, such as tuning, are not defined in this document. - - - The functions that implement the abstract interface demux_t should be defined - static or module private and registered to the Demux Directory for external - access. It is not necessary to implement every function in the demux_t struct, - however (for example, a demux interface might support Section filtering, but - not TS or PES filtering). The API client is expected to check the value of any - function pointer before calling the function: the value of NULL means "function - not available". - - - Whenever the functions of the demux API modify shared data, the possibilities - of lost update and race condition problems should be addressed, e.g. by - protecting parts of code with mutexes. This is especially important on - multi-processor hosts. - - - Note that functions called from a bottom half context must not sleep, at least - in the 2.2.x kernels. Even a simple memory allocation can result in a kernel - thread being put to sleep if swapping is needed. For example, the Linux kernel - calls the functions of a network device interface from a bottom half context. - Thus, if a demux API function is called from network device code, the function - must not sleep. - - -
- -int open ( demux_t* demux ) - - - Parameters - - demux_t* demux I Pointer to the demux API and instance data. - - Description - - This function reserves the demux for use by the caller and, if necessary, - initializes the demux. When the demux is no longer needed, the function close() - should be called. - It should be possible for multiple clients to access the demux at the same time. - Thus, the function implementation should increment the demux usage count when - open() is called and decrement it when close() is called. - - Returns - - 0 The command was successfully performed. - - -EUSERS Maximum usage count reached. - - -EINVAL Bad parameter. - - - -
-
- -
- -int close ( demux_t* demux ) - - Parameters - - demux_t* demux I Pointer to the demux API and instance data. - - Description - - The function is called to indicate that the API client does not need to use - the demux anymore. As a result of this function, the demux usage count is - decremented by one. - When the usage count drops to zero, any demux resources can be released. - - Returns - - 0 The command was successfully performed. - - -ENODEV The demux was not in use. - - -EINVAL Bad parameter. - - - -
-
- -
- -int write ( demux_t* demux, const char* buf, size_t count) - - Parameters - - demux_t* demux I/O Pointer to the demux API and instance data. - - const char* buf I Pointer to the TS data in kernel-space memory. - - size_t length I Length of the TS data. - - - - Description - - This function provides the demux driver with a memory buffer containing TS - packets. Instead of receiving TS packets from the DVB front-end, the demux - driver software will read packets from the memory. Any clients of this demux - with active TS, PES or Section filters will receive filtered data via the Demux - callback API (see 0). The function returns when all the data in the buffer has - been consumed by the demux. - Demux hardware typically cannot read TS from the memory. If this is the case, - memory-based filtering has to be implemented entirely in software. - - Returns - - 0 The command was successfully performed. - - -ENOSYS The command is not implemented. - - -EINVAL Bad parameter. - - - -
-
- -
- -int allocate_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t** feed, dmx_ts_cb callback ) - - Parameters - - demux_t* demux I/O Pointer to the demux API and instance data. - - dmx_ts_feed_t** feed O Pointer to the TS feed API and instance data. - - dmx_ts_cb callback I Pointer to the callback function for - passing received TS packet - - Description - - Allocates a new TS feed, which is used to filter the TS packets carrying a - certain PID. - The TS feed normally corresponds to a hardware PID filter on the demux chip. - - Returns - - 0 The command was successfully performed. - - -EBUSY No more TS feeds available. - - -ENOSYS The command is not implemented. - - -EINVAL Bad parameters. - - - -
-
- -
-int release_ts_feed ( dmx_demux_t* demux, dmx_ts_feed_t* feed) - - Parameters - - dmx_demux_t* demux I/O Pointer to the demux API and - instance data. - dmx_ts_feed_t* feed I Pointer to the TS feed API and - instance data. - - Function Detailed Description - Releases the resources allocated with allocate_ts_feed(). Any filtering in progress - on the TS feed should be stopped before calling this function. - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - -
-
- -
-allocate_pes_feed() - - TBD - - - -
-
- -
-release_pes_feed() - - TBD - - - -
-
- -
-int allocate_section_feed ( dmx_demux_t* demux, - dmx_section_feed_t** - feed, - dmx_section_cb callback ) - - Function Parameters - demux_t* demux I/O Pointer to the demux API and - instance data. - dmx_section_feed_t** feed O Pointer to the section feed API and - - instance data. - dmx_section_cb callback I Pointer to the callback function for - passing received sections - - Function Detailed Description - Allocates a new section feed, i.e. a demux resource for filtering and receiving sections. - On platforms with hardware support for section filtering, a section feed is directly - mapped to the demux HW. On other platforms, TS packets are first PID filtered in - hardware and a hardware section filter then emulated in software. - The caller obtains an API pointer of type dmx_section_feed_t as an out parameter. - Using this API the caller can set filtering parameters and start receiving sections. - - Function Returns - 0 The command was successfully performed. - -EBUSY No more section feeds available. - -ENOSYS The command is not implemented. - -EINVAL Bad parameters. - -
-
- -
- -int release_section_feed ( dmx_demux_t* demux, - dmx_section_feed_t* - feed - ) - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and - instance data. - dmx_section_feed_t* feed I Pointer to the section feed API and - instance data. - - Function Detailed Description - Releases the resources allocated with allocate_section_feed(), including allocated - filters. Any filtering in progress on the section feed should be stopped before calling - this function. - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - - -
-
- -
- -int descramble_mac_address ( dmx_demux_t* demux, - __u8* - buffer1, - size_t - buffer1_length, - __u8* buffer2, - size_t - buffer2_length, - __u16 pid ) - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and - instance data. - __u8* buffer1 I Pointer to the first byte of the - section. - size_t buffer1_length I Length of the section data, - including headers and CRC, in - buffer1. - __u8* buffer2 I Pointer to the tail of the section - data, or NULL. The pointer has a - non-NULL value if the section wraps - past the end of a cyclic buffer. - size_t buffer2_length I Length of the section data, - including headers and CRC, in - buffer2 - __u16 pid I The PID on which the section was - received. Useful for obtaining the - descrambling key, e.g. from a DVB - Common Access facility. - - Function Detailed Description - This function runs a descrambling algorithm on the destination MAC address field of a - DVB Datagram Section, replacing the original address with its unencrypted version. - Otherwise, the description on the function descramble_section_payload() applies - also to this function. - - Function Returns - 0 The command was successfully performed. - -ENOSYS No descrambling facility available. - -EINVAL Bad parameters. - - - - -
-
- -
- -int descramble_section_payload ( dmx_demux_t* demux, - __u8* - buffer1, - size_t - buffer1_length, - __u8* buffer2, - size_t - buffer2_length, - __u16 pid ) - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and - instance data. - __u8* buffer1 I/O Pointer to the first byte of the - section. - size_t buffer1_length I Length of the section data, - including headers and CRC, in - buffer1. - __u8* buffer2 I Pointer to the tail of the section - data, or NULL. The pointer has a - non-NULL value if the section wraps - past the end of a cyclic buffer. - size_t buffer2_length I Length of the section data, - including headers and CRC, in - buffer2 - __u16 pid I The PID on which the section was - received. Useful for obtaining the - descrambling key, e.g. from a DVB - Common Access facility. - - Function Detailed Description - This function runs a descrambling algorithm on the payload of a DVB Datagram - Section, replacing the original payload with its unencrypted version. The function will - be called from the demux API implementation; the API client need not call this function - directly. - Section-level scrambling algorithms are currently standardized only for DVB-RCC - (return channel over 2-directional cable TV network) systems. For all other DVB - networks, encryption schemes are likely to be proprietary to each data broadcaster. - Thus, it is expected that this function pointer will have the value of NULL (i.e., function - not available) in most demux API implementations. Nevertheless, it should be possible - to use the function pointer as a hook for dynamically adding a "plug-in" descrambling - facility to a demux driver. - - - While this function is not needed with hardware-based section descrambling, the - descramble_section_payload function pointer can be used to override the default - hardware-based descrambling algorithm: if the function pointer has a non-NULL value, - the corresponding function should be used instead of any descrambling hardware. - - Function Returns - 0 The command was successfully performed. - -ENOSYS No descrambling facility available. - -EINVAL Bad parameters. - - -
-
- -
- -int add_frontend ( dmx_demux_t* demux, - dmx_frontend_t* - frontend); - - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and instance - data. - dmx_frontend_t* frontend I/O Pointer to the front-end instance data. - - Function Detailed Description - Registers a connectivity between a demux and a front-end, i.e., indicates that the - demux can be connected via a call to connect_frontend() to use the given front-end - as a TS source. The client of this function has to allocate dynamic or static memory for - the frontend structure and initialize its fields before calling this function. - This function is normally called during the driver initialization. The caller must not free - the memory of the frontend struct before successfully calling remove_frontend(). - - Function Returns - 0 The command was successfully performed. - -EEXIST A front-end with the same value of the id field - already registered. - -EINUSE The demux is in use. - -ENOMEM No more front-ends can be added. - -EINVAL Bad parameters. - -
-
- -
- -int remove_frontend ( dmx_demux_t* demux, - dmx_frontend_t* frontend ) - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and instance - data. - dmx_frontend_t* frontend I/O Pointer to the front-end instance data. - - Function Detailed Description - Indicates that the given front-end, registered by a call to add_frontend(), can no - longer be connected as a TS source by this demux. The function should be called - when a front-end driver or a demux driver is removed from the system. If the front-end - is in use, the function fails with the return value of -EBUSY. - After succesfully calling this function, the caller can free the memory of the frontend - struct if it was dynamically allocated before the add_frontend() operation. - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - -EBUSY The front-end is in use, i.e. a call to - connect_frontend() has not been followed by - a call to disconnect_frontend(). - - -
-
- -
- -struct list_head* get_frontends ( dmx_demux_t* demux ) - Function Parameters - dmx_demux_t* demux I Pointer to the demux API and - instance data. - - Function Detailed Description - Provides the APIs of the front-ends that have been registered for this demux. Any of - the front-ends obtained with this call can be used as a parameter for - connect_frontend(). - - - The include file demux.h contains the macro DMX_FE_ENTRY() for converting an - element of the generic type struct list_head* to the type dmx_frontend_t*. - The caller must not free the memory of any of the elements obtained via this function - call. - - Function Returns - A list of front-end interfaces, or NULL in the case of an empty list. - -
-
- -
- -int connect_frontend ( dmx_demux_t* demux, - dmx_frontend_t* frontend ) - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and instance - data. - dmx_frontend_t* frontend I/O Pointer to the front-end instance data. - - Function Detailed Description - Connects the TS output of the front-end to the input of the demux. A demux can only - be connected to a front-end registered to the demux with the function - add_frontend(). - It may or may not be possible to connect multiple demuxes to the same front-end, - depending on the capabilities of the HW platform. When not used, the front-end should - be released by calling disconnect_frontend(). - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - -EBUSY The front-end is in use. - -
-
- -
- -int disconnect_frontend ( dmx_demux_t* demux ) - - - Function Parameters - dmx_demux_t* demux I/O Pointer to the demux API and instance data. - - Function Detailed Description - Disconnects the demux and a front-end previously connected by a - connect_frontend() call. - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - - -
-
-
- - - Demux Callback API - - This kernel-space API comprises the callback functions that deliver filtered data to the - demux client. Unlike the other APIs, these API functions are provided by the client and - called from the demux code. - - - The function pointers of this abstract interface are not packed into a structure as in the - other demux APIs, because the callback functions are registered and used - independent of each other. As an example, it is possible for the API client to provide - several callback functions for receiving TS packets and no callbacks for PES packets - or sections. - - - The functions that implement the callback API need not be re-entrant: when a demux - driver calls one of these functions, the driver is not allowed to call the function again - before the original call returns. If a callback is triggered by a hardware interrupt, it is - recommended to use the Linux "bottom half" mechanism or start a tasklet instead of - making the callback function call directly from a hardware interrupt. - - - -
-int dmx_ts_cb ( __u8* buffer1, size_t buffer1_length, - __u8* buffer2, size_t buffer2_length, - dmx_ts_feed_t* source, dmx_success_t success ) - - Parameters - - __u8* buffer1 I Pointer to the start of the filtered TS packets. - - size_t buffer1_length I Length of the TS data in buffer1. - - __u8* buffer2 I Pointer to the tail of the filtered TS packets, or NULL. - - size_t buffer2_length I Length of the TS data in buffer2. - - dmx_ts_feed_t* source I Indicates which TS feed is the source of the callback. - - dmx_success_t success I Indicates if there was an error in TS reception. - - Description - - This function, provided by the client of the demux API, is called from the - demux code. The function is only called when filtering on this TS feed has - been enabled using the start_filtering() function. If conflict resolution - is used (see Error! Reference source not found.), no callbacks are made to - clients that have been put "on hold" regarding a TS Feed resource. - Any TS packets that match the filter settings are copied to a cyclic buffer. - The filtered TS packets are delivered to the client using this callback - function. The size of the cyclic buffer is controlled by the - circular_buffer_size parameter of the set() function in the TS Feed API. It is - expected that the buffer1 and buffer2 callback parameters point to addresses - within the circular buffer, but other implementations are also - possible. Note that the called party should not try to free the memory the - buffer1 and buffer2 parameters point to. - When this function is called, the buffer1 parameter typically points to the - start of the first undelivered TS packet within a cyclic buffer. The buffer2 - buffer parameter is normally NULL, except when the received TS packets have - crossed the last address of the cyclic buffer and "wrapped" to the beginning - of the buffer. In the latter case the buffer1 parameter would contain an - address within the cyclic buffer, while the buffer2 parameter would contain - the first address of the cyclic buffer. - The number of bytes delivered with this function (i.e. buffer1_length + - buffer2_length) is usually equal to the value of callback_length parameter given - in the set() function, with one exception: if a timeout occurs before receiving - callback_length bytes of TS data, any undelivered packets are immediately - delivered to the client by calling this function. The timeout duration is - controlled by the set() function in the TS Feed API. - If a TS packet is received with errors that could not be fixed by the TS-level - forward error correction (FEC), the Transport_error_indicator flag of the TS - packet header should be set. The TS packet should not be discarded, as the - error can possibly be corrected by a higher layer protocol. - If the called party is slow in processing the callback, it is possible that - the circular buffer eventually fills up. If this happens, the demux driver - should discard any TS packets received while the buffer is full. The error - should be indicated to the client on the next callback by setting the success - parameter to the value of DMX_OVERRUN_ERROR. - - The type of data returned to the callback can be selected by the - new function int (*set_type) (struct dmx_ts_feed_s* feed, int type, - dmx_ts_pes_t pes_type) which is part of the dmx_ts_feed_s struct - (also cf. to the include file ost/demux.h) - The type parameter decides if the raw TS packet (TS_PACKET) or just the - payload (TS_PACKET|TS_PAYLOAD_ONLY) should be returned. - If additionally the TS_DECODER bit is set the stream will also be sent - to the hardware MPEG decoder. In this case, the second flag decides - as what kind of data the stream should be interpreted. - The possible choices are one of DMX_TS_PES_AUDIO, DMX_TS_PES_VIDEO, - DMX_TS_PES_TELETEXT, DMX_TS_PES_SUBTITLE, DMX_TS_PES_PCR, or - DMX_TS_PES_OTHER. - - - Returns - - 0 Continue filtering. - - -1 Stop filtering - has the same effect as a call - to stop_filtering() on the TS Feed API. - - - -
-
- -
- -dmx_pes_cb() - - TBD - -
-
- -
- -int dmx_section_cb ( __u8* buffer1, - size_t - buffer1_length, - __u8* - buffer2, - size_t buffer2_length, - dmx_section_filter_t* - source, - dmx_success_t success ) - - Function Parameters - __u8* buffer1 I Pointer to the start of the filtered section, e.g. - within the cyclic buffer of the demux driver. - size_t buffer1_length I Length of the filtered section data in buffer1, - including headers and CRC. - __u8* buffer2 Pointer to the tail of the filtered section data, or - NULL. Useful to handle the wrapping of a cyclic - buffer. - size_t buffer2_length Length of the filtered section data in buffer2, - including headers and CRC. - dmx_section_filter_t* I Indicates the filter that triggered the callback. - filter - dmx_success_t success I Indicates if there was an error in section - reception. - - Function Detailed Description - This function, provided by the client of the demux API, is called from the demux code. - The function is only called when filtering of sections has been enabled using the - function start_filtering() of the section feed API. - When the demux driver has received a complete section that matches at least one - section filter, the client is notified via this callback function. Normally this function is - called for each received section; however, it is also possible to deliver multiple sections - with one callback, for example when the system load is high. - If an error occurs while receiving a section, this function should be called with the - corresponding error type set in the success field, whether or not there is data to - deliver. - The Section Feed implementation should maintain a cyclic buffer for received sections. - However, this is not necessary if the Section Feed API is implemented as a client of - - - the TS Feed API, because the TS Feed implementation then buffers the - received data. - The size of the circular buffer can be configured using the set() function in the - Section Feed API. If there is no room in the circular buffer when a new section is - received, the section must be discarded. If this happens, the value of the success - parameter should be DMX_OVERRUN_ERROR on the next callback. - - Function Returns - 0 Continue filtering. - -1 Stop filtering - has the same effect as a call - to stop_filtering() on the Section Feed - API. - -
-
- -
- - - TS Feed API - - A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this - API, the client can set the filtering properties to start/stop filtering TS packets on a - particular TS feed. The API is defined as an abstract interface of the type - dmx_ts_feed_t. - - - The functions that implement the interface should be defined static or module - private. The client can get the handle of a TS feed API by calling the function - allocate_ts_feed() in the demux API. - - -
- -int set ( dmx_ts_feed_t* feed, - __u16 - pid, - size_t callback_length, - size_t - cyclic_buffer_size, - int - descramble, - struct timespec timeout) - - Parameters - - dmx_ts_feed_t* feed I/O Pointer to the TS feed API and - instance data. - __u16 pid I PID value to filter. Only the TS - packets carrying the specified PID will - be passed to the API client. - size_t callback_length I Number of bytes to deliver with each - call to the dmx_ts_cb() callback - function. The value of this - parameter should be a multiple of - 188. - - size_t cyclic_buffer_size I Size of the cyclic buffer for the filtered - TS packets. - int descramble I If non-zero, descramble the filtered - TS packets. - struct timespec timeout I Maximum time to wait before - delivering received TS packets to the - client. - - Function Detailed Description - This function sets the parameters of a TS feed. Any filtering in progress on the TS feed - must be stopped before calling this function. - - Function Returns - 0 The command was successfully performed. - -ENOMEM Not enough memory for the requested - buffer size. - -ENOSYS No descrambling facility available for TS - packets. - -EINVAL Bad parameters. - -
-
- - -
- -int start_filtering ( dmx_ts_feed_t* feed ) - - Parameters - - dmx_ts_feed_t* feed I Pointer to the TS feed API and instance data. - - Function Detailed Description - Starts filtering TS packets on this TS feed, according to its settings. The PID value to - filter can be set by the API client. All matching TS packets are delivered - asynchronously to the client, using the callback function registered with - allocate_ts_feed(). - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - - -
-
- -
- -int stop_filtering ( dmx_ts_feed_t* feed ) - - Parameters - - dmx_ts_feed_t* feed I/O Pointer to the TS feed API and instance data. - - Description - - Stops filtering TS packets on this TS feed. - - Returns - - 0 The command was successfully performed. - - -EINVAL Bad parameters. - - - -
-
-
- - - PES Feed API - - TBD - - - - - Section Feed API - - A section feed is a resource consisting of a PID filter and a set of section filters. Using - this API, the client can set the properties of a section feed and to start/stop filtering. - The API is defined as an abstract interface of the type dmx_section_feed_t. - The functions that implement the interface should be defined static or module - private. The client can get the handle of a section feed API by calling the function - allocate_section_feed() in the demux API. - - - On demux platforms that provide section filtering in hardware, the Section Feed API - implementation provides a software wrapper for the demux hardware. Other platforms - may support only PID filtering in hardware, requiring that TS packets are converted to - sections in software. In the latter case the Section Feed API implementation can be a - client of the TS Feed API. - - - -
- -int set ( dmx_section_feed_t* feed, __u16 pid, size_t circular_buffer_size, - int descramble, int check_crc ) - - Parameters - - dmx_section_feed_t* feed I/O Pointer to the section feed API and - instance data. - __u16 pid I PID value to filter; only the TS packets - carrying the specified PID will be - accepted. - size_t circular_buffer_size I Size of the cyclic buffer for filtered - sections. - int descramble I If non-zero, descramble any sections - that are scrambled. - int check_crc I If non-zero, check the CRC values of - filtered sections. - - Function Detailed Description - This function sets the parameters of a section feed. Any filtering in progress on the - section feed must be stopped before calling this function. - If descrambling is enabled, the payload_scrambling_control and - address_scrambling_control fields of received DVB datagram sections should be - observed. If either one is non-zero, the section should be descrambled either in - hardware or using the functions descramble_mac_address() and - descramble_section_payload() of the demux API. Note that according to the - MPEG-2 Systems specification [3], only the payloads of private sections can be - scrambled while the rest of the section data must be sent in the clear. - - Function Returns - 0 The command was successfully performed. - -ENOMEM Not enough memory available for the requested - buffer size. - -ENOSYS No descrambling facility available for sections. - -EINVAL Bad parameters. - -
-
- -
- -int allocate_filter(dmx_section_feed_t* feed, dmx_section_filter_t** filter) - - Parameters - dmx_section_feed_t* feed I/O Pointer to the section feed API and - instance data. - dmx_section_filter_t** filter O Pointer to the allocated filter. - - - Function Detailed Description - This function is used to allocate a section filter on the demux. It should only be called - when no filtering is in progress on this section feed. If a filter cannot be allocated, the - function fails with -ENOSPC. See below for the format of the section filter struct provided - as an out parameter: - typedef struct { - __u8 filter_value [DMX_MAX_FILTER_SIZE]; - __u8 filter_mask [DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed_s* parent; /* Back-pointer */ - void* priv; /* Private data of the client */ - } dmx_section_filter_t; - - The bitfields filter_mask and filter_value should only be modified when no - filtering is in progress on this section feed. filter_mask controls which bits of - filter_value are compared with the section headers/payload. On a binary value of 1 - in filter_mask, the corresponding bits are compared. The filter only accepts sections - that are equal to filter_value in all the tested bit positions. Any changes to the - values of filter_mask and filter_value are guaranteed to take effect only when - the start_filtering() function is called next time. The parent pointer in the struct - is initialized by the API implementation to the value of the feed parameter. The priv - pointer is not used by the API implementation, and can thus be freely utilized by the - caller of this function. Any data pointed to by the priv pointer is available to the - recipient of the dmx_section_cb() function call. - While the maximum section filter length (DMX_MAX_FILTER_SIZE) is currently set at 16 - bytes, hardware filters of that size are not available on all platforms. Therefore, section - filtering will often take place first in hardware, followed by filtering in software for the - header bytes that were not covered by a hardware filter. The filter_mask field can be - checked to determine how many bytes of the section filter are actually used, and if the - hardware filter will suffice. Additionally, software-only section filters can optionally be - allocated to clients when all hardware section filters are in use. - Note that on most demux hardware it is not possible to filter on the section_length field - of the section header - thus this field is ignored, even though it is included in - filter_value and filter_mask fields. - - Function Returns - 0 The command was successfully performed. - -ENOSPC No filters of given type and length available. - -EINVAL Bad parameters. - -
-
- -
-int release_filter ( dmx_section_feed_t* feed, dmx_section_filter_t* filter) - - Parameters - dmx_section_feed_t* feed I/O Pointer to the section feed API and instance - data. - dmx_section_filter_t* I/O Pointer to the instance data of a section filter. - filter - - Function Detailed Description - This function releases all the resources of a previously allocated section filter. The - function should not be called while filtering is in progress on this section feed. After - calling this function, the caller should not try to dereference the filter pointer. - - Function Returns - 0 The command was successfully performed. - -ENODEV No such filter allocated. - -EINVAL Bad parameters. - -
-
- -
-int start_filtering ( dmx_section_feed_t* feed ) - - Parameters - dmx_section_feed_t* feed I/O Pointer to the section feed API and - instance data. - - Function Detailed Description - Starts filtering sections on this section feed, according to its settings. Sections are first - filtered based on their PID and then matched with the section filters allocated for this - feed. If the section matches the PID filter and at least one section filter, it is delivered - to the API client. The section is delivered asynchronously using the callback function - registered with allocate_section_feed(). - - Function Returns - 0 The command was successfully performed. - -EINVAL Bad parameters. - -
-
- -
-int stop_filtering ( dmx_section_feed_t* feed ) - - Parameters - - dmx_section_feed_t* feed I/O Pointer to the section feed API and instance data. - - Description - - Stops filtering sections on this section feed. Note that any changes to the - filtering parameters (filter_value, filter_mask, etc.) should only be made - when filtering is stopped. - - Returns - - 0 The command was successfully performed. - - -EINVAL Bad parameters. - - - -
-
- - -
- -
- -
- -
-
-- cgit v1.2.3 From 9034551a3bbc76b79a152806c781b1b8e8ea3a9a Mon Sep 17 00:00:00 2001 From: rjkm Date: Sun, 16 Sep 2001 22:27:03 -0300 Subject: new API docs --- dvb-spec/dvbapi/Makefile | 30 ++ dvb-spec/dvbapi/audio.tex | 436 +++++++++++++++++ dvb-spec/dvbapi/bibsection.sty | 29 ++ dvb-spec/dvbapi/ca.tex | 127 +++++ dvb-spec/dvbapi/cimlogo.psi | 122 +++++ dvb-spec/dvbapi/demux.tex | 392 ++++++++++++++++ dvb-spec/dvbapi/devices.tex | 12 + dvb-spec/dvbapi/dvbapi.tex | 166 +++++++ dvb-spec/dvbapi/dvbstb.fig | 59 +++ dvb-spec/dvbapi/examples.tex | 365 +++++++++++++++ dvb-spec/dvbapi/fig2pstex | 6 + dvb-spec/dvbapi/getbb | 12 + dvb-spec/dvbapi/intro.tex | 192 ++++++++ dvb-spec/dvbapi/kdapi.tex | 1007 ++++++++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/sec.tex | 282 +++++++++++ dvb-spec/dvbapi/title.tex | 24 + dvb-spec/dvbapi/video.tex | 684 +++++++++++++++++++++++++++ 17 files changed, 3945 insertions(+) create mode 100644 dvb-spec/dvbapi/Makefile create mode 100644 dvb-spec/dvbapi/audio.tex create mode 100644 dvb-spec/dvbapi/bibsection.sty create mode 100644 dvb-spec/dvbapi/ca.tex create mode 100644 dvb-spec/dvbapi/cimlogo.psi create mode 100644 dvb-spec/dvbapi/demux.tex create mode 100644 dvb-spec/dvbapi/devices.tex create mode 100644 dvb-spec/dvbapi/dvbapi.tex create mode 100644 dvb-spec/dvbapi/dvbstb.fig create mode 100644 dvb-spec/dvbapi/examples.tex create mode 100755 dvb-spec/dvbapi/fig2pstex create mode 100755 dvb-spec/dvbapi/getbb create mode 100644 dvb-spec/dvbapi/intro.tex create mode 100644 dvb-spec/dvbapi/kdapi.tex create mode 100644 dvb-spec/dvbapi/sec.tex create mode 100644 dvb-spec/dvbapi/title.tex create mode 100644 dvb-spec/dvbapi/video.tex diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile new file mode 100644 index 000000000..fe9827cff --- /dev/null +++ b/dvb-spec/dvbapi/Makefile @@ -0,0 +1,30 @@ +all: dvbapi.ps dvbapi.pdf + +TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ + intro.tex title.tex dvbstb.ps + +dvbapi.pdf: dvbapi.dvi + dvipdf $< $@ + +dvbapi.ps: dvbapi.dvi + dvips -o $@ $< + +dvbapi.dvi: dvbapi.bbl $(TEXS) + -latex dvbapi + -bibtex dvbapi + -makeindex dvbapi + -latex dvbapi + -latex dvbapi + +dvbapi.bbl: $(TEXS) + -latex dvbapi + -bibtex dvbapi + -makeindex dvbapi + +%.ps: %.fig + ./fig2pstex $< + +clean: + rm -f dvbapi.dvi + rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc + rm -f *.pdf *.pst *.ps diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex new file mode 100644 index 000000000..8c5b4fe82 --- /dev/null +++ b/dvb-spec/dvbapi/audio.tex @@ -0,0 +1,436 @@ +\devsec{DVB Audio Device} + +The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. +It can be accessed through \texttt{/dev/ost/audio}. + + +\devsubsec{Audio Data Types} + +This section describes the structures, data types and defines used when +talking to the audio device. + +\devsubsubsec{audioStreamSource\_t} +\label{audiostreamsource} +The audio stream source is set through the AUDIO\_SELECT\_SOURCE +call and can take the following values, depending on whether we are +replaying from an internal (demuxer) or external (user write) source. +\begin{verbatim} +typedef enum { + AUDIO_SOURCE_DEMUX, + AUDIO_SOURCE_MEMORY +} audioStreamSource_t; +\end{verbatim} +AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed +either by the frontend or the DVR device) as the source of +the video stream. +If AUDIO\_SOURCE\_MEMORY is selected the stream +comes from the application through the \texttt{write()} +system call. + +\devsubsubsec{audioPlayState\_t} +The following values can be returned by the AUDIO\_GET\_STATUS call +representing the state of audio playback. +\label{audioplaystate} +\begin{verbatim} +typedef enum { + AUDIO_STOPPED, + AUDIO_PLAYING, + AUDIO_PAUSED +} audioPlayState_t; +\end{verbatim} + +\devsubsubsec{audioChannelSelect\_t} +\label{audiochannelselect} +The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by +the following values. +\begin{verbatim} +typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, +} audioChannelSelect_t; +\end{verbatim} + +\devsubsubsec{audioStatus\_t} +\label{audiostatus} +The AUDIO\_GET\_STATUS call returns the following structure informing +about various states of the playback operation. +\begin{verbatim} +typedef struct audioStatus { + boolean AVSyncState; + boolean muteState; + audioPlayState_t playState; + audioStreamSource_t streamSource; + audioChannelSelect_t channelSelect; + boolean bypassMode; +} audioStatus_t; +\end{verbatim} + +\devsubsubsec{audioMixer\_t} +\label{audiomixer} +The following structure is used by the AUDIO\_SET\_MIXER call to set +the audio volume. +\begin{verbatim} +typedef struct audioMixer { + unsigned int volume_left; + unsigned int volume_right; +} audioMixer_t; +\end{verbatim} + +\devsubsubsec{audio encodings} +\label{audiotypes} +A call to AUDIO\_GET\_CAPABILITIES returns an unsigned integer with +the following bits set according to the hardwares capabilities. +\begin{verbatim} +#define AUDIO_CAP_DTS 1 +#define AUDIO_CAP_LPCM 2 +#define AUDIO_CAP_MP1 4 +#define AUDIO_CAP_MP2 8 +#define AUDIO_CAP_MP3 16 +#define AUDIO_CAP_AAC 32 +#define AUDIO_CAP_OGG 64 +#define AUDIO_CAP_SDDS 128 +#define AUDIO_CAP_AC3 256 +\end{verbatim} + + +\devsubsubsec{audio karaoke} +\label{audiokaraoke} +The ioctl AUDIO\_SET\_KARAOKE uses the following format: +\begin{verbatim} +typedef +struct audioKaraoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ + int vocal1; /* into left and right t at 70% each */ + int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ + int melody; /* mixed into the left channel and */ + /* Vocal2 into the right channel at 100% each. */ + /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ +} audioKaraoke_t; +\end{verbatim} + +\devsubsubsec{audio attributes} +\label{aattrib} +The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: +\begin{verbatim} +typedef uint16_t audioAttributes_t; +/* bits: descr. */ +/* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ +/* 12 multichannel extension */ +/* 11-10 audio type (0=not spec, 1=language included) */ +/* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ +/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ +/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ +/* 2- 0 number of audio channels (n+1 channels) */ +\end{verbatim} + + +\clearpage + +\devsubsec{Audio Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + use. When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not affect + the semantics of the open() call itself. A device opened in blocking mode can + later be put into non-blocking mode (and vice versa) using the F\_SETFL command + of the fcntl system call. This is a standard system call, documented in the + Linux manual page for fcntl. + Only one user can open the Audio Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error code will be returned. + If the Audio Device is opened in O\_RDONLY mode, the only ioctl call that can + be used is AUDIO\_GET\_STATUS. All other call will return with an error code. + }{ + const char *deviceName & Name of specific audio device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{write()}{ + size\_t write(int fd, const void *buf, size\_t count);}{ + This system call can only be used if AUDIO\_SOURCE\_MEMORY is selected + in the ioctl call AUDIO\_SELECT\_SOURCE. + The data provided shall be in PES format. + If O\_NONBLOCK is not specified the function will block until buffer space is + available. The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the PES data.\\ + size\_t count& Size of buf.\\ + }{ + EPERM& Mode AUDIO\_SOURCE\_MEMORY not selected.\\ + ENOMEM& Attempted to write more data than the internal buffer can hold.\\ + EBADF& fd is not a valid open file descriptor.\\ +} + +\ifunction{AUDIO\_STOP}{ + int ioctl(int fd, int request = AUDIO\_STOP);}{ + This ioctl call asks the Audio Device to stop playing the current stream. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_STOP for this command. + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_PLAY}{ + int ioctl(int fd, int request = AUDIO\_PLAY);}{ + This ioctl call asks the Audio Device to start playing an audio stream + from the selected source. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_PLAY for this command. + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_PAUSE}{ + int ioctl(int fd, int request = AUDIO\_PAUSE);}{ + This ioctl call suspends the audio stream being played. + Decoding and playing are paused. + It is then possible to restart again decoding and playing process of the + audio stream using AUDIO\_CONTINUE command.\\ + If AUDIO\_SOURCE\_MEMORY is selected in the ioctl call + AUDIO\_SELECT\_SOURCE, the DVB-subsystem will not decode (consume) + any more data until the ioctl call + AUDIO\_CONTINUE or AUDIO\_PLAY is performed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_PAUSE for this command. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_SELECT\_SOURCE}{ + int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, + audioStreamSource\_t source);}{ + This ioctl call informs the audio device which source shall be used for the + input data. The possible sources are demux or memory. + If AUDIO\_SOURCE\_MEMORY + is selected, the data is fed to the Audio Device through the write command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\ + audioStreamSource\_t source& Indicates the source that shall be used for the + Audio stream. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_MUTE}{ + int ioctl(int fd, int request = AUDIO\_SET\_MUTE, boolean state);}{ + This ioctl call asks the audio device to mute the stream that is + currently being played. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_MUTE for this command.\\ + boolean state & Indicates if audio device shall mute or not.\\ + &TRUE Audio Mute\\ + &FALSE Audio Un-mute\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_AV\_SYNC}{ + int ioctl(int fd, int request = AUDIO\_SET\_AV\_SYNC, boolean state);}{ + This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_AV\_SYNC for this command.\\ + boolean state& Tells the DVB subsystem if A/V + synchronization shall be ON or OFF.\\ + & TRUE AV-sync ON \\ + & FALSE AV-sync OFF\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_BYPASS\_MODE}{ + int ioctl(int fd, int request = AUDIO\_SET\_BYPASS\_MODE, boolean mode);}{ + This ioctl call asks the Audio Device to bypass the Audio decoder and forward + the stream without decoding. This mode shall be used if streams that can't be + handled by the DVB system shall be decoded. + Dolby DigitalTM streams are automatically forwarded by the DVB + subsystem if the hardware can handle it. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_BYPASS\_MODE for this command.\\ + boolean mode& Enables or disables the decoding of the current + Audio stream in the DVB subsystem.\\ + &TRUE Bypass is disabled\\ + &FALSE Bypass is enabled\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_CHANNEL\_SELECT}{ + int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, + audioChannelSelect\_t);}{ + This ioctl call asks the Audio Device to select the requested channel + if possible. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\ + audioChannelSelect\_t ch & + Select the output format of the audio (mono left/right, stereo). + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter ch. +} + +\ifunction{AUDIO\_GET\_STATUS}{ + int ioctl(int fd, int request = AUDIO\_GET\_STATUS, + struct audioStatus *status);}{ + This ioctl call asks the Audio Device to return the current state + of the Audio Device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_GET\_STATUS for this command.\\ + struct audioStatus *status & Returns the current state of Audio Device. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & status points to invalid address. +} + +\ifunction{AUDIO\_GET\_CAPABILITIES}{ + int ioctl(int fd, int request = AUDIO\_GET\_CAPABILITIES, + unsigned int *cap);}{ + This ioctl call asks the Audio Device to tell us about the + decoding capabilities of the audio hardware. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_GET\_CAPABILITIES for this command.\\ + unsigned int *cap & Returns a bit array of supported sound formats. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & cap points to an invalid address. +} + +\ifunction{AUDIO\_CLEAR\_BUFFER}{ + int ioctl(int fd, int request = AUDIO\_CLEAR\_BUFFER);}{ + This ioctl call asks the Audio Device to clear all software + and hardware buffers of the audio decoder device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_CLEAR\_BUFFER for this command. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_SET\_ID}{ + int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{ + This ioctl selects which sub-stream is to be decoded if a program or + system stream is sent to the video device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ID for this command.\\ + int id& audio sub-stream id + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Invalid sub-stream id. +} + +\ifunction{AUDIO\_SET\_MIXER}{ + int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audioMixer\_t *mix);}{ + This ioctl lets you adjust the mixer settings of the audio decoder. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ID for this command.\\ + audioMixer\_t *mix& mixer settings. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & mix points to an invalid address. +} + +\ifunction{AUDIO\_SET\_STREAMTYPE}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{ + This ioctl tells the driver which kind of audio stream to expect. + This is useful if the stream offers several audio sub-streams + like MPEG2 audio and AC3. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ + int type & stream type\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& type is not a valid or supported stream type.\\ +} + + +\ifunction{AUDIO\_SET\_EXT\_ID}{ + int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{ + This ioctl can be used to set the audio sub\_stream\_id for DVD playback + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ + int id & audio sub\_stream\_id\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& id is not a valid id.\\ +} + +\ifunction{AUDIO\_SET\_ATTRIBUTES}{ + int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ + This ioctl is intended for DVD playback and allows you to set + certain information about the audio stream. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\ + iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& attr is not a valid or supported attribute setting.\\ +} + +\ifunction{AUDIO\_SET\_KARAOKE}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audioKaraoke\_t *karaoke);}{ + This ioctl allows one to set the mixer settings for a karaoke DVD. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ + audioKaraoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ + }{ + EBADF & fd is not a valid open file descriptor \\ + EINVAL& karaoke is not a valid or supported karaoke setting.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/bibsection.sty b/dvb-spec/dvbapi/bibsection.sty new file mode 100644 index 000000000..7f9eedc6a --- /dev/null +++ b/dvb-spec/dvbapi/bibsection.sty @@ -0,0 +1,29 @@ +\def\thebibliography#1{\chapter*{\bibname\@mkboth + {\uppercase{\bibname}}{\uppercase{\bibname}}} + \setcounter{chapter}{0} + \setcounter{section}{0} + \def\thechapter{Bib} + \def\thesection{\Alph{section}} + \edef\biblab{#1} + \addcontentsline{toc}{chapter}{\bibname} + } + +\def\bibtitle#1#2{\expandafter\def\csname bibtitle#1\endcsname{ + \bibsection{#2}} } + +\def\bibsection#1{\section{#1} + \begin{list} + {\@biblabel{\arabic{enumiv}}}{\settowidth\labelwidth{\@biblabel{\biblab}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \usecounter{enumiv}% + \let\p@enumiv\@empty + \def\theenumiv{\arabic{enumiv}}}% + \def\newblock{\hskip .11em plus.33em minus.07em}% + \sloppy\clubpenalty4000\widowpenalty4000 + \sfcode`\.=\@m} + +\def\endbibsection{\end{list}} + +\def\endthebibliography{\endbibsection} + diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex new file mode 100644 index 000000000..eba512b1b --- /dev/null +++ b/dvb-spec/dvbapi/ca.tex @@ -0,0 +1,127 @@ +\devsec{DVB CA Device} + +The DVB CA device controls the conditional access hardware. +It can be accessed through \texttt{/dev/ost/ca}. + + +\devsubsec{CA Data Types} + +\devsubsubsec{ca\_slot\_info\_t} +\label{caslotinfo} + +\begin{verbatim} +/* slot interface types and info */ + +typedef struct ca_slot_info_s { + int num; /* slot number */ + + int type; /* CA interface this slot supports */ +#define CA_CI 1 /* CI high level interface */ +#define CA_CI_LINK 2 /* CI link layer level interface */ +#define CA_CI_PHYS 4 /* CI physical layer level interface */ +#define CA_SC 128 /* simple smart card interface */ + + unsigned int flags; +#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ +#define CA_CI_MODULE_READY 2 +} ca_slot_info_t; +\end{verbatim} + +\devsubsubsec{ca\_descr\_info\_t} +\label{cadescrinfo} + +\begin{verbatim} +typedef struct ca_descr_info_s { + unsigned int num; /* number of available descramblers (keys) */ + unsigned int type; /* type of supported scrambling system */ +#define CA_ECD 1 +#define CA_NDS 2 +#define CA_DSS 4 +} ca_descr_info_t; +\end{verbatim} + +\devsubsubsec{ca\_cap\_t} +\label{cacap} + +\begin{verbatim} +typedef struct ca_cap_s { + unsigned int slot_num; /* total number of CA card and module slots */ + unsigned int slot_type; /* OR of all supported types */ + unsigned int descr_num; /* total number of descrambler slots (keys) */ + unsigned int descr_type;/* OR of all supported types */ +} ca_cap_t; +\end{verbatim} + + +\devsubsubsec{ca\_msg\_t} +\label{camsg} + +\begin{verbatim} +/* a message to/from a CI-CAM */ +typedef struct ca_msg_s { + unsigned int index; + unsigned int type; + unsigned int length; + unsigned char msg[256]; +} ca_msg_t; +\end{verbatim} + + +\devsubsubsec{ca\_descr\_t} +\label{cadescr} + +\begin{verbatim} +typedef struct ca_descr_s { + unsigned int index; + unsigned int parity; + unsigned char cw[8]; +} ca_descr_t; +\end{verbatim} + +\clearpage + +\devsubsec{CA Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named ca device (e.g. /dev/ost/ca) + for subsequent use. + + When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in + the documentation for functions where there is a difference. + It does not affect the semantics of the open() call itself. + A device opened in blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system + call. + This is a standard system call, documented in the Linux manual + page for fcntl. + Only one user can open the CA Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error code will be returned. + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/cimlogo.psi b/dvb-spec/dvbapi/cimlogo.psi new file mode 100644 index 000000000..b7b089a49 --- /dev/null +++ b/dvb-spec/dvbapi/cimlogo.psi @@ -0,0 +1,122 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: /home/rjkm/dvbapi/cimlogo.ps +%%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley +%%BoundingBox: 275 411 309 440 +%%Pages: 1 +%%DocumentFonts: +%%EndComments +%%EndProlog + +%%Page: 1 1 + +% remember original state +/origstate save def + +% build a temporary dictionary +20 dict begin + +% define string to hold a scanline's worth of data +/pix 45 string def + +% define space for color conversions +/grays 45 string def % space for gray scale line +/npixls 0 def +/rgbindx 0 def + +% lower left corner +275 411 translate + +% size of image (on paper, in 1/72inch coords) +33.76800 28.51200 scale + +45 38 8 % dimensions of data +[45 0 0 -38 0 38] % mapping matrix +{currentfile pix readhexstring pop} +image + +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffff00ffffffffffff0000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffff0000000000ffffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffff0000000000000000ffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffff0000000000000000ffffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffff +ffffffffffffffffff +ffffffffffff0000000000000000ffffffffff000000000000ffffff00000000ffffffff +ffffffffffffffffff +ffffffffff00000000000000ffffffffffffff0000000000ffffff0000000000ffffffff +ffffffffffffffffff +ffffffffff000000000000ffffffffffffff000000000000ffffff000000000000ffffff +ffffffffffffffffff +ffffffff00000000000000ffffffffffffff000000000000ffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffff000000000000ffffffff000000000000ffff +ffffffffffffffffff +ffffffff0000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff +ffffffffffffffffff +ffffff000000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff +ffffffffffffffffff +ffffff0000000000ffffffffffffffffff000000000000ffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffffff0000000000ffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff000000000000ffffffffffffffff0000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff000000000000ffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff0000000000ffffffffffffffffff0000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffff000000000000ffffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffff000000000000ffffffffffffffff0000000000ffff +ffffffffffffffffff +ffffff000000000000ffffffffffffff00000000ffffffffffffffffff0000000000ffff +ffffffffffffffffff +ffffffff0000000000ffffffffffffffff0000ffffffffffffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffffffffffffffffffffff000000000000ffffff +ffffffffffffffffff +ffffffffff00000000000000ffffffffffffffffffffffffffff000000000000ffffffff +ff0000000000ffffff +ffffffffff0000000000000000ffffffffffffffffffffffff00000000000000ffffffff +00000000000000ffff +ffffffffffff000000000000000000ffffffffffffffff0000000000000000ffffffffff +00000000000000ffff +ffffffffffffff0000000000000000000000000000000000000000000000ffffffffffff +0000000000000000ff +ffffffffffffffff000000000000000000000000000000000000000000ffffffffffffff +00000000000000ffff +ffffffffffffffffffff0000000000000000000000000000000000ffffffffffffffffff +00000000000000ffff +ffffffffffffffffffffffff00000000000000000000000000ffffffffffffffffffffff +ff0000000000ffffff +ffffffffffffffffffffffffffffff00ff0000000000ffffffffffffffffffffffffffff +ffffff0000ffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff + +showpage + +% stop using temporary dictionary +end + +% restore original state +origstate restore + +%%Trailer diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex new file mode 100644 index 000000000..541ee633a --- /dev/null +++ b/dvb-spec/dvbapi/demux.tex @@ -0,0 +1,392 @@ +\devsec{DVB Demux Device} + +The DVB demux device controls the filters of the DVB hardware/software. +It can be accessed through \texttt{/dev/ost/demux}. + +\devsubsec{Demux Data Types} + +\begin{verbatim} +typedef uint16_t dvb_pid_t; +\end{verbatim} + + +\devsubsubsec{dmxOutput\_t} +\label{dmxoutput} + +\begin{verbatim} +typedef enum +{ + DMX_OUT_DECODER, + DMX_OUT_TAP, + DMX_OUT_TS_TAP +} dmxOutput_t; +\end{verbatim} +/* Output multiplexed into a new TS */ +/* (to be retrieved by reading from the */ +/* logical DVR device). */ + + +\devsubsubsec{dmxInput\_t} +\label{dmxinput} + +\begin{verbatim} +typedef enum +{ + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ +} dmxInput_t; +\end{verbatim} + + +\devsubsubsec{dmxPesType\_t} +\label{dmxpestype} + +\begin{verbatim} +typedef enum +{ + DMX_PES_AUDIO, + DMX_PES_VIDEO, + DMX_PES_TELETEXT, + DMX_PES_SUBTITLE, + DMX_PES_PCR, + DMX_PES_OTHER +} dmxPesType_t; +\end{verbatim} + + +\devsubsubsec{dmxEvent\_t} +\label{dmxeventt} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_EV, + DMX_FRONTEND_EV +} dmxEvent_t; +\end{verbatim} + + +\devsubsubsec{dmxScramblingStatus\_t} +\label{dmxscramblingstatus} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_OFF, + DMX_SCRAMBLING_ON +} dmxScramblingStatus_t; +\end{verbatim} + + +\devsubsubsec{dmxFilter\_t} +\label{dmxfilter} + +\begin{verbatim} +typedef struct dmxFilter +{ + uint8_t filter[DMX_FILTER_SIZE]; + uint8_t mask[DMX_FILTER_SIZE]; +} dmxFilter_t; +\end{verbatim} + + +\devsubsubsec{dmxSctFilterParams} +\label{dmxsctfilterparams} + +\begin{verbatim} +struct dmxSctFilterParams +{ + dvb_pid_t pid; + dmxFilter_t filter; + uint32_t timeout; + uint32_t flags; +#define DMX_CHECK_CRC 1 +#define DMX_ONESHOT 2 +#define DMX_IMMEDIATE_START 4 +}; +\end{verbatim} + + +\devsubsubsec{dmxPesFilterParams} +\label{dmxpesfilterparams} + +\begin{verbatim} +struct dmxPesFilterParams +{ + dvb_pid_t pid; + dmxInput_t input; + dmxOutput_t output; + dmxPesType_t pesType; + uint32_t flags; +}; +\end{verbatim} + + +\devsubsubsec{dmxEvent} +\label{dmxevent} + +\begin{verbatim} +struct dmxEvent +{ + dmxEvent_t event; + time_t timeStamp; + union + { + dmxScramblingStatus_t scrambling; + } u; +}; +\end{verbatim} + +\clearpage + +\devsubsec{Demux Function Calls} +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call, used with a device name of /dev/ost/demuxn, where n + denotes the specific demux device to be opened, allocates a new filter + and returns a handle which can be used for subsequent control of that + filter. This call has to be made for each filter to be used, i.e. every + returned file descriptor is a reference to a single filter. + /dev/ost/dvrn is a logical device to be used for retrieving Transport + Streams for digital video recording. n identifies the physical demux + device that provides the actual DVR functionality. When reading from + this device a transport stream containing the packets from all PES + filters set in the corresponding demux device (/dev/ost/demuxn) + having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream + is replayed by writing to this device. +% This device can only be opened in read-write mode. + + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not + affect the semantics of the open() call itself. A device opened in + blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system call. + }{ + const char *deviceName & Name of demux device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINVAL & Invalid argument.\\ + EMFILE & ``Too many open files'', i.e. no more filters available.\\ + ENOMEM & The driver failed to allocate enough memory.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call deactivates and deallocates a filter that was previously + allocated via the open() call. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{read()}{ + size\_t read(int fd, void *buf, size\_t count); + }{ + This system call returns filtered data, which might be section or PES + data. The filtered data is transferred from the driver's internal circular + buffer to buf. The maximum amount of data to be transferred is implied by + count.\\ + When returning section data the driver always tries to return a complete + single section (even though buf would provide buffer space for more data). + If the size of the buffer is smaller than the section as much as possible + will be returned, and the remaining data will be provided in subsequent + calls.\\ + The size of the internal buffer is 2 * 4096 bytes (the size of two maximum + sized sections) by default. The size of this buffer may be changed by + using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough, + or if the read operations are not performed fast enough, this may result + in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, + and the circular buffer will be emptied. + This call is blocking if there is no data to return, i.e. the process + will be put to sleep waiting for data, unless the O\_NONBLOCK flag is + specified.\\ + Note that in order to be able to read, the filtering process has to be + started by defining either a section or a PES filter by means of the + ioctl functions, and then starting the filtering process via the DMX\_START + ioctl function or by setting the DMX\_IMMEDIATE\_START flag. + If the reading is done from a logical DVR demux device, the data will + constitute a Transport Stream including the packets from all PES filters + in the corresponding demux device /dev/ost/demuxn having the output set + to DMX\_OUT\_TS\_TAP. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer to be used for returned filtered data.\\ + size\_t count & Size of buf.\\ + }{ + EWOULDBLOCK & No data to return and O\_NONBLOCK was specified.\\ + EBADF & fd is not a valid open file descriptor.\\ + ECRC & Last section had a CRC error - no data returned. + The buffer is flushed.\\ + EBUFFEROVERFLOW & \\ +& The filtered data was not read from the buffer in + due time, resulting in non-read data being lost. + The buffer is flushed.\\ + ETIMEDOUT & The section was not loaded within the stated + timeout period. See ioctl DMX\_SET\_FILTER for + how to set a timeout.\\ + EFAULT & The driver failed to write to the callers buffer + due to an invalid *buf pointer.\\ +} + +\function{write()}{ + ssize\_t write(int fd, const void *buf, size\_t count); + }{ + This system call is only provided by the logical device /dev/ost/dvrn, + where n identifies the physical demux device that provides the actual + DVR functionality. It is used for replay of a digitally recorded + Transport Stream. Matching filters have to be defined in the + corresponding physical demux device, /dev/ost/demuxn. + The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the Transport Stream.\\ + size\_t count & Size of buf.\\ + }{ + EWOULDBLOCK & No data was written. This might happen if + O\_NONBLOCK was specified and there is no more + buffer space available (if O\_NONBLOCK is not + specified the function will block until buffer + space is available).\\ + EBUSY & This error code indicates that there are + conflicting requests. The corresponding demux + device is setup to receive data from the front- + end. Make sure that these filters are stopped + and that the filters with input set to DMX\_IN\_DVR + are started.\\ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{DMX\_START}{ + int ioctl( int fd, int request = DMX\_START); + }{ + This ioctl call is used to start the actual filtering operation + defined via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_START for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument, i.e. no filtering parameters + provided via the DMX\_SET\_FILTER or + DMX\_SET\_PES\_FILTER functions.\\ + EBUSY & This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter.\\ +} + +\ifunction{DMX\_STOP}{ + int ioctl( int fd, int request = DMX\_STOP); + }{ + This ioctl call is used to stop the actual filtering operation defined + via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER and started via + the DMX\_START command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_STOP for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ +} + +\ifunction{DMX\_SET\_FILTER}{ + int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmxSctFilterParams *params); + }{ + This ioctl call sets up a filter according to the filter and mask + parameters provided. A timeout may be defined stating number of seconds + to wait for a section to be loaded. A value of 0 means that no timeout + should be applied. Finally there is a flag field where it is possible to + state whether a section should be CRC-checked, whether the filter should + be a "one-shot" filter, i.e. if the filtering operation should be stopped + after the first section is received, and whether the filtering operation + should be started immediately (without waiting for a DMX\_START ioctl call). + If a filter was previously set-up, this filter will be canceled, and the + receive buffer will be flushed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_FILTER for this command.\\ + struct dmxSctFilterParams *params + & Pointer to structure containing filter parameters.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument.\\ +} + +\ifunction{DMX\_SET\_PES\_FILTER}{ + int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, + struct dmxPesFilterParams *params); + }{ + This ioctl call sets up a PES filter according to the parameters provided. + By a PES filter is meant a filter that is based just on the packet + identifier (PID), i.e. no PES header or payload filtering capability is + supported.\\ + The transport stream destination for the filtered output may be set. Also + the PES type may be stated in order to be able to e.g. direct a video + stream directly to the video decoder. Finally there is a flag field where + it is possible to state whether the filtering operation should be started + immediately (without waiting for a DMX\_START ioctl call). + If a filter was previously set-up, this filter will be cancelled, and the + receive buffer will be flushed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ + struct dmxPesFilterParams *params + & Pointer to structure containing filter parameters.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument.\\ + EBUSY & This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter.\\ +} + +\ifunction{DMX\_SET\_BUFFER\_SIZE}{ + int ioctl( int fd, int request = DMX\_SET\_BUFFER\_SIZE, unsigned long size); + }{ + This ioctl call is used to set the size of the circular buffer used + for filtered data. The default size is two maximum sized sections, i.e. + if this function is not called a buffer size of 2 * 4096 bytes will be + used. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_BUFFER\_SIZE for this command.\\ + unsigned long size & Size of circular buffer.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + ENOMEM & The driver was not able to allocate a buffer of the requested size.\\ +} + +\ifunction{DMX\_GET\_EVENT}{ + int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmxEvent *ev); + }{ + This ioctl call returns an event if available. If an event is not + available, the behavior depends on whether the device is in blocking or + non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available.\\ + The standard Linux poll() and/or select() system calls can be used with + the device file descriptor to watch for new events. For select(), the + file descriptor should be included in the exceptfds argument, and for + poll(), POLLPRI should be specified as the wake-up condition. + Only the latest event for each filter is saved. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_GET\_EVENT for this command.\\ + struct dmxEvent *ev & Pointer to the location where the event is to be stored.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & ev points to an invalid address.\\ + EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex new file mode 100644 index 000000000..9c561e853 --- /dev/null +++ b/dvb-spec/dvbapi/devices.tex @@ -0,0 +1,12 @@ +\input{video.tex} +\input{audio.tex} +\input{frontend.tex} +\input{sec.tex} +\input{demux.tex} +\input{ca.tex} +\input{kdapi.tex} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex new file mode 100644 index 000000000..f9fcb841c --- /dev/null +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -0,0 +1,166 @@ +\documentclass[10pt]{book} +\usepackage[dvips,colorlinks=true]{hyperref} + +\usepackage{times} + +%\usepackage[hang]{caption} +\usepackage{fancyheadings} +%\usepackage{lucidabr} +%\usepackage{fancybox} +\usepackage{array} +\usepackage{graphicx} +%\usepackage{latexsym} +%\usepackage{pstricks,pst-node,pst-tree} +%\usepackage{verbatim} +%\usepackage{rotating} +%\usepackage{pdftex} +%\usepackage{color} +%\usepackage{subfigure} +%\usepackage{wrapfig} + +\newcommand{\devsec}[1]{\chapter{#1}} +\newcommand{\devsubsec}[1]{\section{#1}} +\newcommand{\devsubsubsec}[1]{\subsection{#1}} +\newcommand{\function}[5]{ + \subsection{#1} + + \noindent DESCRIPTION + \medskip + + \begin{tabular}[h]{p{11cm}} + #3 + \end{tabular} + + \medskip + \noindent SYNOPSIS + \medskip + + \begin{tabular}[h]{p{11cm}} + {\tt #2} + \end{tabular} + + %\item[] +\medskip +\noindent PARAMETERS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #4 + \end{tabular} + + %\item[] +\medskip +\noindent ERRORS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #5 + \end{tabular} + + %\end{itemize} + +\medskip +} +\def\ifunction#1#2#3#4#5{\function{#1\index{#1}}{#2}{#3}{#4}{#5}} + +\newcommand{\kfunction}[5]{ + \subsection{#1} + \noindent DESCRIPTION + \medskip + + \begin{tabular}[h]{p{11cm}} + #3 + \end{tabular} + + \medskip + \noindent SYNOPSIS + \medskip + + \begin{tabular}[h]{p{11cm}} + {\tt #2} + \end{tabular} + + %\item[] +\medskip +\noindent PARAMETERS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #4 + \end{tabular} + + %\item[] +\medskip +\noindent RETURNS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #5 + \end{tabular} + + %\end{itemize} + +\medskip +} +\def\kifunction#1#2#3#4#5{\kfunction{#1\index{#1}}{#2}{#3}{#4}{#5}} + + +%\usepackage{index} +%\makeindex + + +\begin{document} + +\input{title.tex} + +\cleardoublepage + +\pagenumbering{roman} +\pagestyle{fancyplain} + + +\tableofcontents +%\listoffigures +%\listoftables + +\cleardoublepage + +\pagenumbering{arabic} + +\renewcommand{\chaptermark}[1]{\markboth{\uppercase{#1}}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} +\lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} +\rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} +\cfoot{\copyright 2001 convergence integrated media GmbH} + +\input{intro.tex} + +\input{devices.tex} + +\input{examples.tex} + +\cleardoublepage + +\appendix + +\cleardoublepage + +\thispagestyle{plain}\chaptermark{Bibliography} +\addcontentsline{toc}{chapter}{Bibliography} +\bibliographystyle{bibsec} +\bibliography{main} + +\cleardoublepage + +\thispagestyle{plain}\chaptermark{Subject Index} +\addcontentsline{toc}{chapter}{Subject Index} +%\printindex + +\cleardoublepage + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/dvb-spec/dvbapi/dvbstb.fig b/dvb-spec/dvbapi/dvbstb.fig new file mode 100644 index 000000000..0a6bbadc3 --- /dev/null +++ b/dvb-spec/dvbapi/dvbstb.fig @@ -0,0 +1,59 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1620 360 2520 360 2520 900 1620 900 1620 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1260 1080 1620 630 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2520 630 2880 630 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2880 360 3780 360 3780 900 2880 900 2880 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4590 900 3330 1170 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4590 900 4590 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4140 360 5040 360 5040 900 4140 900 4140 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3780 630 4140 630 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4140 1170 5040 1170 5040 1710 4140 1710 4140 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2880 1170 3780 1170 3780 1710 2880 1710 2880 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1620 1170 2520 1170 2520 1710 1620 1710 1620 1170 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1620 1440 1260 1080 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1350 225 5175 225 5175 1845 1350 1845 1350 225 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3240 1710 3960 2070 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4590 1710 3960 2070 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3510 2070 4410 2070 4410 2610 3510 2610 3510 2070 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 360 810 1260 810 1260 1350 360 1350 360 810 +4 0 0 50 0 0 12 0.0000 4 135 675 1755 675 Frontend\001 +4 0 0 50 0 0 12 0.0000 4 135 690 4275 675 Demuxer\001 +4 0 0 50 0 0 12 0.0000 4 135 450 4365 1485 Video\001 +4 0 0 50 0 0 12 0.0000 4 135 450 3105 1485 Audio\001 +4 0 0 50 0 0 12 0.0000 4 135 345 1890 1485 SEC\001 +4 0 0 50 0 0 12 0.0000 4 135 255 3195 675 CA\001 +4 0 0 50 0 0 12 0.0000 4 135 645 495 1125 Antenna\001 +4 0 0 50 0 0 12 0.0000 4 135 240 3870 2385 TV\001 diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex new file mode 100644 index 000000000..d2786a6f6 --- /dev/null +++ b/dvb-spec/dvbapi/examples.tex @@ -0,0 +1,365 @@ +\chapter{Examples} +In this section we would like to present some examples for using the DVB API. + +\section{Tuning} +We will start with a generic tuning subroutine that uses the frontend +and SEC, as well as the demux devices. The example is given for QPSK +tuners, but can easily be adjusted for QAM. + +{\small +\begin{verbatim} +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DMX "/dev/ost/demux" +#define QPSK "/dev/ost/qpskfe" +#define SEC "/dev/ost/sec" + +/* routine for checking if we have a signal */ +int has_signal(int front) +{ + feStatus stat; + + if ( front < 0 ){ + if((front = open(QPSK,O_RDWR)) < 0){ + perror("FRONTEND DEVICE: "); + return -1; + } + } + + FEReadStatus(front, &stat); + if (stat & FE_HAS_SIGNAL) + return 0; + else { + printf("Tuning failed\n"); + return -1; + } +} + +/* tune qpsk */ +/* freq: frequency of transponder */ +/* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ +/* diseqc: DiSEqC address of the used LNB */ +/* pol: Polarisation */ +/* srate: Symbol Rate */ +/* fec. FEC */ +/* lnb_lof1: local frequency of lower LNB band */ +/* lnb_lof2: local frequency of upper LNB band */ +/* lnb_slof: switch frequency of LNB */ + +int set_qpsk_channel(int freq, int vpid, int apid, int tpid, + int diseqc, int pol, int srate, int fec, int lnb_lof1, + int lnb_lof2, int lnb_slof) +{ + struct secCommand scmd; + struct secCmdSequence scmds; + struct dmxPesFilterParams pesFilterParams; + struct qpskParameters qpsk; + struct pollfd pfd[1]; + struct qpskEvent event; + int front, sec, demux1, demux2, demux3; + + /* Open all the necessary the devices */ + + if((front = open(QPSK,O_RDWR)) < 0){ + perror("FRONTEND DEVICE: "); + return -1; + } + + if((sec = open(SEC,O_RDWR)) < 0){ + perror("SEC DEVICE: "); + return -1; + } + + if ((demux1 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + + if ((demux2 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + + if ((demux3 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + + /* Set the frequency of the transponder, taking into account the + local frequencies of the LNB */ + + if (freq < lnb_slof) { + qpsk.iFrequency = (freq - lnb_lof1); + scmds.continuousTone = SEC_TONE_OFF; + } else { + qpsk.iFrequency = (freq - lnb_lof2); + scmds.continuousTone = SEC_TONE_ON; + } + + /* Set the polarity of the transponder by setting the correct + voltage on the universal LNB */ + + if (pol) scmds.voltage = SEC_VOLTAGE_18; + else scmds.voltage = SEC_VOLTAGE_13; + + /* In case we have a DiSEqC, set it to the correct address */ + + scmd.type=0; + scmd.u.diseqc.addr=0x10; + scmd.u.diseqc.cmd=0x38; + scmd.u.diseqc.numParams=1; + scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | + (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | + (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); + + scmds.miniCommand=SEC_MINI_NONE; + scmds.numCommands=1; + scmds.commands=&scmd; + + /* Send the data to the SEC device to prepare the LNB for tuning */ + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + /* Set symbol rate and FEC */ + + qpsk.SymbolRate = srate; + qpsk.FEC_inner = fec; + + /* Now send it all to the frontend device */ + if (ioctl(front, QPSK_TUNE, &qpsk) < 0){ + perror("QPSK TUNE: "); + return -1; + } + + /* poll for QPSK event to check if tuning worked */ + pfd[0].fd = front; + pfd[0].events = POLLIN; + + if (poll(pfd,1,3000)){ + if (pfd[0].revents & POLLIN){ + printf("Getting QPSK event\n"); + if ( ioctl(front, QPSK_GET_EVENT, &event) + + == -EBUFFEROVERFLOW){ + perror("qpsk get event"); + return -1; + } + printf("Received "); + switch(event.type){ + case FE_UNEXPECTED_EV: + printf("unexpected event\n"); + return -1; + case FE_FAILURE_EV: + printf("failure event\n"); + return -1; + case FE_COMPLETION_EV: + printf("completion event\n"); + } + } + } + + + /* Set the filters for video, audio and teletext demuxing */ + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_vpid"); + return -1; + } + + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_apid"); + return -1; + } + + pesFilterParams.pid = tpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_TELETEXT; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_tpid"); + return -1; + } + + /* check if we have a signal */ + return has_signal(front); +} + +\end{verbatim} +} +The program assumes that you are using a universal LNB and a standard +DiSEqC switch with up to 4 addresses. Of course, you could build in +some more checking if tuning was successful and maybe try to repeat +the tuning process. Depending on the external hardware, i.e. LNB and +DiSEqC switch, and weather conditions this may be necessary. + + +\section{The DVR device} +The following program code shows how to use the DVR device for +recording. + +{\small +\begin{verbatim} +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#define DVR "/dev/ost/dvr" +#define AUDIO "/dev/ost/audio" +#define VIDEO "/dev/ost/video" + +#define BUFFY (188*20) +#define MAX_LENGTH (1024*1024*5) /* record 5MB */ + + +/* switch the demuxes to recording, assuming the transponder is tuned */ + +/* demux1, demux2: file descriptor of video and audio filters */ +/* vpid, apid: PIDs of video and audio channels */ + +int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) +{ + struct dmxPesFilterParams pesFilterParams; + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMXdemuxs, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + return 0; +} + +/* start recording MAX_LENGTH , assuming the transponder is tuned */ + +/* demux1, demux2: file descriptor of video and audio filters */ +/* vpid, apid: PIDs of video and audio channels */ +int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) +{ + int i; + int len; + int written; + uint8_t buf[BUFFY]; + uint64_t length; + struct pollfd pfd[1]; + int dvr, dvr_out; + + /* open dvr device */ + if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ + perror("DVR DEVICE"); + return -1; + } + + /* switch video and audio demuxes to dvr */ + printf ("Switching dvr on\n"); + i = switch_to_record(demux1, demux2, vpid, apid); + printf("finished: "); + + printf("Recording %2.0f MB of test file in TS format\n", + MAX_LENGTH/(1024.0*1024.0)); + length = 0; + + /* open output file */ + if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT + |O_TRUNC, S_IRUSR|S_IWUSR + |S_IRGRP|S_IWGRP|S_IROTH| + S_IWOTH)) < 0){ + perror("Can't open file for dvr test"); + return -1; + } + + pfd[0].fd = dvr; + pfd[0].events = POLLIN; + + /* poll for dvr data and write to file */ + while (length < MAX_LENGTH ) { + if (poll(pfd,1,1)){ + if (pfd[0].revents & POLLIN){ + len = read(dvr, buf, BUFFY); + if (len < 0){ + perror("recording"); + return -1; + } + if (len > 0){ + written = 0; + while (written < len) + written += + write (dvr_out, + buf, len); + length += len; + printf("written %2.0f MB\r", + length/1024./1024.); + } + } + } + } + return 0; +} + +\end{verbatim} +} +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% TeX-master: t +%%% End: diff --git a/dvb-spec/dvbapi/fig2pstex b/dvb-spec/dvbapi/fig2pstex new file mode 100755 index 000000000..bf62eb7ec --- /dev/null +++ b/dvb-spec/dvbapi/fig2pstex @@ -0,0 +1,6 @@ +#!/bin/sh +f=`basename $1 .fig` +fig2dev -L pstex $f.fig $f.ps +fig2dev -L pstex_t -p $f.ps $f.fig $f.pst2 +./getbb $f.pst2 $f.ps > $f.pst +rm $f.pst2 \ No newline at end of file diff --git a/dvb-spec/dvbapi/getbb b/dvb-spec/dvbapi/getbb new file mode 100755 index 000000000..004714d3a --- /dev/null +++ b/dvb-spec/dvbapi/getbb @@ -0,0 +1,12 @@ +#!/bin/sh +f=`grep BoundingBox $2 | cut -d' ' -f2,3,4,5` +g=`\ +echo $2" llx=";(echo $f|cut -d' ' -f1 );\ +echo " lly=";(echo $f|cut -d' ' -f2 );\ +echo " urx=";(echo $f|cut -d' ' -f3 );\ +echo " ury=";(echo $f|cut -d' ' -f4 );\ +echo " rwi=";(echo $f|cut -d' ' -f3 );\ +echo "0" +` +h=`echo $g| sed "s/= /=/g" | sed "s/ 0/0/g"` +cat $1 | sed "s/psfile=$2/psfile=$h/" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex new file mode 100644 index 000000000..acb6b4b85 --- /dev/null +++ b/dvb-spec/dvbapi/intro.tex @@ -0,0 +1,192 @@ +\chapter{Introduction} +%\addcontentsline{toc}{part}{Introduction} +%\chaptermark{Introduction} +\section{What you need to know} +The reader of this document is required to have some knowledge in the +area of digital video broadcasting (DVB) and should be familiar with +part I of ISO/IEC 13818, i.e you should know what a +program/transport stream (PS/TS) is and what is meant by a packetized elementary +stream (PES) or an I-frame. + +It is also necessary to know how to access unix/linux devices and how +to use ioctl calls. This also includes the knowledge of C or C++. +\section{History} + +The first API for DVB cards we used at Convergence in late 1999 +was an extension of the Video4Linux API which was primarily +developed for frame grabber cards. +As such it was not really well suited to be used for DVB cards and +their new features like recording MPEG streams and filtering several +section and PES data streams at the same time. + +In early 2000, we were approached by Nokia with a proposal for a new +standard Linux DVB API. +As a commitment to the development of terminals based on open standards, +Nokia and Convergence made it available to all Linux developers and +published it on \texttt{http://www.linuxtv.org/} in September 2000. +Convergence is the maintainer of the Linux DVB API. +Together with the LinuxTV community (i.e. you, the reader of this document), +the Linux DVB API will be constantly reviewed and improved upon. +With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence +provides a first implementation of the Linux DVB API. + + +\section{Overview} + +\begin{figure}[htbp] + \begin{center} + \includegraphics{dvbstb.ps} + \caption{Components of a DVB card/STB} + \label{fig:dvbstb} + \end{center} +\end{figure} + + +A DVB PCI card or DVB set-top-box (STB) usually consists of the following +main hardware components: +\begin{itemize} +\item Frontend consisting of tuner and DVB demodulator + +Here the raw signal reaches the DVB hardware from a satellite dish or antenna +or directly from cable. The frontend down-converts and demodulates +this signal into an MPEG transport stream (TS). + +\item SEC for controlling external hardware like LNBs and antennas + +This part of the hardware can send signals back through the satellite +cable to control the polarization of the LNB, to switch between +different LNBs or even to control the movements of a dish rotor. + + +\item Conditional Access (CA) hardware like CI adapters and smartcard slots + +The complete TS is passed through the CA hardware. Programs to which +the user has access (controlled by the smart card) are decoded in real +time and re-inserted into the TS. + +\item Demultiplexer which filters the incoming DVB stream + +The demultiplexer splits the TS into its components like audio and video +streams. Besides usually several of such audio and video streams it also +contains data strams with information about the programs offered in this +or other streams of the same provider. + +\item MPEG2 audio and video decoder + +The main targets of the demultiplexer are the MPEG2 audio and video +decoders. After decoding the pass on the uncompressed audio +and video to the computer screen or (through a PAL/NTSC encoder) to +a TV set. +\end{itemize} +Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow +between those components. + +On a DVB PCI card not all of these have to be present since some +functionality can be provided by the main CPU of the PC (e.g. MPEG picture +and sound decoding) or is not needed (e.g. for data-only uses like +``internet over satellite''). +Also not every card or STB provides conditional access hardware. + +\section{Linux DVB Devices} + +The Linux DVB API lets you control these hardware components +through currently six Unix-style character devices for +video, audio, frontend, SEC, demux and CA. +The video and audio devices control the MPEG2 decoder hardware, +the frontend device the tuner and the DVB demodulator. +External hardware like DiSEqC switches and rotors can be controlled +through the SEC device. +The demux device gives you control over the PES and section filters +of the hardware. If the hardware does not support filtering these filters +can be implemented in software. +Finally, the CA device controls all the conditional access capabilities +of the hardware. It can depend on the individual security requirements +of the platform, if and how many of the CA functions are made available +to the application through this device. + +All devices can be found in the \texttt{/dev} tree under +\texttt{/dev/ost}, where OST stands for Open Standards Terminal. +The individual devices are called +\begin{itemize} +\item \texttt{/dev/ost/audio}, +\item \texttt{/dev/ost/video}, +\item \texttt{/dev/ost/qpskfe}, +\item \texttt{/dev/ost/qamfe}, +\item \texttt{/dev/ost/sec}, +\item \texttt{/dev/ost/demux}, +\item \texttt{/dev/ost/ca}, +\end{itemize} +but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of +these devices. + +%Thus, the \texttt{audio} and \texttt{video} devices directly control +%the MPEG2 decoder audio and video decoder, respectively. +%Depending on the kind of frontend present (satellite, cable or +%terrestrial), it will be controlled either through the +%\texttt{qpsk} or \texttt{qamfe} device. +%DiSEqC or other kinds of control signals can be sent to the +%antenna hardware through the \texttt{sec} device. + +If more than one card is present in the system the other cards +can be accessed through the corresponding devices with the +card's number appended. \texttt{/dev/ost/demux0} (which +is identical to \texttt{/dev/ost/demux}) would, e.g., control the +demultiplexer of the first card, while \texttt{/dev/ost/demux1} +would control the demultiplexer of the second card, and so on. + +More details about the data structures and function calls of +all the devices are described in the following chapters. + + +\section{DVB Devices with Devfs} + +Recent Linux kernel versions support a special file system called +\textsl{devfs} which is a replacement for the traditional +device directory. +With devfs a Linux DVB driver will only create those device file entries +which actually exist. +It also makes dealing with more complex DVB hardware much easier. +The device structure described above is not well suited to deal +with multiple DVB cards with more than one frontend or demultiplexer. +Consider, e.g., two DVB cards, one with two frontends and +one demultiplexer, the other with one frontend and two demultiplexers. +If we just assign them consecutive numbers, there would be a demultiplexer +and a frontend which do notbelong to the same card but have +the same number. + +With \textsl{devfs} we propose a different scheme for the device names. +The root directory for all DVB cards will be \texttt{/dev/dvb}. +Each card gets assigned a sub-directory with the name \texttt{/dev/card0}, +\texttt{/dev/card1}, etc. +The files created in these sub-directories will correspond directly to the +hardware actually present on the card. +Thus, if the first card has one QAM frontend, one demultiplexer +and otherwise no other hardware, +only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0} +will be created. +When a second DVB-S card with one frontend (including SEC) device, +two demultiplexers and an MPEG2 audio/video decoder is added, the +complete \texttt{/dev/dvb} tree will look like this: + +\begin{verbatim} +/dev/dvb/card0/qam0 + demux0 + +/dev/dvb/card1/video0 + audio0 + demux0 + demux1 + qpskfe0 + sec0 +\end{verbatim} + + +\section{Using the Devices} + +\dots + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex new file mode 100644 index 000000000..6cee25c85 --- /dev/null +++ b/dvb-spec/dvbapi/kdapi.tex @@ -0,0 +1,1007 @@ +\devsec{Kernel Demux API} + +The kernel demux API + +\devsubsec{Kernel Demux Data Types} + +\devsubsubsec{dmx\_success\_t} +\label{dmxsuccesst} + +\begin{verbatim} +typedef enum { + DMX_OK = 0, /* Received Ok */ + DMX_LENGTH_ERROR, /* Incorrect length */ + DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ + DMX_CRC_ERROR, /* Incorrect CRC */ + DMX_FRAME_ERROR, /* Frame alignment error */ + DMX_FIFO_ERROR, /* Receiver FIFO overrun */ + DMX_MISSED_ERROR /* Receiver missed packet */ +} dmx_success_t; +\end{verbatim} + + +\devsubsubsec{TS filter types} +\label{tsfiltertypes} + +\begin{verbatim} +/*--------------------------------------------------------------------------*/ +/* TS packet reception */ +/*--------------------------------------------------------------------------*/ + +/* TS filter type for set_type() */ + +#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */ +#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS + payload (<=184 bytes per packet) to callback */ +#define TS_DECODER 4 /* send stream to built-in decoder (if present) */ +\end{verbatim} + + +\devsubsubsec{dmx\_ts\_pes\_t} +\label{dmxtspest} + +The structure +/\begin{verbatim} +typedef enum +{ + DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ + DMX_TS_PES_VIDEO, /* ... */ + DMX_TS_PES_TELETEXT, + DMX_TS_PES_SUBTITLE, + DMX_TS_PES_PCR, + DMX_TS_PES_OTHER, +} dmx_ts_pes_t; +\end{verbatim} +describes the PES type for filters which write to +a built-in decoder. +The correspond (and should be kept identical) to the types in +the demux device. + +\begin{verbatim} +struct dmx_ts_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_ts_feed_s* feed, + __u16 pid, + size_t callback_length, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_ts_feed_s* feed); + int (*stop_filtering) (struct dmx_ts_feed_s* feed); + int (*set_type) (struct dmx_ts_feed_s* feed, + int type, + dmx_ts_pes_t pes_type); +}; + +typedef struct dmx_ts_feed_s dmx_ts_feed_t; +\end{verbatim} + +\begin{verbatim} +/*--------------------------------------------------------------------------*/ +/* PES packet reception (not supported yet) */ +/*--------------------------------------------------------------------------*/ + +typedef struct dmx_pes_filter_s { + struct dmx_pes_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_pes_filter_t; +\end{verbatim} + +\begin{verbatim} +typedef struct dmx_pes_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_pes_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_pes_feed_s* feed); + int (*stop_filtering) (struct dmx_pes_feed_s* feed); + int (*allocate_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t** filter); + int (*release_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t* filter); +} dmx_pes_feed_t; +\end{verbatim} + + +\begin{verbatim} +\label{sectionfilter} +typedef struct { + __u8 filter_value [DMX_MAX_FILTER_SIZE]; + __u8 filter_mask [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_section_filter_t; +\end{verbatim} + +\begin{verbatim} +struct dmx_section_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_section_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + int check_crc); + int (*allocate_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t** filter); + int (*release_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t* filter); + int (*start_filtering) (struct dmx_section_feed_s* feed); + int (*stop_filtering) (struct dmx_section_feed_s* feed); +}; +typedef struct dmx_section_feed_s dmx_section_feed_t; + +/*--------------------------------------------------------------------------*/ +/* Callback functions */ +/*--------------------------------------------------------------------------*/ + +typedef int (*dmx_ts_cb) ( __u8 * buffer1, + size_t buffer1_length, + __u8 * buffer2, + size_t buffer2_length, + dmx_ts_feed_t* source, + dmx_success_t success); + +typedef int (*dmx_section_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_section_filter_t * source, + dmx_success_t success); + +typedef int (*dmx_pes_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_pes_filter_t* source, + dmx_success_t success); + +/*--------------------------------------------------------------------------*/ +/* DVB Front-End */ +/*--------------------------------------------------------------------------*/ + +typedef enum { + DMX_OTHER_FE = 0, + DMX_SATELLITE_FE, + DMX_CABLE_FE, + DMX_TERRESTRIAL_FE, + DMX_LVDS_FE, + DMX_ASI_FE, /* DVB-ASI interface */ + DMX_MEMORY_FE +} dmx_frontend_source_t; + +typedef struct { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique front-end identifier */ + char* vendor; /* Name of the front-end vendor */ + char* model; /* Name of the front-end model */ + struct list_head connectivity_list; /* List of front-ends that can + be connected to a particular + demux */ + void* priv; /* Pointer to private data of the API client */ + dmx_frontend_source_t source; +} dmx_frontend_t; + +/*--------------------------------------------------------------------------*/ +/* MPEG-2 TS Demux */ +/*--------------------------------------------------------------------------*/ + +/* + * Flags OR'ed in the capabilites field of struct dmx_demux_s. + */ + +#define DMX_TS_FILTERING 1 +#define DMX_PES_FILTERING 2 +#define DMX_SECTION_FILTERING 4 +#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ +#define DMX_CRC_CHECKING 16 +#define DMX_TS_DESCRAMBLING 32 +#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 +#define DMX_MAC_ADDRESS_DESCRAMBLING 128 +\end{verbatim} + +\devsubsubsec{demux\_demux\_t} +\label{demuxdemuxt} + +\begin{verbatim} +/* + * DMX_FE_ENTRY(): Casts elements in the list of registered + * front-ends from the generic type struct list_head + * to the type * dmx_frontend_t + *. +*/ + +#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) + +struct dmx_demux_s { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique demux identifier */ + char* vendor; /* Name of the demux vendor */ + char* model; /* Name of the demux model */ + __u32 capabilities; /* Bitfield of capability flags */ + dmx_frontend_t* frontend; /* Front-end connected to the demux */ + struct list_head reg_list; /* List of registered demuxes */ + void* priv; /* Pointer to private data of the API client */ + int users; /* Number of users */ + int (*open) (struct dmx_demux_s* demux); + int (*close) (struct dmx_demux_s* demux); + int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); + int (*allocate_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t** feed, + dmx_ts_cb callback); + int (*release_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t* feed); + int (*allocate_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t** feed, + dmx_pes_cb callback); + int (*release_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t* feed); + int (*allocate_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t** feed, + dmx_section_cb callback); + int (*release_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t* feed); + int (*descramble_mac_address) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, + size_t buffer2_length, + __u16 pid); + int (*descramble_section_payload) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, size_t buffer2_length, + __u16 pid); + int (*add_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*remove_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + struct list_head* (*get_frontends) (struct dmx_demux_s* demux); + int (*connect_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*disconnect_frontend) (struct dmx_demux_s* demux); + + + /* added because js cannot keep track of these himself */ + int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids); +}; +typedef struct dmx_demux_s dmx_demux_t; +\end{verbatim} + + +\devsubsubsec{Demux directory} +\label{demuxdir} + +\begin{verbatim} +/* + * DMX_DIR_ENTRY(): Casts elements in the list of registered + * demuxes from the generic type struct list_head* to the type dmx_demux_t + *. + */ + +#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) + +int dmx_register_demux (dmx_demux_t* demux); +int dmx_unregister_demux (dmx_demux_t* demux); +struct list_head* dmx_get_demuxes (void); +\end{verbatim} + +\clearpage + +\devsubsec{Demux Directory API} + +The demux directory is a Linux kernel-wide facility for registering and +accessing the MPEG-2 TS demuxes in the system. Run-time registering and +unregistering of demux drivers is possible using this API. + +All demux drivers in the directory implement the abstract interface dmx\_demux\_t. + +\kifunction{dmx\_register\_demux()}{ + int dmx\_register\_demux ( dmx\_demux\_t *demux ) + }{ + This function makes a demux driver interface available to the Linux kernel. + It is usually called by the init\_module() function of the kernel module that + contains the demux driver. The caller of this function is responsible for + allocating dynamic or static memory for the demux structure and for initializing + its fields before calling this function. + The memory allocated for the demux structure must not be freed before calling + dmx\_unregister\_demux(), + }{ + dmx\_demux\_t* demux & Pointer to the demux structure. + }{ + 0 & The function was completed without errors.\\ + -EEXIST & A demux with the same value of the id field + already stored in the directory.\\ + -ENOSPC & No space left in the directory. +} + +\kifunction{dmx\_unregister\_demux()}{ + int dmx\_unregister\_demux ( dmx\_demux\_t *demux ) + }{ + This function is called to indicate that the given demux interface is no longer + available. The caller of this function is responsible for freeing the memory of + the demux structure, if it was dynamically allocated before calling + dmx\_register\_demux(). + The cleanup\_module() function of the kernel module that contains the demux + driver should call this function. Note that this function fails if the demux + is currently in use, i.e., release\_demux() has not been called for the + interface. + }{ + dmx\_demux\_t* demux & Pointer to the demux structure which is to be unregistered. + }{ + 0 & The function was completed without errors.\\ + ENODEV & The specified demux is not registered in the demux directory.\\ + EBUSY & The specified demux is currently in use. +} + +\kifunction{dmx\_get\_demuxes()}{ + struct list\_head *dmx\_get\_demuxes () + }{ + Provides the caller with the list of registered demux interfaces, using the + standard list structure defined in the include file linux/list.h. + The include file demux.h defines the macro DMX\_DIR\_ENTRY() for converting an + element of the generic type struct list\_head* to the type dmx\_demux\_t*. + The caller must not free the memory of any of the elements obtained via this + function call. + }{ + none + }{ + struct list\_head * & + A list of demux interfaces, or NULL in the case of an empty list. +} + +\clearpage + +\devsubsec{Demux API} + +The demux API should be implemented for each demux in the system. It is used to +select the TS source of a demux and to manage the demux resources. When the +demux client allocates a resource via the demux API, it receives a pointer +to the API of that resource. + +Each demux receives its TS input from a DVB front-end or from memory, as +set via the demux API. In a system with more than one front-end, the API can +be used to select one of the DVB front-ends as a TS source for a demux, unless +this is fixed in the HW platform. The demux API only controls front-ends +regarding their connections with demuxes; the APIs used to set the other +front-end parameters, such as tuning, are not defined in this document. + +The functions that implement the abstract interface demux should be defined +static or module private and registered to the Demux Directory for external +access. It is not necessary to implement every function in the demux\_t struct, +however (for example, a demux interface might support Section filtering, but +not TS or PES filtering). The API client is expected to check the value of any +function pointer before calling the function: the value of NULL means ``function +not available''. + +Whenever the functions of the demux API modify shared data, the possibilities +of lost update and race condition problems should be addressed, e.g. by +protecting parts of code with mutexes. This is especially important on +multi-processor hosts. + +Note that functions called from a bottom half context must not sleep, at least +in the 2.2.x kernels. Even a simple memory allocation can result in a kernel +thread being put to sleep if swapping is needed. For example, the Linux kernel +calls the functions of a network device interface from a bottom half context. +Thus, if a demux API function is called from network device code, the function +must not sleep. + +\kfunction{open()}{ + int open ( demux\_t* demux ); + }{ + This function reserves the demux for use by the caller and, if necessary, + initializes the demux. When the demux is no longer needed, the function close() + should be called. + It should be possible for multiple clients to access the demux at the same time. + Thus, the function implementation should increment the demux usage count when + open() is called and decrement it when close() is called. + }{ + demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EUSERS & Maximum usage count reached.\\ + -EINVAL & Bad parameter. +} + +\kfunction{close()}{ + int close(demux\_t* demux); + }{ + This function reserves the demux for use by the caller and, if necessary, + initializes the demux. When the demux is no longer needed, the function close() + should be called. + It should be possible for multiple clients to access the demux at the same time. + Thus, the function implementation should increment the demux usage count when + open() is called and decrement it when close() is called. + }{ + demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -ENODEV & The demux was not in use.\\ + -EINVAL & Bad parameter. +} + +\kfunction{write()}{ + int write(demux\_t* demux, const char* buf, size\_t count); + }{ + This function provides the demux driver with a memory buffer containing TS + packets. Instead of receiving TS packets from the DVB front-end, the demux + driver software will read packets from memory. Any clients of this demux + with active TS, PES or Section filters will receive filtered data via the Demux + callback API (see 0). The function returns when all the data in the buffer has + been consumed by the demux. + Demux hardware typically cannot read TS from memory. If this is the case, + memory-based filtering has to be implemented entirely in software. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + const char* buf & Pointer to the TS data in kernel-space memory.\\ + size\_t length & Length of the TS data. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + +\kifunction{allocate\_ts\_feed()}{ + int allocate\_ts\_feed(dmx\_demux\_t* demux, + dmx\_ts\_feed\_t** feed, dmx\_ts\_cb callback); + }{ + Allocates a new TS feed, which is used to filter the TS packets carrying a + certain PID. + The TS feed normally corresponds to a hardware PID filter on the demux chip. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_ts\_feed\_t** feed & Pointer to the TS feed API and instance data.\\ + dmx\_ts\_cb callback & Pointer to the callback function for + passing received TS packet + }{ + 0 & The function was completed without errors.\\ + -EBUSY & No more TS feeds available.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + +\kifunction{release\_ts\_feed()}{ + int release\_ts\_feed(dmx\_demux\_t* demux, dmx\_ts\_feed\_t* feed); + }{ + Releases the resources allocated with allocate\_ts\_feed(). Any filtering in progress + on the TS feed should be stopped before calling this function. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{allocate\_section\_feed()}{ + int allocate\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t **feed, + dmx\_section\_cb callback); + }{ + Allocates a new section feed, i.e. a demux resource for filtering and + receiving sections. + On platforms with hardware support for section filtering, a section feed is directly + mapped to the demux HW. On other platforms, TS packets are first PID filtered in + hardware and a hardware section filter then emulated in software. + The caller obtains an API pointer of type dmx\_section\_feed\_t as an out parameter. + Using this API the caller can set filtering parameters and start receiving sections. + }{ + demux\_t *demux & Pointer to the demux API and instance data.\\ + dmx\_section\_feed\_t **feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_cb callback & Pointer to the callback function for + passing received sections. + }{ + 0 & The function was completed without errors.\\ + -EBUSY & No more section feeds available.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + + +\kifunction{release\_section\_feed()}{ + int release\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t *feed); + }{ + Releases the resources allocated with allocate\_section\_feed(), including allocated + filters. + Any filtering in progress on the section feed should be stopped before calling + this function. + }{ + demux\_t *demux & Pointer to the demux API and instance data.\\ + dmx\_section\_feed\_t *feed & Pointer to the section feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{descramble\_mac\_address()}{ + int descramble\_mac\_address(dmx\_demux\_t* demux, + \_\_u8 *buffer1, size\_t buffer1\_length, + \_\_u8 *buffer2, size\_t buffer2\_length, \_\_u16 pid); + }{ + This function runs a descrambling algorithm on the destination MAC address field of a + DVB Datagram Section, replacing the original address with its un-encrypted version. + Otherwise, the description on the function descramble\_section\_payload() applies + also to this function. + }{ + dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ + \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ + size\_t buffer1\_length & Length of the section data, including headers and CRC, + in buffer1.\\ + \_\_u8* buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a circular buffer.\\ + size\_t buffer2\_length & Length of the section data, + including headers and CRC, in buffer2.\\ + \_\_u16 pid & The PID on which the section was received. Useful for obtaining the + descrambling key, e.g. from a DVB Common Access facility. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & No descrambling facility available.\\ + -EINVAL & Bad parameter. +} + +\kifunction{descramble\_section\_payload()}{ + int descramble\_section\_payload(dmx\_demux\_t* demux, + \_\_u8 *buffer1, size\_t buffer1\_length, \_\_u8 *buffer2, size\_t + buffer2\_length, \_\_u16 pid); + }{ + This function runs a descrambling algorithm on the payload of a DVB Datagram + Section, replacing the original payload with its un-encrypted version. + The function will + be called from the demux API implementation; the API client need + not call this function directly. + Section-level scrambling algorithms are currently standardized only for DVB-RCC + (return channel over 2-directional cable TV network) systems. For all other DVB + networks, encryption schemes are likely to be proprietary to each data broadcaster. + Thus, it is expected that this function pointer will have the value of NULL + (i.e., function not available) in most demux API implementations. + Nevertheless, it should be possible + to use the function pointer as a hook for dynamically adding a ``plug-in'' + descrambling facility to a demux driver.\\ + While this function is not needed with hardware-based section descrambling, the + descramble\_section\_payload function pointer can be used to override the default + hardware-based descrambling algorithm: if the function pointer has a non-NULL value, + the corresponding function should be used instead of any descrambling hardware. + }{ + dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ + \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ + size\_t buffer1\_length & Length of the section data, including headers and CRC, in + buffer1.\\ + \_\_u8 *buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a circular buffer.\\ + size\_t buffer2\_length & Length of the section data, including headers and CRC, in + buffer2.\\ + \_\_u16 pid & The PID on which the section was received. Useful for obtaining the + descrambling key, e.g. from a DVB Common Access facility. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & No descrambling facility available.\\ + -EINVAL & Bad parameter. +} + +\kifunction{add\_frontend()}{ + int add\_frontend(dmx\_demux\_t *demux, dmx\_frontend\_t *frontend); + }{ + Registers a connectivity between a demux and a front-end, i.e., indicates that the + demux can be connected via a call to connect\_frontend() to use the given front-end + as a TS source. The client of this function has to allocate dynamic or static + memory for + the frontend structure and initialize its fields before calling this function. + This function is normally called during the driver initialization. + The caller must not free + the memory of the frontend struct before successfully calling remove\_frontend(). + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EEXIST & A front-end with the same value of the id field already registered.\\ + -EINUSE & The demux is in use.\\ + -ENOMEM & No more front-ends can be added.\\ + -EINVAL & Bad parameter. +} + +\kifunction{remove\_frontend()}{ + int remove\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); + }{ + Indicates that the given front-end, registered by a call to add\_frontend(), can no + longer be connected as a TS source by this demux. The function should be called + when a front-end driver or a demux driver is removed from the system. If the front-end + is in use, the function fails with the return value of -EBUSY. + After successfully calling this function, the caller can free the memory of + the frontend struct if it was dynamically allocated before the add\_frontend() + operation. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter.\\ + -EBUSY & The front-end is in use, i.e. a call to + connect\_frontend() has not been followed by + a call to disconnect\_frontend(). +} + +\kifunction{get\_frontends()}{ + struct list\_head* get\_frontends(dmx\_demux\_t* demux); + }{ + Provides the APIs of the front-ends that have been registered for this demux. Any of + the front-ends obtained with this call can be used as a parameter for + connect\_frontend().\\ + The include file demux.h contains the macro DMX\_FE\_ENTRY() for converting an + element of the generic type struct list\_head* to the type dmx\_frontend\_t*. + The caller must not free the memory of any of the elements obtained via this function + call. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data. + }{ + dmx\_demux\_t* & A list of front-end interfaces, or NULL in the case of an empty list. +} + + +\kifunction{connect\_frontend()}{ + int connect\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); + }{ + Connects the TS output of the front-end to the input of the demux. A demux can only + be connected to a front-end registered to the demux with the function + add\_frontend().\\ + It may or may not be possible to connect multiple demuxes to the same front-end, + depending on the capabilities of the HW platform. When not used, the front-end should + be released by calling disconnect\_frontend(). + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter.\\ + -EBUSY & The front-end is in use. +} + +\kifunction{disconnect\_frontend()}{ + int disconnect\_frontend(dmx\_demux\_t* demux); + }{ + Disconnects the demux and a front-end previously connected by a + connect\_frontend() call. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\clearpage + +\devsubsec{Demux Callback API} + +This kernel-space API comprises the callback functions that deliver filtered data to the +demux client. Unlike the other APIs, these API functions are provided by the client and +called from the demux code. + +The function pointers of this abstract interface are not packed into a structure +as in the +other demux APIs, because the callback functions are registered and used +independent of each other. As an example, it is possible for the API client to provide +several callback functions for receiving TS packets and no callbacks for PES packets +or sections. + +The functions that implement the callback API need not be re-entrant: when a demux +driver calls one of these functions, the driver is not allowed to call the +function again before the original call returns. +If a callback is triggered by a hardware interrupt, it is +recommended to use the Linux ``bottom half'' mechanism or start a tasklet instead of +making the callback function call directly from a hardware interrupt. + +\kifunction{dmx\_ts\_cb()}{ + int dmx\_ts\_cb(\_\_u8* buffer1, size\_t buffer1\_length, + \_\_u8* buffer2, size\_t buffer2\_length, + dmx\_ts\_feed\_t* source, dmx\_success\_t success); + }{ + This function, provided by the client of the demux API, is called from the + demux code. The function is only called when filtering on this TS feed has + been enabled using the start\_filtering() function. \\ + Any TS packets that match the filter settings are copied to a circular buffer. + The filtered TS packets are delivered to the client using this callback + function. The size of the circular buffer is controlled by the + circular\_buffer\_size parameter of the set() function in the TS Feed API. It is + expected that the buffer1 and buffer2 callback parameters point to addresses + within the circular buffer, but other implementations are also + possible. Note that the called party should not try to free the memory the + buffer1 and buffer2 parameters point to.\\ + When this function is called, the buffer1 parameter typically points to the + start of the first undelivered TS packet within a circular buffer. The buffer2 + buffer parameter is normally NULL, except when the received TS packets have + crossed the last address of the circular buffer and "wrapped" to the beginning + of the buffer. In the latter case the buffer1 parameter would contain an + address within the circular buffer, while the buffer2 parameter would contain + the first address of the circular buffer.\\ + The number of bytes delivered with this function (i.e. buffer1\_length + + buffer2\_length) is usually equal to the value of callback\_length parameter given + in the set() function, with one exception: if a timeout occurs before receiving + callback\_length bytes of TS data, any undelivered packets are immediately + delivered to the client by calling this function. The timeout duration is + controlled by the set() function in the TS Feed API.\\ + If a TS packet is received with errors that could not be fixed by the TS-level + forward error correction (FEC), the Transport\_error\_indicator flag of the TS + packet header should be set. The TS packet should not be discarded, as the + error can possibly be corrected by a higher layer protocol. + If the called party is slow in processing the callback, it is possible that + the circular buffer eventually fills up. If this happens, the demux driver + should discard any TS packets received while the buffer is full. The error + should be indicated to the client on the next callback by setting the success + parameter to the value of DMX\_OVERRUN\_ERROR.\\ + The type of data returned to the callback can be selected by the + new function int (*set\_type) (struct dmx\_ts\_feed\_s* feed, int type, + dmx\_ts\_pes\_t pes\_type) which is part of the dmx\_ts\_feed\_s struct + (also cf. to the include file ost/demux.h) + The type parameter decides if the raw TS packet (TS\_PACKET) or just the + payload (TS\_PACKET|TS\_PAYLOAD\_ONLY) should be returned. + If additionally the TS\_DECODER bit is set the stream will also be sent + to the hardware MPEG decoder. In this case, the second flag decides + as what kind of data the stream should be interpreted. + The possible choices are one of DMX\_TS\_PES\_AUDIO, DMX\_TS\_PES\_VIDEO, + DMX\_TS\_PES\_TELETEXT, DMX\_TS\_PES\_SUBTITLE, DMX\_TS\_PES\_PCR, or + DMX\_TS\_PES\_OTHER. + }{ + \_\_u8* buffer1 & Pointer to the start of the filtered TS packets.\\ + size\_t buffer1\_length & Length of the TS data in buffer1.\\ + \_\_u8* buffer2 & Pointer to the tail of the filtered TS packets, or NULL.\\ + size\_t buffer2\_length & Length of the TS data in buffer2.\\ + dmx\_ts\_feed\_t* source & Indicates which TS feed is the source of the callback.\\ + dmx\_success\_t success & Indicates if there was an error in TS reception. + }{ + 0 & Continue filtering.\\ + -1& Stop filtering - has the same effect as a call + to stop\_filtering() on the TS Feed API. +} + +\kifunction{dmx\_section\_cb()}{ + int dmx\_section\_cb(\_\_u8* buffer1, size\_t buffer1\_length, \_\_u8* buffer2, + size\_t buffer2\_length, dmx\_section\_filter\_t* source, + dmx\_success\_t success); + }{ + This function, provided by the client of the demux API, is called from the demux code. + The function is only called when filtering of sections has been enabled using the + function start\_filtering() of the section feed API. + When the demux driver has received a complete section that matches at least one + section filter, the client is notified via this callback function. Normally this function is + called for each received section; however, it is also possible to deliver multiple sections + with one callback, for example when the system load is high. + If an error occurs while receiving a section, this function should be called with the + corresponding error type set in the success field, whether or not there is data to + deliver. + The Section Feed implementation should maintain a circular buffer for received sections. + However, this is not necessary if the Section Feed API is implemented as a client of + the TS Feed API, because the TS Feed implementation then buffers the + received data. + The size of the circular buffer can be configured using the set() function in the + Section Feed API. If there is no room in the circular buffer when a new section is + received, the section must be discarded. If this happens, the value of the success + parameter should be DMX\_OVERRUN\_ERROR on the next callback. + }{ + \_\_u8* buffer1 & Pointer to the start of the filtered section, e.g. + within the circular buffer of the demux driver.\\ + size\_t buffer1\_length & Length of the filtered section data in buffer1, + including headers and CRC.\\ + \_\_u8* buffer2 & Pointer to the tail of the filtered section data, or + NULL. Useful to handle the wrapping of a circular + buffer.\\ + size\_t buffer2\_length & Length of the filtered section data in buffer2, + including headers and CRC.\\ + dmx\_section\_filter\_t* filter & Indicates the filter that triggered the callback.\\ + dmx\_success\_t success & Indicates if there was an error in section reception. + }{ + 0 & Continue filtering.\\ + -1& Stop filtering - has the same effect as a call + to stop\_filtering() on the Section Feed API. +} + +\clearpage + +\devsubsec{TS Feed API} + +A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this +API, the client can set the filtering properties to start/stop filtering TS packets on a +particular TS feed. The API is defined as an abstract interface of the type +dmx\_ts\_feed\_t. + +The functions that implement the interface should be defined static or module +private. The client can get the handle of a TS feed API by calling the function +allocate\_ts\_feed() in the demux API. + +\kifunction{set()}{ + int set ( dmx\_ts\_feed\_t* feed, \_\_u16 pid, size\_t callback\_length, + size\_t circular\_buffer\_size, int descramble, struct timespec timeout); + }{ + This function sets the parameters of a TS feed. + Any filtering in progress on the TS feed + must be stopped before calling this function. + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.\\ + \_\_u16 pid & PID value to filter. Only the TS packets carrying the specified PID will + be passed to the API client.\\ + size\_t callback\_length & Number of bytes to deliver with each + call to the dmx\_ts\_cb() callback + function. The value of this + parameter should be a multiple of 188.\\ + size\_t circular\_buffer\_size & Size of the circular buffer for the filtered TS packets.\\ + int descramble & If non-zero, descramble the filtered TS packets.\\ + struct timespec timeout & Maximum time to wait before + delivering received TS packets to the client. + }{ + 0 & The function was completed without errors.\\ + -ENOMEM & Not enough memory for the requested buffer size.\\ + -ENOSYS & No descrambling facility available for TS.\\ + -EINVAL & Bad parameter. +} + + +\kifunction{start\_filtering()}{ + int start\_filtering(dmx\_ts\_feed\_t* feed); + }{ + Starts filtering TS packets on this TS feed, according to its settings. + The PID value to filter can be set by the API client. + All matching TS packets are delivered asynchronously to the client, + using the callback function registered with allocate\_ts\_feed(). + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{stop\_filtering()}{ + int stop\_filtering(dmx\_ts\_feed\_t* feed); + }{ + Stops filtering TS packets on this TS feed. + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\clearpage + +\devsubsec{Section Feed API} + +A section feed is a resource consisting of a PID filter and a set of section filters. +Using this API, the client can set the properties of a section feed and to +start/stop filtering. +The API is defined as an abstract interface of the type dmx\_section\_feed\_t. +The functions that implement the interface should be defined static or module +private. The client can get the handle of a section feed API by calling the function +allocate\_section\_feed() in the demux API. + +On demux platforms that provide section filtering in hardware, the Section Feed API +implementation provides a software wrapper for the demux hardware. Other platforms +may support only PID filtering in hardware, requiring that TS packets are converted to +sections in software. In the latter case the Section Feed API implementation can be a +client of the TS Feed API. + + +\kifunction{set()}{ + int set(dmx\_section\_feed\_t* feed, \_\_u16 pid, size\_t circular\_buffer\_size, + int descramble, int check\_crc); + }{ + This function sets the parameters of a section feed. Any filtering in progress on the + section feed must be stopped before calling this function. + If descrambling is enabled, the payload\_scrambling\_control and + address\_scrambling\_control fields of received DVB datagram sections should be + observed. If either one is non-zero, the section should be descrambled either in + hardware or using the functions descramble\_mac\_address() and + descramble\_section\_payload() of the demux API. Note that according to the + MPEG-2 Systems specification, only the payloads of private sections can be + scrambled while the rest of the section data must be sent in the clear. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + \_\_u16 pid & PID value to filter; only the TS packets + carrying the specified PID will be accepted.\\ + size\_t circular\_buffer\_size & Size of the circular buffer for filtered sections.\\ + int descramble & If non-zero, descramble any sections that are scrambled.\\ + int check\_crc & If non-zero, check the CRC values of filtered sections. + }{ + 0 & The function was completed without errors.\\ + -ENOMEM & Not enough memory for the requested buffer size.\\ + -ENOSYS & No descrambling facility available for sections.\\ + -EINVAL & Bad parameters. +} + +\kifunction{allocate\_filter()}{ + int allocate\_filter(dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t** filter); + }{ + This function is used to allocate a section filter on the demux. + It should only be called when no filtering is in progress on this section feed. + If a filter cannot be allocated, the function fails with -ENOSPC. + See in section \ref{sectionfilter} for the format of the section filter. \\ + The bitfields filter\_mask and filter\_value should only be modified when no + filtering is in progress on this section feed. filter\_mask controls which bits of + filter\_value are compared with the section headers/payload. On a binary value of 1 + in filter\_mask, the corresponding bits are compared. The filter only accepts sections + that are equal to filter\_value in all the tested bit positions. Any changes to the + values of filter\_mask and filter\_value are guaranteed to take effect only when + the start\_filtering() function is called next time. The parent pointer in the struct + is initialized by the API implementation to the value of the feed parameter. The priv + pointer is not used by the API implementation, and can thus be freely utilized by the + caller of this function. Any data pointed to by the priv pointer is available to the + recipient of the dmx\_section\_cb() function call.\\ + While the maximum section filter length (DMX\_MAX\_FILTER\_SIZE) + is currently set at 16 bytes, hardware filters of that size are not + available on all platforms. Therefore, section filtering will often + take place first in hardware, followed by filtering in software for the + header bytes that were not covered by a hardware filter. + The filter\_mask field can be checked to determine how many bytes of + the section filter are actually used, and if the + hardware filter will suffice. Additionally, software-only section filters + can optionally be + allocated to clients when all hardware section filters are in use. + Note that on most demux hardware it is not possible to filter on the + section\_length field + of the section header -- thus this field is ignored, even though it is included in + filter\_value and filter\_mask fields. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_filter\_t** filter & Pointer to the allocated filter. + }{ + 0 & The function was completed without errors.\\ + -ENOSPC & No filters of given type and length available.\\ + -EINVAL & Bad parameters. +} + +\kifunction{release\_filter()}{ + int release\_filter ( dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t* filter); + }{ + This function releases all the resources of a previously allocated section filter. + The function should not be called while filtering is in progress on this section feed. + After calling this function, the caller should not try to dereference the + filter pointer. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_filter\_t* filter & I/O Pointer to the instance data of a section filter. + }{ + 0 & The function was completed without errors.\\ + -ENODEV & No such filter allocated.\\ + -EINVAL & Bad parameter. +} + +\kifunction{start\_filtering()}{ + int start\_filtering ( dmx\_section\_feed\_t* feed ); + }{ + Starts filtering sections on this section feed, according to its settings. + Sections are first filtered based on their PID and then matched with the + section filters allocated for this feed. + If the section matches the PID filter and at least one section filter, it is delivered + to the API client. The section is delivered asynchronously using the callback function + registered with allocate\_section\_feed(). + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{stop\_filtering()}{ + int stop\_filtering ( dmx\_section\_feed\_t* feed ); + }{ + Stops filtering sections on this section feed. Note that any changes to the + filtering parameters (filter\_value, filter\_mask, etc.) should only be made + when filtering is stopped. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex new file mode 100644 index 000000000..6ccd89481 --- /dev/null +++ b/dvb-spec/dvbapi/sec.tex @@ -0,0 +1,282 @@ +\devsec{DVB SEC API} + +The DVB SEC device controls the Satellite Equipment Control of +the DVB hardware, i.e. DiSEqC and V-SEC. +It is accessed through \texttt{/dev/ost/sec}. + +\devsubsec{SEC Data Types} + +\devsubsubsec{secDiseqcCmd} +\label{secdiseqccmd} + +\begin{verbatim} +struct secDiseqcCmd { + uint8_t addr; + uint8_t cmd; + uint8_t numParams; + uint8_t params[SEC_MAX_DISEQC_PARAMS]; +}; +\end{verbatim} + + +\devsubsubsec{secVoltage} +\label{secvoltage} + +\begin{verbatim} +typedef uint32_t secVoltage; +\end{verbatim} +\begin{verbatim} +enum { + SEC_VOLTAGE_OFF, + SEC_VOLTAGE_LT, + SEC_VOLTAGE_13, + SEC_VOLTAGE_13_5, + SEC_VOLTAGE_18, + SEC_VOLTAGE_18_5 +}; +\end{verbatim} + + +\devsubsubsec{secToneMode} +\label{sectonemode} + +\begin{verbatim} +typedef uint32_t secToneMode; +\end{verbatim} +\begin{verbatim} +typedef enum { + SEC_TONE_ON, + SEC_TONE_OFF +} secToneMode_t; +\end{verbatim} + + +\devsubsubsec{secMiniCmd} +\label{secminicmd} + +\begin{verbatim} +typedef uint32_t secMiniCmd; +\end{verbatim} +\begin{verbatim} +typedef enum { + SEC_MINI_NONE, + SEC_MINI_A, + SEC_MINI_B +} secMiniCmd_t; +\end{verbatim} +\begin{verbatim} +struct secStatus { + int32_t busMode; + secVoltage selVolt; + secToneMode contTone; +}; +\end{verbatim} + +\begin{verbatim} +enum { + SEC_BUS_IDLE, + SEC_BUS_BUSY, + SEC_BUS_OFF, + SEC_BUS_OVERLOAD +}; +\end{verbatim} + + +\devsubsubsec{secCommand} +\label{seccommand} + +\begin{verbatim} +struct secCommand { + int32_t type; + union { + struct secDiseqcCmd diseqc; + uint8_t vsec; + uint32_t pause; + } u; +}; +\end{verbatim} + + +\devsubsubsec{secCmdSequence} +\label{seccmdsequence} + +\begin{verbatim} +struct secCmdSequence { + secVoltage voltage; + secMiniCmd miniCommand; + secToneMode continuousTone; + + uint32_t numCommands; + struct secCommand* commands; +}; +\end{verbatim} + +\begin{verbatim} +enum { + SEC_CMDTYPE_DISEQC, + SEC_CMDTYPE_VSEC, + SEC_CMDTYPE_PAUSE +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + SEC_DISEQC_SENT, + SEC_VSEC_SENT, + SEC_PAUSE_COMPLETE, + SEC_CALLBACK_ERROR +} secCallback_t; +\end{verbatim} + +\clearpage + +\devsubsec{SEC Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named SEC device for subsequent use. + If the device is opened in read-only mode, only status and statistics + monitoring is allowed. If the device is opened in read/write mode, all + types of operations can be performed. + Any number of applications can have simultaneous access to the device. + }{ + const char *deviceName & Name of specific SEC device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set, + open() and most other subsequent calls to the device will return -1 and + set errno to EWOULDBLOCK. + The communication with the peripheral devices is sequential by nature, + so it is probably preferable to use the device in synchronous mode. + This is the motivation for not going through the extra effort of + implementing asynchronous operation of the device. + }{ + ENODEV & Device driver not loaded/available.\\ + EFAULT & deviceName does not refer to a valid memory area.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened SEC device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{SEC\_GET\_STATUS}{ + int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{ + This call gets the status of the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_GET\_STATUS for this command.\\ + struct secStatus* status & The status of the device.\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EFAULT & status is an invalid pointer.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ + EPERM & File not opened with read permissions.\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{SEC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{ + If the bus has been automatically powered off due to power overload, this + ioctl call restores the power to the bus. The call requires read/write + access to the device. + This call has no effect if the device is manually powered off. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_RESET\_OVERLOAD for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{SEC\_RESET\_OVERLOAD}{ +int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); +}{ +This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC +commands. The first version of the SEC device does not support V-SEC +signaling and it aborts the operation with an error code if a V-SEC +command is detected in the input data.\\ +\begin{itemize} +\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is +overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be +called and the operation can be retried. +\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE, +the bus voltage will be switched and the continuous 22kHz tone +generation enabled/disabled immediately. +\end{itemize}\\ +This operation is atomic. If several processes calls this ioctl +simultaneously, the operations will be serialized so a complete sequence +is sent at a time. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_SEND\_SEQUENCE for this command.\\ + struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ + EBUSMODE & The device is not prepared for transmission + (e.g. it might be manually powered off).\\ + EBUSOVERLOAD & Bus overload has occurred.\\ +} + + +\ifunction{SEC\_SET\_TONE}{ +int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone); +}{ +This call is used to set the generation of the continuous 22kHz tone. +The possibility to just change the tone mode is already provided by +ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface. +To keep the transmission of a command sequence as +an atomic operation, SEC\_SET\_TONE will block if a transmission is in +progress. This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals SEC\_SET\_TONE for this command.\\ +secToneMode tone & The requested tone generation mode (on/off).\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{SEC\_SET\_VOLTAGE}{ +int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage); +}{ +This call is used to set the bus voltage. The possibility to just change +the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but +SEC\_SET\_VOLTAGE is an easier to use interface. +To keep the transmission of a command sequence as +an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in +progress. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals SEC\_SET\_VOLTAGE for this command.\\ +secVoltage voltage & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex new file mode 100644 index 000000000..ce8b584c1 --- /dev/null +++ b/dvb-spec/dvbapi/title.tex @@ -0,0 +1,24 @@ +\pagenumbering{arabic} +\pagestyle{empty} +\title{\huge\textbf{LINUX DVB API}} + +\author{ +\includegraphics{cimlogo.psi}\\ + Convergence integrated media GmbH\\\\ + Dr. Ralph J.K. Metzler\\ + \texttt{}\\\\ + Dr. Marcus O.C. Metzler\\ + \texttt{} +% Rosenthalerstr. 51\\ +% 10178 Berlin\\Germany +} +\date{09/15/2001\\V 0.9.4} +\maketitle + +\newpage + +%\end{titlepage} +% Local Variables: +% mode: latex +% TeX-master: "dvbapi" +% End: \ No newline at end of file diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex new file mode 100644 index 000000000..67abb9586 --- /dev/null +++ b/dvb-spec/dvbapi/video.tex @@ -0,0 +1,684 @@ +\devsec{DVB Video Device} + +The DVB video device controls the MPEG2 video decoder of the DVB hardware. +It can be accessed through \texttt{/dev/ost/video}. +The include file \texttt{ost/video.h} defines the data types and lists all I/O calls. + + +\devsubsec{Video Data Types} + +\devsubsubsec{videoFormat\_t} +\label{videoformat} + +The \texttt{videoFormat\_t} data type defined by +\begin{verbatim} +typedef enum { + VIDEO_FORMAT_4_3, + VIDEO_FORMAT_16_9 +} videoFormat_t; +\end{verbatim} +is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to +tell the driver which aspect ratio the output hardware (e.g. TV) has. +It is also used in the data structures videoStatus (\ref{videostatus}) +returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and +videoEvent (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) +which report about the display format of the current video stream. + +\devsubsubsec{videoDisplayFormat\_t} +\label{videodispformat} + +In case the display format of the video stream and of the +display hardware differ the application has to specify how to handle +the cropping of the picture. +This can be done using the VIDEO\_SET\_DISPLAY\_FORMAT call +(\ref{videosetdisplayformat}) which accepts +\begin{verbatim} +typedef enum { + VIDEO_PAN_SCAN, + VIDEO_LETTER_BOX, + VIDEO_CENTER_CUT_OUT +} videoDisplayFormat_t; +\end{verbatim} +as argument. + + +\devsubsubsec{video stream source} +\label{videostreamsource} +The video stream source is set through the VIDEO\_SELECT\_SOURCE +call and can take the following values, depending on whether we are +replaying from an internal (demuxer) or external (user write) source. +\begin{verbatim} +typedef enum { + VIDEO_SOURCE_DEMUX, + VIDEO_SOURCE_MEMORY +} videoStreamSource_t; +\end{verbatim} +VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed +either by the frontend or the DVR device) as the source of +the video stream. +If VIDEO\_SOURCE\_MEMORY is selected the stream +comes from the application through the \texttt{write()} +system call. + +\devsubsubsec{video play state} +\label{videoplaystate} +The following values can be returned by the VIDEO\_GET\_STATUS call +representing the state of video playback. +\begin{verbatim} +typedef enum { + VIDEO_STOPPED, + VIDEO_PLAYING, + VIDEO_FREEZED +} videoPlayState_t; +\end{verbatim} + + +\devsubsubsec{video event} +\label{videoevent} +The following is the structure of a video event as it is returned by +the VIDEO\_GET\_EVENT call. +\begin{verbatim} +struct videoEvent { + int32_t type; + time_t timestamp; + union { + videoFormat_t videoFormat; + } u; +}; +\end{verbatim} + +\devsubsubsec{video status} +\label{videostatus} +The VIDEO\_GET\_STATUS call returns the following structure informing +about various states of the playback operation. +\begin{verbatim} +struct videoStatus { + boolean videoBlank; + videoPlayState_t playState; + videoStreamSource_t streamSource; + videoFormat_t videoFormat; + videoDisplayFormat_t displayFormat; +}; +\end{verbatim} +If videoBlank is set video will be blanked out if the channel is changed or +if playback is stopped. Otherwise, the last picture will be displayed. +playState indicates if the video is currently frozen, stopped, or +being played back. The streamSource corresponds to the seleted source +for the video stream. It can come either from the demultiplexer or from memory. +The videoFormat indicates the aspect ratio (one of 4:3 or 16:9) +of the currently played video stream. +Finally, displayFormat corresponds to the selected cropping mode in case the +source video format is not the same as the format of the output device. + + +\devsubsubsec{video display still picture} +\label{videostill} +An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on +within the following structure. +\begin{verbatim} +/* pointer to and size of a single iframe in memory */ +struct videoDisplayStillPicture { + char *iFrame; + int32_t size; +}; +\end{verbatim} + +\devsubsubsec{video capabilities} +\label{videocaps} +A call to VIDEO\_GET\_CAPABILITIES returns an unsigned integer with +the following bits set according to the hardwares capabilities. +\begin{verbatim} +/* bit definitions for capabilities: */ +/* can the hardware decode MPEG1 and/or MPEG2? */ +#define VIDEO_CAP_MPEG1 1 +#define VIDEO_CAP_MPEG2 2 +/* can you send a system and/or program stream to video device? + (you still have to open the video and the audio device but only + send the stream to the video device) */ +#define VIDEO_CAP_SYS 4 +#define VIDEO_CAP_PROG 8 +/* can the driver also handle SPU, NAVI and CSS encoded data? + (CSS API is not present yet) */ +#define VIDEO_CAP_SPU 16 +#define VIDEO_CAP_NAVI 32 +#define VIDEO_CAP_CSS 64 +\end{verbatim} + + +\devsubsubsec{video system} +\label{videosys} +A call to VIDEO\_SET\_SYSTEM sets the desired video system for TV +output. The following system types can be set: + +\begin{verbatim} +typedef enum { + VIDEO_SYSTEM_PAL, + VIDEO_SYSTEM_NTSC, + VIDEO_SYSTEM_PALN, + VIDEO_SYSTEM_PALNc, + VIDEO_SYSTEM_PALM, + VIDEO_SYSTEM_NTSC60, + VIDEO_SYSTEM_PAL60, + VIDEO_SYSTEM_PALM60 +} videoSystem_t; +\end{verbatim} + + + +\devsubsubsec{video highlights} +\label{vhilite} +Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight +information. The call expects the following format for that information: + +\begin{verbatim} +typedef +struct videoHighlight { + boolean active; /* 1=show highlight, 0=hide highlight */ + uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ + /* 3- 0 Background pixel contrast */ + uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */ + /* 3- 0 Emphasis pixel-1 contrast */ + uint8_t color1; /* 7- 4 Pattern pixel color */ + /* 3- 0 Background pixel color */ + uint8_t color2; /* 7- 4 Emphasis pixel-2 color */ + /* 3- 0 Emphasis pixel-1 color */ + uint32_t ypos; /* 23-22 auto action mode */ + /* 21-12 start y */ + /* 9- 0 end y */ + uint32_t xpos; /* 23-22 button color number */ + /* 21-12 start x */ + /* 9- 0 end x */ +} videoHighlight_t; +\end{verbatim} + + +\devsubsubsec{video SPU} +\label{videospu} +Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, +according to the following format: +\begin{verbatim} +typedef +struct videoSPU { + boolean active; + int streamID; +} videoSPU_t; +\end{verbatim} + + +\devsubsubsec{video SPU palette} +\label{vspupal} +The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: +\begin{verbatim} +typedef +struct videoSPUPalette{ /* SPU Palette information */ + int length; + uint8_t *palette; +} videoSPUPalette_t; +\end{verbatim} + +\devsubsubsec{video NAVI pack} +\label{videonavi} +In order to get the navigational data the following structure has to +be passed to the ioctl VIDEO\_GET\_NAVI: +\begin{verbatim} +typedef +struct videoNaviPack{ + int length; /* 0 ... 1024 */ + uint8_t data[1024]; +} videoNaviPack_t; +\end{verbatim} + + +\devsubsubsec{video attributes} +\label{vattrib} +The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: +\begin{verbatim} +typedef uint16_t videoAttributes_t; +/* bits: descr. */ +/* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ +/* 13-12 TV system (0=525/60, 1=625/50) */ +/* 11-10 Aspect ratio (0=4:3, 3=16:9) */ +/* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ +/* 7 line 21-1 data present in GOP (1=yes, 0=no) */ +/* 6 line 21-2 data present in GOP (1=yes, 0=no) */ +/* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ +/* 2 source letterboxed (1=yes, 0=no) */ +/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ +\end{verbatim} + + +\clearpage + +\devsubsec{Video Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named video device (e.g. /dev/ost/video) + for subsequent use. + + When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in + the documentation for functions where there is a difference. + It does not affect the semantics of the open() call itself. + A device opened in blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system + call. + This is a standard system call, documented in the Linux manual + page for fcntl. + Only one user can open the Video Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error-code will be returned. + If the Video Device is opened in O\_RDONLY mode, the only ioctl call that can + be used is VIDEO\_GET\_STATUS. All other call will return an error code. + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened video device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{write()}{ + size\_t write(int fd, const void *buf, size\_t count);}{ + This system call can only be used if VIDEO\_SOURCE\_MEMORY is selected in the + ioctl call VIDEO\_SELECT\_SOURCE. The data provided shall be in PES + format, unless the capability allows other formats. + If O\_NONBLOCK is not specified the function will block until buffer space is + available. The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the PES data.\\ + size\_t count& Size of buf.\\ + }{ + EPERM& Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + ENOMEM& Attempted to write more data than the internal buffer can hold.\\ + EBADF& fd is not a valid open file descriptor.\\ +} + + +\ifunction{VIDEO\_STOP}{ + int ioctl(fd, int request = VIDEO\_STOP, boolean mode);}{ + This ioctl call asks the Video Device to stop playing the current stream. + Depending on the input parameter, the screen can be blanked out or + displaying the last decoded frame. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_STOP for this command. \\ +Boolean mode & Indicates how the screen shall be handled. \\ +& TRUE: Blank screen when stop. \\ +& FALSE: Show last decoded frame.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + +\ifunction{VIDEO\_PLAY}{ + int ioctl(fd, int request = VIDEO\_PLAY);}{ + This ioctl call asks the Video Device to start playing a video stream + from the selected source. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_PLAY for this command. \\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + + +\ifunction{VIDEO\_FREEZE}{ + int ioctl(fd, int request = VIDEO\_FREEZE);}{ + This ioctl call suspends the live video stream being played. + Decoding and playing are frozen. It is then possible to restart + the decoding and playing process of the video stream using the + VIDEO\_CONTINUE command. If VIDEO\_SOURCE\_MEMORY is selected in the + ioctl call VIDEO\_SELECT\_SOURCE, the DVB subsystem will not decode + any more data until the ioctl call VIDEO\_CONTINUE or VIDEO\_PLAY is + performed. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_FREEZE for this command. \\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + +\ifunction{VIDEO\_CONTINUE}{ + int ioctl(fd, int request = VIDEO\_CONTINUE);}{ + This ioctl call restarts decoding and playing processes of the video + stream which was played before a call to VIDEO\_FREEZE was made. + }{ + int fd & File descriptor returned by a previous call to open(). \\ + int request & Equals VIDEO\_CONTINUE for this command. \\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ + } + + +\ifunction{VIDEO\_SELECT\_SOURCE}{ + int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ + This ioctl call informs the video device which source shall be used + for the input data. The possible sources are demux or memory. If + memory is selected, the data is fed to the video device through + the write command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\ + videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +} + +\ifunction{VIDEO\_SET\_BLANK}{ + int ioctl(fd, int request = VIDEO\_SET\_BLANK, boolean mode);}{ + This ioctl call asks the Video Device to blank out the picture. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request& Equals VIDEO\_SET\_BLANK for this command. \\ +boolean mode&TRUE: Blank screen when stop.\\ + &FALSE: Show last decoded frame.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +EINVAL & Illegal input parameter\\ +} + +\ifunction{VIDEO\_GET\_STATUS}{ +\label{videogetstatus} + int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct videoStatus *status);}{ + This ioctl call asks the Video Device to return the current status of the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_GET\_STATUS for this command.\\ + struct videoStatus *status & Returns the current status of the Video Device.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +EFAULT & status points to invalid address\\ +} + +\ifunction{VIDEO\_GET\_EVENT}{ +\label{videogetevent} + int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct videoEvent *ev);}{ + This ioctl call returns an event of type videoEvent if available. + If an event is not available, the behavior depends on whether the device is in + blocking or non-blocking mode. In the latter case, the call fails immediately + with errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available. + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Read-only permissions are sufficient for this ioctl call. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_GET\_EVENT for this command.\\ + struct videoEvent *ev & Points to the location where the event, if any, is + to be stored.\\ +}{ +EBADF & fd is not a valid open file descriptor \\ +EFAULT & ev points to invalid address \\ +EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ +EBUFFEROVERFLOW & \\ +&Overflow in event queue - one or more events were lost.\\ +} + +\ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ +\label{videosetdisplayformat} + int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ + This ioctl call asks the Video Device to select the video format to be applied + by the MPEG chip on the video. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\ + videoDisplayFormat\_t format & Selects the video format to be used.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_STILLPICTURE}{ + int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct videoDisplayStillPicture *sp);}{ + This ioctl call asks the Video Device to display a still picture (I-frame). + The input data shall contain an I-frame. If the pointer is NULL, then the + current displayed still picture is blanked. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_STILLPICTURE for this command.\\ + struct videoDisplayStillPicture *sp& + Pointer to a location where an I-frame and size is stored.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EFAULT & sp points to an invalid iframe.\\ +} + +\ifunction{VIDEO\_FAST\_FORWARD}{ + int ioctl(fd, int request = VIDEO\_FAST\_FORWARD, int nFrames);}{ + This ioctl call asks the Video Device to skip decoding of N number of I-frames. + This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_FAST\_FORWARD for this command.\\ + int nFrames & The number of frames to skip.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_SLOWMOTION}{ + int ioctl(fd, int request = VIDEO\_SLOWMOTION, int nFrames);}{ + This ioctl call asks the video device to repeat decoding frames N + number of times. + This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SLOWMOTION for this command.\\ + int nFrames & The number of times to repeat each frame.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_GET\_CAPABILITIES}{ + int ioctl(fd, int request = VIDEO\_GET\_CAPABILITIES, unsigned int *cap);}{ + This ioctl call asks the video device about its decoding capabilities. + On success it returns and integer which has bits set according to the + defines in section \ref{videocaps}. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_GET\_CAPABILITIES for this command.\\ + unsigned int *cap & Pointer to a location where to store the + capability information.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EFAULT & cap points to an invalid iframe.\\ +} + +\ifunction{VIDEO\_SET\_ID}{ + int ioctl(int fd, int request = VIDEO\_SET\_ID, int id);}{ + This ioctl selects which sub-stream is to be decoded if a program or + system stream is sent to the video device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_ID for this command.\\ + int id& video sub-stream id + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Invalid sub-stream id. +} + +\ifunction{VIDEO\_CLEAR\_BUFFER}{ + int ioctl(fd, int request = VIDEO\_CLEAR\_BUFFER);}{ + This ioctl call clears all video buffers in the driver and + in the decoder hardware. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_CLEAR\_BUFFER for this command.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ +} + +\ifunction{VIDEO\_SET\_STREAMTYPE}{ + int ioctl(fd, int request = VIDEO\_SET\_STREAMTYPE, int type);}{ + This ioctl tells the driver which kind of stream to expect + being written to it. If this call is not used the default of video PES + is used. Some drivers might not support this call and always expect PES. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_STREAMTYPE for this command.\\ + int type & stream type\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& type is not a valid or supported stream type.\\ +} + +\ifunction{VIDEO\_SET\_FORMAT}{ +\label{videosetformat} + int ioctl(fd, int request = VIDEO\_SET\_FORMAT, videoFormat\_t format); +}{ + This ioctl sets the screen format (aspect ratio) of the connected + output device (TV) so that the output of the decoder can + be adjusted accordingly. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_FORMAT for this command.\\ + videoFormat\_t format& video format of TV as defined in section \ref{videoformat}.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& format is not a valid video format.\\ +} + +\ifunction{VIDEO\_SET\_SYSTEM}{ +\label{videosetsystem} + int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); +}{ + This ioctl sets the television output format. The format (see section + \ref{videosys}) may vary from the color format of the displayed MPEG + stream. If the hardware is not able to display the requested format + the call will return an error. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_FORMAT for this command.\\ + videoSystem\_t system& video system of TV output.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& system is not a valid or supported video system.\\ +} + +\ifunction{VIDEO\_SET\_HIGHLIGHT}{ +\label{videosethighlight} + int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,videoHighlight\_t *vhilite) +}{ + This ioctl sets the SPU highlight information for the menu access of + a DVD. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\ + videoHighlight\_t *vhilite& SPU Highlight information according to + section \ref{vhilite}.\\ +}{ + EBADF& fd is not a valid open file descriptor. \\ + EINVAL& input is not a valid highlight setting.\\ +} + + +\ifunction{VIDEO\_SET\_SPU}{ +\label{videosetspu} + int ioctl(fd, int request = VIDEO\_SET\_SPU , videoSPU\_t *spu) +}{ + This ioctl activates or deactivates SPU decoding in a DVD input + stream. It can only be used, if the driver is able to handle a DVD + stream. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_SPU for this command.\\ + videoSPU\_t *spu& SPU decoding (de)activation and subid setting + according to section \ref{videospu}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid spu setting or driver cannot handle SPU.\\ +} + + +\ifunction{VIDEO\_SET\_SPU\_PALETTE}{ +\label{videosetspupalette} + int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,videoSPUPalette\_t *palette ) +}{ + This ioctl sets the SPU color palette. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\ + videoSPUPalette\_t *palette& SPU palette according to section \ref{vspupal}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid palette or driver doesn't handle SPU.\\ +} + + + +\ifunction{VIDEO\_GET\_NAVI}{ +\label{videosetnavi} + int ioctl(fd, int request = VIDEO\_GET\_NAVI , videoNaviPack\_t *navipack) +}{ + This ioctl returns navigational information from the DVD stream. This is + especially needed if an encoded stream has to be decoded by the hardware. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_GET\_NAVI for this command.\\ + videoNaviPack\_t *navipack& PCI or DSI pack (private stream 2) + according to section \ref{videonavi}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EFAULT& driver is not able to return navigational information\\ +} + + +\ifunction{VIDEO\_SET\_ATTRIBUTES}{ +\label{videosetattributes} + int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t + vattr) +}{ + This ioctl is intended for DVD playback and allows you to set + certain information about the stream. Some hardware may not need + this information, but the call also tells the hardware to prepare + for DVD playback. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\ + videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid attribute setting.\\ +} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: -- cgit v1.2.3 From 7577c23439dfbc1d67e490d9dfa4cbd8e3b548ed Mon Sep 17 00:00:00 2001 From: rjkm Date: Sun, 16 Sep 2001 22:27:38 -0300 Subject: added new API docs --- dvb-spec/dvbapi/frontend.tex | 612 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 612 insertions(+) create mode 100644 dvb-spec/dvbapi/frontend.tex diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex new file mode 100644 index 000000000..74f21225d --- /dev/null +++ b/dvb-spec/dvbapi/frontend.tex @@ -0,0 +1,612 @@ +\devsec{DVB Frontend API} + +The DVB frontend device controls the tuner and DVB demodulator hardware. +It can be accessed through \texttt{/dev/ost/frontend}. +If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. +The frontend device will only be made visible through \texttt{devfs} +if the corresponding card actually has a frontend. Cards which support +the DVB API but, e.g., only can play back recordings, will not offer the +frontend device. + +\devsubsec{Frontend Data Types} + +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the feStatus data +type defined by +\begin{verbatim} +typedef uint32_t feStatus; +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. + +\noindent +It can take on the values +\begin{verbatim} +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define TUNER_HAS_LOCK 128 +\end{verbatim} +which can be ORed together and have the following meaning: + +\medskip + +\begin{tabular}{lp{11cm}} +FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ +FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ +FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ +FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +TUNER\_HAS\_LOCK & the tuner has a frequency lock +\end{tabular} + + +\devsubsubsec{frontend parameters} +\label{frontendparameters} + +The kind of parameters passed to the frontend device for tuning +depend on the kind of hardware you are using. +All kinds of parameters are combined as a union in the +FrontendParameters structure: +\begin{verbatim} +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; +\end{verbatim} + +For satellite QPSK frontends you have to use QPSKParameters defined by +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; +\end{verbatim} +for cable QAM frontend you use the QAMParameters structure +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + CodeRate FEC_inner; /* forward error correction (see above) */ + CodeRate FEC_outer; /* forward error correction (see above) */ + Modulation QAM; /* modulation type (see above) */ +} QAMParameters; +\end{verbatim} +DVB-T frontends are supported by the OFDMParamters structure +\begin{verbatim} +typedef struct { + BandWidth bandWidth; + CodeRate HP_CodeRate; /* high priority stream code rate */ + CodeRate LP_CodeRate; /* low priority stream code rate */ + Modulation Constellation; /* modulation type (see above) */ + TransmitMode TransmissionMode; + GuardInterval guardInterval; + Hierarchy HierarchyInformation; +} OFDMParameters; +\end{verbatim} + +In the case of QPSK frontends the Frequency field specifies the intermediate +frequency, i.e. the offset which is effectively added to the local oscillator +frequency (LOF) of the LNB. +The intermediate frequency has to be specified in units of kHz. +For QAM and OFDM frontends the Frequency specifies the absolute frequency +and is given in Hz. + +\noindent +The possible values for the FEC\_inner field are +\begin{verbatim} +enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +}; +\end{verbatim} +which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +no error correction or auto detection. + +\noindent +For cable and terrestrial frontends (QAM and OFDM) one also has to +specify the quadrature modulation mode which can be one of the following: +\begin{verbatim} +typedef enum +{ QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} QAM_TYPE; +\end{verbatim} + +Finally, there are several more parameters for OFDM: +\begin{verbatim} +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} TransmitMode; +\end{verbatim} + +\begin{verbatim} +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} BandWidth; +\end{verbatim} + +\begin{verbatim} +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} GuardInterval; +\end{verbatim} + +\begin{verbatim} +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} Hierarchy; +\end{verbatim} + + +\devsubsubsec{frontend events} +\label{frontendevents} + +\begin{verbatim} +enum { + FE_UNEXPECTED_EV, + FE_COMPLETION_EV, + FE_FAILURE_EV +}; +\end{verbatim} + +\begin{verbatim} +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + FrontendStatus previousStatus; /* status before event */ + FrontendStatus currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; +\end{verbatim} + +\begin{verbatim} +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qamRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +struct qamFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} powerState_t; +\end{verbatim} + + +\clearpage + + +\devsubsec{Frontend Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named frontend device (e.g. /dev/ost/qpskfe + for a satellite frontend or /dev/ost/qamfe for a cable frontend) + for subsequent use. + + The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end device opened in blocking mode can later be put into non-blocking + mode (and vice versa) using the F\_SETFL command of the fcntl system call. + This is a standard system call, documented in the Linux manual page for fcntl. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened front-end device. + After closing a front-end device, its corresponding hardware might be + powered down automatically, but only when this is needed to open + another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST\_SET\_POWER\_STATE ioctl. + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{OST\_SELFTEST}{ + int ioctl(int fd, int request = OST\_SELFTEST);}{ + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SELFTEST for this command.\\ + }{ + -1& Self test failure.\\ +} + +\ifunction{OST\_SET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time.\\ + A device that implements this call does not necessarily support two low-power + modes. If it only supports one low-power state, or none at all, the + OST\_SET\_POWER\_STATE operation for the missing states will + still succeed, but + it will be mapped to an existing state as per this table: \\ + \begin{center} + \begin{tabular}[h]{cll} + number of low-power & requested state & resulting state\\ + states supported &&\\ + \\ + 1 & standby & suspend \\ + 1 & suspend & suspend \\ + 0 & standby & on \\ + 0 & suspend & on + \end{tabular} + \end{center}\\ + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again.\\ + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SET\_POWER\_STATE for this command.\\ + uint32\_t state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& turn power on\\ + OST\_POWER\_STANDBY& set device in standby mode\\ + OST\_POWER\_SUSPEND& set device in suspend mode\\ + OST\_POWER\_OFF& turn power off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EPERM & Permission denied (needs read/write access).\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_GET\_POWER\_STATE for this command.\\ + uint32\_t *state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& power is on\\ + OST\_POWER\_STANDBY& device in standby mode\\ + OST\_POWER\_SUSPEND& device in suspend mode\\ + OST\_POWER\_OFF& power is off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EFAULT& state points to invalid address.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_STATUS}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_STATUS for this command.\\ + struct feStatus *status&Points to the location where the front-end + status word is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ +} + +\ifunction{FE\_READ\_BER}{ + int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_BER for this command.\\ + uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, + is stored into *ber.\\ + & Example: a value of 2500 corresponds to a bit error + rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ber points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SNR}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_SNR for this command.\\ + int32\_t *snr& The signal-to-noise ratio, as a multiple of + $10^{-6}$ dB, is stored into *snr.\\ + & Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& snr points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); +}{ +This ioctl call returns the signal strength value for the signal currently +received by the front-end. For this command, read-only access to the device +is sufficient. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ +int32\_t *strength & The signal strength value, as a multiple of + $10^{-6 }$ dBm, + is stored into *strength. \\ + &Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ + int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ + This ioctl call returns the number of uncorrected blocks detected by + the device driver during its lifetime. + For meaningful measurements, the increment in + block count during a specific time interval should be calculated. + For this command, read-only access to the device is sufficient.\\ + Note that the counter will wrap to zero after its maximum count has + been reached. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ +uint32\_t *ublocks & The total number of uncorrected blocks seen +by the driver so far. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ublocks points to invalid address.\\ + ENOSYS& Function not available for this device. +} + + +\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient.\\ + Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ + uint32\_t *freq& Input: a given frequency \\ + & Output: the frequency corresponding to + the next higher frequency setting.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& freq points to invalid address.\\ + EINVAL& Maximum supported frequency reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); + }{ + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ + uint32\_t *symbolRate& Input: a given symbol rate \\ + & Output: the symbol rate corresponding to + the next higher symbol rate.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& symbolRate points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_SET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for FE\_GET\_EVENT + and FrontendEvent.) + If a new FE\_SET\_FRONTEND operation is initiated before the previous + one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct FrontendParameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_EVENT}{ + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ + This ioctl call returns an event of type qpskEvent if available. If an event + is not available, the behavior depends on whether the device is in blocking + or non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an event + becomes available.\\ + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + usual.\\ + For the sake of implementation simplicity, this command requires read/write + access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals QPSK\_GET\_EVENT for this command.\\ + struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ev points to invalid address.\\ + EWOULDBLOCK & There is no event pending, and the device is in + non-blocking mode.\\ + EBUFFEROVERFLOW &\\ +& Overflow in event queue - one or more events were lost.\\ +} + +\ifunction{FE\_GET\_INFO}{ + int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_INFO for this command.\\ + struct qpskFrontendInfo *info & Points to the location where the front-end + information is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& info points to invalid address.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: -- cgit v1.2.3 From f1e2fc77631891bd568baff424cbe535a2795d65 Mon Sep 17 00:00:00 2001 From: rjkm Date: Wed, 19 Sep 2001 18:48:28 -0300 Subject: removed some typos --- dvb-spec/dvbapi/frontend.tex | 1 - dvb-spec/dvbapi/kdapi.tex | 4 ++-- dvb-spec/dvbapi/sec.tex | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 74f21225d..5b496c688 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -288,7 +288,6 @@ typedef enum { another front-end device. To affect an unconditional power down, it should be done explicitly using the OST\_SET\_POWER\_STATE ioctl. - This system call closes a previously opened audio device. }{ int fd & File descriptor returned by a previous call to open().\\ }{ diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex index 6cee25c85..59490299b 100644 --- a/dvb-spec/dvbapi/kdapi.tex +++ b/dvb-spec/dvbapi/kdapi.tex @@ -41,7 +41,7 @@ typedef enum { \label{dmxtspest} The structure -/\begin{verbatim} +\begin{verbatim} typedef enum { DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ @@ -109,8 +109,8 @@ typedef struct dmx_pes_feed_s { \end{verbatim} -\begin{verbatim} \label{sectionfilter} +\begin{verbatim} typedef struct { __u8 filter_value [DMX_MAX_FILTER_SIZE]; __u8 filter_mask [DMX_MAX_FILTER_SIZE]; diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex index 6ccd89481..88342c3a6 100644 --- a/dvb-spec/dvbapi/sec.tex +++ b/dvb-spec/dvbapi/sec.tex @@ -198,7 +198,7 @@ typedef enum { EINTERNAL & Internal error in the device driver.\\ } -\ifunction{SEC\_RESET\_OVERLOAD}{ +\ifunction{SEC\_SEND\_SEQUENCE}{ int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); }{ This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC -- cgit v1.2.3 From 4b03c3f1a363c428d5bf45e040073345d336ec1c Mon Sep 17 00:00:00 2001 From: rjkm Date: Fri, 21 Sep 2001 09:47:12 -0300 Subject: added inversion field --- dvb-spec/dvbapi/frontend.tex | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 5b496c688..23b9d3e22 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -26,8 +26,11 @@ It can take on the values \begin{verbatim} #define FE_HAS_POWER 1 #define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 +#define FE_SPECTRUM_INV 4 #define FE_HAS_LOCK 8 +#define FE_HAS_CARRIER 16 +#define FE_HAS_VITERBI 32 +#define FE_HAS_SYNC 64 #define TUNER_HAS_LOCK 128 \end{verbatim} which can be ORed together and have the following meaning: @@ -39,6 +42,9 @@ FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +FE\_HAS\_CARRIER & carrier detected in signal\\ +FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ +FE\_HAS\_SYNC & TS sync bytes detected \\ TUNER\_HAS\_LOCK & the tuner has a frequency lock \end{tabular} @@ -54,6 +60,7 @@ FrontendParameters structure: typedef struct { __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ /* intermediate frequency in kHz for QPSK */ + SpectralInversion Inversion; /* spectral inversion */ union { QPSKParameters qpsk; QAMParameters qam; @@ -73,8 +80,8 @@ for cable QAM frontend you use the QAMParameters structure \begin{verbatim} typedef struct { __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_inner; /* forward error correction (see above) */ CodeRate FEC_outer; /* forward error correction (see above) */ + CodeRate FEC_inner; /* forward error correction (see above) */ Modulation QAM; /* modulation type (see above) */ } QAMParameters; \end{verbatim} @@ -98,6 +105,18 @@ The intermediate frequency has to be specified in units of kHz. For QAM and OFDM frontends the Frequency specifies the absolute frequency and is given in Hz. +The Inversion field can take one of these values: +\begin{verbatim} +typedef enum { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO +} SpectralInversion; +\end{verbatim} +It indicates if spectral inversion should be presumed or not. +In the automatic setting (INVERSION_AUTO) the hardware will +try to figure out the correct setting by itself. + \noindent The possible values for the FEC\_inner field are \begin{verbatim} -- cgit v1.2.3 From bb5ef2e954dffbdc1ec75b20ead76b202365862a Mon Sep 17 00:00:00 2001 From: mocm Date: Mon, 15 Oct 2001 11:17:02 -0200 Subject: added ignore --- dvb-spec/dvbapi/.cvsignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dvb-spec/dvbapi/.cvsignore diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore new file mode 100644 index 000000000..fb6974f6b --- /dev/null +++ b/dvb-spec/dvbapi/.cvsignore @@ -0,0 +1,11 @@ +dvbapi.ps +dvbstb.ps +dvbstb.pst +dvbapi.bbl +dvbapi.aux +dvbapi.blg +dvbapi.dvi +dvbapi.log +dvbapi.pdf +dvbapi.out +dvbapi.toc -- cgit v1.2.3 From 231baf9444ac6726bec99d892d2cff2c4af32f5a Mon Sep 17 00:00:00 2001 From: mocm Date: Tue, 12 Feb 2002 14:29:24 -0200 Subject: updateupdatedd --- dvb-spec/dvbapi/frontend.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 23b9d3e22..ceb2f93db 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -114,7 +114,7 @@ typedef enum { } SpectralInversion; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (INVERSION_AUTO) the hardware will +In the automatic setting (\verb INVERSION_AUTO) the hardware will try to figure out the correct setting by itself. \noindent -- cgit v1.2.3 From d50611422c6fb579b75a45b4d36613147abb69e4 Mon Sep 17 00:00:00 2001 From: mocm Date: Thu, 14 Feb 2002 08:51:00 -0200 Subject: some updates and correctionsome updates and correctionss --- dvb-spec/dvbapi/examples.tex | 115 ++++++++++++++++++++++--------------------- dvb-spec/dvbapi/intro.tex | 9 ++-- dvb-spec/dvbapi/title.tex | 4 +- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index d2786a6f6..114579b80 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -23,30 +23,32 @@ tuners, but can easily be adjusted for QAM. #include #define DMX "/dev/ost/demux" -#define QPSK "/dev/ost/qpskfe" +#define FRONT "/dev/ost/frontend" #define SEC "/dev/ost/sec" -/* routine for checking if we have a signal */ -int has_signal(int front) +/* routine for checking if we have a signal and other status information*/ +int FEReadStatus(int fd, FrontendStatus *stat) { - feStatus stat; - - if ( front < 0 ){ - if((front = open(QPSK,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - } + int ans; - FEReadStatus(front, &stat); - if (stat & FE_HAS_SIGNAL) - return 0; - else { - printf("Tuning failed\n"); + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); return -1; } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\n"); + + return 0; } + /* tune qpsk */ /* freq: frequency of transponder */ /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ @@ -65,14 +67,15 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, struct secCommand scmd; struct secCmdSequence scmds; struct dmxPesFilterParams pesFilterParams; - struct qpskParameters qpsk; + FrontendParameters frp; struct pollfd pfd[1]; - struct qpskEvent event; - int front, sec, demux1, demux2, demux3; + FrontendEvent event; + int demux1, dmeux2, demux3, front, - /* Open all the necessary the devices */ + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; - if((front = open(QPSK,O_RDWR)) < 0){ + if((front = open(FRONT,O_RDWR)) < 0){ perror("FRONTEND DEVICE: "); return -1; } @@ -82,40 +85,41 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - if ((demux1 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - if ((demux2 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - if ((demux3 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux3 < 0){ + if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - /* Set the frequency of the transponder, taking into account the - local frequencies of the LNB */ - if (freq < lnb_slof) { - qpsk.iFrequency = (freq - lnb_lof1); + frp.Frequency = (freq - lnb_lof1); scmds.continuousTone = SEC_TONE_OFF; } else { - qpsk.iFrequency = (freq - lnb_lof2); + frp.Frequency = (freq - lnb_lof2); scmds.continuousTone = SEC_TONE_ON; } - - /* Set the polarity of the transponder by setting the correct - voltage on the universal LNB */ - + frp.Inversion = INVERSION_AUTO; if (pol) scmds.voltage = SEC_VOLTAGE_18; else scmds.voltage = SEC_VOLTAGE_13; - - /* In case we have a DiSEqC, set it to the correct address */ - + scmd.type=0; scmd.u.diseqc.addr=0x10; scmd.u.diseqc.cmd=0x38; @@ -127,32 +131,31 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, scmds.miniCommand=SEC_MINI_NONE; scmds.numCommands=1; scmds.commands=&scmd; - - /* Send the data to the SEC device to prepare the LNB for tuning */ if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ perror("SEC SEND: "); return -1; } - /* Set symbol rate and FEC */ + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } - qpsk.SymbolRate = srate; - qpsk.FEC_inner = fec; + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; - /* Now send it all to the frontend device */ - if (ioctl(front, QPSK_TUNE, &qpsk) < 0){ + if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ perror("QPSK TUNE: "); return -1; } - /* poll for QPSK event to check if tuning worked */ pfd[0].fd = front; pfd[0].events = POLLIN; if (poll(pfd,1,3000)){ if (pfd[0].revents & POLLIN){ printf("Getting QPSK event\n"); - if ( ioctl(front, QPSK_GET_EVENT, &event) + if ( ioctl(front, FE_GET_EVENT, &event) == -EBUFFEROVERFLOW){ perror("qpsk get event"); @@ -166,15 +169,14 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, case FE_FAILURE_EV: printf("failure event\n"); return -1; - case FE_COMPLETION_EV: + + case FE_COMPLETION_EV: printf("completion event\n"); } } } - /* Set the filters for video, audio and teletext demuxing */ - pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; @@ -205,8 +207,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - /* check if we have a signal */ - return has_signal(front); + return has_signal(fds); } \end{verbatim} @@ -262,7 +263,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) } if (demux2 < 0){ - if ((demux2=open(DMXdemuxs, O_RDWR|O_NONBLOCK)) + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) < 0){ perror("DEMUX DEVICE: "); return -1; diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index acb6b4b85..e026a86e1 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -110,8 +110,7 @@ The individual devices are called \begin{itemize} \item \texttt{/dev/ost/audio}, \item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/qpskfe}, -\item \texttt{/dev/ost/qamfe}, +\item \texttt{/dev/ost/frontend}, \item \texttt{/dev/ost/sec}, \item \texttt{/dev/ost/demux}, \item \texttt{/dev/ost/ca}, @@ -151,7 +150,7 @@ with multiple DVB cards with more than one frontend or demultiplexer. Consider, e.g., two DVB cards, one with two frontends and one demultiplexer, the other with one frontend and two demultiplexers. If we just assign them consecutive numbers, there would be a demultiplexer -and a frontend which do notbelong to the same card but have +and a frontend which do not belong to the same card but have the same number. With \textsl{devfs} we propose a different scheme for the device names. @@ -169,14 +168,14 @@ two demultiplexers and an MPEG2 audio/video decoder is added, the complete \texttt{/dev/dvb} tree will look like this: \begin{verbatim} -/dev/dvb/card0/qam0 +/dev/dvb/card0/frontend0 demux0 /dev/dvb/card1/video0 audio0 demux0 demux1 - qpskfe0 + frontend0 sec0 \end{verbatim} diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index ce8b584c1..574464d23 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -12,7 +12,7 @@ % Rosenthalerstr. 51\\ % 10178 Berlin\\Germany } -\date{09/15/2001\\V 0.9.4} +\date{02/14/2002\\V 0.9.4} \maketitle \newpage @@ -21,4 +21,4 @@ % Local Variables: % mode: latex % TeX-master: "dvbapi" -% End: \ No newline at end of file +% End: -- cgit v1.2.3 From 7dddc78f51709f911af1106541603949765e3c9f Mon Sep 17 00:00:00 2001 From: mocm Date: Fri, 15 Feb 2002 08:17:18 -0200 Subject: corrections to audio_set_id documentation --- dvb-spec/dvbapi/audio.tex | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 8c5b4fe82..e81dd2f89 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -354,7 +354,12 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_SET\_ID}{ int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{ This ioctl selects which sub-stream is to be decoded if a program or - system stream is sent to the video device. + system stream is sent to the video device. If no audio stream type is set + the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for + AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow + for other stream types. If the stream type is set the id just + specifies the substream id of the audio stream and only the first 5 + bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ID for this command.\\ @@ -382,7 +387,7 @@ typedef uint16_t audioAttributes_t; int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{ This ioctl tells the driver which kind of audio stream to expect. This is useful if the stream offers several audio sub-streams - like MPEG2 audio and AC3. + like LPCM and AC3. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ @@ -395,7 +400,8 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_SET\_EXT\_ID}{ int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{ - This ioctl can be used to set the audio sub\_stream\_id for DVD playback + This ioctl can be used to set the extension id for MPEG streams in + DVD playback. Only the first 3 bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ -- cgit v1.2.3 From aed2950af0b53026e245705b265059ee9a439e1f Mon Sep 17 00:00:00 2001 From: mocm Date: Mon, 4 Mar 2002 09:27:48 -0300 Subject: some error corrections --- dvb-spec/dvbapi/dvbapi.tex | 2 +- dvb-spec/dvbapi/intro.tex | 10 +--------- dvb-spec/dvbapi/video.tex | 6 ++++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index f9fcb841c..ad0251c01 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2001 convergence integrated media GmbH} +\cfoot{\copyright 2002 convergence GmbH} \input{intro.tex} diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index e026a86e1..1d859fadb 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -68,7 +68,7 @@ time and re-inserted into the TS. The demultiplexer splits the TS into its components like audio and video streams. Besides usually several of such audio and video streams it also -contains data strams with information about the programs offered in this +contains data streams with information about the programs offered in this or other streams of the same provider. \item MPEG2 audio and video decoder @@ -118,14 +118,6 @@ The individual devices are called but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of these devices. -%Thus, the \texttt{audio} and \texttt{video} devices directly control -%the MPEG2 decoder audio and video decoder, respectively. -%Depending on the kind of frontend present (satellite, cable or -%terrestrial), it will be controlled either through the -%\texttt{qpsk} or \texttt{qamfe} device. -%DiSEqC or other kinds of control signals can be sent to the -%antenna hardware through the \texttt{sec} device. - If more than one card is present in the system the other cards can be accessed through the corresponding devices with the card's number appended. \texttt{/dev/ost/demux0} (which diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 67abb9586..2659db238 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -2,8 +2,10 @@ The DVB video device controls the MPEG2 video decoder of the DVB hardware. It can be accessed through \texttt{/dev/ost/video}. -The include file \texttt{ost/video.h} defines the data types and lists all I/O calls. - +The include file \texttt{ost/video.h} defines the data types and lists +all I/O calls. Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device as well as the video4linux device. \devsubsec{Video Data Types} -- cgit v1.2.3 From a08ca2834d7a03676f72367ef3ff2a9cba3db387 Mon Sep 17 00:00:00 2001 From: rjkm Date: Wed, 6 Mar 2002 20:44:49 -0300 Subject: change include files --- dvb-spec/dvbapi/audio.tex | 12 +++-- dvb-spec/dvbapi/dvbapi.tex | 2 +- dvb-spec/dvbapi/examples.tex | 115 ++++++++++++++++++++++--------------------- dvb-spec/dvbapi/frontend.tex | 2 +- dvb-spec/dvbapi/intro.tex | 19 ++----- dvb-spec/dvbapi/title.tex | 4 +- dvb-spec/dvbapi/video.tex | 6 ++- 7 files changed, 80 insertions(+), 80 deletions(-) diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 8c5b4fe82..e81dd2f89 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -354,7 +354,12 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_SET\_ID}{ int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{ This ioctl selects which sub-stream is to be decoded if a program or - system stream is sent to the video device. + system stream is sent to the video device. If no audio stream type is set + the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for + AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow + for other stream types. If the stream type is set the id just + specifies the substream id of the audio stream and only the first 5 + bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ID for this command.\\ @@ -382,7 +387,7 @@ typedef uint16_t audioAttributes_t; int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{ This ioctl tells the driver which kind of audio stream to expect. This is useful if the stream offers several audio sub-streams - like MPEG2 audio and AC3. + like LPCM and AC3. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ @@ -395,7 +400,8 @@ typedef uint16_t audioAttributes_t; \ifunction{AUDIO\_SET\_EXT\_ID}{ int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{ - This ioctl can be used to set the audio sub\_stream\_id for DVD playback + This ioctl can be used to set the extension id for MPEG streams in + DVD playback. Only the first 3 bits are recognized. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index f9fcb841c..ad0251c01 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2001 convergence integrated media GmbH} +\cfoot{\copyright 2002 convergence GmbH} \input{intro.tex} diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index d2786a6f6..114579b80 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -23,30 +23,32 @@ tuners, but can easily be adjusted for QAM. #include #define DMX "/dev/ost/demux" -#define QPSK "/dev/ost/qpskfe" +#define FRONT "/dev/ost/frontend" #define SEC "/dev/ost/sec" -/* routine for checking if we have a signal */ -int has_signal(int front) +/* routine for checking if we have a signal and other status information*/ +int FEReadStatus(int fd, FrontendStatus *stat) { - feStatus stat; - - if ( front < 0 ){ - if((front = open(QPSK,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - } + int ans; - FEReadStatus(front, &stat); - if (stat & FE_HAS_SIGNAL) - return 0; - else { - printf("Tuning failed\n"); + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); return -1; } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\n"); + + return 0; } + /* tune qpsk */ /* freq: frequency of transponder */ /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ @@ -65,14 +67,15 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, struct secCommand scmd; struct secCmdSequence scmds; struct dmxPesFilterParams pesFilterParams; - struct qpskParameters qpsk; + FrontendParameters frp; struct pollfd pfd[1]; - struct qpskEvent event; - int front, sec, demux1, demux2, demux3; + FrontendEvent event; + int demux1, dmeux2, demux3, front, - /* Open all the necessary the devices */ + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; - if((front = open(QPSK,O_RDWR)) < 0){ + if((front = open(FRONT,O_RDWR)) < 0){ perror("FRONTEND DEVICE: "); return -1; } @@ -82,40 +85,41 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - if ((demux1 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - if ((demux2 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - if ((demux3 = open(DMX, O_RDWR|O_NONBLOCK)) < 0){ - perror("DEMUX DEVICE: "); - return -1; + if (demux3 < 0){ + if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } } - /* Set the frequency of the transponder, taking into account the - local frequencies of the LNB */ - if (freq < lnb_slof) { - qpsk.iFrequency = (freq - lnb_lof1); + frp.Frequency = (freq - lnb_lof1); scmds.continuousTone = SEC_TONE_OFF; } else { - qpsk.iFrequency = (freq - lnb_lof2); + frp.Frequency = (freq - lnb_lof2); scmds.continuousTone = SEC_TONE_ON; } - - /* Set the polarity of the transponder by setting the correct - voltage on the universal LNB */ - + frp.Inversion = INVERSION_AUTO; if (pol) scmds.voltage = SEC_VOLTAGE_18; else scmds.voltage = SEC_VOLTAGE_13; - - /* In case we have a DiSEqC, set it to the correct address */ - + scmd.type=0; scmd.u.diseqc.addr=0x10; scmd.u.diseqc.cmd=0x38; @@ -127,32 +131,31 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, scmds.miniCommand=SEC_MINI_NONE; scmds.numCommands=1; scmds.commands=&scmd; - - /* Send the data to the SEC device to prepare the LNB for tuning */ if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ perror("SEC SEND: "); return -1; } - /* Set symbol rate and FEC */ + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } - qpsk.SymbolRate = srate; - qpsk.FEC_inner = fec; + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; - /* Now send it all to the frontend device */ - if (ioctl(front, QPSK_TUNE, &qpsk) < 0){ + if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ perror("QPSK TUNE: "); return -1; } - /* poll for QPSK event to check if tuning worked */ pfd[0].fd = front; pfd[0].events = POLLIN; if (poll(pfd,1,3000)){ if (pfd[0].revents & POLLIN){ printf("Getting QPSK event\n"); - if ( ioctl(front, QPSK_GET_EVENT, &event) + if ( ioctl(front, FE_GET_EVENT, &event) == -EBUFFEROVERFLOW){ perror("qpsk get event"); @@ -166,15 +169,14 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, case FE_FAILURE_EV: printf("failure event\n"); return -1; - case FE_COMPLETION_EV: + + case FE_COMPLETION_EV: printf("completion event\n"); } } } - /* Set the filters for video, audio and teletext demuxing */ - pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; @@ -205,8 +207,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, return -1; } - /* check if we have a signal */ - return has_signal(front); + return has_signal(fds); } \end{verbatim} @@ -262,7 +263,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) } if (demux2 < 0){ - if ((demux2=open(DMXdemuxs, O_RDWR|O_NONBLOCK)) + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) < 0){ perror("DEMUX DEVICE: "); return -1; diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index 23b9d3e22..ceb2f93db 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -114,7 +114,7 @@ typedef enum { } SpectralInversion; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (INVERSION_AUTO) the hardware will +In the automatic setting (\verb INVERSION_AUTO) the hardware will try to figure out the correct setting by itself. \noindent diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index acb6b4b85..1d859fadb 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -68,7 +68,7 @@ time and re-inserted into the TS. The demultiplexer splits the TS into its components like audio and video streams. Besides usually several of such audio and video streams it also -contains data strams with information about the programs offered in this +contains data streams with information about the programs offered in this or other streams of the same provider. \item MPEG2 audio and video decoder @@ -110,8 +110,7 @@ The individual devices are called \begin{itemize} \item \texttt{/dev/ost/audio}, \item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/qpskfe}, -\item \texttt{/dev/ost/qamfe}, +\item \texttt{/dev/ost/frontend}, \item \texttt{/dev/ost/sec}, \item \texttt{/dev/ost/demux}, \item \texttt{/dev/ost/ca}, @@ -119,14 +118,6 @@ The individual devices are called but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of these devices. -%Thus, the \texttt{audio} and \texttt{video} devices directly control -%the MPEG2 decoder audio and video decoder, respectively. -%Depending on the kind of frontend present (satellite, cable or -%terrestrial), it will be controlled either through the -%\texttt{qpsk} or \texttt{qamfe} device. -%DiSEqC or other kinds of control signals can be sent to the -%antenna hardware through the \texttt{sec} device. - If more than one card is present in the system the other cards can be accessed through the corresponding devices with the card's number appended. \texttt{/dev/ost/demux0} (which @@ -151,7 +142,7 @@ with multiple DVB cards with more than one frontend or demultiplexer. Consider, e.g., two DVB cards, one with two frontends and one demultiplexer, the other with one frontend and two demultiplexers. If we just assign them consecutive numbers, there would be a demultiplexer -and a frontend which do notbelong to the same card but have +and a frontend which do not belong to the same card but have the same number. With \textsl{devfs} we propose a different scheme for the device names. @@ -169,14 +160,14 @@ two demultiplexers and an MPEG2 audio/video decoder is added, the complete \texttt{/dev/dvb} tree will look like this: \begin{verbatim} -/dev/dvb/card0/qam0 +/dev/dvb/card0/frontend0 demux0 /dev/dvb/card1/video0 audio0 demux0 demux1 - qpskfe0 + frontend0 sec0 \end{verbatim} diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index ce8b584c1..574464d23 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -12,7 +12,7 @@ % Rosenthalerstr. 51\\ % 10178 Berlin\\Germany } -\date{09/15/2001\\V 0.9.4} +\date{02/14/2002\\V 0.9.4} \maketitle \newpage @@ -21,4 +21,4 @@ % Local Variables: % mode: latex % TeX-master: "dvbapi" -% End: \ No newline at end of file +% End: diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 67abb9586..2659db238 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -2,8 +2,10 @@ The DVB video device controls the MPEG2 video decoder of the DVB hardware. It can be accessed through \texttt{/dev/ost/video}. -The include file \texttt{ost/video.h} defines the data types and lists all I/O calls. - +The include file \texttt{ost/video.h} defines the data types and lists +all I/O calls. Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device as well as the video4linux device. \devsubsec{Video Data Types} -- cgit v1.2.3 From 6fd9805ce0670bf99c73ab708daf3ca38b55fc7d Mon Sep 17 00:00:00 2001 From: js Date: Tue, 1 Oct 2002 14:28:22 -0300 Subject: released under the GNU free documentation license --- dvb-spec/dvbapi/LICENSE | 355 +++++++++++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/dvbapi.tex | 6 +- dvb-spec/dvbapi/fdl.tex | 367 +++++++++++++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/title.tex | 17 ++- 4 files changed, 739 insertions(+), 6 deletions(-) create mode 100644 dvb-spec/dvbapi/LICENSE create mode 100644 dvb-spec/dvbapi/fdl.tex diff --git a/dvb-spec/dvbapi/LICENSE b/dvb-spec/dvbapi/LICENSE new file mode 100644 index 000000000..b42936beb --- /dev/null +++ b/dvb-spec/dvbapi/LICENSE @@ -0,0 +1,355 @@ + GNU Free Documentation License + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index ad0251c01..e81940093 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2002 convergence GmbH} +\cfoot{\copyright\ 2002 Convergence GmbH} \input{intro.tex} @@ -145,6 +145,10 @@ \cleardoublepage +\input{fdl.tex} + +\cleardoublepage + \thispagestyle{plain}\chaptermark{Bibliography} \addcontentsline{toc}{chapter}{Bibliography} \bibliographystyle{bibsec} diff --git a/dvb-spec/dvbapi/fdl.tex b/dvb-spec/dvbapi/fdl.tex new file mode 100644 index 000000000..c0fcbe3f3 --- /dev/null +++ b/dvb-spec/dvbapi/fdl.tex @@ -0,0 +1,367 @@ +% fdl.tex +% This file is a chapter. It must be included in a larger document to work +% properly. + +\chapter{GNU Free Documentation License} + +Version 1.1, March 2000\\ + + Copyright \copyright\ 2000 Free Software Foundation, Inc.\\ + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\\ + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +\section*{Preamble} + +The purpose of this License is to make a manual, textbook, or other +written document ``free'' in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +\section{Applicability and Definitions} + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The ``Document'', below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as ``you''. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, \LaTeX~input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +\section{Verbatim Copying} + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +\section{Copying in Quantity} + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +\section{Modifications} + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +\begin{itemize} + +\item Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +\item List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +\item State on the Title page the name of the publisher of the + Modified Version, as the publisher. +\item Preserve all the copyright notices of the Document. +\item Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +\item Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +\item Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +\item Include an unaltered copy of this License. +\item Preserve the section entitled ``History'', and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled ``History'' in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +\item Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the ``History'' section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +\item In any section entitled ``Acknowledgements'' or ``Dedications'', + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +\item Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +\item Delete any section entitled ``Endorsements''. Such a section + may not be included in the Modified Version. +\item Do not retitle any existing section as ``Endorsements'' + or to conflict in title with any Invariant Section. + +\end{itemize} + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties -- for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +\section{Combining Documents} + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled ``History'' +in the various original documents, forming one section entitled +``History''; likewise combine any sections entitled ``Acknowledgements'', +and any sections entitled ``Dedications''. You must delete all sections +entitled ``Endorsements.'' + + +\section{Collections of Documents} + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + + +\section{Aggregation With Independent Works} + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an ``aggregate'', and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +\section{Translation} + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +\section{Termination} + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +\section{Future Revisions of This License} + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + +\section*{ADDENDUM: How to use this License for your documents} + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +\begin{quote} + + Copyright \copyright\ YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + +\end{quote} + +If you have no Invariant Sections, write ``with no Invariant Sections'' +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write ``no Front-Cover Texts'' instead of +``Front-Cover Texts being LIST''; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index 574464d23..693ed829d 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -4,17 +4,24 @@ \author{ \includegraphics{cimlogo.psi}\\ - Convergence integrated media GmbH\\\\ - Dr. Ralph J.K. Metzler\\ + Copyright \copyright 2002 Convergence GmbH\\\\ + Written by Dr. Ralph J.K. Metzler\\ \texttt{}\\\\ - Dr. Marcus O.C. Metzler\\ - \texttt{} + and Dr. Marcus O.C. Metzler\\ + \texttt{}\\ % Rosenthalerstr. 51\\ % 10178 Berlin\\Germany } -\date{02/14/2002\\V 0.9.4} +\date{10/01/2002\\V 0.9.5} + \maketitle +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation. +A copy of the license is included in the chapter entitled "GNU +Free Documentation License". + \newpage %\end{titlepage} -- cgit v1.2.3 From ab85b007da42f42856a775d8cff97332093f5b34 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 15:59:05 -0300 Subject: make room for the new HEAD trunk --- dvb-spec/README.CABLE | 5 - dvb-spec/README.EON | 7 - dvb-spec/channel | 104 ----- dvb-spec/dvbapi/.cvsignore | 11 - dvb-spec/dvbapi/Makefile | 30 -- dvb-spec/dvbapi/audio.tex | 442 ------------------ dvb-spec/dvbapi/bibsection.sty | 29 -- dvb-spec/dvbapi/ca.tex | 127 ----- dvb-spec/dvbapi/cimlogo.psi | 122 ----- dvb-spec/dvbapi/demux.tex | 392 ---------------- dvb-spec/dvbapi/devices.tex | 12 - dvb-spec/dvbapi/dvbapi.tex | 166 ------- dvb-spec/dvbapi/dvbstb.fig | 59 --- dvb-spec/dvbapi/examples.tex | 366 --------------- dvb-spec/dvbapi/fig2pstex | 6 - dvb-spec/dvbapi/frontend.tex | 630 ------------------------- dvb-spec/dvbapi/getbb | 12 - dvb-spec/dvbapi/intro.tex | 183 -------- dvb-spec/dvbapi/kdapi.tex | 1007 ---------------------------------------- dvb-spec/dvbapi/sec.tex | 282 ----------- dvb-spec/dvbapi/title.tex | 24 - dvb-spec/dvbapi/video.tex | 686 --------------------------- 22 files changed, 4702 deletions(-) delete mode 100644 dvb-spec/README.CABLE delete mode 100644 dvb-spec/README.EON delete mode 100644 dvb-spec/channel delete mode 100644 dvb-spec/dvbapi/.cvsignore delete mode 100644 dvb-spec/dvbapi/Makefile delete mode 100644 dvb-spec/dvbapi/audio.tex delete mode 100644 dvb-spec/dvbapi/bibsection.sty delete mode 100644 dvb-spec/dvbapi/ca.tex delete mode 100644 dvb-spec/dvbapi/cimlogo.psi delete mode 100644 dvb-spec/dvbapi/demux.tex delete mode 100644 dvb-spec/dvbapi/devices.tex delete mode 100644 dvb-spec/dvbapi/dvbapi.tex delete mode 100644 dvb-spec/dvbapi/dvbstb.fig delete mode 100644 dvb-spec/dvbapi/examples.tex delete mode 100755 dvb-spec/dvbapi/fig2pstex delete mode 100644 dvb-spec/dvbapi/frontend.tex delete mode 100755 dvb-spec/dvbapi/getbb delete mode 100644 dvb-spec/dvbapi/intro.tex delete mode 100644 dvb-spec/dvbapi/kdapi.tex delete mode 100644 dvb-spec/dvbapi/sec.tex delete mode 100644 dvb-spec/dvbapi/title.tex delete mode 100644 dvb-spec/dvbapi/video.tex diff --git a/dvb-spec/README.CABLE b/dvb-spec/README.CABLE deleted file mode 100644 index de13af020..000000000 --- a/dvb-spec/README.CABLE +++ /dev/null @@ -1,5 +0,0 @@ -- The analog module is not fully supported yet. - The MSP3400 module will have to be extended to handle then audio and - video switching for the module. - If you want sound you will have to remove the module for now. - diff --git a/dvb-spec/README.EON b/dvb-spec/README.EON deleted file mode 100644 index df5098132..000000000 --- a/dvb-spec/README.EON +++ /dev/null @@ -1,7 +0,0 @@ -- If you do not receive any packets over the dvb0 device the reason could - be the rp_filter. - Check if your distribution enables this or disable it with: - - "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter" - - This disables source validation by reversed path lookup. \ No newline at end of file diff --git a/dvb-spec/channel b/dvb-spec/channel deleted file mode 100644 index f17e8cb19..000000000 --- a/dvb-spec/channel +++ /dev/null @@ -1,104 +0,0 @@ -This file describes the format of the new channel config file. - -Comments start with # -Each section starts with one of the identifiers: LNB, DISEQC, ROTOR, ... - -IDs are either the official transponder, network, etc. id if it exists -and is unique, otherwise it is just a consecutive number assigned by -the application. -An LNB can also describe a cable TV outlet or a terrestrial antenna. -Names (as all parameters in brackets) are optional. In this case the -application should use the ID as name. - -The application should offer selection sorted by channel number, network, -satellite, bouquet. - - -# satellite definition -SAT - ID satid # ID = xxxy, sat is at position xxx.y degrees - [NAME name] - LNBID lnbid # LNB this sat is received with - [ROTORID rotorid] # rotor commands to position it on this sat - -# LNB definition -LNB - ID lnbid - [NAME name] - [INPUT input] # input of card which the lnb is connected to (default 0) - TYPE type # LNB, CATV or terrestrial antenna? - LOF1 offset1 # local oscillator frequency 1 - LOF2 offset2 # local oscillator frequency 2 - SLOF switchfreq # switching frequency - [DISEQCNR diseqcnr] # simple 2- or 4-switch DiSEqC - [DISEQCID diseqcid] - [INPUT input] - [SWITCHID switchid] - -# A transponder definition -TRANSPONDER - ID tpid - TYPE type # digital (DVB-S(1), C(2) or T(3)) or analog(0) ? - SATID satid - [NAME name] # if analog this is the channel name - FREQ freq - POL H/V - [QAM qam] # only needed if DVB-C - [SRATE sr] # only if DVB - [FEC fec] # only if DVB - [PICID picid] # picture attributes for all channels on this transponder - -# channel definition (only if DVB) -CHANNEL - ID channelid - [NAME name] - TPID tpid - TYPE type - PNR pnr - VPID vpid - APID apid - TPID tpid - [PMTPID pmtpid] - [PCRPID pcrpid] - [APID apid2 APID apid3 ... APID apidn] # more audio PIDs for several languages - [AC3PID ac3] - [NETWID networkid] - [BOUQID bouquetid] - [PICID picid] - -# network definition -NETWORK - ID nwid - [NAME name] - -# bouquet definition -BOUQUET - ID bqid - [NAME name] - - - -# These will be implemented later - -# DiSEqC command sequence -DISEQC - ID disid - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - -# DiSEqC switch -SWITCH - ID switchid - SWITCHID switchid # next "higher" switch - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - - -# DiSEqC rotor command sequence leading to a certain rotor position -ROTOR - ID rotid - POS degrees - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore deleted file mode 100644 index fb6974f6b..000000000 --- a/dvb-spec/dvbapi/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -dvbapi.ps -dvbstb.ps -dvbstb.pst -dvbapi.bbl -dvbapi.aux -dvbapi.blg -dvbapi.dvi -dvbapi.log -dvbapi.pdf -dvbapi.out -dvbapi.toc diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile deleted file mode 100644 index fe9827cff..000000000 --- a/dvb-spec/dvbapi/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -all: dvbapi.ps dvbapi.pdf - -TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ - intro.tex title.tex dvbstb.ps - -dvbapi.pdf: dvbapi.dvi - dvipdf $< $@ - -dvbapi.ps: dvbapi.dvi - dvips -o $@ $< - -dvbapi.dvi: dvbapi.bbl $(TEXS) - -latex dvbapi - -bibtex dvbapi - -makeindex dvbapi - -latex dvbapi - -latex dvbapi - -dvbapi.bbl: $(TEXS) - -latex dvbapi - -bibtex dvbapi - -makeindex dvbapi - -%.ps: %.fig - ./fig2pstex $< - -clean: - rm -f dvbapi.dvi - rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc - rm -f *.pdf *.pst *.ps diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex deleted file mode 100644 index e81dd2f89..000000000 --- a/dvb-spec/dvbapi/audio.tex +++ /dev/null @@ -1,442 +0,0 @@ -\devsec{DVB Audio Device} - -The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/audio}. - - -\devsubsec{Audio Data Types} - -This section describes the structures, data types and defines used when -talking to the audio device. - -\devsubsubsec{audioStreamSource\_t} -\label{audiostreamsource} -The audio stream source is set through the AUDIO\_SELECT\_SOURCE -call and can take the following values, depending on whether we are -replaying from an internal (demuxer) or external (user write) source. -\begin{verbatim} -typedef enum { - AUDIO_SOURCE_DEMUX, - AUDIO_SOURCE_MEMORY -} audioStreamSource_t; -\end{verbatim} -AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed -either by the frontend or the DVR device) as the source of -the video stream. -If AUDIO\_SOURCE\_MEMORY is selected the stream -comes from the application through the \texttt{write()} -system call. - -\devsubsubsec{audioPlayState\_t} -The following values can be returned by the AUDIO\_GET\_STATUS call -representing the state of audio playback. -\label{audioplaystate} -\begin{verbatim} -typedef enum { - AUDIO_STOPPED, - AUDIO_PLAYING, - AUDIO_PAUSED -} audioPlayState_t; -\end{verbatim} - -\devsubsubsec{audioChannelSelect\_t} -\label{audiochannelselect} -The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by -the following values. -\begin{verbatim} -typedef enum { - AUDIO_STEREO, - AUDIO_MONO_LEFT, - AUDIO_MONO_RIGHT, -} audioChannelSelect_t; -\end{verbatim} - -\devsubsubsec{audioStatus\_t} -\label{audiostatus} -The AUDIO\_GET\_STATUS call returns the following structure informing -about various states of the playback operation. -\begin{verbatim} -typedef struct audioStatus { - boolean AVSyncState; - boolean muteState; - audioPlayState_t playState; - audioStreamSource_t streamSource; - audioChannelSelect_t channelSelect; - boolean bypassMode; -} audioStatus_t; -\end{verbatim} - -\devsubsubsec{audioMixer\_t} -\label{audiomixer} -The following structure is used by the AUDIO\_SET\_MIXER call to set -the audio volume. -\begin{verbatim} -typedef struct audioMixer { - unsigned int volume_left; - unsigned int volume_right; -} audioMixer_t; -\end{verbatim} - -\devsubsubsec{audio encodings} -\label{audiotypes} -A call to AUDIO\_GET\_CAPABILITIES returns an unsigned integer with -the following bits set according to the hardwares capabilities. -\begin{verbatim} -#define AUDIO_CAP_DTS 1 -#define AUDIO_CAP_LPCM 2 -#define AUDIO_CAP_MP1 4 -#define AUDIO_CAP_MP2 8 -#define AUDIO_CAP_MP3 16 -#define AUDIO_CAP_AAC 32 -#define AUDIO_CAP_OGG 64 -#define AUDIO_CAP_SDDS 128 -#define AUDIO_CAP_AC3 256 -\end{verbatim} - - -\devsubsubsec{audio karaoke} -\label{audiokaraoke} -The ioctl AUDIO\_SET\_KARAOKE uses the following format: -\begin{verbatim} -typedef -struct audioKaraoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ - int vocal1; /* into left and right t at 70% each */ - int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ - int melody; /* mixed into the left channel and */ - /* Vocal2 into the right channel at 100% each. */ - /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ -} audioKaraoke_t; -\end{verbatim} - -\devsubsubsec{audio attributes} -\label{aattrib} -The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: -\begin{verbatim} -typedef uint16_t audioAttributes_t; -/* bits: descr. */ -/* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ -/* 12 multichannel extension */ -/* 11-10 audio type (0=not spec, 1=language included) */ -/* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ -/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ -/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ -/* 2- 0 number of audio channels (n+1 channels) */ -\end{verbatim} - - -\clearpage - -\devsubsec{Audio Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent - use. When an open() call has succeeded, the device will be ready for use. - The significance of blocking or non-blocking mode is described in the - documentation for functions where there is a difference. It does not affect - the semantics of the open() call itself. A device opened in blocking mode can - later be put into non-blocking mode (and vice versa) using the F\_SETFL command - of the fcntl system call. This is a standard system call, documented in the - Linux manual page for fcntl. - Only one user can open the Audio Device in O\_RDWR mode. All other attempts to - open the device in this mode will fail, and an error code will be returned. - If the Audio Device is opened in O\_RDONLY mode, the only ioctl call that can - be used is AUDIO\_GET\_STATUS. All other call will return with an error code. - }{ - const char *deviceName & Name of specific audio device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ - & \hspace{1em} (blocking mode is the default)\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EINTERNAL & Internal error.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened audio device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\function{write()}{ - size\_t write(int fd, const void *buf, size\_t count);}{ - This system call can only be used if AUDIO\_SOURCE\_MEMORY is selected - in the ioctl call AUDIO\_SELECT\_SOURCE. - The data provided shall be in PES format. - If O\_NONBLOCK is not specified the function will block until buffer space is - available. The amount of data to be transferred is implied by count. - }{ - int fd & File descriptor returned by a previous call to open().\\ - void *buf & Pointer to the buffer containing the PES data.\\ - size\_t count& Size of buf.\\ - }{ - EPERM& Mode AUDIO\_SOURCE\_MEMORY not selected.\\ - ENOMEM& Attempted to write more data than the internal buffer can hold.\\ - EBADF& fd is not a valid open file descriptor.\\ -} - -\ifunction{AUDIO\_STOP}{ - int ioctl(int fd, int request = AUDIO\_STOP);}{ - This ioctl call asks the Audio Device to stop playing the current stream. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals AUDIO\_STOP for this command. - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error. -} - -\ifunction{AUDIO\_PLAY}{ - int ioctl(int fd, int request = AUDIO\_PLAY);}{ - This ioctl call asks the Audio Device to start playing an audio stream - from the selected source. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals AUDIO\_PLAY for this command. - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error. -} - -\ifunction{AUDIO\_PAUSE}{ - int ioctl(int fd, int request = AUDIO\_PAUSE);}{ - This ioctl call suspends the audio stream being played. - Decoding and playing are paused. - It is then possible to restart again decoding and playing process of the - audio stream using AUDIO\_CONTINUE command.\\ - If AUDIO\_SOURCE\_MEMORY is selected in the ioctl call - AUDIO\_SELECT\_SOURCE, the DVB-subsystem will not decode (consume) - any more data until the ioctl call - AUDIO\_CONTINUE or AUDIO\_PLAY is performed. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals AUDIO\_PAUSE for this command. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error. -} - -\ifunction{AUDIO\_SELECT\_SOURCE}{ - int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, - audioStreamSource\_t source);}{ - This ioctl call informs the audio device which source shall be used for the - input data. The possible sources are demux or memory. - If AUDIO\_SOURCE\_MEMORY - is selected, the data is fed to the Audio Device through the write command. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\ - audioStreamSource\_t source& Indicates the source that shall be used for the - Audio stream. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal input parameter. -} - -\ifunction{AUDIO\_SET\_MUTE}{ - int ioctl(int fd, int request = AUDIO\_SET\_MUTE, boolean state);}{ - This ioctl call asks the audio device to mute the stream that is - currently being played. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_MUTE for this command.\\ - boolean state & Indicates if audio device shall mute or not.\\ - &TRUE Audio Mute\\ - &FALSE Audio Un-mute\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal input parameter. -} - -\ifunction{AUDIO\_SET\_AV\_SYNC}{ - int ioctl(int fd, int request = AUDIO\_SET\_AV\_SYNC, boolean state);}{ - This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_AV\_SYNC for this command.\\ - boolean state& Tells the DVB subsystem if A/V - synchronization shall be ON or OFF.\\ - & TRUE AV-sync ON \\ - & FALSE AV-sync OFF\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal input parameter. -} - -\ifunction{AUDIO\_SET\_BYPASS\_MODE}{ - int ioctl(int fd, int request = AUDIO\_SET\_BYPASS\_MODE, boolean mode);}{ - This ioctl call asks the Audio Device to bypass the Audio decoder and forward - the stream without decoding. This mode shall be used if streams that can't be - handled by the DVB system shall be decoded. - Dolby DigitalTM streams are automatically forwarded by the DVB - subsystem if the hardware can handle it. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_BYPASS\_MODE for this command.\\ - boolean mode& Enables or disables the decoding of the current - Audio stream in the DVB subsystem.\\ - &TRUE Bypass is disabled\\ - &FALSE Bypass is enabled\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal input parameter. -} - -\ifunction{AUDIO\_CHANNEL\_SELECT}{ - int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, - audioChannelSelect\_t);}{ - This ioctl call asks the Audio Device to select the requested channel - if possible. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\ - audioChannelSelect\_t ch & - Select the output format of the audio (mono left/right, stereo). - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal input parameter ch. -} - -\ifunction{AUDIO\_GET\_STATUS}{ - int ioctl(int fd, int request = AUDIO\_GET\_STATUS, - struct audioStatus *status);}{ - This ioctl call asks the Audio Device to return the current state - of the Audio Device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_GET\_STATUS for this command.\\ - struct audioStatus *status & Returns the current state of Audio Device. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EFAULT & status points to invalid address. -} - -\ifunction{AUDIO\_GET\_CAPABILITIES}{ - int ioctl(int fd, int request = AUDIO\_GET\_CAPABILITIES, - unsigned int *cap);}{ - This ioctl call asks the Audio Device to tell us about the - decoding capabilities of the audio hardware. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_GET\_CAPABILITIES for this command.\\ - unsigned int *cap & Returns a bit array of supported sound formats. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EFAULT & cap points to an invalid address. -} - -\ifunction{AUDIO\_CLEAR\_BUFFER}{ - int ioctl(int fd, int request = AUDIO\_CLEAR\_BUFFER);}{ - This ioctl call asks the Audio Device to clear all software - and hardware buffers of the audio decoder device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_CLEAR\_BUFFER for this command. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error. -} - -\ifunction{AUDIO\_SET\_ID}{ - int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{ - This ioctl selects which sub-stream is to be decoded if a program or - system stream is sent to the video device. If no audio stream type is set - the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for - AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow - for other stream types. If the stream type is set the id just - specifies the substream id of the audio stream and only the first 5 - bits are recognized. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_ID for this command.\\ - int id& audio sub-stream id - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Invalid sub-stream id. -} - -\ifunction{AUDIO\_SET\_MIXER}{ - int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audioMixer\_t *mix);}{ - This ioctl lets you adjust the mixer settings of the audio decoder. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_ID for this command.\\ - audioMixer\_t *mix& mixer settings. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EFAULT & mix points to an invalid address. -} - -\ifunction{AUDIO\_SET\_STREAMTYPE}{ - int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{ - This ioctl tells the driver which kind of audio stream to expect. - This is useful if the stream offers several audio sub-streams - like LPCM and AC3. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ - int type & stream type\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& type is not a valid or supported stream type.\\ -} - - -\ifunction{AUDIO\_SET\_EXT\_ID}{ - int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{ - This ioctl can be used to set the extension id for MPEG streams in - DVD playback. Only the first 3 bits are recognized. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ - int id & audio sub\_stream\_id\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& id is not a valid id.\\ -} - -\ifunction{AUDIO\_SET\_ATTRIBUTES}{ - int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ - This ioctl is intended for DVD playback and allows you to set - certain information about the audio stream. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\ - iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& attr is not a valid or supported attribute setting.\\ -} - -\ifunction{AUDIO\_SET\_KARAOKE}{ - int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audioKaraoke\_t *karaoke);}{ - This ioctl allows one to set the mixer settings for a karaoke DVD. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ - audioKaraoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ - }{ - EBADF & fd is not a valid open file descriptor \\ - EINVAL& karaoke is not a valid or supported karaoke setting.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/bibsection.sty b/dvb-spec/dvbapi/bibsection.sty deleted file mode 100644 index 7f9eedc6a..000000000 --- a/dvb-spec/dvbapi/bibsection.sty +++ /dev/null @@ -1,29 +0,0 @@ -\def\thebibliography#1{\chapter*{\bibname\@mkboth - {\uppercase{\bibname}}{\uppercase{\bibname}}} - \setcounter{chapter}{0} - \setcounter{section}{0} - \def\thechapter{Bib} - \def\thesection{\Alph{section}} - \edef\biblab{#1} - \addcontentsline{toc}{chapter}{\bibname} - } - -\def\bibtitle#1#2{\expandafter\def\csname bibtitle#1\endcsname{ - \bibsection{#2}} } - -\def\bibsection#1{\section{#1} - \begin{list} - {\@biblabel{\arabic{enumiv}}}{\settowidth\labelwidth{\@biblabel{\biblab}}% - \leftmargin\labelwidth - \advance\leftmargin\labelsep - \usecounter{enumiv}% - \let\p@enumiv\@empty - \def\theenumiv{\arabic{enumiv}}}% - \def\newblock{\hskip .11em plus.33em minus.07em}% - \sloppy\clubpenalty4000\widowpenalty4000 - \sfcode`\.=\@m} - -\def\endbibsection{\end{list}} - -\def\endthebibliography{\endbibsection} - diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex deleted file mode 100644 index eba512b1b..000000000 --- a/dvb-spec/dvbapi/ca.tex +++ /dev/null @@ -1,127 +0,0 @@ -\devsec{DVB CA Device} - -The DVB CA device controls the conditional access hardware. -It can be accessed through \texttt{/dev/ost/ca}. - - -\devsubsec{CA Data Types} - -\devsubsubsec{ca\_slot\_info\_t} -\label{caslotinfo} - -\begin{verbatim} -/* slot interface types and info */ - -typedef struct ca_slot_info_s { - int num; /* slot number */ - - int type; /* CA interface this slot supports */ -#define CA_CI 1 /* CI high level interface */ -#define CA_CI_LINK 2 /* CI link layer level interface */ -#define CA_CI_PHYS 4 /* CI physical layer level interface */ -#define CA_SC 128 /* simple smart card interface */ - - unsigned int flags; -#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ -#define CA_CI_MODULE_READY 2 -} ca_slot_info_t; -\end{verbatim} - -\devsubsubsec{ca\_descr\_info\_t} -\label{cadescrinfo} - -\begin{verbatim} -typedef struct ca_descr_info_s { - unsigned int num; /* number of available descramblers (keys) */ - unsigned int type; /* type of supported scrambling system */ -#define CA_ECD 1 -#define CA_NDS 2 -#define CA_DSS 4 -} ca_descr_info_t; -\end{verbatim} - -\devsubsubsec{ca\_cap\_t} -\label{cacap} - -\begin{verbatim} -typedef struct ca_cap_s { - unsigned int slot_num; /* total number of CA card and module slots */ - unsigned int slot_type; /* OR of all supported types */ - unsigned int descr_num; /* total number of descrambler slots (keys) */ - unsigned int descr_type;/* OR of all supported types */ -} ca_cap_t; -\end{verbatim} - - -\devsubsubsec{ca\_msg\_t} -\label{camsg} - -\begin{verbatim} -/* a message to/from a CI-CAM */ -typedef struct ca_msg_s { - unsigned int index; - unsigned int type; - unsigned int length; - unsigned char msg[256]; -} ca_msg_t; -\end{verbatim} - - -\devsubsubsec{ca\_descr\_t} -\label{cadescr} - -\begin{verbatim} -typedef struct ca_descr_s { - unsigned int index; - unsigned int parity; - unsigned char cw[8]; -} ca_descr_t; -\end{verbatim} - -\clearpage - -\devsubsec{CA Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named ca device (e.g. /dev/ost/ca) - for subsequent use. - - When an open() call has succeeded, the device will be ready for use. - The significance of blocking or non-blocking mode is described in - the documentation for functions where there is a difference. - It does not affect the semantics of the open() call itself. - A device opened in blocking mode can later be put into non-blocking mode - (and vice versa) using the F\_SETFL command of the fcntl system - call. - This is a standard system call, documented in the Linux manual - page for fcntl. - Only one user can open the CA Device in O\_RDWR mode. All other attempts to - open the device in this mode will fail, and an error code will be returned. - }{ - const char *deviceName & Name of specific video device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ - & \hspace{1em} (blocking mode is the default)\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EINTERNAL & Internal error.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened audio device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/cimlogo.psi b/dvb-spec/dvbapi/cimlogo.psi deleted file mode 100644 index b7b089a49..000000000 --- a/dvb-spec/dvbapi/cimlogo.psi +++ /dev/null @@ -1,122 +0,0 @@ -%!PS-Adobe-2.0 EPSF-2.0 -%%Title: /home/rjkm/dvbapi/cimlogo.ps -%%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley -%%BoundingBox: 275 411 309 440 -%%Pages: 1 -%%DocumentFonts: -%%EndComments -%%EndProlog - -%%Page: 1 1 - -% remember original state -/origstate save def - -% build a temporary dictionary -20 dict begin - -% define string to hold a scanline's worth of data -/pix 45 string def - -% define space for color conversions -/grays 45 string def % space for gray scale line -/npixls 0 def -/rgbindx 0 def - -% lower left corner -275 411 translate - -% size of image (on paper, in 1/72inch coords) -33.76800 28.51200 scale - -45 38 8 % dimensions of data -[45 0 0 -38 0 38] % mapping matrix -{currentfile pix readhexstring pop} -image - -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffff00ffffffffffff0000000000ffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffff0000000000ffffffff000000000000ffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffff0000000000000000ffffff000000000000ffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffff0000000000000000ffffffff000000000000ffffffffffffffffffff -ffffffffffffffffff -ffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffff -ffffffffffffffffff -ffffffffffff0000000000000000ffffffffff000000000000ffffff00000000ffffffff -ffffffffffffffffff -ffffffffff00000000000000ffffffffffffff0000000000ffffff0000000000ffffffff -ffffffffffffffffff -ffffffffff000000000000ffffffffffffff000000000000ffffff000000000000ffffff -ffffffffffffffffff -ffffffff00000000000000ffffffffffffff000000000000ffffffff000000000000ffff -ffffffffffffffffff -ffffffff000000000000ffffffffffffffff000000000000ffffffff000000000000ffff -ffffffffffffffffff -ffffffff0000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff -ffffffffffffffffff -ffffff000000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff -ffffffffffffffffff -ffffff0000000000ffffffffffffffffff000000000000ffffffffffff000000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffffffff0000000000ffffffffffffff000000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffffff000000000000ffffffffffffffff0000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffffff000000000000ffffffffffffff000000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffffff0000000000ffffffffffffffffff0000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffff000000000000ffffffffffffffff000000000000ff -ffffffffffffffffff -ffffff0000000000ffffffffffffff000000000000ffffffffffffffff0000000000ffff -ffffffffffffffffff -ffffff000000000000ffffffffffffff00000000ffffffffffffffffff0000000000ffff -ffffffffffffffffff -ffffffff0000000000ffffffffffffffff0000ffffffffffffffffff000000000000ffff -ffffffffffffffffff -ffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffff -ffffffffffffffffff -ffffffff000000000000ffffffffffffffffffffffffffffffffff000000000000ffffff -ffffffffffffffffff -ffffffffff00000000000000ffffffffffffffffffffffffffff000000000000ffffffff -ff0000000000ffffff -ffffffffff0000000000000000ffffffffffffffffffffffff00000000000000ffffffff -00000000000000ffff -ffffffffffff000000000000000000ffffffffffffffff0000000000000000ffffffffff -00000000000000ffff -ffffffffffffff0000000000000000000000000000000000000000000000ffffffffffff -0000000000000000ff -ffffffffffffffff000000000000000000000000000000000000000000ffffffffffffff -00000000000000ffff -ffffffffffffffffffff0000000000000000000000000000000000ffffffffffffffffff -00000000000000ffff -ffffffffffffffffffffffff00000000000000000000000000ffffffffffffffffffffff -ff0000000000ffffff -ffffffffffffffffffffffffffffff00ff0000000000ffffffffffffffffffffffffffff -ffffff0000ffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffff - -showpage - -% stop using temporary dictionary -end - -% restore original state -origstate restore - -%%Trailer diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex deleted file mode 100644 index 541ee633a..000000000 --- a/dvb-spec/dvbapi/demux.tex +++ /dev/null @@ -1,392 +0,0 @@ -\devsec{DVB Demux Device} - -The DVB demux device controls the filters of the DVB hardware/software. -It can be accessed through \texttt{/dev/ost/demux}. - -\devsubsec{Demux Data Types} - -\begin{verbatim} -typedef uint16_t dvb_pid_t; -\end{verbatim} - - -\devsubsubsec{dmxOutput\_t} -\label{dmxoutput} - -\begin{verbatim} -typedef enum -{ - DMX_OUT_DECODER, - DMX_OUT_TAP, - DMX_OUT_TS_TAP -} dmxOutput_t; -\end{verbatim} -/* Output multiplexed into a new TS */ -/* (to be retrieved by reading from the */ -/* logical DVR device). */ - - -\devsubsubsec{dmxInput\_t} -\label{dmxinput} - -\begin{verbatim} -typedef enum -{ - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ -} dmxInput_t; -\end{verbatim} - - -\devsubsubsec{dmxPesType\_t} -\label{dmxpestype} - -\begin{verbatim} -typedef enum -{ - DMX_PES_AUDIO, - DMX_PES_VIDEO, - DMX_PES_TELETEXT, - DMX_PES_SUBTITLE, - DMX_PES_PCR, - DMX_PES_OTHER -} dmxPesType_t; -\end{verbatim} - - -\devsubsubsec{dmxEvent\_t} -\label{dmxeventt} - -\begin{verbatim} -typedef enum -{ - DMX_SCRAMBLING_EV, - DMX_FRONTEND_EV -} dmxEvent_t; -\end{verbatim} - - -\devsubsubsec{dmxScramblingStatus\_t} -\label{dmxscramblingstatus} - -\begin{verbatim} -typedef enum -{ - DMX_SCRAMBLING_OFF, - DMX_SCRAMBLING_ON -} dmxScramblingStatus_t; -\end{verbatim} - - -\devsubsubsec{dmxFilter\_t} -\label{dmxfilter} - -\begin{verbatim} -typedef struct dmxFilter -{ - uint8_t filter[DMX_FILTER_SIZE]; - uint8_t mask[DMX_FILTER_SIZE]; -} dmxFilter_t; -\end{verbatim} - - -\devsubsubsec{dmxSctFilterParams} -\label{dmxsctfilterparams} - -\begin{verbatim} -struct dmxSctFilterParams -{ - dvb_pid_t pid; - dmxFilter_t filter; - uint32_t timeout; - uint32_t flags; -#define DMX_CHECK_CRC 1 -#define DMX_ONESHOT 2 -#define DMX_IMMEDIATE_START 4 -}; -\end{verbatim} - - -\devsubsubsec{dmxPesFilterParams} -\label{dmxpesfilterparams} - -\begin{verbatim} -struct dmxPesFilterParams -{ - dvb_pid_t pid; - dmxInput_t input; - dmxOutput_t output; - dmxPesType_t pesType; - uint32_t flags; -}; -\end{verbatim} - - -\devsubsubsec{dmxEvent} -\label{dmxevent} - -\begin{verbatim} -struct dmxEvent -{ - dmxEvent_t event; - time_t timeStamp; - union - { - dmxScramblingStatus_t scrambling; - } u; -}; -\end{verbatim} - -\clearpage - -\devsubsec{Demux Function Calls} -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call, used with a device name of /dev/ost/demuxn, where n - denotes the specific demux device to be opened, allocates a new filter - and returns a handle which can be used for subsequent control of that - filter. This call has to be made for each filter to be used, i.e. every - returned file descriptor is a reference to a single filter. - /dev/ost/dvrn is a logical device to be used for retrieving Transport - Streams for digital video recording. n identifies the physical demux - device that provides the actual DVR functionality. When reading from - this device a transport stream containing the packets from all PES - filters set in the corresponding demux device (/dev/ost/demuxn) - having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream - is replayed by writing to this device. -% This device can only be opened in read-write mode. - - The significance of blocking or non-blocking mode is described in the - documentation for functions where there is a difference. It does not - affect the semantics of the open() call itself. A device opened in - blocking mode can later be put into non-blocking mode - (and vice versa) using the F\_SETFL command of the fcntl system call. - }{ - const char *deviceName & Name of demux device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDWR read/write access\\ - & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ - & \hspace{1em} (blocking mode is the default)\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EINVAL & Invalid argument.\\ - EMFILE & ``Too many open files'', i.e. no more filters available.\\ - ENOMEM & The driver failed to allocate enough memory.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call deactivates and deallocates a filter that was previously - allocated via the open() call. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\function{read()}{ - size\_t read(int fd, void *buf, size\_t count); - }{ - This system call returns filtered data, which might be section or PES - data. The filtered data is transferred from the driver's internal circular - buffer to buf. The maximum amount of data to be transferred is implied by - count.\\ - When returning section data the driver always tries to return a complete - single section (even though buf would provide buffer space for more data). - If the size of the buffer is smaller than the section as much as possible - will be returned, and the remaining data will be provided in subsequent - calls.\\ - The size of the internal buffer is 2 * 4096 bytes (the size of two maximum - sized sections) by default. The size of this buffer may be changed by - using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough, - or if the read operations are not performed fast enough, this may result - in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, - and the circular buffer will be emptied. - This call is blocking if there is no data to return, i.e. the process - will be put to sleep waiting for data, unless the O\_NONBLOCK flag is - specified.\\ - Note that in order to be able to read, the filtering process has to be - started by defining either a section or a PES filter by means of the - ioctl functions, and then starting the filtering process via the DMX\_START - ioctl function or by setting the DMX\_IMMEDIATE\_START flag. - If the reading is done from a logical DVR demux device, the data will - constitute a Transport Stream including the packets from all PES filters - in the corresponding demux device /dev/ost/demuxn having the output set - to DMX\_OUT\_TS\_TAP. - }{ - int fd & File descriptor returned by a previous call to open().\\ - void *buf & Pointer to the buffer to be used for returned filtered data.\\ - size\_t count & Size of buf.\\ - }{ - EWOULDBLOCK & No data to return and O\_NONBLOCK was specified.\\ - EBADF & fd is not a valid open file descriptor.\\ - ECRC & Last section had a CRC error - no data returned. - The buffer is flushed.\\ - EBUFFEROVERFLOW & \\ -& The filtered data was not read from the buffer in - due time, resulting in non-read data being lost. - The buffer is flushed.\\ - ETIMEDOUT & The section was not loaded within the stated - timeout period. See ioctl DMX\_SET\_FILTER for - how to set a timeout.\\ - EFAULT & The driver failed to write to the callers buffer - due to an invalid *buf pointer.\\ -} - -\function{write()}{ - ssize\_t write(int fd, const void *buf, size\_t count); - }{ - This system call is only provided by the logical device /dev/ost/dvrn, - where n identifies the physical demux device that provides the actual - DVR functionality. It is used for replay of a digitally recorded - Transport Stream. Matching filters have to be defined in the - corresponding physical demux device, /dev/ost/demuxn. - The amount of data to be transferred is implied by count. - }{ - int fd & File descriptor returned by a previous call to open().\\ - void *buf & Pointer to the buffer containing the Transport Stream.\\ - size\_t count & Size of buf.\\ - }{ - EWOULDBLOCK & No data was written. This might happen if - O\_NONBLOCK was specified and there is no more - buffer space available (if O\_NONBLOCK is not - specified the function will block until buffer - space is available).\\ - EBUSY & This error code indicates that there are - conflicting requests. The corresponding demux - device is setup to receive data from the front- - end. Make sure that these filters are stopped - and that the filters with input set to DMX\_IN\_DVR - are started.\\ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{DMX\_START}{ - int ioctl( int fd, int request = DMX\_START); - }{ - This ioctl call is used to start the actual filtering operation - defined via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_START for this command.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EINVAL & Invalid argument, i.e. no filtering parameters - provided via the DMX\_SET\_FILTER or - DMX\_SET\_PES\_FILTER functions.\\ - EBUSY & This error code indicates that there are - conflicting requests. There are active filters - filtering data from another input source. Make - sure that these filters are stopped before starting - this filter.\\ -} - -\ifunction{DMX\_STOP}{ - int ioctl( int fd, int request = DMX\_STOP); - }{ - This ioctl call is used to stop the actual filtering operation defined - via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER and started via - the DMX\_START command. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_STOP for this command.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ -} - -\ifunction{DMX\_SET\_FILTER}{ - int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmxSctFilterParams *params); - }{ - This ioctl call sets up a filter according to the filter and mask - parameters provided. A timeout may be defined stating number of seconds - to wait for a section to be loaded. A value of 0 means that no timeout - should be applied. Finally there is a flag field where it is possible to - state whether a section should be CRC-checked, whether the filter should - be a "one-shot" filter, i.e. if the filtering operation should be stopped - after the first section is received, and whether the filtering operation - should be started immediately (without waiting for a DMX\_START ioctl call). - If a filter was previously set-up, this filter will be canceled, and the - receive buffer will be flushed. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_SET\_FILTER for this command.\\ - struct dmxSctFilterParams *params - & Pointer to structure containing filter parameters.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EINVAL & Invalid argument.\\ -} - -\ifunction{DMX\_SET\_PES\_FILTER}{ - int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, - struct dmxPesFilterParams *params); - }{ - This ioctl call sets up a PES filter according to the parameters provided. - By a PES filter is meant a filter that is based just on the packet - identifier (PID), i.e. no PES header or payload filtering capability is - supported.\\ - The transport stream destination for the filtered output may be set. Also - the PES type may be stated in order to be able to e.g. direct a video - stream directly to the video decoder. Finally there is a flag field where - it is possible to state whether the filtering operation should be started - immediately (without waiting for a DMX\_START ioctl call). - If a filter was previously set-up, this filter will be cancelled, and the - receive buffer will be flushed. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ - struct dmxPesFilterParams *params - & Pointer to structure containing filter parameters.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EINVAL & Invalid argument.\\ - EBUSY & This error code indicates that there are - conflicting requests. There are active filters - filtering data from another input source. Make - sure that these filters are stopped before starting - this filter.\\ -} - -\ifunction{DMX\_SET\_BUFFER\_SIZE}{ - int ioctl( int fd, int request = DMX\_SET\_BUFFER\_SIZE, unsigned long size); - }{ - This ioctl call is used to set the size of the circular buffer used - for filtered data. The default size is two maximum sized sections, i.e. - if this function is not called a buffer size of 2 * 4096 bytes will be - used. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_SET\_BUFFER\_SIZE for this command.\\ - unsigned long size & Size of circular buffer.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - ENOMEM & The driver was not able to allocate a buffer of the requested size.\\ -} - -\ifunction{DMX\_GET\_EVENT}{ - int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmxEvent *ev); - }{ - This ioctl call returns an event if available. If an event is not - available, the behavior depends on whether the device is in blocking or - non-blocking mode. In the latter case, the call fails immediately with - errno set to EWOULDBLOCK. In the former case, the call blocks until an - event becomes available.\\ - The standard Linux poll() and/or select() system calls can be used with - the device file descriptor to watch for new events. For select(), the - file descriptor should be included in the exceptfds argument, and for - poll(), POLLPRI should be specified as the wake-up condition. - Only the latest event for each filter is saved. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals DMX\_GET\_EVENT for this command.\\ - struct dmxEvent *ev & Pointer to the location where the event is to be stored.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EFAULT & ev points to an invalid address.\\ - EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex deleted file mode 100644 index 9c561e853..000000000 --- a/dvb-spec/dvbapi/devices.tex +++ /dev/null @@ -1,12 +0,0 @@ -\input{video.tex} -\input{audio.tex} -\input{frontend.tex} -\input{sec.tex} -\input{demux.tex} -\input{ca.tex} -\input{kdapi.tex} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex deleted file mode 100644 index ad0251c01..000000000 --- a/dvb-spec/dvbapi/dvbapi.tex +++ /dev/null @@ -1,166 +0,0 @@ -\documentclass[10pt]{book} -\usepackage[dvips,colorlinks=true]{hyperref} - -\usepackage{times} - -%\usepackage[hang]{caption} -\usepackage{fancyheadings} -%\usepackage{lucidabr} -%\usepackage{fancybox} -\usepackage{array} -\usepackage{graphicx} -%\usepackage{latexsym} -%\usepackage{pstricks,pst-node,pst-tree} -%\usepackage{verbatim} -%\usepackage{rotating} -%\usepackage{pdftex} -%\usepackage{color} -%\usepackage{subfigure} -%\usepackage{wrapfig} - -\newcommand{\devsec}[1]{\chapter{#1}} -\newcommand{\devsubsec}[1]{\section{#1}} -\newcommand{\devsubsubsec}[1]{\subsection{#1}} -\newcommand{\function}[5]{ - \subsection{#1} - - \noindent DESCRIPTION - \medskip - - \begin{tabular}[h]{p{11cm}} - #3 - \end{tabular} - - \medskip - \noindent SYNOPSIS - \medskip - - \begin{tabular}[h]{p{11cm}} - {\tt #2} - \end{tabular} - - %\item[] -\medskip -\noindent PARAMETERS -\medskip - - \begin{tabular}[h]{p{3cm}p{8cm}} - #4 - \end{tabular} - - %\item[] -\medskip -\noindent ERRORS -\medskip - - \begin{tabular}[h]{p{3cm}p{8cm}} - #5 - \end{tabular} - - %\end{itemize} - -\medskip -} -\def\ifunction#1#2#3#4#5{\function{#1\index{#1}}{#2}{#3}{#4}{#5}} - -\newcommand{\kfunction}[5]{ - \subsection{#1} - \noindent DESCRIPTION - \medskip - - \begin{tabular}[h]{p{11cm}} - #3 - \end{tabular} - - \medskip - \noindent SYNOPSIS - \medskip - - \begin{tabular}[h]{p{11cm}} - {\tt #2} - \end{tabular} - - %\item[] -\medskip -\noindent PARAMETERS -\medskip - - \begin{tabular}[h]{p{3cm}p{8cm}} - #4 - \end{tabular} - - %\item[] -\medskip -\noindent RETURNS -\medskip - - \begin{tabular}[h]{p{3cm}p{8cm}} - #5 - \end{tabular} - - %\end{itemize} - -\medskip -} -\def\kifunction#1#2#3#4#5{\kfunction{#1\index{#1}}{#2}{#3}{#4}{#5}} - - -%\usepackage{index} -%\makeindex - - -\begin{document} - -\input{title.tex} - -\cleardoublepage - -\pagenumbering{roman} -\pagestyle{fancyplain} - - -\tableofcontents -%\listoffigures -%\listoftables - -\cleardoublepage - -\pagenumbering{arabic} - -\renewcommand{\chaptermark}[1]{\markboth{\uppercase{#1}}{}} -\renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} -\lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} -\rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2002 convergence GmbH} - -\input{intro.tex} - -\input{devices.tex} - -\input{examples.tex} - -\cleardoublepage - -\appendix - -\cleardoublepage - -\thispagestyle{plain}\chaptermark{Bibliography} -\addcontentsline{toc}{chapter}{Bibliography} -\bibliographystyle{bibsec} -\bibliography{main} - -\cleardoublepage - -\thispagestyle{plain}\chaptermark{Subject Index} -\addcontentsline{toc}{chapter}{Subject Index} -%\printindex - -\cleardoublepage - -\end{document} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: t -%%% End: diff --git a/dvb-spec/dvbapi/dvbstb.fig b/dvb-spec/dvbapi/dvbstb.fig deleted file mode 100644 index 0a6bbadc3..000000000 --- a/dvb-spec/dvbapi/dvbstb.fig +++ /dev/null @@ -1,59 +0,0 @@ -#FIG 3.2 -Landscape -Center -Metric -A4 -100.00 -Single --2 -1200 2 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 1620 360 2520 360 2520 900 1620 900 1620 360 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 1260 1080 1620 630 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 2520 630 2880 630 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2880 360 3780 360 3780 900 2880 900 2880 360 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 4590 900 3330 1170 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 4590 900 4590 1170 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4140 360 5040 360 5040 900 4140 900 4140 360 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 3780 630 4140 630 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4140 1170 5040 1170 5040 1710 4140 1710 4140 1170 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2880 1170 3780 1170 3780 1710 2880 1710 2880 1170 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 1620 1170 2520 1170 2520 1710 1620 1710 1620 1170 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1620 1440 1260 1080 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 1350 225 5175 225 5175 1845 1350 1845 1350 225 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 3240 1710 3960 2070 -2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 - 1 1 1.00 60.00 120.00 - 4590 1710 3960 2070 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3510 2070 4410 2070 4410 2610 3510 2610 3510 2070 -2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 360 810 1260 810 1260 1350 360 1350 360 810 -4 0 0 50 0 0 12 0.0000 4 135 675 1755 675 Frontend\001 -4 0 0 50 0 0 12 0.0000 4 135 690 4275 675 Demuxer\001 -4 0 0 50 0 0 12 0.0000 4 135 450 4365 1485 Video\001 -4 0 0 50 0 0 12 0.0000 4 135 450 3105 1485 Audio\001 -4 0 0 50 0 0 12 0.0000 4 135 345 1890 1485 SEC\001 -4 0 0 50 0 0 12 0.0000 4 135 255 3195 675 CA\001 -4 0 0 50 0 0 12 0.0000 4 135 645 495 1125 Antenna\001 -4 0 0 50 0 0 12 0.0000 4 135 240 3870 2385 TV\001 diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex deleted file mode 100644 index 114579b80..000000000 --- a/dvb-spec/dvbapi/examples.tex +++ /dev/null @@ -1,366 +0,0 @@ -\chapter{Examples} -In this section we would like to present some examples for using the DVB API. - -\section{Tuning} -We will start with a generic tuning subroutine that uses the frontend -and SEC, as well as the demux devices. The example is given for QPSK -tuners, but can easily be adjusted for QAM. - -{\small -\begin{verbatim} -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define DMX "/dev/ost/demux" -#define FRONT "/dev/ost/frontend" -#define SEC "/dev/ost/sec" - -/* routine for checking if we have a signal and other status information*/ -int FEReadStatus(int fd, FrontendStatus *stat) -{ - int ans; - - if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ - perror("FE READ STATUS: "); - return -1; - } - - if (*stat & FE_HAS_POWER) - printf("FE HAS POWER\n"); - - if (*stat & FE_HAS_SIGNAL) - printf("FE HAS SIGNAL\n"); - - if (*stat & FE_SPECTRUM_INV) - printf("SPEKTRUM INV\n"); - - return 0; -} - - -/* tune qpsk */ -/* freq: frequency of transponder */ -/* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ -/* diseqc: DiSEqC address of the used LNB */ -/* pol: Polarisation */ -/* srate: Symbol Rate */ -/* fec. FEC */ -/* lnb_lof1: local frequency of lower LNB band */ -/* lnb_lof2: local frequency of upper LNB band */ -/* lnb_slof: switch frequency of LNB */ - -int set_qpsk_channel(int freq, int vpid, int apid, int tpid, - int diseqc, int pol, int srate, int fec, int lnb_lof1, - int lnb_lof2, int lnb_slof) -{ - struct secCommand scmd; - struct secCmdSequence scmds; - struct dmxPesFilterParams pesFilterParams; - FrontendParameters frp; - struct pollfd pfd[1]; - FrontendEvent event; - int demux1, dmeux2, demux3, front, - - frequency = (uint32_t) freq; - symbolrate = (uint32_t) srate; - - if((front = open(FRONT,O_RDWR)) < 0){ - perror("FRONTEND DEVICE: "); - return -1; - } - - if((sec = open(SEC,O_RDWR)) < 0){ - perror("SEC DEVICE: "); - return -1; - } - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux3 < 0){ - if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (freq < lnb_slof) { - frp.Frequency = (freq - lnb_lof1); - scmds.continuousTone = SEC_TONE_OFF; - } else { - frp.Frequency = (freq - lnb_lof2); - scmds.continuousTone = SEC_TONE_ON; - } - frp.Inversion = INVERSION_AUTO; - if (pol) scmds.voltage = SEC_VOLTAGE_18; - else scmds.voltage = SEC_VOLTAGE_13; - - scmd.type=0; - scmd.u.diseqc.addr=0x10; - scmd.u.diseqc.cmd=0x38; - scmd.u.diseqc.numParams=1; - scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | - (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | - (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); - - scmds.miniCommand=SEC_MINI_NONE; - scmds.numCommands=1; - scmds.commands=&scmd; - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ - perror("SEC SEND: "); - return -1; - } - - frp.u.qpsk.SymbolRate = srate; - frp.u.qpsk.FEC_inner = fec; - - if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ - perror("QPSK TUNE: "); - return -1; - } - - pfd[0].fd = front; - pfd[0].events = POLLIN; - - if (poll(pfd,1,3000)){ - if (pfd[0].revents & POLLIN){ - printf("Getting QPSK event\n"); - if ( ioctl(front, FE_GET_EVENT, &event) - - == -EBUFFEROVERFLOW){ - perror("qpsk get event"); - return -1; - } - printf("Received "); - switch(event.type){ - case FE_UNEXPECTED_EV: - printf("unexpected event\n"); - return -1; - case FE_FAILURE_EV: - printf("failure event\n"); - return -1; - - case FE_COMPLETION_EV: - printf("completion event\n"); - } - } - } - - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_vpid"); - return -1; - } - - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_apid"); - return -1; - } - - pesFilterParams.pid = tpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_TELETEXT; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("set_tpid"); - return -1; - } - - return has_signal(fds); -} - -\end{verbatim} -} -The program assumes that you are using a universal LNB and a standard -DiSEqC switch with up to 4 addresses. Of course, you could build in -some more checking if tuning was successful and maybe try to repeat -the tuning process. Depending on the external hardware, i.e. LNB and -DiSEqC switch, and weather conditions this may be necessary. - - -\section{The DVR device} -The following program code shows how to use the DVR device for -recording. - -{\small -\begin{verbatim} -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#define DVR "/dev/ost/dvr" -#define AUDIO "/dev/ost/audio" -#define VIDEO "/dev/ost/video" - -#define BUFFY (188*20) -#define MAX_LENGTH (1024*1024*5) /* record 5MB */ - - -/* switch the demuxes to recording, assuming the transponder is tuned */ - -/* demux1, demux2: file descriptor of video and audio filters */ -/* vpid, apid: PIDs of video and audio channels */ - -int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) -{ - struct dmxPesFilterParams pesFilterParams; - - if (demux1 < 0){ - if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - if (demux2 < 0){ - if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) - < 0){ - perror("DEMUX DEVICE: "); - return -1; - } - } - - pesFilterParams.pid = vpid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_VIDEO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - pesFilterParams.pid = apid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_AUDIO; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - perror("DEMUX DEVICE"); - return -1; - } - return 0; -} - -/* start recording MAX_LENGTH , assuming the transponder is tuned */ - -/* demux1, demux2: file descriptor of video and audio filters */ -/* vpid, apid: PIDs of video and audio channels */ -int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) -{ - int i; - int len; - int written; - uint8_t buf[BUFFY]; - uint64_t length; - struct pollfd pfd[1]; - int dvr, dvr_out; - - /* open dvr device */ - if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ - perror("DVR DEVICE"); - return -1; - } - - /* switch video and audio demuxes to dvr */ - printf ("Switching dvr on\n"); - i = switch_to_record(demux1, demux2, vpid, apid); - printf("finished: "); - - printf("Recording %2.0f MB of test file in TS format\n", - MAX_LENGTH/(1024.0*1024.0)); - length = 0; - - /* open output file */ - if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT - |O_TRUNC, S_IRUSR|S_IWUSR - |S_IRGRP|S_IWGRP|S_IROTH| - S_IWOTH)) < 0){ - perror("Can't open file for dvr test"); - return -1; - } - - pfd[0].fd = dvr; - pfd[0].events = POLLIN; - - /* poll for dvr data and write to file */ - while (length < MAX_LENGTH ) { - if (poll(pfd,1,1)){ - if (pfd[0].revents & POLLIN){ - len = read(dvr, buf, BUFFY); - if (len < 0){ - perror("recording"); - return -1; - } - if (len > 0){ - written = 0; - while (written < len) - written += - write (dvr_out, - buf, len); - length += len; - printf("written %2.0f MB\r", - length/1024./1024.); - } - } - } - } - return 0; -} - -\end{verbatim} -} -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% TeX-master: t -%%% End: diff --git a/dvb-spec/dvbapi/fig2pstex b/dvb-spec/dvbapi/fig2pstex deleted file mode 100755 index bf62eb7ec..000000000 --- a/dvb-spec/dvbapi/fig2pstex +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -f=`basename $1 .fig` -fig2dev -L pstex $f.fig $f.ps -fig2dev -L pstex_t -p $f.ps $f.fig $f.pst2 -./getbb $f.pst2 $f.ps > $f.pst -rm $f.pst2 \ No newline at end of file diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex deleted file mode 100644 index ceb2f93db..000000000 --- a/dvb-spec/dvbapi/frontend.tex +++ /dev/null @@ -1,630 +0,0 @@ -\devsec{DVB Frontend API} - -The DVB frontend device controls the tuner and DVB demodulator hardware. -It can be accessed through \texttt{/dev/ost/frontend}. -If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. -The frontend device will only be made visible through \texttt{devfs} -if the corresponding card actually has a frontend. Cards which support -the DVB API but, e.g., only can play back recordings, will not offer the -frontend device. - -\devsubsec{Frontend Data Types} - -\devsubsubsec{frontend status} -\label{frontendstatus} - -Several functions of the frontend device use the feStatus data -type defined by -\begin{verbatim} -typedef uint32_t feStatus; -\end{verbatim} -to indicate the current state and/or state changes of -the frontend hardware. - -\noindent -It can take on the values -\begin{verbatim} -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 -#define FE_HAS_LOCK 8 -#define FE_HAS_CARRIER 16 -#define FE_HAS_VITERBI 32 -#define FE_HAS_SYNC 64 -#define TUNER_HAS_LOCK 128 -\end{verbatim} -which can be ORed together and have the following meaning: - -\medskip - -\begin{tabular}{lp{11cm}} -FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ -FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ -FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ -FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ -FE\_HAS\_CARRIER & carrier detected in signal\\ -FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ -FE\_HAS\_SYNC & TS sync bytes detected \\ -TUNER\_HAS\_LOCK & the tuner has a frequency lock -\end{tabular} - - -\devsubsubsec{frontend parameters} -\label{frontendparameters} - -The kind of parameters passed to the frontend device for tuning -depend on the kind of hardware you are using. -All kinds of parameters are combined as a union in the -FrontendParameters structure: -\begin{verbatim} -typedef struct { - __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ - /* intermediate frequency in kHz for QPSK */ - SpectralInversion Inversion; /* spectral inversion */ - union { - QPSKParameters qpsk; - QAMParameters qam; - OFDMParameters ofdm; - } u; -} FrontendParameters; -\end{verbatim} - -For satellite QPSK frontends you have to use QPSKParameters defined by -\begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_inner; /* forward error correction (see above) */ -} QPSKParameters; -\end{verbatim} -for cable QAM frontend you use the QAMParameters structure -\begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - CodeRate FEC_outer; /* forward error correction (see above) */ - CodeRate FEC_inner; /* forward error correction (see above) */ - Modulation QAM; /* modulation type (see above) */ -} QAMParameters; -\end{verbatim} -DVB-T frontends are supported by the OFDMParamters structure -\begin{verbatim} -typedef struct { - BandWidth bandWidth; - CodeRate HP_CodeRate; /* high priority stream code rate */ - CodeRate LP_CodeRate; /* low priority stream code rate */ - Modulation Constellation; /* modulation type (see above) */ - TransmitMode TransmissionMode; - GuardInterval guardInterval; - Hierarchy HierarchyInformation; -} OFDMParameters; -\end{verbatim} - -In the case of QPSK frontends the Frequency field specifies the intermediate -frequency, i.e. the offset which is effectively added to the local oscillator -frequency (LOF) of the LNB. -The intermediate frequency has to be specified in units of kHz. -For QAM and OFDM frontends the Frequency specifies the absolute frequency -and is given in Hz. - -The Inversion field can take one of these values: -\begin{verbatim} -typedef enum { - INVERSION_OFF, - INVERSION_ON, - INVERSION_AUTO -} SpectralInversion; -\end{verbatim} -It indicates if spectral inversion should be presumed or not. -In the automatic setting (\verb INVERSION_AUTO) the hardware will -try to figure out the correct setting by itself. - -\noindent -The possible values for the FEC\_inner field are -\begin{verbatim} -enum { - FEC_AUTO, - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_NONE -}; -\end{verbatim} -which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., -no error correction or auto detection. - -\noindent -For cable and terrestrial frontends (QAM and OFDM) one also has to -specify the quadrature modulation mode which can be one of the following: -\begin{verbatim} -typedef enum -{ QPSK, - QAM_16, - QAM_32, - QAM_64, - QAM_128, - QAM_256 -} QAM_TYPE; -\end{verbatim} - -Finally, there are several more parameters for OFDM: -\begin{verbatim} -typedef enum { - TRANSMISSION_MODE_2K, - TRANSMISSION_MODE_8K -} TransmitMode; -\end{verbatim} - -\begin{verbatim} -typedef enum { - BANDWIDTH_8_MHZ, - BANDWIDTH_7_MHZ, - BANDWIDTH_6_MHZ -} BandWidth; -\end{verbatim} - -\begin{verbatim} -typedef enum { - GUARD_INTERVAL_1_32, - GUARD_INTERVAL_1_16, - GUARD_INTERVAL_1_8, - GUARD_INTERVAL_1_4 -} GuardInterval; -\end{verbatim} - -\begin{verbatim} -typedef enum { - HIERARCHY_NONE, - HIERARCHY_1, - HIERARCHY_2, - HIERARCHY_4 -} Hierarchy; -\end{verbatim} - - -\devsubsubsec{frontend events} -\label{frontendevents} - -\begin{verbatim} -enum { - FE_UNEXPECTED_EV, - FE_COMPLETION_EV, - FE_FAILURE_EV -}; -\end{verbatim} - -\begin{verbatim} -typedef struct { - EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ - long timestamp; /* time in seconds since 1970-01-01 */ - - union { - struct { - FrontendStatus previousStatus; /* status before event */ - FrontendStatus currentStatus; /* status during event */ - } unexpectedEvent; - FrontendParameters completionEvent; /* parameters for which the - tuning succeeded */ - FrontendStatus failureEvent; /* status at failure (e.g. no lock) */ - } u; -} FrontendEvent; -\end{verbatim} - -\begin{verbatim} -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qamRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -struct qamFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - FE_POWER_ON, - FE_POWER_STANDBY, - FE_POWER_SUSPEND, - FE_POWER_OFF -} powerState_t; -\end{verbatim} - - -\clearpage - - -\devsubsec{Frontend Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named frontend device (e.g. /dev/ost/qpskfe - for a satellite frontend or /dev/ost/qamfe for a cable frontend) - for subsequent use. - - The device can be opened in read-only mode, which only allows - monitoring of device status and statistics, or read/write mode, which allows - any kind of use (e.g. performing tuning operations.) - - In a system with multiple front-ends, it is usually the case that multiple - devices cannot be open in read/write mode simultaneously. As long as a - front-end device is opened in read/write mode, other open() calls in - read/write mode will either fail or block, depending on whether - non-blocking or blocking mode was specified. - A front-end device opened in blocking mode can later be put into non-blocking - mode (and vice versa) using the F\_SETFL command of the fcntl system call. - This is a standard system call, documented in the Linux manual page for fcntl. - When an open() call has succeeded, the device will be ready for use in the - specified mode. This implies that the corresponding hardware is powered up, - and that other front-ends may have been powered down to make that possible. - - }{ - const char *deviceName & Name of specific video device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ - & \hspace{1em} (blocking mode is the default)\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EINTERNAL & Internal error.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened front-end device. - After closing a front-end device, its corresponding hardware might be - powered down automatically, but only when this is needed to open - another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST\_SET\_POWER\_STATE ioctl. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{OST\_SELFTEST}{ - int ioctl(int fd, int request = OST\_SELFTEST);}{ - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SELFTEST for this command.\\ - }{ - -1& Self test failure.\\ -} - -\ifunction{OST\_SET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time.\\ - A device that implements this call does not necessarily support two low-power - modes. If it only supports one low-power state, or none at all, the - OST\_SET\_POWER\_STATE operation for the missing states will - still succeed, but - it will be mapped to an existing state as per this table: \\ - \begin{center} - \begin{tabular}[h]{cll} - number of low-power & requested state & resulting state\\ - states supported &&\\ - \\ - 1 & standby & suspend \\ - 1 & suspend & suspend \\ - 0 & standby & on \\ - 0 & suspend & on - \end{tabular} - \end{center}\\ - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again.\\ - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SET\_POWER\_STATE for this command.\\ - uint32\_t state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& turn power on\\ - OST\_POWER\_STANDBY& set device in standby mode\\ - OST\_POWER\_SUSPEND& set device in suspend mode\\ - OST\_POWER\_OFF& turn power off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EPERM & Permission denied (needs read/write access).\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_GET\_POWER\_STATE for this command.\\ - uint32\_t *state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& power is on\\ - OST\_POWER\_STANDBY& device in standby mode\\ - OST\_POWER\_SUSPEND& device in suspend mode\\ - OST\_POWER\_OFF& power is off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EFAULT& state points to invalid address.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_STATUS}{ - int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ - This ioctl call returns status information about the front-end. - This call only requires read-only access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_STATUS for this command.\\ - struct feStatus *status&Points to the location where the front-end - status word is to be stored. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& status points to invalid address.\\ -} - -\ifunction{FE\_READ\_BER}{ - int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ - This ioctl call returns the bit error rate for the signal currently - received/demodulated by the front-end. For this command, read-only access - to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_BER for this command.\\ - uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, - is stored into *ber.\\ - & Example: a value of 2500 corresponds to a bit error - rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& ber points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful bit error - rate. Also returned if the front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_SNR}{ - int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ - This ioctl call returns the signal-to-noise ratio for the signal currently - received by the front-end. For this command, read-only access to the device - is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_READ\_SNR for this command.\\ - int32\_t *snr& The signal-to-noise ratio, as a multiple of - $10^{-6}$ dB, is stored into *snr.\\ - & Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& snr points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful signal - strength value. Also returned if front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ - int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); -}{ -This ioctl call returns the signal strength value for the signal currently -received by the front-end. For this command, read-only access to the device -is sufficient. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ -int32\_t *strength & The signal strength value, as a multiple of - $10^{-6 }$ dBm, - is stored into *strength. \\ - &Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& status points to invalid address.\\ - ENOSIGNAL& There is no signal, thus no meaningful signal - strength value. Also returned if front-end is not turned on.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ - int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ - This ioctl call returns the number of uncorrected blocks detected by - the device driver during its lifetime. - For meaningful measurements, the increment in - block count during a specific time interval should be calculated. - For this command, read-only access to the device is sufficient.\\ - Note that the counter will wrap to zero after its maximum count has - been reached. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ -uint32\_t *ublocks & The total number of uncorrected blocks seen -by the driver so far. -}{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& ublocks points to invalid address.\\ - ENOSYS& Function not available for this device. -} - - -\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient.\\ - Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ - uint32\_t *freq& Input: a given frequency \\ - & Output: the frequency corresponding to - the next higher frequency setting.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& freq points to invalid address.\\ - EINVAL& Maximum supported frequency reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); - }{ - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ - uint32\_t *symbolRate& Input: a given symbol rate \\ - & Output: the symbol rate corresponding to - the next higher symbol rate.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& symbolRate points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_SET\_FRONTEND}{ - int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ - This ioctl call starts a tuning operation using specified parameters. - The result of this call will be successful if the parameters were valid and - the tuning could be initiated. - The result of the tuning operation in itself, however, will arrive - asynchronously as an event (see documentation for FE\_GET\_EVENT - and FrontendEvent.) - If a new FE\_SET\_FRONTEND operation is initiated before the previous - one was completed, - the previous operation will be aborted in favor of the new one. - This command requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_SET\_FRONTEND for this command.\\ - struct FrontendParameters *p& Points to parameters for tuning operation.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& p points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ -} - -\ifunction{FE\_GET\_EVENT}{ - int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ - This ioctl call returns an event of type qpskEvent if available. If an event - is not available, the behavior depends on whether the device is in blocking - or non-blocking mode. In the latter case, the call fails immediately with - errno set to EWOULDBLOCK. In the former case, the call blocks until an event - becomes available.\\ - The standard Linux poll() and/or select() system calls can be used with the - device file descriptor to watch for new events. For select(), the file - descriptor should be included in the exceptfds argument, and for poll(), - POLLPRI should be specified as the wake-up condition. - Since the event queue allocated is rather small (room for 8 events), the queue - must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs - the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as - usual.\\ - For the sake of implementation simplicity, this command requires read/write - access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals QPSK\_GET\_EVENT for this command.\\ - struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& ev points to invalid address.\\ - EWOULDBLOCK & There is no event pending, and the device is in - non-blocking mode.\\ - EBUFFEROVERFLOW &\\ -& Overflow in event queue - one or more events were lost.\\ -} - -\ifunction{FE\_GET\_INFO}{ - int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ - This ioctl call returns information about the front-end. - This call only requires read-only access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_INFO for this command.\\ - struct qpskFrontendInfo *info & Points to the location where the front-end - information is to be stored. - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& info points to invalid address.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/getbb b/dvb-spec/dvbapi/getbb deleted file mode 100755 index 004714d3a..000000000 --- a/dvb-spec/dvbapi/getbb +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -f=`grep BoundingBox $2 | cut -d' ' -f2,3,4,5` -g=`\ -echo $2" llx=";(echo $f|cut -d' ' -f1 );\ -echo " lly=";(echo $f|cut -d' ' -f2 );\ -echo " urx=";(echo $f|cut -d' ' -f3 );\ -echo " ury=";(echo $f|cut -d' ' -f4 );\ -echo " rwi=";(echo $f|cut -d' ' -f3 );\ -echo "0" -` -h=`echo $g| sed "s/= /=/g" | sed "s/ 0/0/g"` -cat $1 | sed "s/psfile=$2/psfile=$h/" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex deleted file mode 100644 index 1d859fadb..000000000 --- a/dvb-spec/dvbapi/intro.tex +++ /dev/null @@ -1,183 +0,0 @@ -\chapter{Introduction} -%\addcontentsline{toc}{part}{Introduction} -%\chaptermark{Introduction} -\section{What you need to know} -The reader of this document is required to have some knowledge in the -area of digital video broadcasting (DVB) and should be familiar with -part I of ISO/IEC 13818, i.e you should know what a -program/transport stream (PS/TS) is and what is meant by a packetized elementary -stream (PES) or an I-frame. - -It is also necessary to know how to access unix/linux devices and how -to use ioctl calls. This also includes the knowledge of C or C++. -\section{History} - -The first API for DVB cards we used at Convergence in late 1999 -was an extension of the Video4Linux API which was primarily -developed for frame grabber cards. -As such it was not really well suited to be used for DVB cards and -their new features like recording MPEG streams and filtering several -section and PES data streams at the same time. - -In early 2000, we were approached by Nokia with a proposal for a new -standard Linux DVB API. -As a commitment to the development of terminals based on open standards, -Nokia and Convergence made it available to all Linux developers and -published it on \texttt{http://www.linuxtv.org/} in September 2000. -Convergence is the maintainer of the Linux DVB API. -Together with the LinuxTV community (i.e. you, the reader of this document), -the Linux DVB API will be constantly reviewed and improved upon. -With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence -provides a first implementation of the Linux DVB API. - - -\section{Overview} - -\begin{figure}[htbp] - \begin{center} - \includegraphics{dvbstb.ps} - \caption{Components of a DVB card/STB} - \label{fig:dvbstb} - \end{center} -\end{figure} - - -A DVB PCI card or DVB set-top-box (STB) usually consists of the following -main hardware components: -\begin{itemize} -\item Frontend consisting of tuner and DVB demodulator - -Here the raw signal reaches the DVB hardware from a satellite dish or antenna -or directly from cable. The frontend down-converts and demodulates -this signal into an MPEG transport stream (TS). - -\item SEC for controlling external hardware like LNBs and antennas - -This part of the hardware can send signals back through the satellite -cable to control the polarization of the LNB, to switch between -different LNBs or even to control the movements of a dish rotor. - - -\item Conditional Access (CA) hardware like CI adapters and smartcard slots - -The complete TS is passed through the CA hardware. Programs to which -the user has access (controlled by the smart card) are decoded in real -time and re-inserted into the TS. - -\item Demultiplexer which filters the incoming DVB stream - -The demultiplexer splits the TS into its components like audio and video -streams. Besides usually several of such audio and video streams it also -contains data streams with information about the programs offered in this -or other streams of the same provider. - -\item MPEG2 audio and video decoder - -The main targets of the demultiplexer are the MPEG2 audio and video -decoders. After decoding the pass on the uncompressed audio -and video to the computer screen or (through a PAL/NTSC encoder) to -a TV set. -\end{itemize} -Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow -between those components. - -On a DVB PCI card not all of these have to be present since some -functionality can be provided by the main CPU of the PC (e.g. MPEG picture -and sound decoding) or is not needed (e.g. for data-only uses like -``internet over satellite''). -Also not every card or STB provides conditional access hardware. - -\section{Linux DVB Devices} - -The Linux DVB API lets you control these hardware components -through currently six Unix-style character devices for -video, audio, frontend, SEC, demux and CA. -The video and audio devices control the MPEG2 decoder hardware, -the frontend device the tuner and the DVB demodulator. -External hardware like DiSEqC switches and rotors can be controlled -through the SEC device. -The demux device gives you control over the PES and section filters -of the hardware. If the hardware does not support filtering these filters -can be implemented in software. -Finally, the CA device controls all the conditional access capabilities -of the hardware. It can depend on the individual security requirements -of the platform, if and how many of the CA functions are made available -to the application through this device. - -All devices can be found in the \texttt{/dev} tree under -\texttt{/dev/ost}, where OST stands for Open Standards Terminal. -The individual devices are called -\begin{itemize} -\item \texttt{/dev/ost/audio}, -\item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/frontend}, -\item \texttt{/dev/ost/sec}, -\item \texttt{/dev/ost/demux}, -\item \texttt{/dev/ost/ca}, -\end{itemize} -but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of -these devices. - -If more than one card is present in the system the other cards -can be accessed through the corresponding devices with the -card's number appended. \texttt{/dev/ost/demux0} (which -is identical to \texttt{/dev/ost/demux}) would, e.g., control the -demultiplexer of the first card, while \texttt{/dev/ost/demux1} -would control the demultiplexer of the second card, and so on. - -More details about the data structures and function calls of -all the devices are described in the following chapters. - - -\section{DVB Devices with Devfs} - -Recent Linux kernel versions support a special file system called -\textsl{devfs} which is a replacement for the traditional -device directory. -With devfs a Linux DVB driver will only create those device file entries -which actually exist. -It also makes dealing with more complex DVB hardware much easier. -The device structure described above is not well suited to deal -with multiple DVB cards with more than one frontend or demultiplexer. -Consider, e.g., two DVB cards, one with two frontends and -one demultiplexer, the other with one frontend and two demultiplexers. -If we just assign them consecutive numbers, there would be a demultiplexer -and a frontend which do not belong to the same card but have -the same number. - -With \textsl{devfs} we propose a different scheme for the device names. -The root directory for all DVB cards will be \texttt{/dev/dvb}. -Each card gets assigned a sub-directory with the name \texttt{/dev/card0}, -\texttt{/dev/card1}, etc. -The files created in these sub-directories will correspond directly to the -hardware actually present on the card. -Thus, if the first card has one QAM frontend, one demultiplexer -and otherwise no other hardware, -only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0} -will be created. -When a second DVB-S card with one frontend (including SEC) device, -two demultiplexers and an MPEG2 audio/video decoder is added, the -complete \texttt{/dev/dvb} tree will look like this: - -\begin{verbatim} -/dev/dvb/card0/frontend0 - demux0 - -/dev/dvb/card1/video0 - audio0 - demux0 - demux1 - frontend0 - sec0 -\end{verbatim} - - -\section{Using the Devices} - -\dots - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex deleted file mode 100644 index 59490299b..000000000 --- a/dvb-spec/dvbapi/kdapi.tex +++ /dev/null @@ -1,1007 +0,0 @@ -\devsec{Kernel Demux API} - -The kernel demux API - -\devsubsec{Kernel Demux Data Types} - -\devsubsubsec{dmx\_success\_t} -\label{dmxsuccesst} - -\begin{verbatim} -typedef enum { - DMX_OK = 0, /* Received Ok */ - DMX_LENGTH_ERROR, /* Incorrect length */ - DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ - DMX_CRC_ERROR, /* Incorrect CRC */ - DMX_FRAME_ERROR, /* Frame alignment error */ - DMX_FIFO_ERROR, /* Receiver FIFO overrun */ - DMX_MISSED_ERROR /* Receiver missed packet */ -} dmx_success_t; -\end{verbatim} - - -\devsubsubsec{TS filter types} -\label{tsfiltertypes} - -\begin{verbatim} -/*--------------------------------------------------------------------------*/ -/* TS packet reception */ -/*--------------------------------------------------------------------------*/ - -/* TS filter type for set_type() */ - -#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */ -#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS - payload (<=184 bytes per packet) to callback */ -#define TS_DECODER 4 /* send stream to built-in decoder (if present) */ -\end{verbatim} - - -\devsubsubsec{dmx\_ts\_pes\_t} -\label{dmxtspest} - -The structure -\begin{verbatim} -typedef enum -{ - DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ - DMX_TS_PES_VIDEO, /* ... */ - DMX_TS_PES_TELETEXT, - DMX_TS_PES_SUBTITLE, - DMX_TS_PES_PCR, - DMX_TS_PES_OTHER, -} dmx_ts_pes_t; -\end{verbatim} -describes the PES type for filters which write to -a built-in decoder. -The correspond (and should be kept identical) to the types in -the demux device. - -\begin{verbatim} -struct dmx_ts_feed_s { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_ts_feed_s* feed, - __u16 pid, - size_t callback_length, - size_t circular_buffer_size, - int descramble, - struct timespec timeout); - int (*start_filtering) (struct dmx_ts_feed_s* feed); - int (*stop_filtering) (struct dmx_ts_feed_s* feed); - int (*set_type) (struct dmx_ts_feed_s* feed, - int type, - dmx_ts_pes_t pes_type); -}; - -typedef struct dmx_ts_feed_s dmx_ts_feed_t; -\end{verbatim} - -\begin{verbatim} -/*--------------------------------------------------------------------------*/ -/* PES packet reception (not supported yet) */ -/*--------------------------------------------------------------------------*/ - -typedef struct dmx_pes_filter_s { - struct dmx_pes_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ -} dmx_pes_filter_t; -\end{verbatim} - -\begin{verbatim} -typedef struct dmx_pes_feed_s { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_pes_feed_s* feed, - __u16 pid, - size_t circular_buffer_size, - int descramble, - struct timespec timeout); - int (*start_filtering) (struct dmx_pes_feed_s* feed); - int (*stop_filtering) (struct dmx_pes_feed_s* feed); - int (*allocate_filter) (struct dmx_pes_feed_s* feed, - dmx_pes_filter_t** filter); - int (*release_filter) (struct dmx_pes_feed_s* feed, - dmx_pes_filter_t* filter); -} dmx_pes_feed_t; -\end{verbatim} - - -\label{sectionfilter} -\begin{verbatim} -typedef struct { - __u8 filter_value [DMX_MAX_FILTER_SIZE]; - __u8 filter_mask [DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ -} dmx_section_filter_t; -\end{verbatim} - -\begin{verbatim} -struct dmx_section_feed_s { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_section_feed_s* feed, - __u16 pid, - size_t circular_buffer_size, - int descramble, - int check_crc); - int (*allocate_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t** filter); - int (*release_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t* filter); - int (*start_filtering) (struct dmx_section_feed_s* feed); - int (*stop_filtering) (struct dmx_section_feed_s* feed); -}; -typedef struct dmx_section_feed_s dmx_section_feed_t; - -/*--------------------------------------------------------------------------*/ -/* Callback functions */ -/*--------------------------------------------------------------------------*/ - -typedef int (*dmx_ts_cb) ( __u8 * buffer1, - size_t buffer1_length, - __u8 * buffer2, - size_t buffer2_length, - dmx_ts_feed_t* source, - dmx_success_t success); - -typedef int (*dmx_section_cb) ( __u8 * buffer1, - size_t buffer1_len, - __u8 * buffer2, - size_t buffer2_len, - dmx_section_filter_t * source, - dmx_success_t success); - -typedef int (*dmx_pes_cb) ( __u8 * buffer1, - size_t buffer1_len, - __u8 * buffer2, - size_t buffer2_len, - dmx_pes_filter_t* source, - dmx_success_t success); - -/*--------------------------------------------------------------------------*/ -/* DVB Front-End */ -/*--------------------------------------------------------------------------*/ - -typedef enum { - DMX_OTHER_FE = 0, - DMX_SATELLITE_FE, - DMX_CABLE_FE, - DMX_TERRESTRIAL_FE, - DMX_LVDS_FE, - DMX_ASI_FE, /* DVB-ASI interface */ - DMX_MEMORY_FE -} dmx_frontend_source_t; - -typedef struct { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique front-end identifier */ - char* vendor; /* Name of the front-end vendor */ - char* model; /* Name of the front-end model */ - struct list_head connectivity_list; /* List of front-ends that can - be connected to a particular - demux */ - void* priv; /* Pointer to private data of the API client */ - dmx_frontend_source_t source; -} dmx_frontend_t; - -/*--------------------------------------------------------------------------*/ -/* MPEG-2 TS Demux */ -/*--------------------------------------------------------------------------*/ - -/* - * Flags OR'ed in the capabilites field of struct dmx_demux_s. - */ - -#define DMX_TS_FILTERING 1 -#define DMX_PES_FILTERING 2 -#define DMX_SECTION_FILTERING 4 -#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ -#define DMX_CRC_CHECKING 16 -#define DMX_TS_DESCRAMBLING 32 -#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 -#define DMX_MAC_ADDRESS_DESCRAMBLING 128 -\end{verbatim} - -\devsubsubsec{demux\_demux\_t} -\label{demuxdemuxt} - -\begin{verbatim} -/* - * DMX_FE_ENTRY(): Casts elements in the list of registered - * front-ends from the generic type struct list_head - * to the type * dmx_frontend_t - *. -*/ - -#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) - -struct dmx_demux_s { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique demux identifier */ - char* vendor; /* Name of the demux vendor */ - char* model; /* Name of the demux model */ - __u32 capabilities; /* Bitfield of capability flags */ - dmx_frontend_t* frontend; /* Front-end connected to the demux */ - struct list_head reg_list; /* List of registered demuxes */ - void* priv; /* Pointer to private data of the API client */ - int users; /* Number of users */ - int (*open) (struct dmx_demux_s* demux); - int (*close) (struct dmx_demux_s* demux); - int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); - int (*allocate_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t** feed, - dmx_ts_cb callback); - int (*release_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t* feed); - int (*allocate_pes_feed) (struct dmx_demux_s* demux, - dmx_pes_feed_t** feed, - dmx_pes_cb callback); - int (*release_pes_feed) (struct dmx_demux_s* demux, - dmx_pes_feed_t* feed); - int (*allocate_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t** feed, - dmx_section_cb callback); - int (*release_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t* feed); - int (*descramble_mac_address) (struct dmx_demux_s* demux, - __u8* buffer1, - size_t buffer1_length, - __u8* buffer2, - size_t buffer2_length, - __u16 pid); - int (*descramble_section_payload) (struct dmx_demux_s* demux, - __u8* buffer1, - size_t buffer1_length, - __u8* buffer2, size_t buffer2_length, - __u16 pid); - int (*add_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*remove_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - struct list_head* (*get_frontends) (struct dmx_demux_s* demux); - int (*connect_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*disconnect_frontend) (struct dmx_demux_s* demux); - - - /* added because js cannot keep track of these himself */ - int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids); -}; -typedef struct dmx_demux_s dmx_demux_t; -\end{verbatim} - - -\devsubsubsec{Demux directory} -\label{demuxdir} - -\begin{verbatim} -/* - * DMX_DIR_ENTRY(): Casts elements in the list of registered - * demuxes from the generic type struct list_head* to the type dmx_demux_t - *. - */ - -#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) - -int dmx_register_demux (dmx_demux_t* demux); -int dmx_unregister_demux (dmx_demux_t* demux); -struct list_head* dmx_get_demuxes (void); -\end{verbatim} - -\clearpage - -\devsubsec{Demux Directory API} - -The demux directory is a Linux kernel-wide facility for registering and -accessing the MPEG-2 TS demuxes in the system. Run-time registering and -unregistering of demux drivers is possible using this API. - -All demux drivers in the directory implement the abstract interface dmx\_demux\_t. - -\kifunction{dmx\_register\_demux()}{ - int dmx\_register\_demux ( dmx\_demux\_t *demux ) - }{ - This function makes a demux driver interface available to the Linux kernel. - It is usually called by the init\_module() function of the kernel module that - contains the demux driver. The caller of this function is responsible for - allocating dynamic or static memory for the demux structure and for initializing - its fields before calling this function. - The memory allocated for the demux structure must not be freed before calling - dmx\_unregister\_demux(), - }{ - dmx\_demux\_t* demux & Pointer to the demux structure. - }{ - 0 & The function was completed without errors.\\ - -EEXIST & A demux with the same value of the id field - already stored in the directory.\\ - -ENOSPC & No space left in the directory. -} - -\kifunction{dmx\_unregister\_demux()}{ - int dmx\_unregister\_demux ( dmx\_demux\_t *demux ) - }{ - This function is called to indicate that the given demux interface is no longer - available. The caller of this function is responsible for freeing the memory of - the demux structure, if it was dynamically allocated before calling - dmx\_register\_demux(). - The cleanup\_module() function of the kernel module that contains the demux - driver should call this function. Note that this function fails if the demux - is currently in use, i.e., release\_demux() has not been called for the - interface. - }{ - dmx\_demux\_t* demux & Pointer to the demux structure which is to be unregistered. - }{ - 0 & The function was completed without errors.\\ - ENODEV & The specified demux is not registered in the demux directory.\\ - EBUSY & The specified demux is currently in use. -} - -\kifunction{dmx\_get\_demuxes()}{ - struct list\_head *dmx\_get\_demuxes () - }{ - Provides the caller with the list of registered demux interfaces, using the - standard list structure defined in the include file linux/list.h. - The include file demux.h defines the macro DMX\_DIR\_ENTRY() for converting an - element of the generic type struct list\_head* to the type dmx\_demux\_t*. - The caller must not free the memory of any of the elements obtained via this - function call. - }{ - none - }{ - struct list\_head * & - A list of demux interfaces, or NULL in the case of an empty list. -} - -\clearpage - -\devsubsec{Demux API} - -The demux API should be implemented for each demux in the system. It is used to -select the TS source of a demux and to manage the demux resources. When the -demux client allocates a resource via the demux API, it receives a pointer -to the API of that resource. - -Each demux receives its TS input from a DVB front-end or from memory, as -set via the demux API. In a system with more than one front-end, the API can -be used to select one of the DVB front-ends as a TS source for a demux, unless -this is fixed in the HW platform. The demux API only controls front-ends -regarding their connections with demuxes; the APIs used to set the other -front-end parameters, such as tuning, are not defined in this document. - -The functions that implement the abstract interface demux should be defined -static or module private and registered to the Demux Directory for external -access. It is not necessary to implement every function in the demux\_t struct, -however (for example, a demux interface might support Section filtering, but -not TS or PES filtering). The API client is expected to check the value of any -function pointer before calling the function: the value of NULL means ``function -not available''. - -Whenever the functions of the demux API modify shared data, the possibilities -of lost update and race condition problems should be addressed, e.g. by -protecting parts of code with mutexes. This is especially important on -multi-processor hosts. - -Note that functions called from a bottom half context must not sleep, at least -in the 2.2.x kernels. Even a simple memory allocation can result in a kernel -thread being put to sleep if swapping is needed. For example, the Linux kernel -calls the functions of a network device interface from a bottom half context. -Thus, if a demux API function is called from network device code, the function -must not sleep. - -\kfunction{open()}{ - int open ( demux\_t* demux ); - }{ - This function reserves the demux for use by the caller and, if necessary, - initializes the demux. When the demux is no longer needed, the function close() - should be called. - It should be possible for multiple clients to access the demux at the same time. - Thus, the function implementation should increment the demux usage count when - open() is called and decrement it when close() is called. - }{ - demux\_t* demux & Pointer to the demux API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EUSERS & Maximum usage count reached.\\ - -EINVAL & Bad parameter. -} - -\kfunction{close()}{ - int close(demux\_t* demux); - }{ - This function reserves the demux for use by the caller and, if necessary, - initializes the demux. When the demux is no longer needed, the function close() - should be called. - It should be possible for multiple clients to access the demux at the same time. - Thus, the function implementation should increment the demux usage count when - open() is called and decrement it when close() is called. - }{ - demux\_t* demux & Pointer to the demux API and instance data. - }{ - 0 & The function was completed without errors.\\ - -ENODEV & The demux was not in use.\\ - -EINVAL & Bad parameter. -} - -\kfunction{write()}{ - int write(demux\_t* demux, const char* buf, size\_t count); - }{ - This function provides the demux driver with a memory buffer containing TS - packets. Instead of receiving TS packets from the DVB front-end, the demux - driver software will read packets from memory. Any clients of this demux - with active TS, PES or Section filters will receive filtered data via the Demux - callback API (see 0). The function returns when all the data in the buffer has - been consumed by the demux. - Demux hardware typically cannot read TS from memory. If this is the case, - memory-based filtering has to be implemented entirely in software. - }{ - demux\_t* demux & Pointer to the demux API and instance data.\\ - const char* buf & Pointer to the TS data in kernel-space memory.\\ - size\_t length & Length of the TS data. - }{ - 0 & The function was completed without errors.\\ - -ENOSYS & The command is not implemented.\\ - -EINVAL & Bad parameter. -} - -\kifunction{allocate\_ts\_feed()}{ - int allocate\_ts\_feed(dmx\_demux\_t* demux, - dmx\_ts\_feed\_t** feed, dmx\_ts\_cb callback); - }{ - Allocates a new TS feed, which is used to filter the TS packets carrying a - certain PID. - The TS feed normally corresponds to a hardware PID filter on the demux chip. - }{ - demux\_t* demux & Pointer to the demux API and instance data.\\ - dmx\_ts\_feed\_t** feed & Pointer to the TS feed API and instance data.\\ - dmx\_ts\_cb callback & Pointer to the callback function for - passing received TS packet - }{ - 0 & The function was completed without errors.\\ - -EBUSY & No more TS feeds available.\\ - -ENOSYS & The command is not implemented.\\ - -EINVAL & Bad parameter. -} - -\kifunction{release\_ts\_feed()}{ - int release\_ts\_feed(dmx\_demux\_t* demux, dmx\_ts\_feed\_t* feed); - }{ - Releases the resources allocated with allocate\_ts\_feed(). Any filtering in progress - on the TS feed should be stopped before calling this function. - }{ - demux\_t* demux & Pointer to the demux API and instance data.\\ - dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\kifunction{allocate\_section\_feed()}{ - int allocate\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t **feed, - dmx\_section\_cb callback); - }{ - Allocates a new section feed, i.e. a demux resource for filtering and - receiving sections. - On platforms with hardware support for section filtering, a section feed is directly - mapped to the demux HW. On other platforms, TS packets are first PID filtered in - hardware and a hardware section filter then emulated in software. - The caller obtains an API pointer of type dmx\_section\_feed\_t as an out parameter. - Using this API the caller can set filtering parameters and start receiving sections. - }{ - demux\_t *demux & Pointer to the demux API and instance data.\\ - dmx\_section\_feed\_t **feed & Pointer to the section feed API and instance data.\\ - dmx\_section\_cb callback & Pointer to the callback function for - passing received sections. - }{ - 0 & The function was completed without errors.\\ - -EBUSY & No more section feeds available.\\ - -ENOSYS & The command is not implemented.\\ - -EINVAL & Bad parameter. -} - - -\kifunction{release\_section\_feed()}{ - int release\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t *feed); - }{ - Releases the resources allocated with allocate\_section\_feed(), including allocated - filters. - Any filtering in progress on the section feed should be stopped before calling - this function. - }{ - demux\_t *demux & Pointer to the demux API and instance data.\\ - dmx\_section\_feed\_t *feed & Pointer to the section feed API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\kifunction{descramble\_mac\_address()}{ - int descramble\_mac\_address(dmx\_demux\_t* demux, - \_\_u8 *buffer1, size\_t buffer1\_length, - \_\_u8 *buffer2, size\_t buffer2\_length, \_\_u16 pid); - }{ - This function runs a descrambling algorithm on the destination MAC address field of a - DVB Datagram Section, replacing the original address with its un-encrypted version. - Otherwise, the description on the function descramble\_section\_payload() applies - also to this function. - }{ - dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ - \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ - size\_t buffer1\_length & Length of the section data, including headers and CRC, - in buffer1.\\ - \_\_u8* buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a - non-NULL value if the section wraps - past the end of a circular buffer.\\ - size\_t buffer2\_length & Length of the section data, - including headers and CRC, in buffer2.\\ - \_\_u16 pid & The PID on which the section was received. Useful for obtaining the - descrambling key, e.g. from a DVB Common Access facility. - }{ - 0 & The function was completed without errors.\\ - -ENOSYS & No descrambling facility available.\\ - -EINVAL & Bad parameter. -} - -\kifunction{descramble\_section\_payload()}{ - int descramble\_section\_payload(dmx\_demux\_t* demux, - \_\_u8 *buffer1, size\_t buffer1\_length, \_\_u8 *buffer2, size\_t - buffer2\_length, \_\_u16 pid); - }{ - This function runs a descrambling algorithm on the payload of a DVB Datagram - Section, replacing the original payload with its un-encrypted version. - The function will - be called from the demux API implementation; the API client need - not call this function directly. - Section-level scrambling algorithms are currently standardized only for DVB-RCC - (return channel over 2-directional cable TV network) systems. For all other DVB - networks, encryption schemes are likely to be proprietary to each data broadcaster. - Thus, it is expected that this function pointer will have the value of NULL - (i.e., function not available) in most demux API implementations. - Nevertheless, it should be possible - to use the function pointer as a hook for dynamically adding a ``plug-in'' - descrambling facility to a demux driver.\\ - While this function is not needed with hardware-based section descrambling, the - descramble\_section\_payload function pointer can be used to override the default - hardware-based descrambling algorithm: if the function pointer has a non-NULL value, - the corresponding function should be used instead of any descrambling hardware. - }{ - dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ - \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ - size\_t buffer1\_length & Length of the section data, including headers and CRC, in - buffer1.\\ - \_\_u8 *buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a - non-NULL value if the section wraps - past the end of a circular buffer.\\ - size\_t buffer2\_length & Length of the section data, including headers and CRC, in - buffer2.\\ - \_\_u16 pid & The PID on which the section was received. Useful for obtaining the - descrambling key, e.g. from a DVB Common Access facility. - }{ - 0 & The function was completed without errors.\\ - -ENOSYS & No descrambling facility available.\\ - -EINVAL & Bad parameter. -} - -\kifunction{add\_frontend()}{ - int add\_frontend(dmx\_demux\_t *demux, dmx\_frontend\_t *frontend); - }{ - Registers a connectivity between a demux and a front-end, i.e., indicates that the - demux can be connected via a call to connect\_frontend() to use the given front-end - as a TS source. The client of this function has to allocate dynamic or static - memory for - the frontend structure and initialize its fields before calling this function. - This function is normally called during the driver initialization. - The caller must not free - the memory of the frontend struct before successfully calling remove\_frontend(). - }{ - dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ - dmx\_frontend\_t* frontend & Pointer to the front-end instance data. - }{ - 0 & The function was completed without errors.\\ - -EEXIST & A front-end with the same value of the id field already registered.\\ - -EINUSE & The demux is in use.\\ - -ENOMEM & No more front-ends can be added.\\ - -EINVAL & Bad parameter. -} - -\kifunction{remove\_frontend()}{ - int remove\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); - }{ - Indicates that the given front-end, registered by a call to add\_frontend(), can no - longer be connected as a TS source by this demux. The function should be called - when a front-end driver or a demux driver is removed from the system. If the front-end - is in use, the function fails with the return value of -EBUSY. - After successfully calling this function, the caller can free the memory of - the frontend struct if it was dynamically allocated before the add\_frontend() - operation. - }{ - dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ - dmx\_frontend\_t* frontend & Pointer to the front-end instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter.\\ - -EBUSY & The front-end is in use, i.e. a call to - connect\_frontend() has not been followed by - a call to disconnect\_frontend(). -} - -\kifunction{get\_frontends()}{ - struct list\_head* get\_frontends(dmx\_demux\_t* demux); - }{ - Provides the APIs of the front-ends that have been registered for this demux. Any of - the front-ends obtained with this call can be used as a parameter for - connect\_frontend().\\ - The include file demux.h contains the macro DMX\_FE\_ENTRY() for converting an - element of the generic type struct list\_head* to the type dmx\_frontend\_t*. - The caller must not free the memory of any of the elements obtained via this function - call. - }{ - dmx\_demux\_t* demux & Pointer to the demux API and instance data. - }{ - dmx\_demux\_t* & A list of front-end interfaces, or NULL in the case of an empty list. -} - - -\kifunction{connect\_frontend()}{ - int connect\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); - }{ - Connects the TS output of the front-end to the input of the demux. A demux can only - be connected to a front-end registered to the demux with the function - add\_frontend().\\ - It may or may not be possible to connect multiple demuxes to the same front-end, - depending on the capabilities of the HW platform. When not used, the front-end should - be released by calling disconnect\_frontend(). - }{ - dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ - dmx\_frontend\_t* frontend & Pointer to the front-end instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter.\\ - -EBUSY & The front-end is in use. -} - -\kifunction{disconnect\_frontend()}{ - int disconnect\_frontend(dmx\_demux\_t* demux); - }{ - Disconnects the demux and a front-end previously connected by a - connect\_frontend() call. - }{ - dmx\_demux\_t* demux & Pointer to the demux API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\clearpage - -\devsubsec{Demux Callback API} - -This kernel-space API comprises the callback functions that deliver filtered data to the -demux client. Unlike the other APIs, these API functions are provided by the client and -called from the demux code. - -The function pointers of this abstract interface are not packed into a structure -as in the -other demux APIs, because the callback functions are registered and used -independent of each other. As an example, it is possible for the API client to provide -several callback functions for receiving TS packets and no callbacks for PES packets -or sections. - -The functions that implement the callback API need not be re-entrant: when a demux -driver calls one of these functions, the driver is not allowed to call the -function again before the original call returns. -If a callback is triggered by a hardware interrupt, it is -recommended to use the Linux ``bottom half'' mechanism or start a tasklet instead of -making the callback function call directly from a hardware interrupt. - -\kifunction{dmx\_ts\_cb()}{ - int dmx\_ts\_cb(\_\_u8* buffer1, size\_t buffer1\_length, - \_\_u8* buffer2, size\_t buffer2\_length, - dmx\_ts\_feed\_t* source, dmx\_success\_t success); - }{ - This function, provided by the client of the demux API, is called from the - demux code. The function is only called when filtering on this TS feed has - been enabled using the start\_filtering() function. \\ - Any TS packets that match the filter settings are copied to a circular buffer. - The filtered TS packets are delivered to the client using this callback - function. The size of the circular buffer is controlled by the - circular\_buffer\_size parameter of the set() function in the TS Feed API. It is - expected that the buffer1 and buffer2 callback parameters point to addresses - within the circular buffer, but other implementations are also - possible. Note that the called party should not try to free the memory the - buffer1 and buffer2 parameters point to.\\ - When this function is called, the buffer1 parameter typically points to the - start of the first undelivered TS packet within a circular buffer. The buffer2 - buffer parameter is normally NULL, except when the received TS packets have - crossed the last address of the circular buffer and "wrapped" to the beginning - of the buffer. In the latter case the buffer1 parameter would contain an - address within the circular buffer, while the buffer2 parameter would contain - the first address of the circular buffer.\\ - The number of bytes delivered with this function (i.e. buffer1\_length + - buffer2\_length) is usually equal to the value of callback\_length parameter given - in the set() function, with one exception: if a timeout occurs before receiving - callback\_length bytes of TS data, any undelivered packets are immediately - delivered to the client by calling this function. The timeout duration is - controlled by the set() function in the TS Feed API.\\ - If a TS packet is received with errors that could not be fixed by the TS-level - forward error correction (FEC), the Transport\_error\_indicator flag of the TS - packet header should be set. The TS packet should not be discarded, as the - error can possibly be corrected by a higher layer protocol. - If the called party is slow in processing the callback, it is possible that - the circular buffer eventually fills up. If this happens, the demux driver - should discard any TS packets received while the buffer is full. The error - should be indicated to the client on the next callback by setting the success - parameter to the value of DMX\_OVERRUN\_ERROR.\\ - The type of data returned to the callback can be selected by the - new function int (*set\_type) (struct dmx\_ts\_feed\_s* feed, int type, - dmx\_ts\_pes\_t pes\_type) which is part of the dmx\_ts\_feed\_s struct - (also cf. to the include file ost/demux.h) - The type parameter decides if the raw TS packet (TS\_PACKET) or just the - payload (TS\_PACKET|TS\_PAYLOAD\_ONLY) should be returned. - If additionally the TS\_DECODER bit is set the stream will also be sent - to the hardware MPEG decoder. In this case, the second flag decides - as what kind of data the stream should be interpreted. - The possible choices are one of DMX\_TS\_PES\_AUDIO, DMX\_TS\_PES\_VIDEO, - DMX\_TS\_PES\_TELETEXT, DMX\_TS\_PES\_SUBTITLE, DMX\_TS\_PES\_PCR, or - DMX\_TS\_PES\_OTHER. - }{ - \_\_u8* buffer1 & Pointer to the start of the filtered TS packets.\\ - size\_t buffer1\_length & Length of the TS data in buffer1.\\ - \_\_u8* buffer2 & Pointer to the tail of the filtered TS packets, or NULL.\\ - size\_t buffer2\_length & Length of the TS data in buffer2.\\ - dmx\_ts\_feed\_t* source & Indicates which TS feed is the source of the callback.\\ - dmx\_success\_t success & Indicates if there was an error in TS reception. - }{ - 0 & Continue filtering.\\ - -1& Stop filtering - has the same effect as a call - to stop\_filtering() on the TS Feed API. -} - -\kifunction{dmx\_section\_cb()}{ - int dmx\_section\_cb(\_\_u8* buffer1, size\_t buffer1\_length, \_\_u8* buffer2, - size\_t buffer2\_length, dmx\_section\_filter\_t* source, - dmx\_success\_t success); - }{ - This function, provided by the client of the demux API, is called from the demux code. - The function is only called when filtering of sections has been enabled using the - function start\_filtering() of the section feed API. - When the demux driver has received a complete section that matches at least one - section filter, the client is notified via this callback function. Normally this function is - called for each received section; however, it is also possible to deliver multiple sections - with one callback, for example when the system load is high. - If an error occurs while receiving a section, this function should be called with the - corresponding error type set in the success field, whether or not there is data to - deliver. - The Section Feed implementation should maintain a circular buffer for received sections. - However, this is not necessary if the Section Feed API is implemented as a client of - the TS Feed API, because the TS Feed implementation then buffers the - received data. - The size of the circular buffer can be configured using the set() function in the - Section Feed API. If there is no room in the circular buffer when a new section is - received, the section must be discarded. If this happens, the value of the success - parameter should be DMX\_OVERRUN\_ERROR on the next callback. - }{ - \_\_u8* buffer1 & Pointer to the start of the filtered section, e.g. - within the circular buffer of the demux driver.\\ - size\_t buffer1\_length & Length of the filtered section data in buffer1, - including headers and CRC.\\ - \_\_u8* buffer2 & Pointer to the tail of the filtered section data, or - NULL. Useful to handle the wrapping of a circular - buffer.\\ - size\_t buffer2\_length & Length of the filtered section data in buffer2, - including headers and CRC.\\ - dmx\_section\_filter\_t* filter & Indicates the filter that triggered the callback.\\ - dmx\_success\_t success & Indicates if there was an error in section reception. - }{ - 0 & Continue filtering.\\ - -1& Stop filtering - has the same effect as a call - to stop\_filtering() on the Section Feed API. -} - -\clearpage - -\devsubsec{TS Feed API} - -A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this -API, the client can set the filtering properties to start/stop filtering TS packets on a -particular TS feed. The API is defined as an abstract interface of the type -dmx\_ts\_feed\_t. - -The functions that implement the interface should be defined static or module -private. The client can get the handle of a TS feed API by calling the function -allocate\_ts\_feed() in the demux API. - -\kifunction{set()}{ - int set ( dmx\_ts\_feed\_t* feed, \_\_u16 pid, size\_t callback\_length, - size\_t circular\_buffer\_size, int descramble, struct timespec timeout); - }{ - This function sets the parameters of a TS feed. - Any filtering in progress on the TS feed - must be stopped before calling this function. - }{ - dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.\\ - \_\_u16 pid & PID value to filter. Only the TS packets carrying the specified PID will - be passed to the API client.\\ - size\_t callback\_length & Number of bytes to deliver with each - call to the dmx\_ts\_cb() callback - function. The value of this - parameter should be a multiple of 188.\\ - size\_t circular\_buffer\_size & Size of the circular buffer for the filtered TS packets.\\ - int descramble & If non-zero, descramble the filtered TS packets.\\ - struct timespec timeout & Maximum time to wait before - delivering received TS packets to the client. - }{ - 0 & The function was completed without errors.\\ - -ENOMEM & Not enough memory for the requested buffer size.\\ - -ENOSYS & No descrambling facility available for TS.\\ - -EINVAL & Bad parameter. -} - - -\kifunction{start\_filtering()}{ - int start\_filtering(dmx\_ts\_feed\_t* feed); - }{ - Starts filtering TS packets on this TS feed, according to its settings. - The PID value to filter can be set by the API client. - All matching TS packets are delivered asynchronously to the client, - using the callback function registered with allocate\_ts\_feed(). - }{ - dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\kifunction{stop\_filtering()}{ - int stop\_filtering(dmx\_ts\_feed\_t* feed); - }{ - Stops filtering TS packets on this TS feed. - }{ - dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\clearpage - -\devsubsec{Section Feed API} - -A section feed is a resource consisting of a PID filter and a set of section filters. -Using this API, the client can set the properties of a section feed and to -start/stop filtering. -The API is defined as an abstract interface of the type dmx\_section\_feed\_t. -The functions that implement the interface should be defined static or module -private. The client can get the handle of a section feed API by calling the function -allocate\_section\_feed() in the demux API. - -On demux platforms that provide section filtering in hardware, the Section Feed API -implementation provides a software wrapper for the demux hardware. Other platforms -may support only PID filtering in hardware, requiring that TS packets are converted to -sections in software. In the latter case the Section Feed API implementation can be a -client of the TS Feed API. - - -\kifunction{set()}{ - int set(dmx\_section\_feed\_t* feed, \_\_u16 pid, size\_t circular\_buffer\_size, - int descramble, int check\_crc); - }{ - This function sets the parameters of a section feed. Any filtering in progress on the - section feed must be stopped before calling this function. - If descrambling is enabled, the payload\_scrambling\_control and - address\_scrambling\_control fields of received DVB datagram sections should be - observed. If either one is non-zero, the section should be descrambled either in - hardware or using the functions descramble\_mac\_address() and - descramble\_section\_payload() of the demux API. Note that according to the - MPEG-2 Systems specification, only the payloads of private sections can be - scrambled while the rest of the section data must be sent in the clear. - }{ - dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ - \_\_u16 pid & PID value to filter; only the TS packets - carrying the specified PID will be accepted.\\ - size\_t circular\_buffer\_size & Size of the circular buffer for filtered sections.\\ - int descramble & If non-zero, descramble any sections that are scrambled.\\ - int check\_crc & If non-zero, check the CRC values of filtered sections. - }{ - 0 & The function was completed without errors.\\ - -ENOMEM & Not enough memory for the requested buffer size.\\ - -ENOSYS & No descrambling facility available for sections.\\ - -EINVAL & Bad parameters. -} - -\kifunction{allocate\_filter()}{ - int allocate\_filter(dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t** filter); - }{ - This function is used to allocate a section filter on the demux. - It should only be called when no filtering is in progress on this section feed. - If a filter cannot be allocated, the function fails with -ENOSPC. - See in section \ref{sectionfilter} for the format of the section filter. \\ - The bitfields filter\_mask and filter\_value should only be modified when no - filtering is in progress on this section feed. filter\_mask controls which bits of - filter\_value are compared with the section headers/payload. On a binary value of 1 - in filter\_mask, the corresponding bits are compared. The filter only accepts sections - that are equal to filter\_value in all the tested bit positions. Any changes to the - values of filter\_mask and filter\_value are guaranteed to take effect only when - the start\_filtering() function is called next time. The parent pointer in the struct - is initialized by the API implementation to the value of the feed parameter. The priv - pointer is not used by the API implementation, and can thus be freely utilized by the - caller of this function. Any data pointed to by the priv pointer is available to the - recipient of the dmx\_section\_cb() function call.\\ - While the maximum section filter length (DMX\_MAX\_FILTER\_SIZE) - is currently set at 16 bytes, hardware filters of that size are not - available on all platforms. Therefore, section filtering will often - take place first in hardware, followed by filtering in software for the - header bytes that were not covered by a hardware filter. - The filter\_mask field can be checked to determine how many bytes of - the section filter are actually used, and if the - hardware filter will suffice. Additionally, software-only section filters - can optionally be - allocated to clients when all hardware section filters are in use. - Note that on most demux hardware it is not possible to filter on the - section\_length field - of the section header -- thus this field is ignored, even though it is included in - filter\_value and filter\_mask fields. - }{ - dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ - dmx\_section\_filter\_t** filter & Pointer to the allocated filter. - }{ - 0 & The function was completed without errors.\\ - -ENOSPC & No filters of given type and length available.\\ - -EINVAL & Bad parameters. -} - -\kifunction{release\_filter()}{ - int release\_filter ( dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t* filter); - }{ - This function releases all the resources of a previously allocated section filter. - The function should not be called while filtering is in progress on this section feed. - After calling this function, the caller should not try to dereference the - filter pointer. - }{ - dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ - dmx\_section\_filter\_t* filter & I/O Pointer to the instance data of a section filter. - }{ - 0 & The function was completed without errors.\\ - -ENODEV & No such filter allocated.\\ - -EINVAL & Bad parameter. -} - -\kifunction{start\_filtering()}{ - int start\_filtering ( dmx\_section\_feed\_t* feed ); - }{ - Starts filtering sections on this section feed, according to its settings. - Sections are first filtered based on their PID and then matched with the - section filters allocated for this feed. - If the section matches the PID filter and at least one section filter, it is delivered - to the API client. The section is delivered asynchronously using the callback function - registered with allocate\_section\_feed(). - }{ - dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - -\kifunction{stop\_filtering()}{ - int stop\_filtering ( dmx\_section\_feed\_t* feed ); - }{ - Stops filtering sections on this section feed. Note that any changes to the - filtering parameters (filter\_value, filter\_mask, etc.) should only be made - when filtering is stopped. - }{ - dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data. - }{ - 0 & The function was completed without errors.\\ - -EINVAL & Bad parameter. -} - - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex deleted file mode 100644 index 88342c3a6..000000000 --- a/dvb-spec/dvbapi/sec.tex +++ /dev/null @@ -1,282 +0,0 @@ -\devsec{DVB SEC API} - -The DVB SEC device controls the Satellite Equipment Control of -the DVB hardware, i.e. DiSEqC and V-SEC. -It is accessed through \texttt{/dev/ost/sec}. - -\devsubsec{SEC Data Types} - -\devsubsubsec{secDiseqcCmd} -\label{secdiseqccmd} - -\begin{verbatim} -struct secDiseqcCmd { - uint8_t addr; - uint8_t cmd; - uint8_t numParams; - uint8_t params[SEC_MAX_DISEQC_PARAMS]; -}; -\end{verbatim} - - -\devsubsubsec{secVoltage} -\label{secvoltage} - -\begin{verbatim} -typedef uint32_t secVoltage; -\end{verbatim} -\begin{verbatim} -enum { - SEC_VOLTAGE_OFF, - SEC_VOLTAGE_LT, - SEC_VOLTAGE_13, - SEC_VOLTAGE_13_5, - SEC_VOLTAGE_18, - SEC_VOLTAGE_18_5 -}; -\end{verbatim} - - -\devsubsubsec{secToneMode} -\label{sectonemode} - -\begin{verbatim} -typedef uint32_t secToneMode; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_TONE_ON, - SEC_TONE_OFF -} secToneMode_t; -\end{verbatim} - - -\devsubsubsec{secMiniCmd} -\label{secminicmd} - -\begin{verbatim} -typedef uint32_t secMiniCmd; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_MINI_NONE, - SEC_MINI_A, - SEC_MINI_B -} secMiniCmd_t; -\end{verbatim} -\begin{verbatim} -struct secStatus { - int32_t busMode; - secVoltage selVolt; - secToneMode contTone; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_BUS_IDLE, - SEC_BUS_BUSY, - SEC_BUS_OFF, - SEC_BUS_OVERLOAD -}; -\end{verbatim} - - -\devsubsubsec{secCommand} -\label{seccommand} - -\begin{verbatim} -struct secCommand { - int32_t type; - union { - struct secDiseqcCmd diseqc; - uint8_t vsec; - uint32_t pause; - } u; -}; -\end{verbatim} - - -\devsubsubsec{secCmdSequence} -\label{seccmdsequence} - -\begin{verbatim} -struct secCmdSequence { - secVoltage voltage; - secMiniCmd miniCommand; - secToneMode continuousTone; - - uint32_t numCommands; - struct secCommand* commands; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_CMDTYPE_DISEQC, - SEC_CMDTYPE_VSEC, - SEC_CMDTYPE_PAUSE -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - SEC_DISEQC_SENT, - SEC_VSEC_SENT, - SEC_PAUSE_COMPLETE, - SEC_CALLBACK_ERROR -} secCallback_t; -\end{verbatim} - -\clearpage - -\devsubsec{SEC Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named SEC device for subsequent use. - If the device is opened in read-only mode, only status and statistics - monitoring is allowed. If the device is opened in read/write mode, all - types of operations can be performed. - Any number of applications can have simultaneous access to the device. - }{ - const char *deviceName & Name of specific SEC device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set, - open() and most other subsequent calls to the device will return -1 and - set errno to EWOULDBLOCK. - The communication with the peripheral devices is sequential by nature, - so it is probably preferable to use the device in synchronous mode. - This is the motivation for not going through the extra effort of - implementing asynchronous operation of the device. - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & deviceName does not refer to a valid memory area.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened SEC device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{SEC\_GET\_STATUS}{ - int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{ - This call gets the status of the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_GET\_STATUS for this command.\\ - struct secStatus* status & The status of the device.\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & status is an invalid pointer.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ - EPERM & File not opened with read permissions.\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_RESET\_OVERLOAD}{ - int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{ - If the bus has been automatically powered off due to power overload, this - ioctl call restores the power to the bus. The call requires read/write - access to the device. - This call has no effect if the device is manually powered off. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_RESET\_OVERLOAD for this command.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_SEND\_SEQUENCE}{ -int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); -}{ -This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC -commands. The first version of the SEC device does not support V-SEC -signaling and it aborts the operation with an error code if a V-SEC -command is detected in the input data.\\ -\begin{itemize} -\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is -overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be -called and the operation can be retried. -\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE, -the bus voltage will be switched and the continuous 22kHz tone -generation enabled/disabled immediately. -\end{itemize}\\ -This operation is atomic. If several processes calls this ioctl -simultaneously, the operations will be serialized so a complete sequence -is sent at a time. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_SEND\_SEQUENCE for this command.\\ - struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EFAULT & Seq points to an invalid address.\\ - EINVAL & The data structure referred to by seq is invalid in some way.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ - EBUSMODE & The device is not prepared for transmission - (e.g. it might be manually powered off).\\ - EBUSOVERLOAD & Bus overload has occurred.\\ -} - - -\ifunction{SEC\_SET\_TONE}{ -int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone); -}{ -This call is used to set the generation of the continuous 22kHz tone. -The possibility to just change the tone mode is already provided by -ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_TONE will block if a transmission is in -progress. This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_TONE for this command.\\ -secToneMode tone & The requested tone generation mode (on/off).\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - - -\ifunction{SEC\_SET\_VOLTAGE}{ -int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage); -}{ -This call is used to set the bus voltage. The possibility to just change -the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but -SEC\_SET\_VOLTAGE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in -progress. -This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_VOLTAGE for this command.\\ -secVoltage voltage & The requested bus voltage.\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex deleted file mode 100644 index 574464d23..000000000 --- a/dvb-spec/dvbapi/title.tex +++ /dev/null @@ -1,24 +0,0 @@ -\pagenumbering{arabic} -\pagestyle{empty} -\title{\huge\textbf{LINUX DVB API}} - -\author{ -\includegraphics{cimlogo.psi}\\ - Convergence integrated media GmbH\\\\ - Dr. Ralph J.K. Metzler\\ - \texttt{}\\\\ - Dr. Marcus O.C. Metzler\\ - \texttt{} -% Rosenthalerstr. 51\\ -% 10178 Berlin\\Germany -} -\date{02/14/2002\\V 0.9.4} -\maketitle - -\newpage - -%\end{titlepage} -% Local Variables: -% mode: latex -% TeX-master: "dvbapi" -% End: diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex deleted file mode 100644 index 2659db238..000000000 --- a/dvb-spec/dvbapi/video.tex +++ /dev/null @@ -1,686 +0,0 @@ -\devsec{DVB Video Device} - -The DVB video device controls the MPEG2 video decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/video}. -The include file \texttt{ost/video.h} defines the data types and lists -all I/O calls. Please note that some DVB cards don't have their own -MPEG decoder, which results in the omission of the audio and video -device as well as the video4linux device. - -\devsubsec{Video Data Types} - -\devsubsubsec{videoFormat\_t} -\label{videoformat} - -The \texttt{videoFormat\_t} data type defined by -\begin{verbatim} -typedef enum { - VIDEO_FORMAT_4_3, - VIDEO_FORMAT_16_9 -} videoFormat_t; -\end{verbatim} -is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to -tell the driver which aspect ratio the output hardware (e.g. TV) has. -It is also used in the data structures videoStatus (\ref{videostatus}) -returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and -videoEvent (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) -which report about the display format of the current video stream. - -\devsubsubsec{videoDisplayFormat\_t} -\label{videodispformat} - -In case the display format of the video stream and of the -display hardware differ the application has to specify how to handle -the cropping of the picture. -This can be done using the VIDEO\_SET\_DISPLAY\_FORMAT call -(\ref{videosetdisplayformat}) which accepts -\begin{verbatim} -typedef enum { - VIDEO_PAN_SCAN, - VIDEO_LETTER_BOX, - VIDEO_CENTER_CUT_OUT -} videoDisplayFormat_t; -\end{verbatim} -as argument. - - -\devsubsubsec{video stream source} -\label{videostreamsource} -The video stream source is set through the VIDEO\_SELECT\_SOURCE -call and can take the following values, depending on whether we are -replaying from an internal (demuxer) or external (user write) source. -\begin{verbatim} -typedef enum { - VIDEO_SOURCE_DEMUX, - VIDEO_SOURCE_MEMORY -} videoStreamSource_t; -\end{verbatim} -VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed -either by the frontend or the DVR device) as the source of -the video stream. -If VIDEO\_SOURCE\_MEMORY is selected the stream -comes from the application through the \texttt{write()} -system call. - -\devsubsubsec{video play state} -\label{videoplaystate} -The following values can be returned by the VIDEO\_GET\_STATUS call -representing the state of video playback. -\begin{verbatim} -typedef enum { - VIDEO_STOPPED, - VIDEO_PLAYING, - VIDEO_FREEZED -} videoPlayState_t; -\end{verbatim} - - -\devsubsubsec{video event} -\label{videoevent} -The following is the structure of a video event as it is returned by -the VIDEO\_GET\_EVENT call. -\begin{verbatim} -struct videoEvent { - int32_t type; - time_t timestamp; - union { - videoFormat_t videoFormat; - } u; -}; -\end{verbatim} - -\devsubsubsec{video status} -\label{videostatus} -The VIDEO\_GET\_STATUS call returns the following structure informing -about various states of the playback operation. -\begin{verbatim} -struct videoStatus { - boolean videoBlank; - videoPlayState_t playState; - videoStreamSource_t streamSource; - videoFormat_t videoFormat; - videoDisplayFormat_t displayFormat; -}; -\end{verbatim} -If videoBlank is set video will be blanked out if the channel is changed or -if playback is stopped. Otherwise, the last picture will be displayed. -playState indicates if the video is currently frozen, stopped, or -being played back. The streamSource corresponds to the seleted source -for the video stream. It can come either from the demultiplexer or from memory. -The videoFormat indicates the aspect ratio (one of 4:3 or 16:9) -of the currently played video stream. -Finally, displayFormat corresponds to the selected cropping mode in case the -source video format is not the same as the format of the output device. - - -\devsubsubsec{video display still picture} -\label{videostill} -An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on -within the following structure. -\begin{verbatim} -/* pointer to and size of a single iframe in memory */ -struct videoDisplayStillPicture { - char *iFrame; - int32_t size; -}; -\end{verbatim} - -\devsubsubsec{video capabilities} -\label{videocaps} -A call to VIDEO\_GET\_CAPABILITIES returns an unsigned integer with -the following bits set according to the hardwares capabilities. -\begin{verbatim} -/* bit definitions for capabilities: */ -/* can the hardware decode MPEG1 and/or MPEG2? */ -#define VIDEO_CAP_MPEG1 1 -#define VIDEO_CAP_MPEG2 2 -/* can you send a system and/or program stream to video device? - (you still have to open the video and the audio device but only - send the stream to the video device) */ -#define VIDEO_CAP_SYS 4 -#define VIDEO_CAP_PROG 8 -/* can the driver also handle SPU, NAVI and CSS encoded data? - (CSS API is not present yet) */ -#define VIDEO_CAP_SPU 16 -#define VIDEO_CAP_NAVI 32 -#define VIDEO_CAP_CSS 64 -\end{verbatim} - - -\devsubsubsec{video system} -\label{videosys} -A call to VIDEO\_SET\_SYSTEM sets the desired video system for TV -output. The following system types can be set: - -\begin{verbatim} -typedef enum { - VIDEO_SYSTEM_PAL, - VIDEO_SYSTEM_NTSC, - VIDEO_SYSTEM_PALN, - VIDEO_SYSTEM_PALNc, - VIDEO_SYSTEM_PALM, - VIDEO_SYSTEM_NTSC60, - VIDEO_SYSTEM_PAL60, - VIDEO_SYSTEM_PALM60 -} videoSystem_t; -\end{verbatim} - - - -\devsubsubsec{video highlights} -\label{vhilite} -Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight -information. The call expects the following format for that information: - -\begin{verbatim} -typedef -struct videoHighlight { - boolean active; /* 1=show highlight, 0=hide highlight */ - uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ - /* 3- 0 Background pixel contrast */ - uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */ - /* 3- 0 Emphasis pixel-1 contrast */ - uint8_t color1; /* 7- 4 Pattern pixel color */ - /* 3- 0 Background pixel color */ - uint8_t color2; /* 7- 4 Emphasis pixel-2 color */ - /* 3- 0 Emphasis pixel-1 color */ - uint32_t ypos; /* 23-22 auto action mode */ - /* 21-12 start y */ - /* 9- 0 end y */ - uint32_t xpos; /* 23-22 button color number */ - /* 21-12 start x */ - /* 9- 0 end x */ -} videoHighlight_t; -\end{verbatim} - - -\devsubsubsec{video SPU} -\label{videospu} -Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, -according to the following format: -\begin{verbatim} -typedef -struct videoSPU { - boolean active; - int streamID; -} videoSPU_t; -\end{verbatim} - - -\devsubsubsec{video SPU palette} -\label{vspupal} -The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: -\begin{verbatim} -typedef -struct videoSPUPalette{ /* SPU Palette information */ - int length; - uint8_t *palette; -} videoSPUPalette_t; -\end{verbatim} - -\devsubsubsec{video NAVI pack} -\label{videonavi} -In order to get the navigational data the following structure has to -be passed to the ioctl VIDEO\_GET\_NAVI: -\begin{verbatim} -typedef -struct videoNaviPack{ - int length; /* 0 ... 1024 */ - uint8_t data[1024]; -} videoNaviPack_t; -\end{verbatim} - - -\devsubsubsec{video attributes} -\label{vattrib} -The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: -\begin{verbatim} -typedef uint16_t videoAttributes_t; -/* bits: descr. */ -/* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ -/* 13-12 TV system (0=525/60, 1=625/50) */ -/* 11-10 Aspect ratio (0=4:3, 3=16:9) */ -/* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ -/* 7 line 21-1 data present in GOP (1=yes, 0=no) */ -/* 6 line 21-2 data present in GOP (1=yes, 0=no) */ -/* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ -/* 2 source letterboxed (1=yes, 0=no) */ -/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ -\end{verbatim} - - -\clearpage - -\devsubsec{Video Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named video device (e.g. /dev/ost/video) - for subsequent use. - - When an open() call has succeeded, the device will be ready for use. - The significance of blocking or non-blocking mode is described in - the documentation for functions where there is a difference. - It does not affect the semantics of the open() call itself. - A device opened in blocking mode can later be put into non-blocking mode - (and vice versa) using the F\_SETFL command of the fcntl system - call. - This is a standard system call, documented in the Linux manual - page for fcntl. - Only one user can open the Video Device in O\_RDWR mode. All other attempts to - open the device in this mode will fail, and an error-code will be returned. - If the Video Device is opened in O\_RDONLY mode, the only ioctl call that can - be used is VIDEO\_GET\_STATUS. All other call will return an error code. - }{ - const char *deviceName & Name of specific video device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ - & \hspace{1em} (blocking mode is the default)\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EINTERNAL & Internal error.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened video device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\function{write()}{ - size\_t write(int fd, const void *buf, size\_t count);}{ - This system call can only be used if VIDEO\_SOURCE\_MEMORY is selected in the - ioctl call VIDEO\_SELECT\_SOURCE. The data provided shall be in PES - format, unless the capability allows other formats. - If O\_NONBLOCK is not specified the function will block until buffer space is - available. The amount of data to be transferred is implied by count. - }{ - int fd & File descriptor returned by a previous call to open().\\ - void *buf & Pointer to the buffer containing the PES data.\\ - size\_t count& Size of buf.\\ - }{ - EPERM& Mode VIDEO\_SOURCE\_MEMORY not selected.\\ - ENOMEM& Attempted to write more data than the internal buffer can hold.\\ - EBADF& fd is not a valid open file descriptor.\\ -} - - -\ifunction{VIDEO\_STOP}{ - int ioctl(fd, int request = VIDEO\_STOP, boolean mode);}{ - This ioctl call asks the Video Device to stop playing the current stream. - Depending on the input parameter, the screen can be blanked out or - displaying the last decoded frame. -}{ -int fd & File descriptor returned by a previous call to open(). \\ -int request & Equals VIDEO\_STOP for this command. \\ -Boolean mode & Indicates how the screen shall be handled. \\ -& TRUE: Blank screen when stop. \\ -& FALSE: Show last decoded frame.\\ -}{ -EBADF& fd is not a valid open file descriptor \\ -EINTERNAL & Internal error, possibly in the communication with - the DVB subsystem.\\ -} - -\ifunction{VIDEO\_PLAY}{ - int ioctl(fd, int request = VIDEO\_PLAY);}{ - This ioctl call asks the Video Device to start playing a video stream - from the selected source. -}{ -int fd & File descriptor returned by a previous call to open(). \\ -int request & Equals VIDEO\_PLAY for this command. \\ -}{ -EBADF& fd is not a valid open file descriptor \\ -EINTERNAL & Internal error, possibly in the communication with - the DVB subsystem.\\ -} - - -\ifunction{VIDEO\_FREEZE}{ - int ioctl(fd, int request = VIDEO\_FREEZE);}{ - This ioctl call suspends the live video stream being played. - Decoding and playing are frozen. It is then possible to restart - the decoding and playing process of the video stream using the - VIDEO\_CONTINUE command. If VIDEO\_SOURCE\_MEMORY is selected in the - ioctl call VIDEO\_SELECT\_SOURCE, the DVB subsystem will not decode - any more data until the ioctl call VIDEO\_CONTINUE or VIDEO\_PLAY is - performed. -}{ -int fd & File descriptor returned by a previous call to open(). \\ -int request & Equals VIDEO\_FREEZE for this command. \\ -}{ -EBADF& fd is not a valid open file descriptor \\ -EINTERNAL & Internal error, possibly in the communication with - the DVB subsystem.\\ -} - -\ifunction{VIDEO\_CONTINUE}{ - int ioctl(fd, int request = VIDEO\_CONTINUE);}{ - This ioctl call restarts decoding and playing processes of the video - stream which was played before a call to VIDEO\_FREEZE was made. - }{ - int fd & File descriptor returned by a previous call to open(). \\ - int request & Equals VIDEO\_CONTINUE for this command. \\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error, possibly in the communication with - the DVB subsystem.\\ - } - - -\ifunction{VIDEO\_SELECT\_SOURCE}{ - int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ - This ioctl call informs the video device which source shall be used - for the input data. The possible sources are demux or memory. If - memory is selected, the data is fed to the video device through - the write command. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\ - videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ -} - -\ifunction{VIDEO\_SET\_BLANK}{ - int ioctl(fd, int request = VIDEO\_SET\_BLANK, boolean mode);}{ - This ioctl call asks the Video Device to blank out the picture. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request& Equals VIDEO\_SET\_BLANK for this command. \\ -boolean mode&TRUE: Blank screen when stop.\\ - &FALSE: Show last decoded frame.\\ -}{ -EBADF& fd is not a valid open file descriptor \\ -EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ -EINVAL & Illegal input parameter\\ -} - -\ifunction{VIDEO\_GET\_STATUS}{ -\label{videogetstatus} - int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct videoStatus *status);}{ - This ioctl call asks the Video Device to return the current status of the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals VIDEO\_GET\_STATUS for this command.\\ - struct videoStatus *status & Returns the current status of the Video Device.\\ -}{ -EBADF& fd is not a valid open file descriptor \\ -EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ -EFAULT & status points to invalid address\\ -} - -\ifunction{VIDEO\_GET\_EVENT}{ -\label{videogetevent} - int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct videoEvent *ev);}{ - This ioctl call returns an event of type videoEvent if available. - If an event is not available, the behavior depends on whether the device is in - blocking or non-blocking mode. In the latter case, the call fails immediately - with errno set to EWOULDBLOCK. In the former case, the call blocks until an - event becomes available. - The standard Linux poll() and/or select() system calls can be used with the - device file descriptor to watch for new events. For select(), the file - descriptor should be included in the exceptfds argument, and for poll(), - POLLPRI should be specified as the wake-up condition. - Read-only permissions are sufficient for this ioctl call. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request& Equals VIDEO\_GET\_EVENT for this command.\\ - struct videoEvent *ev & Points to the location where the event, if any, is - to be stored.\\ -}{ -EBADF & fd is not a valid open file descriptor \\ -EFAULT & ev points to invalid address \\ -EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ -EBUFFEROVERFLOW & \\ -&Overflow in event queue - one or more events were lost.\\ -} - -\ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ -\label{videosetdisplayformat} - int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ - This ioctl call asks the Video Device to select the video format to be applied - by the MPEG chip on the video. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\ - videoDisplayFormat\_t format & Selects the video format to be used.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error.\\ - EINVAL & Illegal parameter format.\\ -} - -\ifunction{VIDEO\_STILLPICTURE}{ - int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct videoDisplayStillPicture *sp);}{ - This ioctl call asks the Video Device to display a still picture (I-frame). - The input data shall contain an I-frame. If the pointer is NULL, then the - current displayed still picture is blanked. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_STILLPICTURE for this command.\\ - struct videoDisplayStillPicture *sp& - Pointer to a location where an I-frame and size is stored.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error.\\ - EFAULT & sp points to an invalid iframe.\\ -} - -\ifunction{VIDEO\_FAST\_FORWARD}{ - int ioctl(fd, int request = VIDEO\_FAST\_FORWARD, int nFrames);}{ - This ioctl call asks the Video Device to skip decoding of N number of I-frames. - This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_FAST\_FORWARD for this command.\\ - int nFrames & The number of frames to skip.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error.\\ - EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ - EINVAL & Illegal parameter format.\\ -} - -\ifunction{VIDEO\_SLOWMOTION}{ - int ioctl(fd, int request = VIDEO\_SLOWMOTION, int nFrames);}{ - This ioctl call asks the video device to repeat decoding frames N - number of times. - This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SLOWMOTION for this command.\\ - int nFrames & The number of times to repeat each frame.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINTERNAL & Internal error.\\ - EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ - EINVAL & Illegal parameter format.\\ -} - -\ifunction{VIDEO\_GET\_CAPABILITIES}{ - int ioctl(fd, int request = VIDEO\_GET\_CAPABILITIES, unsigned int *cap);}{ - This ioctl call asks the video device about its decoding capabilities. - On success it returns and integer which has bits set according to the - defines in section \ref{videocaps}. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_GET\_CAPABILITIES for this command.\\ - unsigned int *cap & Pointer to a location where to store the - capability information.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EFAULT & cap points to an invalid iframe.\\ -} - -\ifunction{VIDEO\_SET\_ID}{ - int ioctl(int fd, int request = VIDEO\_SET\_ID, int id);}{ - This ioctl selects which sub-stream is to be decoded if a program or - system stream is sent to the video device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_ID for this command.\\ - int id& video sub-stream id - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINTERNAL & Internal error.\\ - EINVAL & Invalid sub-stream id. -} - -\ifunction{VIDEO\_CLEAR\_BUFFER}{ - int ioctl(fd, int request = VIDEO\_CLEAR\_BUFFER);}{ - This ioctl call clears all video buffers in the driver and - in the decoder hardware. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_CLEAR\_BUFFER for this command.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ -} - -\ifunction{VIDEO\_SET\_STREAMTYPE}{ - int ioctl(fd, int request = VIDEO\_SET\_STREAMTYPE, int type);}{ - This ioctl tells the driver which kind of stream to expect - being written to it. If this call is not used the default of video PES - is used. Some drivers might not support this call and always expect PES. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_STREAMTYPE for this command.\\ - int type & stream type\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& type is not a valid or supported stream type.\\ -} - -\ifunction{VIDEO\_SET\_FORMAT}{ -\label{videosetformat} - int ioctl(fd, int request = VIDEO\_SET\_FORMAT, videoFormat\_t format); -}{ - This ioctl sets the screen format (aspect ratio) of the connected - output device (TV) so that the output of the decoder can - be adjusted accordingly. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - videoFormat\_t format& video format of TV as defined in section \ref{videoformat}.\\ - }{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& format is not a valid video format.\\ -} - -\ifunction{VIDEO\_SET\_SYSTEM}{ -\label{videosetsystem} - int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); -}{ - This ioctl sets the television output format. The format (see section - \ref{videosys}) may vary from the color format of the displayed MPEG - stream. If the hardware is not able to display the requested format - the call will return an error. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - videoSystem\_t system& video system of TV output.\\ -}{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& system is not a valid or supported video system.\\ -} - -\ifunction{VIDEO\_SET\_HIGHLIGHT}{ -\label{videosethighlight} - int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,videoHighlight\_t *vhilite) -}{ - This ioctl sets the SPU highlight information for the menu access of - a DVD. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\ - videoHighlight\_t *vhilite& SPU Highlight information according to - section \ref{vhilite}.\\ -}{ - EBADF& fd is not a valid open file descriptor. \\ - EINVAL& input is not a valid highlight setting.\\ -} - - -\ifunction{VIDEO\_SET\_SPU}{ -\label{videosetspu} - int ioctl(fd, int request = VIDEO\_SET\_SPU , videoSPU\_t *spu) -}{ - This ioctl activates or deactivates SPU decoding in a DVD input - stream. It can only be used, if the driver is able to handle a DVD - stream. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_SPU for this command.\\ - videoSPU\_t *spu& SPU decoding (de)activation and subid setting - according to section \ref{videospu}.\\ -}{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& input is not a valid spu setting or driver cannot handle SPU.\\ -} - - -\ifunction{VIDEO\_SET\_SPU\_PALETTE}{ -\label{videosetspupalette} - int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,videoSPUPalette\_t *palette ) -}{ - This ioctl sets the SPU color palette. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\ - videoSPUPalette\_t *palette& SPU palette according to section \ref{vspupal}.\\ -}{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& input is not a valid palette or driver doesn't handle SPU.\\ -} - - - -\ifunction{VIDEO\_GET\_NAVI}{ -\label{videosetnavi} - int ioctl(fd, int request = VIDEO\_GET\_NAVI , videoNaviPack\_t *navipack) -}{ - This ioctl returns navigational information from the DVD stream. This is - especially needed if an encoded stream has to be decoded by the hardware. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_GET\_NAVI for this command.\\ - videoNaviPack\_t *navipack& PCI or DSI pack (private stream 2) - according to section \ref{videonavi}.\\ -}{ - EBADF& fd is not a valid open file descriptor \\ - EFAULT& driver is not able to return navigational information\\ -} - - -\ifunction{VIDEO\_SET\_ATTRIBUTES}{ -\label{videosetattributes} - int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t - vattr) -}{ - This ioctl is intended for DVD playback and allows you to set - certain information about the stream. Some hardware may not need - this information, but the call also tells the hardware to prepare - for DVD playback. -}{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\ - videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\ -}{ - EBADF& fd is not a valid open file descriptor \\ - EINVAL& input is not a valid attribute setting.\\ -} - - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: -- cgit v1.2.3 From 5a523e605b9b6d1ae50d0707c1874c5b7f0959cc Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 16:22:27 -0300 Subject: the new HEAD --- dvb-spec/HOWTO-use-the-frontend-api | 189 +++++++ dvb-spec/README.CABLE | 5 + dvb-spec/README.EON | 7 + dvb-spec/README.valgrind | 13 + dvb-spec/channel | 104 ++++ dvb-spec/dvbapi/.cvsignore | 11 + dvb-spec/dvbapi/Makefile | 30 ++ dvb-spec/dvbapi/audio.tex | 442 +++++++++++++++ dvb-spec/dvbapi/bibsection.sty | 29 + dvb-spec/dvbapi/ca.tex | 127 +++++ dvb-spec/dvbapi/cimlogo.psi | 122 +++++ dvb-spec/dvbapi/demux.tex | 392 ++++++++++++++ dvb-spec/dvbapi/devices.tex | 12 + dvb-spec/dvbapi/dvbapi.tex | 166 ++++++ dvb-spec/dvbapi/dvbstb.fig | 59 ++ dvb-spec/dvbapi/examples.tex | 366 +++++++++++++ dvb-spec/dvbapi/fig2pstex | 6 + dvb-spec/dvbapi/frontend.tex | 630 ++++++++++++++++++++++ dvb-spec/dvbapi/getbb | 12 + dvb-spec/dvbapi/intro.tex | 183 +++++++ dvb-spec/dvbapi/kdapi.tex | 1007 +++++++++++++++++++++++++++++++++++ dvb-spec/dvbapi/sec.tex | 282 ++++++++++ dvb-spec/dvbapi/title.tex | 24 + dvb-spec/dvbapi/video.tex | 686 ++++++++++++++++++++++++ dvb-spec/valgrind-1.0pre3-dvb.patch | 154 ++++++ 25 files changed, 5058 insertions(+) create mode 100644 dvb-spec/HOWTO-use-the-frontend-api create mode 100644 dvb-spec/README.CABLE create mode 100644 dvb-spec/README.EON create mode 100644 dvb-spec/README.valgrind create mode 100644 dvb-spec/channel create mode 100644 dvb-spec/dvbapi/.cvsignore create mode 100644 dvb-spec/dvbapi/Makefile create mode 100644 dvb-spec/dvbapi/audio.tex create mode 100644 dvb-spec/dvbapi/bibsection.sty create mode 100644 dvb-spec/dvbapi/ca.tex create mode 100644 dvb-spec/dvbapi/cimlogo.psi create mode 100644 dvb-spec/dvbapi/demux.tex create mode 100644 dvb-spec/dvbapi/devices.tex create mode 100644 dvb-spec/dvbapi/dvbapi.tex create mode 100644 dvb-spec/dvbapi/dvbstb.fig create mode 100644 dvb-spec/dvbapi/examples.tex create mode 100755 dvb-spec/dvbapi/fig2pstex create mode 100644 dvb-spec/dvbapi/frontend.tex create mode 100755 dvb-spec/dvbapi/getbb create mode 100644 dvb-spec/dvbapi/intro.tex create mode 100644 dvb-spec/dvbapi/kdapi.tex create mode 100644 dvb-spec/dvbapi/sec.tex create mode 100644 dvb-spec/dvbapi/title.tex create mode 100644 dvb-spec/dvbapi/video.tex create mode 100644 dvb-spec/valgrind-1.0pre3-dvb.patch diff --git a/dvb-spec/HOWTO-use-the-frontend-api b/dvb-spec/HOWTO-use-the-frontend-api new file mode 100644 index 000000000..52bc2836e --- /dev/null +++ b/dvb-spec/HOWTO-use-the-frontend-api @@ -0,0 +1,189 @@ + +------------------------------------------------------------------------------- + +What has changed since the old Nokia OST API? + + file naming: + - /dev/ost directory is now called /dev/dvb + - each DVB adapter has it's own directory /dev/dvb/adapterX + - here you'll find a number of frontend devices /dev/dvb/adapterX/frontendY + - driver header directory is located now in /usr/include/linux/dvb/ + - we have a linux/dvb/version.h file, this is included by all headers which + don't use the original OST API anymore + + struct naming: + - we follow the kernel naming scheme and try to get the namespace clean, + these changes are mostly syntactical + + DiSEqC: + - DiSEqC 2.0 ioctls + - the sec-device is gone, DiSEqC ioctls are passed to the frontend + filedescriptor - this matches the hardware better + - the old secCmdSequence is replaced by lowlevel FE_DISEQC_XXX ioctls, + this allows asynchronous DiSEqC, DiSEqC 2.0 and more flexibility for + cascaded devices and exotic setup + + frontend events: + - the event struct is simplified, you get an event now whenever one of the + frontend status bits changes + + ioctls: + - FE_SELFTEST is gone, was a noop anyway + - FE_GET_NEXT_FREQUENCY and FE_GET_NEXT_SYMBOL_RATE are gone, + this information can be obtained with FE_GET_INFO + - FE_SET_POWER_STATE is gone, powermanagement is done implicitly by device + open()/close() calls + +------------------------------------------------------------------------------- + +How to determine the API version? + + Check in your configure script for #include , + include it and check the DVB_API_VERSION #define. + + Currently we use version 2, it will be incremented whenever an API change + meets the CVS main branch. + +------------------------------------------------------------------------------- + +What do you have to do to set up a your frontend? + + First you should try to determine the type of your frontend. + + struct dvb_frontend_info info; + int fd; + + if ((fd = open ("/dev/dvb/adapter0/frontend0", O_RDWR)) < 0) { + perror ("open failed"); + return -1; + } + + ioctl (fd, FE_GET_INFO, &info); + + Now the info.type field contains either FE_QPSK for a satellite frontend, + FE_QAM for a cable frontend or FE_OFDM for a terrestrial frontend. + + The info.name field contains a human readable vendor string of your frontend. + You might want to show this in your GUI to make support easier. + + The info struct also contains the frequency limits, frontend capabilities, + the frequency and symbol rate tolerance the AFC or timing recovery loop can + compensate and some fields you are not interested in. + +------------------------------------------------------------------------------- + +How to set up a cable or terrestrial frontend? + + Fill a dvb_frontend_parameters struct according to the data in your channel + list. For cable frontends, you have to fill the qam field of the union, for + terrestrial frontends it's the ofdm field. + + Apply it using the FE_SET_FRONTEND_PARAMETERS ioctl. That's all. + +------------------------------------------------------------------------------- + +How to set up a satellite frontend? + + Before you set the frontend parameters you have to setup DiSEqC switches and + the LNB. Modern LNB's switch their polarisation depending of the DC component + of their input (13V for vertical polarisation, 18V for horizontal). When they + see a 22kHz signal at their input they switch into the high band and use a + somewhat higher intermediate frequency to downconvert the signal. + + When your satellite equipment contains a DiSEqC switch device to switch + between different satellites you have to send the according DiSEqC commands, + usually command 0x38. Take a look into the DiSEqC spec available at + http://www.eutelsat.org/ for the complete list of commands. + + The burst signal is used in old equipments and by cheap satellite A/B + switches. + + Voltage, burst and 22kHz tone have to be consistent to the values encoded in + the DiSEqC commands. + + The complete sequence to set up switch and LNB according to the DiSEqC spec + looks like this: + + - stop continous tone + - setup polarisation voltage + - wait at least 15ms. + - send your DiSEqC commands using the FE_DISEQC_SEND_MASTER_CMD ioctl + - wait another 15ms + - send burst + - wait 15ms + - start the 22kHz tone when you tune to a transponder in the high band + + You can copy'n'paste this code sniplets from szap.c or diseqc.c, both + test programs are distributed with the linuxtv DVB driver source. All + DiSEqC related ioctls are passed to the frontend device filedescriptor. + + Depending on the equipment setup, you may or may not have to repeat the + DiSEqC commands (only commands, not the whole sequence) for cascaded devices + and can pack committed/uncommitted switch messages. See the DiSEqC spec for + details. + + In an advanced program, you probably want to send this sequence using an + asynchonous thread. Since sleep() and similiar calls are pthread + cancellation points, it's really simple to stop a running DiSEqC thread + before submitting a new sequence. + + Now you have set up switch and LNB, a valid RF signal of the requested + satellite should be at the input of the demodulator. + + Fill a dvb_frontend_parameters struct using the qpsk field in the union and + apply it using the FE_SET_FRONTEND_PARAMETERS ioctl. + +------------------------------------------------------------------------------- + +How do I check the frontend status? + + You can perform a poll()/select() on the frontend file descriptor. Whenever + one of the frontend status bits toggles the poll returns. Now you can + submit the FE_GET_EVENT ioctl to receive the new status bits. When you used + one of the XXX_AUTO parameters you might want to use the event.parameters + field to determine the correct tuned parameters and update your channel list. + + If you want to simulate the old FE_FAILURE_EV frontend event behaviour you + should check the FE_TIMEDOUT bit, this will be set when the tuning was not + successful within a few seconds. + + When you get a FE_REINIT event the frontend was reinitialized. You should + send the DiSEqC sequence again if you use a QPSK frontend. + + The FE_READ_SIGNAL_STRENGTH ioctl will fill the signal strength into the + 16 LSBs of the passed argument. The signal strength range is from 0 (bad) + to 65535 (too good to be true). + + FE_READ_SNR returns the signal noise ratio. range 0 (bad) to 65535 (not real). + For both the signal strength and signal noise ratio a value of about 60-70% + means a good signal. + + Not all FE_READ_XXX ioctl()s are supported by all hardware. Check the ioctl + return value, if it's less than 0 this ioctl is not supported. + +------------------------------------------------------------------------------- + +What does FE_ENABLE_HIGH_LNB_VOLTAGE? + + some STBs (the dbox2 for example) support somewhat higher LNB voltages than + 13 and 18V. They add about 0.5V to compensate voltage drop on long cables. + + This ioctl is not supported on all boxes. You probably want to show an extra + menu item in your GUI when this ioctl returns a zero value. + +------------------------------------------------------------------------------- + +How to do powermanagement, the FE_SET_POWER_STATE ioctls are gone? + + An open() call on the frontend device powers up and initializes the + demodulator and switches on LNB power if necessairy. The DiSEqC bus won't + be resetted, do this manually if you think you need to. + + Some seconds after the device is closed (and was not opened by a new process) + LNB power and the demodulator are shut down into sleep mode. + + You can configure the shutdown timeout using the shutdown_timeout module + parameter. To disable power management set shutdown_timeout=0. + +------------------------------------------------------------------------------- + diff --git a/dvb-spec/README.CABLE b/dvb-spec/README.CABLE new file mode 100644 index 000000000..de13af020 --- /dev/null +++ b/dvb-spec/README.CABLE @@ -0,0 +1,5 @@ +- The analog module is not fully supported yet. + The MSP3400 module will have to be extended to handle then audio and + video switching for the module. + If you want sound you will have to remove the module for now. + diff --git a/dvb-spec/README.EON b/dvb-spec/README.EON new file mode 100644 index 000000000..df5098132 --- /dev/null +++ b/dvb-spec/README.EON @@ -0,0 +1,7 @@ +- If you do not receive any packets over the dvb0 device the reason could + be the rp_filter. + Check if your distribution enables this or disable it with: + + "echo 0 > /proc/sys/net/ipv4/conf/dvb0/rp_filter" + + This disables source validation by reversed path lookup. \ No newline at end of file diff --git a/dvb-spec/README.valgrind b/dvb-spec/README.valgrind new file mode 100644 index 000000000..c1ce7c994 --- /dev/null +++ b/dvb-spec/README.valgrind @@ -0,0 +1,13 @@ +valgrind-1.0pre3-dvb.patch enables checking correct usage +of the the Linux DVB API ioctls with valgrind +(http://developer.kde.org/~sewardj/). Or, more to the point, +it allows you to check your DVB software with valgrind +without getting all those "unknown ioctl" warnings. + +Notes: +- only frontend and demux ioctls are currently implemented +- some ioctls take structs as arguments; due to padding, valgrind + will complain about uninitialized data passed to the ioctl unless + you memset() the whole struct to some defined value + +Johannes Stezenbach diff --git a/dvb-spec/channel b/dvb-spec/channel new file mode 100644 index 000000000..f17e8cb19 --- /dev/null +++ b/dvb-spec/channel @@ -0,0 +1,104 @@ +This file describes the format of the new channel config file. + +Comments start with # +Each section starts with one of the identifiers: LNB, DISEQC, ROTOR, ... + +IDs are either the official transponder, network, etc. id if it exists +and is unique, otherwise it is just a consecutive number assigned by +the application. +An LNB can also describe a cable TV outlet or a terrestrial antenna. +Names (as all parameters in brackets) are optional. In this case the +application should use the ID as name. + +The application should offer selection sorted by channel number, network, +satellite, bouquet. + + +# satellite definition +SAT + ID satid # ID = xxxy, sat is at position xxx.y degrees + [NAME name] + LNBID lnbid # LNB this sat is received with + [ROTORID rotorid] # rotor commands to position it on this sat + +# LNB definition +LNB + ID lnbid + [NAME name] + [INPUT input] # input of card which the lnb is connected to (default 0) + TYPE type # LNB, CATV or terrestrial antenna? + LOF1 offset1 # local oscillator frequency 1 + LOF2 offset2 # local oscillator frequency 2 + SLOF switchfreq # switching frequency + [DISEQCNR diseqcnr] # simple 2- or 4-switch DiSEqC + [DISEQCID diseqcid] + [INPUT input] + [SWITCHID switchid] + +# A transponder definition +TRANSPONDER + ID tpid + TYPE type # digital (DVB-S(1), C(2) or T(3)) or analog(0) ? + SATID satid + [NAME name] # if analog this is the channel name + FREQ freq + POL H/V + [QAM qam] # only needed if DVB-C + [SRATE sr] # only if DVB + [FEC fec] # only if DVB + [PICID picid] # picture attributes for all channels on this transponder + +# channel definition (only if DVB) +CHANNEL + ID channelid + [NAME name] + TPID tpid + TYPE type + PNR pnr + VPID vpid + APID apid + TPID tpid + [PMTPID pmtpid] + [PCRPID pcrpid] + [APID apid2 APID apid3 ... APID apidn] # more audio PIDs for several languages + [AC3PID ac3] + [NETWID networkid] + [BOUQID bouquetid] + [PICID picid] + +# network definition +NETWORK + ID nwid + [NAME name] + +# bouquet definition +BOUQUET + ID bqid + [NAME name] + + + +# These will be implemented later + +# DiSEqC command sequence +DISEQC + ID disid + [NAME name] + MESSAGE data1 [ ... datan ] BURST 0/1 END + [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] + +# DiSEqC switch +SWITCH + ID switchid + SWITCHID switchid # next "higher" switch + [NAME name] + MESSAGE data1 [ ... datan ] BURST 0/1 END + + +# DiSEqC rotor command sequence leading to a certain rotor position +ROTOR + ID rotid + POS degrees + MESSAGE data1 [ ... datan ] BURST 0/1 END + [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] + diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore new file mode 100644 index 000000000..fb6974f6b --- /dev/null +++ b/dvb-spec/dvbapi/.cvsignore @@ -0,0 +1,11 @@ +dvbapi.ps +dvbstb.ps +dvbstb.pst +dvbapi.bbl +dvbapi.aux +dvbapi.blg +dvbapi.dvi +dvbapi.log +dvbapi.pdf +dvbapi.out +dvbapi.toc diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile new file mode 100644 index 000000000..aae688f33 --- /dev/null +++ b/dvb-spec/dvbapi/Makefile @@ -0,0 +1,30 @@ +all: dvbapi.ps dvbapi.pdf + +TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ + intro.tex title.tex dvbstb.ps + +dvbapi.pdf: dvbapi.dvi + dvipdf -o $@ $< + +dvbapi.ps: dvbapi.dvi + dvips -o $@ $< + +dvbapi.dvi: dvbapi.bbl $(TEXS) + -latex dvbapi + -bibtex dvbapi + -makeindex dvbapi + -latex dvbapi + -latex dvbapi + +dvbapi.bbl: $(TEXS) + -latex dvbapi + -bibtex dvbapi + -makeindex dvbapi + +%.ps: %.fig + ./fig2pstex $< + +clean: + rm -f dvbapi.dvi + rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc + rm -f *.pdf *.pst *.ps diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex new file mode 100644 index 000000000..7b6427094 --- /dev/null +++ b/dvb-spec/dvbapi/audio.tex @@ -0,0 +1,442 @@ +\devsec{DVB Audio Device} + +The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. +It can be accessed through \texttt{/dev/ost/audio}. + + +\devsubsec{Audio Data Types} + +This section describes the structures, data types and defines used when +talking to the audio device. + +\devsubsubsec{audioStreamSource\_t} +\label{audiostreamsource} +The audio stream source is set through the AUDIO\_SELECT\_SOURCE +call and can take the following values, depending on whether we are +replaying from an internal (demuxer) or external (user write) source. +\begin{verbatim} +typedef enum { + AUDIO_SOURCE_DEMUX, + AUDIO_SOURCE_MEMORY +} audio_stream_source_t; +\end{verbatim} +AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed +either by the frontend or the DVR device) as the source of +the video stream. +If AUDIO\_SOURCE\_MEMORY is selected the stream +comes from the application through the \texttt{write()} +system call. + +\devsubsubsec{audioPlayState\_t} +The following values can be returned by the AUDIO\_GET\_STATUS call +representing the state of audio playback. +\label{audioplaystate} +\begin{verbatim} +typedef enum { + AUDIO_STOPPED, + AUDIO_PLAYING, + AUDIO_PAUSED +} audio_play_state_t; +\end{verbatim} + +\devsubsubsec{audioChannelSelect\_t} +\label{audiochannelselect} +The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by +the following values. +\begin{verbatim} +typedef enum { + AUDIO_STEREO, + AUDIO_MONO_LEFT, + AUDIO_MONO_RIGHT, +} audio_channel_select_t; +\end{verbatim} + +\devsubsubsec{audio_status\_t} +\label{audiostatus} +The AUDIO\_GET\_STATUS call returns the following structure informing +about various states of the playback operation. +\begin{verbatim} +typedef struct audio_status { + boolean AV_sync_state; + boolean mute_state; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; + boolean bypass_mode; +} audio_status_t; +\end{verbatim} + +\devsubsubsec{audio_mixer\_t} +\label{audiomixer} +The following structure is used by the AUDIO\_SET\_MIXER call to set +the audio volume. +\begin{verbatim} +typedef struct audio_mixer { + unsigned int volume_left; + unsigned int volume_right; +} audio_mixer_t; +\end{verbatim} + +\devsubsubsec{audio encodings} +\label{audiotypes} +A call to AUDIO\_GET\_CAPABILITIES returns an unsigned integer with +the following bits set according to the hardwares capabilities. +\begin{verbatim} +#define AUDIO_CAP_DTS 1 +#define AUDIO_CAP_LPCM 2 +#define AUDIO_CAP_MP1 4 +#define AUDIO_CAP_MP2 8 +#define AUDIO_CAP_MP3 16 +#define AUDIO_CAP_AAC 32 +#define AUDIO_CAP_OGG 64 +#define AUDIO_CAP_SDDS 128 +#define AUDIO_CAP_AC3 256 +\end{verbatim} + + +\devsubsubsec{audio karaoke} +\label{audiokaraoke} +The ioctl AUDIO\_SET\_KARAOKE uses the following format: +\begin{verbatim} +typedef +struct audio_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ + int vocal1; /* into left and right t at 70% each */ + int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ + int melody; /* mixed into the left channel and */ + /* Vocal2 into the right channel at 100% each. */ + /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ +} audio_karaoke_t; +\end{verbatim} + +\devsubsubsec{audio attributes} +\label{aattrib} +The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: +\begin{verbatim} +typedef uint16_t audio_attributes_t; +/* bits: descr. */ +/* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ +/* 12 multichannel extension */ +/* 11-10 audio type (0=not spec, 1=language included) */ +/* 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ +/* 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, */ +/* 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ +/* 2- 0 number of audio channels (n+1 channels) */ +\end{verbatim} + + +\clearpage + +\devsubsec{Audio Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + use. When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not affect + the semantics of the open() call itself. A device opened in blocking mode can + later be put into non-blocking mode (and vice versa) using the F\_SETFL command + of the fcntl system call. This is a standard system call, documented in the + Linux manual page for fcntl. + Only one user can open the Audio Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error code will be returned. + If the Audio Device is opened in O\_RDONLY mode, the only ioctl call that can + be used is AUDIO\_GET\_STATUS. All other call will return with an error code. + }{ + const char *deviceName & Name of specific audio device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{write()}{ + size\_t write(int fd, const void *buf, size\_t count);}{ + This system call can only be used if AUDIO\_SOURCE\_MEMORY is selected + in the ioctl call AUDIO\_SELECT\_SOURCE. + The data provided shall be in PES format. + If O\_NONBLOCK is not specified the function will block until buffer space is + available. The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the PES data.\\ + size\_t count& Size of buf.\\ + }{ + EPERM& Mode AUDIO\_SOURCE\_MEMORY not selected.\\ + ENOMEM& Attempted to write more data than the internal buffer can hold.\\ + EBADF& fd is not a valid open file descriptor.\\ +} + +\ifunction{AUDIO\_STOP}{ + int ioctl(int fd, int request = AUDIO\_STOP);}{ + This ioctl call asks the Audio Device to stop playing the current stream. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_STOP for this command. + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_PLAY}{ + int ioctl(int fd, int request = AUDIO\_PLAY);}{ + This ioctl call asks the Audio Device to start playing an audio stream + from the selected source. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_PLAY for this command. + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_PAUSE}{ + int ioctl(int fd, int request = AUDIO\_PAUSE);}{ + This ioctl call suspends the audio stream being played. + Decoding and playing are paused. + It is then possible to restart again decoding and playing process of the + audio stream using AUDIO\_CONTINUE command.\\ + If AUDIO\_SOURCE\_MEMORY is selected in the ioctl call + AUDIO\_SELECT\_SOURCE, the DVB-subsystem will not decode (consume) + any more data until the ioctl call + AUDIO\_CONTINUE or AUDIO\_PLAY is performed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals AUDIO\_PAUSE for this command. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_SELECT\_SOURCE}{ + int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, + audioStreamSource\_t source);}{ + This ioctl call informs the audio device which source shall be used for the + input data. The possible sources are demux or memory. + If AUDIO\_SOURCE\_MEMORY + is selected, the data is fed to the Audio Device through the write command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\ + audioStreamSource\_t source& Indicates the source that shall be used for the + Audio stream. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_MUTE}{ + int ioctl(int fd, int request = AUDIO\_SET\_MUTE, boolean state);}{ + This ioctl call asks the audio device to mute the stream that is + currently being played. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_MUTE for this command.\\ + boolean state & Indicates if audio device shall mute or not.\\ + &TRUE Audio Mute\\ + &FALSE Audio Un-mute\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_AV\_SYNC}{ + int ioctl(int fd, int request = AUDIO\_SET\_AV\_SYNC, boolean state);}{ + This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_AV\_SYNC for this command.\\ + boolean state& Tells the DVB subsystem if A/V + synchronization shall be ON or OFF.\\ + & TRUE AV-sync ON \\ + & FALSE AV-sync OFF\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_SET\_BYPASS\_MODE}{ + int ioctl(int fd, int request = AUDIO\_SET\_BYPASS\_MODE, boolean mode);}{ + This ioctl call asks the Audio Device to bypass the Audio decoder and forward + the stream without decoding. This mode shall be used if streams that can't be + handled by the DVB system shall be decoded. + Dolby DigitalTM streams are automatically forwarded by the DVB + subsystem if the hardware can handle it. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_BYPASS\_MODE for this command.\\ + boolean mode& Enables or disables the decoding of the current + Audio stream in the DVB subsystem.\\ + &TRUE Bypass is disabled\\ + &FALSE Bypass is enabled\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter. +} + +\ifunction{AUDIO\_CHANNEL\_SELECT}{ + int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, + audioChannelSelect\_t);}{ + This ioctl call asks the Audio Device to select the requested channel + if possible. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\ + audioChannelSelect\_t ch & + Select the output format of the audio (mono left/right, stereo). + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal input parameter ch. +} + +\ifunction{AUDIO\_GET\_STATUS}{ + int ioctl(int fd, int request = AUDIO\_GET\_STATUS, + struct audio_status *status);}{ + This ioctl call asks the Audio Device to return the current state + of the Audio Device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_GET\_STATUS for this command.\\ + struct audio_status *status & Returns the current state of Audio Device. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & status points to invalid address. +} + +\ifunction{AUDIO\_GET\_CAPABILITIES}{ + int ioctl(int fd, int request = AUDIO\_GET\_CAPABILITIES, + unsigned int *cap);}{ + This ioctl call asks the Audio Device to tell us about the + decoding capabilities of the audio hardware. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_GET\_CAPABILITIES for this command.\\ + unsigned int *cap & Returns a bit array of supported sound formats. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & cap points to an invalid address. +} + +\ifunction{AUDIO\_CLEAR\_BUFFER}{ + int ioctl(int fd, int request = AUDIO\_CLEAR\_BUFFER);}{ + This ioctl call asks the Audio Device to clear all software + and hardware buffers of the audio decoder device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_CLEAR\_BUFFER for this command. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error. +} + +\ifunction{AUDIO\_SET\_ID}{ + int ioctl(int fd, int request = AUDIO\_SET\_ID, int id);}{ + This ioctl selects which sub-stream is to be decoded if a program or + system stream is sent to the video device. If no audio stream type is set + the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for + AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow + for other stream types. If the stream type is set the id just + specifies the substream id of the audio stream and only the first 5 + bits are recognized. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ID for this command.\\ + int id& audio sub-stream id + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Invalid sub-stream id. +} + +\ifunction{AUDIO\_SET\_MIXER}{ + int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio_mixer\_t *mix);}{ + This ioctl lets you adjust the mixer settings of the audio decoder. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ID for this command.\\ + audio_mixer\_t *mix& mixer settings. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EFAULT & mix points to an invalid address. +} + +\ifunction{AUDIO\_SET\_STREAMTYPE}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, int type);}{ + This ioctl tells the driver which kind of audio stream to expect. + This is useful if the stream offers several audio sub-streams + like LPCM and AC3. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ + int type & stream type\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& type is not a valid or supported stream type.\\ +} + + +\ifunction{AUDIO\_SET\_EXT\_ID}{ + int ioctl(fd, int request = AUDIO\_SET\_EXT\_ID, int id);}{ + This ioctl can be used to set the extension id for MPEG streams in + DVD playback. Only the first 3 bits are recognized. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_EXT\_ID for this command.\\ + int id & audio sub\_stream\_id\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& id is not a valid id.\\ +} + +\ifunction{AUDIO\_SET\_ATTRIBUTES}{ + int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ + This ioctl is intended for DVD playback and allows you to set + certain information about the audio stream. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\ + iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& attr is not a valid or supported attribute setting.\\ +} + +\ifunction{AUDIO\_SET\_KARAOKE}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio_karaoke\_t *karaoke);}{ + This ioctl allows one to set the mixer settings for a karaoke DVD. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ + audio_karaoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ + }{ + EBADF & fd is not a valid open file descriptor \\ + EINVAL& karaoke is not a valid or supported karaoke setting.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/bibsection.sty b/dvb-spec/dvbapi/bibsection.sty new file mode 100644 index 000000000..7f9eedc6a --- /dev/null +++ b/dvb-spec/dvbapi/bibsection.sty @@ -0,0 +1,29 @@ +\def\thebibliography#1{\chapter*{\bibname\@mkboth + {\uppercase{\bibname}}{\uppercase{\bibname}}} + \setcounter{chapter}{0} + \setcounter{section}{0} + \def\thechapter{Bib} + \def\thesection{\Alph{section}} + \edef\biblab{#1} + \addcontentsline{toc}{chapter}{\bibname} + } + +\def\bibtitle#1#2{\expandafter\def\csname bibtitle#1\endcsname{ + \bibsection{#2}} } + +\def\bibsection#1{\section{#1} + \begin{list} + {\@biblabel{\arabic{enumiv}}}{\settowidth\labelwidth{\@biblabel{\biblab}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep + \usecounter{enumiv}% + \let\p@enumiv\@empty + \def\theenumiv{\arabic{enumiv}}}% + \def\newblock{\hskip .11em plus.33em minus.07em}% + \sloppy\clubpenalty4000\widowpenalty4000 + \sfcode`\.=\@m} + +\def\endbibsection{\end{list}} + +\def\endthebibliography{\endbibsection} + diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex new file mode 100644 index 000000000..eba512b1b --- /dev/null +++ b/dvb-spec/dvbapi/ca.tex @@ -0,0 +1,127 @@ +\devsec{DVB CA Device} + +The DVB CA device controls the conditional access hardware. +It can be accessed through \texttt{/dev/ost/ca}. + + +\devsubsec{CA Data Types} + +\devsubsubsec{ca\_slot\_info\_t} +\label{caslotinfo} + +\begin{verbatim} +/* slot interface types and info */ + +typedef struct ca_slot_info_s { + int num; /* slot number */ + + int type; /* CA interface this slot supports */ +#define CA_CI 1 /* CI high level interface */ +#define CA_CI_LINK 2 /* CI link layer level interface */ +#define CA_CI_PHYS 4 /* CI physical layer level interface */ +#define CA_SC 128 /* simple smart card interface */ + + unsigned int flags; +#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ +#define CA_CI_MODULE_READY 2 +} ca_slot_info_t; +\end{verbatim} + +\devsubsubsec{ca\_descr\_info\_t} +\label{cadescrinfo} + +\begin{verbatim} +typedef struct ca_descr_info_s { + unsigned int num; /* number of available descramblers (keys) */ + unsigned int type; /* type of supported scrambling system */ +#define CA_ECD 1 +#define CA_NDS 2 +#define CA_DSS 4 +} ca_descr_info_t; +\end{verbatim} + +\devsubsubsec{ca\_cap\_t} +\label{cacap} + +\begin{verbatim} +typedef struct ca_cap_s { + unsigned int slot_num; /* total number of CA card and module slots */ + unsigned int slot_type; /* OR of all supported types */ + unsigned int descr_num; /* total number of descrambler slots (keys) */ + unsigned int descr_type;/* OR of all supported types */ +} ca_cap_t; +\end{verbatim} + + +\devsubsubsec{ca\_msg\_t} +\label{camsg} + +\begin{verbatim} +/* a message to/from a CI-CAM */ +typedef struct ca_msg_s { + unsigned int index; + unsigned int type; + unsigned int length; + unsigned char msg[256]; +} ca_msg_t; +\end{verbatim} + + +\devsubsubsec{ca\_descr\_t} +\label{cadescr} + +\begin{verbatim} +typedef struct ca_descr_s { + unsigned int index; + unsigned int parity; + unsigned char cw[8]; +} ca_descr_t; +\end{verbatim} + +\clearpage + +\devsubsec{CA Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named ca device (e.g. /dev/ost/ca) + for subsequent use. + + When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in + the documentation for functions where there is a difference. + It does not affect the semantics of the open() call itself. + A device opened in blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system + call. + This is a standard system call, documented in the Linux manual + page for fcntl. + Only one user can open the CA Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error code will be returned. + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened audio device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/cimlogo.psi b/dvb-spec/dvbapi/cimlogo.psi new file mode 100644 index 000000000..b7b089a49 --- /dev/null +++ b/dvb-spec/dvbapi/cimlogo.psi @@ -0,0 +1,122 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: /home/rjkm/dvbapi/cimlogo.ps +%%Creator: XV Version 3.10a Rev: 12/29/94 (PNG patch 1.2) - by John Bradley +%%BoundingBox: 275 411 309 440 +%%Pages: 1 +%%DocumentFonts: +%%EndComments +%%EndProlog + +%%Page: 1 1 + +% remember original state +/origstate save def + +% build a temporary dictionary +20 dict begin + +% define string to hold a scanline's worth of data +/pix 45 string def + +% define space for color conversions +/grays 45 string def % space for gray scale line +/npixls 0 def +/rgbindx 0 def + +% lower left corner +275 411 translate + +% size of image (on paper, in 1/72inch coords) +33.76800 28.51200 scale + +45 38 8 % dimensions of data +[45 0 0 -38 0 38] % mapping matrix +{currentfile pix readhexstring pop} +image + +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffff00ffffffffffff0000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffff0000000000ffffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffff0000000000000000ffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffff0000000000000000ffffffff000000000000ffffffffffffffffffff +ffffffffffffffffff +ffffffffffffff000000000000000000ffffff000000000000ffffffffffffffffffffff +ffffffffffffffffff +ffffffffffff0000000000000000ffffffffff000000000000ffffff00000000ffffffff +ffffffffffffffffff +ffffffffff00000000000000ffffffffffffff0000000000ffffff0000000000ffffffff +ffffffffffffffffff +ffffffffff000000000000ffffffffffffff000000000000ffffff000000000000ffffff +ffffffffffffffffff +ffffffff00000000000000ffffffffffffff000000000000ffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffff000000000000ffffffff000000000000ffff +ffffffffffffffffff +ffffffff0000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff +ffffffffffffffffff +ffffff000000000000ffffffffffffffff000000000000ffffffffffff0000000000ffff +ffffffffffffffffff +ffffff0000000000ffffffffffffffffff000000000000ffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffffff0000000000ffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff000000000000ffffffffffffffff0000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff000000000000ffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffffff0000000000ffffffffffffffffff0000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffff000000000000ffffffffffffffff000000000000ff +ffffffffffffffffff +ffffff0000000000ffffffffffffff000000000000ffffffffffffffff0000000000ffff +ffffffffffffffffff +ffffff000000000000ffffffffffffff00000000ffffffffffffffffff0000000000ffff +ffffffffffffffffff +ffffffff0000000000ffffffffffffffff0000ffffffffffffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffffffffffffffffffffffff000000000000ffff +ffffffffffffffffff +ffffffff000000000000ffffffffffffffffffffffffffffffffff000000000000ffffff +ffffffffffffffffff +ffffffffff00000000000000ffffffffffffffffffffffffffff000000000000ffffffff +ff0000000000ffffff +ffffffffff0000000000000000ffffffffffffffffffffffff00000000000000ffffffff +00000000000000ffff +ffffffffffff000000000000000000ffffffffffffffff0000000000000000ffffffffff +00000000000000ffff +ffffffffffffff0000000000000000000000000000000000000000000000ffffffffffff +0000000000000000ff +ffffffffffffffff000000000000000000000000000000000000000000ffffffffffffff +00000000000000ffff +ffffffffffffffffffff0000000000000000000000000000000000ffffffffffffffffff +00000000000000ffff +ffffffffffffffffffffffff00000000000000000000000000ffffffffffffffffffffff +ff0000000000ffffff +ffffffffffffffffffffffffffffff00ff0000000000ffffffffffffffffffffffffffff +ffffff0000ffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffff + +showpage + +% stop using temporary dictionary +end + +% restore original state +origstate restore + +%%Trailer diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex new file mode 100644 index 000000000..3607bbffc --- /dev/null +++ b/dvb-spec/dvbapi/demux.tex @@ -0,0 +1,392 @@ +\devsec{DVB Demux Device} + +The DVB demux device controls the filters of the DVB hardware/software. +It can be accessed through \texttt{/dev/ost/demux}. + +\devsubsec{Demux Data Types} + +\begin{verbatim} +typedef uint16_t dvb_pid_t; +\end{verbatim} + + +\devsubsubsec{dmxOutput\_t} +\label{dmxoutput} + +\begin{verbatim} +typedef enum +{ + DMX_OUT_DECODER, + DMX_OUT_TAP, + DMX_OUT_TS_TAP +} dmx_output_t; +\end{verbatim} +/* Output multiplexed into a new TS */ +/* (to be retrieved by reading from the */ +/* logical DVR device). */ + + +\devsubsubsec{dmxInput\_t} +\label{dmxinput} + +\begin{verbatim} +typedef enum +{ + DMX_IN_FRONTEND, /* Input from a front-end device. */ + DMX_IN_DVR /* Input from the logical DVR device. */ +} dmx_input_t; +\end{verbatim} + + +\devsubsubsec{dmxPesType\_t} +\label{dmxpestype} + +\begin{verbatim} +typedef enum +{ + DMX_PES_AUDIO, + DMX_PES_VIDEO, + DMX_PES_TELETEXT, + DMX_PES_SUBTITLE, + DMX_PES_PCR, + DMX_PES_OTHER +} dmx_pes_type_t; +\end{verbatim} + + +\devsubsubsec{dmx_event\_t} +\label{dmxeventt} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_EV, + DMX_FRONTEND_EV +} dmx_event_t; +\end{verbatim} + + +\devsubsubsec{dmxScramblingStatus\_t} +\label{dmxscramblingstatus} + +\begin{verbatim} +typedef enum +{ + DMX_SCRAMBLING_OFF, + DMX_SCRAMBLING_ON +} dmx_scrambling_status_t; +\end{verbatim} + + +\devsubsubsec{dmx_filter\_t} +\label{dmxfilter} + +\begin{verbatim} +typedef struct dmx_filter +{ + uint8_t filter[DMX_FILTER_SIZE]; + uint8_t mask[DMX_FILTER_SIZE]; +} dmx_filter_t; +\end{verbatim} + + +\devsubsubsec{dmx_sct_filter_params} +\label{dmxsctfilterparams} + +\begin{verbatim} +struct dmx_sct_filter_params +{ + dvb_pid_t pid; + dmx_filter_t filter; + uint32_t timeout; + uint32_t flags; +#define DMX_CHECK_CRC 1 +#define DMX_ONESHOT 2 +#define DMX_IMMEDIATE_START 4 +}; +\end{verbatim} + + +\devsubsubsec{dmx_pes_filter_params} +\label{dmxpesfilterparams} + +\begin{verbatim} +struct dmx_pes_filter_params +{ + dvb_pid_t pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pesType; + uint32_t flags; +}; +\end{verbatim} + + +\devsubsubsec{dmx_event} +\label{dmxevent} + +\begin{verbatim} +struct dmx_event +{ + dmx_event_t event; + time_t timeStamp; + union + { + dmx_scrambling_status_t scrambling; + } u; +}; +\end{verbatim} + +\clearpage + +\devsubsec{Demux Function Calls} +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call, used with a device name of /dev/ost/demuxn, where n + denotes the specific demux device to be opened, allocates a new filter + and returns a handle which can be used for subsequent control of that + filter. This call has to be made for each filter to be used, i.e. every + returned file descriptor is a reference to a single filter. + /dev/ost/dvrn is a logical device to be used for retrieving Transport + Streams for digital video recording. n identifies the physical demux + device that provides the actual DVR functionality. When reading from + this device a transport stream containing the packets from all PES + filters set in the corresponding demux device (/dev/ost/demuxn) + having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream + is replayed by writing to this device. +% This device can only be opened in read-write mode. + + The significance of blocking or non-blocking mode is described in the + documentation for functions where there is a difference. It does not + affect the semantics of the open() call itself. A device opened in + blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system call. + }{ + const char *deviceName & Name of demux device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINVAL & Invalid argument.\\ + EMFILE & ``Too many open files'', i.e. no more filters available.\\ + ENOMEM & The driver failed to allocate enough memory.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call deactivates and deallocates a filter that was previously + allocated via the open() call. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{read()}{ + size\_t read(int fd, void *buf, size\_t count); + }{ + This system call returns filtered data, which might be section or PES + data. The filtered data is transferred from the driver's internal circular + buffer to buf. The maximum amount of data to be transferred is implied by + count.\\ + When returning section data the driver always tries to return a complete + single section (even though buf would provide buffer space for more data). + If the size of the buffer is smaller than the section as much as possible + will be returned, and the remaining data will be provided in subsequent + calls.\\ + The size of the internal buffer is 2 * 4096 bytes (the size of two maximum + sized sections) by default. The size of this buffer may be changed by + using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough, + or if the read operations are not performed fast enough, this may result + in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, + and the circular buffer will be emptied. + This call is blocking if there is no data to return, i.e. the process + will be put to sleep waiting for data, unless the O\_NONBLOCK flag is + specified.\\ + Note that in order to be able to read, the filtering process has to be + started by defining either a section or a PES filter by means of the + ioctl functions, and then starting the filtering process via the DMX\_START + ioctl function or by setting the DMX\_IMMEDIATE\_START flag. + If the reading is done from a logical DVR demux device, the data will + constitute a Transport Stream including the packets from all PES filters + in the corresponding demux device /dev/ost/demuxn having the output set + to DMX\_OUT\_TS\_TAP. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer to be used for returned filtered data.\\ + size\_t count & Size of buf.\\ + }{ + EWOULDBLOCK & No data to return and O\_NONBLOCK was specified.\\ + EBADF & fd is not a valid open file descriptor.\\ + ECRC & Last section had a CRC error - no data returned. + The buffer is flushed.\\ + EBUFFEROVERFLOW & \\ +& The filtered data was not read from the buffer in + due time, resulting in non-read data being lost. + The buffer is flushed.\\ + ETIMEDOUT & The section was not loaded within the stated + timeout period. See ioctl DMX\_SET\_FILTER for + how to set a timeout.\\ + EFAULT & The driver failed to write to the callers buffer + due to an invalid *buf pointer.\\ +} + +\function{write()}{ + ssize\_t write(int fd, const void *buf, size\_t count); + }{ + This system call is only provided by the logical device /dev/ost/dvrn, + where n identifies the physical demux device that provides the actual + DVR functionality. It is used for replay of a digitally recorded + Transport Stream. Matching filters have to be defined in the + corresponding physical demux device, /dev/ost/demuxn. + The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the Transport Stream.\\ + size\_t count & Size of buf.\\ + }{ + EWOULDBLOCK & No data was written. This might happen if + O\_NONBLOCK was specified and there is no more + buffer space available (if O\_NONBLOCK is not + specified the function will block until buffer + space is available).\\ + EBUSY & This error code indicates that there are + conflicting requests. The corresponding demux + device is setup to receive data from the front- + end. Make sure that these filters are stopped + and that the filters with input set to DMX\_IN\_DVR + are started.\\ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{DMX\_START}{ + int ioctl( int fd, int request = DMX\_START); + }{ + This ioctl call is used to start the actual filtering operation + defined via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_START for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument, i.e. no filtering parameters + provided via the DMX\_SET\_FILTER or + DMX\_SET\_PES\_FILTER functions.\\ + EBUSY & This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter.\\ +} + +\ifunction{DMX\_STOP}{ + int ioctl( int fd, int request = DMX\_STOP); + }{ + This ioctl call is used to stop the actual filtering operation defined + via the ioctl calls DMX\_SET\_FILTER or DMX\_SET\_PES\_FILTER and started via + the DMX\_START command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_STOP for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ +} + +\ifunction{DMX\_SET\_FILTER}{ + int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx_sct_filter_params *params); + }{ + This ioctl call sets up a filter according to the filter and mask + parameters provided. A timeout may be defined stating number of seconds + to wait for a section to be loaded. A value of 0 means that no timeout + should be applied. Finally there is a flag field where it is possible to + state whether a section should be CRC-checked, whether the filter should + be a "one-shot" filter, i.e. if the filtering operation should be stopped + after the first section is received, and whether the filtering operation + should be started immediately (without waiting for a DMX\_START ioctl call). + If a filter was previously set-up, this filter will be canceled, and the + receive buffer will be flushed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_FILTER for this command.\\ + struct dmx_sct_filter_params *params + & Pointer to structure containing filter parameters.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument.\\ +} + +\ifunction{DMX\_SET\_PES\_FILTER}{ + int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, + struct dmx_pes_filter_params *params); + }{ + This ioctl call sets up a PES filter according to the parameters provided. + By a PES filter is meant a filter that is based just on the packet + identifier (PID), i.e. no PES header or payload filtering capability is + supported.\\ + The transport stream destination for the filtered output may be set. Also + the PES type may be stated in order to be able to e.g. direct a video + stream directly to the video decoder. Finally there is a flag field where + it is possible to state whether the filtering operation should be started + immediately (without waiting for a DMX\_START ioctl call). + If a filter was previously set-up, this filter will be cancelled, and the + receive buffer will be flushed. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ + struct dmx_pes_filter_params *params + & Pointer to structure containing filter parameters.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EINVAL & Invalid argument.\\ + EBUSY & This error code indicates that there are + conflicting requests. There are active filters + filtering data from another input source. Make + sure that these filters are stopped before starting + this filter.\\ +} + +\ifunction{DMX\_SET\_BUFFER\_SIZE}{ + int ioctl( int fd, int request = DMX\_SET\_BUFFER\_SIZE, unsigned long size); + }{ + This ioctl call is used to set the size of the circular buffer used + for filtered data. The default size is two maximum sized sections, i.e. + if this function is not called a buffer size of 2 * 4096 bytes will be + used. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_SET\_BUFFER\_SIZE for this command.\\ + unsigned long size & Size of circular buffer.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + ENOMEM & The driver was not able to allocate a buffer of the requested size.\\ +} + +\ifunction{DMX\_GET\_EVENT}{ + int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx_event *ev); + }{ + This ioctl call returns an event if available. If an event is not + available, the behavior depends on whether the device is in blocking or + non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available.\\ + The standard Linux poll() and/or select() system calls can be used with + the device file descriptor to watch for new events. For select(), the + file descriptor should be included in the exceptfds argument, and for + poll(), POLLPRI should be specified as the wake-up condition. + Only the latest event for each filter is saved. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_GET\_EVENT for this command.\\ + struct dmx_event *ev & Pointer to the location where the event is to be stored.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & ev points to an invalid address.\\ + EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex new file mode 100644 index 000000000..9c561e853 --- /dev/null +++ b/dvb-spec/dvbapi/devices.tex @@ -0,0 +1,12 @@ +\input{video.tex} +\input{audio.tex} +\input{frontend.tex} +\input{sec.tex} +\input{demux.tex} +\input{ca.tex} +\input{kdapi.tex} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex new file mode 100644 index 000000000..ad0251c01 --- /dev/null +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -0,0 +1,166 @@ +\documentclass[10pt]{book} +\usepackage[dvips,colorlinks=true]{hyperref} + +\usepackage{times} + +%\usepackage[hang]{caption} +\usepackage{fancyheadings} +%\usepackage{lucidabr} +%\usepackage{fancybox} +\usepackage{array} +\usepackage{graphicx} +%\usepackage{latexsym} +%\usepackage{pstricks,pst-node,pst-tree} +%\usepackage{verbatim} +%\usepackage{rotating} +%\usepackage{pdftex} +%\usepackage{color} +%\usepackage{subfigure} +%\usepackage{wrapfig} + +\newcommand{\devsec}[1]{\chapter{#1}} +\newcommand{\devsubsec}[1]{\section{#1}} +\newcommand{\devsubsubsec}[1]{\subsection{#1}} +\newcommand{\function}[5]{ + \subsection{#1} + + \noindent DESCRIPTION + \medskip + + \begin{tabular}[h]{p{11cm}} + #3 + \end{tabular} + + \medskip + \noindent SYNOPSIS + \medskip + + \begin{tabular}[h]{p{11cm}} + {\tt #2} + \end{tabular} + + %\item[] +\medskip +\noindent PARAMETERS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #4 + \end{tabular} + + %\item[] +\medskip +\noindent ERRORS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #5 + \end{tabular} + + %\end{itemize} + +\medskip +} +\def\ifunction#1#2#3#4#5{\function{#1\index{#1}}{#2}{#3}{#4}{#5}} + +\newcommand{\kfunction}[5]{ + \subsection{#1} + \noindent DESCRIPTION + \medskip + + \begin{tabular}[h]{p{11cm}} + #3 + \end{tabular} + + \medskip + \noindent SYNOPSIS + \medskip + + \begin{tabular}[h]{p{11cm}} + {\tt #2} + \end{tabular} + + %\item[] +\medskip +\noindent PARAMETERS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #4 + \end{tabular} + + %\item[] +\medskip +\noindent RETURNS +\medskip + + \begin{tabular}[h]{p{3cm}p{8cm}} + #5 + \end{tabular} + + %\end{itemize} + +\medskip +} +\def\kifunction#1#2#3#4#5{\kfunction{#1\index{#1}}{#2}{#3}{#4}{#5}} + + +%\usepackage{index} +%\makeindex + + +\begin{document} + +\input{title.tex} + +\cleardoublepage + +\pagenumbering{roman} +\pagestyle{fancyplain} + + +\tableofcontents +%\listoffigures +%\listoftables + +\cleardoublepage + +\pagenumbering{arabic} + +\renewcommand{\chaptermark}[1]{\markboth{\uppercase{#1}}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} +\lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} +\rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} +\cfoot{\copyright 2002 convergence GmbH} + +\input{intro.tex} + +\input{devices.tex} + +\input{examples.tex} + +\cleardoublepage + +\appendix + +\cleardoublepage + +\thispagestyle{plain}\chaptermark{Bibliography} +\addcontentsline{toc}{chapter}{Bibliography} +\bibliographystyle{bibsec} +\bibliography{main} + +\cleardoublepage + +\thispagestyle{plain}\chaptermark{Subject Index} +\addcontentsline{toc}{chapter}{Subject Index} +%\printindex + +\cleardoublepage + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/dvb-spec/dvbapi/dvbstb.fig b/dvb-spec/dvbapi/dvbstb.fig new file mode 100644 index 000000000..0a6bbadc3 --- /dev/null +++ b/dvb-spec/dvbapi/dvbstb.fig @@ -0,0 +1,59 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1620 360 2520 360 2520 900 1620 900 1620 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 1260 1080 1620 630 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2520 630 2880 630 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2880 360 3780 360 3780 900 2880 900 2880 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4590 900 3330 1170 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4590 900 4590 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4140 360 5040 360 5040 900 4140 900 4140 360 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3780 630 4140 630 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4140 1170 5040 1170 5040 1710 4140 1710 4140 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2880 1170 3780 1170 3780 1710 2880 1710 2880 1170 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1620 1170 2520 1170 2520 1710 1620 1710 1620 1170 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 1620 1440 1260 1080 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1350 225 5175 225 5175 1845 1350 1845 1350 225 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3240 1710 3960 2070 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4590 1710 3960 2070 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3510 2070 4410 2070 4410 2610 3510 2610 3510 2070 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 360 810 1260 810 1260 1350 360 1350 360 810 +4 0 0 50 0 0 12 0.0000 4 135 675 1755 675 Frontend\001 +4 0 0 50 0 0 12 0.0000 4 135 690 4275 675 Demuxer\001 +4 0 0 50 0 0 12 0.0000 4 135 450 4365 1485 Video\001 +4 0 0 50 0 0 12 0.0000 4 135 450 3105 1485 Audio\001 +4 0 0 50 0 0 12 0.0000 4 135 345 1890 1485 SEC\001 +4 0 0 50 0 0 12 0.0000 4 135 255 3195 675 CA\001 +4 0 0 50 0 0 12 0.0000 4 135 645 495 1125 Antenna\001 +4 0 0 50 0 0 12 0.0000 4 135 240 3870 2385 TV\001 diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex new file mode 100644 index 000000000..ea2797481 --- /dev/null +++ b/dvb-spec/dvbapi/examples.tex @@ -0,0 +1,366 @@ +\chapter{Examples} +In this section we would like to present some examples for using the DVB API. + +\section{Tuning} +We will start with a generic tuning subroutine that uses the frontend +and SEC, as well as the demux devices. The example is given for QPSK +tuners, but can easily be adjusted for QAM. + +{\small +\begin{verbatim} +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define DMX "/dev/ost/demux" +#define FRONT "/dev/ost/frontend" +#define SEC "/dev/ost/sec" + +/* routine for checking if we have a signal and other status information*/ +int FEReadStatus(int fd, fe_status_t *stat) +{ + int ans; + + if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ + perror("FE READ STATUS: "); + return -1; + } + + if (*stat & FE_HAS_POWER) + printf("FE HAS POWER\n"); + + if (*stat & FE_HAS_SIGNAL) + printf("FE HAS SIGNAL\n"); + + if (*stat & FE_SPECTRUM_INV) + printf("SPEKTRUM INV\n"); + + return 0; +} + + +/* tune qpsk */ +/* freq: frequency of transponder */ +/* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */ +/* diseqc: DiSEqC address of the used LNB */ +/* pol: Polarisation */ +/* srate: Symbol Rate */ +/* fec. FEC */ +/* lnb_lof1: local frequency of lower LNB band */ +/* lnb_lof2: local frequency of upper LNB band */ +/* lnb_slof: switch frequency of LNB */ + +int set_qpsk_channel(int freq, int vpid, int apid, int tpid, + int diseqc, int pol, int srate, int fec, int lnb_lof1, + int lnb_lof2, int lnb_slof) +{ + struct secCommand scmd; + struct secCmdSequence scmds; + struct dmx_pes_filter_params pesFilterParams; + FrontendParameters frp; + struct pollfd pfd[1]; + FrontendEvent event; + int demux1, dmeux2, demux3, front, + + frequency = (uint32_t) freq; + symbolrate = (uint32_t) srate; + + if((front = open(FRONT,O_RDWR)) < 0){ + perror("FRONTEND DEVICE: "); + return -1; + } + + if((sec = open(SEC,O_RDWR)) < 0){ + perror("SEC DEVICE: "); + return -1; + } + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux3 < 0){ + if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (freq < lnb_slof) { + frp.Frequency = (freq - lnb_lof1); + scmds.continuousTone = SEC_TONE_OFF; + } else { + frp.Frequency = (freq - lnb_lof2); + scmds.continuousTone = SEC_TONE_ON; + } + frp.Inversion = INVERSION_AUTO; + if (pol) scmds.voltage = SEC_VOLTAGE_18; + else scmds.voltage = SEC_VOLTAGE_13; + + scmd.type=0; + scmd.u.diseqc.addr=0x10; + scmd.u.diseqc.cmd=0x38; + scmd.u.diseqc.numParams=1; + scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | + (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | + (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); + + scmds.miniCommand=SEC_MINI_NONE; + scmds.numCommands=1; + scmds.commands=&scmd; + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ + perror("SEC SEND: "); + return -1; + } + + frp.u.qpsk.SymbolRate = srate; + frp.u.qpsk.FEC_inner = fec; + + if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ + perror("QPSK TUNE: "); + return -1; + } + + pfd[0].fd = front; + pfd[0].events = POLLIN; + + if (poll(pfd,1,3000)){ + if (pfd[0].revents & POLLIN){ + printf("Getting QPSK event\n"); + if ( ioctl(front, FE_GET_EVENT, &event) + + == -EBUFFEROVERFLOW){ + perror("qpsk get event"); + return -1; + } + printf("Received "); + switch(event.type){ + case FE_UNEXPECTED_EV: + printf("unexpected event\n"); + return -1; + case FE_FAILURE_EV: + printf("failure event\n"); + return -1; + + case FE_COMPLETION_EV: + printf("completion event\n"); + } + } + } + + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_vpid"); + return -1; + } + + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_apid"); + return -1; + } + + pesFilterParams.pid = tpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pesType = DMX_PES_TELETEXT; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("set_tpid"); + return -1; + } + + return has_signal(fds); +} + +\end{verbatim} +} +The program assumes that you are using a universal LNB and a standard +DiSEqC switch with up to 4 addresses. Of course, you could build in +some more checking if tuning was successful and maybe try to repeat +the tuning process. Depending on the external hardware, i.e. LNB and +DiSEqC switch, and weather conditions this may be necessary. + + +\section{The DVR device} +The following program code shows how to use the DVR device for +recording. + +{\small +\begin{verbatim} +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#define DVR "/dev/ost/dvr" +#define AUDIO "/dev/ost/audio" +#define VIDEO "/dev/ost/video" + +#define BUFFY (188*20) +#define MAX_LENGTH (1024*1024*5) /* record 5MB */ + + +/* switch the demuxes to recording, assuming the transponder is tuned */ + +/* demux1, demux2: file descriptor of video and audio filters */ +/* vpid, apid: PIDs of video and audio channels */ + +int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) +{ + struct dmx_pes_filter_params pesFilterParams; + + if (demux1 < 0){ + if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + if (demux2 < 0){ + if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) + < 0){ + perror("DEMUX DEVICE: "); + return -1; + } + } + + pesFilterParams.pid = vpid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + pesFilterParams.pid = apid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + perror("DEMUX DEVICE"); + return -1; + } + return 0; +} + +/* start recording MAX_LENGTH , assuming the transponder is tuned */ + +/* demux1, demux2: file descriptor of video and audio filters */ +/* vpid, apid: PIDs of video and audio channels */ +int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid) +{ + int i; + int len; + int written; + uint8_t buf[BUFFY]; + uint64_t length; + struct pollfd pfd[1]; + int dvr, dvr_out; + + /* open dvr device */ + if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ + perror("DVR DEVICE"); + return -1; + } + + /* switch video and audio demuxes to dvr */ + printf ("Switching dvr on\n"); + i = switch_to_record(demux1, demux2, vpid, apid); + printf("finished: "); + + printf("Recording %2.0f MB of test file in TS format\n", + MAX_LENGTH/(1024.0*1024.0)); + length = 0; + + /* open output file */ + if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT + |O_TRUNC, S_IRUSR|S_IWUSR + |S_IRGRP|S_IWGRP|S_IROTH| + S_IWOTH)) < 0){ + perror("Can't open file for dvr test"); + return -1; + } + + pfd[0].fd = dvr; + pfd[0].events = POLLIN; + + /* poll for dvr data and write to file */ + while (length < MAX_LENGTH ) { + if (poll(pfd,1,1)){ + if (pfd[0].revents & POLLIN){ + len = read(dvr, buf, BUFFY); + if (len < 0){ + perror("recording"); + return -1; + } + if (len > 0){ + written = 0; + while (written < len) + written += + write (dvr_out, + buf, len); + length += len; + printf("written %2.0f MB\r", + length/1024./1024.); + } + } + } + } + return 0; +} + +\end{verbatim} +} +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% TeX-master: t +%%% End: diff --git a/dvb-spec/dvbapi/fig2pstex b/dvb-spec/dvbapi/fig2pstex new file mode 100755 index 000000000..bf62eb7ec --- /dev/null +++ b/dvb-spec/dvbapi/fig2pstex @@ -0,0 +1,6 @@ +#!/bin/sh +f=`basename $1 .fig` +fig2dev -L pstex $f.fig $f.ps +fig2dev -L pstex_t -p $f.ps $f.fig $f.pst2 +./getbb $f.pst2 $f.ps > $f.pst +rm $f.pst2 \ No newline at end of file diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex new file mode 100644 index 000000000..cb3285d06 --- /dev/null +++ b/dvb-spec/dvbapi/frontend.tex @@ -0,0 +1,630 @@ +\devsec{DVB Frontend API} + +The DVB frontend device controls the tuner and DVB demodulator hardware. +It can be accessed through \texttt{/dev/ost/frontend}. +If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. +The frontend device will only be made visible through \texttt{devfs} +if the corresponding card actually has a frontend. Cards which support +the DVB API but, e.g., only can play back recordings, will not offer the +frontend device. + +\devsubsec{Frontend Data Types} + +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the feStatus data +type defined by +\begin{verbatim} +typedef uint32_t feStatus; +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. + +\noindent +It can take on the values +\begin{verbatim} +#define FE_HAS_POWER 1 +#define FE_HAS_SIGNAL 2 +#define FE_SPECTRUM_INV 4 +#define FE_HAS_LOCK 8 +#define FE_HAS_CARRIER 16 +#define FE_HAS_VITERBI 32 +#define FE_HAS_SYNC 64 +#define TUNER_HAS_LOCK 128 +\end{verbatim} +which can be ORed together and have the following meaning: + +\medskip + +\begin{tabular}{lp{11cm}} +FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ +FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ +FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ +FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ +FE\_HAS\_CARRIER & carrier detected in signal\\ +FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ +FE\_HAS\_SYNC & TS sync bytes detected \\ +TUNER\_HAS\_LOCK & the tuner has a frequency lock +\end{tabular} + + +\devsubsubsec{frontend parameters} +\label{frontendparameters} + +The kind of parameters passed to the frontend device for tuning +depend on the kind of hardware you are using. +All kinds of parameters are combined as a union in the +FrontendParameters structure: +\begin{verbatim} +typedef struct { + __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t Inversion; /* spectral inversion */ + union { + QPSKParameters qpsk; + QAMParameters qam; + OFDMParameters ofdm; + } u; +} FrontendParameters; +\end{verbatim} + +For satellite QPSK frontends you have to use QPSKParameters defined by +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + fe_code_rate_t FEC_inner; /* forward error correction (see above) */ +} QPSKParameters; +\end{verbatim} +for cable QAM frontend you use the QAMParameters structure +\begin{verbatim} +typedef struct { + __u32 SymbolRate; /* symbol rate in Symbols per second */ + fe_code_rate_t FEC_outer; /* forward error correction (see above) */ + fe_code_rate_t FEC_inner; /* forward error correction (see above) */ + fe_modulation_t QAM; /* modulation type (see above) */ +} QAMParameters; +\end{verbatim} +DVB-T frontends are supported by the OFDMParamters structure +\begin{verbatim} +typedef struct { + fe_bandwidth_t bandWidth; + fe_code_rate_t HP_fe_code_rate_t; /* high priority stream code rate */ + fe_code_rate_t LP_fe_code_rate_t; /* low priority stream code rate */ + fe_modulation_t Constellation; /* modulation type (see above) */ + fe_transmit_mode_t TransmissionMode; + fe_guard_interval_t guardInterval; + fe_hierarchy_t fe_hierarchy_tInformation; +} OFDMParameters; +\end{verbatim} + +In the case of QPSK frontends the Frequency field specifies the intermediate +frequency, i.e. the offset which is effectively added to the local oscillator +frequency (LOF) of the LNB. +The intermediate frequency has to be specified in units of kHz. +For QAM and OFDM frontends the Frequency specifies the absolute frequency +and is given in Hz. + +The Inversion field can take one of these values: +\begin{verbatim} +typedef enum { + INVERSION_OFF, + INVERSION_ON, + INVERSION_AUTO +} fe_spectral_inversion_t; +\end{verbatim} +It indicates if spectral inversion should be presumed or not. +In the automatic setting (\verb INVERSION\_AUTO) the hardware will +try to figure out the correct setting by itself. + +\noindent +The possible values for the FEC\_inner field are +\begin{verbatim} +enum { + FEC_AUTO, + FEC_1_2, + FEC_2_3, + FEC_3_4, + FEC_5_6, + FEC_7_8, + FEC_NONE +}; +\end{verbatim} +which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +no error correction or auto detection. + +\noindent +For cable and terrestrial frontends (QAM and OFDM) one also has to +specify the quadrature modulation mode which can be one of the following: +\begin{verbatim} +typedef enum +{ QPSK, + QAM_16, + QAM_32, + QAM_64, + QAM_128, + QAM_256 +} QAM_TYPE; +\end{verbatim} + +Finally, there are several more parameters for OFDM: +\begin{verbatim} +typedef enum { + TRANSMISSION_MODE_2K, + TRANSMISSION_MODE_8K +} fe_transmit_mode_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + BANDWIDTH_8_MHZ, + BANDWIDTH_7_MHZ, + BANDWIDTH_6_MHZ +} fe_bandwidth_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + GUARD_INTERVAL_1_32, + GUARD_INTERVAL_1_16, + GUARD_INTERVAL_1_8, + GUARD_INTERVAL_1_4 +} fe_guard_interval_t; +\end{verbatim} + +\begin{verbatim} +typedef enum { + HIERARCHY_NONE, + HIERARCHY_1, + HIERARCHY_2, + HIERARCHY_4 +} fe_hierarchy_t; +\end{verbatim} + + +\devsubsubsec{frontend events} +\label{frontendevents} + +\begin{verbatim} +enum { + FE_UNEXPECTED_EV, + FE_COMPLETION_EV, + FE_FAILURE_EV +}; +\end{verbatim} + +\begin{verbatim} +typedef struct { + EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ + long timestamp; /* time in seconds since 1970-01-01 */ + + union { + struct { + fe_status_t previousStatus; /* status before event */ + fe_status_t currentStatus; /* status during event */ + } unexpectedEvent; + FrontendParameters completionEvent; /* parameters for which the + tuning succeeded */ + fe_status_t failureEvent; /* status at failure (e.g. no lock) */ + } u; +} FrontendEvent; +\end{verbatim} + +\begin{verbatim} +struct qpskRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qamRegister { + uint8_t chipId; + uint8_t address; + uint8_t value; +}; +\end{verbatim} + +\begin{verbatim} +struct qpskFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +struct qamFrontendInfo { + uint32_t minFrequency; + uint32_t maxFrequency; + uint32_t maxSymbolRate; + uint32_t minSymbolRate; + uint32_t hwType; + uint32_t hwVersion; +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + FE_POWER_ON, + FE_POWER_STANDBY, + FE_POWER_SUSPEND, + FE_POWER_OFF +} powerState_t; +\end{verbatim} + + +\clearpage + + +\devsubsec{Frontend Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named frontend device (e.g. /dev/ost/qpskfe + for a satellite frontend or /dev/ost/qamfe for a cable frontend) + for subsequent use. + + The device can be opened in read-only mode, which only allows + monitoring of device status and statistics, or read/write mode, which allows + any kind of use (e.g. performing tuning operations.) + + In a system with multiple front-ends, it is usually the case that multiple + devices cannot be open in read/write mode simultaneously. As long as a + front-end device is opened in read/write mode, other open() calls in + read/write mode will either fail or block, depending on whether + non-blocking or blocking mode was specified. + A front-end device opened in blocking mode can later be put into non-blocking + mode (and vice versa) using the F\_SETFL command of the fcntl system call. + This is a standard system call, documented in the Linux manual page for fcntl. + When an open() call has succeeded, the device will be ready for use in the + specified mode. This implies that the corresponding hardware is powered up, + and that other front-ends may have been powered down to make that possible. + + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened front-end device. + After closing a front-end device, its corresponding hardware might be + powered down automatically, but only when this is needed to open + another front-end device. + To affect an unconditional power down, it should be done explicitly using + the OST\_SET\_POWER\_STATE ioctl. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{OST\_SELFTEST}{ + int ioctl(int fd, int request = OST\_SELFTEST);}{ + This ioctl call initiates an automatic self-test of the front-end hardware. + This call requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SELFTEST for this command.\\ + }{ + -1& Self test failure.\\ +} + +\ifunction{OST\_SET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ + This ioctl call, implemented in many OST device drivers, enables direct + control over the power state of the hardware device, which may be on, off, + standby, or suspend. The latter two are low-power modes, which disable all + functionality of the device until turned on again. In contrast to the off + state, however, the standby and suspend states resume operation in the same + state as when the device was active. The only difference between the standby + and suspend states is a different tradeoff between resume time and power + consumption. Power consumption may be lower in the suspend state at the + cost of a longer resume time.\\ + A device that implements this call does not necessarily support two low-power + modes. If it only supports one low-power state, or none at all, the + OST\_SET\_POWER\_STATE operation for the missing states will + still succeed, but + it will be mapped to an existing state as per this table: \\ + \begin{center} + \begin{tabular}[h]{cll} + number of low-power & requested state & resulting state\\ + states supported &&\\ + \\ + 1 & standby & suspend \\ + 1 & suspend & suspend \\ + 0 & standby & on \\ + 0 & suspend & on + \end{tabular} + \end{center}\\ + For other cases where a required state is missing, an error code will be + returned. This can happen if a device does not support the power-off state, + but nevertheless implements this ioctl operation for control of low-power + states. + When opening a device in read/write mode, the driver ensures that the + corresponding hardware device is turned on initially. If the device is + later turned off or put in suspend mode, it has to be explicitly turned on + again.\\ + This call requires read/write access to the device. (Note that the power + management driver can affect the power state of devices without using this + ioctl operation, so having exclusive read/write access to a device does not + imply total control over the power state.) + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_SET\_POWER\_STATE for this command.\\ + uint32\_t state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& turn power on\\ + OST\_POWER\_STANDBY& set device in standby mode\\ + OST\_POWER\_SUSPEND& set device in suspend mode\\ + OST\_POWER\_OFF& turn power off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EPERM & Permission denied (needs read/write access).\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_POWER\_STATE}{ + int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ + This ioctl call, implemented in many OST device drivers, obtains the power + state of the hardware device, which may be on, off, standby, or suspend. + A device that implements this call does not necessarily support all four states. + If there is only one low-power state, the suspend state will be returned for + that state. If there is no low-power state, the on state will be reported + standby and suspend states will be equivalent to the on state. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals OST\_GET\_POWER\_STATE for this command.\\ + uint32\_t *state & Requested power state. One of: \\ + & + \begin{tabular}[h]{ll} + OST\_POWER\_ON& power is on\\ + OST\_POWER\_STANDBY& device in standby mode\\ + OST\_POWER\_SUSPEND& device in suspend mode\\ + OST\_POWER\_OFF& power is off\\ + \end{tabular} + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINVAL& Illegal state, or not available on this device.\\ + EFAULT& state points to invalid address.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_STATUS}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + This ioctl call returns status information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_STATUS for this command.\\ + struct feStatus *status&Points to the location where the front-end + status word is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ +} + +\ifunction{FE\_READ\_BER}{ + int ioctl(int fd, int request = FE\_READ\_BER, uint32\_t *ber);}{ + This ioctl call returns the bit error rate for the signal currently + received/demodulated by the front-end. For this command, read-only access + to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_BER for this command.\\ + uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, + is stored into *ber.\\ + & Example: a value of 2500 corresponds to a bit error + rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ber points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful bit error + rate. Also returned if the front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SNR}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + This ioctl call returns the signal-to-noise ratio for the signal currently + received by the front-end. For this command, read-only access to the device + is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_READ\_SNR for this command.\\ + int32\_t *snr& The signal-to-noise ratio, as a multiple of + $10^{-6}$ dB, is stored into *snr.\\ + & Example: a value of 12,300,000 corresponds + to a signal-to-noise ratio of 12.3 dB. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& snr points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); +}{ +This ioctl call returns the signal strength value for the signal currently +received by the front-end. For this command, read-only access to the device +is sufficient. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ +int32\_t *strength & The signal strength value, as a multiple of + $10^{-6 }$ dBm, + is stored into *strength. \\ + &Example: a value of -12,500,000 corresponds to a signal + strength value of -12.5 dBm. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& status points to invalid address.\\ + ENOSIGNAL& There is no signal, thus no meaningful signal + strength value. Also returned if front-end is not turned on.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_READ\_UNCORRECTED\_BLOCKS}{ + int ioctl( int fd, int request = FE\_READ\_UNCORRECTED\_BLOCKS, uint32\_t *ublocks); }{ + This ioctl call returns the number of uncorrected blocks detected by + the device driver during its lifetime. + For meaningful measurements, the increment in + block count during a specific time interval should be calculated. + For this command, read-only access to the device is sufficient.\\ + Note that the counter will wrap to zero after its maximum count has + been reached. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_READ\_UNCORRECTED\_BLOCKS for this command.\\ +uint32\_t *ublocks & The total number of uncorrected blocks seen +by the driver so far. +}{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ublocks points to invalid address.\\ + ENOSYS& Function not available for this device. +} + + +\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ + When scanning a frequency range, it is desirable to use a scanning step size + that is as large as possible, yet small enough to be able to lock to any signal + within the range. + This ioctl operation does just that - it increments a given frequency by a + step size suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + frequency, hardware capabilities, and parameter settings of the device. Thus, a + returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient.\\ + Note that scanning may still be excruciatingly slow on some hardware, for + other reasons than a non-optimal scanning step size. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ + uint32\_t *freq& Input: a given frequency \\ + & Output: the frequency corresponding to + the next higher frequency setting.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& freq points to invalid address.\\ + EINVAL& Maximum supported frequency reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ + int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); + }{ + When scanning a range of symbol rates (e.g. for "blind acquisition") it is + desirable to use a scanning step size that is as large as possible, yet + small enough to detect any valid signal within the range. This ioctl + operation does just that - it increments a given symbol rate by a step size + suitable for efficient scanning. + The step size used by this function may be a quite complex function of the given + symbol rate, hardware capabilities, and parameter settings of the device. + Thus, a returned result is only valid for the current state of the device. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ + uint32\_t *symbolRate& Input: a given symbol rate \\ + & Output: the symbol rate corresponding to + the next higher symbol rate.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& symbolRate points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ + ENOSYS& Function not available for this device. +} + +\ifunction{FE\_SET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + This ioctl call starts a tuning operation using specified parameters. + The result of this call will be successful if the parameters were valid and + the tuning could be initiated. + The result of the tuning operation in itself, however, will arrive + asynchronously as an event (see documentation for FE\_GET\_EVENT + and FrontendEvent.) + If a new FE\_SET\_FRONTEND operation is initiated before the previous + one was completed, + the previous operation will be aborted in favor of the new one. + This command requires read/write access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct FrontendParameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_EVENT}{ + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ + This ioctl call returns an event of type qpskEvent if available. If an event + is not available, the behavior depends on whether the device is in blocking + or non-blocking mode. In the latter case, the call fails immediately with + errno set to EWOULDBLOCK. In the former case, the call blocks until an event + becomes available.\\ + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Since the event queue allocated is rather small (room for 8 events), the queue + must be serviced regularly to avoid overflow. If an overflow happens, the + oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + the next time the queue is read. After reporting the error condition in this + fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + usual.\\ + For the sake of implementation simplicity, this command requires read/write + access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals QPSK\_GET\_EVENT for this command.\\ + struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& ev points to invalid address.\\ + EWOULDBLOCK & There is no event pending, and the device is in + non-blocking mode.\\ + EBUFFEROVERFLOW &\\ +& Overflow in event queue - one or more events were lost.\\ +} + +\ifunction{FE\_GET\_INFO}{ + int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ + This ioctl call returns information about the front-end. + This call only requires read-only access to the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_GET\_INFO for this command.\\ + struct qpskFrontendInfo *info & Points to the location where the front-end + information is to be stored. + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& info points to invalid address.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/getbb b/dvb-spec/dvbapi/getbb new file mode 100755 index 000000000..004714d3a --- /dev/null +++ b/dvb-spec/dvbapi/getbb @@ -0,0 +1,12 @@ +#!/bin/sh +f=`grep BoundingBox $2 | cut -d' ' -f2,3,4,5` +g=`\ +echo $2" llx=";(echo $f|cut -d' ' -f1 );\ +echo " lly=";(echo $f|cut -d' ' -f2 );\ +echo " urx=";(echo $f|cut -d' ' -f3 );\ +echo " ury=";(echo $f|cut -d' ' -f4 );\ +echo " rwi=";(echo $f|cut -d' ' -f3 );\ +echo "0" +` +h=`echo $g| sed "s/= /=/g" | sed "s/ 0/0/g"` +cat $1 | sed "s/psfile=$2/psfile=$h/" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex new file mode 100644 index 000000000..1d859fadb --- /dev/null +++ b/dvb-spec/dvbapi/intro.tex @@ -0,0 +1,183 @@ +\chapter{Introduction} +%\addcontentsline{toc}{part}{Introduction} +%\chaptermark{Introduction} +\section{What you need to know} +The reader of this document is required to have some knowledge in the +area of digital video broadcasting (DVB) and should be familiar with +part I of ISO/IEC 13818, i.e you should know what a +program/transport stream (PS/TS) is and what is meant by a packetized elementary +stream (PES) or an I-frame. + +It is also necessary to know how to access unix/linux devices and how +to use ioctl calls. This also includes the knowledge of C or C++. +\section{History} + +The first API for DVB cards we used at Convergence in late 1999 +was an extension of the Video4Linux API which was primarily +developed for frame grabber cards. +As such it was not really well suited to be used for DVB cards and +their new features like recording MPEG streams and filtering several +section and PES data streams at the same time. + +In early 2000, we were approached by Nokia with a proposal for a new +standard Linux DVB API. +As a commitment to the development of terminals based on open standards, +Nokia and Convergence made it available to all Linux developers and +published it on \texttt{http://www.linuxtv.org/} in September 2000. +Convergence is the maintainer of the Linux DVB API. +Together with the LinuxTV community (i.e. you, the reader of this document), +the Linux DVB API will be constantly reviewed and improved upon. +With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence +provides a first implementation of the Linux DVB API. + + +\section{Overview} + +\begin{figure}[htbp] + \begin{center} + \includegraphics{dvbstb.ps} + \caption{Components of a DVB card/STB} + \label{fig:dvbstb} + \end{center} +\end{figure} + + +A DVB PCI card or DVB set-top-box (STB) usually consists of the following +main hardware components: +\begin{itemize} +\item Frontend consisting of tuner and DVB demodulator + +Here the raw signal reaches the DVB hardware from a satellite dish or antenna +or directly from cable. The frontend down-converts and demodulates +this signal into an MPEG transport stream (TS). + +\item SEC for controlling external hardware like LNBs and antennas + +This part of the hardware can send signals back through the satellite +cable to control the polarization of the LNB, to switch between +different LNBs or even to control the movements of a dish rotor. + + +\item Conditional Access (CA) hardware like CI adapters and smartcard slots + +The complete TS is passed through the CA hardware. Programs to which +the user has access (controlled by the smart card) are decoded in real +time and re-inserted into the TS. + +\item Demultiplexer which filters the incoming DVB stream + +The demultiplexer splits the TS into its components like audio and video +streams. Besides usually several of such audio and video streams it also +contains data streams with information about the programs offered in this +or other streams of the same provider. + +\item MPEG2 audio and video decoder + +The main targets of the demultiplexer are the MPEG2 audio and video +decoders. After decoding the pass on the uncompressed audio +and video to the computer screen or (through a PAL/NTSC encoder) to +a TV set. +\end{itemize} +Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow +between those components. + +On a DVB PCI card not all of these have to be present since some +functionality can be provided by the main CPU of the PC (e.g. MPEG picture +and sound decoding) or is not needed (e.g. for data-only uses like +``internet over satellite''). +Also not every card or STB provides conditional access hardware. + +\section{Linux DVB Devices} + +The Linux DVB API lets you control these hardware components +through currently six Unix-style character devices for +video, audio, frontend, SEC, demux and CA. +The video and audio devices control the MPEG2 decoder hardware, +the frontend device the tuner and the DVB demodulator. +External hardware like DiSEqC switches and rotors can be controlled +through the SEC device. +The demux device gives you control over the PES and section filters +of the hardware. If the hardware does not support filtering these filters +can be implemented in software. +Finally, the CA device controls all the conditional access capabilities +of the hardware. It can depend on the individual security requirements +of the platform, if and how many of the CA functions are made available +to the application through this device. + +All devices can be found in the \texttt{/dev} tree under +\texttt{/dev/ost}, where OST stands for Open Standards Terminal. +The individual devices are called +\begin{itemize} +\item \texttt{/dev/ost/audio}, +\item \texttt{/dev/ost/video}, +\item \texttt{/dev/ost/frontend}, +\item \texttt{/dev/ost/sec}, +\item \texttt{/dev/ost/demux}, +\item \texttt{/dev/ost/ca}, +\end{itemize} +but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of +these devices. + +If more than one card is present in the system the other cards +can be accessed through the corresponding devices with the +card's number appended. \texttt{/dev/ost/demux0} (which +is identical to \texttt{/dev/ost/demux}) would, e.g., control the +demultiplexer of the first card, while \texttt{/dev/ost/demux1} +would control the demultiplexer of the second card, and so on. + +More details about the data structures and function calls of +all the devices are described in the following chapters. + + +\section{DVB Devices with Devfs} + +Recent Linux kernel versions support a special file system called +\textsl{devfs} which is a replacement for the traditional +device directory. +With devfs a Linux DVB driver will only create those device file entries +which actually exist. +It also makes dealing with more complex DVB hardware much easier. +The device structure described above is not well suited to deal +with multiple DVB cards with more than one frontend or demultiplexer. +Consider, e.g., two DVB cards, one with two frontends and +one demultiplexer, the other with one frontend and two demultiplexers. +If we just assign them consecutive numbers, there would be a demultiplexer +and a frontend which do not belong to the same card but have +the same number. + +With \textsl{devfs} we propose a different scheme for the device names. +The root directory for all DVB cards will be \texttt{/dev/dvb}. +Each card gets assigned a sub-directory with the name \texttt{/dev/card0}, +\texttt{/dev/card1}, etc. +The files created in these sub-directories will correspond directly to the +hardware actually present on the card. +Thus, if the first card has one QAM frontend, one demultiplexer +and otherwise no other hardware, +only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0} +will be created. +When a second DVB-S card with one frontend (including SEC) device, +two demultiplexers and an MPEG2 audio/video decoder is added, the +complete \texttt{/dev/dvb} tree will look like this: + +\begin{verbatim} +/dev/dvb/card0/frontend0 + demux0 + +/dev/dvb/card1/video0 + audio0 + demux0 + demux1 + frontend0 + sec0 +\end{verbatim} + + +\section{Using the Devices} + +\dots + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex new file mode 100644 index 000000000..59490299b --- /dev/null +++ b/dvb-spec/dvbapi/kdapi.tex @@ -0,0 +1,1007 @@ +\devsec{Kernel Demux API} + +The kernel demux API + +\devsubsec{Kernel Demux Data Types} + +\devsubsubsec{dmx\_success\_t} +\label{dmxsuccesst} + +\begin{verbatim} +typedef enum { + DMX_OK = 0, /* Received Ok */ + DMX_LENGTH_ERROR, /* Incorrect length */ + DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ + DMX_CRC_ERROR, /* Incorrect CRC */ + DMX_FRAME_ERROR, /* Frame alignment error */ + DMX_FIFO_ERROR, /* Receiver FIFO overrun */ + DMX_MISSED_ERROR /* Receiver missed packet */ +} dmx_success_t; +\end{verbatim} + + +\devsubsubsec{TS filter types} +\label{tsfiltertypes} + +\begin{verbatim} +/*--------------------------------------------------------------------------*/ +/* TS packet reception */ +/*--------------------------------------------------------------------------*/ + +/* TS filter type for set_type() */ + +#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */ +#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS + payload (<=184 bytes per packet) to callback */ +#define TS_DECODER 4 /* send stream to built-in decoder (if present) */ +\end{verbatim} + + +\devsubsubsec{dmx\_ts\_pes\_t} +\label{dmxtspest} + +The structure +\begin{verbatim} +typedef enum +{ + DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */ + DMX_TS_PES_VIDEO, /* ... */ + DMX_TS_PES_TELETEXT, + DMX_TS_PES_SUBTITLE, + DMX_TS_PES_PCR, + DMX_TS_PES_OTHER, +} dmx_ts_pes_t; +\end{verbatim} +describes the PES type for filters which write to +a built-in decoder. +The correspond (and should be kept identical) to the types in +the demux device. + +\begin{verbatim} +struct dmx_ts_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_ts_feed_s* feed, + __u16 pid, + size_t callback_length, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_ts_feed_s* feed); + int (*stop_filtering) (struct dmx_ts_feed_s* feed); + int (*set_type) (struct dmx_ts_feed_s* feed, + int type, + dmx_ts_pes_t pes_type); +}; + +typedef struct dmx_ts_feed_s dmx_ts_feed_t; +\end{verbatim} + +\begin{verbatim} +/*--------------------------------------------------------------------------*/ +/* PES packet reception (not supported yet) */ +/*--------------------------------------------------------------------------*/ + +typedef struct dmx_pes_filter_s { + struct dmx_pes_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_pes_filter_t; +\end{verbatim} + +\begin{verbatim} +typedef struct dmx_pes_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_pes_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + struct timespec timeout); + int (*start_filtering) (struct dmx_pes_feed_s* feed); + int (*stop_filtering) (struct dmx_pes_feed_s* feed); + int (*allocate_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t** filter); + int (*release_filter) (struct dmx_pes_feed_s* feed, + dmx_pes_filter_t* filter); +} dmx_pes_feed_t; +\end{verbatim} + + +\label{sectionfilter} +\begin{verbatim} +typedef struct { + __u8 filter_value [DMX_MAX_FILTER_SIZE]; + __u8 filter_mask [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ +} dmx_section_filter_t; +\end{verbatim} + +\begin{verbatim} +struct dmx_section_feed_s { + int is_filtering; /* Set to non-zero when filtering in progress */ + struct dmx_demux_s* parent; /* Back-pointer */ + void* priv; /* Pointer to private data of the API client */ + int (*set) (struct dmx_section_feed_s* feed, + __u16 pid, + size_t circular_buffer_size, + int descramble, + int check_crc); + int (*allocate_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t** filter); + int (*release_filter) (struct dmx_section_feed_s* feed, + dmx_section_filter_t* filter); + int (*start_filtering) (struct dmx_section_feed_s* feed); + int (*stop_filtering) (struct dmx_section_feed_s* feed); +}; +typedef struct dmx_section_feed_s dmx_section_feed_t; + +/*--------------------------------------------------------------------------*/ +/* Callback functions */ +/*--------------------------------------------------------------------------*/ + +typedef int (*dmx_ts_cb) ( __u8 * buffer1, + size_t buffer1_length, + __u8 * buffer2, + size_t buffer2_length, + dmx_ts_feed_t* source, + dmx_success_t success); + +typedef int (*dmx_section_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_section_filter_t * source, + dmx_success_t success); + +typedef int (*dmx_pes_cb) ( __u8 * buffer1, + size_t buffer1_len, + __u8 * buffer2, + size_t buffer2_len, + dmx_pes_filter_t* source, + dmx_success_t success); + +/*--------------------------------------------------------------------------*/ +/* DVB Front-End */ +/*--------------------------------------------------------------------------*/ + +typedef enum { + DMX_OTHER_FE = 0, + DMX_SATELLITE_FE, + DMX_CABLE_FE, + DMX_TERRESTRIAL_FE, + DMX_LVDS_FE, + DMX_ASI_FE, /* DVB-ASI interface */ + DMX_MEMORY_FE +} dmx_frontend_source_t; + +typedef struct { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique front-end identifier */ + char* vendor; /* Name of the front-end vendor */ + char* model; /* Name of the front-end model */ + struct list_head connectivity_list; /* List of front-ends that can + be connected to a particular + demux */ + void* priv; /* Pointer to private data of the API client */ + dmx_frontend_source_t source; +} dmx_frontend_t; + +/*--------------------------------------------------------------------------*/ +/* MPEG-2 TS Demux */ +/*--------------------------------------------------------------------------*/ + +/* + * Flags OR'ed in the capabilites field of struct dmx_demux_s. + */ + +#define DMX_TS_FILTERING 1 +#define DMX_PES_FILTERING 2 +#define DMX_SECTION_FILTERING 4 +#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ +#define DMX_CRC_CHECKING 16 +#define DMX_TS_DESCRAMBLING 32 +#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64 +#define DMX_MAC_ADDRESS_DESCRAMBLING 128 +\end{verbatim} + +\devsubsubsec{demux\_demux\_t} +\label{demuxdemuxt} + +\begin{verbatim} +/* + * DMX_FE_ENTRY(): Casts elements in the list of registered + * front-ends from the generic type struct list_head + * to the type * dmx_frontend_t + *. +*/ + +#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) + +struct dmx_demux_s { + /* The following char* fields point to NULL terminated strings */ + char* id; /* Unique demux identifier */ + char* vendor; /* Name of the demux vendor */ + char* model; /* Name of the demux model */ + __u32 capabilities; /* Bitfield of capability flags */ + dmx_frontend_t* frontend; /* Front-end connected to the demux */ + struct list_head reg_list; /* List of registered demuxes */ + void* priv; /* Pointer to private data of the API client */ + int users; /* Number of users */ + int (*open) (struct dmx_demux_s* demux); + int (*close) (struct dmx_demux_s* demux); + int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); + int (*allocate_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t** feed, + dmx_ts_cb callback); + int (*release_ts_feed) (struct dmx_demux_s* demux, + dmx_ts_feed_t* feed); + int (*allocate_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t** feed, + dmx_pes_cb callback); + int (*release_pes_feed) (struct dmx_demux_s* demux, + dmx_pes_feed_t* feed); + int (*allocate_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t** feed, + dmx_section_cb callback); + int (*release_section_feed) (struct dmx_demux_s* demux, + dmx_section_feed_t* feed); + int (*descramble_mac_address) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, + size_t buffer2_length, + __u16 pid); + int (*descramble_section_payload) (struct dmx_demux_s* demux, + __u8* buffer1, + size_t buffer1_length, + __u8* buffer2, size_t buffer2_length, + __u16 pid); + int (*add_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*remove_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + struct list_head* (*get_frontends) (struct dmx_demux_s* demux); + int (*connect_frontend) (struct dmx_demux_s* demux, + dmx_frontend_t* frontend); + int (*disconnect_frontend) (struct dmx_demux_s* demux); + + + /* added because js cannot keep track of these himself */ + int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids); +}; +typedef struct dmx_demux_s dmx_demux_t; +\end{verbatim} + + +\devsubsubsec{Demux directory} +\label{demuxdir} + +\begin{verbatim} +/* + * DMX_DIR_ENTRY(): Casts elements in the list of registered + * demuxes from the generic type struct list_head* to the type dmx_demux_t + *. + */ + +#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) + +int dmx_register_demux (dmx_demux_t* demux); +int dmx_unregister_demux (dmx_demux_t* demux); +struct list_head* dmx_get_demuxes (void); +\end{verbatim} + +\clearpage + +\devsubsec{Demux Directory API} + +The demux directory is a Linux kernel-wide facility for registering and +accessing the MPEG-2 TS demuxes in the system. Run-time registering and +unregistering of demux drivers is possible using this API. + +All demux drivers in the directory implement the abstract interface dmx\_demux\_t. + +\kifunction{dmx\_register\_demux()}{ + int dmx\_register\_demux ( dmx\_demux\_t *demux ) + }{ + This function makes a demux driver interface available to the Linux kernel. + It is usually called by the init\_module() function of the kernel module that + contains the demux driver. The caller of this function is responsible for + allocating dynamic or static memory for the demux structure and for initializing + its fields before calling this function. + The memory allocated for the demux structure must not be freed before calling + dmx\_unregister\_demux(), + }{ + dmx\_demux\_t* demux & Pointer to the demux structure. + }{ + 0 & The function was completed without errors.\\ + -EEXIST & A demux with the same value of the id field + already stored in the directory.\\ + -ENOSPC & No space left in the directory. +} + +\kifunction{dmx\_unregister\_demux()}{ + int dmx\_unregister\_demux ( dmx\_demux\_t *demux ) + }{ + This function is called to indicate that the given demux interface is no longer + available. The caller of this function is responsible for freeing the memory of + the demux structure, if it was dynamically allocated before calling + dmx\_register\_demux(). + The cleanup\_module() function of the kernel module that contains the demux + driver should call this function. Note that this function fails if the demux + is currently in use, i.e., release\_demux() has not been called for the + interface. + }{ + dmx\_demux\_t* demux & Pointer to the demux structure which is to be unregistered. + }{ + 0 & The function was completed without errors.\\ + ENODEV & The specified demux is not registered in the demux directory.\\ + EBUSY & The specified demux is currently in use. +} + +\kifunction{dmx\_get\_demuxes()}{ + struct list\_head *dmx\_get\_demuxes () + }{ + Provides the caller with the list of registered demux interfaces, using the + standard list structure defined in the include file linux/list.h. + The include file demux.h defines the macro DMX\_DIR\_ENTRY() for converting an + element of the generic type struct list\_head* to the type dmx\_demux\_t*. + The caller must not free the memory of any of the elements obtained via this + function call. + }{ + none + }{ + struct list\_head * & + A list of demux interfaces, or NULL in the case of an empty list. +} + +\clearpage + +\devsubsec{Demux API} + +The demux API should be implemented for each demux in the system. It is used to +select the TS source of a demux and to manage the demux resources. When the +demux client allocates a resource via the demux API, it receives a pointer +to the API of that resource. + +Each demux receives its TS input from a DVB front-end or from memory, as +set via the demux API. In a system with more than one front-end, the API can +be used to select one of the DVB front-ends as a TS source for a demux, unless +this is fixed in the HW platform. The demux API only controls front-ends +regarding their connections with demuxes; the APIs used to set the other +front-end parameters, such as tuning, are not defined in this document. + +The functions that implement the abstract interface demux should be defined +static or module private and registered to the Demux Directory for external +access. It is not necessary to implement every function in the demux\_t struct, +however (for example, a demux interface might support Section filtering, but +not TS or PES filtering). The API client is expected to check the value of any +function pointer before calling the function: the value of NULL means ``function +not available''. + +Whenever the functions of the demux API modify shared data, the possibilities +of lost update and race condition problems should be addressed, e.g. by +protecting parts of code with mutexes. This is especially important on +multi-processor hosts. + +Note that functions called from a bottom half context must not sleep, at least +in the 2.2.x kernels. Even a simple memory allocation can result in a kernel +thread being put to sleep if swapping is needed. For example, the Linux kernel +calls the functions of a network device interface from a bottom half context. +Thus, if a demux API function is called from network device code, the function +must not sleep. + +\kfunction{open()}{ + int open ( demux\_t* demux ); + }{ + This function reserves the demux for use by the caller and, if necessary, + initializes the demux. When the demux is no longer needed, the function close() + should be called. + It should be possible for multiple clients to access the demux at the same time. + Thus, the function implementation should increment the demux usage count when + open() is called and decrement it when close() is called. + }{ + demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EUSERS & Maximum usage count reached.\\ + -EINVAL & Bad parameter. +} + +\kfunction{close()}{ + int close(demux\_t* demux); + }{ + This function reserves the demux for use by the caller and, if necessary, + initializes the demux. When the demux is no longer needed, the function close() + should be called. + It should be possible for multiple clients to access the demux at the same time. + Thus, the function implementation should increment the demux usage count when + open() is called and decrement it when close() is called. + }{ + demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -ENODEV & The demux was not in use.\\ + -EINVAL & Bad parameter. +} + +\kfunction{write()}{ + int write(demux\_t* demux, const char* buf, size\_t count); + }{ + This function provides the demux driver with a memory buffer containing TS + packets. Instead of receiving TS packets from the DVB front-end, the demux + driver software will read packets from memory. Any clients of this demux + with active TS, PES or Section filters will receive filtered data via the Demux + callback API (see 0). The function returns when all the data in the buffer has + been consumed by the demux. + Demux hardware typically cannot read TS from memory. If this is the case, + memory-based filtering has to be implemented entirely in software. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + const char* buf & Pointer to the TS data in kernel-space memory.\\ + size\_t length & Length of the TS data. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + +\kifunction{allocate\_ts\_feed()}{ + int allocate\_ts\_feed(dmx\_demux\_t* demux, + dmx\_ts\_feed\_t** feed, dmx\_ts\_cb callback); + }{ + Allocates a new TS feed, which is used to filter the TS packets carrying a + certain PID. + The TS feed normally corresponds to a hardware PID filter on the demux chip. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_ts\_feed\_t** feed & Pointer to the TS feed API and instance data.\\ + dmx\_ts\_cb callback & Pointer to the callback function for + passing received TS packet + }{ + 0 & The function was completed without errors.\\ + -EBUSY & No more TS feeds available.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + +\kifunction{release\_ts\_feed()}{ + int release\_ts\_feed(dmx\_demux\_t* demux, dmx\_ts\_feed\_t* feed); + }{ + Releases the resources allocated with allocate\_ts\_feed(). Any filtering in progress + on the TS feed should be stopped before calling this function. + }{ + demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{allocate\_section\_feed()}{ + int allocate\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t **feed, + dmx\_section\_cb callback); + }{ + Allocates a new section feed, i.e. a demux resource for filtering and + receiving sections. + On platforms with hardware support for section filtering, a section feed is directly + mapped to the demux HW. On other platforms, TS packets are first PID filtered in + hardware and a hardware section filter then emulated in software. + The caller obtains an API pointer of type dmx\_section\_feed\_t as an out parameter. + Using this API the caller can set filtering parameters and start receiving sections. + }{ + demux\_t *demux & Pointer to the demux API and instance data.\\ + dmx\_section\_feed\_t **feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_cb callback & Pointer to the callback function for + passing received sections. + }{ + 0 & The function was completed without errors.\\ + -EBUSY & No more section feeds available.\\ + -ENOSYS & The command is not implemented.\\ + -EINVAL & Bad parameter. +} + + +\kifunction{release\_section\_feed()}{ + int release\_section\_feed(dmx\_demux\_t* demux, dmx\_section\_feed\_t *feed); + }{ + Releases the resources allocated with allocate\_section\_feed(), including allocated + filters. + Any filtering in progress on the section feed should be stopped before calling + this function. + }{ + demux\_t *demux & Pointer to the demux API and instance data.\\ + dmx\_section\_feed\_t *feed & Pointer to the section feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{descramble\_mac\_address()}{ + int descramble\_mac\_address(dmx\_demux\_t* demux, + \_\_u8 *buffer1, size\_t buffer1\_length, + \_\_u8 *buffer2, size\_t buffer2\_length, \_\_u16 pid); + }{ + This function runs a descrambling algorithm on the destination MAC address field of a + DVB Datagram Section, replacing the original address with its un-encrypted version. + Otherwise, the description on the function descramble\_section\_payload() applies + also to this function. + }{ + dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ + \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ + size\_t buffer1\_length & Length of the section data, including headers and CRC, + in buffer1.\\ + \_\_u8* buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a circular buffer.\\ + size\_t buffer2\_length & Length of the section data, + including headers and CRC, in buffer2.\\ + \_\_u16 pid & The PID on which the section was received. Useful for obtaining the + descrambling key, e.g. from a DVB Common Access facility. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & No descrambling facility available.\\ + -EINVAL & Bad parameter. +} + +\kifunction{descramble\_section\_payload()}{ + int descramble\_section\_payload(dmx\_demux\_t* demux, + \_\_u8 *buffer1, size\_t buffer1\_length, \_\_u8 *buffer2, size\_t + buffer2\_length, \_\_u16 pid); + }{ + This function runs a descrambling algorithm on the payload of a DVB Datagram + Section, replacing the original payload with its un-encrypted version. + The function will + be called from the demux API implementation; the API client need + not call this function directly. + Section-level scrambling algorithms are currently standardized only for DVB-RCC + (return channel over 2-directional cable TV network) systems. For all other DVB + networks, encryption schemes are likely to be proprietary to each data broadcaster. + Thus, it is expected that this function pointer will have the value of NULL + (i.e., function not available) in most demux API implementations. + Nevertheless, it should be possible + to use the function pointer as a hook for dynamically adding a ``plug-in'' + descrambling facility to a demux driver.\\ + While this function is not needed with hardware-based section descrambling, the + descramble\_section\_payload function pointer can be used to override the default + hardware-based descrambling algorithm: if the function pointer has a non-NULL value, + the corresponding function should be used instead of any descrambling hardware. + }{ + dmx\_demux\_t *demux & Pointer to the demux API and instance data.\\ + \_\_u8 *buffer1 & Pointer to the first byte of the section.\\ + size\_t buffer1\_length & Length of the section data, including headers and CRC, in + buffer1.\\ + \_\_u8 *buffer2 & Pointer to the tail of the section data, or NULL. The pointer has a + non-NULL value if the section wraps + past the end of a circular buffer.\\ + size\_t buffer2\_length & Length of the section data, including headers and CRC, in + buffer2.\\ + \_\_u16 pid & The PID on which the section was received. Useful for obtaining the + descrambling key, e.g. from a DVB Common Access facility. + }{ + 0 & The function was completed without errors.\\ + -ENOSYS & No descrambling facility available.\\ + -EINVAL & Bad parameter. +} + +\kifunction{add\_frontend()}{ + int add\_frontend(dmx\_demux\_t *demux, dmx\_frontend\_t *frontend); + }{ + Registers a connectivity between a demux and a front-end, i.e., indicates that the + demux can be connected via a call to connect\_frontend() to use the given front-end + as a TS source. The client of this function has to allocate dynamic or static + memory for + the frontend structure and initialize its fields before calling this function. + This function is normally called during the driver initialization. + The caller must not free + the memory of the frontend struct before successfully calling remove\_frontend(). + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EEXIST & A front-end with the same value of the id field already registered.\\ + -EINUSE & The demux is in use.\\ + -ENOMEM & No more front-ends can be added.\\ + -EINVAL & Bad parameter. +} + +\kifunction{remove\_frontend()}{ + int remove\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); + }{ + Indicates that the given front-end, registered by a call to add\_frontend(), can no + longer be connected as a TS source by this demux. The function should be called + when a front-end driver or a demux driver is removed from the system. If the front-end + is in use, the function fails with the return value of -EBUSY. + After successfully calling this function, the caller can free the memory of + the frontend struct if it was dynamically allocated before the add\_frontend() + operation. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter.\\ + -EBUSY & The front-end is in use, i.e. a call to + connect\_frontend() has not been followed by + a call to disconnect\_frontend(). +} + +\kifunction{get\_frontends()}{ + struct list\_head* get\_frontends(dmx\_demux\_t* demux); + }{ + Provides the APIs of the front-ends that have been registered for this demux. Any of + the front-ends obtained with this call can be used as a parameter for + connect\_frontend().\\ + The include file demux.h contains the macro DMX\_FE\_ENTRY() for converting an + element of the generic type struct list\_head* to the type dmx\_frontend\_t*. + The caller must not free the memory of any of the elements obtained via this function + call. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data. + }{ + dmx\_demux\_t* & A list of front-end interfaces, or NULL in the case of an empty list. +} + + +\kifunction{connect\_frontend()}{ + int connect\_frontend(dmx\_demux\_t* demux, dmx\_frontend\_t* frontend); + }{ + Connects the TS output of the front-end to the input of the demux. A demux can only + be connected to a front-end registered to the demux with the function + add\_frontend().\\ + It may or may not be possible to connect multiple demuxes to the same front-end, + depending on the capabilities of the HW platform. When not used, the front-end should + be released by calling disconnect\_frontend(). + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data.\\ + dmx\_frontend\_t* frontend & Pointer to the front-end instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter.\\ + -EBUSY & The front-end is in use. +} + +\kifunction{disconnect\_frontend()}{ + int disconnect\_frontend(dmx\_demux\_t* demux); + }{ + Disconnects the demux and a front-end previously connected by a + connect\_frontend() call. + }{ + dmx\_demux\_t* demux & Pointer to the demux API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\clearpage + +\devsubsec{Demux Callback API} + +This kernel-space API comprises the callback functions that deliver filtered data to the +demux client. Unlike the other APIs, these API functions are provided by the client and +called from the demux code. + +The function pointers of this abstract interface are not packed into a structure +as in the +other demux APIs, because the callback functions are registered and used +independent of each other. As an example, it is possible for the API client to provide +several callback functions for receiving TS packets and no callbacks for PES packets +or sections. + +The functions that implement the callback API need not be re-entrant: when a demux +driver calls one of these functions, the driver is not allowed to call the +function again before the original call returns. +If a callback is triggered by a hardware interrupt, it is +recommended to use the Linux ``bottom half'' mechanism or start a tasklet instead of +making the callback function call directly from a hardware interrupt. + +\kifunction{dmx\_ts\_cb()}{ + int dmx\_ts\_cb(\_\_u8* buffer1, size\_t buffer1\_length, + \_\_u8* buffer2, size\_t buffer2\_length, + dmx\_ts\_feed\_t* source, dmx\_success\_t success); + }{ + This function, provided by the client of the demux API, is called from the + demux code. The function is only called when filtering on this TS feed has + been enabled using the start\_filtering() function. \\ + Any TS packets that match the filter settings are copied to a circular buffer. + The filtered TS packets are delivered to the client using this callback + function. The size of the circular buffer is controlled by the + circular\_buffer\_size parameter of the set() function in the TS Feed API. It is + expected that the buffer1 and buffer2 callback parameters point to addresses + within the circular buffer, but other implementations are also + possible. Note that the called party should not try to free the memory the + buffer1 and buffer2 parameters point to.\\ + When this function is called, the buffer1 parameter typically points to the + start of the first undelivered TS packet within a circular buffer. The buffer2 + buffer parameter is normally NULL, except when the received TS packets have + crossed the last address of the circular buffer and "wrapped" to the beginning + of the buffer. In the latter case the buffer1 parameter would contain an + address within the circular buffer, while the buffer2 parameter would contain + the first address of the circular buffer.\\ + The number of bytes delivered with this function (i.e. buffer1\_length + + buffer2\_length) is usually equal to the value of callback\_length parameter given + in the set() function, with one exception: if a timeout occurs before receiving + callback\_length bytes of TS data, any undelivered packets are immediately + delivered to the client by calling this function. The timeout duration is + controlled by the set() function in the TS Feed API.\\ + If a TS packet is received with errors that could not be fixed by the TS-level + forward error correction (FEC), the Transport\_error\_indicator flag of the TS + packet header should be set. The TS packet should not be discarded, as the + error can possibly be corrected by a higher layer protocol. + If the called party is slow in processing the callback, it is possible that + the circular buffer eventually fills up. If this happens, the demux driver + should discard any TS packets received while the buffer is full. The error + should be indicated to the client on the next callback by setting the success + parameter to the value of DMX\_OVERRUN\_ERROR.\\ + The type of data returned to the callback can be selected by the + new function int (*set\_type) (struct dmx\_ts\_feed\_s* feed, int type, + dmx\_ts\_pes\_t pes\_type) which is part of the dmx\_ts\_feed\_s struct + (also cf. to the include file ost/demux.h) + The type parameter decides if the raw TS packet (TS\_PACKET) or just the + payload (TS\_PACKET|TS\_PAYLOAD\_ONLY) should be returned. + If additionally the TS\_DECODER bit is set the stream will also be sent + to the hardware MPEG decoder. In this case, the second flag decides + as what kind of data the stream should be interpreted. + The possible choices are one of DMX\_TS\_PES\_AUDIO, DMX\_TS\_PES\_VIDEO, + DMX\_TS\_PES\_TELETEXT, DMX\_TS\_PES\_SUBTITLE, DMX\_TS\_PES\_PCR, or + DMX\_TS\_PES\_OTHER. + }{ + \_\_u8* buffer1 & Pointer to the start of the filtered TS packets.\\ + size\_t buffer1\_length & Length of the TS data in buffer1.\\ + \_\_u8* buffer2 & Pointer to the tail of the filtered TS packets, or NULL.\\ + size\_t buffer2\_length & Length of the TS data in buffer2.\\ + dmx\_ts\_feed\_t* source & Indicates which TS feed is the source of the callback.\\ + dmx\_success\_t success & Indicates if there was an error in TS reception. + }{ + 0 & Continue filtering.\\ + -1& Stop filtering - has the same effect as a call + to stop\_filtering() on the TS Feed API. +} + +\kifunction{dmx\_section\_cb()}{ + int dmx\_section\_cb(\_\_u8* buffer1, size\_t buffer1\_length, \_\_u8* buffer2, + size\_t buffer2\_length, dmx\_section\_filter\_t* source, + dmx\_success\_t success); + }{ + This function, provided by the client of the demux API, is called from the demux code. + The function is only called when filtering of sections has been enabled using the + function start\_filtering() of the section feed API. + When the demux driver has received a complete section that matches at least one + section filter, the client is notified via this callback function. Normally this function is + called for each received section; however, it is also possible to deliver multiple sections + with one callback, for example when the system load is high. + If an error occurs while receiving a section, this function should be called with the + corresponding error type set in the success field, whether or not there is data to + deliver. + The Section Feed implementation should maintain a circular buffer for received sections. + However, this is not necessary if the Section Feed API is implemented as a client of + the TS Feed API, because the TS Feed implementation then buffers the + received data. + The size of the circular buffer can be configured using the set() function in the + Section Feed API. If there is no room in the circular buffer when a new section is + received, the section must be discarded. If this happens, the value of the success + parameter should be DMX\_OVERRUN\_ERROR on the next callback. + }{ + \_\_u8* buffer1 & Pointer to the start of the filtered section, e.g. + within the circular buffer of the demux driver.\\ + size\_t buffer1\_length & Length of the filtered section data in buffer1, + including headers and CRC.\\ + \_\_u8* buffer2 & Pointer to the tail of the filtered section data, or + NULL. Useful to handle the wrapping of a circular + buffer.\\ + size\_t buffer2\_length & Length of the filtered section data in buffer2, + including headers and CRC.\\ + dmx\_section\_filter\_t* filter & Indicates the filter that triggered the callback.\\ + dmx\_success\_t success & Indicates if there was an error in section reception. + }{ + 0 & Continue filtering.\\ + -1& Stop filtering - has the same effect as a call + to stop\_filtering() on the Section Feed API. +} + +\clearpage + +\devsubsec{TS Feed API} + +A TS feed is typically mapped to a hardware PID filter on the demux chip. Using this +API, the client can set the filtering properties to start/stop filtering TS packets on a +particular TS feed. The API is defined as an abstract interface of the type +dmx\_ts\_feed\_t. + +The functions that implement the interface should be defined static or module +private. The client can get the handle of a TS feed API by calling the function +allocate\_ts\_feed() in the demux API. + +\kifunction{set()}{ + int set ( dmx\_ts\_feed\_t* feed, \_\_u16 pid, size\_t callback\_length, + size\_t circular\_buffer\_size, int descramble, struct timespec timeout); + }{ + This function sets the parameters of a TS feed. + Any filtering in progress on the TS feed + must be stopped before calling this function. + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data.\\ + \_\_u16 pid & PID value to filter. Only the TS packets carrying the specified PID will + be passed to the API client.\\ + size\_t callback\_length & Number of bytes to deliver with each + call to the dmx\_ts\_cb() callback + function. The value of this + parameter should be a multiple of 188.\\ + size\_t circular\_buffer\_size & Size of the circular buffer for the filtered TS packets.\\ + int descramble & If non-zero, descramble the filtered TS packets.\\ + struct timespec timeout & Maximum time to wait before + delivering received TS packets to the client. + }{ + 0 & The function was completed without errors.\\ + -ENOMEM & Not enough memory for the requested buffer size.\\ + -ENOSYS & No descrambling facility available for TS.\\ + -EINVAL & Bad parameter. +} + + +\kifunction{start\_filtering()}{ + int start\_filtering(dmx\_ts\_feed\_t* feed); + }{ + Starts filtering TS packets on this TS feed, according to its settings. + The PID value to filter can be set by the API client. + All matching TS packets are delivered asynchronously to the client, + using the callback function registered with allocate\_ts\_feed(). + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{stop\_filtering()}{ + int stop\_filtering(dmx\_ts\_feed\_t* feed); + }{ + Stops filtering TS packets on this TS feed. + }{ + dmx\_ts\_feed\_t* feed & Pointer to the TS feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\clearpage + +\devsubsec{Section Feed API} + +A section feed is a resource consisting of a PID filter and a set of section filters. +Using this API, the client can set the properties of a section feed and to +start/stop filtering. +The API is defined as an abstract interface of the type dmx\_section\_feed\_t. +The functions that implement the interface should be defined static or module +private. The client can get the handle of a section feed API by calling the function +allocate\_section\_feed() in the demux API. + +On demux platforms that provide section filtering in hardware, the Section Feed API +implementation provides a software wrapper for the demux hardware. Other platforms +may support only PID filtering in hardware, requiring that TS packets are converted to +sections in software. In the latter case the Section Feed API implementation can be a +client of the TS Feed API. + + +\kifunction{set()}{ + int set(dmx\_section\_feed\_t* feed, \_\_u16 pid, size\_t circular\_buffer\_size, + int descramble, int check\_crc); + }{ + This function sets the parameters of a section feed. Any filtering in progress on the + section feed must be stopped before calling this function. + If descrambling is enabled, the payload\_scrambling\_control and + address\_scrambling\_control fields of received DVB datagram sections should be + observed. If either one is non-zero, the section should be descrambled either in + hardware or using the functions descramble\_mac\_address() and + descramble\_section\_payload() of the demux API. Note that according to the + MPEG-2 Systems specification, only the payloads of private sections can be + scrambled while the rest of the section data must be sent in the clear. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + \_\_u16 pid & PID value to filter; only the TS packets + carrying the specified PID will be accepted.\\ + size\_t circular\_buffer\_size & Size of the circular buffer for filtered sections.\\ + int descramble & If non-zero, descramble any sections that are scrambled.\\ + int check\_crc & If non-zero, check the CRC values of filtered sections. + }{ + 0 & The function was completed without errors.\\ + -ENOMEM & Not enough memory for the requested buffer size.\\ + -ENOSYS & No descrambling facility available for sections.\\ + -EINVAL & Bad parameters. +} + +\kifunction{allocate\_filter()}{ + int allocate\_filter(dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t** filter); + }{ + This function is used to allocate a section filter on the demux. + It should only be called when no filtering is in progress on this section feed. + If a filter cannot be allocated, the function fails with -ENOSPC. + See in section \ref{sectionfilter} for the format of the section filter. \\ + The bitfields filter\_mask and filter\_value should only be modified when no + filtering is in progress on this section feed. filter\_mask controls which bits of + filter\_value are compared with the section headers/payload. On a binary value of 1 + in filter\_mask, the corresponding bits are compared. The filter only accepts sections + that are equal to filter\_value in all the tested bit positions. Any changes to the + values of filter\_mask and filter\_value are guaranteed to take effect only when + the start\_filtering() function is called next time. The parent pointer in the struct + is initialized by the API implementation to the value of the feed parameter. The priv + pointer is not used by the API implementation, and can thus be freely utilized by the + caller of this function. Any data pointed to by the priv pointer is available to the + recipient of the dmx\_section\_cb() function call.\\ + While the maximum section filter length (DMX\_MAX\_FILTER\_SIZE) + is currently set at 16 bytes, hardware filters of that size are not + available on all platforms. Therefore, section filtering will often + take place first in hardware, followed by filtering in software for the + header bytes that were not covered by a hardware filter. + The filter\_mask field can be checked to determine how many bytes of + the section filter are actually used, and if the + hardware filter will suffice. Additionally, software-only section filters + can optionally be + allocated to clients when all hardware section filters are in use. + Note that on most demux hardware it is not possible to filter on the + section\_length field + of the section header -- thus this field is ignored, even though it is included in + filter\_value and filter\_mask fields. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_filter\_t** filter & Pointer to the allocated filter. + }{ + 0 & The function was completed without errors.\\ + -ENOSPC & No filters of given type and length available.\\ + -EINVAL & Bad parameters. +} + +\kifunction{release\_filter()}{ + int release\_filter ( dmx\_section\_feed\_t* feed, dmx\_section\_filter\_t* filter); + }{ + This function releases all the resources of a previously allocated section filter. + The function should not be called while filtering is in progress on this section feed. + After calling this function, the caller should not try to dereference the + filter pointer. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + dmx\_section\_filter\_t* filter & I/O Pointer to the instance data of a section filter. + }{ + 0 & The function was completed without errors.\\ + -ENODEV & No such filter allocated.\\ + -EINVAL & Bad parameter. +} + +\kifunction{start\_filtering()}{ + int start\_filtering ( dmx\_section\_feed\_t* feed ); + }{ + Starts filtering sections on this section feed, according to its settings. + Sections are first filtered based on their PID and then matched with the + section filters allocated for this feed. + If the section matches the PID filter and at least one section filter, it is delivered + to the API client. The section is delivered asynchronously using the callback function + registered with allocate\_section\_feed(). + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data.\\ + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + +\kifunction{stop\_filtering()}{ + int stop\_filtering ( dmx\_section\_feed\_t* feed ); + }{ + Stops filtering sections on this section feed. Note that any changes to the + filtering parameters (filter\_value, filter\_mask, etc.) should only be made + when filtering is stopped. + }{ + dmx\_section\_feed\_t* feed & Pointer to the section feed API and instance data. + }{ + 0 & The function was completed without errors.\\ + -EINVAL & Bad parameter. +} + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex new file mode 100644 index 000000000..88342c3a6 --- /dev/null +++ b/dvb-spec/dvbapi/sec.tex @@ -0,0 +1,282 @@ +\devsec{DVB SEC API} + +The DVB SEC device controls the Satellite Equipment Control of +the DVB hardware, i.e. DiSEqC and V-SEC. +It is accessed through \texttt{/dev/ost/sec}. + +\devsubsec{SEC Data Types} + +\devsubsubsec{secDiseqcCmd} +\label{secdiseqccmd} + +\begin{verbatim} +struct secDiseqcCmd { + uint8_t addr; + uint8_t cmd; + uint8_t numParams; + uint8_t params[SEC_MAX_DISEQC_PARAMS]; +}; +\end{verbatim} + + +\devsubsubsec{secVoltage} +\label{secvoltage} + +\begin{verbatim} +typedef uint32_t secVoltage; +\end{verbatim} +\begin{verbatim} +enum { + SEC_VOLTAGE_OFF, + SEC_VOLTAGE_LT, + SEC_VOLTAGE_13, + SEC_VOLTAGE_13_5, + SEC_VOLTAGE_18, + SEC_VOLTAGE_18_5 +}; +\end{verbatim} + + +\devsubsubsec{secToneMode} +\label{sectonemode} + +\begin{verbatim} +typedef uint32_t secToneMode; +\end{verbatim} +\begin{verbatim} +typedef enum { + SEC_TONE_ON, + SEC_TONE_OFF +} secToneMode_t; +\end{verbatim} + + +\devsubsubsec{secMiniCmd} +\label{secminicmd} + +\begin{verbatim} +typedef uint32_t secMiniCmd; +\end{verbatim} +\begin{verbatim} +typedef enum { + SEC_MINI_NONE, + SEC_MINI_A, + SEC_MINI_B +} secMiniCmd_t; +\end{verbatim} +\begin{verbatim} +struct secStatus { + int32_t busMode; + secVoltage selVolt; + secToneMode contTone; +}; +\end{verbatim} + +\begin{verbatim} +enum { + SEC_BUS_IDLE, + SEC_BUS_BUSY, + SEC_BUS_OFF, + SEC_BUS_OVERLOAD +}; +\end{verbatim} + + +\devsubsubsec{secCommand} +\label{seccommand} + +\begin{verbatim} +struct secCommand { + int32_t type; + union { + struct secDiseqcCmd diseqc; + uint8_t vsec; + uint32_t pause; + } u; +}; +\end{verbatim} + + +\devsubsubsec{secCmdSequence} +\label{seccmdsequence} + +\begin{verbatim} +struct secCmdSequence { + secVoltage voltage; + secMiniCmd miniCommand; + secToneMode continuousTone; + + uint32_t numCommands; + struct secCommand* commands; +}; +\end{verbatim} + +\begin{verbatim} +enum { + SEC_CMDTYPE_DISEQC, + SEC_CMDTYPE_VSEC, + SEC_CMDTYPE_PAUSE +}; +\end{verbatim} + +\begin{verbatim} +typedef enum { + SEC_DISEQC_SENT, + SEC_VSEC_SENT, + SEC_PAUSE_COMPLETE, + SEC_CALLBACK_ERROR +} secCallback_t; +\end{verbatim} + +\clearpage + +\devsubsec{SEC Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named SEC device for subsequent use. + If the device is opened in read-only mode, only status and statistics + monitoring is allowed. If the device is opened in read/write mode, all + types of operations can be performed. + Any number of applications can have simultaneous access to the device. + }{ + const char *deviceName & Name of specific SEC device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set, + open() and most other subsequent calls to the device will return -1 and + set errno to EWOULDBLOCK. + The communication with the peripheral devices is sequential by nature, + so it is probably preferable to use the device in synchronous mode. + This is the motivation for not going through the extra effort of + implementing asynchronous operation of the device. + }{ + ENODEV & Device driver not loaded/available.\\ + EFAULT & deviceName does not refer to a valid memory area.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened SEC device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\ifunction{SEC\_GET\_STATUS}{ + int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{ + This call gets the status of the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_GET\_STATUS for this command.\\ + struct secStatus* status & The status of the device.\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EFAULT & status is an invalid pointer.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ + EPERM & File not opened with read permissions.\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{SEC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{ + If the bus has been automatically powered off due to power overload, this + ioctl call restores the power to the bus. The call requires read/write + access to the device. + This call has no effect if the device is manually powered off. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_RESET\_OVERLOAD for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{SEC\_SEND\_SEQUENCE}{ +int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); +}{ +This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC +commands. The first version of the SEC device does not support V-SEC +signaling and it aborts the operation with an error code if a V-SEC +command is detected in the input data.\\ +\begin{itemize} +\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is +overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be +called and the operation can be retried. +\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE, +the bus voltage will be switched and the continuous 22kHz tone +generation enabled/disabled immediately. +\end{itemize}\\ +This operation is atomic. If several processes calls this ioctl +simultaneously, the operations will be serialized so a complete sequence +is sent at a time. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals SEC\_SEND\_SEQUENCE for this command.\\ + struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ + EBUSMODE & The device is not prepared for transmission + (e.g. it might be manually powered off).\\ + EBUSOVERLOAD & Bus overload has occurred.\\ +} + + +\ifunction{SEC\_SET\_TONE}{ +int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone); +}{ +This call is used to set the generation of the continuous 22kHz tone. +The possibility to just change the tone mode is already provided by +ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface. +To keep the transmission of a command sequence as +an atomic operation, SEC\_SET\_TONE will block if a transmission is in +progress. This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals SEC\_SET\_TONE for this command.\\ +secToneMode tone & The requested tone generation mode (on/off).\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{SEC\_SET\_VOLTAGE}{ +int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage); +}{ +This call is used to set the bus voltage. The possibility to just change +the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but +SEC\_SET\_VOLTAGE is an easier to use interface. +To keep the transmission of a command sequence as +an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in +progress. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals SEC\_SET\_VOLTAGE for this command.\\ +secVoltage voltage & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex new file mode 100644 index 000000000..574464d23 --- /dev/null +++ b/dvb-spec/dvbapi/title.tex @@ -0,0 +1,24 @@ +\pagenumbering{arabic} +\pagestyle{empty} +\title{\huge\textbf{LINUX DVB API}} + +\author{ +\includegraphics{cimlogo.psi}\\ + Convergence integrated media GmbH\\\\ + Dr. Ralph J.K. Metzler\\ + \texttt{}\\\\ + Dr. Marcus O.C. Metzler\\ + \texttt{} +% Rosenthalerstr. 51\\ +% 10178 Berlin\\Germany +} +\date{02/14/2002\\V 0.9.4} +\maketitle + +\newpage + +%\end{titlepage} +% Local Variables: +% mode: latex +% TeX-master: "dvbapi" +% End: diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex new file mode 100644 index 000000000..ee61ad78b --- /dev/null +++ b/dvb-spec/dvbapi/video.tex @@ -0,0 +1,686 @@ +\devsec{DVB Video Device} + +The DVB video device controls the MPEG2 video decoder of the DVB hardware. +It can be accessed through \texttt{/dev/ost/video}. +The include file \texttt{ost/video.h} defines the data types and lists +all I/O calls. Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device as well as the video4linux device. + +\devsubsec{Video Data Types} + +\devsubsubsec{video_format\_t} +\label{videoformat} + +The \texttt{video_format\_t} data type defined by +\begin{verbatim} +typedef enum { + VIDEO_FORMAT_4_3, + VIDEO_FORMAT_16_9 +} video_format_t; +\end{verbatim} +is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to +tell the driver which aspect ratio the output hardware (e.g. TV) has. +It is also used in the data structures video_status (\ref{videostatus}) +returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and +video_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) +which report about the display format of the current video stream. + +\devsubsubsec{videoDisplayFormat\_t} +\label{videodispformat} + +In case the display format of the video stream and of the +display hardware differ the application has to specify how to handle +the cropping of the picture. +This can be done using the VIDEO\_SET\_DISPLAY\_FORMAT call +(\ref{videosetdisplayformat}) which accepts +\begin{verbatim} +typedef enum { + VIDEO_PAN_SCAN, + VIDEO_LETTER_BOX, + VIDEO_CENTER_CUT_OUT +} video_displayformat_t; +\end{verbatim} +as argument. + + +\devsubsubsec{video stream source} +\label{videostreamsource} +The video stream source is set through the VIDEO\_SELECT\_SOURCE +call and can take the following values, depending on whether we are +replaying from an internal (demuxer) or external (user write) source. +\begin{verbatim} +typedef enum { + VIDEO_SOURCE_DEMUX, + VIDEO_SOURCE_MEMORY +} video_stream_source_t; +\end{verbatim} +VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed +either by the frontend or the DVR device) as the source of +the video stream. +If VIDEO\_SOURCE\_MEMORY is selected the stream +comes from the application through the \texttt{write()} +system call. + +\devsubsubsec{video play state} +\label{videoplaystate} +The following values can be returned by the VIDEO\_GET\_STATUS call +representing the state of video playback. +\begin{verbatim} +typedef enum { + VIDEO_STOPPED, + VIDEO_PLAYING, + VIDEO_FREEZED +} video_play_state_t; +\end{verbatim} + + +\devsubsubsec{video event} +\label{videoevent} +The following is the structure of a video event as it is returned by +the VIDEO\_GET\_EVENT call. +\begin{verbatim} +struct video_event { + int32_t type; + time_t timestamp; + union { + video_format_t video_format; + } u; +}; +\end{verbatim} + +\devsubsubsec{video status} +\label{videostatus} +The VIDEO\_GET\_STATUS call returns the following structure informing +about various states of the playback operation. +\begin{verbatim} +struct video_status { + boolean video_blank; + video_play_state_t play_state; + video_stream_source_t stream_source; + video_format_t video_format; + video_displayformat_t display_format; +}; +\end{verbatim} +If video_blank is set video will be blanked out if the channel is changed or +if playback is stopped. Otherwise, the last picture will be displayed. +play_state indicates if the video is currently frozen, stopped, or +being played back. The stream_source corresponds to the seleted source +for the video stream. It can come either from the demultiplexer or from memory. +The video_format indicates the aspect ratio (one of 4:3 or 16:9) +of the currently played video stream. +Finally, display_format corresponds to the selected cropping mode in case the +source video format is not the same as the format of the output device. + + +\devsubsubsec{video display still picture} +\label{videostill} +An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on +within the following structure. +\begin{verbatim} +/* pointer to and size of a single iframe in memory */ +struct video_still_picture { + char *iFrame; + int32_t size; +}; +\end{verbatim} + +\devsubsubsec{video capabilities} +\label{videocaps} +A call to VIDEO\_GET\_CAPABILITIES returns an unsigned integer with +the following bits set according to the hardwares capabilities. +\begin{verbatim} +/* bit definitions for capabilities: */ +/* can the hardware decode MPEG1 and/or MPEG2? */ +#define VIDEO_CAP_MPEG1 1 +#define VIDEO_CAP_MPEG2 2 +/* can you send a system and/or program stream to video device? + (you still have to open the video and the audio device but only + send the stream to the video device) */ +#define VIDEO_CAP_SYS 4 +#define VIDEO_CAP_PROG 8 +/* can the driver also handle SPU, NAVI and CSS encoded data? + (CSS API is not present yet) */ +#define VIDEO_CAP_SPU 16 +#define VIDEO_CAP_NAVI 32 +#define VIDEO_CAP_CSS 64 +\end{verbatim} + + +\devsubsubsec{video system} +\label{videosys} +A call to VIDEO\_SET\_SYSTEM sets the desired video system for TV +output. The following system types can be set: + +\begin{verbatim} +typedef enum { + VIDEO_SYSTEM_PAL, + VIDEO_SYSTEM_NTSC, + VIDEO_SYSTEM_PALN, + VIDEO_SYSTEM_PALNc, + VIDEO_SYSTEM_PALM, + VIDEO_SYSTEM_NTSC60, + VIDEO_SYSTEM_PAL60, + VIDEO_SYSTEM_PALM60 +} video_system_t; +\end{verbatim} + + + +\devsubsubsec{video highlights} +\label{vhilite} +Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight +information. The call expects the following format for that information: + +\begin{verbatim} +typedef +struct video_highlight { + boolean active; /* 1=show highlight, 0=hide highlight */ + uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ + /* 3- 0 Background pixel contrast */ + uint8_t contrast2; /* 7- 4 Emphasis pixel-2 contrast */ + /* 3- 0 Emphasis pixel-1 contrast */ + uint8_t color1; /* 7- 4 Pattern pixel color */ + /* 3- 0 Background pixel color */ + uint8_t color2; /* 7- 4 Emphasis pixel-2 color */ + /* 3- 0 Emphasis pixel-1 color */ + uint32_t ypos; /* 23-22 auto action mode */ + /* 21-12 start y */ + /* 9- 0 end y */ + uint32_t xpos; /* 23-22 button color number */ + /* 21-12 start x */ + /* 9- 0 end x */ +} video_highlight_t; +\end{verbatim} + + +\devsubsubsec{video SPU} +\label{videospu} +Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, +according to the following format: +\begin{verbatim} +typedef +struct video_spu { + boolean active; + int stream_id; +} video_spu_t; +\end{verbatim} + + +\devsubsubsec{video SPU palette} +\label{vspupal} +The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: +\begin{verbatim} +typedef +struct video_spu_palette{ /* SPU Palette information */ + int length; + uint8_t *palette; +} video_spu_palette_t; +\end{verbatim} + +\devsubsubsec{video NAVI pack} +\label{videonavi} +In order to get the navigational data the following structure has to +be passed to the ioctl VIDEO\_GET\_NAVI: +\begin{verbatim} +typedef +struct video_navi_pack{ + int length; /* 0 ... 1024 */ + uint8_t data[1024]; +} video_navi_pack_t; +\end{verbatim} + + +\devsubsubsec{video attributes} +\label{vattrib} +The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: +\begin{verbatim} +typedef uint16_t video_attributes_t; +/* bits: descr. */ +/* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ +/* 13-12 TV system (0=525/60, 1=625/50) */ +/* 11-10 Aspect ratio (0=4:3, 3=16:9) */ +/* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ +/* 7 line 21-1 data present in GOP (1=yes, 0=no) */ +/* 6 line 21-2 data present in GOP (1=yes, 0=no) */ +/* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ +/* 2 source letterboxed (1=yes, 0=no) */ +/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ +\end{verbatim} + + +\clearpage + +\devsubsec{Video Function Calls} + +\function{open()}{ + int open(const char *deviceName, int flags);}{ + This system call opens a named video device (e.g. /dev/ost/video) + for subsequent use. + + When an open() call has succeeded, the device will be ready for use. + The significance of blocking or non-blocking mode is described in + the documentation for functions where there is a difference. + It does not affect the semantics of the open() call itself. + A device opened in blocking mode can later be put into non-blocking mode + (and vice versa) using the F\_SETFL command of the fcntl system + call. + This is a standard system call, documented in the Linux manual + page for fcntl. + Only one user can open the Video Device in O\_RDWR mode. All other attempts to + open the device in this mode will fail, and an error-code will be returned. + If the Video Device is opened in O\_RDONLY mode, the only ioctl call that can + be used is VIDEO\_GET\_STATUS. All other call will return an error code. + }{ + const char *deviceName & Name of specific video device.\\ + int flags & A bit-wise OR of the following flags:\\ + & \hspace{1em} O\_RDONLY read-only access\\ + & \hspace{1em} O\_RDWR read/write access\\ + & \hspace{1em} O\_NONBLOCK open in non-blocking mode \\ + & \hspace{1em} (blocking mode is the default)\\ + }{ + ENODEV & Device driver not loaded/available.\\ + EINTERNAL & Internal error.\\ + EBUSY & Device or resource busy.\\ + EINVAL & Invalid argument.\\ +} + +\function{close()}{ + int close(int fd);}{ + This system call closes a previously opened video device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + }{ + EBADF & fd is not a valid open file descriptor.\\ +} + +\function{write()}{ + size\_t write(int fd, const void *buf, size\_t count);}{ + This system call can only be used if VIDEO\_SOURCE\_MEMORY is selected in the + ioctl call VIDEO\_SELECT\_SOURCE. The data provided shall be in PES + format, unless the capability allows other formats. + If O\_NONBLOCK is not specified the function will block until buffer space is + available. The amount of data to be transferred is implied by count. + }{ + int fd & File descriptor returned by a previous call to open().\\ + void *buf & Pointer to the buffer containing the PES data.\\ + size\_t count& Size of buf.\\ + }{ + EPERM& Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + ENOMEM& Attempted to write more data than the internal buffer can hold.\\ + EBADF& fd is not a valid open file descriptor.\\ +} + + +\ifunction{VIDEO\_STOP}{ + int ioctl(fd, int request = VIDEO\_STOP, boolean mode);}{ + This ioctl call asks the Video Device to stop playing the current stream. + Depending on the input parameter, the screen can be blanked out or + displaying the last decoded frame. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_STOP for this command. \\ +Boolean mode & Indicates how the screen shall be handled. \\ +& TRUE: Blank screen when stop. \\ +& FALSE: Show last decoded frame.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + +\ifunction{VIDEO\_PLAY}{ + int ioctl(fd, int request = VIDEO\_PLAY);}{ + This ioctl call asks the Video Device to start playing a video stream + from the selected source. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_PLAY for this command. \\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + + +\ifunction{VIDEO\_FREEZE}{ + int ioctl(fd, int request = VIDEO\_FREEZE);}{ + This ioctl call suspends the live video stream being played. + Decoding and playing are frozen. It is then possible to restart + the decoding and playing process of the video stream using the + VIDEO\_CONTINUE command. If VIDEO\_SOURCE\_MEMORY is selected in the + ioctl call VIDEO\_SELECT\_SOURCE, the DVB subsystem will not decode + any more data until the ioctl call VIDEO\_CONTINUE or VIDEO\_PLAY is + performed. +}{ +int fd & File descriptor returned by a previous call to open(). \\ +int request & Equals VIDEO\_FREEZE for this command. \\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ +} + +\ifunction{VIDEO\_CONTINUE}{ + int ioctl(fd, int request = VIDEO\_CONTINUE);}{ + This ioctl call restarts decoding and playing processes of the video + stream which was played before a call to VIDEO\_FREEZE was made. + }{ + int fd & File descriptor returned by a previous call to open(). \\ + int request & Equals VIDEO\_CONTINUE for this command. \\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error, possibly in the communication with + the DVB subsystem.\\ + } + + +\ifunction{VIDEO\_SELECT\_SOURCE}{ + int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ + This ioctl call informs the video device which source shall be used + for the input data. The possible sources are demux or memory. If + memory is selected, the data is fed to the video device through + the write command. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\ + videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +} + +\ifunction{VIDEO\_SET\_BLANK}{ + int ioctl(fd, int request = VIDEO\_SET\_BLANK, boolean mode);}{ + This ioctl call asks the Video Device to blank out the picture. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request& Equals VIDEO\_SET\_BLANK for this command. \\ +boolean mode&TRUE: Blank screen when stop.\\ + &FALSE: Show last decoded frame.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +EINVAL & Illegal input parameter\\ +} + +\ifunction{VIDEO\_GET\_STATUS}{ +\label{videogetstatus} + int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video_status *status);}{ + This ioctl call asks the Video Device to return the current status of the device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_GET\_STATUS for this command.\\ + struct video_status *status & Returns the current status of the Video Device.\\ +}{ +EBADF& fd is not a valid open file descriptor \\ +EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ +EFAULT & status points to invalid address\\ +} + +\ifunction{VIDEO\_GET\_EVENT}{ +\label{videogetevent} + int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video_event *ev);}{ + This ioctl call returns an event of type video_event if available. + If an event is not available, the behavior depends on whether the device is in + blocking or non-blocking mode. In the latter case, the call fails immediately + with errno set to EWOULDBLOCK. In the former case, the call blocks until an + event becomes available. + The standard Linux poll() and/or select() system calls can be used with the + device file descriptor to watch for new events. For select(), the file + descriptor should be included in the exceptfds argument, and for poll(), + POLLPRI should be specified as the wake-up condition. + Read-only permissions are sufficient for this ioctl call. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request& Equals VIDEO\_GET\_EVENT for this command.\\ + struct video_event *ev & Points to the location where the event, if any, is + to be stored.\\ +}{ +EBADF & fd is not a valid open file descriptor \\ +EFAULT & ev points to invalid address \\ +EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ +EBUFFEROVERFLOW & \\ +&Overflow in event queue - one or more events were lost.\\ +} + +\ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ +\label{videosetdisplayformat} + int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ + This ioctl call asks the Video Device to select the video format to be applied + by the MPEG chip on the video. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\ + videoDisplayFormat\_t format & Selects the video format to be used.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_STILLPICTURE}{ + int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video_still_picture *sp);}{ + This ioctl call asks the Video Device to display a still picture (I-frame). + The input data shall contain an I-frame. If the pointer is NULL, then the + current displayed still picture is blanked. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_STILLPICTURE for this command.\\ + struct video_still_picture *sp& + Pointer to a location where an I-frame and size is stored.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EFAULT & sp points to an invalid iframe.\\ +} + +\ifunction{VIDEO\_FAST\_FORWARD}{ + int ioctl(fd, int request = VIDEO\_FAST\_FORWARD, int nFrames);}{ + This ioctl call asks the Video Device to skip decoding of N number of I-frames. + This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_FAST\_FORWARD for this command.\\ + int nFrames & The number of frames to skip.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_SLOWMOTION}{ + int ioctl(fd, int request = VIDEO\_SLOWMOTION, int nFrames);}{ + This ioctl call asks the video device to repeat decoding frames N + number of times. + This call can only be used if VIDEO\_SOURCE\_MEMORY is selected. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SLOWMOTION for this command.\\ + int nFrames & The number of times to repeat each frame.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINTERNAL & Internal error.\\ + EPERM & Mode VIDEO\_SOURCE\_MEMORY not selected.\\ + EINVAL & Illegal parameter format.\\ +} + +\ifunction{VIDEO\_GET\_CAPABILITIES}{ + int ioctl(fd, int request = VIDEO\_GET\_CAPABILITIES, unsigned int *cap);}{ + This ioctl call asks the video device about its decoding capabilities. + On success it returns and integer which has bits set according to the + defines in section \ref{videocaps}. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_GET\_CAPABILITIES for this command.\\ + unsigned int *cap & Pointer to a location where to store the + capability information.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EFAULT & cap points to an invalid iframe.\\ +} + +\ifunction{VIDEO\_SET\_ID}{ + int ioctl(int fd, int request = VIDEO\_SET\_ID, int id);}{ + This ioctl selects which sub-stream is to be decoded if a program or + system stream is sent to the video device. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_ID for this command.\\ + int id& video sub-stream id + }{ + EBADF& fd is not a valid open file descriptor.\\ + EINTERNAL & Internal error.\\ + EINVAL & Invalid sub-stream id. +} + +\ifunction{VIDEO\_CLEAR\_BUFFER}{ + int ioctl(fd, int request = VIDEO\_CLEAR\_BUFFER);}{ + This ioctl call clears all video buffers in the driver and + in the decoder hardware. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_CLEAR\_BUFFER for this command.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ +} + +\ifunction{VIDEO\_SET\_STREAMTYPE}{ + int ioctl(fd, int request = VIDEO\_SET\_STREAMTYPE, int type);}{ + This ioctl tells the driver which kind of stream to expect + being written to it. If this call is not used the default of video PES + is used. Some drivers might not support this call and always expect PES. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_STREAMTYPE for this command.\\ + int type & stream type\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& type is not a valid or supported stream type.\\ +} + +\ifunction{VIDEO\_SET\_FORMAT}{ +\label{videosetformat} + int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video_format\_t format); +}{ + This ioctl sets the screen format (aspect ratio) of the connected + output device (TV) so that the output of the decoder can + be adjusted accordingly. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_FORMAT for this command.\\ + video_format\_t format& video format of TV as defined in section \ref{videoformat}.\\ + }{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& format is not a valid video format.\\ +} + +\ifunction{VIDEO\_SET\_SYSTEM}{ +\label{videosetsystem} + int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); +}{ + This ioctl sets the television output format. The format (see section + \ref{videosys}) may vary from the color format of the displayed MPEG + stream. If the hardware is not able to display the requested format + the call will return an error. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_FORMAT for this command.\\ + videoSystem\_t system& video system of TV output.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& system is not a valid or supported video system.\\ +} + +\ifunction{VIDEO\_SET\_HIGHLIGHT}{ +\label{videosethighlight} + int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video_highlight\_t *vhilite) +}{ + This ioctl sets the SPU highlight information for the menu access of + a DVD. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\ + video_highlight\_t *vhilite& SPU Highlight information according to + section \ref{vhilite}.\\ +}{ + EBADF& fd is not a valid open file descriptor. \\ + EINVAL& input is not a valid highlight setting.\\ +} + + +\ifunction{VIDEO\_SET\_SPU}{ +\label{videosetspu} + int ioctl(fd, int request = VIDEO\_SET\_SPU , video_spu\_t *spu) +}{ + This ioctl activates or deactivates SPU decoding in a DVD input + stream. It can only be used, if the driver is able to handle a DVD + stream. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_SPU for this command.\\ + video_spu\_t *spu& SPU decoding (de)activation and subid setting + according to section \ref{videospu}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid spu setting or driver cannot handle SPU.\\ +} + + +\ifunction{VIDEO\_SET\_SPU\_PALETTE}{ +\label{videosetspupalette} + int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video_spu_palette\_t *palette ) +}{ + This ioctl sets the SPU color palette. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\ + video_spu_palette\_t *palette& SPU palette according to section \ref{vspupal}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid palette or driver doesn't handle SPU.\\ +} + + + +\ifunction{VIDEO\_GET\_NAVI}{ +\label{videosetnavi} + int ioctl(fd, int request = VIDEO\_GET\_NAVI , video_navi_pack\_t *navipack) +}{ + This ioctl returns navigational information from the DVD stream. This is + especially needed if an encoded stream has to be decoded by the hardware. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_GET\_NAVI for this command.\\ + video_navi_pack\_t *navipack& PCI or DSI pack (private stream 2) + according to section \ref{videonavi}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EFAULT& driver is not able to return navigational information\\ +} + + +\ifunction{VIDEO\_SET\_ATTRIBUTES}{ +\label{videosetattributes} + int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t + vattr) +}{ + This ioctl is intended for DVD playback and allows you to set + certain information about the stream. Some hardware may not need + this information, but the call also tells the hardware to prepare + for DVD playback. +}{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\ + videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\ +}{ + EBADF& fd is not a valid open file descriptor \\ + EINVAL& input is not a valid attribute setting.\\ +} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/valgrind-1.0pre3-dvb.patch b/dvb-spec/valgrind-1.0pre3-dvb.patch new file mode 100644 index 000000000..6c61ceb91 --- /dev/null +++ b/dvb-spec/valgrind-1.0pre3-dvb.patch @@ -0,0 +1,154 @@ +diff -ur valgrind-1.0pre3.orig/vg_syscall_mem.c valgrind-1.0pre3/vg_syscall_mem.c +--- valgrind-1.0pre3.orig/vg_syscall_mem.c Thu Jun 20 09:23:49 2002 ++++ valgrind-1.0pre3/vg_syscall_mem.c Mon Jul 8 19:55:45 2002 +@@ -2038,6 +2038,136 @@ + sizeof(struct cdrom_msf)); + KERNEL_DO_SYSCALL(tid,res); + break; ++ ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case FE_GET_INFO: ++ must_be_writable(tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ must_be_readable(tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ must_be_writable(tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ must_be_writable(tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ must_be_writable(tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ must_be_writable(tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ must_be_writable(tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ must_be_writable(tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ must_be_readable(tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ must_be_writable(tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ must_be_writable(tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ must_be_writable(tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ must_be_writable(tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(dvb_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, 5*sizeof(dvb_pid_t)); ++ break; ++ case DMX_GET_CAPS: ++ must_be_writable(tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_SET_SOURCE: ++ must_be_readable(tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +diff -ur valgrind-1.0pre3.orig/vg_unsafe.h valgrind-1.0pre3/vg_unsafe.h +--- valgrind-1.0pre3.orig/vg_unsafe.h Thu Jun 13 18:02:37 2002 ++++ valgrind-1.0pre3/vg_unsafe.h Mon Jul 8 19:56:20 2002 +@@ -85,6 +85,10 @@ + + #include + ++#include ++#include ++#include ++#include + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ -- cgit v1.2.3 From a801585585baeadfc1a94c685ebd83304640ff54 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 10 Oct 2002 16:46:21 -0300 Subject: more CodingStyle racism --- dvb-spec/dvbapi/demux.tex | 12 ++++++------ dvb-spec/dvbapi/examples.tex | 12 ++++++------ dvb-spec/dvbapi/frontend.tex | 4 ++-- dvb-spec/dvbapi/video.tex | 2 +- dvb-spec/valgrind-1.0pre3-dvb.patch | 4 ++-- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index 3607bbffc..5a8cc1e9a 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -6,7 +6,7 @@ It can be accessed through \texttt{/dev/ost/demux}. \devsubsec{Demux Data Types} \begin{verbatim} -typedef uint16_t dvb_pid_t; +typedef uint16_t uint16_t; \end{verbatim} @@ -96,7 +96,7 @@ typedef struct dmx_filter \begin{verbatim} struct dmx_sct_filter_params { - dvb_pid_t pid; + uint16_t pid; dmx_filter_t filter; uint32_t timeout; uint32_t flags; @@ -113,10 +113,10 @@ struct dmx_sct_filter_params \begin{verbatim} struct dmx_pes_filter_params { - dvb_pid_t pid; + uint16_t pid; dmx_input_t input; dmx_output_t output; - dmx_pes_type_t pesType; + dmx_pes_type_t pes_type; uint32_t flags; }; \end{verbatim} @@ -200,7 +200,7 @@ struct dmx_event sized sections) by default. The size of this buffer may be changed by using the DMX\_SET\_BUFFER\_SIZE function. If the buffer is not large enough, or if the read operations are not performed fast enough, this may result - in a buffer overflow error. In this case EBUFFEROVERFLOW will be returned, + in a buffer overflow error. In this case EOVERFLOW will be returned, and the circular buffer will be emptied. This call is blocking if there is no data to return, i.e. the process will be put to sleep waiting for data, unless the O\_NONBLOCK flag is @@ -222,7 +222,7 @@ struct dmx_event EBADF & fd is not a valid open file descriptor.\\ ECRC & Last section had a CRC error - no data returned. The buffer is flushed.\\ - EBUFFEROVERFLOW & \\ + EOVERFLOW & \\ & The filtered data was not read from the buffer in due time, resulting in non-read data being lost. The buffer is flushed.\\ diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index ea2797481..fa5c24b48 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -157,7 +157,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, printf("Getting QPSK event\n"); if ( ioctl(front, FE_GET_EVENT, &event) - == -EBUFFEROVERFLOW){ + == -EOVERFLOW){ perror("qpsk get event"); return -1; } @@ -180,7 +180,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_vpid"); @@ -190,7 +190,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_apid"); @@ -200,7 +200,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, pesFilterParams.pid = tpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_DECODER; - pesFilterParams.pesType = DMX_PES_TELETEXT; + pesFilterParams.pes_type = DMX_PES_TELETEXT; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("set_tpid"); @@ -273,7 +273,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = vpid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_VIDEO; + pesFilterParams.pes_type = DMX_PES_VIDEO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); @@ -282,7 +282,7 @@ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) pesFilterParams.pid = apid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pesType = DMX_PES_AUDIO; + pesFilterParams.pes_type = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ perror("DEMUX DEVICE"); diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index cb3285d06..e41ef3d54 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -591,7 +591,7 @@ by the driver so far. POLLPRI should be specified as the wake-up condition. Since the event queue allocated is rather small (room for 8 events), the queue must be serviced regularly to avoid overflow. If an overflow happens, the - oldest event is discarded from the queue, and an error (EBUFFEROVERFLOW) occurs + oldest event is discarded from the queue, and an error (EOVERFLOW) occurs the next time the queue is read. After reporting the error condition in this fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as usual.\\ @@ -606,7 +606,7 @@ by the driver so far. EFAULT& ev points to invalid address.\\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ - EBUFFEROVERFLOW &\\ + EOVERFLOW &\\ & Overflow in event queue - one or more events were lost.\\ } diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index ee61ad78b..d33f03c83 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -440,7 +440,7 @@ EFAULT & status points to invalid address\\ EBADF & fd is not a valid open file descriptor \\ EFAULT & ev points to invalid address \\ EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ -EBUFFEROVERFLOW & \\ +EOVERFLOW & \\ &Overflow in event queue - one or more events were lost.\\ } diff --git a/dvb-spec/valgrind-1.0pre3-dvb.patch b/dvb-spec/valgrind-1.0pre3-dvb.patch index 6c61ceb91..173aaecc5 100644 --- a/dvb-spec/valgrind-1.0pre3-dvb.patch +++ b/dvb-spec/valgrind-1.0pre3-dvb.patch @@ -117,10 +117,10 @@ diff -ur valgrind-1.0pre3.orig/vg_syscall_mem.c valgrind-1.0pre3/vg_syscall_mem. + break; + case DMX_GET_PES_PIDS: + must_be_writable(tst, "ioctl(DMX_GET_PES_PIDS)", arg3, -+ 5*sizeof(dvb_pid_t)); ++ 5*sizeof(uint16_t)); + KERNEL_DO_SYSCALL(tid,res); + if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, 5*sizeof(dvb_pid_t)); ++ make_readable (arg3, 5*sizeof(uint16_t)); + break; + case DMX_GET_CAPS: + must_be_writable(tst, "ioctl(DMX_GET_CAPS)", arg3, -- cgit v1.2.3 From 913350c2997c22fa120029c010859c8bcf12fe12 Mon Sep 17 00:00:00 2001 From: holger Date: Tue, 29 Oct 2002 06:20:39 -0300 Subject: refer to API version 3 not 2 --- dvb-spec/HOWTO-use-the-frontend-api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvb-spec/HOWTO-use-the-frontend-api b/dvb-spec/HOWTO-use-the-frontend-api index 52bc2836e..538f5d05e 100644 --- a/dvb-spec/HOWTO-use-the-frontend-api +++ b/dvb-spec/HOWTO-use-the-frontend-api @@ -41,7 +41,7 @@ How to determine the API version? Check in your configure script for #include , include it and check the DVB_API_VERSION #define. - Currently we use version 2, it will be incremented whenever an API change + Currently we use version 3, it will be incremented whenever an API change meets the CVS main branch. ------------------------------------------------------------------------------- -- cgit v1.2.3 From b12bb27ebff9dfdc48d0d6fb9ee83914f8e2bad7 Mon Sep 17 00:00:00 2001 From: holger Date: Tue, 29 Oct 2002 07:34:35 -0300 Subject: add some words about 'what the heck is a frontend' --- dvb-spec/HOWTO-use-the-frontend-api | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dvb-spec/HOWTO-use-the-frontend-api b/dvb-spec/HOWTO-use-the-frontend-api index 538f5d05e..7f5456d1e 100644 --- a/dvb-spec/HOWTO-use-the-frontend-api +++ b/dvb-spec/HOWTO-use-the-frontend-api @@ -46,10 +46,25 @@ How to determine the API version? ------------------------------------------------------------------------------- -What do you have to do to set up a your frontend? +What is a DVB frontend? + + the term 'frontend' refers to this part of the DVB adapter which receives + an MPEG transport stream and will feed it later into the Demultiplexer. + Whenever you want to receive MPEG streams via satellite, antenna or cable + you have to set up your frontend first. + + When you watch on your DVB card or into your SetTopBox the frontend is usually + the combination of a demodulator chip and a small silver metal box with the + HF electronic. Usually the demodulator is built into this metal box. + +------------------------------------------------------------------------------- + +What do you have to do to set up your frontend? First you should try to determine the type of your frontend. + #include + struct dvb_frontend_info info; int fd; -- cgit v1.2.3 From dfcfc66af625ee81810782a807632a265df83254 Mon Sep 17 00:00:00 2001 From: holger Date: Tue, 29 Oct 2002 07:35:02 -0300 Subject: some words about how to use the demux and section filter API --- dvb-spec/HOWTO-use-the-demux-api | 190 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 dvb-spec/HOWTO-use-the-demux-api diff --git a/dvb-spec/HOWTO-use-the-demux-api b/dvb-spec/HOWTO-use-the-demux-api new file mode 100644 index 000000000..2f1fe8c3d --- /dev/null +++ b/dvb-spec/HOWTO-use-the-demux-api @@ -0,0 +1,190 @@ + +------------------------------------------------------------------------------- + +What has changed since the old Nokia OST API? + + file naming: + - /dev/ost directory is now called /dev/dvb + - each DVB adapter has it's own directory /dev/dvb/adapterX + - here you'll find a number of frontend devices /dev/dvb/adapterX/dmxY + - driver header directory is located now in /usr/include/linux/dvb/ + - we have a linux/dvb/version.h file, this is included by all headers which + don't use the original OST API anymore + + struct naming: + - we follow the kernel naming scheme and try to get the namespace clean, + these changes are mostly syntactical + + new feature: + - section filters have a mode field now, you can set not-equal filters + where you will get only notified when the related bits change + +------------------------------------------------------------------------------- + +How to determine the API version? + + Check in your configure script for #include , + include it and check the DVB_API_VERSION #define. + + Currently we use version 3, it will be incremented whenever an API change + meets the CVS main branch. + +------------------------------------------------------------------------------- + +What is a demultiplexer? + + The demultiplexer in your DVB system cares about the routing of an MPEG2 + stream you feed into the DVB adapter either by read/write system calls, + by using stream inputs of the demultiplexer or the frontend(s). + + Using the demux API you can set up the stream routing and set up filters to + filter the interesting parts of the input streams only. + +------------------------------------------------------------------------------- + +I have set up the frontend and now I want to see some video! +What do I have to do? + + When you have an MPEG video decoder on board we can set up the demultiplexer + to feed the related PES packets into the MPEG decoder: + + #include + + struct dmx_pes_filter_params pesfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + pesfilter.pid = pid; + pesfilter.input = DMX_IN_FRONTEND; + pesfilter.output = DMX_OUT_DECODER; + pesfilter.pes_type = DMX_PES_VIDEO; + pesfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { + perror ("ioctl DMX_SET_PES_FILTER failed"); + return -1; + } + + This will unpack the payload from all transport stream packets with + payload ID and feed it into the MPEG decoder. When pes_type is set + to DMX_PES_VIDEO it will be handled as video data. Other types are + DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_SUBTITLE which will be fed into + the corresponding decoders. + + Open such a PES filter for each substream you want to decode. + + DMX_PES_PCR is used by the decoder to achieve a correct timing syncronisation + for the partial audio/video/... substreams. + + Note that you have to keep the frontend and demux filedescriptor open until + you are not interested in the stream anymore. Old API versions did not shut + down the demodulator and decoder, new driver versions can be configured to + power down after the device is closed. + +------------------------------------------------------------------------------- + +I want to record a stream to disk! How? + + Set up a filter for each substream you want to record as above but set + the pesfilter.output field to DMX_OUT_TAP. Then you can use read() calls + to receive the PES packets. + + When you want to receive transport stream packets use DMX_OUT_TS_TAP and + read the stream from /dev/dvb/adapter0/dvr0. + + Don't forget to keep all device filedescriptors you use open. + +------------------------------------------------------------------------------- + +I want to play back a recorded stream from disk! How? + + Just do the opposite as above. pesfilter.input is now DMX_IN_DVR. + Write your transport stream into the dvr device. + +------------------------------------------------------------------------------- + +What the heck are section filters? + + On some pid's in an MPEG2 stream data is transmitted in form of sections. + These sections describe the stream content, provider data, service + information and other things. + + Here a short list of some pid's where section data is transmitted on DVB + streams: + + 0x00 PAT (Program Association Table - refers to PMT's) + 0x10 NIT (Network Information Table - frequency lists etc) + 0x11 SDT (Service Description Table - service names etc) + 0x12 EIT (Event Information Table - event descriptions etc) + 0x14 TDT/TOT (Time and Date Table, Time Offset Table - time and timezone) + + For a complete list look into the ITU H222.0 (MPEG2) and ETSI EN300468 + standards, there you also find some informations how to parse these sections. + + When you want to receive this data the simple way you can set up a section + filter. + +------------------------------------------------------------------------------- + +How to set up a section filter? + + #include + + struct dmx_sct_filter_params sctfilter; + + if ((fd = open("/dev/dvb/adapter0/demux0", O_RDWR) < 0) { + perror ("open failed"); + return -1; + } + + memset(&sctfilter, 0, sizeof(struct dmx_sct_filter_params)); + + sctfilter.pid = pid; + sctfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(fd, DMX_SET_FILTER, &sctfilter) < 0) { + perror ("ioctl DMX_SET_FILTER failed"); + return -1; + } + + Now start subsequent read() calls to receive your sections and parse them. + Your read-buffer should be at least 4096 bytes if you want to receive complete + sections, otherwise you have to put the parts together manually. + + If your read() call returns -EOVERFLOW you were not fast enough to read/ + process the section data, the internal driver ringbuffer was overflown. + + This error is usually not critical since section data is transmitted + periodically. Anyway, you can adjust the ringbuffer size with the + DMX_SET_BUFFER_SIZE ioctl. + +------------------------------------------------------------------------------- + +How to do table id filtering? + + The struct dmx_sct_filter_params contains two fields filter.filter and + filter.mask. set those mask bits to '1' which should be equal to the filter + bits you set: + + /* set up a TDT filter, table id 0x70 */ + sctfilter.pid = pid; + sctfilter.filter.filter[0] = 0x70; + sctfilter.filter.mask[0] = 0xff; + sctfilter.flags = DMX_IMMEDIATE_START; + + Then submit the DMX_SET_FILTER ioctl. + +------------------------------------------------------------------------------- + +What are not-equal filters? + + When you want to get notified about a new version of a section you can set + up a not-equal filter. Set those filter.mode bits to '1' for which the filter + should pass a section when the corresponding section bit is not equal to the + corresponding filter bit. + +------------------------------------------------------------------------------- + -- cgit v1.2.3 From 731ce4b117fe41c6b57bad827652cdd0a8ad882c Mon Sep 17 00:00:00 2001 From: js Date: Tue, 29 Oct 2002 10:09:27 -0300 Subject: =?UTF-8?q?my=202=C2=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvb-spec/HOWTO-use-the-demux-api | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/dvb-spec/HOWTO-use-the-demux-api b/dvb-spec/HOWTO-use-the-demux-api index 2f1fe8c3d..ee782db6d 100644 --- a/dvb-spec/HOWTO-use-the-demux-api +++ b/dvb-spec/HOWTO-use-the-demux-api @@ -3,10 +3,12 @@ What has changed since the old Nokia OST API? - file naming: + device node naming: - /dev/ost directory is now called /dev/dvb - each DVB adapter has it's own directory /dev/dvb/adapterX - - here you'll find a number of frontend devices /dev/dvb/adapterX/dmxY + - the devfs devices names are identical to those + creatd by the makedev.napi script on non-devfs systems + - here you'll find a number of demux devices /dev/dvb/adapterX/dmxY - driver header directory is located now in /usr/include/linux/dvb/ - we have a linux/dvb/version.h file, this is included by all headers which don't use the original OST API anymore @@ -45,7 +47,7 @@ What is a demultiplexer? I have set up the frontend and now I want to see some video! What do I have to do? - When you have an MPEG video decoder on board we can set up the demultiplexer + When you have an MPEG video decoder on board you can set up the demultiplexer to feed the related PES packets into the MPEG decoder: #include @@ -69,15 +71,20 @@ What do I have to do? } This will unpack the payload from all transport stream packets with - payload ID and feed it into the MPEG decoder. When pes_type is set + packet ID and feed it into the MPEG decoder. When pes_type is set to DMX_PES_VIDEO it will be handled as video data. Other types are DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_SUBTITLE which will be fed into - the corresponding decoders. + the corresponding decoders (if these deocders exist in hardware or firmware). + DMX_PES_TELETEXT usually means VBI insertion by the PAL/NTSC encoder for display + on a connected TV set. If you want to avoid sending the data to one of the + decoders, use pes_type = DMX_PES_OTHER. - Open such a PES filter for each substream you want to decode. + You must open the demux device once for each PES filter you want to set. + E.g. if you want audio and video, you must have two distinct file descriptors + for the two filters. DMX_PES_PCR is used by the decoder to achieve a correct timing syncronisation - for the partial audio/video/... substreams. + between the audio/video/... substreams. Note that you have to keep the frontend and demux filedescriptor open until you are not interested in the stream anymore. Old API versions did not shut @@ -90,10 +97,17 @@ I want to record a stream to disk! How? Set up a filter for each substream you want to record as above but set the pesfilter.output field to DMX_OUT_TAP. Then you can use read() calls - to receive the PES packets. + to receive PES data. When you want to receive transport stream packets use DMX_OUT_TS_TAP and - read the stream from /dev/dvb/adapter0/dvr0. + read the stream from /dev/dvb/adapterX/dvrY. The dvr device gives you + a multiplex of all filtered PES data with DMX_OUT_TS_TAP. E.g. if you + want to record video and audio, open demuxX twice and set two PEs filters + with DMX_OUT_TS_TAP, and open dvrX once to read the TS. + + [ The current API does not allow you to specify you an input/output + routing for section filters. So you can't get multiplexed section + data from the dvr device. ] Don't forget to keep all device filedescriptors you use open. @@ -177,6 +191,9 @@ How to do table id filtering? Then submit the DMX_SET_FILTER ioctl. + The filter comprises 16 bytes covering byte 0 and byte 3..17 in a section, + thus excluding bytes 1 and 2 (the length field of a section). + ------------------------------------------------------------------------------- What are not-equal filters? -- cgit v1.2.3 From d6e1cc571bad041ab402ef377b6ae86bb7599c05 Mon Sep 17 00:00:00 2001 From: holger Date: Thu, 5 Dec 2002 09:37:23 -0200 Subject: Syntax fixes by Joerg Friedrich --- dvb-spec/dvbapi/Makefile | 2 +- dvb-spec/dvbapi/audio.tex | 42 +++++++++---------- dvb-spec/dvbapi/demux.tex | 54 ++++++++++++------------- dvb-spec/dvbapi/video.tex | 100 +++++++++++++++++++++++----------------------- 4 files changed, 99 insertions(+), 99 deletions(-) diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index aae688f33..fe9827cff 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,7 +4,7 @@ TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf -o $@ $< + dvipdf $< $@ dvbapi.ps: dvbapi.dvi dvips -o $@ $< diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 7b6427094..540248463 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -18,7 +18,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { AUDIO_SOURCE_DEMUX, AUDIO_SOURCE_MEMORY -} audio_stream_source_t; +} audio\_stream_source_t; \end{verbatim} AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -36,7 +36,7 @@ typedef enum { AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED -} audio_play_state_t; +} audio\_play_state_t; \end{verbatim} \devsubsubsec{audioChannelSelect\_t} @@ -48,33 +48,33 @@ typedef enum { AUDIO_STEREO, AUDIO_MONO_LEFT, AUDIO_MONO_RIGHT, -} audio_channel_select_t; +} audio\_channel_select_t; \end{verbatim} -\devsubsubsec{audio_status\_t} +\devsubsubsec{audio\_status\_t} \label{audiostatus} The AUDIO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -typedef struct audio_status { +typedef struct audio\_status { boolean AV_sync_state; boolean mute_state; - audio_play_state_t play_state; - audio_stream_source_t stream_source; - audio_channel_select_t channel_select; + audio\_play_state_t play_state; + audio\_stream_source_t stream_source; + audio\_channel_select_t channel_select; boolean bypass_mode; -} audio_status_t; +} audio\_status_t; \end{verbatim} -\devsubsubsec{audio_mixer\_t} +\devsubsubsec{audio\_mixer\_t} \label{audiomixer} The following structure is used by the AUDIO\_SET\_MIXER call to set the audio volume. \begin{verbatim} -typedef struct audio_mixer { +typedef struct audio\_mixer { unsigned int volume_left; unsigned int volume_right; -} audio_mixer_t; +} audio\_mixer_t; \end{verbatim} \devsubsubsec{audio encodings} @@ -99,20 +99,20 @@ the following bits set according to the hardwares capabilities. The ioctl AUDIO\_SET\_KARAOKE uses the following format: \begin{verbatim} typedef -struct audio_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ +struct audio\_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ int vocal1; /* into left and right t at 70% each */ int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ int melody; /* mixed into the left channel and */ /* Vocal2 into the right channel at 100% each. */ /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ -} audio_karaoke_t; +} audio\_karaoke_t; \end{verbatim} \devsubsubsec{audio attributes} \label{aattrib} The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t audio_attributes_t; +typedef uint16_t audio\_attributes_t; /* bits: descr. */ /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ /* 12 multichannel extension */ @@ -311,13 +311,13 @@ typedef uint16_t audio_attributes_t; \ifunction{AUDIO\_GET\_STATUS}{ int ioctl(int fd, int request = AUDIO\_GET\_STATUS, - struct audio_status *status);}{ + struct audio\_status *status);}{ This ioctl call asks the Audio Device to return the current state of the Audio Device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_GET\_STATUS for this command.\\ - struct audio_status *status & Returns the current state of Audio Device. + struct audio\_status *status & Returns the current state of Audio Device. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -371,12 +371,12 @@ typedef uint16_t audio_attributes_t; } \ifunction{AUDIO\_SET\_MIXER}{ - int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio_mixer\_t *mix);}{ + int ioctl(int fd, int request = AUDIO\_SET\_MIXER, audio\_mixer\_t *mix);}{ This ioctl lets you adjust the mixer settings of the audio decoder. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ID for this command.\\ - audio_mixer\_t *mix& mixer settings. + audio\_mixer\_t *mix& mixer settings. }{ EBADF& fd is not a valid open file descriptor.\\ EINTERNAL & Internal error.\\ @@ -425,12 +425,12 @@ typedef uint16_t audio_attributes_t; } \ifunction{AUDIO\_SET\_KARAOKE}{ - int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio_karaoke\_t *karaoke);}{ + int ioctl(fd, int request = AUDIO\_SET\_STREAMTYPE, audio\_karaoke\_t *karaoke);}{ This ioctl allows one to set the mixer settings for a karaoke DVD. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_STREAMTYPE for this command.\\ - audio_karaoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ + audio\_karaoke\_t *karaoke & karaoke settings according to section \ref{audiokaraoke}.\\ }{ EBADF & fd is not a valid open file descriptor \\ EINVAL& karaoke is not a valid or supported karaoke setting.\\ diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index 5a8cc1e9a..c74b133ec 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -19,7 +19,7 @@ typedef enum DMX_OUT_DECODER, DMX_OUT_TAP, DMX_OUT_TS_TAP -} dmx_output_t; +} dmx\_output_t; \end{verbatim} /* Output multiplexed into a new TS */ /* (to be retrieved by reading from the */ @@ -34,7 +34,7 @@ typedef enum { DMX_IN_FRONTEND, /* Input from a front-end device. */ DMX_IN_DVR /* Input from the logical DVR device. */ -} dmx_input_t; +} dmx\_input_t; \end{verbatim} @@ -50,11 +50,11 @@ typedef enum DMX_PES_SUBTITLE, DMX_PES_PCR, DMX_PES_OTHER -} dmx_pes_type_t; +} dmx\_pes\_type_t; \end{verbatim} -\devsubsubsec{dmx_event\_t} +\devsubsubsec{dmx\_event\_t} \label{dmxeventt} \begin{verbatim} @@ -62,7 +62,7 @@ typedef enum { DMX_SCRAMBLING_EV, DMX_FRONTEND_EV -} dmx_event_t; +} dmx\_event_t; \end{verbatim} @@ -74,30 +74,30 @@ typedef enum { DMX_SCRAMBLING_OFF, DMX_SCRAMBLING_ON -} dmx_scrambling_status_t; +} dmx\_scrambling_status_t; \end{verbatim} -\devsubsubsec{dmx_filter\_t} +\devsubsubsec{dmx\_filter\_t} \label{dmxfilter} \begin{verbatim} -typedef struct dmx_filter +typedef struct dmx\_filter { uint8_t filter[DMX_FILTER_SIZE]; uint8_t mask[DMX_FILTER_SIZE]; -} dmx_filter_t; +} dmx\_filter\_t; \end{verbatim} -\devsubsubsec{dmx_sct_filter_params} +\devsubsubsec{dmx\_sct\_filter\_params} \label{dmxsctfilterparams} \begin{verbatim} -struct dmx_sct_filter_params +struct dmx\_sct\_filter\_params { uint16_t pid; - dmx_filter_t filter; + dmx\_filter\_t filter; uint32_t timeout; uint32_t flags; #define DMX_CHECK_CRC 1 @@ -107,32 +107,32 @@ struct dmx_sct_filter_params \end{verbatim} -\devsubsubsec{dmx_pes_filter_params} +\devsubsubsec{dmx\_pes\_filter\_params} \label{dmxpesfilterparams} \begin{verbatim} -struct dmx_pes_filter_params +struct dmx\_pes\_filter\_params { uint16_t pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; + dmx\_input_t input; + dmx\_output_t output; + dmx\_pes\_type_t pes\_type; uint32_t flags; }; \end{verbatim} -\devsubsubsec{dmx_event} +\devsubsubsec{dmx\_event} \label{dmxevent} \begin{verbatim} -struct dmx_event +struct dmx\_event { - dmx_event_t event; + dmx\_event_t event; time_t timeStamp; union { - dmx_scrambling_status_t scrambling; + dmx\_scrambling_status_t scrambling; } u; }; \end{verbatim} @@ -295,7 +295,7 @@ struct dmx_event } \ifunction{DMX\_SET\_FILTER}{ - int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx_sct_filter_params *params); + int ioctl( int fd, int request = DMX\_SET\_FILTER, struct dmx\_sct\_filter\_params *params); }{ This ioctl call sets up a filter according to the filter and mask parameters provided. A timeout may be defined stating number of seconds @@ -310,7 +310,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_FILTER for this command.\\ - struct dmx_sct_filter_params *params + struct dmx\_sct\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -319,7 +319,7 @@ struct dmx_event \ifunction{DMX\_SET\_PES\_FILTER}{ int ioctl( int fd, int request = DMX\_SET\_PES\_FILTER, - struct dmx_pes_filter_params *params); + struct dmx\_pes\_filter\_params *params); }{ This ioctl call sets up a PES filter according to the parameters provided. By a PES filter is meant a filter that is based just on the packet @@ -335,7 +335,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_SET\_PES\_FILTER for this command.\\ - struct dmx_pes_filter_params *params + struct dmx\_pes\_filter\_params *params & Pointer to structure containing filter parameters.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -364,7 +364,7 @@ struct dmx_event } \ifunction{DMX\_GET\_EVENT}{ - int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx_event *ev); + int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx\_event *ev); }{ This ioctl call returns an event if available. If an event is not available, the behavior depends on whether the device is in blocking or @@ -379,7 +379,7 @@ struct dmx_event }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals DMX\_GET\_EVENT for this command.\\ - struct dmx_event *ev & Pointer to the location where the event is to be stored.\\ + struct dmx\_event *ev & Pointer to the location where the event is to be stored.\\ }{ EBADF & fd is not a valid file descriptor.\\ EFAULT & ev points to an invalid address.\\ diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index d33f03c83..7300c95c0 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -9,21 +9,21 @@ device as well as the video4linux device. \devsubsec{Video Data Types} -\devsubsubsec{video_format\_t} +\devsubsubsec{video\_format\_t} \label{videoformat} -The \texttt{video_format\_t} data type defined by +The \texttt{video\_format\_t} data type defined by \begin{verbatim} typedef enum { VIDEO_FORMAT_4_3, VIDEO_FORMAT_16_9 -} video_format_t; +} video\_format_t; \end{verbatim} is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to tell the driver which aspect ratio the output hardware (e.g. TV) has. -It is also used in the data structures video_status (\ref{videostatus}) +It is also used in the data structures video\_status (\ref{videostatus}) returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and -video_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) +video\_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) which report about the display format of the current video stream. \devsubsubsec{videoDisplayFormat\_t} @@ -39,7 +39,7 @@ typedef enum { VIDEO_PAN_SCAN, VIDEO_LETTER_BOX, VIDEO_CENTER_CUT_OUT -} video_displayformat_t; +} video\_displayformat_t; \end{verbatim} as argument. @@ -53,7 +53,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { VIDEO_SOURCE_DEMUX, VIDEO_SOURCE_MEMORY -} video_stream_source_t; +} video\_stream\_source_t; \end{verbatim} VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -71,7 +71,7 @@ typedef enum { VIDEO_STOPPED, VIDEO_PLAYING, VIDEO_FREEZED -} video_play_state_t; +} video\_play\_state_t; \end{verbatim} @@ -80,11 +80,11 @@ typedef enum { The following is the structure of a video event as it is returned by the VIDEO\_GET\_EVENT call. \begin{verbatim} -struct video_event { +struct video\_event { int32_t type; time_t timestamp; union { - video_format_t video_format; + video\_format_t video\_format; } u; }; \end{verbatim} @@ -94,22 +94,22 @@ struct video_event { The VIDEO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -struct video_status { - boolean video_blank; - video_play_state_t play_state; - video_stream_source_t stream_source; - video_format_t video_format; - video_displayformat_t display_format; +struct video\_status { + boolean video\_blank; + video\_play\_state_t play\_state; + video\_stream\_source_t stream\_source; + video\_format_t video\_format; + video\_displayformat_t display\_format; }; \end{verbatim} -If video_blank is set video will be blanked out if the channel is changed or +If video\_blank is set video will be blanked out if the channel is changed or if playback is stopped. Otherwise, the last picture will be displayed. -play_state indicates if the video is currently frozen, stopped, or -being played back. The stream_source corresponds to the seleted source +play\_state indicates if the video is currently frozen, stopped, or +being played back. The stream\_source corresponds to the seleted source for the video stream. It can come either from the demultiplexer or from memory. -The video_format indicates the aspect ratio (one of 4:3 or 16:9) +The video\_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently played video stream. -Finally, display_format corresponds to the selected cropping mode in case the +Finally, display\_format corresponds to the selected cropping mode in case the source video format is not the same as the format of the output device. @@ -119,7 +119,7 @@ An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on within the following structure. \begin{verbatim} /* pointer to and size of a single iframe in memory */ -struct video_still_picture { +struct video\_still\_picture { char *iFrame; int32_t size; }; @@ -162,7 +162,7 @@ typedef enum { VIDEO_SYSTEM_NTSC60, VIDEO_SYSTEM_PAL60, VIDEO_SYSTEM_PALM60 -} video_system_t; +} video\_system_t; \end{verbatim} @@ -174,7 +174,7 @@ information. The call expects the following format for that information: \begin{verbatim} typedef -struct video_highlight { +struct video\_highlight { boolean active; /* 1=show highlight, 0=hide highlight */ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ /* 3- 0 Background pixel contrast */ @@ -190,7 +190,7 @@ struct video_highlight { uint32_t xpos; /* 23-22 button color number */ /* 21-12 start x */ /* 9- 0 end x */ -} video_highlight_t; +} video\_highlight_t; \end{verbatim} @@ -200,10 +200,10 @@ Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, according to the following format: \begin{verbatim} typedef -struct video_spu { +struct video\_spu { boolean active; - int stream_id; -} video_spu_t; + int stream\_id; +} video\_spu\_t; \end{verbatim} @@ -212,10 +212,10 @@ struct video_spu { The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: \begin{verbatim} typedef -struct video_spu_palette{ /* SPU Palette information */ +struct video\_spu\_palette{ /* SPU Palette information */ int length; uint8_t *palette; -} video_spu_palette_t; +} video\_spu\_palette_t; \end{verbatim} \devsubsubsec{video NAVI pack} @@ -224,10 +224,10 @@ In order to get the navigational data the following structure has to be passed to the ioctl VIDEO\_GET\_NAVI: \begin{verbatim} typedef -struct video_navi_pack{ +struct video\_navi\_pack{ int length; /* 0 ... 1024 */ uint8_t data[1024]; -} video_navi_pack_t; +} video\_navi\_pack_t; \end{verbatim} @@ -235,7 +235,7 @@ struct video_navi_pack{ \label{vattrib} The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t video_attributes_t; +typedef uint16_t video\_attributes_t; /* bits: descr. */ /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ /* 13-12 TV system (0=525/60, 1=625/50) */ @@ -406,12 +406,12 @@ EINVAL & Illegal input parameter\\ \ifunction{VIDEO\_GET\_STATUS}{ \label{videogetstatus} - int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video_status *status);}{ + int ioctl(fd, int request = VIDEO\_GET\_STATUS, struct video\_status *status);}{ This ioctl call asks the Video Device to return the current status of the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_GET\_STATUS for this command.\\ - struct video_status *status & Returns the current status of the Video Device.\\ + struct video\_status *status & Returns the current status of the Video Device.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ @@ -420,8 +420,8 @@ EFAULT & status points to invalid address\\ \ifunction{VIDEO\_GET\_EVENT}{ \label{videogetevent} - int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video_event *ev);}{ - This ioctl call returns an event of type video_event if available. + int ioctl(fd, int request = VIDEO\_GET\_EVENT, struct video\_event *ev);}{ + This ioctl call returns an event of type video\_event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an @@ -434,7 +434,7 @@ EFAULT & status points to invalid address\\ }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_GET\_EVENT for this command.\\ - struct video_event *ev & Points to the location where the event, if any, is + struct video\_event *ev & Points to the location where the event, if any, is to be stored.\\ }{ EBADF & fd is not a valid open file descriptor \\ @@ -460,14 +460,14 @@ EOVERFLOW & \\ } \ifunction{VIDEO\_STILLPICTURE}{ - int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video_still_picture *sp);}{ + int ioctl(fd, int request = VIDEO\_STILLPICTURE, struct video\_still\_picture *sp);}{ This ioctl call asks the Video Device to display a still picture (I-frame). The input data shall contain an I-frame. If the pointer is NULL, then the current displayed still picture is blanked. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_STILLPICTURE for this command.\\ - struct video_still_picture *sp& + struct video\_still\_picture *sp& Pointer to a location where an I-frame and size is stored.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -562,7 +562,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_FORMAT}{ \label{videosetformat} - int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video_format\_t format); + int ioctl(fd, int request = VIDEO\_SET\_FORMAT, video\_format\_t format); }{ This ioctl sets the screen format (aspect ratio) of the connected output device (TV) so that the output of the decoder can @@ -570,7 +570,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - video_format\_t format& video format of TV as defined in section \ref{videoformat}.\\ + video\_format\_t format& video format of TV as defined in section \ref{videoformat}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& format is not a valid video format.\\ @@ -595,14 +595,14 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_HIGHLIGHT}{ \label{videosethighlight} - int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video_highlight\_t *vhilite) + int ioctl(fd, int request = VIDEO\_SET\_HIGHLIGHT ,video\_highlight\_t *vhilite) }{ This ioctl sets the SPU highlight information for the menu access of a DVD. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_HIGHLIGHT for this command.\\ - video_highlight\_t *vhilite& SPU Highlight information according to + video\_highlight\_t *vhilite& SPU Highlight information according to section \ref{vhilite}.\\ }{ EBADF& fd is not a valid open file descriptor. \\ @@ -612,7 +612,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU}{ \label{videosetspu} - int ioctl(fd, int request = VIDEO\_SET\_SPU , video_spu\_t *spu) + int ioctl(fd, int request = VIDEO\_SET\_SPU , video\_spu\_t *spu) }{ This ioctl activates or deactivates SPU decoding in a DVD input stream. It can only be used, if the driver is able to handle a DVD @@ -620,7 +620,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_SPU for this command.\\ - video_spu\_t *spu& SPU decoding (de)activation and subid setting + video\_spu\_t *spu& SPU decoding (de)activation and subid setting according to section \ref{videospu}.\\ }{ EBADF& fd is not a valid open file descriptor \\ @@ -630,13 +630,13 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SPU\_PALETTE}{ \label{videosetspupalette} - int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video_spu_palette\_t *palette ) + int ioctl(fd, int request = VIDEO\_SET\_SPU\_PALETTE ,video\_spu\_palette\_t *palette ) }{ This ioctl sets the SPU color palette. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_SPU\_PALETTE for this command.\\ - video_spu_palette\_t *palette& SPU palette according to section \ref{vspupal}.\\ + video\_spu\_palette\_t *palette& SPU palette according to section \ref{vspupal}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& input is not a valid palette or driver doesn't handle SPU.\\ @@ -646,14 +646,14 @@ EOVERFLOW & \\ \ifunction{VIDEO\_GET\_NAVI}{ \label{videosetnavi} - int ioctl(fd, int request = VIDEO\_GET\_NAVI , video_navi_pack\_t *navipack) + int ioctl(fd, int request = VIDEO\_GET\_NAVI , video\_navi\_pack\_t *navipack) }{ This ioctl returns navigational information from the DVD stream. This is especially needed if an encoded stream has to be decoded by the hardware. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_GET\_NAVI for this command.\\ - video_navi_pack\_t *navipack& PCI or DSI pack (private stream 2) + video\_navi\_pack\_t *navipack& PCI or DSI pack (private stream 2) according to section \ref{videonavi}.\\ }{ EBADF& fd is not a valid open file descriptor \\ -- cgit v1.2.3 From 76715ed624559f5d635cc50f74df12a8ac2ad977 Mon Sep 17 00:00:00 2001 From: js Date: Wed, 5 Feb 2003 16:32:21 -0200 Subject: fix syntax error in example program --- dvb-spec/dvbapi/examples.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index fa5c24b48..126268c5d 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -70,7 +70,7 @@ int set_qpsk_channel(int freq, int vpid, int apid, int tpid, FrontendParameters frp; struct pollfd pfd[1]; FrontendEvent event; - int demux1, dmeux2, demux3, front, + int demux1, demux2, demux3, front; frequency = (uint32_t) freq; symbolrate = (uint32_t) srate; -- cgit v1.2.3 From 622f6e3335a0dd1a97cdaee9913c1f105f3e36fa Mon Sep 17 00:00:00 2001 From: js Date: Mon, 10 Feb 2003 10:18:16 -0200 Subject: - merged GNU FDL lincense from NEWSTRUCT branch - updated from DVB_API_VERSION 3 - various minor fixes/additions - bumped version number to 1.0.0-pre1 to match wth upcoming linuxtv-dvb driver release --- dvb-spec/dvbapi/LICENSE | 355 ++++++++++++++++++++++ dvb-spec/dvbapi/Makefile | 8 +- dvb-spec/dvbapi/audio.tex | 80 ++--- dvb-spec/dvbapi/ca.tex | 4 +- dvb-spec/dvbapi/demux.tex | 101 +++---- dvb-spec/dvbapi/devices.tex | 6 +- dvb-spec/dvbapi/dvbapi.tex | 8 +- dvb-spec/dvbapi/examples.tex | 26 +- dvb-spec/dvbapi/fdl.tex | 367 +++++++++++++++++++++++ dvb-spec/dvbapi/frontend.tex | 689 +++++++++++++++++++++++-------------------- dvb-spec/dvbapi/intro.tex | 117 +++----- dvb-spec/dvbapi/kdapi.tex | 9 +- dvb-spec/dvbapi/net.tex | 19 ++ dvb-spec/dvbapi/sec.tex | 282 ------------------ dvb-spec/dvbapi/title.tex | 24 +- dvb-spec/dvbapi/video.tex | 101 ++++--- 16 files changed, 1350 insertions(+), 846 deletions(-) create mode 100644 dvb-spec/dvbapi/LICENSE create mode 100644 dvb-spec/dvbapi/fdl.tex create mode 100644 dvb-spec/dvbapi/net.tex delete mode 100644 dvb-spec/dvbapi/sec.tex diff --git a/dvb-spec/dvbapi/LICENSE b/dvb-spec/dvbapi/LICENSE new file mode 100644 index 000000000..b42936beb --- /dev/null +++ b/dvb-spec/dvbapi/LICENSE @@ -0,0 +1,355 @@ + GNU Free Documentation License + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index fe9827cff..83a5e5f7a 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -1,13 +1,13 @@ all: dvbapi.ps dvbapi.pdf -TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex sec.tex frontend.tex \ - intro.tex title.tex dvbstb.ps +TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ + demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf $< $@ + dvipdf $< dvbapi.ps: dvbapi.dvi - dvips -o $@ $< + dvips $< dvbapi.dvi: dvbapi.bbl $(TEXS) -latex dvbapi diff --git a/dvb-spec/dvbapi/audio.tex b/dvb-spec/dvbapi/audio.tex index 540248463..05c23e56f 100644 --- a/dvb-spec/dvbapi/audio.tex +++ b/dvb-spec/dvbapi/audio.tex @@ -1,7 +1,13 @@ \devsec{DVB Audio Device} The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/audio}. +It can be accessed through \texttt{/dev/dvb/adapter0/audio0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + +Please note that some DVB cards don't have their own +MPEG decoder, which results in the omission of the audio and video +device. \devsubsec{Audio Data Types} @@ -9,16 +15,16 @@ It can be accessed through \texttt{/dev/ost/audio}. This section describes the structures, data types and defines used when talking to the audio device. -\devsubsubsec{audioStreamSource\_t} +\devsubsubsec{audio\_stream\_source\_t} \label{audiostreamsource} The audio stream source is set through the AUDIO\_SELECT\_SOURCE call and can take the following values, depending on whether we are -replaying from an internal (demuxer) or external (user write) source. +replaying from an internal (demux) or external (user write) source. \begin{verbatim} typedef enum { AUDIO_SOURCE_DEMUX, AUDIO_SOURCE_MEMORY -} audio\_stream_source_t; +} audio_stream_source_t; \end{verbatim} AUDIO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -27,7 +33,7 @@ If AUDIO\_SOURCE\_MEMORY is selected the stream comes from the application through the \texttt{write()} system call. -\devsubsubsec{audioPlayState\_t} +\devsubsubsec{audio\_play\_state\_t} The following values can be returned by the AUDIO\_GET\_STATUS call representing the state of audio playback. \label{audioplaystate} @@ -36,45 +42,45 @@ typedef enum { AUDIO_STOPPED, AUDIO_PLAYING, AUDIO_PAUSED -} audio\_play_state_t; +} audio_play_state_t; \end{verbatim} -\devsubsubsec{audioChannelSelect\_t} +\devsubsubsec{audio\_channel\_select\_t} \label{audiochannelselect} The audio channel selected via AUDIO\_CHANNEL\_SELECT is determined by -the following values. +the following values. \begin{verbatim} typedef enum { AUDIO_STEREO, AUDIO_MONO_LEFT, AUDIO_MONO_RIGHT, -} audio\_channel_select_t; +} audio_channel_select_t; \end{verbatim} -\devsubsubsec{audio\_status\_t} +\devsubsubsec{struct audio\_status} \label{audiostatus} The AUDIO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -typedef struct audio\_status { +typedef struct audio_status { boolean AV_sync_state; boolean mute_state; - audio\_play_state_t play_state; - audio\_stream_source_t stream_source; - audio\_channel_select_t channel_select; + audio_play_state_t play_state; + audio_stream_source_t stream_source; + audio_channel_select_t channel_select; boolean bypass_mode; -} audio\_status_t; +} audio_status_t; \end{verbatim} -\devsubsubsec{audio\_mixer\_t} +\devsubsubsec{struct audio\_mixer} \label{audiomixer} The following structure is used by the AUDIO\_SET\_MIXER call to set the audio volume. \begin{verbatim} -typedef struct audio\_mixer { +typedef struct audio_mixer { unsigned int volume_left; unsigned int volume_right; -} audio\_mixer_t; +} audio_mixer_t; \end{verbatim} \devsubsubsec{audio encodings} @@ -94,25 +100,31 @@ the following bits set according to the hardwares capabilities. \end{verbatim} -\devsubsubsec{audio karaoke} +\devsubsubsec{struct audio\_karaoke} \label{audiokaraoke} The ioctl AUDIO\_SET\_KARAOKE uses the following format: \begin{verbatim} typedef -struct audio\_karaoke{ /* if Vocal1 or Vocal2 are non-zero, they get mixed */ - int vocal1; /* into left and right t at 70% each */ - int vocal2; /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets */ - int melody; /* mixed into the left channel and */ - /* Vocal2 into the right channel at 100% each. */ - /* if Melody is non-zero, the melody channel gets mixed */ /* into left and right */ -} audio\_karaoke_t; +struct audio_karaoke{ + int vocal1; + int vocal2; + int melody; +} audio_karaoke_t; \end{verbatim} +If Vocal1 or Vocal2 are non-zero, they get mixed +into left and right t at 70\% each. +If both, Vocal1 and Vocal2 are non-zero, Vocal1 gets +mixed into the left channel and +Vocal2 into the right channel at 100\% each. +Ff Melody is non-zero, the melody channel gets mixed +into left and right. + \devsubsubsec{audio attributes} \label{aattrib} The following attributes can be set by a call to AUDIO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t audio\_attributes_t; +typedef uint16_t audio_attributes_t; /* bits: descr. */ /* 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ /* 12 multichannel extension */ @@ -130,7 +142,7 @@ typedef uint16_t audio\_attributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named audio device (e.g. /dev/ost/audio) for subsequent + This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0) for subsequent use. When an open() call has succeeded, the device will be ready for use. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not affect @@ -225,7 +237,7 @@ typedef uint16_t audio\_attributes_t; \ifunction{AUDIO\_SELECT\_SOURCE}{ int ioctl(int fd, int request = AUDIO\_SELECT\_SOURCE, - audioStreamSource\_t source);}{ + audio\_stream\_source\_t source);}{ This ioctl call informs the audio device which source shall be used for the input data. The possible sources are demux or memory. If AUDIO\_SOURCE\_MEMORY @@ -233,7 +245,7 @@ typedef uint16_t audio\_attributes_t; }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SELECT\_SOURCE for this command.\\ - audioStreamSource\_t source& Indicates the source that shall be used for the + audio\_stream\_source\_t source& Indicates the source that shall be used for the Audio stream. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -295,13 +307,13 @@ typedef uint16_t audio\_attributes_t; \ifunction{AUDIO\_CHANNEL\_SELECT}{ int ioctl(int fd, int request = AUDIO\_CHANNEL\_SELECT, - audioChannelSelect\_t);}{ + audio\_channel\_select\_t);}{ This ioctl call asks the Audio Device to select the requested channel if possible. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_CHANNEL\_SELECT for this command.\\ - audioChannelSelect\_t ch & + audio\_channel\_select\_t ch & Select the output format of the audio (mono left/right, stereo). }{ EBADF& fd is not a valid open file descriptor.\\ @@ -412,13 +424,13 @@ typedef uint16_t audio\_attributes_t; } \ifunction{AUDIO\_SET\_ATTRIBUTES}{ - int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audioAttributes\_t attr );}{ + int ioctl(fd, int request = AUDIO\_SET\_ATTRIBUTES, audio\_attributes\_t attr );}{ This ioctl is intended for DVD playback and allows you to set certain information about the audio stream. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals AUDIO\_SET\_ATTRIBUTES for this command.\\ - iaudioAttributes\_t attr & audio attributes according to section \ref{aattrib}\\ + audio\_attributes\_t attr & audio attributes according to section \ref{aattrib}\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& attr is not a valid or supported attribute setting.\\ diff --git a/dvb-spec/dvbapi/ca.tex b/dvb-spec/dvbapi/ca.tex index eba512b1b..fe76da454 100644 --- a/dvb-spec/dvbapi/ca.tex +++ b/dvb-spec/dvbapi/ca.tex @@ -1,7 +1,9 @@ \devsec{DVB CA Device} The DVB CA device controls the conditional access hardware. -It can be accessed through \texttt{/dev/ost/ca}. +It can be accessed through \texttt{/dev/dvb/adapter0/ca0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/ca.h} in your application. \devsubsec{CA Data Types} diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index c74b133ec..dd032f58d 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -1,16 +1,14 @@ \devsec{DVB Demux Device} The DVB demux device controls the filters of the DVB hardware/software. -It can be accessed through \texttt{/dev/ost/demux}. +It can be accessed through \texttt{/dev/adapter0/demux0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/dmx.h} in your application. \devsubsec{Demux Data Types} -\begin{verbatim} -typedef uint16_t uint16_t; -\end{verbatim} - -\devsubsubsec{dmxOutput\_t} +\devsubsubsec{dmx\_output\_t} \label{dmxoutput} \begin{verbatim} @@ -19,26 +17,30 @@ typedef enum DMX_OUT_DECODER, DMX_OUT_TAP, DMX_OUT_TS_TAP -} dmx\_output_t; +} dmx_output_t; \end{verbatim} -/* Output multiplexed into a new TS */ -/* (to be retrieved by reading from the */ -/* logical DVR device). */ + +\noindent\texttt{DMX\_OUT\_TAP} delivers the stream output to the demux device +on which the ioctl is called. + +\noindent\texttt{DMX\_OUT\_TS\_TAP} routes output to the logical DVR device +\texttt{/dev/dvb/adapter0/dvr0}, which delivers a TS multiplexed from +all filters for which \texttt{DMX\_OUT\_TS\_TAP} was specified. -\devsubsubsec{dmxInput\_t} +\devsubsubsec{dmx\_input\_t} \label{dmxinput} \begin{verbatim} typedef enum { - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ -} dmx\_input_t; + DMX_IN_FRONTEND, + DMX_IN_DVR +} dmx_input_t; \end{verbatim} -\devsubsubsec{dmxPesType\_t} +\devsubsubsec{dmx\_pes\_type\_t} \label{dmxpestype} \begin{verbatim} @@ -50,7 +52,7 @@ typedef enum DMX_PES_SUBTITLE, DMX_PES_PCR, DMX_PES_OTHER -} dmx\_pes\_type_t; +} dmx_pes_type_t; \end{verbatim} @@ -62,11 +64,11 @@ typedef enum { DMX_SCRAMBLING_EV, DMX_FRONTEND_EV -} dmx\_event_t; +} dmx_event_t; \end{verbatim} -\devsubsubsec{dmxScramblingStatus\_t} +\devsubsubsec{dmx\_scrambling\_status\_t} \label{dmxscramblingstatus} \begin{verbatim} @@ -74,32 +76,32 @@ typedef enum { DMX_SCRAMBLING_OFF, DMX_SCRAMBLING_ON -} dmx\_scrambling_status_t; +} dmx_scrambling_status_t; \end{verbatim} -\devsubsubsec{dmx\_filter\_t} +\devsubsubsec{struct dmx\_filter} \label{dmxfilter} \begin{verbatim} -typedef struct dmx\_filter +typedef struct dmx_filter { uint8_t filter[DMX_FILTER_SIZE]; uint8_t mask[DMX_FILTER_SIZE]; -} dmx\_filter\_t; +} dmx_filter_t; \end{verbatim} -\devsubsubsec{dmx\_sct\_filter\_params} +\devsubsubsec{struct dmx\_sct\_filter\_params} \label{dmxsctfilterparams} \begin{verbatim} -struct dmx\_sct\_filter\_params +struct dmx_sct_filter_params { - uint16_t pid; - dmx\_filter\_t filter; - uint32_t timeout; - uint32_t flags; + uint16_t pid; + dmx_filter_t filter; + uint32_t timeout; + uint32_t flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 @@ -107,32 +109,32 @@ struct dmx\_sct\_filter\_params \end{verbatim} -\devsubsubsec{dmx\_pes\_filter\_params} +\devsubsubsec{struct dmx\_pes\_filter\_params} \label{dmxpesfilterparams} \begin{verbatim} -struct dmx\_pes\_filter\_params +struct dmx_pes_filter_params { - uint16_t pid; - dmx\_input_t input; - dmx\_output_t output; - dmx\_pes\_type_t pes\_type; - uint32_t flags; + uint16_t pid; + dmx_input_t input; + dmx_output_t output; + dmx_pes_type_t pes_type; + uint32_t flags; }; \end{verbatim} -\devsubsubsec{dmx\_event} +\devsubsubsec{struct dmx\_event} \label{dmxevent} \begin{verbatim} -struct dmx\_event +struct dmx_event { - dmx\_event_t event; - time_t timeStamp; + dmx_event_t event; + time_t timeStamp; union { - dmx\_scrambling_status_t scrambling; + dmx_scrambling_status_t scrambling; } u; }; \end{verbatim} @@ -142,16 +144,15 @@ struct dmx\_event \devsubsec{Demux Function Calls} \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call, used with a device name of /dev/ost/demuxn, where n - denotes the specific demux device to be opened, allocates a new filter + This system call, used with a device name of /dev/dvb/adapter0/demux0, + allocates a new filter and returns a handle which can be used for subsequent control of that filter. This call has to be made for each filter to be used, i.e. every returned file descriptor is a reference to a single filter. - /dev/ost/dvrn is a logical device to be used for retrieving Transport - Streams for digital video recording. n identifies the physical demux - device that provides the actual DVR functionality. When reading from + /dev/dvb/adapter0/dvr0 is a logical device to be used for retrieving Transport + Streams for digital video recording. When reading from this device a transport stream containing the packets from all PES - filters set in the corresponding demux device (/dev/ost/demuxn) + filters set in the corresponding demux device (/dev/dvb/adapter0/demux0) having the output set to DMX\_OUT\_TS\_TAP. A recorded Transport Stream is replayed by writing to this device. % This device can only be opened in read-write mode. @@ -211,7 +212,7 @@ struct dmx\_event ioctl function or by setting the DMX\_IMMEDIATE\_START flag. If the reading is done from a logical DVR demux device, the data will constitute a Transport Stream including the packets from all PES filters - in the corresponding demux device /dev/ost/demuxn having the output set + in the corresponding demux device /dev/dvb/adapter0/demux0 having the output set to DMX\_OUT\_TS\_TAP. }{ int fd & File descriptor returned by a previous call to open().\\ @@ -236,11 +237,11 @@ struct dmx\_event \function{write()}{ ssize\_t write(int fd, const void *buf, size\_t count); }{ - This system call is only provided by the logical device /dev/ost/dvrn, - where n identifies the physical demux device that provides the actual + This system call is only provided by the logical device /dev/dvb/adapter0/dvr0, + associated with the physical demux device that provides the actual DVR functionality. It is used for replay of a digitally recorded Transport Stream. Matching filters have to be defined in the - corresponding physical demux device, /dev/ost/demuxn. + corresponding physical demux device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is implied by count. }{ int fd & File descriptor returned by a previous call to open().\\ diff --git a/dvb-spec/dvbapi/devices.tex b/dvb-spec/dvbapi/devices.tex index 9c561e853..11eccd897 100644 --- a/dvb-spec/dvbapi/devices.tex +++ b/dvb-spec/dvbapi/devices.tex @@ -1,9 +1,9 @@ -\input{video.tex} -\input{audio.tex} \input{frontend.tex} -\input{sec.tex} \input{demux.tex} +\input{video.tex} +\input{audio.tex} \input{ca.tex} +\input{net.tex} \input{kdapi.tex} %%% Local Variables: diff --git a/dvb-spec/dvbapi/dvbapi.tex b/dvb-spec/dvbapi/dvbapi.tex index ad0251c01..d75c2417f 100644 --- a/dvb-spec/dvbapi/dvbapi.tex +++ b/dvb-spec/dvbapi/dvbapi.tex @@ -1,4 +1,4 @@ -\documentclass[10pt]{book} +\documentclass[a4paper,10pt]{book} \usepackage[dvips,colorlinks=true]{hyperref} \usepackage{times} @@ -131,7 +131,7 @@ \renewcommand{\sectionmark}[1]{\markright{\thesection.\ #1}{}} \lhead[\fancyplain{}{\bfseries \thepage}]{\bfseries \rightmark} \rhead[\fancyplain{}{\bfseries \leftmark}]{\bfseries \thepage} -\cfoot{\copyright 2002 convergence GmbH} +%\cfoot{\copyright\ 2002, 2003 Convergence GmbH} \input{intro.tex} @@ -145,6 +145,10 @@ \cleardoublepage +\input{fdl.tex} + +\cleardoublepage + \thispagestyle{plain}\chaptermark{Bibliography} \addcontentsline{toc}{chapter}{Bibliography} \bibliographystyle{bibsec} diff --git a/dvb-spec/dvbapi/examples.tex b/dvb-spec/dvbapi/examples.tex index 126268c5d..c9a19ba29 100644 --- a/dvb-spec/dvbapi/examples.tex +++ b/dvb-spec/dvbapi/examples.tex @@ -1,6 +1,10 @@ \chapter{Examples} In this section we would like to present some examples for using the DVB API. +Maintainer note: This section is out of date. Please refer to the sample +programs packaged with the driver distribution from +\texttt{http://linuxtv.org/}. + \section{Tuning} We will start with a generic tuning subroutine that uses the frontend and SEC, as well as the demux devices. The example is given for QPSK @@ -17,14 +21,14 @@ tuners, but can easily be adjusted for QAM. #include #include -#include -#include -#include +#include +#include +#include #include -#define DMX "/dev/ost/demux" -#define FRONT "/dev/ost/frontend" -#define SEC "/dev/ost/sec" +#define DMX "/dev/dvb/adapter0/demux1" +#define FRONT "/dev/dvb/adapter0/frontend1" +#define SEC "/dev/dvb/adapter0/sec1" /* routine for checking if we have a signal and other status information*/ int FEReadStatus(int fd, fe_status_t *stat) @@ -234,12 +238,12 @@ recording. #include #include -#include -#include +#include +#include #include -#define DVR "/dev/ost/dvr" -#define AUDIO "/dev/ost/audio" -#define VIDEO "/dev/ost/video" +#define DVR "/dev/dvb/adapter0/dvr1" +#define AUDIO "/dev/dvb/adapter0/audio1" +#define VIDEO "/dev/dvb/adapter0/video1" #define BUFFY (188*20) #define MAX_LENGTH (1024*1024*5) /* record 5MB */ diff --git a/dvb-spec/dvbapi/fdl.tex b/dvb-spec/dvbapi/fdl.tex new file mode 100644 index 000000000..c0fcbe3f3 --- /dev/null +++ b/dvb-spec/dvbapi/fdl.tex @@ -0,0 +1,367 @@ +% fdl.tex +% This file is a chapter. It must be included in a larger document to work +% properly. + +\chapter{GNU Free Documentation License} + +Version 1.1, March 2000\\ + + Copyright \copyright\ 2000 Free Software Foundation, Inc.\\ + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\\ + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +\section*{Preamble} + +The purpose of this License is to make a manual, textbook, or other +written document ``free'' in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +\section{Applicability and Definitions} + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The ``Document'', below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as ``you''. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, \LaTeX~input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +\section{Verbatim Copying} + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +\section{Copying in Quantity} + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +\section{Modifications} + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +\begin{itemize} + +\item Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +\item List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +\item State on the Title page the name of the publisher of the + Modified Version, as the publisher. +\item Preserve all the copyright notices of the Document. +\item Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +\item Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +\item Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +\item Include an unaltered copy of this License. +\item Preserve the section entitled ``History'', and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled ``History'' in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +\item Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the ``History'' section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +\item In any section entitled ``Acknowledgements'' or ``Dedications'', + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +\item Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +\item Delete any section entitled ``Endorsements''. Such a section + may not be included in the Modified Version. +\item Do not retitle any existing section as ``Endorsements'' + or to conflict in title with any Invariant Section. + +\end{itemize} + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties -- for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +\section{Combining Documents} + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled ``History'' +in the various original documents, forming one section entitled +``History''; likewise combine any sections entitled ``Acknowledgements'', +and any sections entitled ``Dedications''. You must delete all sections +entitled ``Endorsements.'' + + +\section{Collections of Documents} + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + + +\section{Aggregation With Independent Works} + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an ``aggregate'', and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +\section{Translation} + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +\section{Termination} + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +\section{Future Revisions of This License} + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + +\section*{ADDENDUM: How to use this License for your documents} + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +\begin{quote} + + Copyright \copyright\ YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled ``GNU + Free Documentation License''. + +\end{quote} + +If you have no Invariant Sections, write ``with no Invariant Sections'' +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write ``no Front-Cover Texts'' instead of +``Front-Cover Texts being LIST''; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index e41ef3d54..bb177df1b 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -1,52 +1,176 @@ \devsec{DVB Frontend API} The DVB frontend device controls the tuner and DVB demodulator hardware. -It can be accessed through \texttt{/dev/ost/frontend}. -If you are using \texttt{devfs} you can use \texttt{/dev/dvb/card0/frontend}. -The frontend device will only be made visible through \texttt{devfs} -if the corresponding card actually has a frontend. Cards which support -the DVB API but, e.g., only can play back recordings, will not offer the -frontend device. +It can be accessed through \texttt{/dev/dvb/adapter0/frontend0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/frontend.h} in your application. + +DVB frontends come in three varieties: DVB-S (satellite), DVB-C (cable) +and DVB-T (terrestrial). Transmission via the internet (DVB-IP) is +not handled by this API. +For DVB-S the frontend device also supports satellite equipment control +(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC) specification +is available from Eutelsat \texttt{http://www.eutelsat.org/}. + +Note that the DVB API may also be used for MPEG decoder-only PCI cards, +in which case there exists no frontend device. \devsubsec{Frontend Data Types} -\devsubsubsec{frontend status} -\label{frontendstatus} +\devsubsubsec{frontend type} +\label{frontendtype} + +For historic reasons frontend types are named after the +type of modulation used in transmission. -Several functions of the frontend device use the feStatus data -type defined by \begin{verbatim} -typedef uint32_t feStatus; +typedef enum fe_type { + FE_QPSK, /* DVB-S */ + FE_QAM, /* DVB-C */ + FE_OFDM /* DVB-T */ +} fe_type_t; \end{verbatim} -to indicate the current state and/or state changes of -the frontend hardware. -\noindent -It can take on the values +\devsubsubsec{frontend capabilities} +\label{frontendcaps} + +Capabilities describe what a frontend can do. Some capabilities +can only be supported for a specific frontend type. + +\begin{verbatim} +typedef enum fe_caps { + FE_IS_STUPID = 0, + FE_CAN_INVERSION_AUTO = 0x1, + FE_CAN_FEC_1_2 = 0x2, + FE_CAN_FEC_2_3 = 0x4, + FE_CAN_FEC_3_4 = 0x8, + FE_CAN_FEC_4_5 = 0x10, + FE_CAN_FEC_5_6 = 0x20, + FE_CAN_FEC_6_7 = 0x40, + FE_CAN_FEC_7_8 = 0x80, + FE_CAN_FEC_8_9 = 0x100, + FE_CAN_FEC_AUTO = 0x200, + FE_CAN_QPSK = 0x400, + FE_CAN_QAM_16 = 0x800, + FE_CAN_QAM_32 = 0x1000, + FE_CAN_QAM_64 = 0x2000, + FE_CAN_QAM_128 = 0x4000, + FE_CAN_QAM_256 = 0x8000, + FE_CAN_QAM_AUTO = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000, + FE_CAN_BANDWIDTH_AUTO = 0x40000, + FE_CAN_GUARD_INTERVAL_AUTO = 0x80000, + FE_CAN_HIERARCHY_AUTO = 0x100000, + FE_CAN_MUTE_TS = 0x80000000, + FE_CAN_CLEAN_SETUP = 0x40000000 +} fe_caps_t; +\end{verbatim} + +\devsubsubsec{frontend information} +\label{frontendinfo} + +Information about the frontend ca be queried with +FE\_GET\_INFO (\ref{fegetinfo}). + +\begin{verbatim} +struct dvb_frontend_info { + char name[128]; + fe_type_t type; + uint32_t frequency_min; + uint32_t frequency_max; + uint32_t frequency_stepsize; + uint32_t frequency_tolerance; + uint32_t symbol_rate_min; + uint32_t symbol_rate_max; + uint32_t symbol_rate_tolerance; /* ppm */ + uint32_t notifier_delay; /* ms */ + fe_caps_t caps; +}; +\end{verbatim} + +\devsubsubsec{diseqc master command} +\label{diseqcmastercmd} + +A message sent from the frontend to DiSEqC capable equipment. + +\begin{verbatim} +struct dvb_diseqc_master_cmd { + uint8_t msg [6]; /* { framing, address, command, data[3] } */ + uint8_t msg_len; /* valid values are 3...6 */ +}; +\end{verbatim} + +\devsubsubsec{diseqc slave reply} +\label{diseqcslavereply} + +A reply to the frontend from DiSEqC 2.0 capable equipment. + +\begin{verbatim} +struct dvb_diseqc_slave_reply { + uint8_t msg [4]; /* { framing, data [3] } */ + uint8_t msg_len; /* valid values are 0...4, 0 means no msg */ + int timeout; /* return from ioctl after timeout ms with */ +}; /* errorcode when no message was received */ +\end{verbatim} + +\devsubsubsec{SEC voltage} +\label{secvoltage} + +The voltage is usually used with non-DiSEqC capable LNBs to +switch the polarzation (horizontal/vertical). + +\begin{verbatim} +typedef enum fe_sec_voltage { + SEC_VOLTAGE_13, + SEC_VOLTAGE_18 +} fe_sec_voltage_t; +\end{verbatim} + +\devsubsubsec{SEC continuous tone} +\label{sectone} + +The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to +switch the high/low band of a dual-band LNB. + +\begin{verbatim} +typedef enum fe_sec_tone_mode { + SEC_TONE_ON, + SEC_TONE_OFF +} fe_sec_tone_mode_t; +\end{verbatim} + +\devsubsubsec{SEC tone burst} +\label{sectoneburst} + +The 22KHz tone burst is usually used with non-DiSEqC capable +switches to select between two connected LNBs/satellites. + \begin{verbatim} -#define FE_HAS_POWER 1 -#define FE_HAS_SIGNAL 2 -#define FE_SPECTRUM_INV 4 -#define FE_HAS_LOCK 8 -#define FE_HAS_CARRIER 16 -#define FE_HAS_VITERBI 32 -#define FE_HAS_SYNC 64 -#define TUNER_HAS_LOCK 128 +typedef enum fe_sec_mini_cmd { + SEC_MINI_A, + SEC_MINI_B +} fe_sec_mini_cmd_t; \end{verbatim} -which can be ORed together and have the following meaning: -\medskip -\begin{tabular}{lp{11cm}} -FE\_HAS\_POWER & the frontend is powered up and is ready to be used\\ -FE\_HAS\_SIGNAL & the frontend detects a signal above the normal noise level\\ -FE\_SPECTRUM\_INV & spectrum inversion is enabled/was necessary for lock\\ -FE\_HAS\_LOCK & frontend successfully locked to a DVB signal \\ -FE\_HAS\_CARRIER & carrier detected in signal\\ -FE\_HAS\_VITERBI & lock at viterbi decoder stage\\ -FE\_HAS\_SYNC & TS sync bytes detected \\ -TUNER\_HAS\_LOCK & the tuner has a frequency lock -\end{tabular} +\devsubsubsec{frontend status} +\label{frontendstatus} + +Several functions of the frontend device use the fe\_status data +type defined by +\begin{verbatim} +typedef enum fe_status { + FE_HAS_SIGNAL = 0x01, /* found something above the noise level */ + FE_HAS_CARRIER = 0x02, /* found a DVB signal */ + FE_HAS_VITERBI = 0x04, /* FEC is stable */ + FE_HAS_SYNC = 0x08, /* found sync bytes */ + FE_HAS_LOCK = 0x10, /* everything's working... */ + FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ + FE_REINIT = 0x40 /* frontend was reinitialized, */ +} fe_status_t; /* application is recommned to reset */ +\end{verbatim} +to indicate the current state and/or state changes of +the frontend hardware. \devsubsubsec{frontend parameters} @@ -57,45 +181,44 @@ depend on the kind of hardware you are using. All kinds of parameters are combined as a union in the FrontendParameters structure: \begin{verbatim} -typedef struct { - __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */ - /* intermediate frequency in kHz for QPSK */ - fe_spectral_inversion_t Inversion; /* spectral inversion */ +struct dvb_frontend_parameters { + uint32_t frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t inversion; union { - QPSKParameters qpsk; - QAMParameters qam; - OFDMParameters ofdm; + struct dvb_qpsk_parameters qpsk; + struct dvb_qam_parameters qam; + struct dvb_ofdm_parameters ofdm; } u; -} FrontendParameters; +}; \end{verbatim} For satellite QPSK frontends you have to use QPSKParameters defined by \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - fe_code_rate_t FEC_inner; /* forward error correction (see above) */ -} QPSKParameters; +struct dvb_qpsk_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ +}; \end{verbatim} for cable QAM frontend you use the QAMParameters structure \begin{verbatim} -typedef struct { - __u32 SymbolRate; /* symbol rate in Symbols per second */ - fe_code_rate_t FEC_outer; /* forward error correction (see above) */ - fe_code_rate_t FEC_inner; /* forward error correction (see above) */ - fe_modulation_t QAM; /* modulation type (see above) */ -} QAMParameters; +struct dvb_qam_parameters { + uint32_t symbol_rate; /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ +}; \end{verbatim} DVB-T frontends are supported by the OFDMParamters structure \begin{verbatim} -typedef struct { - fe_bandwidth_t bandWidth; - fe_code_rate_t HP_fe_code_rate_t; /* high priority stream code rate */ - fe_code_rate_t LP_fe_code_rate_t; /* low priority stream code rate */ - fe_modulation_t Constellation; /* modulation type (see above) */ - fe_transmit_mode_t TransmissionMode; - fe_guard_interval_t guardInterval; - fe_hierarchy_t fe_hierarchy_tInformation; -} OFDMParameters; +struct dvb_ofdm_parameters { + fe_bandwidth_t bandwidth; + fe_code_rate_t code_rate_HP; /* high priority stream code rate */ + fe_code_rate_t code_rate_LP; /* low priority stream code rate */ + fe_modulation_t constellation; /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode; + fe_guard_interval_t guard_interval; + fe_hierarchy_t hierarchy_information; +}; \end{verbatim} In the case of QPSK frontends the Frequency field specifies the intermediate @@ -107,7 +230,7 @@ and is given in Hz. The Inversion field can take one of these values: \begin{verbatim} -typedef enum { +typedef enum fe_spectral_inversion { INVERSION_OFF, INVERSION_ON, INVERSION_AUTO @@ -120,15 +243,18 @@ try to figure out the correct setting by itself. \noindent The possible values for the FEC\_inner field are \begin{verbatim} -enum { - FEC_AUTO, +typedef enum fe_code_rate { + FEC_NONE = 0, FEC_1_2, FEC_2_3, FEC_3_4, + FEC_4_5, FEC_5_6, + FEC_6_7, FEC_7_8, - FEC_NONE -}; + FEC_8_9, + FEC_AUTO +} fe_code_rate_t; \end{verbatim} which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., no error correction or auto detection. @@ -137,47 +263,52 @@ no error correction or auto detection. For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature modulation mode which can be one of the following: \begin{verbatim} -typedef enum -{ QPSK, +typedef enum fe_modulation { + QPSK, QAM_16, QAM_32, QAM_64, QAM_128, - QAM_256 -} QAM_TYPE; + QAM_256, + QAM_AUTO +} fe_modulation_t; \end{verbatim} Finally, there are several more parameters for OFDM: \begin{verbatim} -typedef enum { +typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, - TRANSMISSION_MODE_8K + TRANSMISSION_MODE_8K, + TRANSMISSION_MODE_AUTO } fe_transmit_mode_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_bandwidth { BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, - BANDWIDTH_6_MHZ + BANDWIDTH_6_MHZ, + BANDWIDTH_AUTO } fe_bandwidth_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_guard_interval { GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, - GUARD_INTERVAL_1_4 + GUARD_INTERVAL_1_4, + GUARD_INTERVAL_AUTO } fe_guard_interval_t; \end{verbatim} \begin{verbatim} -typedef enum { +typedef enum fe_hierarchy { HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, - HIERARCHY_4 + HIERARCHY_4, + HIERARCHY_AUTO } fe_hierarchy_t; \end{verbatim} @@ -186,78 +317,12 @@ typedef enum { \label{frontendevents} \begin{verbatim} -enum { - FE_UNEXPECTED_EV, - FE_COMPLETION_EV, - FE_FAILURE_EV +struct dvb_frontend_event { + fe_status_t status; + struct dvb_frontend_parameters parameters; }; \end{verbatim} -\begin{verbatim} -typedef struct { - EventType type; /* type of event, FE_UNEXPECTED_EV, ... */ - long timestamp; /* time in seconds since 1970-01-01 */ - - union { - struct { - fe_status_t previousStatus; /* status before event */ - fe_status_t currentStatus; /* status during event */ - } unexpectedEvent; - FrontendParameters completionEvent; /* parameters for which the - tuning succeeded */ - fe_status_t failureEvent; /* status at failure (e.g. no lock) */ - } u; -} FrontendEvent; -\end{verbatim} - -\begin{verbatim} -struct qpskRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qamRegister { - uint8_t chipId; - uint8_t address; - uint8_t value; -}; -\end{verbatim} - -\begin{verbatim} -struct qpskFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -struct qamFrontendInfo { - uint32_t minFrequency; - uint32_t maxFrequency; - uint32_t maxSymbolRate; - uint32_t minSymbolRate; - uint32_t hwType; - uint32_t hwVersion; -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - FE_POWER_ON, - FE_POWER_STANDBY, - FE_POWER_SUSPEND, - FE_POWER_OFF -} powerState_t; -\end{verbatim} - - \clearpage @@ -265,9 +330,9 @@ typedef enum { \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named frontend device (e.g. /dev/ost/qpskfe - for a satellite frontend or /dev/ost/qamfe for a cable frontend) - for subsequent use. + This system call opens a named frontend device (/dev/dvb/adapter0/frontend0) + for subsequent use. Usually the first thing to do after a successful open + is to find out the frontend type with FE\_GET\_INFO. The device can be opened in read-only mode, which only allows monitoring of device status and statistics, or read/write mode, which allows @@ -303,119 +368,21 @@ typedef enum { int close(int fd);}{ This system call closes a previously opened front-end device. After closing a front-end device, its corresponding hardware might be - powered down automatically, but only when this is needed to open - another front-end device. - To affect an unconditional power down, it should be done explicitly using - the OST\_SET\_POWER\_STATE ioctl. + powered down automatically. }{ int fd & File descriptor returned by a previous call to open().\\ }{ EBADF & fd is not a valid open file descriptor.\\ } -\ifunction{OST\_SELFTEST}{ - int ioctl(int fd, int request = OST\_SELFTEST);}{ - This ioctl call initiates an automatic self-test of the front-end hardware. - This call requires read/write access to the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SELFTEST for this command.\\ - }{ - -1& Self test failure.\\ -} - -\ifunction{OST\_SET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_SET\_POWER\_STATE, uint32\_t state);}{ - This ioctl call, implemented in many OST device drivers, enables direct - control over the power state of the hardware device, which may be on, off, - standby, or suspend. The latter two are low-power modes, which disable all - functionality of the device until turned on again. In contrast to the off - state, however, the standby and suspend states resume operation in the same - state as when the device was active. The only difference between the standby - and suspend states is a different tradeoff between resume time and power - consumption. Power consumption may be lower in the suspend state at the - cost of a longer resume time.\\ - A device that implements this call does not necessarily support two low-power - modes. If it only supports one low-power state, or none at all, the - OST\_SET\_POWER\_STATE operation for the missing states will - still succeed, but - it will be mapped to an existing state as per this table: \\ - \begin{center} - \begin{tabular}[h]{cll} - number of low-power & requested state & resulting state\\ - states supported &&\\ - \\ - 1 & standby & suspend \\ - 1 & suspend & suspend \\ - 0 & standby & on \\ - 0 & suspend & on - \end{tabular} - \end{center}\\ - For other cases where a required state is missing, an error code will be - returned. This can happen if a device does not support the power-off state, - but nevertheless implements this ioctl operation for control of low-power - states. - When opening a device in read/write mode, the driver ensures that the - corresponding hardware device is turned on initially. If the device is - later turned off or put in suspend mode, it has to be explicitly turned on - again.\\ - This call requires read/write access to the device. (Note that the power - management driver can affect the power state of devices without using this - ioctl operation, so having exclusive read/write access to a device does not - imply total control over the power state.) - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_SET\_POWER\_STATE for this command.\\ - uint32\_t state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& turn power on\\ - OST\_POWER\_STANDBY& set device in standby mode\\ - OST\_POWER\_SUSPEND& set device in suspend mode\\ - OST\_POWER\_OFF& turn power off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EPERM & Permission denied (needs read/write access).\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_POWER\_STATE}{ - int ioctl(int fd, int request = OST\_GET\_POWER\_STATE, uint32\_t *state);}{ - This ioctl call, implemented in many OST device drivers, obtains the power - state of the hardware device, which may be on, off, standby, or suspend. - A device that implements this call does not necessarily support all four states. - If there is only one low-power state, the suspend state will be returned for - that state. If there is no low-power state, the on state will be reported - standby and suspend states will be equivalent to the on state. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals OST\_GET\_POWER\_STATE for this command.\\ - uint32\_t *state & Requested power state. One of: \\ - & - \begin{tabular}[h]{ll} - OST\_POWER\_ON& power is on\\ - OST\_POWER\_STANDBY& device in standby mode\\ - OST\_POWER\_SUSPEND& device in suspend mode\\ - OST\_POWER\_OFF& power is off\\ - \end{tabular} - }{ - EBADF& fd is not a valid open file descriptor.\\ - EINVAL& Illegal state, or not available on this device.\\ - EFAULT& state points to invalid address.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_READ\_STATUS}{ - int ioctl(int fd, int request = FE\_READ\_STATUS, feStatus *status);}{ + int ioctl(int fd, int request = FE\_READ\_STATUS, fe\_status\_t *status);}{ This ioctl call returns status information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_STATUS for this command.\\ - struct feStatus *status&Points to the location where the front-end + struct fe\_status\_t *status & Points to the location where the front-end status word is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ @@ -430,10 +397,7 @@ typedef enum { }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_BER for this command.\\ - uint32\_t *ber & The bit error rate, as a multiple of $10^{-9}$, - is stored into *ber.\\ - & Example: a value of 2500 corresponds to a bit error - rate of $2.5\cdot 10^{-6}$, or 1 error in 400000 bits. + uint32\_t *ber & The bit error rate is stored into *ber.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& ber points to invalid address.\\ @@ -443,17 +407,14 @@ typedef enum { } \ifunction{FE\_READ\_SNR}{ - int ioctl(int fd, int request = FE\_READ\_SNR, int32\_t *snr);}{ + int ioctl(int fd, int request = FE\_READ\_SNR, int16\_t *snr);}{ This ioctl call returns the signal-to-noise ratio for the signal currently received by the front-end. For this command, read-only access to the device is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SNR for this command.\\ - int32\_t *snr& The signal-to-noise ratio, as a multiple of - $10^{-6}$ dB, is stored into *snr.\\ - & Example: a value of 12,300,000 corresponds - to a signal-to-noise ratio of 12.3 dB. + int16\_t *snr& The signal-to-noise ratio is stored into *snr.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& snr points to invalid address.\\ @@ -463,7 +424,7 @@ typedef enum { } \ifunction{FE\_READ\_SIGNAL\_STRENGTH}{ - int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int32\_t *strength); + int ioctl( int fd, int request = FE\_READ\_SIGNAL\_STRENGTH, int16\_t *strength); }{ This ioctl call returns the signal strength value for the signal currently received by the front-end. For this command, read-only access to the device @@ -471,11 +432,7 @@ is sufficient. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_READ\_SIGNAL\_STRENGTH for this command.\\ -int32\_t *strength & The signal strength value, as a multiple of - $10^{-6 }$ dBm, - is stored into *strength. \\ - &Example: a value of -12,500,000 corresponds to a signal - strength value of -12.5 dBm. +int16\_t *strength & The signal strength value is stored into *strength.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& status points to invalid address.\\ @@ -505,59 +462,8 @@ by the driver so far. } -\ifunction{FE\_GET\_NEXT\_FREQUENCY}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_FREQUENCY, uint32\_t *freq);}{ - When scanning a frequency range, it is desirable to use a scanning step size - that is as large as possible, yet small enough to be able to lock to any signal - within the range. - This ioctl operation does just that - it increments a given frequency by a - step size suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - frequency, hardware capabilities, and parameter settings of the device. Thus, a - returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient.\\ - Note that scanning may still be excruciatingly slow on some hardware, for - other reasons than a non-optimal scanning step size. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_FREQUENCY for this command.\\ - uint32\_t *freq& Input: a given frequency \\ - & Output: the frequency corresponding to - the next higher frequency setting.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& freq points to invalid address.\\ - EINVAL& Maximum supported frequency reached.\\ - ENOSYS& Function not available for this device. -} - -\ifunction{FE\_GET\_NEXT\_SYMBOL\_RATE}{ - int ioctl( int fd, int request = FE\_GET\_NEXT\_SYMBOL\_RATE, uint32\_t *symbolRate); - }{ - When scanning a range of symbol rates (e.g. for "blind acquisition") it is - desirable to use a scanning step size that is as large as possible, yet - small enough to detect any valid signal within the range. This ioctl - operation does just that - it increments a given symbol rate by a step size - suitable for efficient scanning. - The step size used by this function may be a quite complex function of the given - symbol rate, hardware capabilities, and parameter settings of the device. - Thus, a returned result is only valid for the current state of the device. - For this command, read-only access to the device is sufficient. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_GET\_NEXT\_SYMBOL\_RATE for this command.\\ - uint32\_t *symbolRate& Input: a given symbol rate \\ - & Output: the symbol rate corresponding to - the next higher symbol rate.\\ - }{ - EBADF& fd is not a valid open file descriptor.\\ - EFAULT& symbolRate points to invalid address.\\ - EINVAL& Maximum supported symbol rate reached.\\ - ENOSYS& Function not available for this device. -} - \ifunction{FE\_SET\_FRONTEND}{ - int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct FrontendParameters *p);}{ + int ioctl(int fd, int request = FE\_SET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ This ioctl call starts a tuning operation using specified parameters. The result of this call will be successful if the parameters were valid and the tuning could be initiated. @@ -571,7 +477,21 @@ by the driver so far. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_SET\_FRONTEND for this command.\\ - struct FrontendParameters *p& Points to parameters for tuning operation.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ + }{ + EBADF& fd is not a valid open file descriptor.\\ + EFAULT& p points to invalid address.\\ + EINVAL& Maximum supported symbol rate reached.\\ +} + +\ifunction{FE\_GET\_FRONTEND}{ + int ioctl(int fd, int request = FE\_GET\_FRONTEND, struct dvb\_frontend\_parameters *p);}{ + This ioctl call queries the currently effective frontend parameters. + For this command, read-only access to the device is sufficient. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_SET\_FRONTEND for this command.\\ + struct dvb\_frontend\_parameters *p& Points to parameters for tuning operation.\\ }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& p points to invalid address.\\ @@ -579,8 +499,8 @@ by the driver so far. } \ifunction{FE\_GET\_EVENT}{ - int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct qpskEvent *ev);}{ - This ioctl call returns an event of type qpskEvent if available. If an event + int ioctl(int fd, int request = QPSK\_GET\_EVENT, struct dvb\_frontend\_event *ev);}{ + This ioctl call returns a frontend event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an event @@ -593,14 +513,15 @@ by the driver so far. must be serviced regularly to avoid overflow. If an overflow happens, the oldest event is discarded from the queue, and an error (EOVERFLOW) occurs the next time the queue is read. After reporting the error condition in this - fashion, subsequent QPSK\_GET\_EVENT calls will return events from the queue as + fashion, subsequent FE\_GET\_EVENT calls will return events from the queue as usual.\\ For the sake of implementation simplicity, this command requires read/write access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals QPSK\_GET\_EVENT for this command.\\ - struct qpskEvent *ev&Points to the location where the event, if any, is to be stored. + int request & Equals FE\_GET\_EVENT for this command.\\ + struct dvb\_frontend\_event *ev & Points to the location where the event,\\ + & if any, is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& ev points to invalid address.\\ @@ -611,19 +532,133 @@ by the driver so far. } \ifunction{FE\_GET\_INFO}{ - int ioctl(int fd, int request = FE\_GET\_INFO, struct FrontendInfo *info);}{ +\label{fegetinfo} + int ioctl(int fd, int request = FE\_GET\_INFO, struct dvb\_frontend\_info *info);}{ This ioctl call returns information about the front-end. This call only requires read-only access to the device. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_GET\_INFO for this command.\\ - struct qpskFrontendInfo *info & Points to the location where the front-end + struct dvb\_frontend\_info *info & Points to the location where the front-end information is to be stored. }{ EBADF& fd is not a valid open file descriptor.\\ EFAULT& info points to invalid address.\\ } +\ifunction{FE\_DISEC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = FE\_DISEC\_RESET\_OVERLOAD);}{ + If the bus has been automatically powered off due to power overload, this + ioctl call restores the power to the bus. The call requires read/write + access to the device. + This call has no effect if the device is manually powered off. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_RESET\_OVERLOAD for this command.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_DISEC\_SEND\_MASTER\_CMD}{ +int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ + This ioctl call is used to send a a DiSEqC command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_SEND\_MASTER\_CMD for this command.\\ + struct dvb\_diseqc\_master\_cmd *cmd & Pointer to the command to be transmitted.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_DISEC\_RECV\_SLAVE\_REPLY}{ +int ioctl(int fd, int request = FE\_DISEC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ +This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_RECV\_SLAVE\_REPLY for this command.\\ + struct dvb\_diseqc\_slave\_reply *reply & Pointer to the command to be received.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_DISEC\_SEND\_BURST}{ +int ioctl(int fd, int request = FE\_DISEC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ +This ioctl call is used to send a 22KHz tone burst.\\ + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals FE\_DISEC\_SEND\_BURST for this command.\\ + fe\_sec\_mini\_cmd\_t burst & burst A or B.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & Seq points to an invalid address.\\ + EINVAL & The data structure referred to by seq is invalid in some way.\\ + EPERM & Permission denied (needs read/write access).\\ + EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_SET\_TONE}{ +int ioctl(int fd, int request = FE\_SET\_TONE, fe\_sec\_tone\_mode\_t tone);}{ +This call is used to set the generation of the continuous 22kHz tone. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_TONE for this command.\\ +fe\_sec\_tone\_mode\_t tone & The requested tone generation mode (on/off).\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + +\ifunction{FE\_SET\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_SET\_VOLTAGE, fe\_sec\_voltage\_t voltage);}{ +This call is used to set the bus voltage. +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +fe\_sec\_voltage\_t voltage & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + +\ifunction{FE\_ENABLE\_HIGH\_LNB\_VOLTAGE}{ +int ioctl(int fd, int request = FE\_ENABLE\_HIGH\_LNB\_VOLTAGE, int high);}{ +If high != 0 enables slightly higher voltages instead of 13/18V +(to compensate for long cables). +This call requires read/write permissions. +}{ +int fd & File descriptor returned by a previous call to open().\\ +int request & Equals FE\_SET\_VOLTAGE for this command.\\ +int high & The requested bus voltage.\\ +}{ +ENODEV & Device driver not loaded/available.\\ +EBUSY & Device or resource busy.\\ +EINVAL & Invalid argument.\\ +EPERM & File not opened with read permissions.\\ +EINTERNAL & Internal error in the device driver.\\ +} + + %%% Local Variables: %%% mode: latex %%% TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/intro.tex b/dvb-spec/dvbapi/intro.tex index 1d859fadb..613bcd6c8 100644 --- a/dvb-spec/dvbapi/intro.tex +++ b/dvb-spec/dvbapi/intro.tex @@ -1,15 +1,21 @@ \chapter{Introduction} %\addcontentsline{toc}{part}{Introduction} %\chaptermark{Introduction} + \section{What you need to know} + The reader of this document is required to have some knowledge in the area of digital video broadcasting (DVB) and should be familiar with -part I of ISO/IEC 13818, i.e you should know what a -program/transport stream (PS/TS) is and what is meant by a packetized elementary -stream (PES) or an I-frame. +part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), +i.e you should know what a program/transport stream (PS/TS) is and what is +meant by a packetized elementary stream (PES) or an I-frame. + +Various DVB standards documents are available from +\texttt{http://www.dvb.org/} and/or \texttt{http://www.etsi.org/}. It is also necessary to know how to access unix/linux devices and how to use ioctl calls. This also includes the knowledge of C or C++. + \section{History} The first API for DVB cards we used at Convergence in late 1999 @@ -26,11 +32,12 @@ Nokia and Convergence made it available to all Linux developers and published it on \texttt{http://www.linuxtv.org/} in September 2000. Convergence is the maintainer of the Linux DVB API. Together with the LinuxTV community (i.e. you, the reader of this document), -the Linux DVB API will be constantly reviewed and improved upon. +the Linux DVB API will be constantly reviewed and improved. With the Linux driver for the Siemens/Hauppauge DVB PCI card Convergence provides a first implementation of the Linux DVB API. +\newpage \section{Overview} \begin{figure}[htbp] @@ -49,14 +56,10 @@ main hardware components: Here the raw signal reaches the DVB hardware from a satellite dish or antenna or directly from cable. The frontend down-converts and demodulates -this signal into an MPEG transport stream (TS). - -\item SEC for controlling external hardware like LNBs and antennas - -This part of the hardware can send signals back through the satellite -cable to control the polarization of the LNB, to switch between -different LNBs or even to control the movements of a dish rotor. - +this signal into an MPEG transport stream (TS). In case of a satellite +frontend, this includes a facility for satellite equipment control (SEC), +which allows control of LNB polarization, multi feed switches or +dish rotors. \item Conditional Access (CA) hardware like CI adapters and smartcard slots @@ -74,10 +77,11 @@ or other streams of the same provider. \item MPEG2 audio and video decoder The main targets of the demultiplexer are the MPEG2 audio and video -decoders. After decoding the pass on the uncompressed audio +decoders. After decoding they pass on the uncompressed audio and video to the computer screen or (through a PAL/NTSC encoder) to a TV set. \end{itemize} + Figure \ref{fig:dvbstb} shows a crude schematic of the control and data flow between those components. @@ -91,11 +95,9 @@ Also not every card or STB provides conditional access hardware. The Linux DVB API lets you control these hardware components through currently six Unix-style character devices for -video, audio, frontend, SEC, demux and CA. +video, audio, frontend, demux, CA and IP-over-DVB networking. The video and audio devices control the MPEG2 decoder hardware, the frontend device the tuner and the DVB demodulator. -External hardware like DiSEqC switches and rotors can be controlled -through the SEC device. The demux device gives you control over the PES and section filters of the hardware. If the hardware does not support filtering these filters can be implemented in software. @@ -104,78 +106,41 @@ of the hardware. It can depend on the individual security requirements of the platform, if and how many of the CA functions are made available to the application through this device. +\smallskip All devices can be found in the \texttt{/dev} tree under -\texttt{/dev/ost}, where OST stands for Open Standards Terminal. -The individual devices are called +\texttt{/dev/dvb}. The individual devices are called \begin{itemize} -\item \texttt{/dev/ost/audio}, -\item \texttt{/dev/ost/video}, -\item \texttt{/dev/ost/frontend}, -\item \texttt{/dev/ost/sec}, -\item \texttt{/dev/ost/demux}, -\item \texttt{/dev/ost/ca}, +\item \texttt{/dev/dvb/adapterN/audioM}, +\item \texttt{/dev/dvb/adapterN/videoM}, +\item \texttt{/dev/dvb/adapterN/frontendM}, +\item \texttt{/dev/dvb/adapterN/netM}, +\item \texttt{/dev/dvb/adapterN/demuxM}, +\item \texttt{/dev/dvb/adapterN/caM}, \end{itemize} -but we will omit the ``\texttt{/dev/ost/}'' in the further dicussion of -these devices. - -If more than one card is present in the system the other cards -can be accessed through the corresponding devices with the -card's number appended. \texttt{/dev/ost/demux0} (which -is identical to \texttt{/dev/ost/demux}) would, e.g., control the -demultiplexer of the first card, while \texttt{/dev/ost/demux1} -would control the demultiplexer of the second card, and so on. +where N enumerates the DVB PCI cards in a system starting from~0, +and M enumerates the devices of each type within each adapter, starting +from~0, too. +We will omit the ``\texttt{/dev/dvb/adapterN/}'' in the further dicussion of +these devices. The naming scheme for the devices is the same wheter devfs +is used or not. More details about the data structures and function calls of all the devices are described in the following chapters. +\section{API include files} -\section{DVB Devices with Devfs} - -Recent Linux kernel versions support a special file system called -\textsl{devfs} which is a replacement for the traditional -device directory. -With devfs a Linux DVB driver will only create those device file entries -which actually exist. -It also makes dealing with more complex DVB hardware much easier. -The device structure described above is not well suited to deal -with multiple DVB cards with more than one frontend or demultiplexer. -Consider, e.g., two DVB cards, one with two frontends and -one demultiplexer, the other with one frontend and two demultiplexers. -If we just assign them consecutive numbers, there would be a demultiplexer -and a frontend which do not belong to the same card but have -the same number. - -With \textsl{devfs} we propose a different scheme for the device names. -The root directory for all DVB cards will be \texttt{/dev/dvb}. -Each card gets assigned a sub-directory with the name \texttt{/dev/card0}, -\texttt{/dev/card1}, etc. -The files created in these sub-directories will correspond directly to the -hardware actually present on the card. -Thus, if the first card has one QAM frontend, one demultiplexer -and otherwise no other hardware, -only \texttt{/dev/dvb/card0/qamfe0} and \texttt{/dev/dvb/card0/demux0} -will be created. -When a second DVB-S card with one frontend (including SEC) device, -two demultiplexers and an MPEG2 audio/video decoder is added, the -complete \texttt{/dev/dvb} tree will look like this: +For each of the DVB devices a corresponding include file +exists. The DVB API include files should be included +in application sources with a partial path like: \begin{verbatim} -/dev/dvb/card0/frontend0 - demux0 - -/dev/dvb/card1/video0 - audio0 - demux0 - demux1 - frontend0 - sec0 +#include \end{verbatim} - -\section{Using the Devices} - -\dots - +To enable applications to support different API version, an additional +include file \texttt{linux/dvb/version.h} exists, which defines the +constant \texttt{DVB\_API\_VERSION}. This document describes +\texttt{DVB\_API\_VERSION~3}. %%% Local Variables: %%% mode: latex diff --git a/dvb-spec/dvbapi/kdapi.tex b/dvb-spec/dvbapi/kdapi.tex index 59490299b..f7fc69353 100644 --- a/dvb-spec/dvbapi/kdapi.tex +++ b/dvb-spec/dvbapi/kdapi.tex @@ -1,6 +1,13 @@ \devsec{Kernel Demux API} -The kernel demux API +The kernel demux API defines a driver-internal interface +for registering low-level, hardware specific driver to a +hardware independent demux layer. It is only of interest +for DVB device driver writers. The header file for this +API is named \texttt{demux.h} and located in +\texttt{drivers/media/dvb/dvb-core}. + +Maintainer note: This section must be reviewed. It is probably out of date. \devsubsec{Kernel Demux Data Types} diff --git a/dvb-spec/dvbapi/net.tex b/dvb-spec/dvbapi/net.tex new file mode 100644 index 000000000..dc6566633 --- /dev/null +++ b/dvb-spec/dvbapi/net.tex @@ -0,0 +1,19 @@ +\devsec{DVB Network API} + +The DVB net device enables feeding of MPE (multi protocol +encapsulation) packets received via DVB into the Linux network +protocol stack, e.g. for internet via satellite applications. +It can be accessed through \texttt{/dev/dvb/adapter0/net0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/net.h} in your application. + + +\devsubsec{DVB Net Data Types} + +To be written\dots + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "dvbapi" +%%% End: diff --git a/dvb-spec/dvbapi/sec.tex b/dvb-spec/dvbapi/sec.tex deleted file mode 100644 index 88342c3a6..000000000 --- a/dvb-spec/dvbapi/sec.tex +++ /dev/null @@ -1,282 +0,0 @@ -\devsec{DVB SEC API} - -The DVB SEC device controls the Satellite Equipment Control of -the DVB hardware, i.e. DiSEqC and V-SEC. -It is accessed through \texttt{/dev/ost/sec}. - -\devsubsec{SEC Data Types} - -\devsubsubsec{secDiseqcCmd} -\label{secdiseqccmd} - -\begin{verbatim} -struct secDiseqcCmd { - uint8_t addr; - uint8_t cmd; - uint8_t numParams; - uint8_t params[SEC_MAX_DISEQC_PARAMS]; -}; -\end{verbatim} - - -\devsubsubsec{secVoltage} -\label{secvoltage} - -\begin{verbatim} -typedef uint32_t secVoltage; -\end{verbatim} -\begin{verbatim} -enum { - SEC_VOLTAGE_OFF, - SEC_VOLTAGE_LT, - SEC_VOLTAGE_13, - SEC_VOLTAGE_13_5, - SEC_VOLTAGE_18, - SEC_VOLTAGE_18_5 -}; -\end{verbatim} - - -\devsubsubsec{secToneMode} -\label{sectonemode} - -\begin{verbatim} -typedef uint32_t secToneMode; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_TONE_ON, - SEC_TONE_OFF -} secToneMode_t; -\end{verbatim} - - -\devsubsubsec{secMiniCmd} -\label{secminicmd} - -\begin{verbatim} -typedef uint32_t secMiniCmd; -\end{verbatim} -\begin{verbatim} -typedef enum { - SEC_MINI_NONE, - SEC_MINI_A, - SEC_MINI_B -} secMiniCmd_t; -\end{verbatim} -\begin{verbatim} -struct secStatus { - int32_t busMode; - secVoltage selVolt; - secToneMode contTone; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_BUS_IDLE, - SEC_BUS_BUSY, - SEC_BUS_OFF, - SEC_BUS_OVERLOAD -}; -\end{verbatim} - - -\devsubsubsec{secCommand} -\label{seccommand} - -\begin{verbatim} -struct secCommand { - int32_t type; - union { - struct secDiseqcCmd diseqc; - uint8_t vsec; - uint32_t pause; - } u; -}; -\end{verbatim} - - -\devsubsubsec{secCmdSequence} -\label{seccmdsequence} - -\begin{verbatim} -struct secCmdSequence { - secVoltage voltage; - secMiniCmd miniCommand; - secToneMode continuousTone; - - uint32_t numCommands; - struct secCommand* commands; -}; -\end{verbatim} - -\begin{verbatim} -enum { - SEC_CMDTYPE_DISEQC, - SEC_CMDTYPE_VSEC, - SEC_CMDTYPE_PAUSE -}; -\end{verbatim} - -\begin{verbatim} -typedef enum { - SEC_DISEQC_SENT, - SEC_VSEC_SENT, - SEC_PAUSE_COMPLETE, - SEC_CALLBACK_ERROR -} secCallback_t; -\end{verbatim} - -\clearpage - -\devsubsec{SEC Function Calls} - -\function{open()}{ - int open(const char *deviceName, int flags);}{ - This system call opens a named SEC device for subsequent use. - If the device is opened in read-only mode, only status and statistics - monitoring is allowed. If the device is opened in read/write mode, all - types of operations can be performed. - Any number of applications can have simultaneous access to the device. - }{ - const char *deviceName & Name of specific SEC device.\\ - int flags & A bit-wise OR of the following flags:\\ - & \hspace{1em} O\_RDONLY read-only access\\ - & \hspace{1em} O\_RDWR read/write access\\ - & The optional flag O\_NONBLOCK is not supported. If O\_NONBLOCK is set, - open() and most other subsequent calls to the device will return -1 and - set errno to EWOULDBLOCK. - The communication with the peripheral devices is sequential by nature, - so it is probably preferable to use the device in synchronous mode. - This is the motivation for not going through the extra effort of - implementing asynchronous operation of the device. - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & deviceName does not refer to a valid memory area.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ -} - -\function{close()}{ - int close(int fd);}{ - This system call closes a previously opened SEC device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - }{ - EBADF & fd is not a valid open file descriptor.\\ -} - -\ifunction{SEC\_GET\_STATUS}{ - int ioctl(int fd, int request = SEC\_GET\_STATUS, struct secStatus* status);}{ - This call gets the status of the device. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_GET\_STATUS for this command.\\ - struct secStatus* status & The status of the device.\\ - }{ - ENODEV & Device driver not loaded/available.\\ - EFAULT & status is an invalid pointer.\\ - EBUSY & Device or resource busy.\\ - EINVAL & Invalid argument.\\ - EPERM & File not opened with read permissions.\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_RESET\_OVERLOAD}{ - int ioctl(int fd, int request = SEC\_RESET\_OVERLOAD);}{ - If the bus has been automatically powered off due to power overload, this - ioctl call restores the power to the bus. The call requires read/write - access to the device. - This call has no effect if the device is manually powered off. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_RESET\_OVERLOAD for this command.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ -} - -\ifunction{SEC\_SEND\_SEQUENCE}{ -int ioctl(int fd, int request = SEC\_SEND\_SEQUENCE, struct secCmdSequence *seq); -}{ -This ioctl call is used to send a sequence of DiSEqCTM and/or V-SEC -commands. The first version of the SEC device does not support V-SEC -signaling and it aborts the operation with an error code if a V-SEC -command is detected in the input data.\\ -\begin{itemize} -\item[$\bullet$] The call will fail with errno set to EBUSOVERLOAD if the bus is -overloaded. If the bus is overloaded, SEC\_RESET\_OVERLOAD can be -called and the operation can be retried. -\item[$\bullet$] If seq.numCommands equals 0 and seq.miniCommand equals SEC\_MINI\_NONE, -the bus voltage will be switched and the continuous 22kHz tone -generation enabled/disabled immediately. -\end{itemize}\\ -This operation is atomic. If several processes calls this ioctl -simultaneously, the operations will be serialized so a complete sequence -is sent at a time. - }{ - int fd & File descriptor returned by a previous call to open().\\ - int request & Equals SEC\_SEND\_SEQUENCE for this command.\\ - struct secCmdSequence *seq & Pointer to the command sequence to be transmitted.\\ - }{ - EBADF & fd is not a valid file descriptor.\\ - EFAULT & Seq points to an invalid address.\\ - EINVAL & The data structure referred to by seq is invalid in some way.\\ - EPERM & Permission denied (needs read/write access).\\ - EINTERNAL & Internal error in the device driver.\\ - EBUSMODE & The device is not prepared for transmission - (e.g. it might be manually powered off).\\ - EBUSOVERLOAD & Bus overload has occurred.\\ -} - - -\ifunction{SEC\_SET\_TONE}{ -int ioctl(int fd, int request = SEC\_SET\_TONE, secToneMode tone); -}{ -This call is used to set the generation of the continuous 22kHz tone. -The possibility to just change the tone mode is already provided by -ioctl SEC\_SEND\_SEQUENCE, but SEC\_SET\_TONE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_TONE will block if a transmission is in -progress. This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_TONE for this command.\\ -secToneMode tone & The requested tone generation mode (on/off).\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - - -\ifunction{SEC\_SET\_VOLTAGE}{ -int ioctl(int fd, int request = SEC\_SET\_VOLTAGE, secVoltage voltage); -}{ -This call is used to set the bus voltage. The possibility to just change -the bus voltage is already provided by ioctl SEC\_SEND\_SEQUENCE, but -SEC\_SET\_VOLTAGE is an easier to use interface. -To keep the transmission of a command sequence as -an atomic operation, SEC\_SET\_VOLTAGE will block if a transmission is in -progress. -This call requires read/write permissions. -}{ -int fd & File descriptor returned by a previous call to open().\\ -int request & Equals SEC\_SET\_VOLTAGE for this command.\\ -secVoltage voltage & The requested bus voltage.\\ -}{ -ENODEV & Device driver not loaded/available.\\ -EBUSY & Device or resource busy.\\ -EINVAL & Invalid argument.\\ -EPERM & File not opened with read permissions.\\ -EINTERNAL & Internal error in the device driver.\\ -} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "dvbapi" -%%% End: diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index 574464d23..29aca30d6 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -1,23 +1,27 @@ \pagenumbering{arabic} \pagestyle{empty} -\title{\huge\textbf{LINUX DVB API}} +\title{\huge\textbf{LINUX DVB API Version 3}} \author{ \includegraphics{cimlogo.psi}\\ - Convergence integrated media GmbH\\\\ - Dr. Ralph J.K. Metzler\\ - \texttt{}\\\\ - Dr. Marcus O.C. Metzler\\ - \texttt{} -% Rosenthalerstr. 51\\ -% 10178 Berlin\\Germany + Copyright 2002, 2003 Convergence GmbH\\\\ + Written by Dr. Ralph J.K. Metzler\\ + \texttt{}\\\\ + and Dr. Marcus O.C. Metzler\\ + \texttt{}\\ } -\date{02/14/2002\\V 0.9.4} +\date{02/10/2003\\V 1.0.0-pre1} + \maketitle +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 +or any later version published by the Free Software Foundation. +A copy of the license is included in the chapter entitled "GNU +Free Documentation License". + \newpage -%\end{titlepage} % Local Variables: % mode: latex % TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/video.tex b/dvb-spec/dvbapi/video.tex index 7300c95c0..3fa066b87 100644 --- a/dvb-spec/dvbapi/video.tex +++ b/dvb-spec/dvbapi/video.tex @@ -1,11 +1,22 @@ \devsec{DVB Video Device} The DVB video device controls the MPEG2 video decoder of the DVB hardware. -It can be accessed through \texttt{/dev/ost/video}. -The include file \texttt{ost/video.h} defines the data types and lists -all I/O calls. Please note that some DVB cards don't have their own -MPEG decoder, which results in the omission of the audio and video -device as well as the video4linux device. +It can be accessed through \texttt{/dev/dvb/adapter0/video0}. +Data types and and ioctl definitions can be accessed by including +\texttt{linux/dvb/video.h} in your application. + + +Note that the DVB video device only controls decoding of the MPEG +video stream, not its presentation on the TV or computer screen. +On PCs this is typically handled by an associated video4linux device, e.g. +\texttt{/dev/video}, which allows scaling and defining output windows. + +Some DVB cards don't have their own MPEG decoder, which results in the omission +of the audio and video device as well as the video4linux device. + +The ioctls that deal with SPUs (sub picture units) and navigation +packets are only supported on some MPEG decoders made for DVD playback. + \devsubsec{Video Data Types} @@ -17,7 +28,7 @@ The \texttt{video\_format\_t} data type defined by typedef enum { VIDEO_FORMAT_4_3, VIDEO_FORMAT_16_9 -} video\_format_t; +} video_format_t; \end{verbatim} is used in the VIDEO\_SET\_FORMAT function (\ref{videosetformat}) to tell the driver which aspect ratio the output hardware (e.g. TV) has. @@ -26,7 +37,7 @@ returned by VIDEO\_GET\_STATUS (\ref{videogetstatus}) and video\_event (\ref{videoevent}) returned by VIDEO\_GET\_EVENT (\ref{videogetevent}) which report about the display format of the current video stream. -\devsubsubsec{videoDisplayFormat\_t} +\devsubsubsec{video\_display\_format\_t} \label{videodispformat} In case the display format of the video stream and of the @@ -39,7 +50,7 @@ typedef enum { VIDEO_PAN_SCAN, VIDEO_LETTER_BOX, VIDEO_CENTER_CUT_OUT -} video\_displayformat_t; +} video_display_format_t; \end{verbatim} as argument. @@ -53,7 +64,7 @@ replaying from an internal (demuxer) or external (user write) source. typedef enum { VIDEO_SOURCE_DEMUX, VIDEO_SOURCE_MEMORY -} video\_stream\_source_t; +} video_stream_source_t; \end{verbatim} VIDEO\_SOURCE\_DEMUX selects the demultiplexer (fed either by the frontend or the DVR device) as the source of @@ -71,35 +82,35 @@ typedef enum { VIDEO_STOPPED, VIDEO_PLAYING, VIDEO_FREEZED -} video\_play\_state_t; +} video_play_state_t; \end{verbatim} -\devsubsubsec{video event} +\devsubsubsec{struct video\_event} \label{videoevent} The following is the structure of a video event as it is returned by the VIDEO\_GET\_EVENT call. \begin{verbatim} -struct video\_event { +struct video_event { int32_t type; time_t timestamp; union { - video\_format_t video\_format; + video_format_t video_format; } u; }; \end{verbatim} -\devsubsubsec{video status} +\devsubsubsec{struct video\_status} \label{videostatus} The VIDEO\_GET\_STATUS call returns the following structure informing about various states of the playback operation. \begin{verbatim} -struct video\_status { - boolean video\_blank; - video\_play\_state_t play\_state; - video\_stream\_source_t stream\_source; - video\_format_t video\_format; - video\_displayformat_t display\_format; +struct video_status { + boolean video_blank; + video_play_state_t play_state; + video_stream_source_t stream_source; + video_format_t video_format; + video_displayformat_t display_format; }; \end{verbatim} If video\_blank is set video will be blanked out if the channel is changed or @@ -113,13 +124,13 @@ Finally, display\_format corresponds to the selected cropping mode in case the source video format is not the same as the format of the output device. -\devsubsubsec{video display still picture} +\devsubsubsec{struct video\_still\_picture} \label{videostill} An I-frame displayed via the VIDEO\_STILLPICTURE call is passed on within the following structure. \begin{verbatim} /* pointer to and size of a single iframe in memory */ -struct video\_still\_picture { +struct video_still_picture { char *iFrame; int32_t size; }; @@ -162,19 +173,19 @@ typedef enum { VIDEO_SYSTEM_NTSC60, VIDEO_SYSTEM_PAL60, VIDEO_SYSTEM_PALM60 -} video\_system_t; +} video_system_t; \end{verbatim} -\devsubsubsec{video highlights} +\devsubsubsec{struct video\_highlight} \label{vhilite} Calling the ioctl VIDEO\_SET\_HIGHLIGHTS posts the SPU highlight information. The call expects the following format for that information: - + \begin{verbatim} typedef -struct video\_highlight { +struct video_highlight { boolean active; /* 1=show highlight, 0=hide highlight */ uint8_t contrast1; /* 7- 4 Pattern pixel contrast */ /* 3- 0 Background pixel contrast */ @@ -190,7 +201,7 @@ struct video\_highlight { uint32_t xpos; /* 23-22 button color number */ /* 21-12 start x */ /* 9- 0 end x */ -} video\_highlight_t; +} video_highlight_t; \end{verbatim} @@ -200,10 +211,10 @@ Calling VIDEO\_SET\_SPU deactivates or activates SPU decoding, according to the following format: \begin{verbatim} typedef -struct video\_spu { +struct video_spu { boolean active; - int stream\_id; -} video\_spu\_t; + int stream_id; +} video_spu_t; \end{verbatim} @@ -212,10 +223,10 @@ struct video\_spu { The following structure is used to set the SPU palette by calling VIDEO\_SPU\_PALETTE: \begin{verbatim} typedef -struct video\_spu\_palette{ /* SPU Palette information */ +struct video_spu_palette{ int length; uint8_t *palette; -} video\_spu\_palette_t; +} video_spu_palette_t; \end{verbatim} \devsubsubsec{video NAVI pack} @@ -224,10 +235,10 @@ In order to get the navigational data the following structure has to be passed to the ioctl VIDEO\_GET\_NAVI: \begin{verbatim} typedef -struct video\_navi\_pack{ - int length; /* 0 ... 1024 */ +struct video_navi_pack{ + int length; /* 0 ... 1024 */ uint8_t data[1024]; -} video\_navi\_pack_t; +} video_navi_pack_t; \end{verbatim} @@ -235,7 +246,7 @@ struct video\_navi\_pack{ \label{vattrib} The following attributes can be set by a call to VIDEO\_SET\_ATTRIBUTES: \begin{verbatim} -typedef uint16_t video\_attributes_t; +typedef uint16_t video_attributes_t; /* bits: descr. */ /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ /* 13-12 TV system (0=525/60, 1=625/50) */ @@ -255,7 +266,7 @@ typedef uint16_t video\_attributes_t; \function{open()}{ int open(const char *deviceName, int flags);}{ - This system call opens a named video device (e.g. /dev/ost/video) + This system call opens a named video device (e.g. /dev/dvb/adapter0/video0) for subsequent use. When an open() call has succeeded, the device will be ready for use. @@ -376,7 +387,7 @@ EINTERNAL & Internal error, possibly in the communication with \ifunction{VIDEO\_SELECT\_SOURCE}{ - int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, videoStreamSource\_t source);}{ + int ioctl(fd, int request = VIDEO\_SELECT\_SOURCE, video\_stream\_source\_t source);}{ This ioctl call informs the video device which source shall be used for the input data. The possible sources are demux or memory. If memory is selected, the data is fed to the video device through @@ -384,7 +395,7 @@ EINTERNAL & Internal error, possibly in the communication with }{ int fd & File descriptor returned by a previous call to open().\\ int request& Equals VIDEO\_SELECT\_SOURCE for this command. \\ - videoStreamSource\_t source&Indicates which source shall be used for the Video stream.\\ + video\_stream\_source\_t source&Indicates which source shall be used for the Video stream.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error, possibly in the communication with the DVB subsystem.\\ @@ -446,13 +457,13 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_DISPLAY\_FORMAT}{ \label{videosetdisplayformat} - int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, videoDisplayFormat\_t format);}{ + int ioctl(fd, int request = VIDEO\_SET\_DISPLAY\_FORMAT, video\_display\_format\_t format);}{ This ioctl call asks the Video Device to select the video format to be applied by the MPEG chip on the video. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_DISPLAY\_FORMAT for this command.\\ - videoDisplayFormat\_t format & Selects the video format to be used.\\ + video\_display\_format\_t format & Selects the video format to be used.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINTERNAL & Internal error.\\ @@ -578,7 +589,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_SYSTEM}{ \label{videosetsystem} - int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , videoSystem\_t system); + int ioctl(fd, int request = VIDEO\_SET\_SYSTEM , video\_system\_t system); }{ This ioctl sets the television output format. The format (see section \ref{videosys}) may vary from the color format of the displayed MPEG @@ -587,7 +598,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_FORMAT for this command.\\ - videoSystem\_t system& video system of TV output.\\ + video\_system\_t system& video system of TV output.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& system is not a valid or supported video system.\\ @@ -663,7 +674,7 @@ EOVERFLOW & \\ \ifunction{VIDEO\_SET\_ATTRIBUTES}{ \label{videosetattributes} - int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,videoAttributes\_t + int ioctl(fd, int request = VIDEO\_SET\_ATTRIBUTE ,video\_attributes\_t vattr) }{ This ioctl is intended for DVD playback and allows you to set @@ -673,7 +684,7 @@ EOVERFLOW & \\ }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals VIDEO\_SET\_ATTRIBUTE for this command.\\ - videoAttributes\_t vattr& video attributes according to section \ref{vattrib}.\\ + video\_attributes\_t vattr& video attributes according to section \ref{vattrib}.\\ }{ EBADF& fd is not a valid open file descriptor \\ EINVAL& input is not a valid attribute setting.\\ -- cgit v1.2.3 From e2d96061a03942dabe4a4248f41c7aea300f6680 Mon Sep 17 00:00:00 2001 From: holger Date: Mon, 10 Feb 2003 11:06:51 -0200 Subject: fix some minor typos --- dvb-spec/dvbapi/frontend.tex | 57 +++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index bb177df1b..cbd646b93 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -7,7 +7,7 @@ Data types and and ioctl definitions can be accessed by including DVB frontends come in three varieties: DVB-S (satellite), DVB-C (cable) and DVB-T (terrestrial). Transmission via the internet (DVB-IP) is -not handled by this API. +not yet handled by this API but a future extension is possible. For DVB-S the frontend device also supports satellite equipment control (SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC) specification is available from Eutelsat \texttt{http://www.eutelsat.org/}. @@ -20,7 +20,7 @@ in which case there exists no frontend device. \devsubsubsec{frontend type} \label{frontendtype} -For historic reasons frontend types are named after the +For historical reasons frontend types are named after the type of modulation used in transmission. \begin{verbatim} @@ -117,7 +117,9 @@ struct dvb_diseqc_slave_reply { \label{secvoltage} The voltage is usually used with non-DiSEqC capable LNBs to -switch the polarzation (horizontal/vertical). +switch the polarzation (horizontal/vertical). +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_voltage { @@ -131,6 +133,8 @@ typedef enum fe_sec_voltage { The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the high/low band of a dual-band LNB. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_tone_mode { @@ -144,6 +148,8 @@ typedef enum fe_sec_tone_mode { The 22KHz tone burst is usually used with non-DiSEqC capable switches to select between two connected LNBs/satellites. +When using DiSEqC epuipment this voltage has to be switched consistently +to the DiSEqC commands as described in the DiSEqC spec. \begin{verbatim} typedef enum fe_sec_mini_cmd { @@ -193,14 +199,15 @@ struct dvb_frontend_parameters { }; \end{verbatim} -For satellite QPSK frontends you have to use QPSKParameters defined by +For satellite QPSK frontends you have to use the \verb|QPSKParameters| member +defined by \begin{verbatim} struct dvb_qpsk_parameters { uint32_t symbol_rate; /* symbol rate in Symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ }; \end{verbatim} -for cable QAM frontend you use the QAMParameters structure +for cable QAM frontend you use the \verb|QAMParameters| structure \begin{verbatim} struct dvb_qam_parameters { uint32_t symbol_rate; /* symbol rate in Symbols per second */ @@ -208,7 +215,7 @@ struct dvb_qam_parameters { fe_modulation_t modulation; /* modulation type (see above) */ }; \end{verbatim} -DVB-T frontends are supported by the OFDMParamters structure +DVB-T frontends are supported by the \verb|OFDMParamters| structure \begin{verbatim} struct dvb_ofdm_parameters { fe_bandwidth_t bandwidth; @@ -221,9 +228,9 @@ struct dvb_ofdm_parameters { }; \end{verbatim} -In the case of QPSK frontends the Frequency field specifies the intermediate -frequency, i.e. the offset which is effectively added to the local oscillator -frequency (LOF) of the LNB. +In the case of QPSK frontends the \verb|Frequency| field specifies the +intermediate frequency, i.e. the offset which is effectively added to the +local oscillator frequency (LOF) of the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and OFDM frontends the Frequency specifies the absolute frequency and is given in Hz. @@ -237,11 +244,11 @@ typedef enum fe_spectral_inversion { } fe_spectral_inversion_t; \end{verbatim} It indicates if spectral inversion should be presumed or not. -In the automatic setting (\verb INVERSION\_AUTO) the hardware will +In the automatic setting (\verb|INVERSION_AUTO|) the hardware will try to figure out the correct setting by itself. \noindent -The possible values for the FEC\_inner field are +The possible values for the \verb|FEC_inner| field are \begin{verbatim} typedef enum fe_code_rate { FEC_NONE = 0, @@ -256,7 +263,7 @@ typedef enum fe_code_rate { FEC_AUTO } fe_code_rate_t; \end{verbatim} -which correspond to error correction rates of $1\over 2$, $2\over 3$, etc., +which correspond to error correction rates of $1/2$, $2/3$, etc., no error correction or auto detection. \noindent @@ -546,15 +553,16 @@ by the driver so far. EFAULT& info points to invalid address.\\ } -\ifunction{FE\_DISEC\_RESET\_OVERLOAD}{ - int ioctl(int fd, int request = FE\_DISEC\_RESET\_OVERLOAD);}{ +\ifunction{FE\_DISEQC\_RESET\_OVERLOAD}{ + int ioctl(int fd, int request = FE\_DISEQC\_RESET\_OVERLOAD);}{ If the bus has been automatically powered off due to power overload, this ioctl call restores the power to the bus. The call requires read/write access to the device. This call has no effect if the device is manually powered off. + Not all DVB adapters support this ioctl. }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_RESET\_OVERLOAD for this command.\\ + int request & Equals FE\_DISEQC\_RESET\_OVERLOAD for this command.\\ }{ EBADF & fd is not a valid file descriptor.\\ EPERM & Permission denied (needs read/write access).\\ @@ -562,12 +570,12 @@ by the driver so far. } -\ifunction{FE\_DISEC\_SEND\_MASTER\_CMD}{ -int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ +\ifunction{FE\_DISEQC\_SEND\_MASTER\_CMD}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_MASTER\_CMD, struct dvb\_diseqc\_master\_cmd *cmd);}{ This ioctl call is used to send a a DiSEqC command.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_SEND\_MASTER\_CMD for this command.\\ + int request & Equals FE\_DISEQC\_SEND\_MASTER\_CMD for this command.\\ struct dvb\_diseqc\_master\_cmd *cmd & Pointer to the command to be transmitted.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -577,12 +585,12 @@ int ioctl(int fd, int request = FE\_DISEC\_SEND\_MASTER\_CMD, struct dvb\_diseqc EINTERNAL & Internal error in the device driver.\\ } -\ifunction{FE\_DISEC\_RECV\_SLAVE\_REPLY}{ -int ioctl(int fd, int request = FE\_DISEC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ +\ifunction{FE\_DISEQC\_RECV\_SLAVE\_REPLY}{ +int ioctl(int fd, int request = FE\_DISEQC\_RECV\_SLAVE\_REPLY, struct dvb\_diseqc\_slave\_reply *reply);}{ This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_RECV\_SLAVE\_REPLY for this command.\\ + int request & Equals FE\_DISEQC\_RECV\_SLAVE\_REPLY for this command.\\ struct dvb\_diseqc\_slave\_reply *reply & Pointer to the command to be received.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -592,12 +600,12 @@ This ioctl call is used to receive reply to a DiSEqC 2.0 command.\\ EINTERNAL & Internal error in the device driver.\\ } -\ifunction{FE\_DISEC\_SEND\_BURST}{ -int ioctl(int fd, int request = FE\_DISEC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ +\ifunction{FE\_DISEQC\_SEND\_BURST}{ +int ioctl(int fd, int request = FE\_DISEQC\_SEND\_BURST, fe\_sec\_mini\_cmd\_t burst);}{ This ioctl call is used to send a 22KHz tone burst.\\ }{ int fd & File descriptor returned by a previous call to open().\\ - int request & Equals FE\_DISEC\_SEND\_BURST for this command.\\ + int request & Equals FE\_DISEQC\_SEND\_BURST for this command.\\ fe\_sec\_mini\_cmd\_t burst & burst A or B.\\ }{ EBADF & fd is not a valid file descriptor.\\ @@ -646,6 +654,7 @@ int ioctl(int fd, int request = FE\_ENABLE\_HIGH\_LNB\_VOLTAGE, int high);}{ If high != 0 enables slightly higher voltages instead of 13/18V (to compensate for long cables). This call requires read/write permissions. +Not all DVB adapters support this ioctl. }{ int fd & File descriptor returned by a previous call to open().\\ int request & Equals FE\_SET\_VOLTAGE for this command.\\ -- cgit v1.2.3 From f005fb88fdf382126eb5e52a0910b5d60f750d5d Mon Sep 17 00:00:00 2001 From: oberritter Date: Mon, 3 Mar 2003 02:31:56 -0300 Subject: updated valgrind patch to version 1.0.4 and added checks for audio-, ca-, net-, osd- and video ioctl()s. note that NET_REMOVE_IF and VIDEO_SET_ATTRIBUTES both are _IO('o', 53), so VIDEO_SET_ATTRIBUTES can not checked. --- dvb-spec/valgrind-1.0.4.diff | 353 ++++++++++++++++++++++++++++++++++++ dvb-spec/valgrind-1.0pre3-dvb.patch | 154 ---------------- 2 files changed, 353 insertions(+), 154 deletions(-) create mode 100644 dvb-spec/valgrind-1.0.4.diff delete mode 100644 dvb-spec/valgrind-1.0pre3-dvb.patch diff --git a/dvb-spec/valgrind-1.0.4.diff b/dvb-spec/valgrind-1.0.4.diff new file mode 100644 index 000000000..20ddcc956 --- /dev/null +++ b/dvb-spec/valgrind-1.0.4.diff @@ -0,0 +1,353 @@ +diff -Naur valgrind-1.0.4.orig/vg_syscall_mem.c valgrind-1.0.4/vg_syscall_mem.c +--- valgrind-1.0.4.orig/vg_syscall_mem.c 2002-10-13 17:04:49.000000000 +0200 ++++ valgrind-1.0.4/vg_syscall_mem.c 2003-03-03 06:17:15.000000000 +0100 +@@ -2323,6 +2323,332 @@ + sizeof(struct cdrom_msf)); + KERNEL_DO_SYSCALL(tid,res); + break; ++ ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ must_be_writable(tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ must_be_writable(tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ must_be_readable(tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ must_be_readable(tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ must_be_readable(tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ must_be_writable(tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ must_be_writable(tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ must_be_writable(tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ must_be_writable(tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ must_be_readable(tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ must_be_readable(tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ must_be_readable(tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ must_be_readable(tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ must_be_writable(tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ must_be_writable(tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ must_be_writable(tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_SET_SOURCE: ++ must_be_readable(tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ must_be_writable(tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ must_be_readable(tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ must_be_writable(tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ must_be_writable(tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ must_be_writable(tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ must_be_writable(tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ must_be_writable(tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ must_be_writable(tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ must_be_readable(tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ must_be_writable(tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ must_be_writable(tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ must_be_readable(tst, "ioctl(NET_ADD_IF)", arg3, ++ sizeof(struct dvb_net_if)); ++ must_be_writable(tst, "ioctl(NET_ADD_IF)", arg3, ++ sizeof(struct dvb_net_if)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ must_be_readable(tst, "ioctl(NET_GET_IF)", arg3, ++ sizeof(struct dvb_net_if)); ++ must_be_writable(tst, "ioctl(NET_GET_IF)", arg3, ++ sizeof(struct dvb_net_if)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ must_be_readable(tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ must_be_writable(tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ must_be_writable(tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ must_be_readable(tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ must_be_writable(tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ must_be_readable(tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ must_be_readable(tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ must_be_readable(tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ must_be_writable(tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ make_readable (arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +diff -Naur valgrind-1.0.4.orig/vg_unsafe.h valgrind-1.0.4/vg_unsafe.h +--- valgrind-1.0.4.orig/vg_unsafe.h 2002-09-17 16:31:08.000000000 +0200 ++++ valgrind-1.0.4/vg_unsafe.h 2003-03-03 06:12:23.000000000 +0100 +@@ -86,6 +86,13 @@ + + #include + ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ diff --git a/dvb-spec/valgrind-1.0pre3-dvb.patch b/dvb-spec/valgrind-1.0pre3-dvb.patch deleted file mode 100644 index 173aaecc5..000000000 --- a/dvb-spec/valgrind-1.0pre3-dvb.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff -ur valgrind-1.0pre3.orig/vg_syscall_mem.c valgrind-1.0pre3/vg_syscall_mem.c ---- valgrind-1.0pre3.orig/vg_syscall_mem.c Thu Jun 20 09:23:49 2002 -+++ valgrind-1.0pre3/vg_syscall_mem.c Mon Jul 8 19:55:45 2002 -@@ -2038,6 +2038,136 @@ - sizeof(struct cdrom_msf)); - KERNEL_DO_SYSCALL(tid,res); - break; -+ -+ /* DVB (Digital Video Broadcasting) related stuff -+ * http://www.linuxtv.org -+ */ -+ case FE_GET_INFO: -+ must_be_writable(tst, "ioctl(FE_GET_INFO)", arg3, -+ sizeof(struct dvb_frontend_info)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(struct dvb_frontend_info)); -+ break; -+ case FE_DISEQC_RESET_OVERLOAD: -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case FE_DISEQC_SEND_MASTER_CMD: -+ must_be_readable(tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, -+ sizeof(struct dvb_diseqc_master_cmd)); -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case FE_DISEQC_RECV_SLAVE_REPLY: -+ must_be_writable(tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, -+ sizeof(struct dvb_diseqc_slave_reply)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(struct dvb_diseqc_slave_reply)); -+ break; -+ case FE_DISEQC_SEND_BURST: -+ case FE_SET_TONE: -+ case FE_SET_VOLTAGE: -+ case FE_ENABLE_HIGH_LNB_VOLTAGE: -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case FE_READ_STATUS: -+ must_be_writable(tst, "ioctl(FE_READ_STATUS)", arg3, -+ sizeof(fe_status_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(fe_status_t)); -+ break; -+ case FE_READ_BER: -+ must_be_writable(tst, "ioctl(FE_READ_BER)", arg3, -+ sizeof(uint32_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(uint32_t)); -+ break; -+ case FE_READ_SIGNAL_STRENGTH: -+ must_be_writable(tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, -+ sizeof(uint16_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(uint16_t)); -+ break; -+ case FE_READ_SNR: -+ must_be_writable(tst, "ioctl(FE_READ_SNR)", arg3, -+ sizeof(uint16_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(uint16_t)); -+ break; -+ case FE_READ_UNCORRECTED_BLOCKS: -+ must_be_writable(tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, -+ sizeof(uint32_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(uint32_t)); -+ break; -+ case FE_SET_FRONTEND: -+ must_be_readable(tst, "ioctl(FE_SET_FRONTEND)", arg3, -+ sizeof(struct dvb_frontend_parameters)); -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case FE_GET_FRONTEND: -+ must_be_writable(tst, "ioctl(FE_GET_FRONTEND)", arg3, -+ sizeof(struct dvb_frontend_parameters)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(struct dvb_frontend_parameters)); -+ break; -+ case FE_GET_EVENT: -+ must_be_writable(tst, "ioctl(FE_GET_EVENT)", arg3, -+ sizeof(struct dvb_frontend_event)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(struct dvb_frontend_event)); -+ break; -+ case DMX_START: -+ case DMX_STOP: -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case DMX_SET_FILTER: -+ must_be_readable(tst, "ioctl(DMX_SET_FILTER)", arg3, -+ sizeof(struct dmx_sct_filter_params)); -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case DMX_SET_PES_FILTER: -+ must_be_readable(tst, "ioctl(DMX_SET_PES_FILTER)", arg3, -+ sizeof(struct dmx_pes_filter_params)); -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case DMX_SET_BUFFER_SIZE: -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ case DMX_GET_EVENT: -+ must_be_writable(tst, "ioctl(DMX_GET_EVENT)", arg3, -+ sizeof(struct dmx_event)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(struct dmx_event)); -+ break; -+ case DMX_GET_PES_PIDS: -+ must_be_writable(tst, "ioctl(DMX_GET_PES_PIDS)", arg3, -+ 5*sizeof(uint16_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, 5*sizeof(uint16_t)); -+ break; -+ case DMX_GET_CAPS: -+ must_be_writable(tst, "ioctl(DMX_GET_CAPS)", arg3, -+ sizeof(dmx_caps_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ if (!VG_(is_kerror)(res) && res == 0) -+ make_readable (arg3, sizeof(dmx_caps_t)); -+ break; -+ case DMX_SET_SOURCE: -+ must_be_readable(tst, "ioctl(DMX_SET_SOURCE)", arg3, -+ sizeof(dmx_source_t)); -+ KERNEL_DO_SYSCALL(tid,res); -+ break; -+ - /* We don't have any specific information on it, so - try to do something reasonable based on direction and - size bits. The encoding scheme is described in -diff -ur valgrind-1.0pre3.orig/vg_unsafe.h valgrind-1.0pre3/vg_unsafe.h ---- valgrind-1.0pre3.orig/vg_unsafe.h Thu Jun 13 18:02:37 2002 -+++ valgrind-1.0pre3/vg_unsafe.h Mon Jul 8 19:56:20 2002 -@@ -85,6 +85,10 @@ - - #include - -+#include -+#include -+#include -+#include - - /*--------------------------------------------------------------------*/ - /*--- end vg_unsafe.h ---*/ -- cgit v1.2.3 From 0c835747fef0c13496f773a754bf557183734387 Mon Sep 17 00:00:00 2001 From: oberritter Date: Mon, 3 Mar 2003 03:42:29 -0300 Subject: fixed NET_ADD_IF/NET_GET_IF which are _IOWR and added diff for valgrind version 1.9.4 --- dvb-spec/valgrind-1.0.4.diff | 24 +-- dvb-spec/valgrind-1.9.4.diff | 356 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 10 deletions(-) create mode 100644 dvb-spec/valgrind-1.9.4.diff diff --git a/dvb-spec/valgrind-1.0.4.diff b/dvb-spec/valgrind-1.0.4.diff index 20ddcc956..0e77afe14 100644 --- a/dvb-spec/valgrind-1.0.4.diff +++ b/dvb-spec/valgrind-1.0.4.diff @@ -1,7 +1,7 @@ diff -Naur valgrind-1.0.4.orig/vg_syscall_mem.c valgrind-1.0.4/vg_syscall_mem.c --- valgrind-1.0.4.orig/vg_syscall_mem.c 2002-10-13 17:04:49.000000000 +0200 -+++ valgrind-1.0.4/vg_syscall_mem.c 2003-03-03 06:17:15.000000000 +0100 -@@ -2323,6 +2323,332 @@ ++++ valgrind-1.0.4/vg_syscall_mem.c 2003-03-03 07:34:50.000000000 +0100 +@@ -2323,6 +2323,336 @@ sizeof(struct cdrom_msf)); KERNEL_DO_SYSCALL(tid,res); break; @@ -229,10 +229,12 @@ diff -Naur valgrind-1.0.4.orig/vg_syscall_mem.c valgrind-1.0.4/vg_syscall_mem.c + make_readable (arg3, sizeof(struct dvb_frontend_event)); + break; + case NET_ADD_IF: -+ must_be_readable(tst, "ioctl(NET_ADD_IF)", arg3, -+ sizeof(struct dvb_net_if)); -+ must_be_writable(tst, "ioctl(NET_ADD_IF)", arg3, -+ sizeof(struct dvb_net_if)); ++ must_be_readable(tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ must_be_writable(tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); + KERNEL_DO_SYSCALL(tid,res); + if (!VG_(is_kerror)(res) && res == 0) + make_readable (arg3, sizeof(struct dvb_net_if)); @@ -241,10 +243,12 @@ diff -Naur valgrind-1.0.4.orig/vg_syscall_mem.c valgrind-1.0.4/vg_syscall_mem.c + KERNEL_DO_SYSCALL(tid,res); + break; + case NET_GET_IF: -+ must_be_readable(tst, "ioctl(NET_GET_IF)", arg3, -+ sizeof(struct dvb_net_if)); -+ must_be_writable(tst, "ioctl(NET_GET_IF)", arg3, -+ sizeof(struct dvb_net_if)); ++ must_be_readable(tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ must_be_writable(tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); + KERNEL_DO_SYSCALL(tid,res); + if (!VG_(is_kerror)(res) && res == 0) + make_readable (arg3, sizeof(struct dvb_net_if)); diff --git a/dvb-spec/valgrind-1.9.4.diff b/dvb-spec/valgrind-1.9.4.diff new file mode 100644 index 000000000..bcc9de6ea --- /dev/null +++ b/dvb-spec/valgrind-1.9.4.diff @@ -0,0 +1,356 @@ +diff -Naur valgrind-1.9.4.orig/coregrind/vg_syscalls.c valgrind-1.9.4/coregrind/vg_syscalls.c +--- valgrind-1.9.4.orig/coregrind/vg_syscalls.c 2003-02-24 22:58:01.000000000 +0100 ++++ valgrind-1.9.4/coregrind/vg_syscalls.c 2003-03-03 07:25:43.000000000 +0100 +@@ -2365,6 +2365,335 @@ + KERNEL_DO_SYSCALL(tid,res); + break; + ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_SET_SOURCE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +diff -Naur valgrind-1.9.4.orig/coregrind/vg_unsafe.h valgrind-1.9.4/coregrind/vg_unsafe.h +--- valgrind-1.9.4.orig/coregrind/vg_unsafe.h 2002-10-05 17:18:27.000000000 +0200 ++++ valgrind-1.9.4/coregrind/vg_unsafe.h 2003-03-03 07:00:37.000000000 +0100 +@@ -86,6 +86,13 @@ + + #include + ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ -- cgit v1.2.3 From e3a855eb32a18c8a10cf2a5d35a6d8c43e06bc7f Mon Sep 17 00:00:00 2001 From: endriss Date: Sun, 4 May 2003 19:14:01 -0300 Subject: updated --- dvb-spec/README.CABLE | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dvb-spec/README.CABLE b/dvb-spec/README.CABLE index de13af020..0a8466f6d 100644 --- a/dvb-spec/README.CABLE +++ b/dvb-spec/README.CABLE @@ -1,5 +1,5 @@ -- The analog module is not fully supported yet. - The MSP3400 module will have to be extended to handle then audio and - video switching for the module. - If you want sound you will have to remove the module for now. - +- The analog module of the DVB-C should be detected automatically. + +- If you are using a Technotrend/Hauppauge DVB-C card *without* analog module, + you might have to use module parameter adac=-1 (dvb-ttpci.o). + -- cgit v1.2.3 From 8c9b6d3513b11e6f02a76a8d2a938a547c3b6d92 Mon Sep 17 00:00:00 2001 From: js Date: Thu, 24 Jul 2003 12:57:26 -0300 Subject: rm'ed leftover from Metzler's libdvb --- dvb-spec/channel | 104 ------------------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 dvb-spec/channel diff --git a/dvb-spec/channel b/dvb-spec/channel deleted file mode 100644 index f17e8cb19..000000000 --- a/dvb-spec/channel +++ /dev/null @@ -1,104 +0,0 @@ -This file describes the format of the new channel config file. - -Comments start with # -Each section starts with one of the identifiers: LNB, DISEQC, ROTOR, ... - -IDs are either the official transponder, network, etc. id if it exists -and is unique, otherwise it is just a consecutive number assigned by -the application. -An LNB can also describe a cable TV outlet or a terrestrial antenna. -Names (as all parameters in brackets) are optional. In this case the -application should use the ID as name. - -The application should offer selection sorted by channel number, network, -satellite, bouquet. - - -# satellite definition -SAT - ID satid # ID = xxxy, sat is at position xxx.y degrees - [NAME name] - LNBID lnbid # LNB this sat is received with - [ROTORID rotorid] # rotor commands to position it on this sat - -# LNB definition -LNB - ID lnbid - [NAME name] - [INPUT input] # input of card which the lnb is connected to (default 0) - TYPE type # LNB, CATV or terrestrial antenna? - LOF1 offset1 # local oscillator frequency 1 - LOF2 offset2 # local oscillator frequency 2 - SLOF switchfreq # switching frequency - [DISEQCNR diseqcnr] # simple 2- or 4-switch DiSEqC - [DISEQCID diseqcid] - [INPUT input] - [SWITCHID switchid] - -# A transponder definition -TRANSPONDER - ID tpid - TYPE type # digital (DVB-S(1), C(2) or T(3)) or analog(0) ? - SATID satid - [NAME name] # if analog this is the channel name - FREQ freq - POL H/V - [QAM qam] # only needed if DVB-C - [SRATE sr] # only if DVB - [FEC fec] # only if DVB - [PICID picid] # picture attributes for all channels on this transponder - -# channel definition (only if DVB) -CHANNEL - ID channelid - [NAME name] - TPID tpid - TYPE type - PNR pnr - VPID vpid - APID apid - TPID tpid - [PMTPID pmtpid] - [PCRPID pcrpid] - [APID apid2 APID apid3 ... APID apidn] # more audio PIDs for several languages - [AC3PID ac3] - [NETWID networkid] - [BOUQID bouquetid] - [PICID picid] - -# network definition -NETWORK - ID nwid - [NAME name] - -# bouquet definition -BOUQUET - ID bqid - [NAME name] - - - -# These will be implemented later - -# DiSEqC command sequence -DISEQC - ID disid - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - -# DiSEqC switch -SWITCH - ID switchid - SWITCHID switchid # next "higher" switch - [NAME name] - MESSAGE data1 [ ... datan ] BURST 0/1 END - - -# DiSEqC rotor command sequence leading to a certain rotor position -ROTOR - ID rotid - POS degrees - MESSAGE data1 [ ... datan ] BURST 0/1 END - [MESSAGE data1 [ ... datan ] BURST 0/1 END ...] - -- cgit v1.2.3 From 904b355be5e52d80295f03db1f48301d2a28628e Mon Sep 17 00:00:00 2001 From: js Date: Thu, 24 Jul 2003 13:31:30 -0300 Subject: updated for latest (1.9.6+) valgrind release, added DMX_GET_STC --- dvb-spec/valgrind-20030716.diff | 361 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 dvb-spec/valgrind-20030716.diff diff --git a/dvb-spec/valgrind-20030716.diff b/dvb-spec/valgrind-20030716.diff new file mode 100644 index 000000000..af0adc806 --- /dev/null +++ b/dvb-spec/valgrind-20030716.diff @@ -0,0 +1,361 @@ +--- valgrind-20030716/coregrind/vg_syscalls.c.orig 2003-07-05 17:44:45.000000000 +0200 ++++ valgrind-20030716/coregrind/vg_syscalls.c 2003-07-24 18:26:48.000000000 +0200 +@@ -2430,6 +2430,342 @@ void VG_(perform_assumed_nonblocking_sys + KERNEL_DO_SYSCALL(tid,res); + break; + ++ /* DVB (Digital Video Broadcasting) related stuff ++ * http://www.linuxtv.org ++ */ ++ case AUDIO_STOP: ++ case AUDIO_PLAY: ++ case AUDIO_PAUSE: ++ case AUDIO_CONTINUE: ++ case AUDIO_SELECT_SOURCE: ++ case AUDIO_SET_MUTE: ++ case AUDIO_SET_AV_SYNC: ++ case AUDIO_SET_BYPASS_MODE: ++ case AUDIO_CHANNEL_SELECT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_STATUS)", arg3, ++ sizeof(audio_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(audio_status_t)); ++ break; ++ case AUDIO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(AUDIO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case AUDIO_CLEAR_BUFFER: ++ case AUDIO_SET_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_MIXER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_MIXER)", arg3, ++ sizeof(audio_mixer_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_STREAMTYPE: ++ case AUDIO_SET_EXT_ID: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_ATTRIBUTES: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_ATTRIBUTES)", arg3, ++ sizeof(audio_attributes_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case AUDIO_SET_KARAOKE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(AUDIO_SET_KARAOKE)", arg3, ++ sizeof(audio_karaoke_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_RESET: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_GET_CAP: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_CAP)", arg3, ++ sizeof(ca_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_caps_t)); ++ break; ++ case CA_GET_SLOT_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_SLOT_INFO)", arg3, ++ sizeof(ca_slot_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_slot_info_t)); ++ break; ++ case CA_GET_DESCR_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_DESCR_INFO)", arg3, ++ sizeof(ca_descr_info_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_descr_info_t)); ++ break; ++ case CA_GET_MSG: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(CA_GET_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(ca_msg_t)); ++ break; ++ case CA_SEND_MSG: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SEND_MSG)", arg3, ++ sizeof(ca_msg_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_DESCR: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_DESCR)", arg3, ++ sizeof(ca_descr_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case CA_SET_PID: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(CA_SET_PID)", arg3, ++ sizeof(ca_pid_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_START: ++ case DMX_STOP: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_FILTER)", arg3, ++ sizeof(struct dmx_sct_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_PES_FILTER: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_PES_FILTER)", arg3, ++ sizeof(struct dmx_pes_filter_params)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_SET_BUFFER_SIZE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case DMX_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_EVENT)", arg3, ++ sizeof(struct dmx_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_event)); ++ break; ++ case DMX_GET_PES_PIDS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_PES_PIDS)", arg3, ++ 5*sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, 5*sizeof(uint16_t)); ++ break; ++ case DMX_GET_CAPS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_CAPS)", arg3, ++ sizeof(dmx_caps_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(dmx_caps_t)); ++ break; ++ case DMX_GET_STC: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(DMX_GET_STC)", arg3, ++ sizeof(struct dmx_stc)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dmx_stc)); ++ break; ++ case DMX_SET_SOURCE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(DMX_SET_SOURCE)", arg3, ++ sizeof(dmx_source_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_INFO: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_INFO)", arg3, ++ sizeof(struct dvb_frontend_info)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_info)); ++ break; ++ case FE_DISEQC_RESET_OVERLOAD: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_SEND_MASTER_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_DISEQC_SEND_MASTER_CMD)", arg3, ++ sizeof(struct dvb_diseqc_master_cmd)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_DISEQC_RECV_SLAVE_REPLY: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_DISEQC_RECV_SLAVE_REPLY)", arg3, ++ sizeof(struct dvb_diseqc_slave_reply)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_diseqc_slave_reply)); ++ break; ++ case FE_DISEQC_SEND_BURST: ++ case FE_SET_TONE: ++ case FE_SET_VOLTAGE: ++ case FE_ENABLE_HIGH_LNB_VOLTAGE: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_READ_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_STATUS)", arg3, ++ sizeof(fe_status_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(fe_status_t)); ++ break; ++ case FE_READ_BER: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_BER)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_READ_SIGNAL_STRENGTH: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SIGNAL_STRENGTH)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_SNR: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_SNR)", arg3, ++ sizeof(uint16_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint16_t)); ++ break; ++ case FE_READ_UNCORRECTED_BLOCKS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_READ_UNCORRECTED_BLOCKS)", arg3, ++ sizeof(uint32_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(uint32_t)); ++ break; ++ case FE_SET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(FE_SET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case FE_GET_FRONTEND: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_FRONTEND)", arg3, ++ sizeof(struct dvb_frontend_parameters)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_parameters)); ++ break; ++ case FE_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(FE_GET_EVENT)", arg3, ++ sizeof(struct dvb_frontend_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_frontend_event)); ++ break; ++ case NET_ADD_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_ADD_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_ADD_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case NET_REMOVE_IF: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case NET_GET_IF: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(NET_GET_IF (if_num, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->if_num), ++ sizeof(((struct dvb_net_if *) arg3)->if_num)); ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(NET_GET_IF (pid, uint16_t))", ++ (int) &(((struct dvb_net_if *) arg3)->pid), ++ sizeof(((struct dvb_net_if *) arg3)->pid)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct dvb_net_if)); ++ break; ++ case OSD_SEND_CMD: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(OSD_SEND_CMD)", arg3, ++ sizeof(osd_cmd_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STOP: ++ case VIDEO_PLAY: ++ case VIDEO_FREEZE: ++ case VIDEO_CONTINUE: ++ case VIDEO_SELECT_SOURCE: ++ case VIDEO_SET_BLANK: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_STATUS: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_STATUS)", arg3, ++ sizeof(struct video_status)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_status)); ++ break; ++ case VIDEO_GET_EVENT: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_EVENT)", arg3, ++ sizeof(struct video_event)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(struct video_event)); ++ break; ++ case VIDEO_SET_DISPLAY_FORMAT: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_STILLPICTURE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_STILLPICTURE)", arg3, ++ sizeof(struct video_still_picture)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_FAST_FORWARD: ++ case VIDEO_SLOWMOTION: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_CAPABILITIES: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_CAPABILITIES)", arg3, ++ sizeof(unsigned int)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(unsigned int)); ++ break; ++ case VIDEO_CLEAR_BUFFER: ++ case VIDEO_SET_ID: ++ case VIDEO_SET_STREAMTYPE: ++ case VIDEO_SET_FORMAT: ++ case VIDEO_SET_SYSTEM: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_HIGHLIGHT: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_HIGHLIGHT)", arg3, ++ sizeof(video_highlight_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU)", arg3, ++ sizeof(video_spu_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_SET_SPU_PALETTE: ++ SYSCALL_TRACK( pre_mem_read,tst, "ioctl(VIDEO_SET_SPU_PALETTE)", arg3, ++ sizeof(video_spu_palette_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++ case VIDEO_GET_NAVI: ++ SYSCALL_TRACK( pre_mem_write,tst, "ioctl(VIDEO_GET_NAVI)", arg3, ++ sizeof(video_navi_pack_t)); ++ KERNEL_DO_SYSCALL(tid,res); ++ if (!VG_(is_kerror)(res) && res == 0) ++ VG_TRACK( post_mem_write,arg3, sizeof(video_navi_pack_t)); ++ break; ++#if 0 ++ /* FIXME: conflicts with NET_REMOVE_IF - both are _IO('o', 53) */ ++ case VIDEO_SET_ATTRIBUTES: ++ KERNEL_DO_SYSCALL(tid,res); ++ break; ++#endif ++ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in +--- valgrind-20030716/coregrind/vg_unsafe.h.orig 2003-06-14 10:50:27.000000000 +0200 ++++ valgrind-20030716/coregrind/vg_unsafe.h 2003-07-24 18:22:55.000000000 +0200 +@@ -88,6 +88,13 @@ + + #include + ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + /*--------------------------------------------------------------------*/ + /*--- end vg_unsafe.h ---*/ -- cgit v1.2.3 From b51e4627e2053a7434d1f308123a6a9b07e4e78f Mon Sep 17 00:00:00 2001 From: js Date: Thu, 24 Jul 2003 14:08:21 -0300 Subject: - document DMX_GET_STC - bump version to 1.0.0 --- dvb-spec/dvbapi/demux.tex | 32 +++++++++++++++++++++++++++++++- dvb-spec/dvbapi/title.tex | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/dvb-spec/dvbapi/demux.tex b/dvb-spec/dvbapi/demux.tex index dd032f58d..882463090 100644 --- a/dvb-spec/dvbapi/demux.tex +++ b/dvb-spec/dvbapi/demux.tex @@ -139,6 +139,17 @@ struct dmx_event }; \end{verbatim} +\devsubsubsec{struct dmx\_stc} +\label{dmxstc} + +\begin{verbatim} +struct dmx_stc { + unsigned int num; /* input : which STC? 0..N */ + unsigned int base; /* output: divisor for stc to get 90 kHz clock */ + uint64_t stc; /* output: stc in 'base'*90 kHz units */ +}; +\end{verbatim} + \clearpage \devsubsec{Demux Function Calls} @@ -367,7 +378,7 @@ struct dmx_event \ifunction{DMX\_GET\_EVENT}{ int ioctl( int fd, int request = DMX\_GET\_EVENT, struct dmx\_event *ev); }{ - This ioctl call returns an event if available. If an event is not + This ioctl call returns an event if available. If an event is not available, the behavior depends on whether the device is in blocking or non-blocking mode. In the latter case, the call fails immediately with errno set to EWOULDBLOCK. In the former case, the call blocks until an @@ -387,6 +398,25 @@ struct dmx_event EWOULDBLOCK & There is no event pending, and the device is in non-blocking mode.\\ } +\ifunction{DMX\_GET\_STC}{ + int ioctl( int fd, int request = DMX\_GET\_STC, struct dmx\_stc *stc); + }{ + This ioctl call returns the current value of the system time counter + (which is driven by a PES filter of type DMX\_PES\_PCR). Some hardware + supports more than one STC, so you must specify which one by setting + the num field of stc before the ioctl (range 0...n). The result is returned in form + of a ratio with a 64 bit numerator and a 32 bit denominator, so the + real 90kHz STC value is \begin{ttfamily}stc->stc / stc->base\end{ttfamily}. + }{ + int fd & File descriptor returned by a previous call to open().\\ + int request & Equals DMX\_GET\_STC for this command.\\ + struct dmx\_stc *stc & Pointer to the location where the stc is to be stored.\\ + }{ + EBADF & fd is not a valid file descriptor.\\ + EFAULT & stc points to an invalid address.\\ + EINVAL & Invalid stc number.\\ +} + %%% Local Variables: %%% mode: latex %%% TeX-master: "dvbapi" diff --git a/dvb-spec/dvbapi/title.tex b/dvb-spec/dvbapi/title.tex index 29aca30d6..857492b7e 100644 --- a/dvb-spec/dvbapi/title.tex +++ b/dvb-spec/dvbapi/title.tex @@ -10,7 +10,7 @@ and Dr. Marcus O.C. Metzler\\ \texttt{}\\ } -\date{02/10/2003\\V 1.0.0-pre1} +\date{24/07/2003\\V 1.0.0} \maketitle -- cgit v1.2.3 From 56a4ef5b2748552e9f28020a1dad9dec2119542c Mon Sep 17 00:00:00 2001 From: js Date: Fri, 25 Jul 2003 16:07:49 -0300 Subject: added HTML target --- dvb-spec/dvbapi/.cvsignore | 2 ++ dvb-spec/dvbapi/Makefile | 7 ++++--- dvb-spec/dvbapi/frontend.tex | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore index fb6974f6b..71db27b0a 100644 --- a/dvb-spec/dvbapi/.cvsignore +++ b/dvb-spec/dvbapi/.cvsignore @@ -9,3 +9,5 @@ dvbapi.log dvbapi.pdf dvbapi.out dvbapi.toc +dvbapi.ind +dvbapi.ilg diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 83a5e5f7a..1158360e2 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -10,9 +10,6 @@ dvbapi.ps: dvbapi.dvi dvips $< dvbapi.dvi: dvbapi.bbl $(TEXS) - -latex dvbapi - -bibtex dvbapi - -makeindex dvbapi -latex dvbapi -latex dvbapi @@ -21,6 +18,9 @@ dvbapi.bbl: $(TEXS) -bibtex dvbapi -makeindex dvbapi +html: dvbapi.dvi + latex2html -address "LinuxTV DVB API" -long_titles 4 -split 3 dvbapi.tex + %.ps: %.fig ./fig2pstex $< @@ -28,3 +28,4 @@ clean: rm -f dvbapi.dvi rm -f *.aux *.bbl *.blg *.idx *.ilg *.ind *.log *.out *.toc rm -f *.pdf *.pst *.ps + rm -rf dvbapi diff --git a/dvb-spec/dvbapi/frontend.tex b/dvb-spec/dvbapi/frontend.tex index cbd646b93..9ae8a343e 100644 --- a/dvb-spec/dvbapi/frontend.tex +++ b/dvb-spec/dvbapi/frontend.tex @@ -263,7 +263,7 @@ typedef enum fe_code_rate { FEC_AUTO } fe_code_rate_t; \end{verbatim} -which correspond to error correction rates of $1/2$, $2/3$, etc., +which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto detection. \noindent -- cgit v1.2.3 From e09b3f6768a32a3ac714c8a44fa5ec64f986a41f Mon Sep 17 00:00:00 2001 From: js Date: Tue, 29 Jul 2003 14:05:03 -0300 Subject: ignore html output dir --- dvb-spec/dvbapi/.cvsignore | 1 + 1 file changed, 1 insertion(+) diff --git a/dvb-spec/dvbapi/.cvsignore b/dvb-spec/dvbapi/.cvsignore index 71db27b0a..89f9afcb7 100644 --- a/dvb-spec/dvbapi/.cvsignore +++ b/dvb-spec/dvbapi/.cvsignore @@ -11,3 +11,4 @@ dvbapi.out dvbapi.toc dvbapi.ind dvbapi.ilg +dvbapi -- cgit v1.2.3 From 8d72af7c80177c51843d0b0326d0a4a01099cb04 Mon Sep 17 00:00:00 2001 From: hunold Date: Fri, 23 Apr 2004 03:38:10 -0300 Subject: - standard dvips sends output to the default printer! use "-o $@" to send it to the destination file instead. (ever wondered who prints out the dvb api regularly on your laser printer? ;-) --- dvb-spec/dvbapi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 1158360e2..6d349c80d 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,10 +4,10 @@ TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf $< + dvipdf -f $< -o $@ dvbapi.ps: dvbapi.dvi - dvips $< + dvips -f $< -o $@ dvbapi.dvi: dvbapi.bbl $(TEXS) -latex dvbapi -- cgit v1.2.3 From 6236b63ea391dfb73f0ade028a1ea7889eb5319c Mon Sep 17 00:00:00 2001 From: hunold Date: Fri, 23 Apr 2004 08:55:10 -0300 Subject: - fix dvipdf --- dvb-spec/dvbapi/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvb-spec/dvbapi/Makefile b/dvb-spec/dvbapi/Makefile index 6d349c80d..e741df6da 100644 --- a/dvb-spec/dvbapi/Makefile +++ b/dvb-spec/dvbapi/Makefile @@ -4,7 +4,7 @@ TEXS= dvbapi.tex devices.tex video.tex audio.tex ca.tex net.tex frontend.tex \ demux.tex kdapi.tex examples.tex intro.tex title.tex dvbstb.ps dvbapi.pdf: dvbapi.dvi - dvipdf -f $< -o $@ + dvipdf $< $@ dvbapi.ps: dvbapi.dvi dvips -f $< -o $@ -- cgit v1.2.3 From cc7185f96b8e9132c28118367f6c84569939c37d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 16 Dec 2008 00:56:08 -0500 Subject: sms1xxx: enable rf switch on Hauppauge Tiger devices From: Michael Krufky Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 23 +++++++++++++++++++++-- linux/drivers/media/dvb/siano/sms-cards.h | 3 ++- linux/drivers/media/dvb/siano/smsdvb.c | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 79f5715c0..6c8faeb74 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -117,6 +117,7 @@ static struct sms_board sms_boards[] = { .type = SMS_NOVA_B0, .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = 29, + .rf_switch = 17, }, [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { .name = "Hauppauge WinTV MiniCard", @@ -199,8 +200,8 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff) case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: /* LNA */ - sms_set_gpio(coredev, - board->lna_ctrl, onoff ? 1 : 0); + if (!onoff) + sms_set_gpio(coredev, board->lna_ctrl, 0); break; } return 0; @@ -227,3 +228,21 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led) } return 0; } + +int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) +{ + int board_id = smscore_get_board_id(coredev); + struct sms_board *board = sms_get_board(board_id); + + sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled"); + + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + sms_set_gpio(coredev, + board->rf_switch, onoff ? 1 : 0); + return sms_set_gpio(coredev, + board->lna_ctrl, onoff ? 1 : 0); + } + return -EINVAL; +} diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 8e0fe9fd2..fe292aaea 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -40,7 +40,7 @@ struct sms_board { char *name, *fw[DEVICE_MODE_MAX]; /* gpios */ - int led_power, led_hi, led_lo, lna_ctrl; + int led_power, led_hi, led_lo, lna_ctrl, rf_switch; }; struct sms_board *sms_get_board(int id); @@ -52,6 +52,7 @@ int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_HI 2 int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); +int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); extern struct usb_device_id smsusb_id_table[]; diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index bbc87fe2e..a2efb402e 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -262,6 +262,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct SmsMsgHdr_ST Msg; u32 Data[3]; } Msg; + int ret; Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; Msg.Msg.msgDstId = HIF_TASK; @@ -285,6 +286,24 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, default: return -EINVAL; } + /* Disable LNA, if any. An error is returned if no LNA is present */ + ret = sms_board_lna_control(client->coredev, 0); + if (ret == 0) { + fe_status_t status; + + /* tune with LNA off at first */ + ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); + + smsdvb_read_status(fe, &status); + + if (status & FE_HAS_LOCK) + return ret; + + /* previous tune didnt lock - enable LNA and tune again */ + sms_board_lna_control(client->coredev, 1); + } + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); } -- cgit v1.2.3 From 5180a035b637308ddd873e58c46fdedbecb061f6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:15:47 -0400 Subject: sms1xxx: move definition of struct smsdvb_client_t into smsdvb.c From: Michael Krufky Nobody uses struct smsdvb_client_t other than smsdvb.c -- this does not need to be inside smscoreapi.h Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/smscoreapi.h | 21 --------------------- linux/drivers/media/dvb/siano/smsdvb.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 1ab277767..0469f1bd8 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -523,27 +523,6 @@ struct smscore_gpio_config { u8 outputdriving; }; -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_unc, fe_signal_strength; - - struct completion tune_done, stat_done; - - /* todo: save freq/band instead whole struct */ - struct dvb_frontend_parameters fe_params; - -}; - extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index a2efb402e..68f3f31bb 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -27,6 +27,26 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +struct smsdvb_client_t { + struct list_head entry; + + struct smscore_device_t *coredev; + struct smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_unc, fe_signal_strength; + + struct completion tune_done, stat_done; + + /* todo: save freq/band instead whole struct */ + struct dvb_frontend_parameters fe_params; +}; + static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; -- cgit v1.2.3 From c058193ee17449d1cb5e4685cab530b95bbb2b1b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 30 Aug 2008 23:44:04 -0400 Subject: sms1xxx: restore smsusb_driver.name to smsusb From: Uri Shkolnik The sms1xxx driver will be broken down into smaller modules, so the original name, smsusb, is more appropriate. Signed-off-by: Uri Shkolnik Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index fd191b0ef..7a04b34b0 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -479,7 +479,7 @@ static int smsusb_resume(struct usb_interface *intf) } static struct usb_driver smsusb_driver = { - .name = "sms1xxx", + .name = "smsusb", .probe = smsusb_probe, .disconnect = smsusb_disconnect, .id_table = smsusb_id_table, -- cgit v1.2.3 From ddc98ba47b865fb467edeb186cb64ae65d608e26 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:03:15 -0400 Subject: sms1xxx: move smsusb_id_table into smsusb.c From: Michael Krufky Move the usb_device_id table to the smsusb module in preparation for the sms1xxx module to be split into sub-modules. This will allow the smsusb driver to start up automatically upon insertion of the USB device. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 47 ------------------------------- linux/drivers/media/dvb/siano/sms-cards.h | 2 -- linux/drivers/media/dvb/siano/smsusb.c | 47 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 6c8faeb74..39f83faa2 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -19,53 +19,6 @@ #include "sms-cards.h" -struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS - { USB_DEVICE(0x187f, 0x0010), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0100), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0200), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, - { USB_DEVICE(0x187f, 0x0201), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, - { USB_DEVICE(0x187f, 0x0300), - .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif - { USB_DEVICE(0x2040, 0x1700), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, - { USB_DEVICE(0x2040, 0x1800), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, - { USB_DEVICE(0x2040, 0x1801), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, - { USB_DEVICE(0x2040, 0x2000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2009), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, - { USB_DEVICE(0x2040, 0x200a), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2011), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2019), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x5500), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5510), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5580), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5590), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - static struct sms_board sms_boards[] = { [SMS_BOARD_UNKNOWN] = { .name = "Unknown board", diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index fe292aaea..8f539a2e5 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -54,6 +54,4 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); -extern struct usb_device_id smsusb_id_table[]; - #endif /* __SMS_CARDS_H__ */ diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 7a04b34b0..19005c26b 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -478,6 +478,53 @@ static int smsusb_resume(struct usb_interface *intf) return 0; } +struct usb_device_id smsusb_id_table[] = { +#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS + { USB_DEVICE(0x187f, 0x0010), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0100), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0200), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, + { USB_DEVICE(0x187f, 0x0201), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, + { USB_DEVICE(0x187f, 0x0300), + .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, +#endif + { USB_DEVICE(0x2040, 0x1700), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, + { USB_DEVICE(0x2040, 0x1800), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, + { USB_DEVICE(0x2040, 0x1801), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, + { USB_DEVICE(0x2040, 0x2000), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2009), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, + { USB_DEVICE(0x2040, 0x200a), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2010), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2011), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x2019), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, + { USB_DEVICE(0x2040, 0x5500), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5510), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5520), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5530), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5580), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5590), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, smsusb_id_table); + static struct usb_driver smsusb_driver = { .name = "smsusb", .probe = smsusb_probe, -- cgit v1.2.3 From e8a3398295b9a981e3c19553f7908bebe95de079 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 30 Aug 2008 23:44:04 -0400 Subject: import changes from Siano From: Uri Shkolnik Import the following changes from Uri Shkolnik * Two-ways merge with Siano internal repository * Continuing with DVB sub-system separation * kconfig and makefile updates * Code cleanup This is a work-in-progress sync with Siano's internal repository. Some changes had to be altered or dropped in order not to break the build. This breaks normal operation for the current driver, but it is being committed now for tracking purposes. These changes introduce the following checkpatch.pl violations: ERROR: do not use C99 // comments 156: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1373: +//#ifdef DVB_CORE ERROR: do not use C99 // comments 157: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1374: +// smsdvb_unregister(); ERROR: do not use C99 // comments 158: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1375: +//#endif WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 163: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1380: +EXPORT_SYMBOL(smscore_onresponse); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 164: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1381: +EXPORT_SYMBOL(sms_get_board); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 165: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1382: +EXPORT_SYMBOL(sms_debug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 166: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1383: +EXPORT_SYMBOL(smscore_putbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 167: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1384: +EXPORT_SYMBOL(smscore_registry_getmode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 168: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1385: +EXPORT_SYMBOL(smscore_register_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 169: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1386: +EXPORT_SYMBOL(smscore_set_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 170: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1387: +EXPORT_SYMBOL(smscore_start_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 171: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1388: +EXPORT_SYMBOL(smsusb_id_table); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 172: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1389: +EXPORT_SYMBOL(smscore_unregister_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 173: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1390: +EXPORT_SYMBOL(smscore_getbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 174: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1391: +EXPORT_SYMBOL(smscore_get_device_mode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 175: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1392: +EXPORT_SYMBOL(smscore_register_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 176: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1393: +EXPORT_SYMBOL(smscore_unregister_hotplug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 177: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1394: +EXPORT_SYMBOL(smsclient_sendrequest); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 178: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1395: +EXPORT_SYMBOL(smscore_unregister_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 179: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1396: +EXPORT_SYMBOL(smscore_get_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 180: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1397: +EXPORT_SYMBOL(smscore_register_hotplug); WARNING: line over 80 characters 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); ERROR: "foo* bar" should be "foo *bar" 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); WARNING: line over 80 characters 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: "foo* bar" should be "foo *bar" 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: space required after that ',' (ctx:VxV) 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 489: FILE: linux/drivers/media/dvb/siano/smsusb.c:443: + printk(KERN_INFO"%s Entering status %d.\n", __FUNCTION__, msg.event); WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 501: FILE: linux/drivers/media/dvb/siano/smsusb.c:455: + printk(KERN_INFO "%s Entering.\n", __FUNCTION__); ERROR: space prohibited before that '++' (ctx:WxB) 505: FILE: linux/drivers/media/dvb/siano/smsusb.c:459: + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 517: FILE: linux/drivers/media/dvb/siano/smsusb.c:471: + __FUNCTION__, rc); total: 7 errors, 23 warnings, 524 lines checked Priority: normal Signed-off-by: Uri Shkolnik Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/Makefile | 4 +- linux/drivers/media/dvb/siano/smscoreapi.c | 121 +++++++++++++++++++++++++---- linux/drivers/media/dvb/siano/smscoreapi.h | 15 ++-- linux/drivers/media/dvb/siano/smsdvb.c | 23 +++--- linux/drivers/media/dvb/siano/smsusb.c | 10 ++- 5 files changed, 134 insertions(+), 39 deletions(-) diff --git a/linux/drivers/media/dvb/siano/Makefile b/linux/drivers/media/dvb/siano/Makefile index ee0737af9..bcf93f482 100644 --- a/linux/drivers/media/dvb/siano/Makefile +++ b/linux/drivers/media/dvb/siano/Makefile @@ -1,6 +1,8 @@ -sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o +sms1xxx-objs := smscoreapi.o sms-cards.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o +obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o +obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index b19dd9c7d..5d56f6295 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -3,7 +3,7 @@ * * This file contains implementation for the interface to sms core component * - * author: Anatoly Greenblat + * author: Uri Shkolnik * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -732,7 +732,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "none", "none"}, + {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, /*DABIP*/ {"none", "none", "none", "none"}, /*BDA*/ @@ -960,10 +960,6 @@ void smscore_onresponse(struct smscore_device_t *coredev, #endif /* If no client registered for type & id, * check for control client where type is not registered */ -#if 0 - if (!client) - client = smscore_find_client(coredev, 0, phdr->msgDstId); -#endif if (client) rc = client->onresponse_handler(client->context, cb); @@ -1337,12 +1333,67 @@ static int __init smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); - /* USB Register */ - rc = smsusb_register(); +#if 0 /* def SMS_CHAR_CLIENT */ + /* Char interface Register */ + rc = smschar_register(); + if (rc) { + sms_err("Error registering char device client.\n"); + goto smschar_error; + } +#endif +#if 0 /* def SMS_DVB_CLIENT */ /* DVB Register */ rc = smsdvb_register(); + if (rc) { + sms_err("Error registering DVB client.\n"); + goto smsdvb_error; + } +#endif + +#if 0 /* def SMS_NET_CLIENT */ + /* DVB Register */ + rc = smsnet_register(); + if (rc) { + sms_err("Error registering Network client.\n"); + goto smsnet_error; + } +#endif +#if 0 /* def SMS_USB_BUS_DRV */ + /* USB Register */ + rc = smsusb_register(); + if (rc) { + sms_err("Error registering USB bus driver.\n"); + goto sms_bus_drv_error; + } +#endif + +#if 0 /* def SMS_SPI_BUS_DRV */ + /* USB Register */ + rc = smsspi_register(); + if (rc) { + sms_err("Error registering spi bus driver.\n"); + goto sms_bus_drv_error; + } +#endif + + return rc; +#if 0 +sms_bus_drv_error: +#endif /* 0 */ +#if 0 /* def SMS_NET_CLIENT */ + smsnet_unregister(); +smsnet_error: +#endif +#if 0 /* def SMS_DVB_CLIENT */ + smsdvb_unregister(); +smsdvb_error: +#endif +#if 0 /* def SMS_CHAR_CLIENT */ + smschar_unregister(); +smschar_error: +#endif sms_debug("rc %d", rc); return rc; @@ -1350,6 +1401,30 @@ static int __init smscore_module_init(void) static void __exit smscore_module_exit(void) { +#if 0 /* def SMS_CHAR_CLIENT */ + /* Char interface UnRegister */ + smschar_unregister(); +#endif + +#if 0 /* def SMS_DVB_CLIENT */ + /* DVB UnRegister */ + smsdvb_unregister(); +#endif + +#if 0 /* def SMS_NET_CLIENT */ + /* NET UnRegister */ + smsnet_unregister(); +#endif + +#if 0 /* def SMS_USB_BUS_DRV */ + /* Unregister USB */ + smsusb_unregister(); +#endif + +#if 0 /* def SMS_SPI_BUS_DRV */ + /* Unregister SPI */ + smsspi_unregister(); +#endif kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { @@ -1373,18 +1448,34 @@ static void __exit smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); - /* DVB UnRegister */ - smsdvb_unregister(); - - /* Unregister USB */ - smsusb_unregister(); +//#ifdef DVB_CORE +// smsdvb_unregister(); +//#endif sms_debug(""); } +EXPORT_SYMBOL(smscore_onresponse); +EXPORT_SYMBOL(sms_get_board); +EXPORT_SYMBOL(sms_debug); +EXPORT_SYMBOL(smscore_putbuffer); +EXPORT_SYMBOL(smscore_registry_getmode); +EXPORT_SYMBOL(smscore_register_device); +EXPORT_SYMBOL(smscore_set_board_id); +EXPORT_SYMBOL(smscore_start_device); +EXPORT_SYMBOL(smscore_unregister_device); +EXPORT_SYMBOL(smscore_getbuffer); +EXPORT_SYMBOL(smscore_get_device_mode); +EXPORT_SYMBOL(smscore_register_client); +EXPORT_SYMBOL(smscore_unregister_hotplug); +EXPORT_SYMBOL(smsclient_sendrequest); +EXPORT_SYMBOL(smscore_unregister_client); +EXPORT_SYMBOL(smscore_get_board_id); +EXPORT_SYMBOL(smscore_register_hotplug); + module_init(smscore_module_init); module_exit(smscore_module_exit); -MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); -MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); +MODULE_DESCRIPTION("Siano MDTV Core module"); +MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 0469f1bd8..2134a2fb7 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -29,14 +29,14 @@ #include #include #include - +#include #include "compat.h" + #include "dmxdev.h" #include "dvbdev.h" #include "dvb_demux.h" #include "dvb_frontend.h" -#include #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) @@ -551,10 +551,12 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -#if 0 +#if 1 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); #endif extern @@ -571,13 +573,6 @@ int smscore_get_board_id(struct smscore_device_t *core); int smscore_led_state(struct smscore_device_t *core, int led); -/* smsdvb.c */ -int smsdvb_register(void); -void smsdvb_unregister(void); - -/* smsusb.c */ -int smsusb_register(void); -void smsusb_unregister(void); /* ------------------------------------------------------------------------ */ diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 68f3f31bb..c91f6f242 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -1,7 +1,7 @@ /* * Driver for the Siano SMS1xxx USB dongle * - * author: Anatoly Greenblat + * Author: Uri Shkolni * * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. * @@ -371,7 +371,7 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital SMS1xxx", + .name = "Siano Mobile Digital MDTV Receiver", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, @@ -413,16 +413,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, if (!arrival) return 0; - if (smscore_get_device_mode(coredev) != 4) { -#if 1 /* new siano drop (1.2.17) does this -- yuck */ + if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) { sms_err("SMS Device mode is not set for " "DVB operation."); return 0; -#else - rc = smscore_set_device_mode(coredev, 4); - if (rc < 0) - return rc; -#endif } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); @@ -521,7 +515,7 @@ adapter_error: return rc; } -int smsdvb_register(void) +int smsdvb_module_init(void) { int rc; @@ -535,7 +529,7 @@ int smsdvb_register(void) return rc; } -void smsdvb_unregister(void) +void smsdvb_module_exit(void) { smscore_unregister_hotplug(smsdvb_hotplug); @@ -547,3 +541,10 @@ void smsdvb_unregister(void) kmutex_unlock(&g_smsdvb_clientslock); } + +module_init(smsdvb_module_init); +module_exit(smsdvb_module_exit); + +MODULE_DESCRIPTION("SMS DVB subsystem adaptation module"); +MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 19005c26b..eb12b08df 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -535,7 +535,7 @@ static struct usb_driver smsusb_driver = { .resume = smsusb_resume, }; -int smsusb_register(void) +int smsusb_module_init(void) { int rc = usb_register(&smsusb_driver); if (rc) @@ -546,10 +546,16 @@ int smsusb_register(void) return rc; } -void smsusb_unregister(void) +void smsusb_module_exit(void) { sms_debug(""); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); } +module_init(smsusb_module_init); +module_exit(smsusb_module_exit); + +MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); +MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 319b736506ba8f695f973876299c72930508f68c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 15:08:15 -0400 Subject: sms1xxx: fix checkpatch.pl violations introduced by previous changeset From: Michael Krufky Fix checkpatch.pl violations introduced by previous changeset: ERROR: do not use C99 // comments 156: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1373: +//#ifdef DVB_CORE ERROR: do not use C99 // comments 157: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1374: +// smsdvb_unregister(); ERROR: do not use C99 // comments 158: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1375: +//#endif WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 163: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1380: +EXPORT_SYMBOL(smscore_onresponse); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 164: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1381: +EXPORT_SYMBOL(sms_get_board); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 165: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1382: +EXPORT_SYMBOL(sms_debug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 166: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1383: +EXPORT_SYMBOL(smscore_putbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 167: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1384: +EXPORT_SYMBOL(smscore_registry_getmode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 168: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1385: +EXPORT_SYMBOL(smscore_register_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 169: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1386: +EXPORT_SYMBOL(smscore_set_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 170: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1387: +EXPORT_SYMBOL(smscore_start_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 171: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1388: +EXPORT_SYMBOL(smsusb_id_table); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 172: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1389: +EXPORT_SYMBOL(smscore_unregister_device); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 173: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1390: +EXPORT_SYMBOL(smscore_getbuffer); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 174: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1391: +EXPORT_SYMBOL(smscore_get_device_mode); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 175: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1392: +EXPORT_SYMBOL(smscore_register_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 176: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1393: +EXPORT_SYMBOL(smscore_unregister_hotplug); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 177: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1394: +EXPORT_SYMBOL(smsclient_sendrequest); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 178: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1395: +EXPORT_SYMBOL(smscore_unregister_client); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 179: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1396: +EXPORT_SYMBOL(smscore_get_board_id); WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable 180: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:1397: +EXPORT_SYMBOL(smscore_register_hotplug); WARNING: line over 80 characters 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); ERROR: "foo* bar" should be "foo *bar" 391: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:398: +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); WARNING: line over 80 characters 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: "foo* bar" should be "foo *bar" 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ERROR: space required after that ',' (ctx:VxV) 392: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:399: +extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 489: FILE: linux/drivers/media/dvb/siano/smsusb.c:443: + printk(KERN_INFO"%s Entering status %d.\n", __FUNCTION__, msg.event); WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 501: FILE: linux/drivers/media/dvb/siano/smsusb.c:455: + printk(KERN_INFO "%s Entering.\n", __FUNCTION__); ERROR: space prohibited before that '++' (ctx:WxB) 505: FILE: linux/drivers/media/dvb/siano/smsusb.c:459: + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) ^ WARNING: __func__ should be used instead of gcc specific __FUNCTION__ 517: FILE: linux/drivers/media/dvb/siano/smsusb.c:471: + __FUNCTION__, rc); Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 5 ++++ linux/drivers/media/dvb/siano/smscoreapi.c | 41 +++++++++++++----------------- linux/drivers/media/dvb/siano/smscoreapi.h | 10 +++++--- linux/drivers/media/dvb/siano/smsdvb.c | 4 +++ linux/drivers/media/dvb/siano/smsusb.c | 13 ++++++---- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 39f83faa2..4fa86f5b7 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -86,6 +86,7 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } +EXPORT_SYMBOL(sms_get_board); static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { @@ -138,6 +139,7 @@ int sms_board_setup(struct smscore_device_t *coredev) } return 0; } +EXPORT_SYMBOL(sms_board_setup); int sms_board_power(struct smscore_device_t *coredev, int onoff) { @@ -159,6 +161,7 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff) } return 0; } +EXPORT_SYMBOL(sms_board_power); int sms_board_led_feedback(struct smscore_device_t *coredev, int led) { @@ -181,6 +184,7 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led) } return 0; } +EXPORT_SYMBOL(sms_board_led_feedback); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) { @@ -199,3 +203,4 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) } return -EINVAL; } +EXPORT_SYMBOL(sms_board_lna_control); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 5d56f6295..8cb36f540 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -34,8 +34,8 @@ #include "smscoreapi.h" #include "sms-cards.h" -int sms_debug; -module_param_named(debug, sms_debug, int, 0644); +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); struct smscore_device_notifyee_t { @@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_device_t *core, int led) core->led_state = led; return core->led_state; } +EXPORT_SYMBOL(smscore_set_board_id); int smscore_get_board_id(struct smscore_device_t *core) { return core->board_id; } +EXPORT_SYMBOL(smscore_get_board_id); struct smscore_registry_entry_t { struct list_head entry; @@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpath) return default_mode; } +EXPORT_SYMBOL(smscore_registry_getmode); static enum sms_device_type_st smscore_registry_gettype(char *devpath) { @@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t hotplug) return rc; } +EXPORT_SYMBOL(smscore_register_hotplug); /** * unregister a client callback that called when device plugged in/unplugged @@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } +EXPORT_SYMBOL(smscore_unregister_hotplug); static void smscore_notify_clients(struct smscore_device_t *coredev) { @@ -432,6 +437,7 @@ int smscore_register_device(struct smsdevice_params_t *params, return 0; } +EXPORT_SYMBOL(smscore_register_device); /** * sets initial device mode and notifies client hotplugs that device is ready @@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_device_t *coredev) return rc; } +EXPORT_SYMBOL(smscore_start_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, @@ -688,6 +695,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("device %p destroyed", coredev); } +EXPORT_SYMBOL(smscore_unregister_device); static int smscore_detect_mode(struct smscore_device_t *coredev) { @@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev) { return coredev->mode; } +EXPORT_SYMBOL(smscore_get_device_mode); /** * find client by response id & type within the clients list. @@ -1013,6 +1022,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, smscore_putbuffer(coredev, cb); } } +EXPORT_SYMBOL(smscore_onresponse); /** * return pointer to next free buffer descriptor from core pool @@ -1038,6 +1048,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) return cb; } +EXPORT_SYMBOL(smscore_getbuffer); /** * return buffer descriptor to a pool @@ -1052,6 +1063,7 @@ void smscore_putbuffer(struct smscore_device_t *coredev, { list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } +EXPORT_SYMBOL(smscore_putbuffer); static int smscore_validate_client(struct smscore_device_t *coredev, struct smscore_client_t *client, @@ -1131,6 +1143,7 @@ int smscore_register_client(struct smscore_device_t *coredev, return 0; } +EXPORT_SYMBOL(smscore_register_client); /** * frees smsclient object and all subclients associated with it @@ -1161,6 +1174,7 @@ void smscore_unregister_client(struct smscore_client_t *client) spin_unlock_irqrestore(&coredev->clientslock, flags); } +EXPORT_SYMBOL(smscore_unregister_client); /** * verifies that source id is not taken by another client, @@ -1200,6 +1214,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, return coredev->sendrequest_handler(coredev->context, buffer, size); } +EXPORT_SYMBOL(smsclient_sendrequest); #if 0 /** @@ -1448,31 +1463,9 @@ static void __exit smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); -//#ifdef DVB_CORE -// smsdvb_unregister(); -//#endif - sms_debug(""); } -EXPORT_SYMBOL(smscore_onresponse); -EXPORT_SYMBOL(sms_get_board); -EXPORT_SYMBOL(sms_debug); -EXPORT_SYMBOL(smscore_putbuffer); -EXPORT_SYMBOL(smscore_registry_getmode); -EXPORT_SYMBOL(smscore_register_device); -EXPORT_SYMBOL(smscore_set_board_id); -EXPORT_SYMBOL(smscore_start_device); -EXPORT_SYMBOL(smscore_unregister_device); -EXPORT_SYMBOL(smscore_getbuffer); -EXPORT_SYMBOL(smscore_get_device_mode); -EXPORT_SYMBOL(smscore_register_client); -EXPORT_SYMBOL(smscore_unregister_hotplug); -EXPORT_SYMBOL(smsclient_sendrequest); -EXPORT_SYMBOL(smscore_unregister_client); -EXPORT_SYMBOL(smscore_get_board_id); -EXPORT_SYMBOL(smscore_register_hotplug); - module_init(smscore_module_init); module_exit(smscore_module_exit); diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index 2134a2fb7..14dcbdd80 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -555,8 +555,10 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); -extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char* filename); -extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8* ufwbuf,int size); +extern int smscore_get_fw_filename(struct smscore_device_t *coredev, + int mode, char *filename); +extern int smscore_send_fw_file(struct smscore_device_t *coredev, + u8 *ufwbuf, int size); #endif extern @@ -576,7 +578,7 @@ int smscore_led_state(struct smscore_device_t *core, int led); /* ------------------------------------------------------------------------ */ -extern int sms_debug; +extern int sms_dbg; #define DBG_INFO 1 #define DBG_ADV 2 @@ -585,7 +587,7 @@ extern int sms_debug; printk(kern "%s: " fmt "\n", __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_debug & lvl) \ + if (sms_dbg & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index c91f6f242..f7f5569c1 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -50,6 +50,10 @@ struct smsdvb_client_t { static struct list_head g_smsdvb_clients; static struct mutex g_smsdvb_clientslock; +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index eb12b08df..e5c378e46 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -27,6 +27,10 @@ #include "smscoreapi.h" #include "sms-cards.h" +int sms_dbg; +module_param_named(debug, sms_dbg, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + #define USB1_BUFFER_SIZE 0x1000 #define USB2_BUFFER_SIZE 0x4000 @@ -440,7 +444,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) { struct smsusb_device_t *dev = (struct smsusb_device_t *)usb_get_intfdata(intf); - printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); + printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); smsusb_stop_streaming(dev); return 0; } @@ -452,7 +456,7 @@ static int smsusb_resume(struct usb_interface *intf) (struct smsusb_device_t *)usb_get_intfdata(intf); struct usb_device *udev = interface_to_usbdev(intf); - printk(KERN_INFO "%s Entering.\n", __func__); + printk(KERN_INFO "%s: Entering.\n", __func__); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); @@ -467,9 +471,8 @@ static int smsusb_resume(struct usb_interface *intf) intf->cur_altsetting->desc. bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO - "%s usb_set_interface failed, rc %d\n", - __func__, rc); + printk(KERN_INFO "%s usb_set_interface failed, " + "rc %d\n", __func__, rc); return rc; } } -- cgit v1.2.3 From 7d89270edcc221ddc81a48fb810066488b224b25 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 31 Aug 2008 16:39:58 -0400 Subject: sms1xxx: load smsdvb module automatically based on device id From: Michael Krufky The smsdvb module was separated from the core and usb code. This change loads smsdvb automatically for driver configurations that depend on it. Priority: normal Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/siano/sms-cards.c | 17 +++++++++++++++++ linux/drivers/media/dvb/siano/sms-cards.h | 2 ++ linux/drivers/media/dvb/siano/smsusb.c | 1 + 3 files changed, 20 insertions(+) diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index 4fa86f5b7..44df81a81 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -204,3 +204,20 @@ int sms_board_lna_control(struct smscore_device_t *coredev, int onoff) return -EINVAL; } EXPORT_SYMBOL(sms_board_lna_control); + +int sms_board_load_modules(int id) +{ + switch (id) { + case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT: + case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A: + case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B: + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + request_module("smsdvb"); + break; + default: + /* do nothing */ + break; + } + return 0; +} +EXPORT_SYMBOL(sms_board_load_modules); diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 8f539a2e5..64d74c59c 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -54,4 +54,6 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led); int sms_board_power(struct smscore_device_t *coredev, int onoff); int sms_board_lna_control(struct smscore_device_t *coredev, int onoff); +extern int sms_board_load_modules(int id); + #endif /* __SMS_CARDS_H__ */ diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index e5c378e46..a2da36122 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -432,6 +432,7 @@ static int smsusb_probe(struct usb_interface *intf, rc = smsusb_init_device(intf, id->driver_info); sms_info("rc %d", rc); + sms_board_load_modules(id->driver_info); return rc; } -- cgit v1.2.3 From 5c190e9dc01651545a2cb6e709953984ebae4be2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 12 Jan 2009 10:17:43 +0100 Subject: tvp514x: make the module aware of rich people From: Sebastian Andrzej Siewior because they might design two of those chips on a single board. You never know. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvp514x.c | 106 ++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/linux/drivers/media/video/tvp514x.c b/linux/drivers/media/video/tvp514x.c index 5f4cbc2b2..f0b2b8ed2 100644 --- a/linux/drivers/media/video/tvp514x.c +++ b/linux/drivers/media/video/tvp514x.c @@ -86,9 +86,12 @@ struct tvp514x_std_info { struct v4l2_standard standard; }; +static struct tvp514x_reg tvp514x_reg_list_default[0x40]; /** - * struct tvp514x_decoded - TVP5146/47 decoder object + * struct tvp514x_decoder - TVP5146/47 decoder object * @v4l2_int_device: Slave handle + * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device + * @tvp514x_regs: copy of hw's regs with preset values. * @pdata: Board specific * @client: I2C client data * @id: Entry from I2C table @@ -103,7 +106,9 @@ struct tvp514x_std_info { * @route: input and output routing at chip level */ struct tvp514x_decoder { - struct v4l2_int_device *v4l2_int_device; + struct v4l2_int_device v4l2_int_device; + struct v4l2_int_slave tvp514x_slave; + struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; const struct tvp514x_platform_data *pdata; struct i2c_client *client; @@ -124,7 +129,7 @@ struct tvp514x_decoder { }; /* TVP514x default register values */ -static struct tvp514x_reg tvp514x_reg_list[] = { +static struct tvp514x_reg tvp514x_reg_list_default[] = { {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ @@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder) /* common register initialization */ err = - tvp514x_write_regs(decoder->client, tvp514x_reg_list); + tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); if (err) return err; @@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) return err; decoder->current_std = i; - tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std; + decoder->tvp514x_regs[REG_VIDEO_STD].val = + decoder->std_list[i].video_std; v4l_dbg(1, debug, decoder->client, "Standard set to: %s", decoder->std_list[i].standard.name); @@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s, if (err) return err; - tvp514x_reg_list[REG_INPUT_SEL].val = input_sel; - tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel; + decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel; + decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel; /* Clear status */ msleep(LOCK_RETRY_DELAY); @@ -779,16 +785,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val; + ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val; break; case V4L2_CID_CONTRAST: - ctrl->value = tvp514x_reg_list[REG_CONTRAST].val; + ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val; break; case V4L2_CID_SATURATION: - ctrl->value = tvp514x_reg_list[REG_SATURATION].val; + ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val; break; case V4L2_CID_HUE: - ctrl->value = tvp514x_reg_list[REG_HUE].val; + ctrl->value = decoder->tvp514x_regs[REG_HUE].val; if (ctrl->value == 0x7F) ctrl->value = 180; else if (ctrl->value == 0x80) @@ -798,7 +804,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) break; case V4L2_CID_AUTOGAIN: - ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val; + ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val; if ((ctrl->value & 0x3) == 3) ctrl->value = 1; else @@ -848,7 +854,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_BRIGHTNESS].val = value; + decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; break; case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 255) { @@ -861,7 +867,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_CONTRAST].val = value; + decoder->tvp514x_regs[REG_CONTRAST].val = value; break; case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 255) { @@ -874,7 +880,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_SATURATION].val = value; + decoder->tvp514x_regs[REG_SATURATION].val = value; break; case V4L2_CID_HUE: if (value == 180) @@ -893,7 +899,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_HUE].val = value; + decoder->tvp514x_regs[REG_HUE].val = value; break; case V4L2_CID_AUTOGAIN: if (value == 1) @@ -910,7 +916,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) value); if (err) return err; - tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value; + decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; break; default: v4l_err(decoder->client, @@ -1275,7 +1281,7 @@ static int ioctl_init(struct v4l2_int_device *s) struct tvp514x_decoder *decoder = s->priv; /* Set default standard to auto */ - tvp514x_reg_list[REG_VIDEO_STD].val = + decoder->tvp514x_regs[REG_VIDEO_STD].val = VIDEO_STD_AUTO_SWITCH_BIT; return tvp514x_configure(decoder); @@ -1344,11 +1350,6 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { (v4l2_int_ioctl_func *) ioctl_s_routing}, }; -static struct v4l2_int_slave tvp514x_slave = { - .ioctls = tvp514x_ioctl_desc, - .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), -}; - static struct tvp514x_decoder tvp514x_dev = { .state = STATE_NOT_DETECTED, @@ -1369,17 +1370,15 @@ static struct tvp514x_decoder tvp514x_dev = { .current_std = STD_NTSC_MJ, .std_list = tvp514x_std_list, .num_stds = ARRAY_SIZE(tvp514x_std_list), - -}; - -static struct v4l2_int_device tvp514x_int_device = { - .module = THIS_MODULE, - .name = TVP514X_MODULE_NAME, - .priv = &tvp514x_dev, - .type = v4l2_int_type_slave, - .u = { - .slave = &tvp514x_slave, - }, + .v4l2_int_device = { + .module = THIS_MODULE, + .name = TVP514X_MODULE_NAME, + .type = v4l2_int_type_slave, + }, + .tvp514x_slave = { + .ioctls = tvp514x_ioctl_desc, + .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc), + }, }; /** @@ -1392,26 +1391,37 @@ static struct v4l2_int_device tvp514x_int_device = { static int tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct tvp514x_decoder *decoder = &tvp514x_dev; + struct tvp514x_decoder *decoder; int err; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - decoder->pdata = client->dev.platform_data; - if (!decoder->pdata) { + decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) + return -ENOMEM; + + if (!client->dev.platform_data) { v4l_err(client, "No platform data!!\n"); - return -ENODEV; + err = -ENODEV; + goto out_free; } + + *decoder = tvp514x_dev; + decoder->v4l2_int_device.priv = decoder; + decoder->pdata = client->dev.platform_data; + decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave; + memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, + sizeof(tvp514x_reg_list_default)); /* * Fetch platform specific data, and configure the * tvp514x_reg_list[] accordingly. Since this is one * time configuration, no need to preserve. */ - tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |= + decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= (decoder->pdata->clk_polarity << 1); - tvp514x_reg_list[REG_SYNC_CONTROL].val |= + decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= ((decoder->pdata->hs_polarity << 2) | (decoder->pdata->vs_polarity << 3)); /* @@ -1419,23 +1429,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) */ decoder->id = (struct i2c_device_id *)id; /* Attach to Master */ - strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master); - decoder->v4l2_int_device = &tvp514x_int_device; + strcpy(decoder->v4l2_int_device.u.slave->attach_to, + decoder->pdata->master); decoder->client = client; i2c_set_clientdata(client, decoder); /* Register with V4L2 layer as slave device */ - err = v4l2_int_device_register(decoder->v4l2_int_device); + err = v4l2_int_device_register(&decoder->v4l2_int_device); if (err) { i2c_set_clientdata(client, NULL); v4l_err(client, "Unable to register to v4l2. Err[%d]\n", err); + goto out_free; } else v4l_info(client, "Registered to v4l2 master %s!!\n", decoder->pdata->master); - return 0; + +out_free: + kfree(decoder); + return err; } /** @@ -1452,9 +1466,9 @@ static int __exit tvp514x_remove(struct i2c_client *client) if (!client->adapter) return -ENODEV; /* our client isn't attached */ - v4l2_int_device_unregister(decoder->v4l2_int_device); + v4l2_int_device_unregister(&decoder->v4l2_int_device); i2c_set_clientdata(client, NULL); - + kfree(decoder); return 0; } /* -- cgit v1.2.3 From 03bcc8695fb4334e4e30d03a9dc0867361615c1a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 15:27:44 -0300 Subject: Revert changeset aa3e5cc1d833 From: Mauro Carvalho Chehab On Mon, 02 Feb 2009, Hartmut wrote: This change set is wrong. The affected functions cannot be called from an interrupt context, because they may process large buffers. In this case, interrupts are disabled for a long time. Functions, like dvb_dmx_swfilter_packets(), could be called only from a tasklet. This change set does hide some strong design bugs in dm1105.c and au0828-dvb.c. Please revert this change set and do fix the bugs in dm1105.c and au0828-dvb.c (and other files). On Sun, 15 Feb 2009, Oliver Endriss wrote: This changeset _must_ be reverted! It breaks all kernels since 2.6.27 for applications which use DVB and require a low interrupt latency. It is a very bad idea to call the demuxer to process data buffers with interrupts disabled! On Mon, 16 Feb 2009, Trent Piepho wrote: I agree, this is bad. The demuxer is far too much work to be done with IRQs off. IMHO, even doing it under a spin-lock is excessive. It should be a mutex. Drivers should use a work-queue to feed the demuxer. Thank you for testing this changeset and discovering the issues on it. Priority: high CC: Trent Piepho CC: Hartmut CC: Oliver Endriss CC: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dmxdev.c | 16 +++++++--------- linux/drivers/media/dvb/dvb-core/dvb_demux.c | 16 ++++++---------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index cc143929a..c35fbb8d8 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, enum dmx_success success) { struct dmxdev_filter *dmxdevfilter = filter->priv; - unsigned long flags; int ret; if (dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } del_timer(&dmxdevfilter->timer); @@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; - unsigned long flags; int ret; - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); + spin_lock(&dmxdevfilter->dev->lock); if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); return 0; } @@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, else buffer = &dmxdevfilter->dev->dvr_buffer; if (buffer->error) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } @@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, dvb_ringbuffer_flush(buffer); buffer->error = ret; } - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); + spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index a2c1fd5d2..e2eca0b1f 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; - - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); while (count--) { if (buf[0] == 0x47) @@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, buf += 188; } - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_packets); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter); void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) { - unsigned long flags; int p = 0, i, j; u8 tmppack[188]; - spin_lock_irqsave(&demux->lock, flags); + spin_lock(&demux->lock); if (demux->tsbufp) { i = demux->tsbufp; @@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) } bailout: - spin_unlock_irqrestore(&demux->lock, flags); + spin_unlock(&demux->lock); } EXPORT_SYMBOL(dvb_dmx_swfilter_204); -- cgit v1.2.3 From 6d5737990907617f67f5d8a9633ed16c8714171d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 15:54:29 -0300 Subject: v4l2-framework.txt: Whitespace clenups From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index a6005257a..48cdf8624 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -531,11 +531,11 @@ struct v4l2_device *v4l2_dev = vdev->v4l2_dev; video buffer helper functions ----------------------------- -The v4l2 core API provides a standard method for dealing with video -buffers. Those methods allow a driver to implement read(), mmap() and +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and overlay() on a consistent way. -There are currently methods for using video buffers on devices that +There are currently methods for using video buffers on devices that supports DMA with scatter/gather method (videobuf-dma-sg), DMA with linear access (videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers (videobuf-vmalloc). @@ -544,50 +544,50 @@ Any driver using videobuf should provide operations (callbacks) for four handlers: ops->buf_setup - calculates the size of the video buffers and avoid they - to waste more than some maximum limit of RAM; + to waste more than some maximum limit of RAM; ops->buf_prepare - fills the video buffer structs and calls videobuf_iolock() to alloc and prepare mmaped memory; ops->buf_queue - advices the driver that another buffer were - requested (by read() or by QBUF); + requested (by read() or by QBUF); ops->buf_release - frees any buffer that were allocated. In order to use it, the driver need to have a code (generally called at interrupt context) that will properly handle the buffer request lists, announcing that a new buffer were filled. -The irq handling code should handle the videobuf task lists, in order -to advice videobuf that a new frame were filled, in order to honor to a +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a request. The code is generally like this one: - if (list_empty(&dma_q->active)) + if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); - if (!waitqueue_active(&buf->vb.done)) + if (!waitqueue_active(&buf->vb.done)) return; /* Some logic to handle the buf may be needed here */ - list_del(&buf->vb.queue); - do_gettimeofday(&buf->vb.ts); - wake_up(&buf->vb.done); + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); -Those are the videobuffer functions used on drivers, implemented on +Those are the videobuffer functions used on drivers, implemented on videobuf-core: - Videobuf init functions videobuf_queue_sg_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that uses DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA Scatter/Gather buffers. videobuf_queue_dma_contig_init - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that need DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA contiguous buffers. videobuf_queue_vmalloc_init() - Initializes the videobuf infrastructure. This function should be + Initializes the videobuf infrastructure. This function should be called before any other videobuf function on USB (and other drivers) that need a vmalloced type of videobuf. @@ -607,12 +607,12 @@ videobuf-core: Stops video handling, ends mmap and frees mmap and other buffers. - V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: - videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). - V4L1 api function (corresponds to VIDIOCMBUF ioctl): videobuf_cgmbuf() - This function is used to provide backward compatibility with V4L1 + This function is used to provide backward compatibility with V4L1 API. - Some help functions for read()/poll() operations: @@ -623,7 +623,7 @@ videobuf-core: videobuf_poll_stream() polling help function -The better way to understand it is to take a look at vivi driver. One -of the main reasons for vivi is to be a videobuf usage example. the -vivi_thread_tick() does the task that the IRQ callback would do on PCI +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). -- cgit v1.2.3 From 7c429cdbe8e7fa93d0c24d10749fe2a2bdd5e524 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 15 Jan 2009 21:58:55 +0900 Subject: saa7134: fix Avermedia E506R composite input From: Tim Farrington Make correction to composite input plus svideo input to Avermedia E506R Signed-off-by: Tim Farrington Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-cards.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index 01cc9543f..e565d437b 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -4362,13 +4362,13 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .tv = 1, }, { - .name = name_comp, - .vmux = 0, + .name = name_comp1, + .vmux = 3, .amux = LINE1, }, { .name = name_svideo, .vmux = 8, - .amux = LINE1, + .amux = LINE2, } }, .radio = { .name = name_radio, -- cgit v1.2.3 From a341145919a0d3bf91e657926a06bebca10a94ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 20 Jan 2009 15:34:43 -0600 Subject: V4L2: Add COLORFX user control From: Sergio Aguirre This is a common feature on many cameras. the options are: Default colors, B & W, Sepia Signed-off-by: Sergio Aguirre Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/videodev2.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index e5be28ac6..6969c3086 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -880,8 +880,15 @@ enum v4l2_power_line_frequency { #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, +}; + /* last CID + 1 */ -#define V4L2_CID_LASTP1 (V4L2_CID_BASE+31) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+32) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -- cgit v1.2.3 -- cgit v1.2.3 From 398b32c3c4e7f3675a104de6c037024e7803bf08 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Feb 2009 21:38:08 -0300 Subject: Add dvb API docs at hgignore From: Mauro Carvalho Chehab In order to compile dvb API, it is needed to have tetex-latex and Xfig packages. This patch adds the generated docs at hgignore. Signed-off-by: Mauro Carvalho Chehab --- .hgignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.hgignore b/.hgignore index cc9eea282..c47aa55bb 100644 --- a/.hgignore +++ b/.hgignore @@ -24,6 +24,7 @@ v4l/oss v4l/Modules.symvers$ v4l/Module.symvers$ v4l/modules.order$ +v4l/Module.markers$ v4l/config-compat.h$ v4l/.myconfig$ v4l/.snapshot$ @@ -73,3 +74,14 @@ v4l/firmware/dabusb/firmware.fw v4l/firmware/ihex2fw v4l/firmware/ttusb-budget/dspbootcode.bin v4l/firmware/vicam/firmware.fw +dvb-spec/dvbapi/dvbapi.aux +dvb-spec/dvbapi/dvbapi.bbl +dvb-spec/dvbapi/dvbapi.blg +dvb-spec/dvbapi/dvbapi.dvi +dvb-spec/dvbapi/dvbapi.log +dvb-spec/dvbapi/dvbapi.out +dvb-spec/dvbapi/dvbapi.pdf +dvb-spec/dvbapi/dvbapi.ps +dvb-spec/dvbapi/dvbapi.toc +dvb-spec/dvbapi/dvbstb.ps +dvb-spec/dvbapi/dvbstb.pst -- cgit v1.2.3 From fb3a9246d433dda2f7ace056abb2574ed3a9da42 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 27 Jan 2009 06:02:41 +0000 Subject: tw9910: color format check is added on set_fmt From: Kuninori Morimoto Signed-off-by: Kuninori Morimoto Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tw9910.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/linux/drivers/media/video/tw9910.c b/linux/drivers/media/video/tw9910.c index c670b23a1..4593cdea7 100644 --- a/linux/drivers/media/video/tw9910.c +++ b/linux/drivers/media/video/tw9910.c @@ -645,6 +645,19 @@ static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt, struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); int ret = -EINVAL; u8 val; + int i; + + /* + * check color format + */ + for (i = 0 ; i < ARRAY_SIZE(tw9910_color_fmt) ; i++) { + if (pixfmt == tw9910_color_fmt[i].fourcc) { + ret = 0; + break; + } + } + if (ret < 0) + goto tw9910_set_fmt_error; /* * select suitable norm -- cgit v1.2.3 From 13e2e59a82953d5b837a02c7115ae6fad1c0f1d4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 23:58:33 +0100 Subject: ivtv: fix decoder crash regression From: Hans Verkuil The video_ioctl2 conversion of ivtv in kernel 2.6.27 introduced a bug causing decoder commands to crash. The decoder commands should have been handled from the video_ioctl2 default handler, ensuring correct mapping of the argument between user and kernel space. Unfortunately they ended up before the video_ioctl2 call, causing random crashes. Thanks to hannes@linus.priv.at for testing and helping me track down the cause! Priority: high Signed-off-by: Hans Verkuil --- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index aa55a3cc4..d7a708ad3 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1752,6 +1752,18 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) break; } + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(file, cmd, (void *)arg); + default: return -EINVAL; } @@ -1794,18 +1806,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(filp, cmd, (void *)arg); - default: break; } -- cgit v1.2.3 From 337e145d4f292cbeeb8dd95c70ecef641230a657 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 16 Feb 2009 08:25:32 +0100 Subject: ivtv: fix regression in get sliced vbi format From: Hans Verkuil The new v4l2_subdev_call used s_fmt instead of g_fmt. Priority: high Signed-off-by: Hans Verkuil Thanks-to: Andy Walls --- linux/drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index d7a708ad3..9a0424298 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -391,7 +391,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo return 0; } - v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); + v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); vbifmt->service_set = ivtv_get_service_set(vbifmt); return 0; } -- cgit v1.2.3 From fa940b36a68186b4e5b77a5afb929f68603b52bf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 21:06:49 +0000 Subject: V4L: Storage class should be before const qualifier From: Tobias Klauser The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser CC: Jean-Francois Moine CC: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/gspca/t613.c | 2 +- linux/drivers/media/video/tcm825x.c | 22 +++++++++++----------- linux/drivers/media/video/tcm825x.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index adec0767c..c04836ed2 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -272,7 +272,7 @@ struct additional_sensor_data { const u8 stream[4]; }; -const static struct additional_sensor_data sensor_data[] = { +static const struct additional_sensor_data sensor_data[] = { { /* OM6802 */ .data1 = {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06, diff --git a/linux/drivers/media/video/tcm825x.c b/linux/drivers/media/video/tcm825x.c index 2f823f27a..559ade821 100644 --- a/linux/drivers/media/video/tcm825x.c +++ b/linux/drivers/media/video/tcm825x.c @@ -50,7 +50,7 @@ struct tcm825x_sensor { }; /* list of image formats supported by TCM825X sensor */ -const static struct v4l2_fmtdesc tcm825x_formats[] = { +static const struct v4l2_fmtdesc tcm825x_formats[] = { { .description = "YUYV (YUV 4:2:2), packed", .pixelformat = V4L2_PIX_FMT_UYVY, @@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x_formats[] = { * TCM825X register configuration for all combinations of pixel format and * image size */ -const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; -const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; -const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; -const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; -const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; -const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; +static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ }; +static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ }; +static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ }; +static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ }; +static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ }; +static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ }; -const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; -const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; +static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT }; +static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT }; /* Our own specific controls */ #define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE @@ -248,10 +248,10 @@ static struct vcontrol { }; -const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = +static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] = { &subqcif, &qqvga, &qcif, &qvga, &cif, &vga }; -const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = +static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] = { &yuv422, &rgb565 }; /* diff --git a/linux/drivers/media/video/tcm825x.h b/linux/drivers/media/video/tcm825x.h index 770ebacfa..5b7e69682 100644 --- a/linux/drivers/media/video/tcm825x.h +++ b/linux/drivers/media/video/tcm825x.h @@ -188,7 +188,7 @@ struct tcm825x_platform_data { /* Array of image sizes supported by TCM825X. These must be ordered from * smallest image size to largest. */ -const static struct capture_size tcm825x_sizes[] = { +static const struct capture_size tcm825x_sizes[] = { { 128, 96 }, /* subQCIF */ { 160, 120 }, /* QQVGA */ { 176, 144 }, /* QCIF */ -- cgit v1.2.3 From ae420af84b9a311c94b8c41557e700a13fe2f520 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 9 Feb 2009 21:57:06 +0000 Subject: tvp514x: try_count reaches 0, not -1 From: Roel Kluin with while (try_count-- > 0) { ... } try_count reaches 0, not -1. Signed-off-by: Roel Kluin CC: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvp514x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/tvp514x.c b/linux/drivers/media/video/tvp514x.c index 8e23aa53c..5f4cbc2b2 100644 --- a/linux/drivers/media/video/tvp514x.c +++ b/linux/drivers/media/video/tvp514x.c @@ -686,7 +686,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s, break; /* Input detected */ } - if ((current_std == STD_INVALID) || (try_count < 0)) + if ((current_std == STD_INVALID) || (try_count <= 0)) return -EINVAL; decoder->current_std = current_std; -- cgit v1.2.3 From de8d080a697cf4a8c8c997f7f3b76ea1f49a51bd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 11 Feb 2009 09:34:11 +0000 Subject: V4L/DVB: calibration still successful at 10 From: Roel Kluin With while (i++ < 10) { ... } i can reach 11, so callibration still succeeds at i == 10. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/mt2060.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/common/tuners/mt2060.c b/linux/drivers/media/common/tuners/mt2060.c index d1962bb24..1f1fe90cb 100644 --- a/linux/drivers/media/common/tuners/mt2060.c +++ b/linux/drivers/media/common/tuners/mt2060.c @@ -285,7 +285,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv) while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0) msleep(20); - if (i < 10) { + if (i <= 10) { mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :) dprintk("calibration was successful: %d", (int)priv->fmfreq); } else -- cgit v1.2.3 From e07511c36db32bec6bd0fde4e996001b6e5709e0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 12 Feb 2009 18:19:24 +0000 Subject: zoran: fix printk format From: Randy Dunlap Fix printk format warning: drivers/media/video/zoran/zoran_driver.c:345: warning: format '%lx' expects type 'long unsigned int', but argument 5 has type 'phys_addr_t' Signed-off-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/zoran/zoran_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 2609f54d7..798745c0a 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -356,9 +356,9 @@ v4l_fbuffer_alloc (struct file *file) SetPageReserved(MAP_NR(mem + off)); dprintk(4, KERN_INFO - "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", ZR_DEVNAME(zr), i, (unsigned long) mem, - virt_to_bus(mem)); + (unsigned long long)virt_to_bus(mem)); } else { #if defined(CONFIG_BIGPHYS_AREA) /* Use bigphysarea_alloc_pages */ -- cgit v1.2.3 From d5e10736ed6dd53b02e973042f407a3316c28533 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 12 Feb 2009 06:43:11 +0000 Subject: Added support for AVerMedia Cardbus Hybrid remote control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Oldřich Jedlička Added support for I2C device at address 0x40 and subaddress 0x0d/0x0b that provides remote control key reading support for AVerMedia Cardbus Hybrid card, possibly for other AVerMedia Cardbus cards. The I2C address 0x40 doesn't like the SAA7134's 0xfd quirk, so it was disabled. Signed-off-by: Oldřich Jedlička [mchehab@redhat.com: CodingStyle fixes] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/ir-keymaps.c | 59 +++++++++++++++++++++ linux/drivers/media/video/ir-kbd-i2c.c | 64 +++++++++++++++++++++++ linux/drivers/media/video/saa7134/saa7134-cards.c | 5 ++ linux/drivers/media/video/saa7134/saa7134-i2c.c | 2 +- linux/include/media/ir-common.h | 1 + 5 files changed, 130 insertions(+), 1 deletion(-) diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 03fabc86c..827e65582 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -154,6 +154,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { }; EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); +/* Oldrich Jedlicka */ +IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { + [0x00] = KEY_POWER, + [0x01] = KEY_TUNER, /* TV/FM */ + [0x03] = KEY_TEXT, /* Teletext */ + [0x04] = KEY_EPG, + [0x05] = KEY_1, + [0x06] = KEY_2, + [0x07] = KEY_3, + [0x08] = KEY_AUDIO, + [0x09] = KEY_4, + [0x0a] = KEY_5, + [0x0b] = KEY_6, + [0x0c] = KEY_ZOOM, /* Full screen */ + [0x0d] = KEY_7, + [0x0e] = KEY_8, + [0x0f] = KEY_9, + [0x10] = KEY_PAGEUP, /* 16-CH PREV */ + [0x11] = KEY_0, + [0x12] = KEY_INFO, + [0x13] = KEY_AGAIN, /* CH RTN - channel return */ + [0x14] = KEY_MUTE, + [0x15] = KEY_EDIT, /* Autoscan */ + [0x17] = KEY_SAVE, /* Screenshot */ + [0x18] = KEY_PLAYPAUSE, + [0x19] = KEY_RECORD, + [0x1a] = KEY_PLAY, + [0x1b] = KEY_STOP, + [0x1c] = KEY_FASTFORWARD, + [0x1d] = KEY_REWIND, + [0x1e] = KEY_VOLUMEDOWN, + [0x1f] = KEY_VOLUMEUP, + [0x22] = KEY_SLEEP, /* Sleep */ + [0x23] = KEY_ZOOM, /* Aspect */ + [0x26] = KEY_SCREEN, /* Pos */ + [0x27] = KEY_ANGLE, /* Size */ + [0x28] = KEY_SELECT, /* Select */ + [0x29] = KEY_BLUE, /* Blue/Picture */ + [0x2a] = KEY_BACKSPACE, /* Back */ + [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */ + [0x2c] = KEY_DOWN, + [0x2e] = KEY_DOT, + [0x2f] = KEY_TV, /* Live TV */ + [0x32] = KEY_LEFT, + [0x33] = KEY_CLEAR, /* Clear */ + [0x35] = KEY_RED, /* Red/TV */ + [0x36] = KEY_UP, + [0x37] = KEY_HOME, /* Home */ + [0x39] = KEY_GREEN, /* Green/Video */ + [0x3d] = KEY_YELLOW, /* Yellow/Music */ + [0x3e] = KEY_OK, /* Ok */ + [0x3f] = KEY_RIGHT, + [0x40] = KEY_NEXT, /* Next */ + [0x41] = KEY_PREVIOUS, /* Previous */ + [0x42] = KEY_CHANNELDOWN, /* Channel down */ + [0x43] = KEY_CHANNELUP /* Channel up */ +}; +EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); + /* Attila Kondoros */ IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index a67bed7d7..a99aea49a 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -16,6 +16,8 @@ * Henry Wong * Mark Schultz * Brian Rogers + * modified for AVerMedia Cardbus by + * Oldrich Jedlicka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -217,6 +219,46 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +static int get_key_avermedia_cardbus(struct IR_i2c *ir, + u32 *ir_key, u32 *ir_raw) +{ + unsigned char subaddr, key, keygroup; + struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, + .buf = &subaddr, .len = 1}, + { .addr = ir->c.addr, .flags = I2C_M_RD, + .buf = &key, .len = 1} }; + subaddr = 0x0d; + if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { + dprintk(1, "read error\n"); + return -EIO; + } + + if (key == 0xff) + return 0; + + subaddr = 0x0b; + msg[1].buf = &keygroup; + if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { + dprintk(1, "read error\n"); + return -EIO; + } + + if (keygroup == 0xff) + return 0; + + dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup); + if (keygroup < 2 || keygroup > 3) { + /* Only a warning */ + dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n", + keygroup, key); + } + key |= (keygroup & 1) << 6; + + *ir_key = key; + *ir_raw = key; + return 1; +} + /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR_i2c *ir) @@ -369,6 +411,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir_type = IR_TYPE_OTHER; } break; + case 0x40: + name = "AVerMedia Cardbus remote"; + ir->get_key = get_key_avermedia_cardbus; + ir_type = IR_TYPE_OTHER; + ir_codes = ir_codes_avermedia_cardbus; + break; default: /* shouldn't happen */ printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); @@ -537,6 +585,22 @@ static int ir_probe(struct i2c_adapter *adap) ir_attach(adap, msg.addr, 0, 0); } + /* Special case for AVerMedia Cardbus remote */ + if (adap->id == I2C_HW_SAA7134) { + unsigned char subaddr, data; + struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, + .buf = &subaddr, .len = 1}, + { .addr = 0x40, .flags = I2C_M_RD, + .buf = &data, .len = 1} }; + subaddr = 0x0d; + rc = i2c_transfer(adap, msg, 2); + dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", + msg[0].addr, subaddr, adap->name, + (2 == rc) ? "yes" : "no"); + if (2 == rc) + ir_attach(adap, msg[0].addr, 0, 0); + } + return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index e565d437b..9db045cf5 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -6120,6 +6120,11 @@ int saa7134_board_init1(struct saa7134_dev *dev) msleep(10); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + saa7134_set_gpio(dev, 23, 0); + msleep(10); + saa7134_set_gpio(dev, 23, 1); + dev->has_remote = SAA7134_REMOTE_I2C; + break; case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index 4b4d5ef76..b77ccb5a0 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -260,7 +260,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, addr = msgs[i].addr << 1; if (msgs[i].flags & I2C_M_RD) addr |= 1; - if (i > 0 && msgs[i].flags & I2C_M_RD) { + if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { /* workaround for a saa7134 i2c bug * needed to talk to the mt352 demux * thanks to pinnacle for the hint */ diff --git a/linux/include/media/ir-common.h b/linux/include/media/ir-common.h index 31e62abb5..135e02270 100644 --- a/linux/include/media/ir-common.h +++ b/linux/include/media/ir-common.h @@ -111,6 +111,7 @@ extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE]; -- cgit v1.2.3 From e63d9cf5d9e5f269f241490e6e190e8f4d92a5d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 1 Feb 2009 22:31:54 +0000 Subject: DAB: fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Márton Németh Fix typo in "DAB adapters" section in Kconfig. Signed-off-by: Márton Németh Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 93ea201f4..223c36ede 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig" config DAB boolean "DAB adapters" ---help--- - Allow selecting support for for Digital Audio Broadcasting (DAB) + Allow selecting support for Digital Audio Broadcasting (DAB) Receiver adapters. if DAB -- cgit v1.2.3 From 4b7ea770410dae8b9ca79623e4e36e94dfa86fd4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Feb 2009 11:43:50 +0100 Subject: gspca - vc032x: Remove the vc0321 reset. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/vc032x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux/drivers/media/video/gspca/vc032x.c b/linux/drivers/media/video/gspca/vc032x.c index 1832d241f..72cbf56c9 100644 --- a/linux/drivers/media/video/gspca/vc032x.c +++ b/linux/drivers/media/video/gspca/vc032x.c @@ -2098,6 +2098,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev, /*not reached*/ } +#if 0 static void vc0321_reset(struct gspca_dev *gspca_dev) { reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); @@ -2106,6 +2107,7 @@ static void vc0321_reset(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); msleep(100); } +#endif /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, @@ -2118,8 +2120,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; sd->bridge = id->driver_info; - +#if 0 vc0321_reset(gspca_dev); +#endif sensor = vc032x_probe_sensor(gspca_dev); switch (sensor) { case -1: -- cgit v1.2.3 From c1d676109e87244212120f7ba938d67c3d0571a0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 2 Feb 2009 20:25:38 +0100 Subject: gspca - some drivers: Fix compilation warnings. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/mr97310a.c | 2 +- linux/drivers/media/video/gspca/sonixj.c | 2 +- linux/drivers/media/video/gspca/spca505.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/gspca/mr97310a.c b/linux/drivers/media/video/gspca/mr97310a.c index 3a5ddff8f..5ec5ce6e3 100644 --- a/linux/drivers/media/video/gspca/mr97310a.c +++ b/linux/drivers/media/video/gspca/mr97310a.c @@ -73,7 +73,7 @@ static int reg_w(struct gspca_dev *gspca_dev, int len) rc = usb_bulk_msg(gspca_dev->dev, usb_sndbulkpipe(gspca_dev->dev, 4), - gspca_dev->usb_buf, len, 0, 500); + gspca_dev->usb_buf, len, NULL, 500); if (rc < 0) PDEBUG(D_ERR, "reg write [%02x] error %d", gspca_dev->usb_buf[0], rc); diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 0aa4649bd..3be96d9f4 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -1031,7 +1031,7 @@ static void mi0360_probe(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, j; - u16 val; + u16 val = 0; static const u8 probe_tb[][4][8] = { { /* mi0360 */ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, diff --git a/linux/drivers/media/video/gspca/spca505.c b/linux/drivers/media/video/gspca/spca505.c index 4fc54d8b8..2acec58b1 100644 --- a/linux/drivers/media/video/gspca/spca505.c +++ b/linux/drivers/media/video/gspca/spca505.c @@ -426,8 +426,8 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x05, 0x00, 0x11}, {0x05, 0x00, 0x12}, {0x05, 0x6f, 0x00}, - {0x05, (u8) (initial_brightness >> 6), 0x00}, - {0x05, (u8) (initial_brightness << 2), 0x01}, + {0x05, initial_brightness >> 6, 0x00}, + {0x05, (initial_brightness << 2) & 0xff, 0x01}, {0x05, 0x00, 0x02}, {0x05, 0x01, 0x03}, {0x05, 0x00, 0x04}, @@ -560,8 +560,8 @@ static const u8 spca505b_open_data_ccd[][3] = { {0x06, 0x5f, 0x1f}, {0x06, 0x32, 0x20}, - {0x05, (u8) (initial_brightness >> 6), 0x00}, - {0x05, (u8) (initial_brightness << 2), 0x01}, + {0x05, initial_brightness >> 6, 0x00}, + {0x05, (initial_brightness << 2) & 0xff, 0x01}, {0x05, 0x06, 0xc1}, {0x05, 0x58, 0xc2}, {0x05, 0x00, 0xca}, -- cgit v1.2.3 From e086109f0cad2b76f5a32cf18db838e2026712bb Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 4 Feb 2009 19:33:21 +0100 Subject: gspca - main: Destroy the URBs at disconnection time. From: Adam Baker If a device using the gspca framework is unplugged while it is still streaming then the call that is used to free the URBs that have been allocated occurs after the pointer it uses becomes invalid at the end of gspca_disconnect. Make another cleanup call in gspca_disconnect while the pointer is still valid (multiple calls are OK as destroy_urbs checks for pointers already being NULL. Priority: high Signed-off-by: Adam Baker Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index cac937040..64842682e 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -434,6 +434,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; + BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; if (!gspca_dev->present) usb_kill_urb(urb); @@ -1953,8 +1954,12 @@ void gspca_disconnect(struct usb_interface *intf) { struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; + mutex_unlock(&gspca_dev->usb_lock); + destroy_urbs(gspca_dev); + gspca_dev->dev = NULL; usb_set_intfdata(intf, NULL); /* release the device */ -- cgit v1.2.3 From 8d372d7b7fad4952e30da202fa0be5905382a8fd Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 5 Feb 2009 19:04:33 +0100 Subject: gspca - sonixj: No vertical flip control for mt9v111. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 3be96d9f4..6c5ec09a5 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -235,9 +235,9 @@ static __u32 ctrl_dis[] = { (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_MO4000 2 */ #if 1 - 0, + (1 << VFLIP_IDX), #else - (1 << AUTOGAIN_IDX), + (1 << AUTOGAIN_IDX) | (1 << VFLIP_IDX), #endif /* SENSOR_MT9V111 3 */ (1 << INFRARED_IDX) | (1 << VFLIP_IDX), -- cgit v1.2.3 From 1aa4c1b8e3ab0204e2985d4a13d81379b5fb7b02 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 5 Feb 2009 19:12:24 +0100 Subject: gspca - sonixj: Add autogain for ov7630/48 and vflip for ov7648. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/sonixj.c | 43 ++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index 6c5ec09a5..5cdb643b8 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -45,7 +45,7 @@ struct sd { u8 blue; u8 red; u8 gamma; - u8 vflip; /* ov7630 only */ + u8 vflip; /* ov7630/ov7648 only */ u8 infrared; /* mt9v111 only */ s8 ag_cnt; @@ -192,7 +192,7 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, -/* ov7630 only */ +/* ov7630/ov7648 only */ #define VFLIP_IDX 6 { { @@ -202,7 +202,7 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, -#define VFLIP_DEF 1 +#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */ .default_value = VFLIP_DEF, }, .set = sd_setvflip, @@ -244,7 +244,7 @@ static __u32 ctrl_dis[] = { /* SENSOR_OM6802 4 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX), /* SENSOR_OV7630 5 */ - (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), + (1 << INFRARED_IDX), /* SENSOR_OV7648 6 */ (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX), /* SENSOR_OV7660 7 */ @@ -677,7 +677,8 @@ static const u8 ov7648_sensor_init[][8] = { {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, /*...*/ /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */ -/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */ +/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN + * set by setvflip */ {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */ @@ -1319,7 +1320,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->gamma = GAMMA_DEF; sd->autogain = AUTOGAIN_DEF; sd->ag_cnt = -1; - sd->vflip = VFLIP_DEF; + if (sd->sensor != SENSOR_OV7630) + sd->vflip = 0; + else + sd->vflip = 1; sd->infrared = INFRARED_DEF; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; @@ -1589,16 +1593,39 @@ static void setautogain(struct gspca_dev *gspca_dev) if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX)) return; + switch (sd->sensor) { + case SENSOR_OV7630: + case SENSOR_OV7648: { + u8 comb; + + if (sd->sensor == SENSOR_OV7630) + comb = 0xc0; + else + comb = 0xa0; + if (sd->autogain) + comb |= 0x02; + i2c_w1(&sd->gspca_dev, 0x13, comb); + return; + } + } if (sd->autogain) sd->ag_cnt = AG_CNT_START; else sd->ag_cnt = -1; } +/* ov7630/ov7648 only */ static void setvflip(struct sd *sd) { - i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ - sd->vflip ? 0x82 : 0x02); + u8 comn; + + if (sd->sensor == SENSOR_OV7630) + comn = 0x02; + else + comn = 0x06; + if (sd->vflip) + comn |= 0x80; + i2c_w1(&sd->gspca_dev, 0x75, comn); } static void setinfrared(struct sd *sd) -- cgit v1.2.3 From 891ac17d7e12b75ddf21bea407b502569f94bb3e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 17:45:23 +0100 Subject: gspca - t613: Bad sensor name in kernel trace when 'other' sensor. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index adec0767c..1b0fc86c4 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -685,7 +685,7 @@ static int sd_init(struct gspca_dev *gspca_dev) sd->sensor = SENSOR_TAS5130A; break; case 0x0803: - PDEBUG(D_CONF, "sensor om6802"); + PDEBUG(D_CONF, "sensor 'other'"); sd->sensor = SENSOR_OTHER; break; case 0x0807: -- cgit v1.2.3 From a50f33bc015e6def039a24ead62b4e32d76d44e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 18:11:58 +0100 Subject: gspca - t613: Bad debug level when displaying the sensor type. From: Jean-Francois Moine Priority: normal Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/t613.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/drivers/media/video/gspca/t613.c b/linux/drivers/media/video/gspca/t613.c index 1b0fc86c4..4891592ea 100644 --- a/linux/drivers/media/video/gspca/t613.c +++ b/linux/drivers/media/video/gspca/t613.c @@ -681,19 +681,19 @@ static int sd_init(struct gspca_dev *gspca_dev) | reg_r(gspca_dev, 0x07); switch (sensor_id) { case 0x0801: - PDEBUG(D_CONF, "sensor tas5130a"); + PDEBUG(D_PROBE, "sensor tas5130a"); sd->sensor = SENSOR_TAS5130A; break; case 0x0803: - PDEBUG(D_CONF, "sensor 'other'"); + PDEBUG(D_PROBE, "sensor 'other'"); sd->sensor = SENSOR_OTHER; break; case 0x0807: - PDEBUG(D_CONF, "sensor om6802"); + PDEBUG(D_PROBE, "sensor om6802"); sd->sensor = SENSOR_OM6802; break; default: - PDEBUG(D_CONF, "unknown sensor %04x", sensor_id); + PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id); return -EINVAL; } -- cgit v1.2.3 From 9e943ca0c659d66896f55dcfa1280f1d22556e78 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 6 Feb 2009 19:12:46 +0100 Subject: gspca - sq905: New subdriver. From: Adam Baker Add initial support for cameras based on the SQ Technologies SQ-905 chipset (USB ID 2770:9120) to V4L2 using the gspca infrastructure. Currently only supports one resolution and doesn't attempt to inform libv4l what image flipping options are needed. Priority: normal Signed-off-by: Adam Baker Signed-off-by: Theodore Kilgore Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/Kconfig | 9 + linux/drivers/media/video/gspca/Makefile | 2 + linux/drivers/media/video/gspca/sq905.c | 438 +++++++++++++++++++++++++++++++ 3 files changed, 449 insertions(+) create mode 100644 linux/drivers/media/video/gspca/sq905.c diff --git a/linux/drivers/media/video/gspca/Kconfig b/linux/drivers/media/video/gspca/Kconfig index 11c5d2fc2..a0f05ef5c 100644 --- a/linux/drivers/media/video/gspca/Kconfig +++ b/linux/drivers/media/video/gspca/Kconfig @@ -176,6 +176,15 @@ config USB_GSPCA_SPCA561 To compile this driver as a module, choose M here: the module will be called gspca_spca561. +config USB_GSPCA_SQ905 + tristate "SQ Technologies SQ905 based USB Camera Driver" + depends on VIDEO_V4L2 && USB_GSPCA + help + Say Y here if you want support for cameras based on the SQ905 chip. + + To compile this driver as a module, choose M here: the + module will be called gspca_sq905. + config USB_GSPCA_STK014 tristate "Syntek DV4000 (STK014) USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA diff --git a/linux/drivers/media/video/gspca/Makefile b/linux/drivers/media/video/gspca/Makefile index b3cbcc176..b6ec61185 100644 --- a/linux/drivers/media/video/gspca/Makefile +++ b/linux/drivers/media/video/gspca/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o +obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o @@ -41,6 +42,7 @@ gspca_spca505-objs := spca505.o gspca_spca506-objs := spca506.o gspca_spca508-objs := spca508.o gspca_spca561-objs := spca561.o +gspca_sq905-objs := sq905.o gspca_stk014-objs := stk014.o gspca_sunplus-objs := sunplus.o gspca_t613-objs := t613.o diff --git a/linux/drivers/media/video/gspca/sq905.c b/linux/drivers/media/video/gspca/sq905.c new file mode 100644 index 000000000..dafaed69e --- /dev/null +++ b/linux/drivers/media/video/gspca/sq905.c @@ -0,0 +1,438 @@ +/* + * SQ905 subdriver + * + * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * History and Acknowledgments + * + * The original Linux driver for SQ905 based cameras was written by + * Marcell Lengyel and furter developed by many other contributers + * and is available from http://sourceforge.net/projects/sqcam/ + * + * This driver takes advantage of the reverse engineering work done for + * that driver and for libgphoto2 but shares no code with them. + * + * This driver has used as a base the finepix driver and other gspca + * based drivers and may still contain code fragments taken from those + * drivers. + */ + +#define MODULE_NAME "sq905" + +#include +#include "gspca.h" + +MODULE_AUTHOR("Adam Baker , " + "Theodore Kilgore "); +MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* Default timeouts, in ms */ +#define SQ905_CMD_TIMEOUT 500 +#define SQ905_DATA_TIMEOUT 1000 + +/* Maximum transfer size to use. */ +#define SQ905_MAX_TRANSFER 0x8000 +#define FRAME_HEADER_LEN 64 + +/* The known modes, or registers. These go in the "value" slot. */ + +/* 00 is "none" obviously */ + +#define SQ905_BULK_READ 0x03 /* precedes any bulk read */ +#define SQ905_COMMAND 0x06 /* precedes the command codes below */ +#define SQ905_PING 0x07 /* when reading an "idling" command */ +#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */ + +/* Some command codes. These go in the "index" slot. */ + +#define SQ905_ID 0xf0 /* asks for model string */ +#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */ +#define SQ905_DATA 0x30 /* accesses photo data, not used here */ +#define SQ905_CLEAR 0xa0 /* clear everything */ +#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */ +#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */ +/* note that the capture command also controls the output dimensions */ +/* 0x60 -> 160x120, 0x61 -> 320x240 0x62 -> 640x480 depends on camera */ +/* 0x62 is not correct, at least for some cams. Should be 0x63 ? */ + +/* Structure to hold all of our device specific stuff */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + u8 cam_type; + + /* + * Driver stuff + */ + struct work_struct work_struct; + struct workqueue_struct *work_thread; +}; + +/* The driver only supports 320x240 so far. */ +static struct v4l2_pix_format sq905_mode[1] = { + { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0} +}; + +struct cam_type { + u32 ident_word; + char *name; + struct v4l2_pix_format *min_mode; + u8 num_modes; + u8 sensor_flags; +}; + +#define SQ905_FLIP_HORIZ (1 << 0) +#define SQ905_FLIP_VERT (1 << 1) + +/* Last entry is default if nothing else matches */ +static struct cam_type cam_types[] = { + { 0x19010509, "PocketCam", &sq905_mode[0], 1, SQ905_FLIP_HORIZ }, + { 0x32010509, "Magpix", &sq905_mode[0], 1, SQ905_FLIP_HORIZ }, + { 0, "Default", &sq905_mode[0], 1, SQ905_FLIP_HORIZ | SQ905_FLIP_VERT } +}; + +/* + * Send a command to the camera. + */ +static int sq905_command(struct gspca_dev *gspca_dev, u16 index) +{ + int ret; + + gspca_dev->usb_buf[0] = '\0'; + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_SYNCH_FRAME, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + SQ905_COMMAND, index, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", + __func__, ret); + return ret; + } + + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_SYNCH_FRAME, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + SQ905_PING, 0, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)", + __func__, ret); + return ret; + } + + return 0; +} + +/* + * Acknowledge the end of a frame - see warning on sq905_command. + */ +static int sq905_ack_frame(struct gspca_dev *gspca_dev) +{ + int ret; + + gspca_dev->usb_buf[0] = '\0'; + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_SYNCH_FRAME, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1, + SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); + return ret; + } + + return 0; +} + +/* + * request and read a block of data - see warning on sq905_command. + */ +static int +sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size) +{ + int ret; + int act_len; + + gspca_dev->usb_buf[0] = '\0'; + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + USB_REQ_SYNCH_FRAME, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + SQ905_BULK_READ, size, gspca_dev->usb_buf, + 1, SQ905_CMD_TIMEOUT); + if (ret < 0) { + PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret); + return ret; + } + ret = usb_bulk_msg(gspca_dev->dev, + usb_rcvbulkpipe(gspca_dev->dev, 0x81), + data, size, &act_len, SQ905_DATA_TIMEOUT); + + /* successful, it returns 0, otherwise negative */ + if (ret < 0 || act_len != size) { + PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d", + ret, act_len, size); + return -EIO; + } + return 0; +} + +/* This function is called as a workqueue function and runs whenever the camera + * is streaming data. Because it is a workqueue function it is allowed to sleep + * so we can use synchronous USB calls. To avoid possible collisions with other + * threads attempting to use the camera's USB interface we take the gspca + * usb_lock when performing USB operations. In practice the only thing we need + * to protect against is the usb_set_interface call that gspca makes during + * stream_off as the camera doesn't provide any controls that the user could try + * to change. + */ +static void sq905_dostream(struct work_struct *work) +{ + struct sd *dev = container_of(work, struct sd, work_struct); + struct gspca_dev *gspca_dev = &dev->gspca_dev; + struct gspca_frame *frame; + int bytes_left; /* bytes remaining in current frame. */ + int data_len; /* size to use for the next read. */ + int header_read; /* true if we have already read the frame header. */ + int discarding; /* true if we failed to get space for frame. */ + int packet_type; + int ret; + u8 *data; + u8 *buffer; + + buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA); + mutex_lock(&gspca_dev->usb_lock); + if (!buffer) { + PDEBUG(D_ERR, "Couldn't allocate USB buffer"); + goto quit_stream; + } + + while (gspca_dev->present && gspca_dev->streaming) { + /* Need a short delay to ensure streaming flag was set by + * gspca and to make sure gspca can grab the mutex. */ + mutex_unlock(&gspca_dev->usb_lock); + msleep(1); + + /* request some data and then read it until we have + * a complete frame. */ + bytes_left = sq905_mode[0].sizeimage + FRAME_HEADER_LEN; + header_read = 0; + discarding = 0; + + while (bytes_left > 0) { + data_len = bytes_left > SQ905_MAX_TRANSFER ? + SQ905_MAX_TRANSFER : bytes_left; + mutex_lock(&gspca_dev->usb_lock); + if (!gspca_dev->present) + goto quit_stream; + ret = sq905_read_data(gspca_dev, buffer, data_len); + if (ret < 0) + goto quit_stream; + mutex_unlock(&gspca_dev->usb_lock); + PDEBUG(D_STREAM, + "Got %d bytes out of %d for frame", + data_len, bytes_left); + bytes_left -= data_len; + data = buffer; + if (!header_read) { + packet_type = FIRST_PACKET; + /* The first 64 bytes of each frame are + * a header full of FF 00 bytes */ + data += FRAME_HEADER_LEN; + data_len -= FRAME_HEADER_LEN; + header_read = 1; + } else if (bytes_left == 0) { + packet_type = LAST_PACKET; + } else { + packet_type = INTER_PACKET; + } + frame = gspca_get_i_frame(gspca_dev); + if (frame && !discarding) + gspca_frame_add(gspca_dev, packet_type, + frame, data, data_len); + else + discarding = 1; + } + /* acknowledge the frame */ + mutex_lock(&gspca_dev->usb_lock); + if (!gspca_dev->present) + goto quit_stream; + ret = sq905_ack_frame(gspca_dev); + if (ret < 0) + goto quit_stream; + } +quit_stream: + /* the usb_lock is already acquired */ + if (gspca_dev->present) + sq905_command(gspca_dev, SQ905_CLEAR); + mutex_unlock(&gspca_dev->usb_lock); + kfree(buffer); +} + +/* This function is called at probe time just before sd_init */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam = &gspca_dev->cam; + struct sd *dev = (struct sd *) gspca_dev; + + cam->cam_mode = sq905_mode; + cam->nmodes = 1; + /* We don't use the buffer gspca allocates so make it small. */ + cam->bulk_size = 64; + + INIT_WORK(&dev->work_struct, sq905_dostream); + + return 0; +} + +/* called on streamoff with alt==0 and on disconnect */ +/* the usb_lock is held at entry - restore on exit */ +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + + /* wait for the work queue to terminate */ + mutex_unlock(&gspca_dev->usb_lock); + /* This waits for sq905_dostream to finish */ + destroy_workqueue(dev->work_thread); + dev->work_thread = NULL; + mutex_lock(&gspca_dev->usb_lock); +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + u32 ident; + int ret; + + /* connect to the camera and read + * the model ID and process that and put it away. + */ + ret = sq905_command(gspca_dev, SQ905_CLEAR); + if (ret < 0) + return ret; + ret = sq905_command(gspca_dev, SQ905_ID); + if (ret < 0) + return ret; + ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4); + if (ret < 0) + return ret; + /* usb_buf is allocated with kmalloc so is aligned. */ + ident = le32_to_cpup((u32 *)gspca_dev->usb_buf); + ret = sq905_command(gspca_dev, SQ905_CLEAR); + if (ret < 0) + return ret; + dev->cam_type = 0; + while (dev->cam_type < ARRAY_SIZE(cam_types) - 1 && + ident != cam_types[dev->cam_type].ident_word) + dev->cam_type++; + PDEBUG(D_CONF, "SQ905 camera %s, ID %08x detected", + cam_types[dev->cam_type].name, ident); + return 0; +} + +/* Set up for getting frames. */ +static int sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *dev = (struct sd *) gspca_dev; + int ret; + + /* "Open the shutter" and set size, to start capture */ + ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED); + if (ret < 0) { + PDEBUG(D_ERR, "Start streaming command failed"); + return ret; + } + + /* Start the workqueue function to do the streaming */ + dev->work_thread = create_singlethread_workqueue(MODULE_NAME); + queue_work(dev->work_thread, &dev->work_struct); + + return 0; +} + +/* Table of supported USB devices */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x2770, 0x9120)}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* sub-driver description */ +static const struct sd_desc sd_desc = { + .name = MODULE_NAME, + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stop0 = sd_stop0, +}; + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, + &sd_desc, + sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + int ret; + + ret = usb_register(&sd_driver); + if (ret < 0) + return ret; + PDEBUG(D_PROBE, "registered"); + return 0; +} + +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); -- cgit v1.2.3 From 9ddff42d7f7354e47e024a3b71bb84cf04158ad9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Feb 2009 12:05:45 +0100 Subject: gspca - main: More checks of the device disconnection. From: Jean-Francois Moine - prevent application oops when the device is disconnected - wake up the application at disconnection time - check the disconnection in ioctl dqbuf and poll Priority: high Signed-off-by: Jean-Francois Moine --- linux/drivers/media/video/gspca/gspca.c | 105 ++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 64842682e..8d78b9287 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -136,11 +136,13 @@ static void fill_frame(struct gspca_dev *gspca_dev, cam_pkt_op pkt_scan; if (urb->status != 0) { + if (urb->status == -ESHUTDOWN) + return; /* disconnection */ #ifdef CONFIG_PM if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; /* disconnection ? */ + return; } pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -220,6 +222,8 @@ static void bulk_irq(struct urb *urb) switch (urb->status) { case 0: break; + case -ESHUTDOWN: + return; /* disconnection */ case -ECONNRESET: urb->status = 0; break; @@ -228,7 +232,7 @@ static void bulk_irq(struct urb *urb) if (!gspca_dev->frozen) #endif PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); - return; /* disconnection ? */ + return; } /* check the availability of the frame buffer */ @@ -434,10 +438,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) if (urb == NULL) break; - BUG_ON(!gspca_dev->dev); gspca_dev->urb[i] = NULL; - if (!gspca_dev->present) - usb_kill_urb(urb); + usb_kill_urb(urb); if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, @@ -605,6 +607,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } + /* set the higher alternate setting and * loop until urb submit succeeds */ gspca_dev->alt = gspca_dev->nbalt; @@ -674,12 +681,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; - if (gspca_dev->present - && gspca_dev->sd_desc->stopN) - gspca_dev->sd_desc->stopN(gspca_dev); - destroy_urbs(gspca_dev); - if (gspca_dev->present) + if (gspca_dev->present) { + if (gspca_dev->sd_desc->stopN) + gspca_dev->sd_desc->stopN(gspca_dev); + destroy_urbs(gspca_dev); gspca_set_alt0(gspca_dev); + } + + /* always call stop0 to free the subdriver's resources */ if (gspca_dev->sd_desc->stop0) gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); @@ -961,8 +970,17 @@ static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct gspca_dev *gspca_dev = priv; + int ret; memset(cap, 0, sizeof *cap); + + /* protect the access to the usb device */ + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); if (gspca_dev->dev->product != NULL) { strncpy(cap->card, gspca_dev->dev->product, @@ -978,7 +996,10 @@ static int vidioc_querycap(struct file *file, void *priv, cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; - return 0; + ret = 0; +out: + mutex_unlock(&gspca_dev->usb_lock); + return ret; } static int vidioc_queryctrl(struct file *file, void *priv, @@ -1041,7 +1062,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv, PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = ctrls->set(gspca_dev, ctrl->value); + if (gspca_dev->present) + ret = ctrls->set(gspca_dev, ctrl->value); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1065,7 +1089,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = ctrls->get(gspca_dev, &ctrl->value); + if (gspca_dev->present) + ret = ctrls->get(gspca_dev, &ctrl->value); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1227,10 +1254,7 @@ static int vidioc_streamon(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - if (!gspca_dev->present) { - ret = -ENODEV; - goto out; - } + if (gspca_dev->nframes == 0 || !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) { ret = -EINVAL; @@ -1298,7 +1322,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1313,7 +1340,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1332,7 +1362,11 @@ static int vidioc_g_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, + parm); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1357,7 +1391,11 @@ static int vidioc_s_parm(struct file *filp, void *priv, if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm); + if (gspca_dev->present) + ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, + parm); + else + ret = -ENODEV; mutex_unlock(&gspca_dev->usb_lock); return ret; } @@ -1531,7 +1569,8 @@ static int frame_wait(struct gspca_dev *gspca_dev, if (gspca_dev->sd_desc->dq_callback) { mutex_lock(&gspca_dev->usb_lock); - gspca_dev->sd_desc->dq_callback(gspca_dev); + if (gspca_dev->present) + gspca_dev->sd_desc->dq_callback(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } return j; @@ -1553,6 +1592,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, if (v4l2_buf->memory != gspca_dev->memory) return -EINVAL; + if (!gspca_dev->present) + return -ENODEV; + /* if not streaming, be sure the application will not loop forever */ if (!(file->f_flags & O_NONBLOCK) && !gspca_dev->streaming && gspca_dev->users == 1) @@ -1703,8 +1745,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) PDEBUG(D_FRAM, "poll"); poll_wait(file, &gspca_dev->wq, wait); - if (!gspca_dev->present) - return POLLERR; /* if reqbufs is not done, the user would use read() */ if (gspca_dev->nframes == 0) { @@ -1717,10 +1757,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) return POLLERR; - if (!gspca_dev->present) { - ret = POLLERR; - goto out; - } /* check the next incoming buffer */ i = gspca_dev->fr_o; @@ -1729,8 +1765,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) ret = POLLIN | POLLRDNORM; /* something to read */ else ret = 0; -out: mutex_unlock(&gspca_dev->queue_lock); + if (!gspca_dev->present) + return POLLHUP; return ret; } @@ -1956,10 +1993,16 @@ void gspca_disconnect(struct usb_interface *intf) mutex_lock(&gspca_dev->usb_lock); gspca_dev->present = 0; - mutex_unlock(&gspca_dev->usb_lock); - destroy_urbs(gspca_dev); + if (gspca_dev->streaming) { + destroy_urbs(gspca_dev); + wake_up_interruptible(&gspca_dev->wq); + } + + /* the device is freed at exit of this function */ gspca_dev->dev = NULL; + mutex_unlock(&gspca_dev->usb_lock); + usb_set_intfdata(intf, NULL); /* release the device */ -- cgit v1.2.3 From 8f6e212e7f25dca1323cc8b7d4a5112c3b2225e3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Feb 2009 08:29:07 -0200 Subject: v4l2-framework: documments videobuf usage on drivers From: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 92 +++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index 73f9b6423..21f83089a 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -47,7 +47,9 @@ All drivers have the following structure: 3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and /dev/vtxX) and keeping track of device-node specific data. -4) Filehandle-specific structs containing per-filehandle data. +4) Filehandle-specific structs containing per-filehandle data; + +5) video buffer handling. This is a rough schematic of how it all relates: @@ -525,3 +527,91 @@ void *video_drvdata(struct file *file); You can go from a video_device struct to the v4l2_device struct using: struct v4l2_device *v4l2_dev = vdev->v4l2_dev; + +video buffer helper functions +----------------------------- + +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and +overlay() on a consistent way. + +There are currently methods for using video buffers on devices that +supports DMA with scatter/gather method (videobuf-dma-sg), DMA with +linear access (videobuf-dma-contig), and vmalloced buffers, mostly +used on USB drivers (videobuf-vmalloc). + +Any driver using videobuf should provide operations (callbacks) for +four handlers: + +ops->buf_setup - calculates the size of the video buffers and avoid they + to waste more than some maximum limit of RAM; +ops->buf_prepare - fills the video buffer structs and calls + videobuf_iolock() to alloc and prepare mmaped memory; +ops->buf_queue - advices the driver that another buffer were + requested (by read() or by QBUF); +ops->buf_release - frees any buffer that were allocated. + +In order to use it, the driver need to have a code (generally called at +interrupt context) that will properly handle the buffer request lists, +announcing that a new buffer were filled. + +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a +request. The code is generally like this one: + if (list_empty(&dma_q->active)) + return; + + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + + if (!waitqueue_active(&buf->vb.done)) + return; + + /* Some logic to handle the buf may be needed here */ + + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); + +Those are the videobuffer functions used on drivers, implemented on +videobuf-core: + +- videobuf_queue_core_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function. + +- videobuf_iolock() + Prepares the videobuf memory for the proper method (read, mmap, overlay). + +- videobuf_queue_is_busy() + Checks if a videobuf is streaming. + +- videobuf_queue_cancel() + Stops video handling. + +- videobuf_mmap_free() + frees mmap buffers. + +- videobuf_stop() + Stops video handling, ends mmap and frees mmap and other buffers. + +- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). + +- V4L1 api function (corresponds to VIDIOCMBUF ioctl): + videobuf_cgmbuf() + This function is used to provide backward compatibility with V4L1 + API. + +- Some help functions for read()/poll() operations: + videobuf_read_stream() + For continuous stream read() + videobuf_read_one() + For snapshot read() + videobuf_poll_stream() + polling help function + +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI +drivers (or the irq callback on USB). -- cgit v1.2.3 From c02991ae9384f6940ac34f853f5191b7bcf1f453 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Feb 2009 08:51:28 -0200 Subject: v4l2-framework.txt: Fixes the videobuf init functions From: Mauro Carvalho Chehab Documents the driver usage functions, instead of the generic one used by the videobuf specific handlers. Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/v4l2-framework.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index 21f83089a..a6005257a 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -575,9 +575,21 @@ request. The code is generally like this one: Those are the videobuffer functions used on drivers, implemented on videobuf-core: -- videobuf_queue_core_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function. +- Videobuf init functions + videobuf_queue_sg_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA + Scatter/Gather buffers. + + videobuf_queue_dma_contig_init + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA + contiguous buffers. + + videobuf_queue_vmalloc_init() + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on USB (and other drivers) + that need a vmalloced type of videobuf. - videobuf_iolock() Prepares the videobuf memory for the proper method (read, mmap, overlay). -- cgit v1.2.3 From add4cca4f1bb659d08d75b45f57b226325a34a6b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:31:01 +0100 Subject: v4l2-dev: remove limit of 32 devices per driver in get_index() From: Hans Verkuil get_index() had a limitation of 32 devices per driver. This was unnecessarily strict and has been replaced with the maximum number of devices. That should really satisfy anyone! Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/v4l2-dev.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index 9e34e9ec2..e6dc1279a 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -326,37 +326,38 @@ static const struct file_operations v4l2_fops = { */ static int get_index(struct video_device *vdev, int num) { - u32 used = 0; - const int max_index = sizeof(used) * 8 - 1; + /* This can be static since this function is called with the global + videodev_lock held. */ + static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); int i; - /* Currently a single v4l driver instance cannot create more than - 32 devices. - Increase to u64 or an array of u32 if more are needed. */ - if (num > max_index) { + if (num >= VIDEO_NUM_DEVICES) { printk(KERN_ERR "videodev: %s num is too large\n", __func__); return -EINVAL; } - /* Some drivers do not set the parent. In that case always return 0. */ + /* Some drivers do not set the parent. In that case always return + num or 0. */ if (vdev->parent == NULL) - return 0; + return num >= 0 ? num : 0; + + bitmap_zero(used, VIDEO_NUM_DEVICES); for (i = 0; i < VIDEO_NUM_DEVICES; i++) { if (video_device[i] != NULL && video_device[i]->parent == vdev->parent) { - used |= 1 << video_device[i]->index; + set_bit(video_device[i]->index, used); } } if (num >= 0) { - if (used & (1 << num)) + if (test_bit(num, used)) return -ENFILE; return num; } - i = ffz(used); - return i > max_index ? -ENFILE : i; + i = find_first_zero_bit(used, VIDEO_NUM_DEVICES); + return i == VIDEO_NUM_DEVICES ? -ENFILE : i; } int video_register_device(struct video_device *vdev, int type, int nr) -- cgit v1.2.3 From 398608cab6406080ef01e4cbfbd88a4c401f4fc0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:37:17 +0100 Subject: vivi: update comment to reflect that vivi can now create more than 32 devs. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 603274874..e089cbd27 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -1348,10 +1348,7 @@ static struct video_device vivi_template = { The real maximum number of virtual drivers will depend on how many drivers will succeed. This is limited to the maximum number of devices that - videodev supports. Since there are 64 minors for video grabbers, this is - currently the theoretical maximum limit. However, a further limit does - exist at videodev that forbids any driver to register more than 32 video - grabbers. + videodev supports, which is equal to VIDEO_NUM_DEVICES. */ static int __init vivi_init(void) { -- cgit v1.2.3 From 9511f472cfb47c53ad0f210dd137dedfb753cea7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 15:54:23 +0100 Subject: v4l2-device: allow a NULL parent device when registering. From: Hans Verkuil Some drivers (e.g. for ISA devices) have no parent device because there is no associated bus driver. Allow the parent device to be NULL in those cases when registering v4l2_device. Priority: normal Signed-off-by: Hans Verkuil --- linux/Documentation/video4linux/v4l2-framework.txt | 58 +++++++++++----------- linux/drivers/media/video/v4l2-device.c | 37 +++++++++----- linux/include/media/v4l2-device.h | 31 +++++++----- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index a6005257a..e1620e2a3 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -84,12 +84,14 @@ You must register the device instance: v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); Registration will initialize the v4l2_device struct and link dev->driver_data -to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from -dev (driver name followed by the bus_id, to be precise). You may change the -name after registration if you want. +to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived +from dev (driver name followed by the bus_id, to be precise). If you set it +up before calling v4l2_device_register then it will be untouched. If dev is +NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. The first 'dev' argument is normally the struct device pointer of a pci_dev, -usb_device or platform_device. +usb_device or platform_device. It is rare for dev to be NULL, but it happens +with ISA devices, for example. You unregister with: @@ -531,11 +533,11 @@ struct v4l2_device *v4l2_dev = vdev->v4l2_dev; video buffer helper functions ----------------------------- -The v4l2 core API provides a standard method for dealing with video -buffers. Those methods allow a driver to implement read(), mmap() and +The v4l2 core API provides a standard method for dealing with video +buffers. Those methods allow a driver to implement read(), mmap() and overlay() on a consistent way. -There are currently methods for using video buffers on devices that +There are currently methods for using video buffers on devices that supports DMA with scatter/gather method (videobuf-dma-sg), DMA with linear access (videobuf-dma-contig), and vmalloced buffers, mostly used on USB drivers (videobuf-vmalloc). @@ -544,50 +546,50 @@ Any driver using videobuf should provide operations (callbacks) for four handlers: ops->buf_setup - calculates the size of the video buffers and avoid they - to waste more than some maximum limit of RAM; + to waste more than some maximum limit of RAM; ops->buf_prepare - fills the video buffer structs and calls videobuf_iolock() to alloc and prepare mmaped memory; ops->buf_queue - advices the driver that another buffer were - requested (by read() or by QBUF); + requested (by read() or by QBUF); ops->buf_release - frees any buffer that were allocated. In order to use it, the driver need to have a code (generally called at interrupt context) that will properly handle the buffer request lists, announcing that a new buffer were filled. -The irq handling code should handle the videobuf task lists, in order -to advice videobuf that a new frame were filled, in order to honor to a +The irq handling code should handle the videobuf task lists, in order +to advice videobuf that a new frame were filled, in order to honor to a request. The code is generally like this one: - if (list_empty(&dma_q->active)) + if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); + buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue); - if (!waitqueue_active(&buf->vb.done)) + if (!waitqueue_active(&buf->vb.done)) return; /* Some logic to handle the buf may be needed here */ - list_del(&buf->vb.queue); - do_gettimeofday(&buf->vb.ts); - wake_up(&buf->vb.done); + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + wake_up(&buf->vb.done); -Those are the videobuffer functions used on drivers, implemented on +Those are the videobuffer functions used on drivers, implemented on videobuf-core: - Videobuf init functions videobuf_queue_sg_init() - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that uses DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that uses DMA Scatter/Gather buffers. videobuf_queue_dma_contig_init - Initializes the videobuf infrastructure. This function should be - called before any other videobuf function on drivers that need DMA + Initializes the videobuf infrastructure. This function should be + called before any other videobuf function on drivers that need DMA contiguous buffers. videobuf_queue_vmalloc_init() - Initializes the videobuf infrastructure. This function should be + Initializes the videobuf infrastructure. This function should be called before any other videobuf function on USB (and other drivers) that need a vmalloced type of videobuf. @@ -607,12 +609,12 @@ videobuf-core: Stops video handling, ends mmap and frees mmap and other buffers. - V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls: - videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), + videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(), videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff(). - V4L1 api function (corresponds to VIDIOCMBUF ioctl): videobuf_cgmbuf() - This function is used to provide backward compatibility with V4L1 + This function is used to provide backward compatibility with V4L1 API. - Some help functions for read()/poll() operations: @@ -623,7 +625,7 @@ videobuf-core: videobuf_poll_stream() polling help function -The better way to understand it is to take a look at vivi driver. One -of the main reasons for vivi is to be a videobuf usage example. the -vivi_thread_tick() does the task that the IRQ callback would do on PCI +The better way to understand it is to take a look at vivi driver. One +of the main reasons for vivi is to be a videobuf usage example. the +vivi_thread_tick() does the task that the IRQ callback would do on PCI drivers (or the irq callback on USB). diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index e84925976..cb8234437 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -27,15 +27,24 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) { - if (dev == NULL || v4l2_dev == NULL) + if (v4l2_dev == NULL) return -EINVAL; - /* Warn if we apparently re-register a device */ - WARN_ON(dev_get_drvdata(dev) != NULL); + INIT_LIST_HEAD(&v4l2_dev->subdevs); spin_lock_init(&v4l2_dev->lock); v4l2_dev->dev = dev; - snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", + if (dev == NULL) { + /* If dev == NULL, then name must be filled in by the caller */ + WARN_ON(!v4l2_dev->name[0]); + return 0; + } + + /* Set name to driver name + device name if it is empty. */ + if (!v4l2_dev->name[0]) + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", dev->driver->name, dev_name(dev)); + if (dev_get_drvdata(dev)) + v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n"); dev_set_drvdata(dev, v4l2_dev); return 0; } @@ -45,10 +54,11 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) { struct v4l2_subdev *sd, *next; - if (v4l2_dev == NULL || v4l2_dev->dev == NULL) + if (v4l2_dev == NULL) return; - dev_set_drvdata(v4l2_dev->dev, NULL); - /* unregister subdevs */ + if (v4l2_dev->dev) + dev_set_drvdata(v4l2_dev->dev, NULL); + /* Unregister subdevs */ list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) v4l2_device_unregister_subdev(sd); @@ -56,19 +66,20 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) } EXPORT_SYMBOL_GPL(v4l2_device_unregister); -int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd) +int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd) { /* Check for valid input */ - if (dev == NULL || sd == NULL || !sd->name[0]) + if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) return -EINVAL; /* Warn if we apparently re-register a subdev */ WARN_ON(sd->dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; - sd->dev = dev; - spin_lock(&dev->lock); - list_add_tail(&sd->list, &dev->subdevs); - spin_unlock(&dev->lock); + sd->dev = v4l2_dev; + spin_lock(&v4l2_dev->lock); + list_add_tail(&sd->list, &v4l2_dev->subdevs); + spin_unlock(&v4l2_dev->lock); return 0; } EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); diff --git a/linux/include/media/v4l2-device.h b/linux/include/media/v4l2-device.h index 55e41afd9..5d7146dc2 100644 --- a/linux/include/media/v4l2-device.h +++ b/linux/include/media/v4l2-device.h @@ -33,7 +33,9 @@ #define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16) struct v4l2_device { - /* dev->driver_data points to this struct */ + /* dev->driver_data points to this struct. + Note: dev might be NULL if there is no parent device + as is the case with e.g. ISA devices. */ struct device *dev; /* used to keep track of the registered subdevs */ struct list_head subdevs; @@ -44,7 +46,9 @@ struct v4l2_device { char name[V4L2_DEVICE_NAME_SIZE]; }; -/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev */ +/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. + dev may be NULL in rare cases (ISA devices). In that case you + must fill in the v4l2_dev->name field before calling this function. */ int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); /* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); @@ -52,23 +56,24 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); /* Register a subdev with a v4l2 device. While registered the subdev module is marked as in-use. An error is returned if the module is no longer loaded when you attempt to register it. */ -int __must_check v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd); +int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd); /* Unregister a subdev with a v4l2 device. Can also be called if the subdev wasn't registered. In that case it will do nothing. */ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /* Iterate over all subdevs. */ -#define v4l2_device_for_each_subdev(sd, dev) \ - list_for_each_entry(sd, &(dev)->subdevs, list) +#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) /* Call the specified callback for all subdevs matching the condition. Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define __v4l2_device_call_subdevs(dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ do { \ struct v4l2_subdev *sd; \ \ - list_for_each_entry(sd, &(dev)->subdevs, list) \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) \ if ((cond) && sd->ops->o && sd->ops->o->f) \ sd->ops->o->f(sd , ##args); \ } while (0) @@ -77,12 +82,12 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); 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_call_subdevs_until_err(dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ ({ \ struct v4l2_subdev *sd; \ long err = 0; \ \ - list_for_each_entry(sd, &(dev)->subdevs, list) { \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) { \ if ((cond) && sd->ops->o && sd->ops->o->f) \ err = sd->ops->o->f(sd , ##args); \ if (err && err != -ENOIOCTLCMD) \ @@ -94,16 +99,16 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /* Call the specified callback for all subdevs matching grp_id (if 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_call_all(dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs(dev, \ +#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ + __v4l2_device_call_subdevs(v4l2_dev, \ !(grpid) || sd->grp_id == (grpid), o, f , ##args) /* Call the specified callback for all subdevs matching grp_id (if 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_call_until_err(dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs_until_err(dev, \ +#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ + __v4l2_device_call_subdevs_until_err(v4l2_dev, \ !(grpid) || sd->grp_id == (grpid), o, f , ##args) #endif -- cgit v1.2.3 From 951bf44feee86f832f1b68efe05395dfee73a15c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 16:00:53 +0100 Subject: v4l2-subdev: rename dev field to v4l2_dev From: Hans Verkuil Remain consistent in the naming: fields pointing to v4l2_device should be called v4l2_dev. There are too many device-like entities without adding to the confusion by mixing naming conventions. Priority: normal Signed-off-by: Hans Verkuil --- linux/Documentation/video4linux/v4l2-framework.txt | 2 +- linux/drivers/media/video/v4l2-device.c | 12 ++++++------ linux/include/media/v4l2-subdev.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/linux/Documentation/video4linux/v4l2-framework.txt b/linux/Documentation/video4linux/v4l2-framework.txt index e1620e2a3..accc376e9 100644 --- a/linux/Documentation/video4linux/v4l2-framework.txt +++ b/linux/Documentation/video4linux/v4l2-framework.txt @@ -268,7 +268,7 @@ errors (except -ENOIOCTLCMD) occured, then 0 is returned. The second argument to both calls is a group ID. If 0, then all subdevs are called. If non-zero, then only those whose group ID match that value will -be called. Before a bridge driver registers a subdev it can set subdev->grp_id +be called. Before a bridge driver registers a subdev it can set sd->grp_id to whatever value it wants (it's 0 by default). This value is owned by the bridge driver and the sub-device driver will never modify or use it. diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c index cb8234437..35e42e947 100644 --- a/linux/drivers/media/video/v4l2-device.c +++ b/linux/drivers/media/video/v4l2-device.c @@ -73,10 +73,10 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) return -EINVAL; /* Warn if we apparently re-register a subdev */ - WARN_ON(sd->dev != NULL); + WARN_ON(sd->v4l2_dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; - sd->dev = v4l2_dev; + sd->v4l2_dev = v4l2_dev; spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -87,12 +87,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) { /* return if it isn't registered */ - if (sd == NULL || sd->dev == NULL) + if (sd == NULL || sd->v4l2_dev == NULL) return; - spin_lock(&sd->dev->lock); + spin_lock(&sd->v4l2_dev->lock); list_del(&sd->list); - spin_unlock(&sd->dev->lock); - sd->dev = NULL; + spin_unlock(&sd->v4l2_dev->lock); + sd->v4l2_dev = NULL; module_put(sd->owner); } EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); diff --git a/linux/include/media/v4l2-subdev.h b/linux/include/media/v4l2-subdev.h index cd640c6f0..05b69652e 100644 --- a/linux/include/media/v4l2-subdev.h +++ b/linux/include/media/v4l2-subdev.h @@ -137,7 +137,7 @@ struct v4l2_subdev_ops { struct v4l2_subdev { struct list_head list; struct module *owner; - struct v4l2_device *dev; + struct v4l2_device *v4l2_dev; const struct v4l2_subdev_ops *ops; /* name must be unique */ char name[V4L2_SUBDEV_NAME_SIZE]; @@ -176,7 +176,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, /* ops->core MUST be set */ BUG_ON(!ops || !ops->core); sd->ops = ops; - sd->dev = NULL; + sd->v4l2_dev = NULL; sd->name[0] = '\0'; sd->grp_id = 0; sd->priv = NULL; -- cgit v1.2.3 From f9bd48b87f02902de6b355af1489669baaad39b5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:23:12 +0100 Subject: vivi: introduce v4l2_device and do several cleanups From: Hans Verkuil - add v4l2_device - remove BKL - make the debug parameter settable on the fly - set bus_info in querycap Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 258 ++++++++++++++++++++------------------- 1 file changed, 130 insertions(+), 128 deletions(-) diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index e089cbd27..e4cb33ca0 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -34,14 +34,15 @@ #include #endif #include -#include -#include -#include #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) #include #endif +#include +#include +#include +#include "font.h" #define VIVI_MODULE_NAME "vivi" @@ -50,18 +51,32 @@ #define WAKE_DENOMINATOR 1001 #define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ -#include "font.h" - #define VIVI_MAJOR_VERSION 0 -#define VIVI_MINOR_VERSION 5 +#define VIVI_MINOR_VERSION 6 #define VIVI_RELEASE 0 #define VIVI_VERSION \ KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) -/* Declare static vars that will be used as parameters */ -static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ -static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -static int n_devs = 1; /* Number of virtual devices */ +MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); +MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); +MODULE_LICENSE("Dual BSD/GPL"); + +static unsigned video_nr = -1; +module_param(video_nr, uint, 0644); +MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect"); + +static unsigned n_devs = 1; +module_param(n_devs, uint, 0644); +MODULE_PARM_DESC(n_devs, "number of video devices to create"); + +static unsigned debug; +module_param(debug, uint, 0644); +MODULE_PARM_DESC(debug, "activates debug info"); + +static unsigned int vid_limit = 16; +module_param(vid_limit, uint, 0644); +MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); + /* supported controls */ static struct v4l2_queryctrl vivi_qctrl[] = { @@ -115,11 +130,8 @@ static struct v4l2_queryctrl vivi_qctrl[] = { static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; -#define dprintk(dev, level, fmt, arg...) \ - do { \ - if (dev->vfd->debug >= (level)) \ - printk(KERN_DEBUG "vivi: " fmt , ## arg); \ - } while (0) +#define dprintk(dev, level, fmt, arg...) \ + v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) /* ------------------------------------------------------------------ Basic structures @@ -209,6 +221,7 @@ static LIST_HEAD(vivi_devlist); struct vivi_dev { struct list_head vivi_devlist; + struct v4l2_device v4l2_dev; spinlock_t slock; struct mutex mutex; @@ -659,7 +672,7 @@ static int vivi_start_thread(struct vivi_fh *fh) dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); if (IS_ERR(dma_q->kthread)) { - printk(KERN_ERR "vivi: kernel_thread() failed\n"); + v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); return PTR_ERR(dma_q->kthread); } /* Wakes thread */ @@ -802,8 +815,12 @@ static struct videobuf_queue_ops vivi_video_qops = { static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; + strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); + strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); cap->version = VIVI_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | @@ -1127,32 +1144,21 @@ static int vidioc_s_ctrl(struct file *file, void *priv, static int vivi_open(struct file *file) { - int minor = video_devdata(file)->minor; - struct vivi_dev *dev; + struct vivi_dev *dev = video_drvdata(file); struct vivi_fh *fh = NULL; int i; int retval = 0; - printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor); - - lock_kernel(); - list_for_each_entry(dev, &vivi_devlist, vivi_devlist) - if (dev->vfd->minor == minor) - goto found; - unlock_kernel(); - return -ENODEV; - -found: mutex_lock(&dev->mutex); dev->users++; if (dev->users > 1) { dev->users--; - retval = -EBUSY; - goto unlock; + mutex_unlock(&dev->mutex); + return -EBUSY; } - dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor, + dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num, v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users); /* allocate + initialize per filehandle data */ @@ -1160,14 +1166,11 @@ found: if (NULL == fh) { dev->users--; retval = -ENOMEM; - goto unlock; } -unlock: mutex_unlock(&dev->mutex); - if (retval) { - unlock_kernel(); + + if (retval) return retval; - } file->private_data = fh; fh->dev = dev; @@ -1196,7 +1199,6 @@ unlock: sizeof(struct vivi_buffer), fh); vivi_start_thread(fh); - unlock_kernel(); return 0; } @@ -1252,32 +1254,6 @@ static int vivi_close(struct file *file) return 0; } -static int vivi_release(void) -{ - struct vivi_dev *dev; - struct list_head *list; - - while (!list_empty(&vivi_devlist)) { - list = vivi_devlist.next; - list_del(list); - dev = list_entry(list, struct vivi_dev, vivi_devlist); - - if (-1 != dev->vfd->minor) { - printk(KERN_INFO "%s: unregistering /dev/video%d\n", - VIVI_MODULE_NAME, dev->vfd->num); - video_unregister_device(dev->vfd); - } else { - printk(KERN_INFO "%s: releasing /dev/video%d\n", - VIVI_MODULE_NAME, dev->vfd->num); - video_device_release(dev->vfd); - } - - kfree(dev); - } - - return 0; -} - static int vivi_mmap(struct file *file, struct vm_area_struct *vma) { struct vivi_fh *fh = file->private_data; @@ -1340,84 +1316,126 @@ static struct video_device vivi_template = { .tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; + /* ----------------------------------------------------------------- Initialization and module stuff ------------------------------------------------------------------*/ -/* This routine allocates from 1 to n_devs virtual drivers. +static int vivi_release(void) +{ + struct vivi_dev *dev; + struct list_head *list; - The real maximum number of virtual drivers will depend on how many drivers - will succeed. This is limited to the maximum number of devices that - videodev supports, which is equal to VIDEO_NUM_DEVICES. - */ -static int __init vivi_init(void) + while (!list_empty(&vivi_devlist)) { + list = vivi_devlist.next; + list_del(list); + dev = list_entry(list, struct vivi_dev, vivi_devlist); + + v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n", + dev->vfd->num); + video_unregister_device(dev->vfd); + v4l2_device_unregister(&dev->v4l2_dev); + kfree(dev); + } + + return 0; +} + +static int __init vivi_create_instance(int i) { - int ret = -ENOMEM, i; struct vivi_dev *dev; struct video_device *vfd; + int ret; - if (n_devs <= 0) - n_devs = 1; + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; - for (i = 0; i < n_devs; i++) { - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - break; + snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), + "%s-%03d", VIVI_MODULE_NAME, i); + ret = v4l2_device_register(NULL, &dev->v4l2_dev); + if (ret) + goto free_dev; - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - init_waitqueue_head(&dev->vidq.wq); + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + init_waitqueue_head(&dev->vidq.wq); - /* initialize locks */ - spin_lock_init(&dev->slock); - mutex_init(&dev->mutex); + /* initialize locks */ + spin_lock_init(&dev->slock); + mutex_init(&dev->mutex); - vfd = video_device_alloc(); - if (!vfd) { - kfree(dev); - break; - } + ret = -ENOMEM; + vfd = video_device_alloc(); + if (!vfd) + goto unreg_dev; - *vfd = vivi_template; + *vfd = vivi_template; - ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); - if (ret < 0) { - video_device_release(vfd); - kfree(dev); + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); + if (ret < 0) + goto rel_vdev; - /* If some registers succeeded, keep driver */ - if (i) - ret = 0; + video_set_drvdata(vfd, dev); - break; - } + /* Now that everything is fine, let's add it to device list */ + list_add_tail(&dev->vivi_devlist, &vivi_devlist); - /* Now that everything is fine, let's add it to device list */ - list_add_tail(&dev->vivi_devlist, &vivi_devlist); + snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", + vivi_template.name, vfd->num); - snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", - vivi_template.name, vfd->minor); + if (video_nr >= 0) + video_nr++; - if (video_nr >= 0) - video_nr++; + dev->vfd = vfd; + v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n", + vfd->num); + return 0; + +rel_vdev: + video_device_release(vfd); +unreg_dev: + v4l2_device_unregister(&dev->v4l2_dev); +free_dev: + kfree(dev); + return ret; +} - dev->vfd = vfd; - printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", - VIVI_MODULE_NAME, vfd->num); +/* This routine allocates from 1 to n_devs virtual drivers. + + The real maximum number of virtual drivers will depend on how many drivers + will succeed. This is limited to the maximum number of devices that + videodev supports, which is equal to VIDEO_NUM_DEVICES. + */ +static int __init vivi_init(void) +{ + int ret, i; + + if (n_devs <= 0) + n_devs = 1; + + for (i = 0; i < n_devs; i++) { + ret = vivi_create_instance(i); + if (ret) { + /* If some instantiations succeeded, keep driver */ + if (i) + ret = 0; + break; + } } if (ret < 0) { - vivi_release(); printk(KERN_INFO "Error %d while loading vivi driver\n", ret); - } else { - printk(KERN_INFO "Video Technology Magazine Virtual Video " + return ret; + } + + printk(KERN_INFO "Video Technology Magazine Virtual Video " "Capture Board ver %u.%u.%u successfully loaded.\n", (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, VIVI_VERSION & 0xFF); - /* n_devs will reflect the actual number of allocated devices */ - n_devs = i; - } + /* n_devs will reflect the actual number of allocated devices */ + n_devs = i; return ret; } @@ -1429,19 +1447,3 @@ static void __exit vivi_exit(void) module_init(vivi_init); module_exit(vivi_exit); - -MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board"); -MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); -MODULE_LICENSE("Dual BSD/GPL"); - -module_param(video_nr, uint, 0444); -MODULE_PARM_DESC(video_nr, "video iminor start number"); - -module_param(n_devs, uint, 0444); -MODULE_PARM_DESC(n_devs, "number of video devices to create"); - -module_param_named(debug, vivi_template.debug, int, 0444); -MODULE_PARM_DESC(debug, "activates debug info"); - -module_param(vid_limit, int, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); -- cgit v1.2.3 From c70e5dd6b23d260a1294ff4b23f49ccd78999c86 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:43:44 +0100 Subject: vivi: controls are per-device, not global. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index e4cb33ca0..207dfa58f 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -128,8 +128,6 @@ static struct v4l2_queryctrl vivi_qctrl[] = { } }; -static int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; - #define dprintk(dev, level, fmt, arg...) \ v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg) @@ -242,6 +240,9 @@ struct vivi_dev { /* Input Number */ int input; + + /* Control 'registers' */ + int qctl_regs[ARRAY_SIZE(vivi_qctrl)]; }; struct vivi_fh { @@ -1111,12 +1112,14 @@ static int vidioc_queryctrl(struct file *file, void *priv, static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - ctrl->value = qctl_regs[i]; - return (0); + ctrl->value = dev->qctl_regs[i]; + return 0; } return -EINVAL; @@ -1124,16 +1127,18 @@ static int vidioc_g_ctrl(struct file *file, void *priv, static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { + struct vivi_fh *fh = priv; + struct vivi_dev *dev = fh->dev; int i; for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) if (ctrl->id == vivi_qctrl[i].id) { - if (ctrl->value < vivi_qctrl[i].minimum - || ctrl->value > vivi_qctrl[i].maximum) { - return (-ERANGE); - } - qctl_regs[i] = ctrl->value; - return (0); + if (ctrl->value < vivi_qctrl[i].minimum || + ctrl->value > vivi_qctrl[i].maximum) { + return -ERANGE; + } + dev->qctl_regs[i] = ctrl->value; + return 0; } return -EINVAL; } @@ -1146,7 +1151,6 @@ static int vivi_open(struct file *file) { struct vivi_dev *dev = video_drvdata(file); struct vivi_fh *fh = NULL; - int i; int retval = 0; mutex_lock(&dev->mutex); @@ -1180,10 +1184,6 @@ static int vivi_open(struct file *file) fh->width = 640; fh->height = 480; - /* Put all controls at a sane state */ - for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) - qctl_regs[i] = vivi_qctrl[i].default_value; - /* Resets frame counters */ dev->h = 0; dev->m = 0; @@ -1341,18 +1341,18 @@ static int vivi_release(void) return 0; } -static int __init vivi_create_instance(int i) +static int __init vivi_create_instance(int inst) { struct vivi_dev *dev; struct video_device *vfd; - int ret; + int ret, i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), - "%s-%03d", VIVI_MODULE_NAME, i); + "%s-%03d", VIVI_MODULE_NAME, inst); ret = v4l2_device_register(NULL, &dev->v4l2_dev); if (ret) goto free_dev; @@ -1378,6 +1378,10 @@ static int __init vivi_create_instance(int i) video_set_drvdata(vfd, dev); + /* Set all controls to their default value. */ + for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++) + dev->qctl_regs[i] = vivi_qctrl[i].default_value; + /* Now that everything is fine, let's add it to device list */ list_add_tail(&dev->vivi_devlist, &vivi_devlist); -- cgit v1.2.3 From 9446aad394fc912dc47f17e7638357edfd470ded Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 14 Feb 2009 17:50:19 +0100 Subject: vivi: add slider flag to controls. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/vivi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 207dfa58f..76f7dfc32 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -87,7 +87,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 65535, .step = 65535/100, .default_value = 65535, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, .type = V4L2_CTRL_TYPE_INTEGER, }, { .id = V4L2_CID_BRIGHTNESS, @@ -97,7 +97,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 1, .default_value = 127, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, @@ -106,7 +106,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 0x10, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, @@ -115,7 +115,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 255, .step = 0x1, .default_value = 127, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, }, { .id = V4L2_CID_HUE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -124,7 +124,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = { .maximum = 127, .step = 0x1, .default_value = 0, - .flags = 0, + .flags = V4L2_CTRL_FLAG_SLIDER, } }; -- cgit v1.2.3 From bdff40c8e0a3b0971c67f28db1b0f9b2fe581313 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 14 Feb 2009 23:26:56 +0100 Subject: uvcvideo: Initialize streaming parameters with the probe control value From: Laurent Pinchart The UVC specification requires SET_CUR requests on the streaming commit control to use values retrieved from a successful GET_CUR request on the probe control. Initialize streaming parameters with the probe control current value to make sure the driver always complies. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_video.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 04c791213..a4034ccb2 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -1030,11 +1030,20 @@ int uvc_video_init(struct uvc_video_device *video) */ usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); - /* Some webcams don't suport GET_DEF requests on the probe control. We - * fall back to GET_CUR if GET_DEF fails. + /* Set the streaming probe control with default streaming parameters + * retrieved from the device. Webcams that don't suport GET_DEF + * requests on the probe control will just keep their current streaming + * parameters. */ - if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 && - (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) + if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0) + uvc_set_video_ctrl(video, probe, 1); + + /* Initialize the streaming parameters with the probe control current + * value. This makes sure SET_CUR requests on the streaming commit + * control will always use values retrieved from a successful GET_CUR + * request on the probe control, as required by the UVC specification. + */ + if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) return ret; /* Check if the default format descriptor exists. Use the first -- cgit v1.2.3 From e2a760f26ff7124de2bc6bed4647962dd7078d1b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 14 Feb 2009 23:39:08 +0100 Subject: uvcvideo: Ignore empty bulk URBs From: Laurent Pinchart Devices may send a zero-length packet to signal the end of a bulk payload. If the payload size is a multiple of the URB size the zero-length packet will be received by the URB completion handler. Handle this by ignoring all empty URBs. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index a4034ccb2..328910855 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -540,6 +540,9 @@ static void uvc_video_decode_bulk(struct urb *urb, u8 *mem; int len, ret; + if (urb->actual_length == 0) + return; + mem = urb->transfer_buffer; len = urb->actual_length; video->bulk.payload_size += len; -- cgit v1.2.3 From b25818a3a4e324f54c59786922c73867af099253 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 16 Feb 2009 21:41:52 +0100 Subject: uvcvideo: Add quirk to override wrong bandwidth value for Vimicro devices From: Laurent Pinchart At least 3 Vimicro cameras (0x332d, 0x3410 and 0x3420) fail to return correct bandwidth information. The first model rounds the value provided by the host to the nearest supported packet size, while the other two always request the maximum bandwidth. Introduce a device quirk to override the value returned by the device with an estimated bandwidth computed by the driver from the frame size and frame rate, and enable it for all Vimicro cameras. Priority: normal Signed-off-by: Laurent Pinchart --- linux/drivers/media/video/uvc/uvc_driver.c | 9 ++++++++ linux/drivers/media/video/uvc/uvc_video.c | 34 ++++++++++++++++++++++++++---- linux/drivers/media/video/uvc/uvcvideo.h | 1 + 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index 2a41eb418..0d2d87198 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -1863,6 +1863,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* ViMicro */ + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0ac8, + .idProduct = 0x0000, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, /* MT6227 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 328910855..82a9999b6 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, return 0; } -static void uvc_fixup_buffer_size(struct uvc_video_device *video, +static void uvc_fixup_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl) { struct uvc_format *format; @@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, video->dev->uvc_version < 0x0110)) ctrl->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize; + + if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && + video->streaming->intf->num_altsetting > 1) { + u32 interval; + u32 bandwidth; + + interval = (ctrl->dwFrameInterval > 100000) + ? ctrl->dwFrameInterval + : frame->dwFrameInterval[0]; + + /* Compute a bandwidth estimation by multiplying the frame + * size by the number of video frames per second, divide the + * result by the number of USB frames (or micro-frames for + * high-speed devices) per second and add the UVC header size + * (assumed to be 12 bytes long). + */ + bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; + bandwidth *= 10000000 / interval + 1; + bandwidth /= 1000; + if (video->dev->udev->speed == USB_SPEED_HIGH) + bandwidth /= 8; + bandwidth += 12; + + ctrl->dwMaxPayloadTransferSize = bandwidth; + } } static int uvc_get_video_ctrl(struct uvc_video_device *video, @@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, ctrl->bMaxVersion = 0; } - /* Some broken devices return a null or wrong dwMaxVideoFrameSize. - * Try to get the value from the format and frame descriptors. + /* Some broken devices return null or wrong dwMaxVideoFrameSize and + * dwMaxPayloadTransferSize fields. Try to get the value from the + * format and frame descriptors. */ - uvc_fixup_buffer_size(video, ctrl); + uvc_fixup_video_ctrl(video, ctrl); ret = 0; out: diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h index 408b8b846..53d5c9e0c 100644 --- a/linux/drivers/media/video/uvc/uvcvideo.h +++ b/linux/drivers/media/video/uvc/uvcvideo.h @@ -315,6 +315,7 @@ struct uvc_xu_control { #define UVC_QUIRK_STREAM_NO_FID 0x00000010 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 +#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 -- cgit v1.2.3 From b598952580418f91c7bd0dc9d42802a052e84a6e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Feb 2009 10:11:12 -0300 Subject: backport include changes on some .h files From: Mauro Carvalho Chehab kernel-sync: Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/dvb/audio.h | 5 ----- linux/include/linux/dvb/dmx.h | 2 +- linux/include/linux/dvb/frontend.h | 3 +-- linux/include/linux/dvb/net.h | 3 +-- linux/include/linux/dvb/video.h | 7 ++----- linux/include/linux/video_decoder.h | 2 ++ linux/include/linux/videodev.h | 1 + linux/include/media/videobuf-dma-sg.h | 2 +- 8 files changed, 9 insertions(+), 16 deletions(-) diff --git a/linux/include/linux/dvb/audio.h b/linux/include/linux/dvb/audio.h index 89412e18f..bb0df2aae 100644 --- a/linux/include/linux/dvb/audio.h +++ b/linux/include/linux/dvb/audio.h @@ -24,12 +24,7 @@ #ifndef _DVBAUDIO_H_ #define _DVBAUDIO_H_ -#ifdef __KERNEL__ #include -#else -#include -#endif - typedef enum { AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ diff --git a/linux/include/linux/dvb/dmx.h b/linux/include/linux/dvb/dmx.h index 402fb7a8d..fef943738 100644 --- a/linux/include/linux/dvb/dmx.h +++ b/linux/include/linux/dvb/dmx.h @@ -24,7 +24,7 @@ #ifndef _DVBDMX_H_ #define _DVBDMX_H_ -#include +#include #ifdef __KERNEL__ #include #else diff --git a/linux/include/linux/dvb/frontend.h b/linux/include/linux/dvb/frontend.h index 61a86e720..6a0405f65 100644 --- a/linux/include/linux/dvb/frontend.h +++ b/linux/include/linux/dvb/frontend.h @@ -26,8 +26,7 @@ #ifndef _DVBFRONTEND_H_ #define _DVBFRONTEND_H_ -#include - +#include typedef enum fe_type { FE_QPSK, diff --git a/linux/include/linux/dvb/net.h b/linux/include/linux/dvb/net.h index 5be474bf0..f451e7eb0 100644 --- a/linux/include/linux/dvb/net.h +++ b/linux/include/linux/dvb/net.h @@ -24,8 +24,7 @@ #ifndef _DVBNET_H_ #define _DVBNET_H_ -#include - +#include struct dvb_net_if { __u16 pid; diff --git a/linux/include/linux/dvb/video.h b/linux/include/linux/dvb/video.h index 50839fe9e..bd49c3ebf 100644 --- a/linux/include/linux/dvb/video.h +++ b/linux/include/linux/dvb/video.h @@ -24,17 +24,14 @@ #ifndef _DVBVIDEO_H_ #define _DVBVIDEO_H_ -#include - -#ifdef __KERNEL__ #include +#ifdef __KERNEL__ +#include #else -#include #include #include #endif - typedef enum { VIDEO_FORMAT_4_3, /* Select 4:3 format */ VIDEO_FORMAT_16_9, /* Select 16:9 format. */ diff --git a/linux/include/linux/video_decoder.h b/linux/include/linux/video_decoder.h index 121e26da2..e26c0c86a 100644 --- a/linux/include/linux/video_decoder.h +++ b/linux/include/linux/video_decoder.h @@ -1,6 +1,8 @@ #ifndef _LINUX_VIDEO_DECODER_H #define _LINUX_VIDEO_DECODER_H +#include + #define HAVE_VIDEO_DECODER 1 struct video_decoder_capability { /* this name is too long */ diff --git a/linux/include/linux/videodev.h b/linux/include/linux/videodev.h index 15a653d41..837f392fb 100644 --- a/linux/include/linux/videodev.h +++ b/linux/include/linux/videodev.h @@ -12,6 +12,7 @@ #ifndef __LINUX_VIDEODEV_H #define __LINUX_VIDEODEV_H +#include #include #include diff --git a/linux/include/media/videobuf-dma-sg.h b/linux/include/media/videobuf-dma-sg.h index 90edd22d3..dda47f008 100644 --- a/linux/include/media/videobuf-dma-sg.h +++ b/linux/include/media/videobuf-dma-sg.h @@ -49,7 +49,7 @@ struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages, * does memory allocation too using vmalloc_32(). * * videobuf_dma_*() - * see Documentation/DMA-mapping.txt, these functions to + * see Documentation/PCI/PCI-DMA-mapping.txt, these functions to * basically the same. The map function does also build a * scatterlist for the buffer (and unmap frees it ...) * -- cgit v1.2.3 From 538850e6819a36200323bf1469eb8544e4f4e0c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 17 Feb 2009 13:46:22 +0000 Subject: Drop test for kernel version 2.6.15 From: Jean Delvare The v4l-dvb repository supports kernel versions 2.6.16 and later only, so no need to test for kernel version 2.6.15. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-usb/af9015.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/linux/drivers/media/dvb/dvb-usb/af9015.c b/linux/drivers/media/dvb/dvb-usb/af9015.c index 88a365ad9..ca7609583 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9015.c +++ b/linux/drivers/media/dvb/dvb-usb/af9015.c @@ -1507,9 +1507,6 @@ static void af9015_usb_device_exit(struct usb_interface *intf) /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver af9015_usb_driver = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) - .owner = THIS_MODULE, -#endif .name = "dvb_usb_af9015", .probe = af9015_usb_probe, .disconnect = af9015_usb_device_exit, -- cgit v1.2.3 From ec587d5a2c052529e35797c42522fde8a9efa1b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Feb 2009 12:36:38 -0300 Subject: sq905 require 2.6.20 or upper From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- v4l/versions.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/v4l/versions.txt b/v4l/versions.txt index ac0266047..8435046c5 100644 --- a/v4l/versions.txt +++ b/v4l/versions.txt @@ -37,6 +37,8 @@ USB_SI470X USB_GSPCA_FINEPIX # uses linux/hid.h and struct delayed_work USB_SI470X +# due to INIT_WORK changes +USB_GSPCA_SQ905 [2.6.19] #This driver were developed at kernel 2.6.19, requiring vmalloc_user/remap_vmalloc_range -- cgit v1.2.3 From ea5c2ae318fda3731d4fe711b704122a62a7dce9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 18 Feb 2009 10:11:10 +0100 Subject: [PATCH] V4L: missing parentheses? From: Roel Kluin Add missing parentheses Signed-off-by: Roel Kluin Acked-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/common/tuners/tda18271-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/common/tuners/tda18271-common.c b/linux/drivers/media/common/tuners/tda18271-common.c index a8fb96698..a49facb7b 100644 --- a/linux/drivers/media/common/tuners/tda18271-common.c +++ b/linux/drivers/media/common/tuners/tda18271-common.c @@ -558,9 +558,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe, tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ - regs[R_EP3] |= sm ? (1 << 7) : 0 | - sm_lt ? (1 << 6) : 0 | - sm_xt ? (1 << 5) : 0; + regs[R_EP3] |= (sm ? (1 << 7) : 0) | + (sm_lt ? (1 << 6) : 0) | + (sm_xt ? (1 << 5) : 0); return tda18271_write_regs(fe, R_EP3, 1); } -- cgit v1.2.3 From 0e80661eedb37a2d8810e6de027c2530db814c27 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:22:16 +0100 Subject: saa7115: don't access reg 0x87 if it is not present. From: Hans Verkuil Devices like the saa7111 do not have this register, so check for this before using it. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 9fbb93775..2e868fade 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1309,11 +1309,12 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable) v4l2_dbg(1, debug, sd, "%s output\n", enable ? "enable" : "disable"); - if (state->enable != enable) { - state->enable = enable; - saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, - state->enable); - } + if (state->enable == enable) + return 0; + state->enable = enable; + if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED)) + return 0; + saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable); return 0; } -- cgit v1.2.3 From 6fdf67ebdaa0672d9f580433d4331b451ada01bd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:23:38 +0100 Subject: saa7185: add colorbar support. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7185.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 195e2f415..68bec4d5d 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -282,6 +282,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) switch (*iarg) { case 0: + /* turn off colorbar */ + saa7185_write(client, 0x3a, 0x0f); /* Switch RTCE to 1 */ saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08); @@ -289,6 +291,8 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) break; case 1: + /* turn off colorbar */ + saa7185_write(client, 0x3a, 0x0f); /* Switch RTCE to 0 */ saa7185_write(client, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00); @@ -296,6 +300,16 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) saa7185_write(client, 0x6e, 0x00); break; + case 2: + /* turn on colorbar */ + saa7185_write(client, 0x3a, 0x8f); + /* Switch RTCE to 0 */ + saa7185_write(client, 0x61, + (encoder->reg[0x61] & 0xf7) | 0x08); + /* SW: a slight sync problem... */ + saa7185_write(client, 0x6e, 0x01); + break; + default: return -EINVAL; } -- cgit v1.2.3 From d508d21a881363ed8a29131a5d766a17562d9596 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 16:35:33 +0100 Subject: saa7115: add querystd and g_input_status support for zoran. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/saa7115.c | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c index 2e868fade..169b01f6d 100644 --- a/linux/drivers/media/video/saa7115.c +++ b/linux/drivers/media/video/saa7115.c @@ -1372,6 +1372,47 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat } } +static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) +{ + struct saa711x_state *state = to_state(sd); + int reg1e; + + *std = V4L2_STD_ALL; + if (state->ident != V4L2_IDENT_SAA7115) + return 0; + reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); + + switch (reg1e & 0x03) { + case 1: + *std = V4L2_STD_NTSC; + break; + case 2: + *std = V4L2_STD_PAL; + break; + case 3: + *std = V4L2_STD_SECAM; + break; + default: + break; + } + return 0; +} + +static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status) +{ + struct saa711x_state *state = to_state(sd); + int reg1e = 0x80; + int reg1f; + + *status = V4L2_IN_ST_NO_SIGNAL; + if (state->ident == V4L2_IDENT_SAA7115) + reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC); + reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC); + if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80) + *status = 0; + return 0; +} + #ifdef CONFIG_VIDEO_ADV_DEBUG static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { @@ -1495,6 +1536,8 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = { .g_vbi_data = saa711x_g_vbi_data, .decode_vbi_line = saa711x_decode_vbi_line, .s_stream = saa711x_s_stream, + .querystd = saa711x_querystd, + .g_input_status = saa711x_g_input_status, }; static const struct v4l2_subdev_ops saa711x_ops = { -- cgit v1.2.3 From 01293c4d013ac24226a4b52660d28c2fe85fe3fa Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:13:31 +0100 Subject: zoran: convert to video_ioctl2 and remove 'ready_to_be_freed' hack. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 2 - linux/drivers/media/video/zoran/zoran_driver.c | 2557 +++++++++++------------- 2 files changed, 1114 insertions(+), 1445 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index e873a9162..1bf540cb5 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -312,7 +312,6 @@ struct zoran_jpg_struct { struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ u8 need_contiguous; /* Flag if contiguous buffers are needed */ }; @@ -321,7 +320,6 @@ struct zoran_v4l_struct { struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */ int num_buffers, buffer_size; u8 allocated; /* Flag if buffers are allocated */ - u8 ready_to_be_freed; /* hack - see zoran_driver.c */ }; struct zoran; diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 798745c0a..afbb18b89 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -321,11 +321,6 @@ v4l_fbuffer_alloc (struct file *file) unsigned long pmem = 0; #endif - /* we might have old buffers lying around... */ - if (fh->v4l_buffers.ready_to_be_freed) { - v4l_fbuffer_free(file); - } - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, @@ -486,7 +481,6 @@ v4l_fbuffer_free (struct file *file) } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; } /* @@ -531,11 +525,6 @@ jpg_fbuffer_alloc (struct file *file) int i, j, off; unsigned long mem; - /* we might have old buffers lying around */ - if (fh->jpg_buffers.ready_to_be_freed) { - jpg_fbuffer_free(file); - } - for (i = 0; i < fh->jpg_buffers.num_buffers; i++) { if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, @@ -678,7 +667,6 @@ jpg_fbuffer_free (struct file *file) } fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; } /* @@ -722,7 +710,7 @@ zoran_v4l_set_format (struct file *file, if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { dprintk(1, KERN_ERR - "%s: v4l_set_format() - wrong frame alingment\n", + "%s: v4l_set_format() - wrong frame alignment\n", ZR_DEVNAME(zr)); return -EINVAL; } @@ -1187,7 +1175,6 @@ zoran_open_init_session (struct file *file) fh->v4l_buffers.buffer[i].bs.frame = i; } fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 0; fh->v4l_buffers.active = ZORAN_FREE; fh->v4l_buffers.buffer_size = v4l_bufsize; fh->v4l_buffers.num_buffers = v4l_nbufs; @@ -1203,7 +1190,6 @@ zoran_open_init_session (struct file *file) } fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous; fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 0; fh->jpg_buffers.active = ZORAN_FREE; fh->jpg_buffers.buffer_size = jpg_bufsize; fh->jpg_buffers.num_buffers = jpg_nbufs; @@ -1237,10 +1223,8 @@ zoran_close_end_session (struct file *file) } /* v4l buffers */ - if (fh->v4l_buffers.allocated || - fh->v4l_buffers.ready_to_be_freed) { + if (fh->v4l_buffers.allocated) v4l_fbuffer_free(file); - } /* jpg capture */ if (fh->jpg_buffers.active != ZORAN_FREE) { @@ -1251,10 +1235,8 @@ zoran_close_end_session (struct file *file) } /* jpg buffers */ - if (fh->jpg_buffers.allocated || - fh->jpg_buffers.ready_to_be_freed) { + if (fh->jpg_buffers.allocated) jpg_fbuffer_free(file); - } } /* @@ -1968,38 +1950,13 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ -static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) { - struct zoran_fh *fh = file->private_data; + struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - /* CAREFUL: used in multiple places here */ struct zoran_jpg_settings settings; - /* we might have older buffers lying around... We don't want - * to wait, but we do want to try cleaning them up ASAP. So - * we try to obtain the lock and free them. If that fails, we - * don't do anything and wait for the next turn. In the end, - * zoran_close() or a new allocation will still free them... - * This is just a 'the sooner the better' extra 'feature' - * - * We don't free the buffers right on munmap() because that - * causes oopses (kfree() inside munmap() oopses for no - * apparent reason - it's also not reproduceable in any way, - * but moving the free code outside the munmap() handler fixes - * all this... If someone knows why, please explain me (Ronald) - */ - if (mutex_trylock(&zr->resource_lock)) { - /* we obtained it! Let's try to free some things */ - if (fh->jpg_buffers.ready_to_be_freed) - jpg_fbuffer_free(file); - if (fh->v4l_buffers.ready_to_be_freed) - v4l_fbuffer_free(file); - - mutex_unlock(&zr->resource_lock); - } - switch (cmd) { - case VIDIOCGCAP: { struct video_capability *vcap = arg; @@ -2021,7 +1978,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCGCHAN: { @@ -2052,7 +2008,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: * @@ -2082,11 +2037,10 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* Make sure the changes come into effect */ res = wait_grab_pending(zr); - schan_unlock_and_return: +schan_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGPICT: { @@ -2110,7 +2064,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCSPICT: { @@ -2156,7 +2109,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case VIDIOCCAPTURE: { @@ -2171,7 +2123,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCGWIN: { @@ -2189,7 +2140,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) vwin->clipcount = 0; return 0; } - break; case VIDIOCSWIN: { @@ -2211,7 +2161,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCGFBUF: { @@ -2224,7 +2173,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) mutex_unlock(&zr->resource_lock); return 0; } - break; case VIDIOCSFBUF: { @@ -2257,7 +2205,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case VIDIOCSYNC: { @@ -2273,7 +2220,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) zr->v4l_sync_tail++; return res; } - break; case VIDIOCMCAPTURE: { @@ -2291,7 +2237,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGMBUF: { @@ -2327,12 +2272,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* The next mmap will map the V4L buffers */ fh->map_mode = ZORAN_MAP_MODE_RAW; - v4l1reqbuf_unlock_and_return: +v4l1reqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case VIDIOCGUNIT: { @@ -2348,7 +2292,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; /* * RJ: In principal we could support subcaptures for V4L grabbing. @@ -2362,7 +2305,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) ZR_DEVNAME(zr)); return -EINVAL; } - break; case VIDIOCSCAPTURE: { @@ -2370,7 +2312,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) ZR_DEVNAME(zr)); return -EINVAL; } - break; case BUZIOC_G_PARAMS: { @@ -2417,7 +2358,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return 0; } - break; case BUZIOC_S_PARAMS: { @@ -2466,12 +2406,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) } fh->jpg_settings = settings; - sparams_unlock_and_return: +sparams_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_REQBUFS: { @@ -2521,12 +2460,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* The next mmap will map the MJPEG buffers - could * also be *_PLAY, but it doesn't matter here */ fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - jpgreqbuf_unlock_and_return: +jpgreqbuf_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; } - break; case BUZIOC_QBUF_CAPT: { @@ -2541,7 +2479,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_QBUF_PLAY: { @@ -2556,7 +2493,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_SYNC: { @@ -2571,7 +2507,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; case BUZIOC_G_STATUS: { @@ -2615,7 +2550,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) input = zr->card.input[zr->input].muxsel; decoder_command(zr, DECODER_SET_INPUT, &input); decoder_command(zr, DECODER_SET_NORM, &zr->norm); - gstat_unlock_and_return: +gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { @@ -2634,1599 +2569,1297 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg) return res; } - break; - - /* The new video4linux2 capture interface - much nicer than video4linux1, since - * it allows for integrating the JPEG capturing calls inside standard v4l2 - */ - - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr)); - memset(cap, 0, sizeof(*cap)); - strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); - strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", - pci_name(zr->pci_dev)); - cap->version = - KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, - RELEASE_VERSION); - cap->capabilities = ZORAN_V4L2_VID_FLAGS; - - return 0; + default: + return -EINVAL; } - break; - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - int index = fmt->index, num = -1, i, flag = 0, type = - fmt->type; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n", - ZR_DEVNAME(zr), fmt->index); +static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - flag = ZORAN_FORMAT_CAPTURE; - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - flag = ZORAN_FORMAT_PLAYBACK; - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - flag = ZORAN_FORMAT_OVERLAY; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_ENUM_FMT - unknown type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + memset(cap, 0, sizeof(*cap)); + strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1); + strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(zr->pci_dev)); + cap->version = + KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + RELEASE_VERSION); + cap->capabilities = ZORAN_V4L2_VID_FLAGS; - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].flags & flag) - num++; - if (num == fmt->index) - break; - } - if (fmt->index < 0 /* late, but not too late */ || - i == NUM_FORMATS) - return -EINVAL; + return 0; +} - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); - fmt->pixelformat = zoran_formats[i].fourcc; - if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; +static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) +{ + int num = -1, i; - return 0; + for (i = 0; i < NUM_FORMATS; i++) { + if (zoran_formats[i].flags & flag) + num++; + if (num == fmt->index) + break; } - break; - - case VIDIOC_G_FMT: - { - struct v4l2_format *fmt = arg; - int type = fmt->type; + if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS) + return -EINVAL; - dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr)); + strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1); + fmt->pixelformat = zoran_formats[i].fourcc; + if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + return 0; +} - memset(fmt, 0, sizeof(*fmt)); - fmt->type = type; +static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); +} - mutex_lock(&zr->resource_lock); +static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - fmt->fmt.win.w.left = fh->overlay_settings.x; - fmt->fmt.win.w.top = fh->overlay_settings.y; - fmt->fmt.win.w.width = fh->overlay_settings.width; - fmt->fmt.win.w.height = - fh->overlay_settings.height; - if (fh->overlay_settings.width * 2 > - BUZ_MAX_HEIGHT) - fmt->fmt.win.field = V4L2_FIELD_INTERLACED; - else - fmt->fmt.win.field = V4L2_FIELD_TOP; + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); +} - mutex_unlock(&zr->resource_lock); +static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_fmtdesc *f) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - break; + return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); +} - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - mutex_lock(&zr->resource_lock); - - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && - fh->map_mode == ZORAN_MAP_MODE_RAW) { - - fmt->fmt.pix.width = - fh->v4l_settings.width; - fmt->fmt.pix.height = - fh->v4l_settings.height; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.bytesperline * - fh->v4l_settings.height; - fmt->fmt.pix.pixelformat = - fh->v4l_settings.format->fourcc; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; +static int zoran_g_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - } else { + mutex_lock(&zr->resource_lock); - fmt->fmt.pix.width = - fh->jpg_settings.img_width / - fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = - fh->jpg_settings.img_height / - (fh->jpg_settings.VerDcm * - fh->jpg_settings.TmpDcm); - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.pixelformat = - V4L2_PIX_FMT_MJPEG; - if (fh->jpg_settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_BT : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - } + fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; + fmt->fmt.pix.height = fh->jpg_settings.img_height / + (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; + if (fh->jpg_settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - mutex_unlock(&zr->resource_lock); + mutex_unlock(&zr->resource_lock); + return 0; +} - break; +static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } - return 0; - } - break; + if (fh->map_mode != ZORAN_MAP_MODE_RAW) + return zoran_g_fmt_vid_out(file, fh, fmt); - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt = arg; - int i, res = 0; - __le32 printformat; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", - ZR_DEVNAME(zr), fmt->type); - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - - dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", - fmt->fmt.win.w.left, fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_lock(&zr->resource_lock); - res = - setup_window(file, fmt->fmt.win.w.left, - fmt->fmt.win.w.top, - fmt->fmt.win.w.width, - fmt->fmt.win.w.height, - (struct video_clip __user *) - fmt->fmt.win.clips, - fmt->fmt.win.clipcount, - fmt->fmt.win.bitmap); - mutex_unlock(&zr->resource_lock); - return res; - break; + mutex_lock(&zr->resource_lock); + fmt->fmt.pix.width = fh->v4l_settings.width; + fmt->fmt.pix.height = fh->v4l_settings.height; + fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * + fh->v4l_settings.height; + fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; + mutex_unlock(&zr->resource_lock); + return 0; +} - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - - printformat = - __cpu_to_le32(fmt->fmt.pix.pixelformat); - dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", - fmt->fmt.pix.width, fmt->fmt.pix.height, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - - /* we can be requested to do JPEG/raw playback/capture */ - if (! - (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - fmt->fmt.pix.pixelformat == - V4L2_PIX_FMT_MJPEG))) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n", - ZR_DEVNAME(zr), fmt->type, - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } +static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - settings = fh->jpg_settings; + fmt->fmt.win.w.left = fh->overlay_settings.x; + fmt->fmt.win.w.top = fh->overlay_settings.y; + fmt->fmt.win.w.width = fh->overlay_settings.width; + fmt->fmt.win.w.height = fh->overlay_settings.height; + if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) + fmt->fmt.win.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.win.field = V4L2_FIELD_TOP; - if (fh->v4l_buffers.allocated || - fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtjpg_unlock_and_return; - } + mutex_unlock(&zr->resource_lock); + return 0; +} - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto sfmtjpg_unlock_and_return; - - /* it's ok, so set them */ - fh->jpg_settings = settings; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh-> - jpg_settings); - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = - fh->jpg_buffers.buffer_size; - fmt->fmt.pix.colorspace = - V4L2_COLORSPACE_SMPTE170M; - - /* we hereby abuse this variable to show that - * we're gonna do mjpeg capture */ - fh->map_mode = - (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) ? - ZORAN_MAP_MODE_JPG_REC : - ZORAN_MAP_MODE_JPG_PLAY; - sfmtjpg_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } else { - for (i = 0; i < NUM_FORMATS; i++) - if (fmt->fmt.pix.pixelformat == - zoran_formats[i].fourcc) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n", - ZR_DEVNAME(zr), - fmt->fmt.pix.pixelformat, - (char *) &printformat); - return -EINVAL; - } - mutex_lock(&zr->resource_lock); - if (fh->jpg_buffers.allocated || - (fh->v4l_buffers.allocated && - fh->v4l_buffers.active != - ZORAN_FREE)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - cannot change capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sfmtv4l_unlock_and_return; - } - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - - if ((res = - zoran_v4l_set_format(file, - fmt->fmt.pix. - width, - fmt->fmt.pix. - height, - &zoran_formats - [i]))) - goto sfmtv4l_unlock_and_return; - - /* tell the user the - * results/missing stuff */ - fmt->fmt.pix.bytesperline = - fh->v4l_settings.bytesperline; - fmt->fmt.pix.sizeimage = - fh->v4l_settings.height * - fh->v4l_settings.bytesperline; - fmt->fmt.pix.colorspace = - fh->v4l_settings.format->colorspace; - if (BUZ_MAX_HEIGHT < - (fh->v4l_settings.height * 2)) - fmt->fmt.pix.field = - V4L2_FIELD_INTERLACED; - else - fmt->fmt.pix.field = - V4L2_FIELD_TOP; - - fh->map_mode = ZORAN_MAP_MODE_RAW; - sfmtv4l_unlock_and_return: - mutex_unlock(&zr->resource_lock); - } +static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - break; + mutex_lock(&zr->resource_lock); - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FMT - unsupported type %d\n", - ZR_DEVNAME(zr), fmt->type); - return -EINVAL; - } + if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) + fmt->fmt.win.w.width = BUZ_MAX_WIDTH; + if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) + fmt->fmt.win.w.width = BUZ_MIN_WIDTH; + if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) + fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) + fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; - return res; - } - break; + mutex_unlock(&zr->resource_lock); + return 0; +} - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *fb = arg; +static int zoran_try_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + struct zoran_jpg_settings settings; + int res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr)); + if (fmt->fmt.pix.bytesperline > 0) + return -EINVAL; - memset(fb, 0, sizeof(*fb)); - mutex_lock(&zr->resource_lock); - fb->base = zr->buffer.base; - fb->fmt.width = zr->buffer.width; - fb->fmt.height = zr->buffer.height; - if (zr->overlay_settings.format) { - fb->fmt.pixelformat = - fh->overlay_settings.format->fourcc; - } - fb->fmt.bytesperline = zr->buffer.bytesperline; - mutex_unlock(&zr->resource_lock); - fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; - fb->fmt.field = V4L2_FIELD_INTERLACED; - fb->flags = V4L2_FBUF_FLAG_OVERLAY; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - return 0; - } - break; + mutex_lock(&zr->resource_lock); + settings = fh->jpg_settings; - case VIDIOC_S_FBUF: - { - int i, res = 0; - struct v4l2_framebuffer *fb = arg; - __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto tryfmt_unlock_and_return; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n", - ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline, fb->fmt.pixelformat, - (char *) &printformat); + fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); +tryfmt_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == fb->fmt.pixelformat) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", - ZR_DEVNAME(zr), fb->fmt.pixelformat, - (char *) &printformat); - return -EINVAL; - } +static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i; - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, fb->base, &zoran_formats[i], - fb->fmt.width, fb->fmt.height, - fb->fmt.bytesperline); - mutex_unlock(&zr->resource_lock); + if (fmt->fmt.pix.bytesperline > 0) + return -EINVAL; - return res; - } - break; + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_try_fmt_vid_out(file, fh, fmt); - case VIDIOC_OVERLAY: - { - int *on = arg, res; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n", - ZR_DEVNAME(zr), *on); + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) + break; - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); + if (i == NUM_FORMATS) { mutex_unlock(&zr->resource_lock); - - return res; + return -EINVAL; } - break; - - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - int res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n", - ZR_DEVNAME(zr), req->type); - if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(1, - KERN_ERR - "%s: only MEMORY_MMAP capture is supported, not %d\n", - ZR_DEVNAME(zr), req->memory); - return -EINVAL; - } + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) + fmt->fmt.pix.width = BUZ_MIN_WIDTH; + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) + fmt->fmt.pix.height = BUZ_MIN_HEIGHT; + mutex_unlock(&zr->resource_lock); - mutex_lock(&zr->resource_lock); + return 0; +} - if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - buffers allready allocated\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto v4l2reqbuf_unlock_and_return; - } +static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; + + dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", + fmt->fmt.win.w.left, fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_lock(&zr->resource_lock); + res = setup_window(file, fmt->fmt.win.w.left, + fmt->fmt.win.w.top, + fmt->fmt.win.w.width, + fmt->fmt.win.w.height, + (struct video_clip __user *) + fmt->fmt.win.clips, + fmt->fmt.win.clipcount, + fmt->fmt.win.bitmap); + mutex_unlock(&zr->resource_lock); + return res; +} - if (fh->map_mode == ZORAN_MAP_MODE_RAW && - req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { +static int zoran_s_fmt_vid_out(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); + struct zoran_jpg_settings settings; + int res = 0; - /* control user input */ - if (req->count < 2) - req->count = 2; - if (req->count > v4l_nbufs) - req->count = v4l_nbufs; - fh->v4l_buffers.num_buffers = req->count; + dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", + fmt->fmt.pix.width, fmt->fmt.pix.height, + fmt->fmt.pix.pixelformat, + (char *) &printformat); + if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } + mutex_lock(&zr->resource_lock); - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; + settings = fh->jpg_settings; - } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || - fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtjpg_unlock_and_return; + } - /* we need to calculate size ourselves now */ - if (req->count < 4) - req->count = 4; - if (req->count > jpg_nbufs) - req->count = jpg_nbufs; - fh->jpg_buffers.num_buffers = req->count; - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - - if (jpg_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l2reqbuf_unlock_and_return; - } - - /* The next mmap will map the MJPEG buffers */ - if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - fh->map_mode = ZORAN_MAP_MODE_JPG_REC; - else - fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - - } else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_REQBUFS - unknown type %d\n", - ZR_DEVNAME(zr), req->type); - res = -EINVAL; - goto v4l2reqbuf_unlock_and_return; - } - v4l2reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return 0; - } - break; - - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - __u32 type = buf->type; - int index = buf->index, res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n", - ZR_DEVNAME(zr), buf->index, buf->type); + /* we actually need to set 'real' parameters now */ + if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + settings.TmpDcm = 1; + else + settings.TmpDcm = 2; + settings.decimation = 0; + if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) + settings.VerDcm = 2; + else + settings.VerDcm = 1; + if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) + settings.HorDcm = 4; + else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) + settings.HorDcm = 2; + else + settings.HorDcm = 1; + if (settings.TmpDcm == 1) + settings.field_per_buff = 2; + else + settings.field_per_buff = 1; + + /* check */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto sfmtjpg_unlock_and_return; + + /* it's ok, so set them */ + fh->jpg_settings = settings; + + /* tell the user what we actually did */ + fmt->fmt.pix.width = settings.img_width / settings.HorDcm; + fmt->fmt.pix.height = settings.img_height * 2 / + (settings.TmpDcm * settings.VerDcm); + if (settings.TmpDcm == 1) + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); + else + fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? + V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); + fh->jpg_buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.sizeimage = fh->jpg_buffers.buffer_size; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + + /* we hereby abuse this variable to show that + * we're gonna do mjpeg capture */ + fh->map_mode = (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ? + ZORAN_MAP_MODE_JPG_REC : ZORAN_MAP_MODE_JPG_PLAY; +sfmtjpg_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - memset(buf, 0, sizeof(*buf)); - buf->type = type; - buf->index = index; +static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, + struct v4l2_format *fmt) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i; + int res = 0; - mutex_lock(&zr->resource_lock); - res = zoran_v4l2_buffer_status(file, buf, buf->index); - mutex_unlock(&zr->resource_lock); + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + return zoran_s_fmt_vid_out(file, fh, fmt); - return res; + for (i = 0; i < NUM_FORMATS; i++) + if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) + break; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", + ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); + return -EINVAL; } - break; - - case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, codec_mode, buf_type; - - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n", - ZR_DEVNAME(zr), buf->type, buf->index); + mutex_lock(&zr->resource_lock); + if (fh->jpg_buffers.allocated || + (fh->v4l_buffers.allocated && fh->v4l_buffers.active != ZORAN_FREE)) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sfmtv4l_unlock_and_return; + } + if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) + fmt->fmt.pix.height = BUZ_MAX_HEIGHT; + if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) + fmt->fmt.pix.width = BUZ_MAX_WIDTH; + + res = zoran_v4l_set_format(file, fmt->fmt.pix.width, + fmt->fmt.pix.height, &zoran_formats[i]); + if (res) + goto sfmtv4l_unlock_and_return; + + /* tell the user the + * results/missing stuff */ + fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; + fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; + fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; + if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + else + fmt->fmt.pix.field = V4L2_FIELD_TOP; - mutex_lock(&zr->resource_lock); + fh->map_mode = ZORAN_MAP_MODE_RAW; +sfmtv4l_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_g_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - res = zoran_v4l_queue_frame(file, buf->index); - if (res) - goto qbuf_unlock_and_return; - if (!zr->v4l_memgrab_active && - fh->v4l_buffers.active == ZORAN_LOCKED) - zr36057_set_memgrab(zr, 1); - break; + memset(fb, 0, sizeof(*fb)); + mutex_lock(&zr->resource_lock); + fb->base = zr->buffer.base; + fb->fmt.width = zr->buffer.width; + fb->fmt.height = zr->buffer.height; + if (zr->overlay_settings.format) + fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; + fb->fmt.bytesperline = zr->buffer.bytesperline; + mutex_unlock(&zr->resource_lock); + fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->flags = V4L2_FBUF_FLAG_OVERLAY; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - codec_mode = BUZ_MODE_MOTION_DECOMPRESS; - } else { - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - codec_mode = BUZ_MODE_MOTION_COMPRESS; - } + return 0; +} - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto qbuf_unlock_and_return; - } +static int zoran_s_fbuf(struct file *file, void *__fh, + struct v4l2_framebuffer *fb) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; + __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); - res = - zoran_jpg_queue_frame(file, buf->index, - codec_mode); - if (res != 0) - goto qbuf_unlock_and_return; - if (zr->codec_mode == BUZ_MODE_IDLE && - fh->jpg_buffers.active == ZORAN_LOCKED) { - zr36057_enable_jpg(zr, codec_mode); - } + for (i = 0; i < NUM_FORMATS; i++) + if (zoran_formats[i].fourcc == fb->fmt.pixelformat) break; - - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto qbuf_unlock_and_return; - } - qbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + if (i == NUM_FORMATS) { + dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", + ZR_DEVNAME(zr), fb->fmt.pixelformat, + (char *)&printformat); + return -EINVAL; } - break; - - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n", - ZR_DEVNAME(zr), buf->type); - - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); + res = setup_fbuffer(file, fb->base, &zoran_formats[i], + fb->fmt.width, fb->fmt.height, + fb->fmt.bytesperline); + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } + return res; +} - num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; - if (file->f_flags & O_NONBLOCK && - zr->v4l_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = v4l_sync(file, num); - if (res) - goto dqbuf_unlock_and_return; - else - zr->v4l_sync_tail++; - res = zoran_v4l2_buffer_status(file, buf, num); - break; +static int zoran_overlay(struct file *file, void *__fh, unsigned int on) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - { - struct zoran_sync bs; + mutex_lock(&zr->resource_lock); + res = setup_overlay(file, on); + mutex_unlock(&zr->resource_lock); - if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - else - buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + return res; +} - if (buf->type != buf_type) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", - ZR_DEVNAME(zr), buf->type, fh->map_mode); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } +static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - num = - zr->jpg_pend[zr-> - jpg_que_tail & BUZ_MASK_FRAME]; + if (req->memory != V4L2_MEMORY_MMAP) { + dprintk(1, + KERN_ERR + "%s: only MEMORY_MMAP capture is supported, not %d\n", + ZR_DEVNAME(zr), req->memory); + return -EINVAL; + } - if (file->f_flags & O_NONBLOCK && - zr->jpg_buffers.buffer[num].state != - BUZ_STATE_DONE) { - res = -EAGAIN; - goto dqbuf_unlock_and_return; - } - res = jpg_sync(file, &bs); - if (res) - goto dqbuf_unlock_and_return; - res = - zoran_v4l2_buffer_status(file, buf, bs.frame); - break; - } + mutex_lock(&zr->resource_lock); - default: - dprintk(1, + if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { + dprintk(1, KERN_ERR - "%s: VIDIOC_DQBUF - unsupported type %d\n", - ZR_DEVNAME(zr), buf->type); - res = -EINVAL; - goto dqbuf_unlock_and_return; - } - dqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - buffers allready allocated\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto v4l2reqbuf_unlock_and_return; } - break; - - case VIDIOC_STREAMON: - { - int res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr)); + if (fh->map_mode == ZORAN_MAP_MODE_RAW && + req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_lock(&zr->resource_lock); + /* control user input */ + if (req->count < 2) + req->count = 2; + if (req->count > v4l_nbufs) + req->count = v4l_nbufs; + fh->v4l_buffers.num_buffers = req->count; - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (zr->v4l_buffers.active != ZORAN_ACTIVE || - fh->v4l_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_LOCKED; - zr->v4l_settings = fh->v4l_settings; + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; - zr->v4l_sync_tail = zr->v4l_pend_tail; - if (!zr->v4l_memgrab_active && - zr->v4l_pend_head != zr->v4l_pend_tail) { - zr36057_set_memgrab(zr, 1); - } - break; + } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || + fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - /* what is the codec mode right now? */ - if (zr->jpg_buffers.active != ZORAN_ACTIVE || - fh->jpg_buffers.active != ZORAN_ACTIVE) { - res = -EBUSY; - goto strmon_unlock_and_return; - } + /* we need to calculate size ourselves now */ + if (req->count < 4) + req->count = 4; + if (req->count > jpg_nbufs) + req->count = jpg_nbufs; + fh->jpg_buffers.num_buffers = req->count; + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); - zr->jpg_buffers.active = fh->jpg_buffers.active = - ZORAN_LOCKED; + if (jpg_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l2reqbuf_unlock_and_return; + } - if (zr->jpg_que_head != zr->jpg_que_tail) { - /* Start the jpeg codec when the first frame is queued */ - jpeg_start(zr); - } + /* The next mmap will map the MJPEG buffers */ + if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + fh->map_mode = ZORAN_MAP_MODE_JPG_REC; + else + fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY; - break; - default: - dprintk(1, + } else { + dprintk(1, KERN_ERR - "%s: VIDIOC_STREAMON - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); - res = -EINVAL; - goto strmon_unlock_and_return; - } - strmon_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; + "%s: VIDIOC_REQBUFS - unknown type %d\n", + ZR_DEVNAME(zr), req->type); + res = -EINVAL; + goto v4l2reqbuf_unlock_and_return; } - break; - - case VIDIOC_STREAMOFF: - { - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); +v4l2reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - switch (fh->map_mode) { - case ZORAN_MAP_MODE_RAW: /* raw capture */ - if (fh->v4l_buffers.active == ZORAN_FREE && - zr->v4l_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->v4l_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; + return res; +} - /* unload capture */ - if (zr->v4l_memgrab_active) { - unsigned long flags; +static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + __u32 type = buf->type; + int index = buf->index, res; - spin_lock_irqsave(&zr->spinlock, flags); - zr36057_set_memgrab(zr, 0); - spin_unlock_irqrestore(&zr->spinlock, flags); - } + memset(buf, 0, sizeof(*buf)); + buf->type = type; + buf->index = index; - for (i = 0; i < fh->v4l_buffers.num_buffers; i++) - zr->v4l_buffers.buffer[i].state = - BUZ_STATE_USER; - fh->v4l_buffers = zr->v4l_buffers; + mutex_lock(&zr->resource_lock); + res = zoran_v4l2_buffer_status(file, buf, buf->index); + mutex_unlock(&zr->resource_lock); - zr->v4l_buffers.active = fh->v4l_buffers.active = - ZORAN_FREE; + return res; +} - zr->v4l_grab_seq = 0; - zr->v4l_pend_head = zr->v4l_pend_tail = 0; - zr->v4l_sync_tail = 0; +static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, codec_mode, buf_type; - break; + mutex_lock(&zr->resource_lock); - case ZORAN_MAP_MODE_JPG_REC: - case ZORAN_MAP_MODE_JPG_PLAY: - if (fh->jpg_buffers.active == ZORAN_FREE && - zr->jpg_buffers.active != ZORAN_FREE) { - res = -EPERM; /* stay off other's settings! */ - goto strmoff_unlock_and_return; - } - if (zr->jpg_buffers.active == ZORAN_FREE) - goto strmoff_unlock_and_return; - - res = - jpg_qbuf(file, -1, - (fh->map_mode == - ZORAN_MAP_MODE_JPG_REC) ? - BUZ_MODE_MOTION_COMPRESS : - BUZ_MODE_MOTION_DECOMPRESS); - if (res) - goto strmoff_unlock_and_return; - break; - default: - dprintk(1, - KERN_ERR - "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", - ZR_DEVNAME(zr), fh->map_mode); + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); res = -EINVAL; - goto strmoff_unlock_and_return; + goto qbuf_unlock_and_return; } - strmoff_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + res = zoran_v4l_queue_frame(file, buf->index); + if (res) + goto qbuf_unlock_and_return; + if (!zr->v4l_memgrab_active && + fh->v4l_buffers.active == ZORAN_LOCKED) + zr36057_set_memgrab(zr, 1); break; - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - else { - int id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + codec_mode = BUZ_MODE_MOTION_DECOMPRESS; + } else { + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + codec_mode = BUZ_MODE_MOTION_COMPRESS; } - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); - break; - case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); - break; - case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); - break; - case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); - break; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto qbuf_unlock_and_return; } - ctrl->minimum = 0; - ctrl->maximum = 65535; - ctrl->step = 1; - ctrl->default_value = 32768; - ctrl->type = V4L2_CTRL_TYPE_INTEGER; - - return 0; - } - break; - - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); - - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; - - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = zr->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = zr->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = zr->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = zr->hue; - break; + res = zoran_jpg_queue_frame(file, buf->index, + codec_mode); + if (res != 0) + goto qbuf_unlock_and_return; + if (zr->codec_mode == BUZ_MODE_IDLE && + fh->jpg_buffers.active == ZORAN_LOCKED) { + zr36057_enable_jpg(zr, codec_mode); } - mutex_unlock(&zr->resource_lock); + break; - return 0; - } + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +qbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct video_picture pict; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n", - ZR_DEVNAME(zr), ctrl->id); +static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0, buf_type, num = -1; /* compiler borks here (?) */ - /* we only support hue/saturation/contrast/brightness */ - if (ctrl->id < V4L2_CID_BRIGHTNESS || - ctrl->id > V4L2_CID_HUE) - return -EINVAL; + mutex_lock(&zr->resource_lock); - if (ctrl->value < 0 || ctrl->value > 65535) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", - ZR_DEVNAME(zr), ctrl->value, ctrl->id); - return -EINVAL; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - zr->brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - zr->contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - zr->saturation = ctrl->value; - break; - case V4L2_CID_HUE: - zr->hue = ctrl->value; - break; + num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; + if (file->f_flags & O_NONBLOCK && + zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; } - pict.brightness = zr->brightness; - pict.contrast = zr->contrast; - pict.colour = zr->saturation; - pict.hue = zr->hue; - - decoder_command(zr, DECODER_SET_PICTURE, &pict); - - mutex_unlock(&zr->resource_lock); - - return 0; - } + res = v4l_sync(file, num); + if (res) + goto dqbuf_unlock_and_return; + zr->v4l_sync_tail++; + res = zoran_v4l2_buffer_status(file, buf, num); break; - case VIDIOC_ENUMSTD: + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: { - struct v4l2_standard *std = arg; + struct zoran_sync bs; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n", - ZR_DEVNAME(zr), std->index); + if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + else + buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (std->index < 0 || std->index >= (zr->card.norms + 1)) - return -EINVAL; - else { - int id = std->index; - memset(std, 0, sizeof(*std)); - std->index = id; + if (buf->type != buf_type) { + dprintk(1, KERN_ERR + "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", + ZR_DEVNAME(zr), buf->type, fh->map_mode); + res = -EINVAL; + goto dqbuf_unlock_and_return; } - if (std->index == zr->card.norms) { - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, - &caps); - if (caps.flags & VIDEO_DECODER_AUTO) { - std->id = V4L2_STD_ALL; - strncpy(std->name, "Autodetect", sizeof(std->name)-1); - return 0; - } else - return -EINVAL; - } - switch (std->index) { - case 0: - std->id = V4L2_STD_PAL; - strncpy(std->name, "PAL", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[0]->Ht; - break; - case 1: - std->id = V4L2_STD_NTSC; - strncpy(std->name, "NTSC", sizeof(std->name)-1); - std->frameperiod.numerator = 1001; - std->frameperiod.denominator = 30000; - std->framelines = zr->card.tvn[1]->Ht; - break; - case 2: - std->id = V4L2_STD_SECAM; - strncpy(std->name, "SECAM", sizeof(std->name)-1); - std->frameperiod.numerator = 1; - std->frameperiod.denominator = 25; - std->framelines = zr->card.tvn[2]->Ht; - break; - } + num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; - return 0; + if (file->f_flags & O_NONBLOCK && + zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { + res = -EAGAIN; + goto dqbuf_unlock_and_return; + } + res = jpg_sync(file, &bs); + if (res) + goto dqbuf_unlock_and_return; + res = zoran_v4l2_buffer_status(file, buf, bs.frame); + break; } + + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_DQBUF - unsupported type %d\n", + ZR_DEVNAME(zr), buf->type); + res = -EINVAL; break; + } +dqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_G_STD: - { - v4l2_std_id *std = arg; - int norm; + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr)); +static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; - mutex_lock(&zr->resource_lock); - norm = zr->norm; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - switch (norm) { - case VIDEO_MODE_PAL: - *std = V4L2_STD_PAL; - break; - case VIDEO_MODE_NTSC: - *std = V4L2_STD_NTSC; - break; - case VIDEO_MODE_SECAM: - *std = V4L2_STD_SECAM; - break; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (zr->v4l_buffers.active != ZORAN_ACTIVE || + fh->v4l_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; } - return 0; - } + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_LOCKED; + zr->v4l_settings = fh->v4l_settings; + + zr->v4l_sync_tail = zr->v4l_pend_tail; + if (!zr->v4l_memgrab_active && + zr->v4l_pend_head != zr->v4l_pend_tail) { + zr36057_set_memgrab(zr, 1); + } break; - case VIDIOC_S_STD: - { - int norm = -1, res = 0; - v4l2_std_id *std = arg; + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + /* what is the codec mode right now? */ + if (zr->jpg_buffers.active != ZORAN_ACTIVE || + fh->jpg_buffers.active != ZORAN_ACTIVE) { + res = -EBUSY; + goto strmon_unlock_and_return; + } - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); + zr->jpg_buffers.active = fh->jpg_buffers.active = ZORAN_LOCKED; - if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) - norm = VIDEO_MODE_PAL; - else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) - norm = VIDEO_MODE_NTSC; - else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) - norm = VIDEO_MODE_SECAM; - else if (*std == V4L2_STD_ALL) - norm = VIDEO_MODE_AUTO; - else { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - return -EINVAL; + if (zr->jpg_que_head != zr->jpg_que_tail) { + /* Start the jpeg codec when the first frame is queued */ + jpeg_start(zr); } + break; - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_norm(zr, norm))) - goto sstd_unlock_and_return; - - res = wait_grab_pending(zr); - sstd_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } + default: + dprintk(1, + KERN_ERR + "%s: VIDIOC_STREAMON - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; break; + } +strmon_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *inp = arg; - int status; + return res; +} + +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n", - ZR_DEVNAME(zr), inp->index); + mutex_lock(&zr->resource_lock); - if (inp->index < 0 || inp->index >= zr->card.inputs) - return -EINVAL; - else { - int id = inp->index; - memset(inp, 0, sizeof(*inp)); - inp->index = id; + switch (fh->map_mode) { + case ZORAN_MAP_MODE_RAW: /* raw capture */ + if (fh->v4l_buffers.active == ZORAN_FREE && + zr->v4l_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; } + if (zr->v4l_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; - strncpy(inp->name, zr->card.input[inp->index].name, - sizeof(inp->name) - 1); - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->std = V4L2_STD_ALL; - - /* Get status of video decoder */ - mutex_lock(&zr->resource_lock); - decoder_command(zr, DECODER_GET_STATUS, &status); - mutex_unlock(&zr->resource_lock); + /* unload capture */ + if (zr->v4l_memgrab_active) { + unsigned long flags; - if (!(status & DECODER_STATUS_GOOD)) { - inp->status |= V4L2_IN_ST_NO_POWER; - inp->status |= V4L2_IN_ST_NO_SIGNAL; + spin_lock_irqsave(&zr->spinlock, flags); + zr36057_set_memgrab(zr, 0); + spin_unlock_irqrestore(&zr->spinlock, flags); } - if (!(status & DECODER_STATUS_COLOR)) - inp->status |= V4L2_IN_ST_NO_COLOR; - return 0; - } - break; + for (i = 0; i < fh->v4l_buffers.num_buffers; i++) + zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; + fh->v4l_buffers = zr->v4l_buffers; - case VIDIOC_G_INPUT: - { - int *input = arg; + zr->v4l_buffers.active = fh->v4l_buffers.active = ZORAN_FREE; - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr)); + zr->v4l_grab_seq = 0; + zr->v4l_pend_head = zr->v4l_pend_tail = 0; + zr->v4l_sync_tail = 0; - mutex_lock(&zr->resource_lock); - *input = zr->input; - mutex_unlock(&zr->resource_lock); + break; - return 0; - } + case ZORAN_MAP_MODE_JPG_REC: + case ZORAN_MAP_MODE_JPG_PLAY: + if (fh->jpg_buffers.active == ZORAN_FREE && + zr->jpg_buffers.active != ZORAN_FREE) { + res = -EPERM; /* stay off other's settings! */ + goto strmoff_unlock_and_return; + } + if (zr->jpg_buffers.active == ZORAN_FREE) + goto strmoff_unlock_and_return; + + res = jpg_qbuf(file, -1, + (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? + BUZ_MODE_MOTION_COMPRESS : + BUZ_MODE_MOTION_DECOMPRESS); + if (res) + goto strmoff_unlock_and_return; + break; + default: + dprintk(1, KERN_ERR + "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", + ZR_DEVNAME(zr), fh->map_mode); + res = -EINVAL; break; + } +strmoff_unlock_and_return: + mutex_unlock(&zr->resource_lock); - case VIDIOC_S_INPUT: - { - int *input = arg, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n", - ZR_DEVNAME(zr), *input); - - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, *input))) - goto sinput_unlock_and_return; + return res; +} - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); - sinput_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; +static int zoran_queryctrl(struct file *file, void *__fh, + struct v4l2_queryctrl *ctrl) +{ + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; + else { + int id = ctrl->id; + memset(ctrl, 0, sizeof(*ctrl)); + ctrl->id = id; } + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); + break; + case V4L2_CID_CONTRAST: + strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); + break; + case V4L2_CID_SATURATION: + strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); break; + case V4L2_CID_HUE: + strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); + break; + } - case VIDIOC_ENUMOUTPUT: - { - struct v4l2_output *outp = arg; + ctrl->minimum = 0; + ctrl->maximum = 65535; + ctrl->step = 1; + ctrl->default_value = 32768; + ctrl->type = V4L2_CTRL_TYPE_INTEGER; - dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n", - ZR_DEVNAME(zr), outp->index); + return 0; +} - if (outp->index != 0) - return -EINVAL; +static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - memset(outp, 0, sizeof(*outp)); - outp->index = 0; - outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; - strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - return 0; - } + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = zr->brightness; break; + case V4L2_CID_CONTRAST: + ctrl->value = zr->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = zr->saturation; + break; + case V4L2_CID_HUE: + ctrl->value = zr->hue; + break; + } + mutex_unlock(&zr->resource_lock); - case VIDIOC_G_OUTPUT: - { - int *output = arg; + return 0; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr)); +static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + struct video_picture pict; - *output = 0; + /* we only support hue/saturation/contrast/brightness */ + if (ctrl->id < V4L2_CID_BRIGHTNESS || + ctrl->id > V4L2_CID_HUE) + return -EINVAL; - return 0; + if (ctrl->value < 0 || ctrl->value > 65535) { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", + ZR_DEVNAME(zr), ctrl->value, ctrl->id); + return -EINVAL; } + + mutex_lock(&zr->resource_lock); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + zr->brightness = ctrl->value; + break; + case V4L2_CID_CONTRAST: + zr->contrast = ctrl->value; break; + case V4L2_CID_SATURATION: + zr->saturation = ctrl->value; + break; + case V4L2_CID_HUE: + zr->hue = ctrl->value; + break; + } + pict.brightness = zr->brightness; + pict.contrast = zr->contrast; + pict.colour = zr->saturation; + pict.hue = zr->hue; - case VIDIOC_S_OUTPUT: - { - int *output = arg; + decoder_command(zr, DECODER_SET_PICTURE, &pict); - dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n", - ZR_DEVNAME(zr), *output); + mutex_unlock(&zr->resource_lock); - if (*output != 0) - return -EINVAL; + return 0; +} - return 0; - } +static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int norm; + + mutex_lock(&zr->resource_lock); + norm = zr->norm; + mutex_unlock(&zr->resource_lock); + + switch (norm) { + case VIDEO_MODE_PAL: + *std = V4L2_STD_PAL; break; + case VIDEO_MODE_NTSC: + *std = V4L2_STD_NTSC; + break; + case VIDEO_MODE_SECAM: + *std = V4L2_STD_SECAM; + break; + } - /* cropping (sub-frame capture) */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cropcap = arg; - int type = cropcap->type, res = 0; + return 0; +} - dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n", - ZR_DEVNAME(zr), cropcap->type); +static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int norm = -1, res = 0; + + if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) + norm = VIDEO_MODE_PAL; + else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) + norm = VIDEO_MODE_NTSC; + else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) + norm = VIDEO_MODE_SECAM; + else if (*std == V4L2_STD_ALL) + norm = VIDEO_MODE_AUTO; + else { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", + ZR_DEVNAME(zr), (unsigned long long)*std); + return -EINVAL; + } - memset(cropcap, 0, sizeof(*cropcap)); - cropcap->type = type; + mutex_lock(&zr->resource_lock); + res = zoran_set_norm(zr, norm); + if (res) + goto sstd_unlock_and_return; - mutex_lock(&zr->resource_lock); + res = wait_grab_pending(zr); +sstd_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto cropcap_unlock_and_return; - } +static int zoran_enum_input(struct file *file, void *__fh, + struct v4l2_input *inp) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int status; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = BUZ_MAX_WIDTH; - cropcap->bounds.height = BUZ_MAX_HEIGHT; - cropcap->defrect.top = cropcap->defrect.left = 0; - cropcap->defrect.width = BUZ_MIN_WIDTH; - cropcap->defrect.height = BUZ_MIN_HEIGHT; - cropcap_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; + if (inp->index < 0 || inp->index >= zr->card.inputs) + return -EINVAL; + else { + int id = inp->index; + memset(inp, 0, sizeof(*inp)); + inp->index = id; } - break; - case VIDIOC_G_CROP: - { - struct v4l2_crop *crop = arg; - int type = crop->type, res = 0; + strncpy(inp->name, zr->card.input[inp->index].name, + sizeof(inp->name) - 1); + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = V4L2_STD_ALL; - dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n", - ZR_DEVNAME(zr), crop->type); + /* Get status of video decoder */ + mutex_lock(&zr->resource_lock); + decoder_command(zr, DECODER_GET_STATUS, &status); + mutex_unlock(&zr->resource_lock); - memset(crop, 0, sizeof(*crop)); - crop->type = type; + if (!(status & DECODER_STATUS_GOOD)) { + inp->status |= V4L2_IN_ST_NO_POWER; + inp->status |= V4L2_IN_ST_NO_SIGNAL; + } + if (!(status & DECODER_STATUS_COLOR)) + inp->status |= V4L2_IN_ST_NO_COLOR; - mutex_lock(&zr->resource_lock); + return 0; +} - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto gcrop_unlock_and_return; - } +static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; - crop->c.top = fh->jpg_settings.img_y; - crop->c.left = fh->jpg_settings.img_x; - crop->c.width = fh->jpg_settings.img_width; - crop->c.height = fh->jpg_settings.img_height; + mutex_lock(&zr->resource_lock); + *input = zr->input; + mutex_unlock(&zr->resource_lock); - gcrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); + return 0; +} - return res; - } - break; +static int zoran_s_input(struct file *file, void *__fh, unsigned int input) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res; - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = arg; - int res = 0; + mutex_lock(&zr->resource_lock); + res = zoran_set_input(zr, input); + if (res) + goto sinput_unlock_and_return; - settings = fh->jpg_settings; + /* Make sure the changes come into effect */ + res = wait_grab_pending(zr); +sinput_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - dprintk(3, - KERN_ERR - "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n", - ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top, - crop->c.width, crop->c.height); +static int zoran_enum_output(struct file *file, void *__fh, + struct v4l2_output *outp) +{ + if (outp->index != 0) + return -EINVAL; - mutex_lock(&zr->resource_lock); + memset(outp, 0, sizeof(*outp)); + outp->index = 0; + outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; + strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_S_CROP - cannot change settings while active\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto scrop_unlock_and_return; - } + return 0; +} - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && - (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - fh->map_mode == ZORAN_MAP_MODE_RAW)) { - dprintk(1, - KERN_ERR - "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto scrop_unlock_and_return; - } +static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) +{ + *output = 0; + + return 0; +} - /* move into a form that we understand */ - settings.img_x = crop->c.left; - settings.img_y = crop->c.top; - settings.img_width = crop->c.width; - settings.img_height = crop->c.height; +static int zoran_s_output(struct file *file, void *__fh, unsigned int output) +{ + if (output != 0) + return -EINVAL; - /* check validity */ - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto scrop_unlock_and_return; + return 0; +} - /* accept */ - fh->jpg_settings = settings; +/* cropping (sub-frame capture) */ +static int zoran_cropcap(struct file *file, void *__fh, + struct v4l2_cropcap *cropcap) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = cropcap->type, res = 0; - scrop_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - break; + memset(cropcap, 0, sizeof(*cropcap)); + cropcap->type = type; - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; + mutex_lock(&zr->resource_lock); - dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n", + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n", ZR_DEVNAME(zr)); + res = -EINVAL; + goto cropcap_unlock_and_return; + } - memset(params, 0, sizeof(*params)); + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = BUZ_MAX_WIDTH; + cropcap->bounds.height = BUZ_MAX_HEIGHT; + cropcap->defrect.top = cropcap->defrect.left = 0; + cropcap->defrect.width = BUZ_MIN_WIDTH; + cropcap->defrect.height = BUZ_MIN_HEIGHT; +cropcap_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int type = crop->type, res = 0; - params->quality = fh->jpg_settings.jpg_comp.quality; - params->APPn = fh->jpg_settings.jpg_comp.APPn; - memcpy(params->APP_data, - fh->jpg_settings.jpg_comp.APP_data, - fh->jpg_settings.jpg_comp.APP_len); - params->APP_len = fh->jpg_settings.jpg_comp.APP_len; - memcpy(params->COM_data, - fh->jpg_settings.jpg_comp.COM_data, - fh->jpg_settings.jpg_comp.COM_len); - params->COM_len = fh->jpg_settings.jpg_comp.COM_len; - params->jpeg_markers = - fh->jpg_settings.jpg_comp.jpeg_markers; + memset(crop, 0, sizeof(*crop)); + crop->type = type; - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, + KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto gcrop_unlock_and_return; } - break; - - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; - int res = 0; - settings = fh->jpg_settings; + crop->c.top = fh->jpg_settings.img_y; + crop->c.left = fh->jpg_settings.img_x; + crop->c.width = fh->jpg_settings.img_width; + crop->c.height = fh->jpg_settings.img_height; - dprintk(3, - KERN_DEBUG - "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n", - ZR_DEVNAME(zr), params->quality, params->APPn, - params->APP_len, params->COM_len); +gcrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); - settings.jpg_comp = *params; + return res; +} - mutex_lock(&zr->resource_lock); +static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - if (fh->v4l_buffers.active != ZORAN_FREE || - fh->jpg_buffers.active != ZORAN_FREE) { - dprintk(1, - KERN_WARNING - "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", - ZR_DEVNAME(zr)); - res = -EBUSY; - goto sjpegc_unlock_and_return; - } + settings = fh->jpg_settings; - if ((res = zoran_check_jpg_settings(zr, &settings))) - goto sjpegc_unlock_and_return; - if (!fh->jpg_buffers.allocated) - fh->jpg_buffers.buffer_size = - zoran_v4l2_calc_bufsize(&fh->jpg_settings); - fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; - sjpegc_unlock_and_return: - mutex_unlock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - return 0; + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, KERN_ERR + "%s: VIDIOC_S_CROP - cannot change settings while active\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto scrop_unlock_and_return; } - break; - case VIDIOC_QUERYSTD: /* why is this useful? */ - { - v4l2_std_id *std = arg; + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && + (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + fh->map_mode == ZORAN_MAP_MODE_RAW)) { + dprintk(1, KERN_ERR + "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto scrop_unlock_and_return; + } - dprintk(3, - KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); + /* move into a form that we understand */ + settings.img_x = crop->c.left; + settings.img_y = crop->c.top; + settings.img_width = crop->c.width; + settings.img_height = crop->c.height; - if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC || - *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM && - zr->card.norms == 3)) { - return 0; - } + /* check validity */ + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto scrop_unlock_and_return; - return -EINVAL; - } - break; + /* accept */ + fh->jpg_settings = settings; - case VIDIOC_TRY_FMT: - { - struct v4l2_format *fmt = arg; - int res = 0; +scrop_unlock_and_return: + mutex_unlock(&zr->resource_lock); + return res; +} - dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n", - ZR_DEVNAME(zr), fmt->type); +static int zoran_g_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + memset(params, 0, sizeof(*params)); - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - mutex_lock(&zr->resource_lock); + mutex_lock(&zr->resource_lock); - if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) - fmt->fmt.win.w.width = BUZ_MAX_WIDTH; - if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) - fmt->fmt.win.w.width = BUZ_MIN_WIDTH; - if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) - fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; - if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) - fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; + params->quality = fh->jpg_settings.jpg_comp.quality; + params->APPn = fh->jpg_settings.jpg_comp.APPn; + memcpy(params->APP_data, + fh->jpg_settings.jpg_comp.APP_data, + fh->jpg_settings.jpg_comp.APP_len); + params->APP_len = fh->jpg_settings.jpg_comp.APP_len; + memcpy(params->COM_data, + fh->jpg_settings.jpg_comp.COM_data, + fh->jpg_settings.jpg_comp.COM_len); + params->COM_len = fh->jpg_settings.jpg_comp.COM_len; + params->jpeg_markers = + fh->jpg_settings.jpg_comp.jpeg_markers; - mutex_unlock(&zr->resource_lock); - break; + mutex_unlock(&zr->resource_lock); - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; + return 0; +} - mutex_lock(&zr->resource_lock); - - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) { - settings = fh->jpg_settings; - - /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > - BUZ_MAX_HEIGHT) - settings.TmpDcm = 1; - else - settings.TmpDcm = 2; - settings.decimation = 0; - if (fmt->fmt.pix.height <= - fh->jpg_settings.img_height / 2) - settings.VerDcm = 2; - else - settings.VerDcm = 1; - if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 4) - settings.HorDcm = 4; - else if (fmt->fmt.pix.width <= - fh->jpg_settings.img_width / 2) - settings.HorDcm = 2; - else - settings.HorDcm = 1; - if (settings.TmpDcm == 1) - settings.field_per_buff = 2; - else - settings.field_per_buff = 1; - - /* check */ - if ((res = - zoran_check_jpg_settings(zr, - &settings))) - goto tryfmt_unlock_and_return; - - /* tell the user what we actually did */ - fmt->fmt.pix.width = - settings.img_width / settings.HorDcm; - fmt->fmt.pix.height = - settings.img_height * 2 / - (settings.TmpDcm * settings.VerDcm); - if (settings.TmpDcm == 1) - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_SEQ_TB : - V4L2_FIELD_SEQ_BT); - else - fmt->fmt.pix.field = - (fh->jpg_settings. - odd_even ? V4L2_FIELD_TOP : - V4L2_FIELD_BOTTOM); - - fmt->fmt.pix.sizeimage = - zoran_v4l2_calc_bufsize(&settings); - } else if (fmt->type == - V4L2_BUF_TYPE_VIDEO_CAPTURE) { - int i; - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].fourcc == - fmt->fmt.pix.pixelformat) - break; - if (i == NUM_FORMATS) { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } +static int zoran_s_jpegcomp(struct file *file, void *__fh, + struct v4l2_jpegcompression *params) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int res = 0; + struct zoran_jpg_settings settings; - if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) - fmt->fmt.pix.width = BUZ_MAX_WIDTH; - if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) - fmt->fmt.pix.width = BUZ_MIN_WIDTH; - if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) - fmt->fmt.pix.height = - BUZ_MAX_HEIGHT; - if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT) - fmt->fmt.pix.height = - BUZ_MIN_HEIGHT; - } else { - res = -EINVAL; - goto tryfmt_unlock_and_return; - } - tryfmt_unlock_and_return: - mutex_unlock(&zr->resource_lock); + settings = fh->jpg_settings; - return res; - break; + settings.jpg_comp = *params; - default: - return -EINVAL; - } + mutex_lock(&zr->resource_lock); - return 0; + if (fh->v4l_buffers.active != ZORAN_FREE || + fh->jpg_buffers.active != ZORAN_FREE) { + dprintk(1, KERN_WARNING + "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", + ZR_DEVNAME(zr)); + res = -EBUSY; + goto sjpegc_unlock_and_return; } - break; - default: - dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", - ZR_DEVNAME(zr), cmd); - return -ENOIOCTLCMD; - break; + res = zoran_check_jpg_settings(zr, &settings); + if (res) + goto sjpegc_unlock_and_return; + if (!fh->jpg_buffers.allocated) + fh->jpg_buffers.buffer_size = + zoran_v4l2_calc_bufsize(&fh->jpg_settings); + fh->jpg_settings.jpg_comp = *params = settings.jpg_comp; +sjpegc_unlock_and_return: + mutex_unlock(&zr->resource_lock); - } return 0; } - -static long -zoran_ioctl(struct file *file, - unsigned int cmd, - unsigned long arg) -{ - return video_usercopy(file, cmd, arg, zoran_do_ioctl); -} - static unsigned int zoran_poll (struct file *file, poll_table *wait) @@ -4365,10 +3998,7 @@ zoran_vm_close (struct vm_area_struct *vma) fh->jpg_buffers.active = ZORAN_FREE; } - //jpg_fbuffer_free(file); - fh->jpg_buffers.allocated = 0; - fh->jpg_buffers.ready_to_be_freed = 1; - + jpg_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4405,10 +4035,7 @@ zoran_vm_close (struct vm_area_struct *vma) ZORAN_FREE; spin_unlock_irqrestore(&zr->spinlock, flags); } - //v4l_fbuffer_free(file); - fh->v4l_buffers.allocated = 0; - fh->v4l_buffers.ready_to_be_freed = 1; - + v4l_fbuffer_free(file); mutex_unlock(&zr->resource_lock); } @@ -4647,11 +4274,53 @@ zoran_mmap (struct file *file, return 0; } +static const struct v4l2_ioctl_ops zoran_ioctl_ops = { + .vidioc_querycap = zoran_querycap, + .vidioc_cropcap = zoran_cropcap, + .vidioc_s_crop = zoran_s_crop, + .vidioc_g_crop = zoran_g_crop, + .vidioc_enum_input = zoran_enum_input, + .vidioc_g_input = zoran_g_input, + .vidioc_s_input = zoran_s_input, + .vidioc_enum_output = zoran_enum_output, + .vidioc_g_output = zoran_g_output, + .vidioc_s_output = zoran_s_output, + .vidioc_g_fbuf = zoran_g_fbuf, + .vidioc_s_fbuf = zoran_s_fbuf, + .vidioc_g_std = zoran_g_std, + .vidioc_s_std = zoran_s_std, + .vidioc_g_jpegcomp = zoran_g_jpegcomp, + .vidioc_s_jpegcomp = zoran_s_jpegcomp, + .vidioc_overlay = zoran_overlay, + .vidioc_reqbufs = zoran_reqbufs, + .vidioc_querybuf = zoran_querybuf, + .vidioc_qbuf = zoran_qbuf, + .vidioc_dqbuf = zoran_dqbuf, + .vidioc_streamon = zoran_streamon, + .vidioc_streamoff = zoran_streamoff, + .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, + .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, + .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, + .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, + .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, + .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, + .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, + .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, + .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, + .vidioc_queryctrl = zoran_queryctrl, + .vidioc_s_ctrl = zoran_s_ctrl, + .vidioc_g_ctrl = zoran_g_ctrl, + .vidioc_default = zoran_default, +}; + static const struct v4l2_file_operations zoran_fops = { .owner = THIS_MODULE, .open = zoran_open, .release = zoran_close, - .ioctl = zoran_ioctl, + .ioctl = video_ioctl2, .read = zoran_read, .write = zoran_write, .mmap = zoran_mmap, @@ -4661,7 +4330,9 @@ static const struct v4l2_file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, .fops = &zoran_fops, + .ioctl_ops = &zoran_ioctl_ops, .release = &zoran_vdev_release, + .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, .minor = -1 }; -- cgit v1.2.3 From d69e4a1d433220958c117d5e9a51638eaeb3e361 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:20:05 +0100 Subject: zoran: remove broken BIGPHYS_AREA and BUZ_HIMEM code, and allow for kmallocs > 128 kB From: Hans Verkuil Remove memory allocation madness. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 2 - linux/drivers/media/video/zoran/zoran_driver.c | 247 +++---------------------- 2 files changed, 28 insertions(+), 221 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index 1bf540cb5..76668bda0 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -170,8 +170,6 @@ Private IOCTL to set up for displaying MJPEG #endif #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) -#define MAX_KMALLOC_MEM (128*1024) - #include "zr36057.h" enum card_type { diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index afbb18b89..5c8630647 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -192,16 +192,6 @@ const struct zoran_format zoran_formats[] = { }; #define NUM_FORMATS ARRAY_SIZE(zoran_formats) -// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined -#if !defined(CONFIG_BIGPHYS_AREA) && !defined(BUZ_USE_HIMEM) -//#undef CONFIG_BIGPHYS_AREA -#define BUZ_USE_HIMEM -#endif - -#if defined(CONFIG_BIGPHYS_AREA) -# include -#endif - static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ module_param(lock_norm, int, 0644); MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); @@ -237,79 +227,8 @@ static void jpg_fbuffer_free(struct file *file); * Allocate the V4L grab buffers * * These have to be pysically contiguous. - * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc - * else we try to allocate them with bigphysarea_alloc_pages - * if the bigphysarea patch is present in the kernel, - * else we try to use high memory (if the user has bootet - * Linux with the necessary memory left over). - */ - -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) -static unsigned long -get_high_mem (unsigned long size) -{ -/* - * Check if there is usable memory at the end of Linux memory - * of at least size. Return the physical address of this memory, - * return 0 on failure. - * - * The idea is from Alexandro Rubini's book "Linux device drivers". - * The driver from him which is downloadable from O'Reilly's - * web site misses the "virt_to_phys(high_memory)" part - * (and therefore doesn't work at all - at least with 2.2.x kernels). - * - * It should be unnecessary to mention that THIS IS DANGEROUS, - * if more than one driver at a time has the idea to use this memory!!!! */ - volatile unsigned char __iomem *mem; - unsigned char c; - unsigned long hi_mem_ph; - unsigned long i; - - /* Map the high memory to user space */ - - hi_mem_ph = virt_to_phys(high_memory); - - mem = ioremap(hi_mem_ph, size); - if (!mem) { - dprintk(1, - KERN_ERR "%s: get_high_mem() - ioremap failed\n", - ZORAN_NAME); - return 0; - } - - for (i = 0; i < size; i++) { - /* Check if it is memory */ - c = i & 0xff; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - c = 255 - c; - writeb(c, mem + i); - if (readb(mem + i) != c) - break; - writeb(0, mem + i); /* zero out memory */ - - /* give the kernel air to breath */ - if ((i & 0x3ffff) == 0x3ffff) - schedule(); - } - - iounmap(mem); - - if (i != size) { - dprintk(1, - KERN_ERR - "%s: get_high_mem() - requested %lu, avail %lu\n", - ZORAN_NAME, size, i); - return 0; - } - - return hi_mem_ph; -} -#endif - static int v4l_fbuffer_alloc (struct file *file) { @@ -317,132 +236,37 @@ v4l_fbuffer_alloc (struct file *file) struct zoran *zr = fh->zr; int i, off; unsigned char *mem; -#if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) - unsigned long pmem = 0; -#endif for (i = 0; i < fh->v4l_buffers.num_buffers; i++) { if (fh->v4l_buffers.buffer[i].fbuffer) dprintk(2, KERN_WARNING - "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: v4l_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); //udelay(20); - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - /* Use kmalloc */ - - mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); - if (!mem) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%llx)\n", - ZR_DEVNAME(zr), i, (unsigned long) mem, - (unsigned long long)virt_to_bus(mem)); - } else { -#if defined(CONFIG_BIGPHYS_AREA) - /* Use bigphysarea_alloc_pages */ - - int n = - (fh->v4l_buffers.buffer_size + PAGE_SIZE - - 1) / PAGE_SIZE; - - mem = - (unsigned char *) bigphysarea_alloc_pages(n, 0, - GFP_KERNEL); - if (mem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n", - ZR_DEVNAME(zr), i); - v4l_fbuffer_free(file); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[i].fbuffer = mem; - fh->v4l_buffers.buffer[i].fbuffer_phys = - virt_to_phys(mem); - fh->v4l_buffers.buffer[i].fbuffer_bus = - virt_to_bus(mem); - dprintk(4, - KERN_INFO - "%s: Bigphysarea frame %d mem %p (bus: 0x%lx)\n", - ZR_DEVNAME(zr), i, mem, virt_to_bus(mem)); - - /* Zero out the allocated memory */ - memset(fh->v4l_buffers.buffer[i].fbuffer, 0, - fh->v4l_buffers.buffer_size); -#else -#if defined(BUZ_USE_HIMEM) - - /* Use high memory which has been left at boot time */ - - /* Ok., Ok. this is an evil hack - we make - * the assumption that physical addresses are - * the same as bus addresses (true at least - * for Intel processors). The whole method of - * obtaining and using this memory is not very - * nice - but I hope it saves some poor users - * from kernel hacking, which might have even - * more evil results */ - - if (i == 0) { - int size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - - pmem = get_high_mem(size); - if (pmem == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n", - ZR_DEVNAME(zr), size >> 10); - return -ENOBUFS; - } - fh->v4l_buffers.buffer[0].fbuffer = NULL; - fh->v4l_buffers.buffer[0].fbuffer_phys = pmem; - fh->v4l_buffers.buffer[0].fbuffer_bus = pmem; - dprintk(4, - KERN_INFO - "%s: v4l_fbuffer_alloc() - using %d KB high memory\n", - ZR_DEVNAME(zr), size >> 10); - } else { - fh->v4l_buffers.buffer[i].fbuffer = NULL; - fh->v4l_buffers.buffer[i].fbuffer_phys = - pmem + i * fh->v4l_buffers.buffer_size; - fh->v4l_buffers.buffer[i].fbuffer_bus = - pmem + i * fh->v4l_buffers.buffer_size; - } -#else - /* No bigphysarea present, usage of high memory disabled, - * but user wants buffers of more than MAX_KMALLOC_MEM */ + mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); + if (!mem) { dprintk(1, KERN_ERR - "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n", - ZR_DEVNAME(zr)); - dprintk(1, - KERN_ERR - "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n", - ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers, - fh->v4l_buffers.buffer_size >> 10); + "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", + ZR_DEVNAME(zr), i); + v4l_fbuffer_free(file); return -ENOBUFS; -#endif -#endif } + fh->v4l_buffers.buffer[i].fbuffer = mem; + fh->v4l_buffers.buffer[i].fbuffer_phys = + virt_to_phys(mem); + fh->v4l_buffers.buffer[i].fbuffer_bus = + virt_to_bus(mem); + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + SetPageReserved(MAP_NR(mem + off)); + dprintk(4, + KERN_INFO + "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", + ZR_DEVNAME(zr), i, (unsigned long) mem, + virt_to_bus(mem)); } fh->v4l_buffers.allocated = 1; @@ -465,18 +289,11 @@ v4l_fbuffer_free (struct file *file) if (!fh->v4l_buffers.buffer[i].fbuffer) continue; - if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) { - mem = fh->v4l_buffers.buffer[i].fbuffer; - for (off = 0; off < fh->v4l_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR(mem + off)); - kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); - } -#if defined(CONFIG_BIGPHYS_AREA) - else - bigphysarea_free_pages((void *) fh->v4l_buffers. - buffer[i].fbuffer); -#endif + mem = fh->v4l_buffers.buffer[i].fbuffer; + for (off = 0; off < fh->v4l_buffers.buffer_size; + off += PAGE_SIZE) + ClearPageReserved(MAP_NR(mem + off)); + kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); fh->v4l_buffers.buffer[i].fbuffer = NULL; } @@ -486,16 +303,10 @@ v4l_fbuffer_free (struct file *file) /* * Allocate the MJPEG grab buffers. * - * If the requested buffer size is smaller than MAX_KMALLOC_MEM, - * kmalloc is used to request a physically contiguous area, - * else we allocate the memory in framgents with get_zeroed_page. - * * If a Natoma chipset is present and this is a revision 1 zr36057, * each MJPEG buffer needs to be physically contiguous. * (RJ: This statement is from Dave Perks' original driver, * I could never check it because I have a zr36067) - * The driver cares about this because it reduces the buffer - * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation). * * RJ: The contents grab buffers needs never be accessed in the driver. * Therefore there is no need to allocate them with vmalloc in order @@ -529,7 +340,7 @@ jpg_fbuffer_alloc (struct file *file) if (fh->jpg_buffers.buffer[i].frag_tab) dprintk(2, KERN_WARNING - "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n", + "%s: jpg_fbuffer_alloc() - buffer %d already allocated!?\n", ZR_DEVNAME(zr), i); /* Allocate fragment table for this buffer */ @@ -569,7 +380,7 @@ jpg_fbuffer_alloc (struct file *file) off += PAGE_SIZE) SetPageReserved(MAP_NR(mem + off)); } else { - /* jpg_bufsize is allreay page aligned */ + /* jpg_bufsize is already page aligned */ for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { @@ -2238,6 +2049,7 @@ schan_unlock_and_return: return res; } + case VIDIOCGMBUF: { struct video_mbuf *vmbuf = arg; @@ -2434,16 +2246,13 @@ sparams_unlock_and_return: * tables to a Maximum of 2 MB */ if (breq->size > jpg_bufsize) breq->size = jpg_bufsize; - if (fh->jpg_buffers.need_contiguous && - breq->size > MAX_KMALLOC_MEM) - breq->size = MAX_KMALLOC_MEM; mutex_lock(&zr->resource_lock); if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { dprintk(1, KERN_ERR - "%s: BUZIOC_REQBUFS - buffers allready allocated\n", + "%s: BUZIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto jpgreqbuf_unlock_and_return; -- cgit v1.2.3 From c263f2e699cb58f1ac5e12e170d0879329845c0a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:23:24 +0100 Subject: zoran: use slider flag with volume etc. controls. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 5c8630647..ebae49f91 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -3261,6 +3261,7 @@ static int zoran_queryctrl(struct file *file, void *__fh, ctrl->step = 1; ctrl->default_value = 32768; ctrl->type = V4L2_CTRL_TYPE_INTEGER; + ctrl->flags = V4L2_CTRL_FLAG_SLIDER; return 0; } -- cgit v1.2.3 From a393861c10e72edfaf97362739be70ebe940c246 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:24:56 +0100 Subject: zoran: fix field typo. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index ebae49f91..eeb541f26 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2464,7 +2464,7 @@ static int zoran_g_fmt_vid_out(struct file *file, void *__fh, fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; if (fh->jpg_settings.TmpDcm == 1) fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? - V4L2_FIELD_SEQ_BT : V4L2_FIELD_SEQ_BT); + V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); else fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); -- cgit v1.2.3 From 0dd0437a3727766237df82bdfa89bc02a18cc901 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:28:28 +0100 Subject: zoran: set bytesperline to 0 when using MJPEG. From: Hans Verkuil Remove bogus check on bytesperline in the try_fmt_vid_out call. Just set it to 0. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index eeb541f26..b4a1b1c7b 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2550,12 +2550,11 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, struct zoran_jpg_settings settings; int res = 0; - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; - if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; + fmt->fmt.pix.bytesperline = 0; + mutex_lock(&zr->resource_lock); settings = fh->jpg_settings; @@ -2609,9 +2608,6 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, struct zoran *zr = fh->zr; int i; - if (fmt->fmt.pix.bytesperline > 0) - return -EINVAL; - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) return zoran_try_fmt_vid_out(file, fh, fmt); -- cgit v1.2.3 From 4f77e897cb187126ad10aad97b2edc6a89395d79 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:51:13 +0100 Subject: zoran: remove old V4L1 ioctls, use v4l1-compat instead. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/Kconfig | 4 +- linux/drivers/media/video/zoran/zoran_driver.c | 459 +++---------------------- 2 files changed, 46 insertions(+), 417 deletions(-) diff --git a/linux/drivers/media/video/zoran/Kconfig b/linux/drivers/media/video/zoran/Kconfig index 4ea5fa71d..a0fe52260 100644 --- a/linux/drivers/media/video/zoran/Kconfig +++ b/linux/drivers/media/video/zoran/Kconfig @@ -1,6 +1,6 @@ config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" - depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS + depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS help Say Y for support for MJPEG capture cards based on the Zoran 36057/36067 PCI controller chipset. This includes the Iomega @@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10 config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO help diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index b4a1b1c7b..6a2607998 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -614,64 +614,6 @@ zoran_v4l_queue_frame (struct file *file, return res; } -static int -v4l_grab (struct file *file, - struct video_mmap *mp) -{ - struct zoran_fh *fh = file->private_data; - struct zoran *zr = fh->zr; - int res = 0, i; - - for (i = 0; i < NUM_FORMATS; i++) { - if (zoran_formats[i].palette == mp->format && - zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE && - !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)) - break; - } - if (i == NUM_FORMATS || zoran_formats[i].depth == 0) { - dprintk(1, - KERN_ERR - "%s: v4l_grab() - wrong bytes-per-pixel format\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - /* - * To minimize the time spent in the IRQ routine, we avoid setting up - * the video front end there. - * If this grab has different parameters from a running streaming capture - * we stop the streaming capture and start it over again. - */ - if (zr->v4l_memgrab_active && - (zr->v4l_settings.width != mp->width || - zr->v4l_settings.height != mp->height || - zr->v4l_settings.format->palette != mp->format)) { - res = wait_grab_pending(zr); - if (res) - return res; - } - if ((res = zoran_v4l_set_format(file, - mp->width, - mp->height, - &zoran_formats[i]))) - return res; - zr->v4l_settings = fh->v4l_settings; - - /* queue the frame in the pending queue */ - if ((res = zoran_v4l_queue_frame(file, mp->frame))) { - fh->v4l_buffers.active = ZORAN_FREE; - return res; - } - - /* put the 36057 into frame grabbing mode */ - if (!res && !zr->v4l_memgrab_active) - zr36057_set_memgrab(zr, 1); - - //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr)); - - return res; -} - /* * Sync on a V4L buffer */ @@ -1761,6 +1703,7 @@ zoran_set_input (struct zoran *zr, * ioctl routine */ +#ifdef CONFIG_VIDEO_V4L1_COMPAT static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) { struct zoran_fh *fh = __fh; @@ -1768,363 +1711,6 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) struct zoran_jpg_settings settings; switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *vcap = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr)); - - memset(vcap, 0, sizeof(struct video_capability)); - strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1); - vcap->type = ZORAN_VID_TYPE; - - vcap->channels = zr->card.inputs; - vcap->audios = 0; - mutex_lock(&zr->resource_lock); - vcap->maxwidth = BUZ_MAX_WIDTH; - vcap->maxheight = BUZ_MAX_HEIGHT; - vcap->minwidth = BUZ_MIN_WIDTH; - vcap->minheight = BUZ_MIN_HEIGHT; - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCGCHAN: - { - struct video_channel *vchan = arg; - int channel = vchan->channel; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n", - ZR_DEVNAME(zr), vchan->channel); - - memset(vchan, 0, sizeof(struct video_channel)); - if (channel > zr->card.inputs || channel < 0) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGCHAN on not existing channel %d\n", - ZR_DEVNAME(zr), channel); - return -EINVAL; - } - - strcpy(vchan->name, zr->card.input[channel].name); - - vchan->tuners = 0; - vchan->flags = 0; - vchan->type = VIDEO_TYPE_CAMERA; - mutex_lock(&zr->resource_lock); - vchan->norm = zr->norm; - mutex_unlock(&zr->resource_lock); - vchan->channel = channel; - - return 0; - } - - /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says: - * - * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input." - * * ^^^^^^^ - * * The famos BTTV driver has it implemented with a struct video_channel argument - * * and we follow it for compatibility reasons - * * - * * BTW: this is the only way the user can set the norm! - */ - - case VIDIOCSCHAN: - { - struct video_channel *vchan = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSCHAN - channel=%d, norm=%d\n", - ZR_DEVNAME(zr), vchan->channel, vchan->norm); - - mutex_lock(&zr->resource_lock); - if ((res = zoran_set_input(zr, vchan->channel))) - goto schan_unlock_and_return; - if ((res = zoran_set_norm(zr, vchan->norm))) - goto schan_unlock_and_return; - - /* Make sure the changes come into effect */ - res = wait_grab_pending(zr); -schan_unlock_and_return: - mutex_unlock(&zr->resource_lock); - return res; - } - - case VIDIOCGPICT: - { - struct video_picture *vpict = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr)); - - memset(vpict, 0, sizeof(struct video_picture)); - mutex_lock(&zr->resource_lock); - vpict->hue = zr->hue; - vpict->brightness = zr->brightness; - vpict->contrast = zr->contrast; - vpict->colour = zr->saturation; - if (fh->overlay_settings.format) { - vpict->depth = fh->overlay_settings.format->depth; - vpict->palette = fh->overlay_settings.format->palette; - } else { - vpict->depth = 0; - } - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCSPICT: - { - struct video_picture *vpict = arg; - int i; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n", - ZR_DEVNAME(zr), vpict->brightness, vpict->hue, - vpict->colour, vpict->contrast, vpict->depth, - vpict->palette); - - for (i = 0; i < NUM_FORMATS; i++) { - const struct zoran_format *fmt = &zoran_formats[i]; - - if (fmt->palette != -1 && - fmt->flags & ZORAN_FORMAT_OVERLAY && - fmt->palette == vpict->palette && - fmt->depth == vpict->depth) - break; - } - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSPICT - Invalid palette %d\n", - ZR_DEVNAME(zr), vpict->palette); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - - decoder_command(zr, DECODER_SET_PICTURE, vpict); - - zr->hue = vpict->hue; - zr->contrast = vpict->contrast; - zr->saturation = vpict->colour; - zr->brightness = vpict->brightness; - - fh->overlay_settings.format = &zoran_formats[i]; - - mutex_unlock(&zr->resource_lock); - - return 0; - } - - case VIDIOCCAPTURE: - { - int *on = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n", - ZR_DEVNAME(zr), *on); - - mutex_lock(&zr->resource_lock); - res = setup_overlay(file, *on); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGWIN: - { - struct video_window *vwin = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr)); - - memset(vwin, 0, sizeof(struct video_window)); - mutex_lock(&zr->resource_lock); - vwin->x = fh->overlay_settings.x; - vwin->y = fh->overlay_settings.y; - vwin->width = fh->overlay_settings.width; - vwin->height = fh->overlay_settings.height; - mutex_unlock(&zr->resource_lock); - vwin->clipcount = 0; - return 0; - } - - case VIDIOCSWIN: - { - struct video_window *vwin = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n", - ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clipcount); - - mutex_lock(&zr->resource_lock); - res = - setup_window(file, vwin->x, vwin->y, vwin->width, - vwin->height, vwin->clips, - vwin->clipcount, NULL); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGFBUF: - { - struct video_buffer *vbuf = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr)); - - mutex_lock(&zr->resource_lock); - *vbuf = zr->buffer; - mutex_unlock(&zr->resource_lock); - return 0; - } - - case VIDIOCSFBUF: - { - struct video_buffer *vbuf = arg; - int i, res = 0; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n", - ZR_DEVNAME(zr), vbuf->base, vbuf->width, - vbuf->height, vbuf->depth, vbuf->bytesperline); - - for (i = 0; i < NUM_FORMATS; i++) - if (zoran_formats[i].depth == vbuf->depth) - break; - if (i == NUM_FORMATS) { - dprintk(1, - KERN_ERR - "%s: VIDIOCSFBUF - invalid fbuf depth %d\n", - ZR_DEVNAME(zr), vbuf->depth); - return -EINVAL; - } - - mutex_lock(&zr->resource_lock); - res = - setup_fbuffer(file, vbuf->base, &zoran_formats[i], - vbuf->width, vbuf->height, - vbuf->bytesperline); - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCSYNC: - { - int *frame = arg, res; - - dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n", - ZR_DEVNAME(zr), *frame); - - mutex_lock(&zr->resource_lock); - res = v4l_sync(file, *frame); - mutex_unlock(&zr->resource_lock); - if (!res) - zr->v4l_sync_tail++; - return res; - } - - case VIDIOCMCAPTURE: - { - struct video_mmap *vmap = arg; - int res; - - dprintk(3, - KERN_DEBUG - "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n", - ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height, - vmap->format); - - mutex_lock(&zr->resource_lock); - res = v4l_grab(file, vmap); - mutex_unlock(&zr->resource_lock); - return res; - } - - - case VIDIOCGMBUF: - { - struct video_mbuf *vmbuf = arg; - int i, res = 0; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr)); - - vmbuf->size = - fh->v4l_buffers.num_buffers * - fh->v4l_buffers.buffer_size; - vmbuf->frames = fh->v4l_buffers.num_buffers; - for (i = 0; i < vmbuf->frames; i++) { - vmbuf->offsets[i] = - i * fh->v4l_buffers.buffer_size; - } - - mutex_lock(&zr->resource_lock); - - if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { - dprintk(1, - KERN_ERR - "%s: VIDIOCGMBUF - buffers already allocated\n", - ZR_DEVNAME(zr)); - res = -EINVAL; - goto v4l1reqbuf_unlock_and_return; - } - - if (v4l_fbuffer_alloc(file)) { - res = -ENOMEM; - goto v4l1reqbuf_unlock_and_return; - } - - /* The next mmap will map the V4L buffers */ - fh->map_mode = ZORAN_MAP_MODE_RAW; -v4l1reqbuf_unlock_and_return: - mutex_unlock(&zr->resource_lock); - - return res; - } - - case VIDIOCGUNIT: - { - struct video_unit *vunit = arg; - - dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr)); - - vunit->video = zr->video_dev->minor; - vunit->vbi = VIDEO_NO_UNIT; - vunit->radio = VIDEO_NO_UNIT; - vunit->audio = VIDEO_NO_UNIT; - vunit->teletext = VIDEO_NO_UNIT; - - return 0; - } - - /* - * RJ: In principal we could support subcaptures for V4L grabbing. - * Not even the famous BTTV driver has them, however. - * If there should be a strong demand, one could consider - * to implement them. - */ - case VIDIOCGCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - case VIDIOCSCAPTURE: - { - dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - case BUZIOC_G_PARAMS: { struct zoran_params *bparams = arg; @@ -2384,6 +1970,46 @@ gstat_unlock_and_return: } } +static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf) +{ + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + int i, res = 0; + + vmbuf->size = + fh->v4l_buffers.num_buffers * + fh->v4l_buffers.buffer_size; + vmbuf->frames = fh->v4l_buffers.num_buffers; + for (i = 0; i < vmbuf->frames; i++) { + vmbuf->offsets[i] = + i * fh->v4l_buffers.buffer_size; + } + + mutex_lock(&zr->resource_lock); + + if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) { + dprintk(1, + KERN_ERR + "%s: VIDIOCGMBUF - buffers already allocated\n", + ZR_DEVNAME(zr)); + res = -EINVAL; + goto v4l1reqbuf_unlock_and_return; + } + + if (v4l_fbuffer_alloc(file)) { + res = -ENOMEM; + goto v4l1reqbuf_unlock_and_return; + } + + /* The next mmap will map the V4L buffers */ + fh->map_mode = ZORAN_MAP_MODE_RAW; +v4l1reqbuf_unlock_and_return: + mutex_unlock(&zr->resource_lock); + + return res; +} +#endif + static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) { struct zoran_fh *fh = __fh; @@ -4119,7 +3745,10 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = { .vidioc_queryctrl = zoran_queryctrl, .vidioc_s_ctrl = zoran_s_ctrl, .vidioc_g_ctrl = zoran_g_ctrl, +#ifdef CONFIG_VIDEO_V4L1_COMPAT .vidioc_default = zoran_default, + .vidiocgmbuf = zoran_vidiocgmbuf, +#endif }; static const struct v4l2_file_operations zoran_fops = { -- cgit v1.2.3 From 7b62aa559970adaf22b84c7e776fbefc96d14dd1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 17:52:24 +0100 Subject: zoran: set correct parent of the video device. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 5d0fa99f2..99a25218b 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -1138,6 +1138,7 @@ zr36057_init (struct zoran *zr) * Now add the template and register the device unit. */ memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template)); + zr->video_dev->parent = &zr->pci_dev->dev; strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); if (err < 0) -- cgit v1.2.3 From 549f66e3e6f4a7fd57d6419903467daaf099461e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 18 Feb 2009 17:47:38 +0000 Subject: Trivial fixes for README.patches From: Nicola Soranzo Uniform capitals, add trailing slash to some URLs and other typo corrections. Priority: normal Signed-off-by: Nicola Soranzo Signed-off-by: Mauro Carvalho Chehab --- README.patches | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/README.patches b/README.patches index 28d697302..f989bc3f3 100644 --- a/README.patches +++ b/README.patches @@ -7,13 +7,13 @@ and by the v4l-dvb community. (*) This is just an aka for the main developers involved in V4L/DVB drivers. They are a volunteer and unremunerated group of people that have the common interest of providing a good support on Linux for -receiving and capturing video streams from Web cams, Analog TV, Digital +receiving and capturing video streams from webcams, analog TV, digital TV and radio broadcast AM/FM. CONTENTS ======== - 1. A Brief introduction about patch management + 1. A brief introduction about patch management 2. Git trees' relationships with v4l/dvb development 3. Mercurial trees used for v4l/dvb development 4. Community best practices @@ -23,7 +23,7 @@ TV and radio broadcast AM/FM. 8. Identifying regressions with Mercurial 9. Creating a newer driver -1. A Brief introduction about patch management +1. A brief introduction about patch management ========================================== Current V4L/DVB development is based on a modern SCM system that @@ -35,7 +35,7 @@ final users. That's the reason why hg was selected for V4L/DVB development. There are some tutorials, FAQs and other valuable information at -http://selenic.com/mercurial about hg usage. +http://selenic.com/mercurial/ about hg usage. Mercurial is a distributed SCM, which means every developer gets his own full copy of the repository (including the complete revision @@ -44,7 +44,7 @@ The resulting changesets can then be exchanged between repositories and finally merged into a common repository on linuxtv.org. A list of current available repositories is available at: - http://linuxtv.org/hg + http://linuxtv.org/hg/ 2. Git and Mercurial trees' relationships with v4l/dvb development =============================================================== @@ -58,12 +58,13 @@ The main kernel trees is owned by Linus Torvalds, being located at: The subsystem master tree is owned by the subsystem maintainer (Mauro Carvalho Chehab) being located at: http://git.kernel.org/?p=linux/kernel/git/mchehab/linux-2.6.git + A tree with development patches that aren't ready yet for upstream is handled at: http://git.kernel.org/?p=linux/kernel/git/mchehab/devel.git -There's also an experimental tree, that contains all experimental patches -from subsystem trees. It is called linux-next. Its purpose is to check in +There is also an experimental tree, that contains all experimental patches +from subsystem trees, called linux-next. Its purpose is to check in advance if patches from different trees would conflict. The main tree for linux-next is owned by Stephen Rothwell and it is located at: http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git @@ -79,7 +80,7 @@ located at: Before committing into the master -git tree, the finished patches from each maintainers tree are added on a staging tree, owned by the subsystem maintainer, at: - http://linuxtv.org/hg/v4l-dvb + http://linuxtv.org/hg/v4l-dvb/ The main function of this tree is to merge patches from other repositories and to test the entire subsystem with the finished patches. @@ -87,7 +88,7 @@ This is also the recommended tree for users interested on testing newer V4L/DVB patches and drivers. Users are welcome to use, test and report any issues via the mailing -lists or via the Kernel's bugzilla, available at: +lists or via the Kernel Bug Tracker, available at: http://bugzilla.kernel.org Michael Krufky maintains a backport tree, containing a subset of the @@ -95,7 +96,7 @@ patches from the subsystem tree that are meant to be sent to kernel -stable team, at: http://git.kernel.org/http://git.kernel.org/?p=linux/kernel/git/mkrufky/v4l-dvb-2.6.x.y.git -3. Other mercurial trees used for v4l/dvb development +3. Other Mercurial trees used for v4l/dvb development ================================================== V4L/DVB driver development is hosted at http://linuxtv.org. There are a @@ -132,7 +133,7 @@ a) Every developer should follow the "rules of thumb" of kernel development Documentation/SubmitChecklist Documentation/CodingStyle -b) All commits at mercurial trees should have a consistent message, +b) All commits at Mercurial trees should have a consistent message, describing the patch. This is done by using: make commit @@ -157,7 +158,7 @@ b) All commits at mercurial trees should have a consistent message, Signed-off-by: nowhere All lines starting with # and all lines starting with HG: will be - removed from the mercurial commit log. + removed from the Mercurial commit log. *WARNING* Be careful not to leave the first line blank, otherwise hg will leave subject blank. @@ -212,9 +213,9 @@ d) For "make commit" to work properly, the HGUSER shell environment var It is strongly recommended to have those lines in .bashrc or .profile. -e) All patches shall have a Developers Certificate of Origin +e) All patches shall have a Developer's Certificate of Origin version 1.1 in the commit log or the email description, signed by the - patch authors, as postulated in the Linux Kernel source at: + patch authors, as postulated in the Linux kernel source at: Documentation/SubmittingPatches @@ -255,19 +256,19 @@ g) Another kernel's practice that is agreed to be good is that a Reviewed-by: My Name This is particularly important for Kernel to userspace ABI changes. -h) If the patch also affects other parts of kernel (like Alsa +h) If the patch also affects other parts of kernel (like ALSA or i2c), it is required that, when submitting upstream, the patch also goes to the maintainers of that subsystem. To do this, the developer shall copy the interested parties. - At mercurial tree, this can be handled automatically by the LinuxTV + At Mercurial tree, this can be handled automatically by the LinuxTV scripts, by using the cc: meta tag, together with the Signed-off-by lines. Something like: CC: someotherkerneldeveloper@someplace Signed-off-by: nowhere - This way, when a patch arrives mercurial hg tree, a mailbomb script + This way, when a patch arrives Mercurial hg tree, a mailbomb script will copy the proper interested parties. When submitting a patch via e-mail, it is better to copy all interested @@ -283,8 +284,8 @@ i) If the patch modifies the include/linux/videodev2.h file, then you document still builds. Of course, any changes you make to the public V4L2 API must be documented anyway. -j) Sometimes, mainstream changes affect the v4l-dvb tree, and mast be - backported to the v4l-dvb tree. This kind of commit to the mercurial +j) Sometimes, mainstream changes affect the v4l-dvb tree, and must be + backported to the v4l-dvb tree. This kind of commit to the Mercurial tree should follow the rules above and should also have the line: kernel-sync: @@ -352,7 +353,7 @@ l) To import contributed stuff to a developer's, a script is provided. machine, since git has a gitimport script that is used by mailimport. There's also a helper script to make easier to retrieve patches from - other mercurial repositories. The syntax is: + other Mercurial repositories. The syntax is: ./hgimport Also, hg has a feature, called mqueue, that allows having several patches @@ -437,7 +438,7 @@ Those changes will require some manual sync between -git and -hg, it is better to avoid those circumstances. During the procedure of generating kernel patches, the maintainer uses -to do a diff between the kernel tree and v4l-dvb mercurial tree +to do a diff between the kernel tree and v4l-dvb Mercurial tree (without any backport code there). If there are discrepancies, a backport patch from mainstream to v4l-dvb is generally applied by the maintainer. @@ -498,9 +499,9 @@ c. Please include a brief description in the headers of your This is just a sample commit comment, just for reference purposes. This does nothing. - Signed-off-by nowhere + Signed-off-by: nowhere -d. Every patch shall have a Developers Certificate of Origin and should +d. Every patch shall have a Developer's Certificate of Origin and should be submitted by one of its authors. All the patch authors should sign it. @@ -522,7 +523,7 @@ g. If it is a newer driver (not yet in one of the development trees), The better way for you to identify regressions with Mercurial is to use hg bisect. This is an extension provided with the current - mercurial versions. For it to work, you need to have the proper setup + Mercurial versions. For it to work, you need to have the proper setup at an hgrc file. To test if bisect is working, you can do: hg bisect help -- cgit v1.2.3 From f29dd75cad2ab933c187296919168a2a2a34ae1b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:00:37 +0100 Subject: zoran: cleanups in an attempt to make the source a bit more readable. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 9 +- linux/drivers/media/video/zoran/zoran_device.c | 404 +++++++++++-------------- linux/drivers/media/video/zoran/zoran_driver.c | 4 +- 3 files changed, 184 insertions(+), 233 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 99a25218b..ef0533086 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -920,15 +920,12 @@ zoran_check_jpg_settings (struct zoran *zr, err0++; if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) err0++; - if (settings->img_y + settings->img_height > - BUZ_MAX_HEIGHT / 2) + if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) err0++; if (settings->HorDcm && settings->VerDcm) { - if (settings->img_width % - (16 * settings->HorDcm) != 0) + if (settings->img_width % (16 * settings->HorDcm) != 0) err0++; - if (settings->img_height % - (8 * settings->VerDcm) != 0) + if (settings->img_height % (8 * settings->VerDcm) != 0) err0++; } diff --git a/linux/drivers/media/video/zoran/zoran_device.c b/linux/drivers/media/video/zoran/zoran_device.c index 87f894fa2..592300e2f 100644 --- a/linux/drivers/media/video/zoran/zoran_device.c +++ b/linux/drivers/media/video/zoran/zoran_device.c @@ -1209,22 +1209,52 @@ zoran_reap_stat_com (struct zoran *zr) } } +static void zoran_restart(struct zoran *zr) +{ + /* Now the stat_comm buffer is ready for restart */ + int status, mode; + + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { + decoder_command(zr, DECODER_GET_STATUS, &status); + mode = CODEC_DO_COMPRESSION; + } else { + status = 0; + mode = CODEC_DO_EXPANSION; + } + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + (status & DECODER_STATUS_GOOD)) { + /********** RESTART code *************/ + jpeg_codec_reset(zr); + zr->codec->set_mode(zr->codec, mode); + zr36057_set_jpg(zr, zr->codec_mode); + jpeg_start(zr); + + if (zr->num_errors <= 8) + dprintk(2, KERN_INFO "%s: Restart\n", + ZR_DEVNAME(zr)); + + zr->JPEG_missed = 0; + zr->JPEG_error = 2; + /********** End RESTART code ***********/ + } +} + static void error_handler (struct zoran *zr, u32 astat, u32 stat) { + int i, j; + /* This is JPEG error handling part */ - if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) && - (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) { - //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode); + if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && + zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { return; } if ((stat & 1) == 0 && zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && - zr->jpg_dma_tail - zr->jpg_que_tail >= - zr->jpg_buffers.num_buffers) { + zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { /* No free buffers... */ zoran_reap_stat_com(zr); zoran_feed_stat_com(zr); @@ -1233,142 +1263,95 @@ error_handler (struct zoran *zr, return; } - if (zr->JPEG_error != 1) { - /* - * First entry: error just happened during normal operation - * - * In BUZ_MODE_MOTION_COMPRESS: - * - * Possible glitch in TV signal. In this case we should - * stop the codec and wait for good quality signal before - * restarting it to avoid further problems - * - * In BUZ_MODE_MOTION_DECOMPRESS: - * - * Bad JPEG frame: we have to mark it as processed (codec crashed - * and was not able to do it itself), and to remove it from queue. - */ - btand(~ZR36057_JMC_Go_en, ZR36057_JMC); - udelay(1); - stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; - btwrite(0, ZR36057_JPC); - btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); - jpeg_codec_reset(zr); - jpeg_codec_sleep(zr, 1); - zr->JPEG_error = 1; - zr->num_errors++; - - /* Report error */ - if (zr36067_debug > 1 && zr->num_errors <= 8) { - long frame; - frame = - zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; - printk(KERN_ERR - "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", - ZR_DEVNAME(zr), stat, zr->last_isr, - zr->jpg_que_tail, zr->jpg_dma_tail, - zr->jpg_dma_head, zr->jpg_que_head, - zr->jpg_seq_num, frame); - printk("stat_com frames:"); - { - int i, j; - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - for (i = 0; - i < zr->jpg_buffers.num_buffers; - i++) { - if (le32_to_cpu(zr->stat_com[j]) == - zr->jpg_buffers. - buffer[i]. - frag_tab_bus) { - printk("% d->%d", - j, i); - } - } - } - printk("\n"); - } - } - /* Find an entry in stat_com and rotate contents */ - { - int i; - - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { - /* Mimic zr36067 operation */ - zr->stat_com[i] |= cpu_to_le32(1); - if (zr->jpg_settings.TmpDcm != 1) - zr->stat_com[i + 1] |= cpu_to_le32(1); - /* Refill */ - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - /* Find an entry in stat_com again after refill */ - if (zr->jpg_settings.TmpDcm == 1) - i = (zr->jpg_dma_tail - - zr->jpg_err_shift) & - BUZ_MASK_STAT_COM; - else - i = ((zr->jpg_dma_tail - - zr->jpg_err_shift) & 1) * 2; - } - if (i) { - /* Rotate stat_comm entries to make current entry first */ - int j; - __le32 bus_addr[BUZ_NUM_STAT_COM]; - - /* Here we are copying the stat_com array, which - * is already in little endian format, so - * no endian conversions here - */ - memcpy(bus_addr, zr->stat_com, - sizeof(bus_addr)); - for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - zr->stat_com[j] = - bus_addr[(i + j) & - BUZ_MASK_STAT_COM]; + if (zr->JPEG_error == 1) { + zoran_restart(zr); + return; + } - } - zr->jpg_err_shift += i; - zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + /* + * First entry: error just happened during normal operation + * + * In BUZ_MODE_MOTION_COMPRESS: + * + * Possible glitch in TV signal. In this case we should + * stop the codec and wait for good quality signal before + * restarting it to avoid further problems + * + * In BUZ_MODE_MOTION_DECOMPRESS: + * + * Bad JPEG frame: we have to mark it as processed (codec crashed + * and was not able to do it itself), and to remove it from queue. + */ + btand(~ZR36057_JMC_Go_en, ZR36057_JMC); + udelay(1); + stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; + btwrite(0, ZR36057_JPC); + btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); + jpeg_codec_reset(zr); + jpeg_codec_sleep(zr, 1); + zr->JPEG_error = 1; + zr->num_errors++; + + /* Report error */ + if (zr36067_debug > 1 && zr->num_errors <= 8) { + long frame; + + frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; + printk(KERN_ERR + "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", + ZR_DEVNAME(zr), stat, zr->last_isr, + zr->jpg_que_tail, zr->jpg_dma_tail, + zr->jpg_dma_head, zr->jpg_que_head, + zr->jpg_seq_num, frame); + printk(KERN_INFO "stat_com frames:"); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) { + for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { + if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].frag_tab_bus) + printk(KERN_CONT "% d->%d", j, i); } - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) - zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ } + printk(KERN_CONT "\n"); } + /* Find an entry in stat_com and rotate contents */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { + /* Mimic zr36067 operation */ + zr->stat_com[i] |= cpu_to_le32(1); + if (zr->jpg_settings.TmpDcm != 1) + zr->stat_com[i + 1] |= cpu_to_le32(1); + /* Refill */ + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); + /* Find an entry in stat_com again after refill */ + if (zr->jpg_settings.TmpDcm == 1) + i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; + else + i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; + } + if (i) { + /* Rotate stat_comm entries to make current entry first */ + int j; + __le32 bus_addr[BUZ_NUM_STAT_COM]; + + /* Here we are copying the stat_com array, which + * is already in little endian format, so + * no endian conversions here + */ + memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); - /* Now the stat_comm buffer is ready for restart */ - do { - int status, mode; - - if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_command(zr, DECODER_GET_STATUS, &status); - mode = CODEC_DO_COMPRESSION; - } else { - status = 0; - mode = CODEC_DO_EXPANSION; - } - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - (status & DECODER_STATUS_GOOD)) { - /********** RESTART code *************/ - jpeg_codec_reset(zr); - zr->codec->set_mode(zr->codec, mode); - zr36057_set_jpg(zr, zr->codec_mode); - jpeg_start(zr); - - if (zr->num_errors <= 8) - dprintk(2, KERN_INFO "%s: Restart\n", - ZR_DEVNAME(zr)); + for (j = 0; j < BUZ_NUM_STAT_COM; j++) + zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; - zr->JPEG_missed = 0; - zr->JPEG_error = 2; - /********** End RESTART code ***********/ - } - } while (0); + zr->jpg_err_shift += i; + zr->jpg_err_shift &= BUZ_MASK_STAT_COM; + } + if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) + zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ + zoran_restart(zr); } irqreturn_t @@ -1431,10 +1414,8 @@ zoran_irq (int irq, * We simply ignore them */ if (zr->v4l_memgrab_active) { - /* A lot more checks should be here ... */ - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_SnapShot) == 0) + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) dprintk(1, KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", @@ -1442,10 +1423,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { /* There is a grab on a frame going on, check if it has finished */ - - if ((btread(ZR36057_VSSFGR) & - ZR36057_VSSFGR_FrameGrab) == - 0) { + if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { /* it is finished, notify the user */ zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; @@ -1463,9 +1441,7 @@ zoran_irq (int irq, if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && zr->v4l_pend_tail != zr->v4l_pend_head) { - - int frame = zr->v4l_pend[zr->v4l_pend_tail & - V4L_MASK_FRAME]; + int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; u32 reg; zr->v4l_grab_frame = frame; @@ -1474,27 +1450,17 @@ zoran_irq (int irq, /* Buffer address */ - reg = - zr->v4l_buffers.buffer[frame]. - fbuffer_bus; + reg = zr->v4l_buffers.buffer[frame].fbuffer_bus; btwrite(reg, ZR36057_VDTR); - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; btwrite(reg, ZR36057_VDBR); /* video stride, status, and frame grab register */ reg = 0; - if (zr->v4l_settings.height > - BUZ_MAX_HEIGHT / 2) - reg += - zr->v4l_settings. - bytesperline; - reg = - (reg << - ZR36057_VSSFGR_DispStride); + if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) + reg += zr->v4l_settings.bytesperline; + reg = (reg << ZR36057_VSSFGR_DispStride); reg |= ZR36057_VSSFGR_VidOvf; reg |= ZR36057_VSSFGR_SnapShot; reg |= ZR36057_VSSFGR_FrameGrab; @@ -1512,77 +1478,66 @@ zoran_irq (int irq, #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) if (astat & ZR36057_ISR_CodRepIRQ) { zr->intr_counter_CodRepIRQ++; - IDEBUG(printk - (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", + IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", ZR_DEVNAME(zr))); btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); } #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) - if (astat & ZR36057_ISR_JPEGRepIRQ) { - - if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - if (zr36067_debug > 1 && - (!zr->frame_num || zr->JPEG_error)) { - printk(KERN_INFO - "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", - ZR_DEVNAME(zr), stat, - zr->jpg_settings.odd_even, - zr->jpg_settings. - field_per_buff, - zr->JPEG_missed); - { - char sc[] = "0000"; - char sv[5]; - int i; - strcpy(sv, sc); - for (i = 0; i < 4; i++) { - if (le32_to_cpu(zr->stat_com[i]) & 1) - sv[i] = '1'; - } - sv[4] = 0; - printk(KERN_INFO - "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", - ZR_DEVNAME(zr), sv, - zr->jpg_que_tail, - zr->jpg_dma_tail, - zr->jpg_dma_head, - zr->jpg_que_head); - } - } else { - if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics - zr->JPEG_max_missed = - zr->JPEG_missed; - if (zr->JPEG_missed < - zr->JPEG_min_missed) - zr->JPEG_min_missed = - zr->JPEG_missed; + if ((astat & ZR36057_ISR_JPEGRepIRQ) && + (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || + zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { + if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { + char sc[] = "0000"; + char sv[5]; + int i; + + printk(KERN_INFO + "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", + ZR_DEVNAME(zr), stat, + zr->jpg_settings.odd_even, + zr->jpg_settings.field_per_buff, + zr->JPEG_missed); + + strcpy(sv, sc); + for (i = 0; i < 4; i++) { + if (le32_to_cpu(zr->stat_com[i]) & 1) + sv[i] = '1'; } + sv[4] = 0; + printk(KERN_INFO + "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", + ZR_DEVNAME(zr), sv, + zr->jpg_que_tail, + zr->jpg_dma_tail, + zr->jpg_dma_head, + zr->jpg_que_head); + } else { + /* Get statistics */ + if (zr->JPEG_missed > zr->JPEG_max_missed) + zr->JPEG_max_missed = zr->JPEG_missed; + if (zr->JPEG_missed < zr->JPEG_min_missed) + zr->JPEG_min_missed = zr->JPEG_missed; + } - if (zr36067_debug > 2 && zr->frame_num < 6) { - int i; - printk("%s: seq=%ld stat_com:", - ZR_DEVNAME(zr), zr->jpg_seq_num); - for (i = 0; i < 4; i++) { - printk(" %08x", - le32_to_cpu(zr->stat_com[i])); - } - printk("\n"); + if (zr36067_debug > 2 && zr->frame_num < 6) { + int i; + + printk(KERN_INFO "%s: seq=%ld stat_com:", + ZR_DEVNAME(zr), zr->jpg_seq_num); + for (i = 0; i < 4; i++) { + printk(KERN_CONT " %08x", + le32_to_cpu(zr->stat_com[i])); } - zr->frame_num++; - zr->JPEG_missed = 0; - zr->JPEG_error = 0; - zoran_reap_stat_com(zr); - zoran_feed_stat_com(zr); - wake_up_interruptible(&zr->jpg_capq); - } /*else { - dprintk(1, - KERN_ERR - "%s: JPEG interrupt while not in motion (de)compress mode!\n", - ZR_DEVNAME(zr)); - }*/ + printk(KERN_CONT "\n"); + } + zr->frame_num++; + zr->JPEG_missed = 0; + zr->JPEG_error = 0; + zoran_reap_stat_com(zr); + zoran_feed_stat_com(zr); + wake_up_interruptible(&zr->jpg_capq); } #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ @@ -1591,8 +1546,7 @@ zoran_irq (int irq, zr->JPEG_missed > 25 || zr->JPEG_error == 1 || ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && - (zr->frame_num & (zr->JPEG_missed > - zr->jpg_settings.field_per_buff)))) { + (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { error_handler(zr, astat, stat); } diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 6a2607998..18c3516f8 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2315,7 +2315,7 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, } /* we actually need to set 'real' parameters now */ - if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) + if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) settings.TmpDcm = 1; else settings.TmpDcm = 2; @@ -2502,7 +2502,7 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { dprintk(1, KERN_ERR - "%s: VIDIOC_REQBUFS - buffers allready allocated\n", + "%s: VIDIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); res = -EBUSY; goto v4l2reqbuf_unlock_and_return; -- cgit v1.2.3 From 796fbda0aa38a68a6ba7451fb0cb1974f36cf956 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:11:17 +0100 Subject: zoran: fix TRY_FMT support From: Hans Verkuil Actually try to turn the format into something usable rather than just rejecting it if it isn't perfect. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 63 ++++++++++++++++++-------- linux/drivers/media/video/zoran/zoran_card.h | 3 +- linux/drivers/media/video/zoran/zoran_driver.c | 21 +++++++-- 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index ef0533086..552204bab 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -836,7 +836,8 @@ zoran_unregister_i2c (struct zoran *zr) int zoran_check_jpg_settings (struct zoran *zr, - struct zoran_jpg_settings *settings) + struct zoran_jpg_settings *settings, + int try) { int err = 0, err0 = 0; @@ -901,35 +902,61 @@ zoran_check_jpg_settings (struct zoran *zr, /* We have to check the data the user has set */ if (settings->HorDcm != 1 && settings->HorDcm != 2 && - (zr->card.type == DC10_new || settings->HorDcm != 4)) + (zr->card.type == DC10_new || settings->HorDcm != 4)) { + settings->HorDcm = clamp(settings->HorDcm, 1, 2); err0++; - if (settings->VerDcm != 1 && settings->VerDcm != 2) + } + if (settings->VerDcm != 1 && settings->VerDcm != 2) { + settings->VerDcm = clamp(settings->VerDcm, 1, 2); err0++; - if (settings->TmpDcm != 1 && settings->TmpDcm != 2) + } + if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { + settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); err0++; + } if (settings->field_per_buff != 1 && - settings->field_per_buff != 2) + settings->field_per_buff != 2) { + settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); err0++; - if (settings->img_x < 0) + } + if (settings->img_x < 0) { + settings->img_x = 0; err0++; - if (settings->img_y < 0) + } + if (settings->img_y < 0) { + settings->img_y = 0; err0++; - if (settings->img_width < 0) + } + if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { + settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); err0++; - if (settings->img_height < 0) + } + if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); err0++; - if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) + } + if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { + settings->img_x = BUZ_MAX_WIDTH - settings->img_width; + err0++; + } + if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { + settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; err0++; - if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) + } + if (settings->img_width % (16 * settings->HorDcm) != 0) { + settings->img_width -= settings->img_width % (16 * settings->HorDcm); + if (settings->img_width == 0) + settings->img_width = 16 * settings->HorDcm; + err0++; + } + if (settings->img_height % (8 * settings->VerDcm) != 0) { + settings->img_height -= settings->img_height % (8 * settings->VerDcm); + if (settings->img_height == 0) + settings->img_height = 8 * settings->VerDcm; err0++; - if (settings->HorDcm && settings->VerDcm) { - if (settings->img_width % (16 * settings->HorDcm) != 0) - err0++; - if (settings->img_height % (8 * settings->VerDcm) != 0) - err0++; } - if (err0) { + if (!try && err0) { dprintk(1, KERN_ERR "%s: check_jpg_settings() - error in params for decimation = 0\n", @@ -1019,7 +1046,7 @@ zoran_open_init_params (struct zoran *zr) sizeof(zr->jpg_settings.jpg_comp.COM_data)); zr->jpg_settings.jpg_comp.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT; - i = zoran_check_jpg_settings(zr, &zr->jpg_settings); + i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); if (i) dprintk(1, KERN_ERR diff --git a/linux/drivers/media/video/zoran/zoran_card.h b/linux/drivers/media/video/zoran/zoran_card.h index 4507bdc5e..4936fead7 100644 --- a/linux/drivers/media/video/zoran/zoran_card.h +++ b/linux/drivers/media/video/zoran/zoran_card.h @@ -44,7 +44,8 @@ extern int zr36067_debug; extern struct video_device zoran_template; extern int zoran_check_jpg_settings(struct zoran *zr, - struct zoran_jpg_settings *settings); + struct zoran_jpg_settings *settings, + int try); extern void zoran_open_init_params(struct zoran *zr); extern void zoran_vdev_release(struct video_device *vdev); diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 18c3516f8..748df1fcf 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -1798,7 +1798,7 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) /* Check the params first before overwriting our * nternal values */ - if (zoran_check_jpg_settings(zr, &settings)) { + if (zoran_check_jpg_settings(zr, &settings, 0)) { res = -EINVAL; goto sparams_unlock_and_return; } @@ -2206,7 +2206,7 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, settings.field_per_buff = 1; /* check */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 1); if (res) goto tryfmt_unlock_and_return; @@ -2232,6 +2232,7 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; + int bpp; int i; if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) @@ -2248,6 +2249,8 @@ static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, return -EINVAL; } + bpp = (zoran_formats[i].depth + 7) / 8; + fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3); if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) fmt->fmt.pix.width = BUZ_MAX_WIDTH; if (fmt->fmt.pix.width < BUZ_MIN_WIDTH) @@ -2335,8 +2338,16 @@ static int zoran_s_fmt_vid_out(struct file *file, void *__fh, else settings.field_per_buff = 1; + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; + } + /* check */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto sfmtjpg_unlock_and_return; @@ -3217,7 +3228,7 @@ static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop) settings.img_height = crop->c.height; /* check validity */ - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto scrop_unlock_and_return; @@ -3279,7 +3290,7 @@ static int zoran_s_jpegcomp(struct file *file, void *__fh, goto sjpegc_unlock_and_return; } - res = zoran_check_jpg_settings(zr, &settings); + res = zoran_check_jpg_settings(zr, &settings, 0); if (res) goto sjpegc_unlock_and_return; if (!fh->jpg_buffers.allocated) -- cgit v1.2.3 From 3c0d4e5fb734b1afe1cd961a4c61b90c8c6d5d9d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:12:34 +0100 Subject: zoran: fix G_FMT From: Hans Verkuil Returned height was really height / 2. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 748df1fcf..98741c992 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2084,7 +2084,7 @@ static int zoran_g_fmt_vid_out(struct file *file, void *__fh, mutex_lock(&zr->resource_lock); fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; - fmt->fmt.pix.height = fh->jpg_settings.img_height / + fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; -- cgit v1.2.3 From 42175ea795fa141cd724faf722cdbbd59358ad3c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:15:46 +0100 Subject: zoran: if reqbufs is called with count == 0, do a streamoff. From: Hans Verkuil count == 0 has a special meaning, implement this. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 98741c992..e67c6caac 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2494,6 +2494,8 @@ static int zoran_overlay(struct file *file, void *__fh, unsigned int on) return res; } +static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); + static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) { struct zoran_fh *fh = __fh; @@ -2501,17 +2503,19 @@ static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffe int res = 0; if (req->memory != V4L2_MEMORY_MMAP) { - dprintk(1, + dprintk(2, KERN_ERR "%s: only MEMORY_MMAP capture is supported, not %d\n", ZR_DEVNAME(zr), req->memory); return -EINVAL; } - mutex_lock(&zr->resource_lock); + if (req->count == 0) + return zoran_streamoff(file, fh, req->type); + mutex_lock(&zr->resource_lock); if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) { - dprintk(1, + dprintk(2, KERN_ERR "%s: VIDIOC_REQBUFS - buffers already allocated\n", ZR_DEVNAME(zr)); -- cgit v1.2.3 From 441ce16cab1f8d7a546eeb785da0f9caf28ef7cc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:26:06 +0100 Subject: zoran et al: convert zoran i2c modules to V4L2. From: Hans Verkuil The zoran i2c modules were still using V4L1 internally. Replace this with V4L2. Also deleted saa7111.c and saa7114.c, we use saa7115.c instead. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/Kconfig | 28 +- linux/drivers/media/video/Makefile | 2 - linux/drivers/media/video/adv7170.c | 74 +- linux/drivers/media/video/adv7175.c | 81 +- linux/drivers/media/video/bt819.c | 271 +++--- linux/drivers/media/video/bt856.c | 92 +- linux/drivers/media/video/bt866.c | 67 +- linux/drivers/media/video/ks0127.c | 140 ++-- linux/drivers/media/video/saa7110.c | 208 ++--- linux/drivers/media/video/saa7111.c | 497 ----------- linux/drivers/media/video/saa7114.c | 1073 ------------------------ linux/drivers/media/video/saa7185.c | 78 +- linux/drivers/media/video/vpx3220.c | 220 ++--- linux/drivers/media/video/zoran/Kconfig | 4 +- linux/drivers/media/video/zoran/zoran.h | 6 +- linux/drivers/media/video/zoran/zoran_card.c | 60 +- linux/drivers/media/video/zoran/zoran_device.c | 61 +- linux/drivers/media/video/zoran/zoran_driver.c | 220 ++--- 18 files changed, 642 insertions(+), 2540 deletions(-) delete mode 100644 linux/drivers/media/video/saa7111.c delete mode 100644 linux/drivers/media/video/saa7114.c diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 19cf3b8f6..e671beb59 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -307,38 +307,18 @@ config VIDEO_TCM825X config VIDEO_SAA7110 tristate "Philips SAA7110 video decoder" - depends on VIDEO_V4L1 && I2C + depends on VIDEO_V4L2 && I2C ---help--- Support for the Philips SAA7110 video decoders. To compile this driver as a module, choose M here: the module will be called saa7110. -config VIDEO_SAA7111 - tristate "Philips SAA7111 video decoder" - depends on VIDEO_V4L1 && I2C - ---help--- - Support for the Philips SAA711 video decoder. - - To compile this driver as a module, choose M here: the - module will be called saa7111. - -config VIDEO_SAA7114 - tristate "Philips SAA7114 video decoder" - depends on VIDEO_V4L1 && I2C - ---help--- - Support for the Philips SAA7114 video decoder. This driver - is used only on Zoran driver and should be moved soon to - SAA711x module. - - To compile this driver as a module, choose M here: the - module will be called saa7114. - config VIDEO_SAA711X - tristate "Philips SAA7113/4/5 video decoders" + tristate "Philips SAA7111/3/4/5 video decoders" depends on VIDEO_V4L2 && I2C ---help--- - Support for the Philips SAA7113/4/5 video decoders. + Support for the Philips SAA7111/3/4/5 video decoders. To compile this driver as a module, choose M here: the module will be called saa7115. @@ -639,7 +619,7 @@ config VIDEO_MXB depends on PCI && VIDEO_V4L1 && I2C select VIDEO_SAA7146_VV select VIDEO_TUNER - select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 72f6d03d2..263c2264d 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -43,8 +43,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o -obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o -obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c index 0a319ad8e..323cea3a9 100644 --- a/linux/drivers/media/video/adv7170.c +++ b/linux/drivers/media/video/adv7170.c @@ -53,9 +53,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct adv7170 { unsigned char reg[128]; - int norm; + v4l2_std_id norm; int input; - int enable; int bright; int contrast; int hue; @@ -63,7 +62,6 @@ struct adv7170 { }; static char *inputs[] = { "pass_through", "play_back" }; -static char *norms[] = { "PAL", "NTSC" }; /* ----------------------------------------------------------------------- */ @@ -192,7 +190,7 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) struct adv7170 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: #if 0 /* keep */ /* This is just for testing!!! */ adv7170_write_block(client, init_common, @@ -202,63 +200,47 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) #endif break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id iarg = *(v4l2_std_id *) arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int iarg = *(int *) arg; - - v4l_dbg(1, debug, client, "set norm %d\n", iarg); + v4l_dbg(1, debug, client, "set norm %llx\n", iarg); - switch (iarg) { - case VIDEO_MODE_NTSC: + if (iarg & V4L2_STD_NTSC) { adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_PAL: + } else if (iarg & V4L2_STD_PAL) { adv7170_write_block(client, init_PAL, sizeof(init_PAL)); if (encoder->input == 0) adv7170_write(client, 0x02, 0x0e); // Enable genlock adv7170_write(client, 0x07, TR0MODE | TR0RST); adv7170_write(client, 0x07, TR0MODE); - break; - - default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + } else { + v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + v4l_dbg(1, debug, client, "switched to %llx\n", iarg); encoder->norm = iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int iarg = *(int *) arg; + struct v4l2_routing *route = arg; /* RJ: *iarg = 0: input is from decoder *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ v4l_dbg(1, debug, client, "set input from %s\n", - iarg == 0 ? "decoder" : "ZR36060"); + route->input == 0 ? "decoder" : "ZR36060"); - switch (iarg) { + switch (route->input) { case 0: adv7170_write(client, 0x01, 0x20); adv7170_write(client, 0x08, TR1CAPT); /* TR1 */ @@ -278,30 +260,11 @@ static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); - return -EINVAL; - } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); - encoder->input = iarg; - break; - } - - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { + v4l_dbg(1, debug, client, "illegal input: %d\n", route->input); return -EINVAL; } - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; + v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]); + encoder->input = route->input; break; } @@ -338,9 +301,8 @@ static int adv7170_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; + encoder->norm = V4L2_STD_NTSC; encoder->input = 0; - encoder->enable = 1; i2c_set_clientdata(client, encoder); i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC)); diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c index 281a3f53c..11c92440e 100644 --- a/linux/drivers/media/video/adv7175.c +++ b/linux/drivers/media/video/adv7175.c @@ -47,9 +47,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); /* ----------------------------------------------------------------------- */ struct adv7175 { - int norm; + v4l2_std_id norm; int input; - int enable; int bright; int contrast; int hue; @@ -60,7 +59,6 @@ struct adv7175 { #define I2C_ADV7176 0x54 static char *inputs[] = { "pass_through", "play_back", "color_bar" }; -static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" }; /* ----------------------------------------------------------------------- */ @@ -190,7 +188,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) struct adv7175 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ adv7175_write_block(client, init_common, sizeof(init_common)); @@ -198,42 +196,25 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x07, TR0MODE); break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id iarg = *(v4l2_std_id *) arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_SECAM; /* well, hacky */ - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int iarg = *(int *) arg; - - switch (iarg) { - case VIDEO_MODE_NTSC: + if (iarg & V4L2_STD_NTSC) { adv7175_write_block(client, init_ntsc, sizeof(init_ntsc)); if (encoder->input == 0) adv7175_write(client, 0x0d, 0x4f); // Enable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_PAL: + } else if (iarg & V4L2_STD_PAL) { adv7175_write_block(client, init_pal, sizeof(init_pal)); if (encoder->input == 0) adv7175_write(client, 0x0d, 0x4f); // Enable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - - case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM. + } else if (iarg & V4L2_STD_SECAM) { /* This is an attempt to convert * SECAM->PAL (typically it does not work * due to genlock: when decoder is in SECAM @@ -246,33 +227,32 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) adv7175_write(client, 0x0d, 0x49); // Disable genlock adv7175_write(client, 0x07, TR0MODE | TR0RST); adv7175_write(client, 0x07, TR0MODE); - break; - default: - v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg); + } else { + v4l_dbg(1, debug, client, "illegal norm: %llx\n", iarg); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]); + v4l_dbg(1, debug, client, "switched to %llx\n", iarg); encoder->norm = iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int iarg = *(int *) arg; + struct v4l2_routing *route = arg; /* RJ: *iarg = 0: input is from SAA7110 *iarg = 1: input is from ZR36060 *iarg = 2: color bar */ - switch (iarg) { + switch (route->input) { case 0: adv7175_write(client, 0x01, 0x00); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 1); adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */ - if (encoder->norm == VIDEO_MODE_SECAM) + if (encoder->norm & V4L2_STD_SECAM) adv7175_write(client, 0x0d, 0x49); // Disable genlock else adv7175_write(client, 0x0d, 0x4f); // Enable genlock @@ -284,7 +264,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) case 1: adv7175_write(client, 0x01, 0x00); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 0); adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */ @@ -297,7 +277,7 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) case 2: adv7175_write(client, 0x01, 0x80); - if (encoder->norm == VIDEO_MODE_NTSC) + if (encoder->norm & V4L2_STD_NTSC) set_subcarrier_freq(client, 0); adv7175_write(client, 0x0d, 0x49); @@ -307,29 +287,11 @@ static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg) break; default: - v4l_dbg(1, debug, client, "illegal input: %d\n", iarg); + v4l_dbg(1, debug, client, "illegal input: %d\n", route->input); return -EINVAL; } - v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]); - encoder->input = iarg; - break; - } - - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; + v4l_dbg(1, debug, client, "switched to %s\n", inputs[route->input]); + encoder->input = route->input; break; } @@ -370,9 +332,8 @@ static int adv7175_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_PAL; + encoder->norm = V4L2_STD_NTSC; encoder->input = 0; - encoder->enable = 1; i2c_set_clientdata(client, encoder); i = adv7175_write_block(client, init_common, sizeof(init_common)); diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 201dd9277..cd85ea462 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -55,7 +55,7 @@ struct bt819 { unsigned char reg[32]; int initialized; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -179,7 +179,7 @@ static int bt819_init(struct i2c_client *client) 0x1a, 0x80, /* 0x1a ADC Interface */ }; - struct timing *timing = &timing_data[decoder->norm]; + struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0]; init[0x03 * 2 - 1] = (((timing->vdelay >> 8) & 0x03) << 6) | @@ -193,7 +193,7 @@ static int bt819_init(struct i2c_client *client) init[0x08 * 2 - 1] = timing->hscale >> 8; init[0x09 * 2 - 1] = timing->hscale & 0xff; /* 0x15 in array is address 0x19 */ - init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */ + init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */ /* reset */ bt819_write(client, 0x1f, 0x00); mdelay(1); @@ -216,121 +216,93 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) } switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ bt819_init(client); break; - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { int *iarg = arg; + v4l2_std_id *istd = arg; int status; - int res; + int res = V4L2_IN_ST_NO_SIGNAL; + v4l2_std_id std; status = bt819_read(client, 0x00); - res = 0; if ((status & 0x80)) - res |= DECODER_STATUS_GOOD; + res = 0; - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & 0x10)) - res |= DECODER_STATUS_PAL; - else - res |= DECODER_STATUS_NTSC; - break; - } - res |= DECODER_STATUS_COLOR; - *iarg = res; + if ((status & 0x10)) + std = V4L2_STD_PAL; + else + std = V4L2_STD_NTSC; + if (cmd == VIDIOC_QUERYSTD) + *istd = std; + else + *iarg = res; v4l_dbg(1, debug, client, "get status %x\n", *iarg); break; } - case DECODER_SET_NORM: + case VIDIOC_S_STD: { - int *iarg = arg; + v4l2_std_id *iarg = arg; struct timing *timing = NULL; - v4l_dbg(1, debug, client, "set norm %x\n", *iarg); + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) { bt819_setbit(client, 0x01, 0, 1); bt819_setbit(client, 0x01, 1, 0); bt819_setbit(client, 0x01, 5, 0); bt819_write(client, 0x18, 0x68); bt819_write(client, 0x19, 0x5d); /* bt819_setbit(client, 0x1a, 5, 1); */ - timing = &timing_data[VIDEO_MODE_NTSC]; - break; - case VIDEO_MODE_PAL: + timing = &timing_data[1]; + } else if (*iarg & V4L2_STD_PAL) { bt819_setbit(client, 0x01, 0, 1); bt819_setbit(client, 0x01, 1, 1); bt819_setbit(client, 0x01, 5, 1); bt819_write(client, 0x18, 0x7f); bt819_write(client, 0x19, 0x72); /* bt819_setbit(client, 0x1a, 5, 0); */ - timing = &timing_data[VIDEO_MODE_PAL]; - break; - case VIDEO_MODE_AUTO: - bt819_setbit(client, 0x01, 0, 0); - bt819_setbit(client, 0x01, 1, 0); - break; - default: - v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg); + timing = &timing_data[0]; + } else { + v4l_dbg(1, debug, client, "unsupported norm %llx\n", *iarg); return -EINVAL; } - - if (timing) { - bt819_write(client, 0x03, - (((timing->vdelay >> 8) & 0x03) << 6) | - (((timing->vactive >> 8) & 0x03) << 4) | - (((timing->hdelay >> 8) & 0x03) << 2) | - ((timing->hactive >> 8) & 0x03) ); - bt819_write(client, 0x04, timing->vdelay & 0xff); - bt819_write(client, 0x05, timing->vactive & 0xff); - bt819_write(client, 0x06, timing->hdelay & 0xff); - bt819_write(client, 0x07, timing->hactive & 0xff); - bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff); - bt819_write(client, 0x09, timing->hscale & 0xff); - } - +/* case VIDEO_MODE_AUTO: + bt819_setbit(client, 0x01, 0, 0); + bt819_setbit(client, 0x01, 1, 0);*/ + + bt819_write(client, 0x03, + (((timing->vdelay >> 8) & 0x03) << 6) | + (((timing->vactive >> 8) & 0x03) << 4) | + (((timing->hdelay >> 8) & 0x03) << 2) | + ((timing->hactive >> 8) & 0x03)); + bt819_write(client, 0x04, timing->vdelay & 0xff); + bt819_write(client, 0x05, timing->vactive & 0xff); + bt819_write(client, 0x06, timing->hdelay & 0xff); + bt819_write(client, 0x07, timing->hactive & 0xff); + bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff); + bt819_write(client, 0x09, timing->hscale & 0xff); decoder->norm = *iarg; break; } - case DECODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - v4l_dbg(1, debug, client, "set input %x\n", *iarg); + v4l_dbg(1, debug, client, "set input %x\n", route->input); - if (*iarg < 0 || *iarg > 7) + if (route->input < 0 || route->input > 7) return -EINVAL; - if (decoder->input != *iarg) { - decoder->input = *iarg; + if (decoder->input != route->input) { + decoder->input = route->input; /* select mode */ if (decoder->input == 0) { bt819_setbit(client, 0x0b, 6, 0); @@ -343,75 +315,116 @@ static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case DECODER_SET_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int *iarg = arg; + int enable = cmd == VIDIOC_STREAMON; - v4l_dbg(1, debug, client, "set output %x\n", *iarg); + v4l_dbg(1, debug, client, "enable output %x\n", enable); - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; + if (decoder->enable != enable) { + decoder->enable = enable; + bt819_setbit(client, 0x16, 7, !enable); + } break; } - case DECODER_ENABLE_OUTPUT: + case VIDIOC_QUERYCTRL: { - int *iarg = arg; - int enable = (*iarg != 0); + struct v4l2_queryctrl *qc = arg; - v4l_dbg(1, debug, client, "enable output %x\n", *iarg); + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; - if (decoder->enable != enable) { - decoder->enable = enable; - bt819_setbit(client, 0x16, 7, !enable); + case V4L2_CID_CONTRAST: + v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); + break; + + case V4L2_CID_SATURATION: + v4l2_ctrl_query_fill(qc, 0, 511, 1, 256); + break; + + case V4L2_CID_HUE: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; + + default: + return -EINVAL; } break; } - case DECODER_SET_PICTURE: + case VIDIOC_S_CTRL: { - struct video_picture *pic = arg; + struct v4l2_control *ctrl = arg; - v4l_dbg(1, debug, client, - "set picture brightness %d contrast %d colour %d\n", - pic->brightness, pic->contrast, pic->colour); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + bt819_write(client, 0x0a, decoder->bright); + } + break; + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + decoder->contrast = ctrl->value; + bt819_write(client, 0x0c, + decoder->contrast & 0xff); + bt819_setbit(client, 0x0b, 2, + ((decoder->contrast >> 8) & 0x01)); + } + break; - if (decoder->bright != pic->brightness) { - /* We want -128 to 127 we get 0-65535 */ - decoder->bright = pic->brightness; - bt819_write(client, 0x0a, - (decoder->bright >> 8) - 128); - } + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + bt819_write(client, 0x0d, + (decoder->sat >> 7) & 0xff); + bt819_setbit(client, 0x0b, 1, + ((decoder->sat >> 15) & 0x01)); + + /* Ratio between U gain and V gain must stay the same as + the ratio between the default U and V gain values. */ + temp = (decoder->sat * 180) / 254; + bt819_write(client, 0x0e, (temp >> 7) & 0xff); + bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); + } + break; - if (decoder->contrast != pic->contrast) { - /* We want 0 to 511 we get 0-65535 */ - decoder->contrast = pic->contrast; - bt819_write(client, 0x0c, - (decoder->contrast >> 7) & 0xff); - bt819_setbit(client, 0x0b, 2, - ((decoder->contrast >> 15) & 0x01)); + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + bt819_write(client, 0x0f, decoder->hue); + } + break; + default: + return -EINVAL; } + break; + } - if (decoder->sat != pic->colour) { - /* We want 0 to 511 we get 0-65535 */ - decoder->sat = pic->colour; - bt819_write(client, 0x0d, - (decoder->sat >> 7) & 0xff); - bt819_setbit(client, 0x0b, 1, - ((decoder->sat >> 15) & 0x01)); - - temp = (decoder->sat * 201) / 237; - bt819_write(client, 0x0e, (temp >> 7) & 0xff); - bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01); - } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - bt819_write(client, 0x0f, - 128 - (decoder->hue >> 8)); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } break; } @@ -463,13 +476,13 @@ static int bt819_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL); if (decoder == NULL) return -ENOMEM; - decoder->norm = VIDEO_MODE_NTSC; + decoder->norm = V4L2_STD_NTSC; decoder->input = 0; decoder->enable = 1; - decoder->bright = 32768; - decoder->contrast = 32768; - decoder->hue = 32768; - decoder->sat = 32768; + decoder->bright = 0; + decoder->contrast = 0xd8; /* 100% of original signal */ + decoder->hue = 0; + decoder->sat = 0xfe; /* 100% of original signal */ decoder->initialized = 0; i2c_set_clientdata(client, decoder); diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c index 89c4061c7..626019e49 100644 --- a/linux/drivers/media/video/bt856.c +++ b/linux/drivers/media/video/bt856.c @@ -56,8 +56,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct bt856 { unsigned char reg[BT856_NR_REG]; - int norm; - int enable; + v4l2_std_id norm; }; /* ----------------------------------------------------------------------- */ @@ -97,7 +96,7 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) struct bt856 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: /* This is just for testing!!! */ v4l_dbg(1, debug, client, "init\n"); bt856_write(client, 0xdc, 0x18); @@ -108,15 +107,10 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) //bt856_setbit(client, 0xdc, 6, 0); bt856_setbit(client, 0xdc, 4, 1); - switch (encoder->norm) { - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + else bt856_setbit(client, 0xdc, 2, 1); - break; - } bt856_setbit(client, 0xdc, 1, 1); bt856_setbit(client, 0xde, 4, 0); @@ -125,38 +119,19 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) bt856_dump(client); break; - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "get capabilities\n"); + v4l2_std_id *iarg = arg; - cap->flags = VIDEO_ENCODER_PAL | - VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_CCIR; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int *iarg = arg; + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); - - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) { bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + } else if (*iarg & V4L2_STD_PAL) { bt856_setbit(client, 0xdc, 2, 1); bt856_setbit(client, 0xda, 0, 0); //bt856_setbit(client, 0xda, 0, 1); - break; - - default: + } else { return -EINVAL; } encoder->norm = *iarg; @@ -165,16 +140,16 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + v4l_dbg(1, debug, client, "set input %d\n", route->input); /* We only have video bus. - * iarg = 0: input is from bt819 - * iarg = 1: input is from ZR36060 */ - switch (*iarg) { + * route->input= 0: input is from bt819 + * route->input= 1: input is from ZR36060 */ + switch (route->input) { case 0: bt856_setbit(client, 0xde, 4, 0); bt856_setbit(client, 0xde, 3, 1); @@ -200,28 +175,6 @@ static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output %d\n", *iarg); - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; - - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; - } - default: return -EINVAL; } @@ -250,8 +203,7 @@ static int bt856_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; - encoder->enable = 1; + encoder->norm = V4L2_STD_NTSC; i2c_set_clientdata(client, encoder); bt856_write(client, 0xdc, 0x18); @@ -262,16 +214,10 @@ static int bt856_probe(struct i2c_client *client, //bt856_setbit(client, 0xdc, 6, 0); bt856_setbit(client, 0xdc, 4, 1); - switch (encoder->norm) { - - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) bt856_setbit(client, 0xdc, 2, 0); - break; - - case VIDEO_MODE_PAL: + else bt856_setbit(client, 0xdc, 2, 1); - break; - } bt856_setbit(client, 0xdc, 1, 1); bt856_setbit(client, 0xde, 4, 0); diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index aaa985c8e..5aed3c7f1 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -53,8 +53,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct bt866 { u8 reg[256]; - int norm; - int enable; + v4l2_std_id norm; int bright; int contrast; int hue; @@ -95,44 +94,21 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) struct bt866 *encoder = i2c_get_clientdata(client); switch (cmd) { - case ENCODER_GET_CAPABILITIES: + case VIDIOC_INT_S_STD_OUTPUT: { - struct video_encoder_capability *cap = arg; + v4l2_std_id *iarg = arg; - v4l_dbg(1, debug, client, "get capabilities\n"); + v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); - cap->flags - = VIDEO_ENCODER_PAL - | VIDEO_ENCODER_NTSC - | VIDEO_ENCODER_CCIR; - cap->inputs = 2; - cap->outputs = 1; - break; - } - - case ENCODER_SET_NORM: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set norm %d\n", *iarg); - - switch (*iarg) { - case VIDEO_MODE_NTSC: - break; - - case VIDEO_MODE_PAL: - break; - - default: + if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL))) return -EINVAL; - } encoder->norm = *iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; static const __u8 init[] = { 0xc8, 0xcc, /* CRSCALE */ 0xca, 0x91, /* CBSCALE */ @@ -168,7 +144,7 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) val = encoder->reg[0xdc]; - if (*iarg == 0) + if (route->input == 0) val |= 0x40; /* CBSWAP */ else val &= ~0x40; /* !CBSWAP */ @@ -176,15 +152,15 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) bt866_write(client, 0xdc, val); val = encoder->reg[0xcc]; - if (*iarg == 2) + if (route->input == 2) val |= 0x01; /* OSDBAR */ else val &= ~0x01; /* !OSDBAR */ bt866_write(client, 0xcc, val); - v4l_dbg(1, debug, client, "set input %d\n", *iarg); + v4l_dbg(1, debug, client, "set input %d\n", route->input); - switch (*iarg) { + switch (route->input) { case 0: break; case 1: @@ -195,27 +171,6 @@ static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output %d\n", *iarg); - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - encoder->enable = !!*iarg; - - v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable); - break; - } - case 4711: { int *iarg = arg; diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c index 16526165b..3b565c039 100644 --- a/linux/drivers/media/video/ks0127.c +++ b/linux/drivers/media/video/ks0127.c @@ -202,7 +202,7 @@ struct ks0127 { int format_height; int cap_width; int cap_height; - int norm; + v4l2_std_id norm; int ks_type; u8 regs[256]; }; @@ -409,20 +409,22 @@ static void ks0127_reset(struct i2c_client *c) static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) { struct ks0127 *ks = i2c_get_clientdata(c); + struct v4l2_routing *route = arg; int *iarg = (int *)arg; + v4l2_std_id *istd = arg; int status; if (!ks) return -ENODEV; switch (cmd) { - case DECODER_INIT: - v4l_dbg(1, debug, c, "DECODER_INIT\n"); + case VIDIOC_INT_INIT: + v4l_dbg(1, debug, c, "VIDIOC_INT_INIT\n"); ks0127_reset(c); break; - case DECODER_SET_INPUT: - switch(*iarg) { + case VIDIOC_INT_S_VIDEO_ROUTING: + switch (route->input) { case KS_INPUT_COMPOSITE_1: case KS_INPUT_COMPOSITE_2: case KS_INPUT_COMPOSITE_3: @@ -430,7 +432,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_COMPOSITE_5: case KS_INPUT_COMPOSITE_6: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: Composite\n", *iarg); + "VIDIOC_S_INPUT %d: Composite\n", *iarg); /* autodetect 50/60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ @@ -464,7 +466,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_SVIDEO_2: case KS_INPUT_SVIDEO_3: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT %d: S-Video\n", *iarg); + "VIDIOC_S_INPUT %d: S-Video\n", *iarg); /* autodetect 50/60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00); /* VSE=0 */ @@ -496,9 +498,8 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) case KS_INPUT_YUV656: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT 15: YUV656\n"); - if (ks->norm == VIDEO_MODE_NTSC || - ks->norm == KS_STD_PAL_M) + "VIDIOC_S_INPUT 15: YUV656\n"); + if (ks->norm & V4L2_STD_525_60) /* force 60 Hz */ ks0127_and_or(c, KS_CMDA, 0xfc, 0x03); else @@ -542,7 +543,7 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) default: v4l_dbg(1, debug, c, - "DECODER_SET_INPUT: Unknown input %d\n", *iarg); + "VIDIOC_INT_S_VIDEO_ROUTING: Unknown input %d\n", route->input); break; } @@ -551,33 +552,18 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]); break; - case DECODER_SET_OUTPUT: - switch(*iarg) { - case KS_OUTPUT_YUV656E: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n"); - return -EINVAL; - - case KS_OUTPUT_EXV: - v4l_dbg(1, debug, c, - "DECODER_SET_OUTPUT: OUTPUT_EXV\n"); - ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09); - break; - } - break; - - case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */ + case VIDIOC_S_STD: /* sam This block mixes old and new norm names... */ /* Set to automatic SECAM/Fsc mode */ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00); - ks->norm = *iarg; - switch (*iarg) { + ks->norm = *istd; +#if 0 /* this is untested !! */ /* It just detects PAL_N/NTSC_M (no special frequencies) */ /* And you have to set the standard a second time afterwards */ case VIDEO_MODE_AUTO: v4l_dbg(1, debug, c, - "DECODER_SET_NORM: AUTO\n"); + "VIDIOC_S_STD: AUTO\n"); /* The chip determines the format */ /* based on the current field rate */ @@ -588,40 +574,33 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) ks->format_height = 240; ks->format_width = 704; break; +#endif - case VIDEO_MODE_NTSC: + if (*istd & V4L2_STD_NTSC) { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: NTSC_M\n"); + "VIDIOC_S_STD: NTSC_M\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 240; ks->format_width = 704; - break; - - case KS_STD_NTSC_N: + } else if (*istd & V4L2_STD_PAL_N) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: NTSC_N (fixme)\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 240; ks->format_width = 704; - break; - - case VIDEO_MODE_PAL: + } else if (*istd & V4L2_STD_PAL) { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: PAL_N\n"); + "VIDIOC_S_STD: PAL_N\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20); ks->format_height = 290; ks->format_width = 704; - break; - - case KS_STD_PAL_M: + } else if (*istd & V4L2_STD_PAL_M) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: PAL_M (fixme)\n"); ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40); ks->format_height = 290; ks->format_width = 704; - break; - - case VIDEO_MODE_SECAM: + } else if (*istd & V4L2_STD_SECAM) { v4l_dbg(1, debug, c, "KS0127_SET_NORM: SECAM\n"); ks->format_height = 290; @@ -633,29 +612,34 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) schedule_timeout_interruptible(HZ/10+1); /* did it autodetect? */ - if (ks0127_read(c, KS_DEMOD) & 0x40) - break; - - /* force to secam mode */ - ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); - break; - - default: + if (!(ks0127_read(c, KS_DEMOD) & 0x40)) + /* force to secam mode */ + ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f); + } else { v4l_dbg(1, debug, c, - "DECODER_SET_NORM: Unknown norm %d\n", *iarg); - break; + "VIDIOC_S_STD: Unknown norm %llx\n", *istd); } break; - case DECODER_SET_PICTURE: + case VIDIOC_QUERYCTRL: + { + return -EINVAL; + } + + case VIDIOC_S_CTRL: v4l_dbg(1, debug, c, - "DECODER_SET_PICTURE: not yet supported\n"); + "VIDIOC_S_CTRL: not yet supported\n"); return -EINVAL; - /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */ - /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */ - /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */ + case VIDIOC_G_CTRL: + v4l_dbg(1, debug, c, + "VIDIOC_G_CTRL: not yet supported\n"); + return -EINVAL; + + /* sam todo: KS0127_SET_BRIGHTNESS: Merge into VIDIOC_S_CTRL */ + /* sam todo: KS0127_SET_CONTRAST: Merge into VIDIOC_S_CTRL */ + /* sam todo: KS0127_SET_HUE: Merge into VIDIOC_S_CTRL? */ + /* sam todo: KS0127_SET_SATURATION: Merge into VIDIOC_S_CTRL */ /* sam todo: KS0127_SET_AGC_MODE: */ /* sam todo: KS0127_SET_AGC: */ /* sam todo: KS0127_SET_CHROMA_MODE: */ @@ -671,22 +655,21 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) /* sam todo: KS0127_SET_UNUSEV: */ /* sam todo: KS0127_SET_VSALIGN_MODE: */ - case DECODER_ENABLE_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int enable; + int enable = cmd == VIDIOC_STREAMON; - iarg = arg; - enable = (*iarg != 0); if (enable) { v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT on\n"); + "VIDIOC_STREAMON\n"); /* All output pins on */ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30); /* Obey the OEN pin */ ks0127_and_or(c, KS_CDEM, 0x7f, 0x00); } else { v4l_dbg(1, debug, c, - "DECODER_ENABLE_OUTPUT off\n"); + "VIDIOC_STREAMOFF\n"); /* Video output pins off */ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00); /* Ignore the OEN pin */ @@ -700,19 +683,26 @@ static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg) /* sam todo: KS0127_SET_HEIGHT: */ /* sam todo: KS0127_SET_HSCALE: */ - case DECODER_GET_STATUS: - v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n"); - *iarg = 0; + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { + int stat = V4L2_IN_ST_NO_SIGNAL; + v4l2_std_id std = V4L2_STD_ALL; + v4l_dbg(1, debug, c, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); status = ks0127_read(c, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ - *iarg = (*iarg | DECODER_STATUS_GOOD); - if ((status & 0x01)) /* CLOCK set */ - *iarg = (*iarg | DECODER_STATUS_COLOR); + stat = 0; + if (!(status & 0x01)) /* CLOCK set */ + stat |= V4L2_IN_ST_NO_COLOR; if ((status & 0x08)) /* PALDET set */ - *iarg = (*iarg | DECODER_STATUS_PAL); + std = V4L2_STD_PAL; + else + std = V4L2_STD_NTSC; + if (cmd == VIDIOC_QUERYSTD) + *istd = std; else - *iarg = (*iarg | DECODER_STATUS_NTSC); + *iarg = stat; break; + } /* Catch any unknown command */ default: diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index b7afe3124..147c36a71 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct saa7110 { u8 reg[SAA7110_NR_REG]; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -177,7 +177,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = { /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 }; -static int determine_norm(struct i2c_client *client) +static v4l2_std_id determine_norm(struct i2c_client *client) { DEFINE_WAIT(wait); struct saa7110 *decoder = i2c_get_clientdata(client); @@ -199,11 +199,11 @@ static int determine_norm(struct i2c_client *client) if (status & 0x20) { v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status); //saa7110_write(client,0x2E,0x81); - return VIDEO_MODE_NTSC; + return V4L2_STD_NTSC; } v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status); //saa7110_write(client,0x2E,0x9A); - return VIDEO_MODE_PAL; + return V4L2_STD_PAL; } //saa7110_write(client,0x06,0x03); if (status & 0x20) { /* 60Hz */ @@ -212,7 +212,7 @@ static int determine_norm(struct i2c_client *client) saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client,0x2E,0x81); - return VIDEO_MODE_NTSC; + return V4L2_STD_NTSC; } /* 50Hz -> PAL/SECAM */ @@ -229,10 +229,10 @@ static int determine_norm(struct i2c_client *client) if ((status & 0x03) == 0x01) { v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status); saa7110_write(client, 0x0D, 0x87); - return VIDEO_MODE_SECAM; + return V4L2_STD_SECAM; } v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status); - return VIDEO_MODE_PAL; + return V4L2_STD_PAL; } static int @@ -241,112 +241,81 @@ saa7110_command (struct i2c_client *client, void *arg) { struct saa7110 *decoder = i2c_get_clientdata(client); + struct v4l2_routing *route = arg; + v4l2_std_id std; int v; switch (cmd) { - case 0: + case VIDIOC_INT_INIT: //saa7110_write_block(client, initseq, sizeof(initseq)); break; - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *dc = arg; - - dc->flags = - VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; - dc->inputs = SAA7110_MAX_INPUT; - dc->outputs = SAA7110_MAX_OUTPUT; - break; - } - - case DECODER_GET_STATUS: + case VIDIOC_INT_G_INPUT_STATUS: { + int res = V4L2_IN_ST_NO_SIGNAL; int status; - int res = 0; status = saa7110_read(client); - v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n", + v4l_dbg(1, debug, client, "status=0x%02x norm=%llx\n", status, decoder->norm); if (!(status & 0x40)) - res |= DECODER_STATUS_GOOD; - if (status & 0x03) - res |= DECODER_STATUS_COLOR; + res = 0; + if (!(status & 0x03)) + res |= V4L2_IN_ST_NO_COLOR; - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - } *(int *) arg = res; break; } - case DECODER_SET_NORM: - v = *(int *) arg; - if (decoder->norm != v) { - decoder->norm = v; + case VIDIOC_QUERYSTD: + { + *(v4l2_std_id *)arg = determine_norm(client); + break; + } + + case VIDIOC_S_STD: + std = *(v4l2_std_id *) arg; + if (decoder->norm != std) { + decoder->norm = std; //saa7110_write(client, 0x06, 0x03); - switch (v) { - case VIDEO_MODE_NTSC: + if (std & V4L2_STD_NTSC) { saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x50); saa7110_write(client, 0x11, 0x2C); //saa7110_write(client, 0x2E, 0x81); v4l_dbg(1, debug, client, "switched to NTSC\n"); - break; - case VIDEO_MODE_PAL: + } else if (std & V4L2_STD_PAL) { saa7110_write(client, 0x0D, 0x86); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to PAL\n"); - break; - case VIDEO_MODE_SECAM: + } else if (std & V4L2_STD_SECAM) { saa7110_write(client, 0x0D, 0x87); saa7110_write(client, 0x0F, 0x10); saa7110_write(client, 0x11, 0x59); //saa7110_write(client, 0x2E, 0x9A); v4l_dbg(1, debug, client, "switched to SECAM\n"); - break; - case VIDEO_MODE_AUTO: - v4l_dbg(1, debug, client, "switched to AUTO\n"); - decoder->norm = determine_norm(client); - *(int *) arg = decoder->norm; - break; - default: - return -EPERM; + } else { + return -EINVAL; } } break; - case DECODER_SET_INPUT: - v = *(int *) arg; - if (v < 0 || v >= SAA7110_MAX_INPUT) { - v4l_dbg(1, debug, client, "input=%d not available\n", v); + case VIDIOC_INT_S_VIDEO_ROUTING: + if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) { + v4l_dbg(1, debug, client, "input=%d not available\n", route->input); return -EINVAL; } - if (decoder->input != v) { - saa7110_selmux(client, v); - v4l_dbg(1, debug, client, "switched to input=%d\n", v); + if (decoder->input != route->input) { + saa7110_selmux(client, route->input); + v4l_dbg(1, debug, client, "switched to input=%d\n", route->input); } break; - case DECODER_SET_OUTPUT: - v = *(int *) arg; - /* not much choice of outputs */ - if (v != 0) - return -EINVAL; - break; - - case DECODER_ENABLE_OUTPUT: - v = *(int *) arg; + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: + v = cmd == VIDIOC_STREAMON; if (decoder->enable != v) { decoder->enable = v; saa7110_write(client, 0x0E, v ? 0x18 : 0x80); @@ -354,46 +323,79 @@ saa7110_command (struct i2c_client *client, } break; - case DECODER_SET_PICTURE: + case VIDIOC_QUERYCTRL: { - struct video_picture *pic = arg; - - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - saa7110_write(client, 0x19, decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 127 we get 0-65535 */ - decoder->contrast = pic->contrast; - saa7110_write(client, 0x13, - decoder->contrast >> 9); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 127 we get 0-65535 */ - decoder->sat = pic->colour; - saa7110_write(client, 0x12, decoder->sat >> 9); + struct v4l2_queryctrl *qc = arg; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + case V4L2_CID_CONTRAST: + case V4L2_CID_SATURATION: + case V4L2_CID_HUE: + return v4l2_ctrl_query_fill_std(qc); + default: + return -EINVAL; } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - saa7110_write(client, 0x07, - (decoder->hue >> 8) - 128); + break; + } + + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } break; } - case DECODER_DUMP: - if (!debug) + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + saa7110_write(client, 0x19, decoder->bright); + } break; - for (v = 0; v < SAA7110_NR_REG; v += 16) { - int j; - v4l_dbg(1, debug, client, "%02x:", v); - for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++) - printk(KERN_CONT " %02x", decoder->reg[v + j]); - printk(KERN_CONT "\n"); + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + decoder->contrast = ctrl->value; + saa7110_write(client, 0x13, decoder->contrast); + } + break; + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + saa7110_write(client, 0x12, decoder->sat); + } + break; + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + saa7110_write(client, 0x07, decoder->hue); + } + break; + default: + return -EINVAL; } break; + } default: v4l_dbg(1, debug, client, "unknown command %08x\n", cmd); @@ -430,7 +432,7 @@ static int saa7110_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); if (!decoder) return -ENOMEM; - decoder->norm = VIDEO_MODE_PAL; + decoder->norm = V4L2_STD_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c deleted file mode 100644 index 94e5d0b4e..000000000 --- a/linux/drivers/media/video/saa7111.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * saa7111 - Philips SAA7111A video decoder driver version 0.0.3 - * - * Copyright (C) 1998 Dave Perks - * - * Slight changes for video timing and attachment output by - * Wolfgang Scherr - * - * Changes by Ronald Bultje - * - moved over to linux>=2.4.x i2c protocol (1/1/2003) - * - * Changes by Michael Hunold - * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat.h" - -MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); -MODULE_AUTHOR("Dave Perks"); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -/* ----------------------------------------------------------------------- */ - -#define SAA7111_NR_REG 0x18 - -struct saa7111 { - unsigned char reg[SAA7111_NR_REG]; - - int norm; - int input; - int enable; -}; - -/* ----------------------------------------------------------------------- */ - -static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - decoder->reg[reg] = value; - return i2c_smbus_write_byte_data(client, reg, value); -} - -static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - if (decoder->reg[reg] != value) { - decoder->reg[reg] = value; - i2c_smbus_write_byte_data(client, reg, value); - } -} - -static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len) -{ - int ret = -1; - u8 reg; - - /* the saa7111 has an autoincrement function, use it if - * the adapter understands raw I2C */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - /* do raw I2C, not smbus compatible */ - struct saa7111 *decoder = i2c_get_clientdata(client); - u8 block_data[32]; - int block_len; - - while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; - do { - block_data[block_len++] = - decoder->reg[reg++] = data[1]; - len -= 2; - data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) - break; - } - } else { - /* do some slow I2C emulation kind of thing */ - while (len >= 2) { - reg = *data++; - ret = saa7111_write(client, reg, *data++); - if (ret < 0) - break; - len -= 2; - } - } - - return ret; -} - -static int saa7111_init_decoder(struct i2c_client *client, - struct video_decoder_init *init) -{ - return saa7111_write_block(client, init->data, init->len); -} - -static inline int saa7111_read(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -/* ----------------------------------------------------------------------- */ - -static const unsigned char saa7111_i2c_init[] = { - 0x00, 0x00, /* 00 - ID byte */ - 0x01, 0x00, /* 01 - reserved */ - - /*front end */ - 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */ - 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, - * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ - 0x04, 0x00, /* 04 - GAI1=256 */ - 0x05, 0x00, /* 05 - GAI2=256 */ - - /* decoder */ - 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz) - * pixels after end of last line */ - /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels - * after end of last line */ - 0x07, 0xe8, /* 07 - HSS seems to be needed to - * work with NTSC, too */ - 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, - * VTRC=1, HPLL=0, VNOI=0 */ - 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, - * VBLB=0, UPTCV=0, APER=1 */ - 0x0a, 0x80, /* 0a - BRIG=128 */ - 0x0b, 0x47, /* 0b - CONT=1.109 */ - 0x0c, 0x40, /* 0c - SATN=1.0 */ - 0x0d, 0x00, /* 0d - HUE=0 */ - 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, - * FCTC=0, CHBW=1 */ - 0x0f, 0x00, /* 0f - reserved */ - 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */ - 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, - * OEYC=1, OEHV=1, VIPB=0, COLO=0 */ - 0x12, 0x00, /* 12 - output control 2 */ - 0x13, 0x00, /* 13 - output control 3 */ - 0x14, 0x00, /* 14 - reserved */ - 0x15, 0x00, /* 15 - VBI */ - 0x16, 0x00, /* 16 - VBI */ - 0x17, 0x00, /* 17 - VBI */ -}; - -static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - struct saa7111 *decoder = i2c_get_clientdata(client); - - switch (cmd) { - case 0: - break; - case DECODER_INIT: - { - struct video_decoder_init *init = arg; - struct video_decoder_init vdi; - - if (NULL != init) - return saa7111_init_decoder(client, init); - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - return saa7111_init_decoder(client, &vdi); - } - - case DECODER_DUMP: - { - int i; - - for (i = 0; i < SAA7111_NR_REG; i += 16) { - int j; - - v4l_info(client, "%03x", i); - for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) { - printk(KERN_CONT " %02x", - saa7111_read(client, i + j)); - } - printk(KERN_CONT "\n"); - } - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res; - - status = saa7111_read(client, 0x1f); - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); - res = 0; - if ((status & (1 << 6)) == 0) { - res |= DECODER_STATUS_GOOD; - } - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & (1 << 5)) != 0) { - res |= DECODER_STATUS_NTSC; - } else { - res |= DECODER_STATUS_PAL; - } - break; - } - if ((status & (1 << 0)) != 0) { - res |= DECODER_STATUS_COLOR; - } - *iarg = res; - break; - } - - case DECODER_SET_GPIO: - { - int *iarg = arg; - if (0 != *iarg) { - saa7111_write(client, 0x11, - (decoder->reg[0x11] | 0x80)); - } else { - saa7111_write(client, 0x11, - (decoder->reg[0x11] & 0x7f)); - } - break; - } - - case DECODER_SET_VBI_BYPASS: - { - int *iarg = arg; - if (0 != *iarg) { - saa7111_write(client, 0x13, - (decoder->reg[0x13] & 0xf0) | 0x0a); - } else { - saa7111_write(client, 0x13, - (decoder->reg[0x13] & 0xf0)); - } - break; - } - - case DECODER_SET_NORM: - { - int *iarg = arg; - - switch (*iarg) { - - case VIDEO_MODE_NTSC: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x40); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_PAL: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_SECAM: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f) | 0x50); - break; - - case VIDEO_MODE_AUTO: - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x80); - saa7111_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - default: - return -EINVAL; - - } - decoder->norm = *iarg; - break; - } - - case DECODER_SET_INPUT: - { - int *iarg = arg; - - if (*iarg < 0 || *iarg > 7) { - return -EINVAL; - } - - if (decoder->input != *iarg) { - decoder->input = *iarg; - /* select mode */ - saa7111_write(client, 0x02, - (decoder-> - reg[0x02] & 0xf8) | decoder->input); - /* bypass chrominance trap for modes 4..7 */ - saa7111_write(client, 0x09, - (decoder-> - reg[0x09] & 0x7f) | ((decoder-> - input > - 3) ? 0x80 : - 0)); - } - break; - } - - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - break; - } - - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - int enable = (*iarg != 0); - - if (decoder->enable != enable) { - decoder->enable = enable; - - /* RJ: If output should be disabled (for - * playing videos), we also need a open PLL. - * The input is set to 0 (where no input - * source is connected), although this - * is not necessary. - * - * If output should be enabled, we have to - * reverse the above. - */ - - if (decoder->enable) { - saa7111_write(client, 0x02, - (decoder-> - reg[0x02] & 0xf8) | - decoder->input); - saa7111_write(client, 0x08, - (decoder->reg[0x08] & 0xfb)); - saa7111_write(client, 0x11, - (decoder-> - reg[0x11] & 0xf3) | 0x0c); - } else { - saa7111_write(client, 0x02, - (decoder->reg[0x02] & 0xf8)); - saa7111_write(client, 0x08, - (decoder-> - reg[0x08] & 0xfb) | 0x04); - saa7111_write(client, 0x11, - (decoder->reg[0x11] & 0xf3)); - } - } - break; - } - - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - - /* We want 0 to 255 we get 0-65535 */ - saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8); - /* We want 0 to 127 we get 0-65535 */ - saa7111_write(client, 0x0b, pic->contrast >> 9); - /* We want 0 to 127 we get 0-65535 */ - saa7111_write(client, 0x0c, pic->colour >> 9); - /* We want -128 to 127 we get 0-65535 */ - saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8); - break; - } - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa7111_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int i; - struct saa7111 *decoder; - struct video_decoder_init vdi; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); - return -ENOMEM; - } - decoder->norm = VIDEO_MODE_NTSC; - decoder->input = 0; - decoder->enable = 1; - i2c_set_clientdata(client, decoder); - - vdi.data = saa7111_i2c_init; - vdi.len = sizeof(saa7111_i2c_init); - i = saa7111_init_decoder(client, &vdi); - if (i < 0) { - v4l_dbg(1, debug, client, "init status %d\n", i); - } else { - v4l_dbg(1, debug, client, "revision %x\n", - saa7111_read(client, 0x00) >> 4); - } - return 0; -} - -static int saa7111_remove(struct i2c_client *client) -{ - kfree(i2c_get_clientdata(client)); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -static const struct i2c_device_id saa7111_id[] = { - { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7111_id); - -#endif -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7111", - .driverid = I2C_DRIVERID_SAA7111A, - .command = saa7111_command, - .probe = saa7111_probe, - .remove = saa7111_remove, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) - .id_table = saa7111_id, -#endif -}; diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c deleted file mode 100644 index 6d380e255..000000000 --- a/linux/drivers/media/video/saa7114.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* - * saa7114 - Philips SAA7114H video decoder driver version 0.0.1 - * - * Copyright (C) 2002 Maxim Yevtyushkin - * - * Based on saa7111 driver by Dave Perks - * - * Copyright (C) 1998 Dave Perks - * - * Slight changes for video timing and attachment output by - * Wolfgang Scherr - * - * Changes by Ronald Bultje - * - moved over to linux>=2.4.x i2c protocol (1/1/2003) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat.h" - -MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); -MODULE_AUTHOR("Maxim Yevtyushkin"); -MODULE_LICENSE("GPL"); - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0-1)"); - -/* ----------------------------------------------------------------------- */ - -struct saa7114 { - unsigned char reg[0xf0 * 2]; - - int norm; - int input; - int enable; - int bright; - int contrast; - int hue; - int sat; - int playback; -}; - -#define I2C_DELAY 10 - - -//#define SAA_7114_NTSC_HSYNC_START (-3) -//#define SAA_7114_NTSC_HSYNC_STOP (-18) - -#define SAA_7114_NTSC_HSYNC_START (-17) -#define SAA_7114_NTSC_HSYNC_STOP (-32) - -//#define SAA_7114_NTSC_HOFFSET (5) -#define SAA_7114_NTSC_HOFFSET (6) -#define SAA_7114_NTSC_VOFFSET (10) -#define SAA_7114_NTSC_WIDTH (720) -#define SAA_7114_NTSC_HEIGHT (250) - -#define SAA_7114_SECAM_HSYNC_START (-17) -#define SAA_7114_SECAM_HSYNC_STOP (-32) - -#define SAA_7114_SECAM_HOFFSET (2) -#define SAA_7114_SECAM_VOFFSET (10) -#define SAA_7114_SECAM_WIDTH (720) -#define SAA_7114_SECAM_HEIGHT (300) - -#define SAA_7114_PAL_HSYNC_START (-17) -#define SAA_7114_PAL_HSYNC_STOP (-32) - -#define SAA_7114_PAL_HOFFSET (2) -#define SAA_7114_PAL_VOFFSET (10) -#define SAA_7114_PAL_WIDTH (720) -#define SAA_7114_PAL_HEIGHT (300) - - - -#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040 -#define SAA_7114_VERTICAL_LUMA_OFFSET 0 - -#define REG_ADDR(x) (((x) << 1) + 1) -#define LOBYTE(x) ((unsigned char)((x) & 0xff)) -#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff)) -#define LOWORD(x) ((unsigned short int)((x) & 0xffff)) -#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff)) - - -/* ----------------------------------------------------------------------- */ - -static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value) -{ - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len) -{ - int ret = -1; - u8 reg; - - /* the saa7114 has an autoincrement function, use it if - * the adapter understands raw I2C */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - /* do raw I2C, not smbus compatible */ - u8 block_data[32]; - int block_len; - - while (len >= 2) { - block_len = 0; - block_data[block_len++] = reg = data[0]; - do { - block_data[block_len++] = data[1]; - reg++; - len -= 2; - data += 2; - } while (len >= 2 && data[0] == reg && block_len < 32); - ret = i2c_master_send(client, block_data, block_len); - if (ret < 0) - break; - } - } else { - /* do some slow I2C emulation kind of thing */ - while (len >= 2) { - reg = *data++; - ret = saa7114_write(client, reg, *data++); - if (ret < 0) - break; - len -= 2; - } - } - - return ret; -} - -static inline int saa7114_read(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -/* ----------------------------------------------------------------------- */ - -// initially set NTSC, composite - - -static const unsigned char init[] = { - 0x00, 0x00, /* 00 - ID byte , chip version, - * read only */ - 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 - - * horizontal increment delay, - * recommended position */ - 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ; - * input control */ - 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, - * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ - 0x04, 0x90, /* 04 - GAI1=256 */ - 0x05, 0x90, /* 05 - GAI2=256 */ - 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start, - * depends on the video standard */ - 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends - *on the video standard */ - 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, - * HPLL: free running in playback, locked - * in capture, VNOI=0 */ - 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, - * UPTCV=0, APER=1; depends from input */ - 0x0a, 0x80, /* 0a - BRIG=128 */ - 0x0b, 0x44, /* 0b - CONT=1.109 */ - 0x0c, 0x40, /* 0c - SATN=1.0 */ - 0x0d, 0x00, /* 0d - HUE=0 */ - 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC, - * CCOMB; depends from video standard */ - 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends - * from video standard */ - 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW, - * LCBW2 to 0 */ - 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0, - * YDEL2 to 0 */ - 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10 - * and 03 to 00 */ - 0x13, 0x80, /* 13 - RT/X port output control */ - 0x14, 0x00, /* 14 - analog, ADC, compatibility control */ - 0x15, 0x00, /* 15 - VGATE start FID change */ - 0x16, 0xfe, /* 16 - VGATE stop */ - 0x17, 0x00, /* 17 - Misc., VGATE MSBs */ - 0x18, 0x40, /* RAWG */ - 0x19, 0x80, /* RAWO */ - 0x1a, 0x00, - 0x1b, 0x00, - 0x1c, 0x00, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x00, /* status byte, read only */ - 0x20, 0x00, /* video decoder reserved part */ - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x00, - 0x25, 0x00, - 0x26, 0x00, - 0x27, 0x00, - 0x28, 0x00, - 0x29, 0x00, - 0x2a, 0x00, - 0x2b, 0x00, - 0x2c, 0x00, - 0x2d, 0x00, - 0x2e, 0x00, - 0x2f, 0x00, - 0x30, 0xbc, /* audio clock generator */ - 0x31, 0xdf, - 0x32, 0x02, - 0x33, 0x00, - 0x34, 0xcd, - 0x35, 0xcc, - 0x36, 0x3a, - 0x37, 0x00, - 0x38, 0x03, - 0x39, 0x10, - 0x3a, 0x00, - 0x3b, 0x00, - 0x3c, 0x00, - 0x3d, 0x00, - 0x3e, 0x00, - 0x3f, 0x00, - 0x40, 0x00, /* VBI data slicer */ - 0x41, 0xff, - 0x42, 0xff, - 0x43, 0xff, - 0x44, 0xff, - 0x45, 0xff, - 0x46, 0xff, - 0x47, 0xff, - 0x48, 0xff, - 0x49, 0xff, - 0x4a, 0xff, - 0x4b, 0xff, - 0x4c, 0xff, - 0x4d, 0xff, - 0x4e, 0xff, - 0x4f, 0xff, - 0x50, 0xff, - 0x51, 0xff, - 0x52, 0xff, - 0x53, 0xff, - 0x54, 0xff, - 0x55, 0xff, - 0x56, 0xff, - 0x57, 0xff, - 0x58, 0x40, // framing code - 0x59, 0x47, // horizontal offset - 0x5a, 0x06, // vertical offset - 0x5b, 0x83, // field offset - 0x5c, 0x00, // reserved - 0x5d, 0x3e, // header and data - 0x5e, 0x00, // sliced data - 0x5f, 0x00, // reserved - 0x60, 0x00, /* video decoder reserved part */ - 0x61, 0x00, - 0x62, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x00, - 0x6b, 0x00, - 0x6c, 0x00, - 0x6d, 0x00, - 0x6e, 0x00, - 0x6f, 0x00, - 0x70, 0x00, /* video decoder reserved part */ - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x00, - 0x75, 0x00, - 0x76, 0x00, - 0x77, 0x00, - 0x78, 0x00, - 0x79, 0x00, - 0x7a, 0x00, - 0x7b, 0x00, - 0x7c, 0x00, - 0x7d, 0x00, - 0x7e, 0x00, - 0x7f, 0x00, - 0x80, 0x00, /* X-port, I-port and scaler */ - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0xc5, - 0x85, 0x0d, // hsync and vsync ? - 0x86, 0x40, - 0x87, 0x01, - 0x88, 0x00, - 0x89, 0x00, - 0x8a, 0x00, - 0x8b, 0x00, - 0x8c, 0x00, - 0x8d, 0x00, - 0x8e, 0x00, - 0x8f, 0x00, - 0x90, 0x03, /* Task A definition */ - 0x91, 0x08, - 0x92, 0x00, - 0x93, 0x40, - 0x94, 0x00, // window settings - 0x95, 0x00, - 0x96, 0x00, - 0x97, 0x00, - 0x98, 0x00, - 0x99, 0x00, - 0x9a, 0x00, - 0x9b, 0x00, - 0x9c, 0x00, - 0x9d, 0x00, - 0x9e, 0x00, - 0x9f, 0x00, - 0xa0, 0x01, /* horizontal integer prescaling ratio */ - 0xa1, 0x00, /* horizontal prescaler accumulation - * sequence length */ - 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler - * DC gain */ - 0xa3, 0x00, - 0xa4, 0x80, // luminance brightness - 0xa5, 0x40, // luminance gain - 0xa6, 0x40, // chrominance saturation - 0xa7, 0x00, - 0xa8, 0x00, // horizontal luminance scaling increment - 0xa9, 0x04, - 0xaa, 0x00, // horizontal luminance phase offset - 0xab, 0x00, - 0xac, 0x00, // horizontal chrominance scaling increment - 0xad, 0x02, - 0xae, 0x00, // horizontal chrominance phase offset - 0xaf, 0x00, - 0xb0, 0x00, // vertical luminance scaling increment - 0xb1, 0x04, - 0xb2, 0x00, // vertical chrominance scaling increment - 0xb3, 0x04, - 0xb4, 0x00, - 0xb5, 0x00, - 0xb6, 0x00, - 0xb7, 0x00, - 0xb8, 0x00, - 0xb9, 0x00, - 0xba, 0x00, - 0xbb, 0x00, - 0xbc, 0x00, - 0xbd, 0x00, - 0xbe, 0x00, - 0xbf, 0x00, - 0xc0, 0x02, // Task B definition - 0xc1, 0x08, - 0xc2, 0x00, - 0xc3, 0x40, - 0xc4, 0x00, // window settings - 0xc5, 0x00, - 0xc6, 0x00, - 0xc7, 0x00, - 0xc8, 0x00, - 0xc9, 0x00, - 0xca, 0x00, - 0xcb, 0x00, - 0xcc, 0x00, - 0xcd, 0x00, - 0xce, 0x00, - 0xcf, 0x00, - 0xd0, 0x01, // horizontal integer prescaling ratio - 0xd1, 0x00, // horizontal prescaler accumulation sequence length - 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain - 0xd3, 0x00, - 0xd4, 0x80, // luminance brightness - 0xd5, 0x40, // luminance gain - 0xd6, 0x40, // chrominance saturation - 0xd7, 0x00, - 0xd8, 0x00, // horizontal luminance scaling increment - 0xd9, 0x04, - 0xda, 0x00, // horizontal luminance phase offset - 0xdb, 0x00, - 0xdc, 0x00, // horizontal chrominance scaling increment - 0xdd, 0x02, - 0xde, 0x00, // horizontal chrominance phase offset - 0xdf, 0x00, - 0xe0, 0x00, // vertical luminance scaling increment - 0xe1, 0x04, - 0xe2, 0x00, // vertical chrominance scaling increment - 0xe3, 0x04, - 0xe4, 0x00, - 0xe5, 0x00, - 0xe6, 0x00, - 0xe7, 0x00, - 0xe8, 0x00, - 0xe9, 0x00, - 0xea, 0x00, - 0xeb, 0x00, - 0xec, 0x00, - 0xed, 0x00, - 0xee, 0x00, - 0xef, 0x00 -}; - -static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - struct saa7114 *decoder = i2c_get_clientdata(client); - - switch (cmd) { - case 0: - //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client)); - //saa7114_write_block(client, init, sizeof(init)); - break; - - case DECODER_DUMP: - { - int i; - - if (!debug) - break; - v4l_info(client, "decoder dump\n"); - - for (i = 0; i < 32; i += 16) { - int j; - - v4l_info(client, "%03x", i); - for (j = 0; j < 16; ++j) { - printk(KERN_CONT " %02x", - saa7114_read(client, i + j)); - } - printk(KERN_CONT "\n"); - } - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "get capabilities\n"); - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res; - - status = saa7114_read(client, 0x1f); - - v4l_dbg(1, debug, client, "status: 0x%02x\n", status); - res = 0; - if ((status & (1 << 6)) == 0) { - res |= DECODER_STATUS_GOOD; - } - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & (1 << 5)) != 0) { - res |= DECODER_STATUS_NTSC; - } else { - res |= DECODER_STATUS_PAL; - } - break; - } - if ((status & (1 << 0)) != 0) { - res |= DECODER_STATUS_COLOR; - } - *iarg = res; - break; - } - - case DECODER_SET_NORM: - { - int *iarg = arg; - - short int hoff = 0, voff = 0, w = 0, h = 0; - - v4l_dbg(1, debug, client, "set norm\n"); - - switch (*iarg) { - case VIDEO_MODE_NTSC: - v4l_dbg(1, debug, client, "NTSC\n"); - decoder->reg[REG_ADDR(0x06)] = - SAA_7114_NTSC_HSYNC_START; - decoder->reg[REG_ADDR(0x07)] = - SAA_7114_NTSC_HSYNC_STOP; - - decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture - - decoder->reg[REG_ADDR(0x0e)] = 0x85; - decoder->reg[REG_ADDR(0x0f)] = 0x24; - - hoff = SAA_7114_NTSC_HOFFSET; - voff = SAA_7114_NTSC_VOFFSET; - w = SAA_7114_NTSC_WIDTH; - h = SAA_7114_NTSC_HEIGHT; - - break; - - case VIDEO_MODE_PAL: - v4l_dbg(1, debug, client, "PAL\n"); - decoder->reg[REG_ADDR(0x06)] = - SAA_7114_PAL_HSYNC_START; - decoder->reg[REG_ADDR(0x07)] = - SAA_7114_PAL_HSYNC_STOP; - - decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture - - decoder->reg[REG_ADDR(0x0e)] = 0x81; - decoder->reg[REG_ADDR(0x0f)] = 0x24; - - hoff = SAA_7114_PAL_HOFFSET; - voff = SAA_7114_PAL_VOFFSET; - w = SAA_7114_PAL_WIDTH; - h = SAA_7114_PAL_HEIGHT; - - break; - - default: - v4l_dbg(1, debug, client, "Unknown video mode\n"); - return -EINVAL; - } - - - decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high - - - saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - - saa7114_write_block(client, decoder->reg + (0x06 << 1), - 3 << 1); - saa7114_write_block(client, decoder->reg + (0x0e << 1), - 2 << 1); - saa7114_write_block(client, decoder->reg + (0x5a << 1), - 2 << 1); - - saa7114_write_block(client, decoder->reg + (0x94 << 1), - (0x9f + 1 - 0x94) << 1); - saa7114_write_block(client, decoder->reg + (0xc4 << 1), - (0xcf + 1 - 0xc4) << 1); - - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection - - decoder->norm = *iarg; - break; - } - - case DECODER_SET_INPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set input (%d)\n", *iarg); - if (*iarg < 0 || *iarg > 7) { - return -EINVAL; - } - - if (decoder->input != *iarg) { - v4l_dbg(1, debug, client, "now setting %s input\n", - *iarg >= 6 ? "S-Video" : "Composite"); - decoder->input = *iarg; - - /* select mode */ - decoder->reg[REG_ADDR(0x02)] = - (decoder-> - reg[REG_ADDR(0x02)] & 0xf0) | (decoder-> - input < - 6 ? 0x0 : 0x9); - saa7114_write(client, 0x02, - decoder->reg[REG_ADDR(0x02)]); - - /* bypass chrominance trap for modes 6..9 */ - decoder->reg[REG_ADDR(0x09)] = - (decoder-> - reg[REG_ADDR(0x09)] & 0x7f) | (decoder-> - input < - 6 ? 0x0 : - 0x80); - saa7114_write(client, 0x09, - decoder->reg[REG_ADDR(0x09)]); - - decoder->reg[REG_ADDR(0x0e)] = - decoder->input < - 6 ? decoder-> - reg[REG_ADDR(0x0e)] | 1 : decoder-> - reg[REG_ADDR(0x0e)] & ~1; - saa7114_write(client, 0x0e, - decoder->reg[REG_ADDR(0x0e)]); - } - break; - } - - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - v4l_dbg(1, debug, client, "set output\n"); - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - break; - } - - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - int enable = (*iarg != 0); - - v4l_dbg(1, debug, client, "%s output\n", - enable ? "enable" : "disable"); - - decoder->playback = !enable; - - if (decoder->enable != enable) { - decoder->enable = enable; - - /* RJ: If output should be disabled (for - * playing videos), we also need a open PLL. - * The input is set to 0 (where no input - * source is connected), although this - * is not necessary. - * - * If output should be enabled, we have to - * reverse the above. - */ - - if (decoder->enable) { - decoder->reg[REG_ADDR(0x08)] = 0xb8; - decoder->reg[REG_ADDR(0x12)] = 0xc9; - decoder->reg[REG_ADDR(0x13)] = 0x80; - decoder->reg[REG_ADDR(0x87)] = 0x01; - } else { - decoder->reg[REG_ADDR(0x08)] = 0x7c; - decoder->reg[REG_ADDR(0x12)] = 0x00; - decoder->reg[REG_ADDR(0x13)] = 0x00; - decoder->reg[REG_ADDR(0x87)] = 0x00; - } - - saa7114_write_block(client, - decoder->reg + (0x12 << 1), - 2 << 1); - saa7114_write(client, 0x08, - decoder->reg[REG_ADDR(0x08)]); - saa7114_write(client, 0x87, - decoder->reg[REG_ADDR(0x87)]); - saa7114_write(client, 0x88, 0xd8); // sw reset scaler - saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - saa7114_write(client, 0x80, 0x36); - - } - break; - } - - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - - v4l_dbg(1, debug, client, - "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n", - pic->brightness, pic->contrast, pic->colour, pic->hue); - - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - saa7114_write(client, 0x0a, decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 127 we get 0-65535 */ - decoder->contrast = pic->contrast; - saa7114_write(client, 0x0b, - decoder->contrast >> 9); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 127 we get 0-65535 */ - decoder->sat = pic->colour; - saa7114_write(client, 0x0c, decoder->sat >> 9); - } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - saa7114_write(client, 0x0d, - (decoder->hue - 32768) >> 8); - } - break; - } - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; - -I2C_CLIENT_INSMOD; - -static int saa7114_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int i, err[30]; - short int hoff = SAA_7114_NTSC_HOFFSET; - short int voff = SAA_7114_NTSC_VOFFSET; - short int w = SAA_7114_NTSC_WIDTH; - short int h = SAA_7114_NTSC_HEIGHT; - struct saa7114 *decoder; - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -ENODEV; - - v4l_info(client, "chip found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - - decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL); - if (decoder == NULL) - return -ENOMEM; - decoder->norm = VIDEO_MODE_NTSC; - decoder->input = -1; - decoder->enable = 1; - decoder->bright = 32768; - decoder->contrast = 32768; - decoder->hue = 32768; - decoder->sat = 32768; - decoder->playback = 0; // initially capture mode useda - i2c_set_clientdata(client, decoder); - - memcpy(decoder->reg, init, sizeof(init)); - - decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low - decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high - decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low - decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high - decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low - decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high - decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low - decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high - decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low - decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high - decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low - decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high - - decoder->reg[REG_ADDR(0xb8)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xb9)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xba)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xbb)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - - decoder->reg[REG_ADDR(0xbc)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbd)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbe)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xbf)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - - decoder->reg[REG_ADDR(0xe8)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xe9)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xea)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - decoder->reg[REG_ADDR(0xeb)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET)); - - decoder->reg[REG_ADDR(0xec)] = - LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xed)] = - HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xee)] = - LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - decoder->reg[REG_ADDR(0xef)] = - HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET)); - - - decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on - decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port - decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0 - - decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy - decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap - decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on - - - v4l_dbg(1, debug, client, "starting init\n"); - - err[0] = - saa7114_write_block(client, decoder->reg + (0x20 << 1), - 0x10 << 1); - err[1] = - saa7114_write_block(client, decoder->reg + (0x30 << 1), - 0x10 << 1); - err[2] = - saa7114_write_block(client, decoder->reg + (0x63 << 1), - (0x7f + 1 - 0x63) << 1); - err[3] = - saa7114_write_block(client, decoder->reg + (0x89 << 1), - 6 << 1); - err[4] = - saa7114_write_block(client, decoder->reg + (0xb8 << 1), - 8 << 1); - err[5] = - saa7114_write_block(client, decoder->reg + (0xe8 << 1), - 8 << 1); - - - for (i = 0; i <= 5; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - v4l_dbg(1, debug, client, - "performing decoder reset sequence\n"); - - err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off - err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler - err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - - for (i = 6; i <= 8; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - v4l_dbg(1, debug, client, "performing the rest of init\n"); - - err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]); - err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq - err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer - err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ? - err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ? - err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A - err[15] = - saa7114_write_block(client, decoder->reg + (0x94 << 1), - 12 << 1); - err[16] = - saa7114_write_block(client, decoder->reg + (0xa0 << 1), - 8 << 1); - err[17] = - saa7114_write_block(client, decoder->reg + (0xa8 << 1), - 8 << 1); - err[18] = - saa7114_write_block(client, decoder->reg + (0xb0 << 1), - 8 << 1); - err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B - err[15] = - saa7114_write_block(client, decoder->reg + (0xc4 << 1), - 12 << 1); - err[16] = - saa7114_write_block(client, decoder->reg + (0xd0 << 1), - 8 << 1); - err[17] = - saa7114_write_block(client, decoder->reg + (0xd8 << 1), - 8 << 1); - err[18] = - saa7114_write_block(client, decoder->reg + (0xe0 << 1), - 8 << 1); - - for (i = 9; i <= 18; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - - for (i = 6; i < 8; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - - for (i = 0x11; i <= 0x13; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - - v4l_dbg(1, debug, client, "setting video input\n"); - - err[19] = - saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]); - err[20] = - saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]); - err[21] = - saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]); - - for (i = 19; i <= 21; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - v4l_dbg(1, debug, client, "performing decoder reset sequence\n"); - - err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler - err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release - err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off - - - for (i = 22; i <= 24; i++) { - if (err[i] < 0) { - v4l_dbg(1, debug, client, - "init error %d at stage %d, leaving attach.\n", - i, err[i]); - kfree(decoder); - return -EIO; - } - } - - err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]); - err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]); - err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]); - - v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n", - saa7114_read(client, 0x00) >> 4, - saa7114_read(client, 0x1f)); - v4l_dbg(1, debug, client, - "power save control: 0x%02x, scaler status: 0x%02x\n", - saa7114_read(client, 0x88), - saa7114_read(client, 0x8f)); - - - for (i = 0x94; i < 0x96; i++) { - v4l_dbg(1, debug, client, - "reg[0x%02x] = 0x%02x (0x%02x)\n", - i, saa7114_read(client, i), - decoder->reg[REG_ADDR(i)]); - } - - //i = saa7114_write_block(client, init, sizeof(init)); - return 0; -} - -static int saa7114_remove(struct i2c_client *client) -{ - kfree(i2c_get_clientdata(client)); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -static const struct i2c_device_id saa7114_id[] = { - { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */ - { } -}; -MODULE_DEVICE_TABLE(i2c, saa7114_id); - -#endif -static struct v4l2_i2c_driver_data v4l2_i2c_data = { - .name = "saa7114", - .driverid = I2C_DRIVERID_SAA7114, - .command = saa7114_command, - .probe = saa7114_probe, - .remove = saa7114_remove, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) - .id_table = saa7114_id, -#endif -}; diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 68bec4d5d..08cc04138 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -50,8 +50,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct saa7185 { unsigned char reg[128]; - int norm; - int enable; + v4l2_std_id norm; int bright; int contrast; int hue; @@ -219,68 +218,43 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) struct saa7185 *encoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: saa7185_write_block(client, init_common, sizeof(init_common)); - switch (encoder->norm) { - - case VIDEO_MODE_NTSC: + if (encoder->norm & V4L2_STD_NTSC) saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); - break; - - case VIDEO_MODE_PAL: + else saa7185_write_block(client, init_pal, sizeof(init_pal)); - break; - } - break; - - case ENCODER_GET_CAPABILITIES: - { - struct video_encoder_capability *cap = arg; - - cap->flags = - VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC | - VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR; - cap->inputs = 1; - cap->outputs = 1; break; - } - case ENCODER_SET_NORM: + case VIDIOC_INT_S_STD_OUTPUT: { - int *iarg = arg; + v4l2_std_id *iarg = arg; //saa7185_write_block(client, init_common, sizeof(init_common)); - switch (*iarg) { - case VIDEO_MODE_NTSC: + if (*iarg & V4L2_STD_NTSC) saa7185_write_block(client, init_ntsc, sizeof(init_ntsc)); - break; - - case VIDEO_MODE_PAL: + else if (*iarg & V4L2_STD_PAL) saa7185_write_block(client, init_pal, sizeof(init_pal)); - break; - - case VIDEO_MODE_SECAM: - default: + else return -EINVAL; - } encoder->norm = *iarg; break; } - case ENCODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg; + struct v4l2_routing *route = arg; - /* RJ: *iarg = 0: input is from SA7111 - *iarg = 1: input is from ZR36060 */ + /* RJ: route->input = 0: input is from SA7111 + route->input = 1: input is from ZR36060 */ - switch (*iarg) { + switch (route->input) { case 0: /* turn off colorbar */ saa7185_write(client, 0x3a, 0x0f); @@ -316,27 +290,6 @@ static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case ENCODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) - return -EINVAL; - break; - } - - case ENCODER_ENABLE_OUTPUT: - { - int *iarg = arg; - - encoder->enable = !!*iarg; - saa7185_write(client, 0x61, - (encoder->reg[0x61] & 0xbf) | - (encoder->enable ? 0x00 : 0x40)); - break; - } - default: return -EINVAL; } @@ -366,8 +319,7 @@ static int saa7185_probe(struct i2c_client *client, encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - encoder->norm = VIDEO_MODE_NTSC; - encoder->enable = 1; + encoder->norm = V4L2_STD_NTSC; i2c_set_clientdata(client, encoder); i = saa7185_write_block(client, init_common, sizeof(init_common)); diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c index 5f368a1be..2487f8fe2 100644 --- a/linux/drivers/media/video/vpx3220.c +++ b/linux/drivers/media/video/vpx3220.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "compat.h" @@ -45,7 +46,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); struct vpx3220 { unsigned char reg[255]; - int norm; + v4l2_std_id norm; int input; int enable; int bright; @@ -260,6 +261,7 @@ static const unsigned short init_fp[] = { 0x4b, 0x298, /* PLL gain */ }; +#if 0 static void vpx3220_dump_i2c(struct i2c_client *client) { int len = sizeof(init_common); @@ -272,67 +274,42 @@ static void vpx3220_dump_i2c(struct i2c_client *client) len -= 2; } } +#endif static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) { struct vpx3220 *decoder = i2c_get_clientdata(client); switch (cmd) { - case 0: + case VIDIOC_INT_INIT: { vpx3220_write_block(client, init_common, sizeof(init_common)); vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1); - switch (decoder->norm) { - case VIDEO_MODE_NTSC: + if (decoder->norm & V4L2_STD_NTSC) { vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); - break; - - case VIDEO_MODE_PAL: + } else if (decoder->norm & V4L2_STD_PAL) { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - break; - case VIDEO_MODE_SECAM: + } else if (decoder->norm & V4L2_STD_SECAM) { vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); - break; - default: + } else { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); - break; } break; } - case DECODER_DUMP: - { - vpx3220_dump_i2c(client); - break; - } - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n"); - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 3; - cap->outputs = 1; - break; - } - - case DECODER_GET_STATUS: + case VIDIOC_QUERYSTD: + case VIDIOC_INT_G_INPUT_STATUS: { - int res = 0, status; + int res = V4L2_IN_ST_NO_SIGNAL, status; + v4l2_std_id std = 0; - v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n"); + v4l_dbg(1, debug, client, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n"); status = vpx3220_fp_read(client, 0x0f3); @@ -342,35 +319,38 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) return status; if ((status & 0x20) == 0) { - res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR; + res = 0; switch (status & 0x18) { case 0x00: case 0x10: case 0x14: case 0x18: - res |= DECODER_STATUS_PAL; + std = V4L2_STD_PAL; break; case 0x08: - res |= DECODER_STATUS_SECAM; + std = V4L2_STD_SECAM; break; case 0x04: case 0x0c: case 0x1c: - res |= DECODER_STATUS_NTSC; + std = V4L2_STD_NTSC; break; } } - *(int *) arg = res; + if (cmd == VIDIOC_QUERYSTD) + *(v4l2_std_id *)arg = std; + else + *(int *)arg = res; break; } - case DECODER_SET_NORM: + case VIDIOC_S_STD: { - int *iarg = arg, data; + v4l2_std_id *iarg = arg; int temp_input; /* Here we back up the input selection because it gets @@ -378,36 +358,31 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) choosen video norm */ temp_input = vpx3220_fp_read(client, 0xf2); - v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg); - switch (*iarg) { - case VIDEO_MODE_NTSC: + v4l_dbg(1, debug, client, "VIDIOC_S_STD %llx\n", *iarg); + if (*iarg & V4L2_STD_NTSC) { vpx3220_write_fp_block(client, init_ntsc, sizeof(init_ntsc) >> 1); v4l_dbg(1, debug, client, "norm switched to NTSC\n"); - break; - - case VIDEO_MODE_PAL: + } else if (*iarg & V4L2_STD_PAL) { vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1); v4l_dbg(1, debug, client, "norm switched to PAL\n"); - break; - - case VIDEO_MODE_SECAM: + } else if (*iarg & V4L2_STD_SECAM) { vpx3220_write_fp_block(client, init_secam, sizeof(init_secam) >> 1); v4l_dbg(1, debug, client, "norm switched to SECAM\n"); - break; + } else { + return -EINVAL; + } +#if 0 case VIDEO_MODE_AUTO: /* FIXME This is only preliminary support */ data = vpx3220_fp_read(client, 0xf2) & 0x20; vpx3220_fp_write(client, 0xf2, 0x00c0 | data); v4l_dbg(1, debug, client, "norm switched to AUTO\n"); break; - - default: - return -EINVAL; - } +#endif decoder->norm = *iarg; /* And here we set the backed up video input again */ @@ -416,9 +391,10 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) break; } - case DECODER_SET_INPUT: + case VIDIOC_INT_S_VIDEO_ROUTING: { - int *iarg = arg, data; + struct v4l2_routing *route = arg; + int data; /* RJ: *iarg = 0: ST8 (PCTV) input *iarg = 1: COMPOSITE input @@ -430,73 +406,117 @@ static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg) {0x0e, 1} }; - if (*iarg < 0 || *iarg > 2) + if (route->input < 0 || route->input > 2) return -EINVAL; - v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]); + v4l_dbg(1, debug, client, "input switched to %s\n", inputs[route->input]); - vpx3220_write(client, 0x33, input[*iarg][0]); + vpx3220_write(client, 0x33, input[route->input][0]); data = vpx3220_fp_read(client, 0xf2) & ~(0x0020); if (data < 0) return data; /* 0x0010 is required to latch the setting */ vpx3220_fp_write(client, 0xf2, - data | (input[*iarg][1] << 5) | 0x0010); + data | (input[route->input][1] << 5) | 0x0010); udelay(10); break; } - case DECODER_SET_OUTPUT: + case VIDIOC_STREAMON: + case VIDIOC_STREAMOFF: { - int *iarg = arg; + int on = cmd == VIDIOC_STREAMON; + v4l_dbg(1, debug, client, "VIDIOC_STREAM%s\n", on ? "ON" : "OFF"); - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } + vpx3220_write(client, 0xf2, (on ? 0x1b : 0x00)); break; } - case DECODER_ENABLE_OUTPUT: + case VIDIOC_QUERYCTRL: { - int *iarg = arg; + struct v4l2_queryctrl *qc = arg; + + switch (qc->id) { + case V4L2_CID_BRIGHTNESS: + v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); + break; + + case V4L2_CID_CONTRAST: + v4l2_ctrl_query_fill(qc, 0, 63, 1, 32); + break; + + case V4L2_CID_SATURATION: + v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048); + break; - v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg); + case V4L2_CID_HUE: + v4l2_ctrl_query_fill(qc, -512, 511, 1, 0); + break; - vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00)); + default: + return -EINVAL; + } break; } - case DECODER_SET_PICTURE: + case VIDIOC_G_CTRL: { - struct video_picture *pic = arg; + struct v4l2_control *ctrl = arg; - if (decoder->bright != pic->brightness) { - /* We want -128 to 128 we get 0-65535 */ - decoder->bright = pic->brightness; - vpx3220_write(client, 0xe6, - (decoder->bright - 32768) >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 64 we get 0-65535 */ - /* Bit 7 and 8 is for noise shaping */ - decoder->contrast = pic->contrast; - vpx3220_write(client, 0xe7, - (decoder->contrast >> 10) + 192); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 4096 we get 0-65535 */ - decoder->sat = pic->colour; - vpx3220_fp_write(client, 0xa0, - decoder->sat >> 4); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = decoder->bright; + break; + case V4L2_CID_CONTRAST: + ctrl->value = decoder->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = decoder->sat; + break; + case V4L2_CID_HUE: + ctrl->value = decoder->hue; + break; + default: + return -EINVAL; } - if (decoder->hue != pic->hue) { - /* We want -512 to 512 we get 0-65535 */ - decoder->hue = pic->hue; - vpx3220_fp_write(client, 0x1c, - ((decoder->hue - 32768) >> 6) & 0xFFF); + break; + } + + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (decoder->bright != ctrl->value) { + decoder->bright = ctrl->value; + vpx3220_write(client, 0xe6, decoder->bright); + } + break; + case V4L2_CID_CONTRAST: + if (decoder->contrast != ctrl->value) { + /* Bit 7 and 8 is for noise shaping */ + decoder->contrast = ctrl->value; + vpx3220_write(client, 0xe7, + decoder->contrast + 192); + } + break; + case V4L2_CID_SATURATION: + if (decoder->sat != ctrl->value) { + decoder->sat = ctrl->value; + vpx3220_fp_write(client, 0xa0, decoder->sat); + } + break; + case V4L2_CID_HUE: + if (decoder->hue != ctrl->value) { + decoder->hue = ctrl->value; + vpx3220_fp_write(client, 0x1c, decoder->hue); + } + break; + default: + return -EINVAL; } break; } @@ -542,7 +562,7 @@ static int vpx3220_probe(struct i2c_client *client, decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL); if (decoder == NULL) return -ENOMEM; - decoder->norm = VIDEO_MODE_PAL; + decoder->norm = V4L2_STD_PAL; decoder->input = 0; decoder->enable = 1; decoder->bright = 32768; diff --git a/linux/drivers/media/video/zoran/Kconfig b/linux/drivers/media/video/zoran/Kconfig index a0fe52260..925fb5159 100644 --- a/linux/drivers/media/video/zoran/Kconfig +++ b/linux/drivers/media/video/zoran/Kconfig @@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060 config VIDEO_ZORAN_BUZ tristate "Iomega Buz support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO help Support for the Iomega Buz MJPEG capture/playback card. @@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33 config VIDEO_ZORAN_LML33R10 tristate "Linux Media Labs LML33R10 support" depends on VIDEO_ZORAN_ZR36060 - select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO help support for the Linux Media Labs LML33R10 MJPEG capture/playback diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index 76668bda0..ee31bfc34 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -352,7 +352,7 @@ struct card_info { char name[32]; } input[BUZ_MAX_INPUT]; - int norms; + v4l2_std_id norms; struct tvnorm *tvn[3]; /* supported TV norms */ u32 jpeg_int; /* JPEG interrupt */ @@ -401,8 +401,8 @@ struct zoran { spinlock_t spinlock; /* Spinlock */ /* Video for Linux parameters */ - int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */ - int hue, saturation, contrast, brightness; /* Current picture params */ + int input; /* card's norm and input - norm=VIDEO_MODE_* */ + v4l2_std_id norm; struct video_buffer buffer; /* Current buffer params */ struct zoran_overlay_settings overlay_settings; u32 *overlay_mask; /* overlay mask */ diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 552204bab..17c3aaffd 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -341,11 +341,8 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_SAA7110: name = "saa7110"; break; - case I2C_DRIVERID_SAA7111A: - name = "saa7111"; - break; - case I2C_DRIVERID_SAA7114: - name = "saa7114"; + case I2C_DRIVERID_SAA711X: + name = "saa7115"; break; case I2C_DRIVERID_SAA7185B: name = "saa7185"; @@ -440,7 +437,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -468,7 +465,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -495,7 +492,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 7, "S-Video" }, { 5, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel, &f60sqpixel, @@ -524,7 +521,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -553,7 +550,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 2, "S-Video" }, { 0, "Internal/comp" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50sqpixel_dc10, &f60sqpixel_dc10, @@ -580,7 +577,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lml33, &f60ccir601_lml33, @@ -598,7 +595,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = LML33R10, .name = "LML33R10", - .i2c_decoder = I2C_DRIVERID_SAA7114, + .i2c_decoder = I2C_DRIVERID_SAA711X, .i2c_encoder = I2C_DRIVERID_ADV7170, .video_codec = CODEC_TYPE_ZR36060, @@ -607,7 +604,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 0, "Composite" }, { 7, "S-Video" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_lm33r10, &f60ccir601_lm33r10, @@ -625,7 +622,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { }, { .type = BUZ, .name = "Buz", - .i2c_decoder = I2C_DRIVERID_SAA7111A, + .i2c_decoder = I2C_DRIVERID_SAA711X, .i2c_encoder = I2C_DRIVERID_SAA7185B, .video_codec = CODEC_TYPE_ZR36060, @@ -634,7 +631,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { { 3, "Composite" }, { 7, "S-Video" } }, - .norms = 3, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, .tvn = { &f50ccir601, &f60ccir601, @@ -671,7 +668,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { {10, "S-Video 3" }, {15, "YCbCr" } }, - .norms = 2, + .norms = V4L2_STD_NTSC|V4L2_STD_PAL, .tvn = { &f50ccir601_avs6eyes, &f60ccir601_avs6eyes, @@ -1087,8 +1084,6 @@ static int __devinit zr36057_init (struct zoran *zr) { int j, err; - int two = 2; - int zero = 0; dprintk(1, KERN_INFO @@ -1114,14 +1109,23 @@ zr36057_init (struct zoran *zr) if (default_norm < VIDEO_MODE_PAL && default_norm > VIDEO_MODE_SECAM) default_norm = VIDEO_MODE_PAL; - zr->norm = default_norm; - if (!(zr->timing = zr->card.tvn[zr->norm])) { + if (default_norm == VIDEO_MODE_PAL) { + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; + } else if (default_norm == VIDEO_MODE_NTSC) { + zr->norm = V4L2_STD_NTSC; + zr->timing = zr->card.tvn[1]; + } else { + zr->norm = V4L2_STD_SECAM; + zr->timing = zr->card.tvn[2]; + } + if (zr->timing == NULL) { dprintk(1, KERN_WARNING "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n", ZR_DEVNAME(zr)); - zr->norm = VIDEO_MODE_PAL; - zr->timing = zr->card.tvn[zr->norm]; + zr->norm = V4L2_STD_PAL; + zr->timing = zr->card.tvn[0]; } if (default_input > zr->card.inputs-1) { @@ -1133,12 +1137,6 @@ zr36057_init (struct zoran *zr) } zr->input = default_input; - /* Should the following be reset at every open ? */ - zr->hue = 32768; - zr->contrast = 32768; - zr->saturation = 32768; - zr->brightness = 32768; - /* default setup (will be repeated at every open) */ zoran_open_init_params(zr); @@ -1174,8 +1172,10 @@ zr36057_init (struct zoran *zr) detect_guest_activity(zr); test_interrupts(zr); if (!pass_through) { - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_command(zr, VIDIOC_STREAMOFF, 0); + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); } zr->zoran_proc = NULL; diff --git a/linux/drivers/media/video/zoran/zoran_device.c b/linux/drivers/media/video/zoran/zoran_device.c index 592300e2f..8544c9b99 100644 --- a/linux/drivers/media/video/zoran/zoran_device.c +++ b/linux/drivers/media/video/zoran/zoran_device.c @@ -38,6 +38,8 @@ #include #include "compat.h" #include +#include +#include #include #include @@ -313,9 +315,9 @@ zr36057_adjust_vfe (struct zoran *zr, case BUZ_MODE_MOTION_COMPRESS: case BUZ_MODE_IDLE: default: - if (zr->norm == VIDEO_MODE_NTSC || + if ((zr->norm & V4L2_STD_NTSC) || (zr->card.type == LML33R10 && - zr->norm == VIDEO_MODE_PAL)) + (zr->norm & V4L2_STD_PAL))) btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); else btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); @@ -356,14 +358,6 @@ zr36057_set_vfe (struct zoran *zr, dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", ZR_DEVNAME(zr), video_width, video_height); - if (zr->norm != VIDEO_MODE_PAL && - zr->norm != VIDEO_MODE_NTSC && - zr->norm != VIDEO_MODE_SECAM) { - dprintk(1, - KERN_ERR "%s: set_vfe() - norm = %d not valid\n", - ZR_DEVNAME(zr), zr->norm); - return; - } if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT || video_width > Wa || video_height > Ha) { @@ -427,7 +421,7 @@ zr36057_set_vfe (struct zoran *zr, * we get the correct colors when uncompressing to the screen */ //reg |= ZR36057_VFESPFR_VCLKPol; /**/ /* RJ: Don't know if that is needed for NTSC also */ - if (zr->norm != VIDEO_MODE_NTSC) + if (!(zr->norm & V4L2_STD_NTSC)) reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang reg |= ZR36057_VFESPFR_TopField; if (HorDcm >= 48) { @@ -982,11 +976,10 @@ void zr36057_enable_jpg (struct zoran *zr, enum zoran_codec_mode mode) { - static int zero; - static int one = 1; struct vfe_settings cap; int field_size = zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; + struct v4l2_routing route = { 0, 0 }; zr->codec_mode = mode; @@ -1008,8 +1001,9 @@ zr36057_enable_jpg (struct zoran *zr, * the video bus direction set to input. */ set_videobus_dir(zr, 0); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_command(zr, VIDIOC_STREAMON, 0); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1055,9 +1049,10 @@ zr36057_enable_jpg (struct zoran *zr, /* In motion decompression mode, the decoder output must be disabled, and * the video bus direction set to output. */ - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); + decoder_command(zr, VIDIOC_STREAMOFF, 0); set_videobus_dir(zr, 1); - encoder_command(zr, ENCODER_SET_INPUT, &one); + route.input = 1; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* Take the JPEG codec and the VFE out of sleep */ jpeg_codec_sleep(zr, 0); @@ -1101,8 +1096,9 @@ zr36057_enable_jpg (struct zoran *zr, jpeg_codec_sleep(zr, 1); zr36057_adjust_vfe(zr, mode); - decoder_command(zr, DECODER_ENABLE_OUTPUT, &one); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + decoder_command(zr, VIDIOC_STREAMON, 0); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); break; @@ -1212,17 +1208,17 @@ zoran_reap_stat_com (struct zoran *zr) static void zoran_restart(struct zoran *zr) { /* Now the stat_comm buffer is ready for restart */ - int status, mode; + int status = 0, mode; if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); mode = CODEC_DO_COMPRESSION; } else { - status = 0; + status = V4L2_IN_ST_NO_SIGNAL; mode = CODEC_DO_EXPANSION; } if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || - (status & DECODER_STATUS_GOOD)) { + !(status & V4L2_IN_ST_NO_SIGNAL)) { /********** RESTART code *************/ jpeg_codec_reset(zr); zr->codec->set_mode(zr->codec, mode); @@ -1588,7 +1584,7 @@ zoran_set_pci_master (struct zoran *zr, void zoran_init_hardware (struct zoran *zr) { - int j, zero = 0; + struct v4l2_routing route = { 0, 0 }; /* Enable bus-mastering */ zoran_set_pci_master(zr, 1); @@ -1598,15 +1594,16 @@ zoran_init_hardware (struct zoran *zr) zr->card.init(zr); } - j = zr->card.input[zr->input].muxsel; + route.input = zr->card.input[zr->input].muxsel; - decoder_command(zr, 0, NULL); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); - decoder_command(zr, DECODER_SET_INPUT, &j); + decoder_command(zr, VIDIOC_INT_INIT, NULL); + decoder_command(zr, VIDIOC_S_STD, &zr->norm); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); - encoder_command(zr, 0, NULL); - encoder_command(zr, ENCODER_SET_NORM, &zr->norm); - encoder_command(zr, ENCODER_SET_INPUT, &zero); + encoder_command(zr, VIDIOC_INT_INIT, NULL); + encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &zr->norm); + route.input = 0; + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* toggle JPEG codec sleep to sync PLL */ jpeg_codec_sleep(zr, 1); @@ -1680,7 +1677,7 @@ decoder_command (struct zoran *zr, return -EIO; if (zr->card.type == LML33 && - (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) { + (cmd == VIDIOC_S_STD || cmd == VIDIOC_INT_S_VIDEO_ROUTING)) { int res; // Bt819 needs to reset its FIFO buffer using #FRST pin and diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index e67c6caac..5145d2921 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -1146,9 +1146,10 @@ zoran_close(struct file *file) zoran_set_pci_master(zr, 0); if (!pass_through) { /* Switch to color bar */ - int zero = 0, two = 2; - decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero); - encoder_command(zr, ENCODER_SET_INPUT, &two); + struct v4l2_routing route = { 2, 0 }; + + decoder_command(zr, VIDIOC_STREAMOFF, 0); + encoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); } } @@ -1570,9 +1571,9 @@ zoran_v4l2_buffer_status (struct file *file, static int zoran_set_norm (struct zoran *zr, - int norm) /* VIDEO_MODE_* */ + v4l2_std_id norm) { - int norm_encoder, on; + int on; if (zr->v4l_buffers.active != ZORAN_FREE || zr->jpg_buffers.active != ZORAN_FREE) { @@ -1599,52 +1600,42 @@ zoran_set_norm (struct zoran *zr, } } - if (norm != VIDEO_MODE_AUTO && - (norm < 0 || norm >= zr->card.norms || - !zr->card.tvn[norm])) { + if (!(norm & zr->card.norms)) { dprintk(1, - KERN_ERR "%s: set_norm() - unsupported norm %d\n", + KERN_ERR "%s: set_norm() - unsupported norm %llx\n", ZR_DEVNAME(zr), norm); return -EINVAL; } - if (norm == VIDEO_MODE_AUTO) { - int status; + if (norm == V4L2_STD_ALL) { + int status = 0; + v4l2_std_id std = 0; - /* if we have autodetect, ... */ - struct video_decoder_capability caps; - decoder_command(zr, DECODER_GET_CAPABILITIES, &caps); - if (!(caps.flags & VIDEO_DECODER_AUTO)) { - dprintk(1, KERN_ERR "%s: norm=auto unsupported\n", - ZR_DEVNAME(zr)); - return -EINVAL; - } - - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_command(zr, VIDIOC_QUERYSTD, &std); + decoder_command(zr, VIDIOC_S_STD, &std); /* let changes come into effect */ ssleep(2); - decoder_command(zr, DECODER_GET_STATUS, &status); - if (!(status & DECODER_STATUS_GOOD)) { + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); + if (status & V4L2_IN_ST_NO_SIGNAL) { dprintk(1, KERN_ERR "%s: set_norm() - no norm detected\n", ZR_DEVNAME(zr)); /* reset norm */ - decoder_command(zr, DECODER_SET_NORM, &zr->norm); + decoder_command(zr, VIDIOC_S_STD, &zr->norm); return -EIO; } - if (status & DECODER_STATUS_NTSC) - norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) - norm = VIDEO_MODE_SECAM; - else - norm = VIDEO_MODE_PAL; + norm = std; } - zr->timing = zr->card.tvn[norm]; - norm_encoder = norm; + if (norm & V4L2_STD_SECAM) + zr->timing = zr->card.tvn[2]; + else if (norm & V4L2_STD_NTSC) + zr->timing = zr->card.tvn[1]; + else + zr->timing = zr->card.tvn[0]; /* We switch overlay off and on since a change in the * norm needs different VFE settings */ @@ -1652,8 +1643,8 @@ zoran_set_norm (struct zoran *zr, if (on) zr36057_overlay(zr, 0); - decoder_command(zr, DECODER_SET_NORM, &norm); - encoder_command(zr, ENCODER_SET_NORM, &norm_encoder); + decoder_command(zr, VIDIOC_S_STD, &norm); + encoder_command(zr, VIDIOC_INT_S_STD_OUTPUT, &norm); if (on) zr36057_overlay(zr, 1); @@ -1668,7 +1659,7 @@ static int zoran_set_input (struct zoran *zr, int input) { - int realinput; + struct v4l2_routing route = { 0, 0 }; if (input == zr->input) { return 0; @@ -1691,10 +1682,10 @@ zoran_set_input (struct zoran *zr, return -EINVAL; } - realinput = zr->card.input[input].muxsel; + route.input = zr->card.input[input].muxsel; zr->input = input; - decoder_command(zr, DECODER_SET_INPUT, &realinput); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); return 0; } @@ -1723,7 +1714,13 @@ static long zoran_default(struct file *file, void *__fh, int cmd, void *arg) mutex_lock(&zr->resource_lock); - bparams->norm = zr->norm; + if (zr->norm & V4L2_STD_NTSC) + bparams->norm = VIDEO_MODE_NTSC; + else if (zr->norm & V4L2_STD_PAL) + bparams->norm = VIDEO_MODE_PAL; + else + bparams->norm = VIDEO_MODE_SECAM; + bparams->input = zr->input; bparams->decimation = fh->jpg_settings.decimation; @@ -1906,7 +1903,9 @@ jpgreqbuf_unlock_and_return: case BUZIOC_G_STATUS: { struct zoran_status *bstat = arg; - int norm, input, status, res = 0; + struct v4l2_routing route = { 0, 0 }; + int status = 0, res = 0; + v4l2_std_id norm; dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr)); @@ -1918,8 +1917,7 @@ jpgreqbuf_unlock_and_return: return -EINVAL; } - input = zr->card.input[bstat->input].muxsel; - norm = VIDEO_MODE_AUTO; + route.input = zr->card.input[bstat->input].muxsel; mutex_lock(&zr->resource_lock); @@ -1932,34 +1930,33 @@ jpgreqbuf_unlock_and_return: goto gstat_unlock_and_return; } - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &norm); + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); /* sleep 1 second */ ssleep(1); /* Get status of video decoder */ - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_QUERYSTD, &norm); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &status); /* restore previous input and norm */ - input = zr->card.input[zr->input].muxsel; - decoder_command(zr, DECODER_SET_INPUT, &input); - decoder_command(zr, DECODER_SET_NORM, &zr->norm); + route.input = zr->card.input[zr->input].muxsel; + decoder_command(zr, VIDIOC_INT_S_VIDEO_ROUTING, &route); gstat_unlock_and_return: mutex_unlock(&zr->resource_lock); if (!res) { bstat->signal = - (status & DECODER_STATUS_GOOD) ? 1 : 0; - if (status & DECODER_STATUS_NTSC) + (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1; + if (norm & V4L2_STD_NTSC) bstat->norm = VIDEO_MODE_NTSC; - else if (status & DECODER_STATUS_SECAM) + else if (norm & V4L2_STD_SECAM) bstat->norm = VIDEO_MODE_SECAM; else bstat->norm = VIDEO_MODE_PAL; bstat->color = - (status & DECODER_STATUS_COLOR) ? 1 : 0; + (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1; } return res; @@ -2868,37 +2865,15 @@ strmoff_unlock_and_return: static int zoran_queryctrl(struct file *file, void *__fh, struct v4l2_queryctrl *ctrl) { + struct zoran_fh *fh = __fh; + struct zoran *zr = fh->zr; + /* we only support hue/saturation/contrast/brightness */ if (ctrl->id < V4L2_CID_BRIGHTNESS || ctrl->id > V4L2_CID_HUE) return -EINVAL; - else { - int id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; - } - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1); - break; - case V4L2_CID_CONTRAST: - strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1); - break; - case V4L2_CID_SATURATION: - strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1); - break; - case V4L2_CID_HUE: - strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1); - break; - } - ctrl->minimum = 0; - ctrl->maximum = 65535; - ctrl->step = 1; - ctrl->default_value = 32768; - ctrl->type = V4L2_CTRL_TYPE_INTEGER; - ctrl->flags = V4L2_CTRL_FLAG_SLIDER; + decoder_command(zr, VIDIOC_QUERYCTRL, ctrl); return 0; } @@ -2914,20 +2889,7 @@ static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl return -EINVAL; mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = zr->brightness; - break; - case V4L2_CID_CONTRAST: - ctrl->value = zr->contrast; - break; - case V4L2_CID_SATURATION: - ctrl->value = zr->saturation; - break; - case V4L2_CID_HUE: - ctrl->value = zr->hue; - break; - } + decoder_command(zr, VIDIOC_G_CTRL, ctrl); mutex_unlock(&zr->resource_lock); return 0; @@ -2937,42 +2899,14 @@ static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - struct video_picture pict; /* we only support hue/saturation/contrast/brightness */ if (ctrl->id < V4L2_CID_BRIGHTNESS || ctrl->id > V4L2_CID_HUE) return -EINVAL; - if (ctrl->value < 0 || ctrl->value > 65535) { - dprintk(1, KERN_ERR - "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n", - ZR_DEVNAME(zr), ctrl->value, ctrl->id); - return -EINVAL; - } - mutex_lock(&zr->resource_lock); - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - zr->brightness = ctrl->value; - break; - case V4L2_CID_CONTRAST: - zr->contrast = ctrl->value; - break; - case V4L2_CID_SATURATION: - zr->saturation = ctrl->value; - break; - case V4L2_CID_HUE: - zr->hue = ctrl->value; - break; - } - pict.brightness = zr->brightness; - pict.contrast = zr->contrast; - pict.colour = zr->saturation; - pict.hue = zr->hue; - - decoder_command(zr, DECODER_SET_PICTURE, &pict); - + decoder_command(zr, VIDIOC_S_CTRL, ctrl); mutex_unlock(&zr->resource_lock); return 0; @@ -2982,24 +2916,10 @@ static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int norm; mutex_lock(&zr->resource_lock); - norm = zr->norm; + *std = zr->norm; mutex_unlock(&zr->resource_lock); - - switch (norm) { - case VIDEO_MODE_PAL: - *std = V4L2_STD_PAL; - break; - case VIDEO_MODE_NTSC: - *std = V4L2_STD_NTSC; - break; - case VIDEO_MODE_SECAM: - *std = V4L2_STD_SECAM; - break; - } - return 0; } @@ -3007,25 +2927,10 @@ static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std) { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int norm = -1, res = 0; - - if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL)) - norm = VIDEO_MODE_PAL; - else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC)) - norm = VIDEO_MODE_NTSC; - else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM)) - norm = VIDEO_MODE_SECAM; - else if (*std == V4L2_STD_ALL) - norm = VIDEO_MODE_AUTO; - else { - dprintk(1, KERN_ERR - "%s: VIDIOC_S_STD - invalid norm 0x%llx\n", - ZR_DEVNAME(zr), (unsigned long long)*std); - return -EINVAL; - } + int res = 0; mutex_lock(&zr->resource_lock); - res = zoran_set_norm(zr, norm); + res = zoran_set_norm(zr, *std); if (res) goto sstd_unlock_and_return; @@ -3040,7 +2945,6 @@ static int zoran_enum_input(struct file *file, void *__fh, { struct zoran_fh *fh = __fh; struct zoran *zr = fh->zr; - int status; if (inp->index < 0 || inp->index >= zr->card.inputs) return -EINVAL; @@ -3057,16 +2961,8 @@ static int zoran_enum_input(struct file *file, void *__fh, /* Get status of video decoder */ mutex_lock(&zr->resource_lock); - decoder_command(zr, DECODER_GET_STATUS, &status); + decoder_command(zr, VIDIOC_INT_G_INPUT_STATUS, &inp->status); mutex_unlock(&zr->resource_lock); - - if (!(status & DECODER_STATUS_GOOD)) { - inp->status |= V4L2_IN_ST_NO_POWER; - inp->status |= V4L2_IN_ST_NO_SIGNAL; - } - if (!(status & DECODER_STATUS_COLOR)) - inp->status |= V4L2_IN_ST_NO_COLOR; - return 0; } -- cgit v1.2.3 From 5ac82a7507d0e50ce9a90a524c6d2d410c1de604 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 21:39:45 +0100 Subject: zoran: clean up some old V4L1 left-overs and remove the MAP_NR macro. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran.h | 3 - linux/drivers/media/video/zoran/zoran_driver.c | 130 ++++++++----------------- 2 files changed, 43 insertions(+), 90 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran.h b/linux/drivers/media/video/zoran/zoran.h index ee31bfc34..a323eb66e 100644 --- a/linux/drivers/media/video/zoran/zoran.h +++ b/linux/drivers/media/video/zoran/zoran.h @@ -238,9 +238,6 @@ enum gpcs_type { struct zoran_format { char *name; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - int palette; -#endif __u32 fourcc; int colorspace; int depth; diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 5145d2921..96085b123 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -58,16 +58,6 @@ #include #include -#define MAP_NR(x) virt_to_page(x) -#define ZORAN_VID_TYPE ( \ - VID_TYPE_CAPTURE | \ - VID_TYPE_OVERLAY | \ - VID_TYPE_CLIPPING | \ - VID_TYPE_FRAMERAM | \ - VID_TYPE_SCALES | \ - VID_TYPE_MJPEG_DECODER | \ - VID_TYPE_MJPEG_ENCODER \ - ) #include #include @@ -87,29 +77,12 @@ #include "zoran_device.h" #include "zoran_card.h" - /* we declare some card type definitions here, they mean - * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ -#define ZORAN_V4L2_VID_FLAGS ( \ - V4L2_CAP_STREAMING |\ - V4L2_CAP_VIDEO_CAPTURE |\ - V4L2_CAP_VIDEO_OUTPUT |\ - V4L2_CAP_VIDEO_OVERLAY \ - ) - - -#if defined(CONFIG_VIDEO_V4L1_COMPAT) -#define ZFMT(pal, fcc, cs) \ - .palette = (pal), .fourcc = (fcc), .colorspace = (cs) -#else -#define ZFMT(pal, fcc, cs) \ - .fourcc = (fcc), .colorspace = (cs) -#endif const struct zoran_format zoran_formats[] = { { .name = "15-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB555, - V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -117,16 +90,16 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "15-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB555X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 15, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, }, { .name = "16-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB565, - V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, @@ -134,56 +107,56 @@ const struct zoran_format zoran_formats[] = { ZR36057_VFESPFR_LittleEndian, }, { .name = "16-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB565X, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, }, { .name = "24-bit RGB", - ZFMT(VIDEO_PALETTE_RGB24, - V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR24, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 24, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, }, { .name = "32-bit RGB LE", - ZFMT(VIDEO_PALETTE_RGB32, - V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_BGR32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, }, { .name = "32-bit RGB BE", - ZFMT(-1, - V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB), + .fourcc = V4L2_PIX_FMT_RGB32, + .colorspace = V4L2_COLORSPACE_SRGB, .depth = 32, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_RGB888, }, { .name = "4:2:2, packed, YUYV", - ZFMT(VIDEO_PALETTE_YUV422, - V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_YUYV, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422, }, { .name = "4:2:2, packed, UYVY", - ZFMT(VIDEO_PALETTE_UYVY, - V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_UYVY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 16, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_OVERLAY, .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, }, { .name = "Hardware-encoded Motion-JPEG", - ZFMT(-1, - V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M), + .fourcc = V4L2_PIX_FMT_MJPEG, + .colorspace = V4L2_COLORSPACE_SMPTE170M, .depth = 0, .flags = ZORAN_FORMAT_CAPTURE | ZORAN_FORMAT_PLAYBACK | @@ -261,7 +234,7 @@ v4l_fbuffer_alloc (struct file *file) virt_to_bus(mem); for (off = 0; off < fh->v4l_buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); + SetPageReserved(virt_to_page(mem + off)); dprintk(4, KERN_INFO "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n", @@ -292,7 +265,7 @@ v4l_fbuffer_free (struct file *file) mem = fh->v4l_buffers.buffer[i].fbuffer; for (off = 0; off < fh->v4l_buffers.buffer_size; off += PAGE_SIZE) - ClearPageReserved(MAP_NR(mem + off)); + ClearPageReserved(virt_to_page(mem + off)); kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); fh->v4l_buffers.buffer[i].fbuffer = NULL; } @@ -378,7 +351,7 @@ jpg_fbuffer_alloc (struct file *file) cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1); for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) - SetPageReserved(MAP_NR(mem + off)); + SetPageReserved(virt_to_page(mem + off)); } else { /* jpg_bufsize is already page aligned */ for (j = 0; @@ -399,7 +372,7 @@ jpg_fbuffer_alloc (struct file *file) fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = cpu_to_le32((PAGE_SIZE / 4) << 1); - SetPageReserved(MAP_NR(mem)); + SetPageReserved(virt_to_page(mem)); } fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1); @@ -425,6 +398,7 @@ jpg_fbuffer_free (struct file *file) struct zoran *zr = fh->zr; int i, j, off; unsigned char *mem; + __le32 frag_tab; dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr)); @@ -432,48 +406,31 @@ jpg_fbuffer_free (struct file *file) if (!fh->jpg_buffers.buffer[i].frag_tab) continue; - //if (alloc_contig) { if (fh->jpg_buffers.need_contiguous) { - if (fh->jpg_buffers.buffer[i].frag_tab[0]) { - mem = (unsigned char *) bus_to_virt(le32_to_cpu( - fh->jpg_buffers.buffer[i].frag_tab[0])); - for (off = 0; - off < fh->jpg_buffers.buffer_size; - off += PAGE_SIZE) - ClearPageReserved(MAP_NR - (mem + off)); + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[0]; + + if (frag_tab) { + mem = (unsigned char *)bus_to_virt(le32_to_cpu(frag_tab)); + for (off = 0; off < fh->jpg_buffers.buffer_size; off += PAGE_SIZE) + ClearPageReserved(virt_to_page(mem + off)); kfree(mem); fh->jpg_buffers.buffer[i].frag_tab[0] = 0; fh->jpg_buffers.buffer[i].frag_tab[1] = 0; } } else { - for (j = 0; - j < fh->jpg_buffers.buffer_size / PAGE_SIZE; - j++) { - if (!fh->jpg_buffers.buffer[i]. - frag_tab[2 * j]) + for (j = 0; j < fh->jpg_buffers.buffer_size / PAGE_SIZE; j++) { + frag_tab = fh->jpg_buffers.buffer[i].frag_tab[2 * j]; + + if (!frag_tab) break; - ClearPageReserved(MAP_NR - (bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i].frag_tab[2 * - j])))); - free_page((unsigned long) - bus_to_virt - (le32_to_cpu - (fh->jpg_buffers. - buffer[i]. - frag_tab[2 * j]))); - fh->jpg_buffers.buffer[i].frag_tab[2 * j] = - 0; - fh->jpg_buffers.buffer[i].frag_tab[2 * j + - 1] = 0; + ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); + free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); + fh->jpg_buffers.buffer[i].frag_tab[2 * j] = 0; + fh->jpg_buffers.buffer[i].frag_tab[2 * j + 1] = 0; } } - free_page((unsigned long) fh->jpg_buffers.buffer[i]. - frag_tab); + free_page((unsigned long)fh->jpg_buffers.buffer[i].frag_tab); fh->jpg_buffers.buffer[i].frag_tab = NULL; } @@ -2017,11 +1974,10 @@ static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability strncpy(cap->driver, "zoran", sizeof(cap->driver)-1); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(zr->pci_dev)); - cap->version = - KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, + cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); - cap->capabilities = ZORAN_V4L2_VID_FLAGS; - + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; return 0; } -- cgit v1.2.3 From a9e2b393853fab732f68350caf74d3f8057ed8f1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 22:33:35 +0100 Subject: zoran: change buffer defaults to something that works with tvtime From: Hans Verkuil By popular request increased the default number and size of the buffers to something that tvtime likes. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_card.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c index 17c3aaffd..37f75045f 100644 --- a/linux/drivers/media/video/zoran/zoran_card.c +++ b/linux/drivers/media/video/zoran/zoran_card.c @@ -126,8 +126,8 @@ MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); */ -int v4l_nbufs = 2; -int v4l_bufsize = 128; /* Everybody should be able to work with this setting */ +int v4l_nbufs = 4; +int v4l_bufsize = 810; /* Everybody should be able to work with this setting */ module_param(v4l_nbufs, int, 0644); MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); module_param(v4l_bufsize, int, 0644); -- cgit v1.2.3 From bb9189ca522bccdf0c7d76b92a5860b074bc0c02 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 18 Feb 2009 22:34:55 +0100 Subject: zoran: TRY_FMT and S_FMT now do the same parameter checks. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/zoran/zoran_driver.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c index 96085b123..66659d479 100644 --- a/linux/drivers/media/video/zoran/zoran_driver.c +++ b/linux/drivers/media/video/zoran/zoran_driver.c @@ -2132,8 +2132,6 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) return -EINVAL; - fmt->fmt.pix.bytesperline = 0; - mutex_lock(&zr->resource_lock); settings = fh->jpg_settings; @@ -2158,6 +2156,14 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, else settings.field_per_buff = 1; + if (settings.HorDcm > 1) { + settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; + settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; + } else { + settings.img_x = 0; + settings.img_width = BUZ_MAX_WIDTH; + } + /* check */ res = zoran_check_jpg_settings(zr, &settings, 1); if (res) @@ -2175,6 +2181,8 @@ static int zoran_try_fmt_vid_out(struct file *file, void *__fh, V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; tryfmt_unlock_and_return: mutex_unlock(&zr->resource_lock); return res; -- cgit v1.2.3 From 353efa42bb001bd99872fdedd37a76d4fc085b23 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 19 Feb 2009 08:49:29 +0100 Subject: bt866: convert to v4l2_subdev. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/bt866.c | 231 ++++++++++++++++++---------------- linux/include/media/v4l2-chip-ident.h | 3 + 2 files changed, 125 insertions(+), 109 deletions(-) diff --git a/linux/drivers/media/video/bt866.c b/linux/drivers/media/video/bt866.c index 5aed3c7f1..9f53b8176 100644 --- a/linux/drivers/media/video/bt866.c +++ b/linux/drivers/media/video/bt866.c @@ -34,9 +34,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include "compat.h" @@ -48,21 +48,25 @@ static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + /* ----------------------------------------------------------------------- */ struct bt866 { + struct v4l2_subdev sd; u8 reg[256]; - - v4l2_std_id norm; - int bright; - int contrast; - int hue; - int sat; }; -static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) +static inline struct bt866 *to_bt866(struct v4l2_subdev *sd) { - struct bt866 *encoder = i2c_get_clientdata(client); + return container_of(sd, struct bt866, sd); +} + +static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data) +{ + struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); u8 buffer[2]; int err; @@ -89,119 +93,125 @@ static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data) return 0; } -static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) +static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) { - struct bt866 *encoder = i2c_get_clientdata(client); + v4l2_dbg(1, debug, sd, "set norm %llx\n", std); - switch (cmd) { - case VIDIOC_INT_S_STD_OUTPUT: - { - v4l2_std_id *iarg = arg; - - v4l_dbg(1, debug, client, "set norm %llx\n", *iarg); + /* Only PAL supported by this driver at the moment! */ + if (!(std & V4L2_STD_NTSC)) + return -EINVAL; + return 0; +} - if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL))) - return -EINVAL; - encoder->norm = *iarg; +static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +{ + static const __u8 init[] = { + 0xc8, 0xcc, /* CRSCALE */ + 0xca, 0x91, /* CBSCALE */ + 0xcc, 0x24, /* YC16 | OSDNUM */ + 0xda, 0x00, /* */ + 0xdc, 0x24, /* SETMODE | PAL */ + 0xde, 0x02, /* EACTIVE */ + + /* overlay colors */ + 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ + 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ + 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ + 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ + 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ + 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ + 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ + 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ + + 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ + 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ + 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ + 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ + 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ + 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ + 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ + 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ + }; + struct bt866 *encoder = to_bt866(sd); + u8 val; + int i; + + for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) + bt866_write(encoder, init[i], init[i+1]); + + val = encoder->reg[0xdc]; + + if (route->input == 0) + val |= 0x40; /* CBSWAP */ + else + val &= ~0x40; /* !CBSWAP */ + + bt866_write(encoder, 0xdc, val); + + val = encoder->reg[0xcc]; + if (route->input == 2) + val |= 0x01; /* OSDBAR */ + else + val &= ~0x01; /* !OSDBAR */ + bt866_write(encoder, 0xcc, val); + + v4l2_dbg(1, debug, sd, "set input %d\n", route->input); + + switch (route->input) { + case 0: + case 1: + case 2: break; + default: + return -EINVAL; } + return 0; +} - case VIDIOC_INT_S_VIDEO_ROUTING: - { - struct v4l2_routing *route = arg; - static const __u8 init[] = { - 0xc8, 0xcc, /* CRSCALE */ - 0xca, 0x91, /* CBSCALE */ - 0xcc, 0x24, /* YC16 | OSDNUM */ - 0xda, 0x00, /* */ - 0xdc, 0x24, /* SETMODE | PAL */ - 0xde, 0x02, /* EACTIVE */ - - /* overlay colors */ - 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */ - 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */ - 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */ - 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */ - 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */ - 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */ - 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */ - 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */ - - 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */ - 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */ - 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */ - 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */ - 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */ - 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */ - 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */ - 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */ - }; - int i; - u8 val; - - for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2) - bt866_write(client, init[i], init[i+1]); - - val = encoder->reg[0xdc]; - - if (route->input == 0) - val |= 0x40; /* CBSWAP */ - else - val &= ~0x40; /* !CBSWAP */ - - bt866_write(client, 0xdc, val); - - val = encoder->reg[0xcc]; - if (route->input == 2) - val |= 0x01; /* OSDBAR */ - else - val &= ~0x01; /* !OSDBAR */ - bt866_write(client, 0xcc, val); - - v4l_dbg(1, debug, client, "set input %d\n", route->input); - - switch (route->input) { - case 0: - break; - case 1: - break; - default: - return -EINVAL; - } - break; - } +#if 0 /* keep */ +/* Code to setup square pixels, might be of some use in the future, + but is currently unused. */ + val = encoder->reg[0xdc]; + if (*iarg) + val |= 1; /* SQUARE */ + else + val &= ~1; /* !SQUARE */ + bt866_write(client, 0xdc, val); +#endif - case 4711: - { - int *iarg = arg; - __u8 val; +static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); - v4l_dbg(1, debug, client, "square %d\n", *iarg); + return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0); +} - val = encoder->reg[0xdc]; - if (*iarg) - val |= 1; /* SQUARE */ - else - val &= ~1; /* !SQUARE */ - bt866_write(client, 0xdc, val); - break; - } +static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); +} - default: - return -EINVAL; - } +/* ----------------------------------------------------------------------- */ - return 0; -} +static const struct v4l2_subdev_core_ops bt866_core_ops = { + .g_chip_ident = bt866_g_chip_ident, +}; -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; +static const struct v4l2_subdev_video_ops bt866_video_ops = { + .s_std_output = bt866_s_std_output, + .s_routing = bt866_s_routing, +}; -I2C_CLIENT_INSMOD; +static const struct v4l2_subdev_ops bt866_ops = { + .core = &bt866_core_ops, + .video = &bt866_video_ops, +}; static int bt866_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bt866 *encoder; + struct v4l2_subdev *sd; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); @@ -209,14 +219,17 @@ static int bt866_probe(struct i2c_client *client, encoder = kzalloc(sizeof(*encoder), GFP_KERNEL); if (encoder == NULL) return -ENOMEM; - - i2c_set_clientdata(client, encoder); + sd = &encoder->sd; + v4l2_i2c_subdev_init(sd, client, &bt866_ops); return 0; } static int bt866_remove(struct i2c_client *client) { - kfree(i2c_get_clientdata(client)); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + + v4l2_device_unregister_subdev(sd); + kfree(to_bt866(sd)); return 0; } diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index bbe2bb6a5..cfb236e5a 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -71,6 +71,9 @@ enum { V4L2_IDENT_CX23416 = 416, V4L2_IDENT_CX23418 = 418, + /* module bt866: just ident 866 */ + V4L2_IDENT_BT866 = 866, + /* module vp27smpx: just ident 2700 */ V4L2_IDENT_VP27SMPX = 2700, -- cgit v1.2.3 From fbef599baf91dd9e8d3926f440a4087b8eaaaeb1 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 23 Feb 2009 16:11:25 +0100 Subject: soc-camera: fix S_CROP breakage on PXA and SuperH From: Guennadi Liakhovetski Recent format-negotiation patches caused S_CROP breakage in pxa_camera.c and sh_mobile_ceu_camera.c drivers, fix it. Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/pxa_camera.c | 26 +++++++++++++------------- drivers/media/video/sh_mobile_ceu_camera.c | 13 +++++-------- 2 files changed, 18 insertions(+), 21 deletions(-) --- linux/drivers/media/video/pxa_camera.c | 26 ++++++++++++------------ linux/drivers/media/video/sh_mobile_ceu_camera.c | 13 +++++------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index 2c283b82a..b6a34ba18 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -1164,23 +1164,23 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct pxa_camera_dev *pcdev = ici->priv; - const struct soc_camera_data_format *host_fmt, *cam_fmt = NULL; - const struct soc_camera_format_xlate *xlate; + const struct soc_camera_data_format *cam_fmt = NULL; + const struct soc_camera_format_xlate *xlate = NULL; struct soc_camera_sense sense = { .master_clock = pcdev->mclk, .pixel_clock_max = pcdev->ciclk / 4, }; - int ret, buswidth; + int ret; - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(&ici->dev, "Format %x not found\n", pixfmt); - return -EINVAL; - } + if (pixfmt) { + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } - buswidth = xlate->buswidth; - host_fmt = xlate->host_fmt; - cam_fmt = xlate->cam_fmt; + cam_fmt = xlate->cam_fmt; + } /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -1210,8 +1210,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd, } if (pixfmt && !ret) { - icd->buswidth = buswidth; - icd->current_fmt = host_fmt; + icd->buswidth = xlate->buswidth; + icd->current_fmt = xlate->host_fmt; } return ret; diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index ae98eaf5f..ee113de47 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -604,21 +604,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; int ret; + if (!pixfmt) + return icd->ops->set_fmt(icd, pixfmt, rect); + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { dev_warn(&ici->dev, "Format %x not found\n", pixfmt); return -EINVAL; } - switch (pixfmt) { - case 0: /* Only geometry change */ - ret = icd->ops->set_fmt(icd, pixfmt, rect); - break; - default: - ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - } + ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect); - if (pixfmt && !ret) { + if (!ret) { icd->buswidth = xlate->buswidth; icd->current_fmt = xlate->host_fmt; pcdev->camera_fmt = xlate->cam_fmt; -- cgit v1.2.3 From bc4a98a515e5988ced76cd09ff64046835528fde Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 19 Feb 2009 10:25:22 +0100 Subject: add SuperH files we need for video patches Signed-off-by: Guennadi Liakhovetski kernel-sync: --- --- linux/arch/sh/boards/board-ap325rxa.c | 525 +++++++++++++++++++++++++++++ linux/arch/sh/boards/mach-migor/setup.c | 578 ++++++++++++++++++++++++++++++++ 2 files changed, 1103 insertions(+) create mode 100644 linux/arch/sh/boards/board-ap325rxa.c create mode 100644 linux/arch/sh/boards/mach-migor/setup.c diff --git a/linux/arch/sh/boards/board-ap325rxa.c b/linux/arch/sh/boards/board-ap325rxa.c new file mode 100644 index 000000000..7c35787d2 --- /dev/null +++ b/linux/arch/sh/boards/board-ap325rxa.c @@ -0,0 +1,525 @@ +/* + * Renesas - AP-325RXA + * (Compatible with Algo System ., LTD. - AP-320A) + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Author : Yusuke Goda + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include