diff options
Diffstat (limited to 'drivers/media/usb/tlg2300/pd-common.h')
| -rw-r--r-- | drivers/media/usb/tlg2300/pd-common.h | 271 | 
1 files changed, 271 insertions, 0 deletions
diff --git a/drivers/media/usb/tlg2300/pd-common.h b/drivers/media/usb/tlg2300/pd-common.h new file mode 100644 index 00000000000..9e23ad32d2f --- /dev/null +++ b/drivers/media/usb/tlg2300/pd-common.h @@ -0,0 +1,271 @@ +#ifndef PD_COMMON_H +#define PD_COMMON_H + +#include <linux/fs.h> +#include <linux/wait.h> +#include <linux/list.h> +#include <linux/videodev2.h> +#include <linux/semaphore.h> +#include <linux/usb.h> +#include <linux/poll.h> +#include <media/videobuf-vmalloc.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ctrls.h> + +#include "dvb_frontend.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dmxdev.h" + +#define SBUF_NUM	8 +#define MAX_BUFFER_NUM	6 +#define PK_PER_URB	32 +#define ISO_PKT_SIZE	3072 + +#define POSEIDON_STATE_NONE		(0x0000) +#define POSEIDON_STATE_ANALOG		(0x0001) +#define POSEIDON_STATE_FM		(0x0002) +#define POSEIDON_STATE_DVBT		(0x0004) +#define POSEIDON_STATE_DISCONNECT	(0x0080) + +#define PM_SUSPEND_DELAY	3 + +#define V4L_PAL_VBI_LINES	18 +#define V4L_NTSC_VBI_LINES	12 +#define V4L_PAL_VBI_FRAMESIZE	(V4L_PAL_VBI_LINES * 1440 * 2) +#define V4L_NTSC_VBI_FRAMESIZE	(V4L_NTSC_VBI_LINES * 1440 * 2) + +#define TUNER_FREQ_MIN		(45000000U) +#define TUNER_FREQ_MAX		(862000000U) + +struct vbi_data { +	struct video_device	v_dev; +	struct video_data	*video; +	struct front_face	*front; + +	unsigned int		copied; +	unsigned int		vbi_size; /* the whole size of two fields */ +	int 			users; +}; + +/* + * This is the running context of the video, it is useful for + * resume() + */ +struct running_context { +	u32		freq;		/* VIDIOC_S_FREQUENCY */ +	int		audio_idx;	/* VIDIOC_S_TUNER    */ +	v4l2_std_id	tvnormid;	/* VIDIOC_S_STD     */ +	int		sig_index;	/* VIDIOC_S_INPUT  */ +	struct v4l2_pix_format pix;	/* VIDIOC_S_FMT   */ +}; + +struct video_data { +	/* v4l2 video device */ +	struct video_device	v_dev; +	struct v4l2_ctrl_handler ctrl_handler; + +	/* the working context */ +	struct running_context	context; + +	/* for data copy */ +	int		field_count; + +	char		*dst; +	int		lines_copied; +	int		prev_left; + +	int		lines_per_field; +	int		lines_size; + +	/* for communication */ +	u8			endpoint_addr; +	struct urb 		*urb_array[SBUF_NUM]; +	struct vbi_data		*vbi; +	struct poseidon 	*pd; +	struct front_face	*front; + +	int			is_streaming; +	int			users; + +	/* for bubble handler */ +	struct work_struct	bubble_work; +}; + +enum pcm_stream_state { +	STREAM_OFF, +	STREAM_ON, +	STREAM_SUSPEND, +}; + +#define AUDIO_BUFS (3) +#define CAPTURE_STREAM_EN 1 +struct poseidon_audio { +	struct urb		*urb_array[AUDIO_BUFS]; +	unsigned int 		copied_position; +	struct snd_pcm_substream   *capture_pcm_substream; + +	unsigned int 		rcv_position; +	struct	snd_card	*card; +	int 			card_close; + +	int 			users; +	int			pm_state; +	enum pcm_stream_state 	capture_stream; +}; + +struct radio_data { +	__u32		fm_freq; +	unsigned int	is_radio_streaming; +	int		pre_emphasis; +	struct video_device fm_dev; +	struct v4l2_ctrl_handler ctrl_handler; +}; + +#define DVB_SBUF_NUM		4 +#define DVB_URB_BUF_SIZE	0x2000 +struct pd_dvb_adapter { +	struct dvb_adapter	dvb_adap; +	struct dvb_frontend	dvb_fe; +	struct dmxdev		dmxdev; +	struct dvb_demux	demux; + +	atomic_t		users; +	atomic_t		active_feed; + +	/* data transfer */ +	s32			is_streaming; +	struct urb		*urb_array[DVB_SBUF_NUM]; +	struct poseidon		*pd_device; +	u8			ep_addr; +	u8			reserved[3]; + +	/* data for power resume*/ +	struct dtv_frontend_properties fe_param; + +	/* for channel scanning */ +	int		prev_freq; +	int		bandwidth; +	unsigned long	last_jiffies; +}; + +struct front_face { +	/* use this field to distinguish VIDEO and VBI */ +	enum v4l2_buf_type	type; + +	/* for host */ +	struct videobuf_queue	q; + +	/* the bridge for host and device */ +	struct videobuf_buffer	*curr_frame; + +	/* for device */ +	spinlock_t		queue_lock; +	struct list_head	active; +	struct poseidon		*pd; +}; + +struct poseidon { +	struct list_head	device_list; + +	struct mutex		lock; +	struct kref		kref; + +	/* for V4L2 */ +	struct v4l2_device	v4l2_dev; + +	/* hardware info */ +	struct usb_device	*udev; +	struct usb_interface	*interface; +	int 			cur_transfer_mode; + +	struct video_data	video_data;	/* video */ +	struct vbi_data		vbi_data;	/* vbi	 */ +	struct poseidon_audio	audio;		/* audio (alsa) */ +	struct radio_data	radio_data;	/* FM	 */ +	struct pd_dvb_adapter	dvb_data;	/* DVB	 */ + +	u32			state; +	struct file		*file_for_stream; /* the active stream*/ + +#ifdef CONFIG_PM +	int (*pm_suspend)(struct poseidon *); +	int (*pm_resume)(struct poseidon *); +	pm_message_t		msg; + +	struct work_struct	pm_work; +	u8			portnum; +#endif +}; + +struct poseidon_format { +	char 	*name; +	int	fourcc;		 /* video4linux 2	  */ +	int	depth;		 /* bit/pixel		  */ +	int	flags; +}; + +struct poseidon_tvnorm { +	v4l2_std_id	v4l2_id; +	char		name[12]; +	u32		tlg_tvnorm; +}; + +/* video */ +int pd_video_init(struct poseidon *); +void pd_video_exit(struct poseidon *); +int stop_all_video_stream(struct poseidon *); + +/* alsa audio */ +int poseidon_audio_init(struct poseidon *); +int poseidon_audio_free(struct poseidon *); +#ifdef CONFIG_PM +int pm_alsa_suspend(struct poseidon *); +int pm_alsa_resume(struct poseidon *); +#endif + +/* dvb */ +int pd_dvb_usb_device_init(struct poseidon *); +void pd_dvb_usb_device_exit(struct poseidon *); +void pd_dvb_usb_device_cleanup(struct poseidon *); +int pd_dvb_get_adapter_num(struct pd_dvb_adapter *); +void dvb_stop_streaming(struct pd_dvb_adapter *); + +/* FM */ +int poseidon_fm_init(struct poseidon *); +int poseidon_fm_exit(struct poseidon *); + +/* vendor command ops */ +int send_set_req(struct poseidon*, u8, s32, s32*); +int send_get_req(struct poseidon*, u8, s32, void*, s32*, s32); +s32 set_tuner_mode(struct poseidon*, unsigned char); + +/* bulk urb alloc/free */ +int alloc_bulk_urbs_generic(struct urb **urb_array, int num, +			struct usb_device *udev, u8 ep_addr, +			int buf_size, gfp_t gfp_flags, +			usb_complete_t complete_fn, void *context); +void free_all_urb_generic(struct urb **urb_array, int num); + +/* misc */ +void poseidon_delete(struct kref *kref); +extern int debug_mode; +void set_debug_mode(struct video_device *vfd, int debug_mode); + +#ifdef CONFIG_PM +#define in_hibernation(pd) (pd->msg.event == PM_EVENT_FREEZE) +#else +#define in_hibernation(pd) (0) +#endif +#define get_pm_count(p) (atomic_read(&(p)->interface->pm_usage_cnt)) + +#define log(a, ...) printk(KERN_DEBUG "\t[ %s : %.3d ] "a"\n", \ +				__func__, __LINE__,  ## __VA_ARGS__) + +/* for power management */ +#define logpm(pd) do {\ +			if (debug_mode & 0x10)\ +				log();\ +		} while (0) + +#endif  | 
