/*
 * demux.h
 *
 * The Kernel Digital TV Demux kABI defines a driver-internal interface for
 * registering low-level, hardware specific driver to a hardware independent
 * demux layer.
 *
 * Copyright (c) 2002 Convergence GmbH
 *
 * based on code:
 * Copyright (c) 2000 Nokia Research Center
 *                    Tampere, FINLAND
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * 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.
 *
 */

#ifndef __DEMUX_H
#define __DEMUX_H

#include <linux/types.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/time.h>
#include <linux/dvb/dmx.h>

/*
 * 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 18
#endif

/*
 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed
 * filter.
 */

#ifndef DMX_MAX_SECTION_SIZE
#define DMX_MAX_SECTION_SIZE 4096
#endif
#ifndef DMX_MAX_SECFEED_SIZE
#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
#endif

/*
 * TS packet reception
 */

/**
 * enum ts_filter_type - filter type bitmap for dmx_ts_feed.set\(\)
 *
 * @TS_PACKET:		Send TS packets (188 bytes) to callback (default).
 * @TS_PAYLOAD_ONLY:	In case TS_PACKET is set, only send the TS payload
 *			(<=184 bytes per packet) to callback
 * @TS_DECODER:		Send stream to built-in decoder (if present).
 * @TS_DEMUX:		In case TS_PACKET is set, send the TS to the demux
 *			device, not to the dvr device
 */
enum ts_filter_type {
	TS_PACKET = 1,
	TS_PAYLOAD_ONLY = 2,
	TS_DECODER = 4,
	TS_DEMUX = 8,
};

/**
 * struct dmx_ts_feed - Structure that contains a TS feed filter
 *
 * @is_filtering:	Set to non-zero when filtering in progress
 * @parent:		pointer to struct dmx_demux
 * @priv:		pointer to private data of the API client
 * @set:		sets the TS filter
 * @start_filtering:	starts TS filtering
 * @stop_filtering:	stops TS filtering
 *
 * 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.
 */
struct dmx_ts_feed {
	int is_filtering;
	struct dmx_demux *parent;
	void *priv;
	int (*set)(struct dmx_ts_feed *feed,
		   u16 pid,
		   int type,
		   enum dmx_ts_pes pes_type,
		   ktime_t timeout);
	int (*start_filtering)(struct dmx_ts_feed *feed);
	int (*stop_filtering)(struct dmx_ts_feed *feed);
};

/*
 * Section reception
 */

/**
 * struct dmx_section_filter - Structure that describes a section filter
 *
 * @filter_value: Contains up to 16 bytes (128 bits) of the TS section header
 *		  that will be matched by the section filter
 * @filter_mask:  Contains a 16 bytes (128 bits) filter mask with the bits
 *		  specified by @filter_value that will be used on the filter
 *		  match logic.
 * @filter_mode:  Contains a 16 bytes (128 bits) filter mode.
 * @parent:	  Pointer to struct dmx_section_feed.
 * @priv:	  Pointer to private data of the API client.
 *
 *
 * The @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.
 */
struct dmx_section_filter {
	u8 filter_value[DMX_MAX_FILTER_SIZE];
	u8 filter_mask[DMX_MAX_FILTER_SIZE];
	u8 filter_mode[DMX_MAX_FILTER_SIZE];
	struct dmx_section_feed *parent; /* Back-pointer */
	void *priv; /* Pointer to private data of the API client */
};

/**
 * struct dmx_section_feed - Structure that contains a section feed filter
 *
 * @is_filtering:	Set to non-zero when filtering in progress
 * @parent:		pointer to struct dmx_demux
 * @priv:		pointer to private data of the API client
 * @check_crc:		If non-zero, check the CRC values of filtered sections.
 * @set:		sets the section filter
 * @allocate_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.
 * @release_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.
 * @start_filtering:	starts section filtering
 * @stop_filtering:	stops section filtering
 *
 * 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.
 */
struct dmx_section_feed {
	int is_filtering;
	struct dmx_demux *parent;
	void *priv;

	int check_crc;

	/* private: Used internally at dvb_demux.c */
	u32 crc_val;

	u8 *secbuf;
	u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
	u16 secbufp, seclen, tsfeedp;

	/* public: */
	int (*set)(struct dmx_section_feed *feed,
		   u16 pid,
		   int check_crc);
	int (*allocate_filter)(struct dmx_section_feed *feed,
			       struct dmx_section_filter **filter);
	int (*release_filter)(struct dmx_section_feed *feed,
			      struct dmx_section_filter *filter);
	int (*start_filtering)(struct dmx_section_feed *feed);
	int (*stop_filtering)(struct dmx_section_feed *feed);
};

/**
 * typedef dmx_ts_cb - DVB demux TS filter callback function prototype
 *
 * @buffer1:		Pointer to the start of the filtered TS packets.
 * @buffer1_length:	Length of the TS data in buffer1.
 * @buffer2:		Pointer to the tail of the filtered TS packets, or NULL.
 * @buffer2_length:	Length of the TS data in buffer2.
 * @source:		Indicates which TS feed is the source of the callback.
 *
 * This function callback prototype, provided by the client of the demux API,
 * is called from the demux code. The function is only called when filtering
 * on a TS feed has been enabled using the start_filtering\(\) function at
 * the &dmx_demux.
 * 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.
 * 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 and return -EOVERFLOW.
 *
 * The type of data returned to the callback can be selected by the
 * &dmx_ts_feed.@set function. 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.
 *
 * Return:
 *
 * - 0, on success;
 *
 * - -EOVERFLOW, on buffer overflow.
 */
typedef int (*dmx_ts_cb)(const u8 *buffer1,
			 size_t buffer1_length,
			 const u8 *buffer2,
			 size_t buffer2_length,
			 struct dmx_ts_feed *source);

/**
 * typedef dmx_section_cb - DVB demux TS filter callback function prototype
 *
 * @buffer1:		Pointer to the start of the filtered section, e.g.
 *			within the circular buffer of the demux driver.
 * @buffer1_len:	Length of the filtered section data in @buffer1,
 *			including headers and CRC.
 * @buffer2:		Pointer to the tail of the filtered section data,
 *			or NULL. Useful to handle the wrapping of a
 *			circular buffer.
 * @buffer2_len:	Length of the filtered section data in @buffer2,
 *			including headers and CRC.
 * @source:		Indicates which section feed is the source of the
 *			callback.
 *
 * This function callback prototype, 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
 * &dmx_ts_feed.@start_filtering. 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 &dmx_ts_feed.@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.
 */
typedef int (*dmx_section_cb)(const u8 *buffer1,
			      size_t buffer1_len,
			      const u8 *buffer2,
			      size_t buffer2_len,
			      struct dmx_section_filter *source);

/*
 * DVB Front-End
 */

/**
 * enum dmx_frontend_source - Used to identify the type of frontend
 *
 * @DMX_MEMORY_FE:	The source of the demux is memory. It means that
 *			the MPEG-TS to be filtered comes from userspace,
 *			via write() syscall.
 *
 * @DMX_FRONTEND_0:	The source of the demux is a frontend connected
 *			to the demux.
 */
enum dmx_frontend_source {
	DMX_MEMORY_FE,
	DMX_FRONTEND_0,
};

/**
 * struct dmx_frontend - Structure that lists the frontends associated with
 *			 a demux
 *
 * @connectivity_list:	List of front-ends that can be connected to a
 *			particular demux;
 * @source:		Type of the frontend.
 *
 * FIXME: this structure should likely be replaced soon by some
 *	media-controller based logic.
 */
struct dmx_frontend {
	struct list_head connectivity_list;
	enum dmx_frontend_source source;
};

/*
 * MPEG-2 TS Demux
 */

/**
 * enum dmx_demux_caps - MPEG-2 TS Demux capabilities bitmap
 *
 * @DMX_TS_FILTERING:		set if TS filtering is supported;
 * @DMX_SECTION_FILTERING:	set if section filtering is supported;
 * @DMX_MEMORY_BASED_FILTERING:	set if write() available.
 *
 * Those flags are OR'ed in the &dmx_demux.capabilities field
 */
enum dmx_demux_caps {
	DMX_TS_FILTERING = 1,
	DMX_SECTION_FILTERING = 4,
	DMX_MEMORY_BASED_FILTERING = 8,
};

/*
 * 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 * struct dmx_frontend
 *
 * @list: list of struct dmx_frontend
 */
#define DMX_FE_ENTRY(list) \
	list_entry(list, struct dmx_frontend, connectivity_list)

/**
 * struct dmx_demux - Structure that contains the demux capabilities and
 *		      callbacks.
 *
 * @capabilities: Bitfield of capability flags.
 *
 * @frontend: Front-end connected to the demux
 *
 * @priv: Pointer to private data of the API client
 *
 * @open: 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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EUSERS, if maximum usage count was reached;
 *	-EINVAL, on bad parameter.
 *
 * @close: 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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-ENODEV, if demux was not in use (e. g. no users);
 *	-EINVAL, on bad parameter.
 *
 * @write: 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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @buf function parameter contains a pointer to the TS data in
 *	kernel-space memory.
 *	The @count function parameter contains the length of the TS data.
 *	It returns:
 *	0 on success;
 *	-ERESTARTSYS, if mutex lock was interrupted;
 *	-EINTR, if a signal handling is pending;
 *	-ENODEV, if demux was removed;
 *	-EINVAL, on bad parameter.
 *
 * @allocate_ts_feed: 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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @feed function parameter contains a pointer to the TS feed API and
 *	instance data.
 *	The @callback function parameter contains a pointer to the callback
 *	function for passing received TS packet.
 *	It returns:
 *	0 on success;
 *	-ERESTARTSYS, if mutex lock was interrupted;
 *	-EBUSY, if no more TS feeds is available;
 *	-EINVAL, on bad parameter.
 *
 * @release_ts_feed: Releases the resources allocated with @allocate_ts_feed.
 *	Any filtering in progress on the TS feed should be stopped before
 *	calling this function.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @feed function parameter contains a pointer to the TS feed API and
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EINVAL on bad parameter.
 *
 * @allocate_section_feed: 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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @feed function parameter contains a pointer to the TS feed API and
 *	instance data.
 *	The @callback function parameter contains a pointer to the callback
 *	function for passing received TS packet.
 *	It returns:
 *	0 on success;
 *	-EBUSY, if no more TS feeds is available;
 *	-EINVAL, on bad parameter.
 *
 * @release_section_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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @feed function parameter contains a pointer to the TS feed API and
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EINVAL, on bad parameter.
 *
 * @add_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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @frontend function parameter contains a pointer to the front-end
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EINVAL, on bad parameter.
 *
 * @remove_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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @frontend function parameter contains a pointer to the front-end
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-ENODEV, if the front-end was not found,
 *	-EINVAL, on bad parameter.
 *
 * @get_frontends: 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
 *	struct &dmx_frontend *. The caller must not free the memory of any of
 *	the elements obtained via this function call.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	It returns a struct list_head pointer to the list of front-end
 *	interfaces, or NULL in the case of an empty list.
 *
 * @connect_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.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @frontend function parameter contains a pointer to the front-end
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EINVAL, on bad parameter.
 *
 * @disconnect_frontend: Disconnects the demux and a front-end previously
 *	connected by a @connect_frontend call.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	It returns:
 *	0 on success;
 *	-EINVAL on bad parameter.
 *
 * @get_pes_pids: Get the PIDs for DMX_PES_AUDIO0, DMX_PES_VIDEO0,
 *	DMX_PES_TELETEXT0, DMX_PES_SUBTITLE0 and DMX_PES_PCR0.
 *	The @demux function parameter contains a pointer to the demux API and
 *	instance data.
 *	The @pids function parameter contains an array with five u16 elements
 *	where the PIDs will be stored.
 *	It returns:
 *	0 on success;
 *	-EINVAL on bad parameter.
 */
struct dmx_demux {
	enum dmx_demux_caps capabilities;
	struct dmx_frontend *frontend;
	void *priv;
	int (*open)(struct dmx_demux *demux);
	int (*close)(struct dmx_demux *demux);
	int (*write)(struct dmx_demux *demux, const char __user *buf,
		     size_t count);
	int (*allocate_ts_feed)(struct dmx_demux *demux,
				struct dmx_ts_feed **feed,
				dmx_ts_cb callback);
	int (*release_ts_feed)(struct dmx_demux *demux,
			       struct dmx_ts_feed *feed);
	int (*allocate_section_feed)(struct dmx_demux *demux,
				     struct dmx_section_feed **feed,
				     dmx_section_cb callback);
	int (*release_section_feed)(struct dmx_demux *demux,
				    struct dmx_section_feed *feed);
	int (*add_frontend)(struct dmx_demux *demux,
			    struct dmx_frontend *frontend);
	int (*remove_frontend)(struct dmx_demux *demux,
			       struct dmx_frontend *frontend);
	struct list_head *(*get_frontends)(struct dmx_demux *demux);
	int (*connect_frontend)(struct dmx_demux *demux,
				struct dmx_frontend *frontend);
	int (*disconnect_frontend)(struct dmx_demux *demux);

	int (*get_pes_pids)(struct dmx_demux *demux, u16 *pids);

	/* private: */

	/*
	 * Only used at av7110, to read some data from firmware.
	 * As this was never documented, we have no clue about what's
	 * there, and its usage on other drivers aren't encouraged.
	 */
	int (*get_stc)(struct dmx_demux *demux, unsigned int num,
		       u64 *stc, unsigned int *base);
};

#endif /* #ifndef __DEMUX_H */
