2008-04-18 21:34:00 -03:00
/*
* Driver for the Auvitek AU0828 USB bridge
*
2008-09-03 17:12:12 -03:00
* Copyright ( c ) 2008 Steven Toth < stoth @ linuxtv . org >
2008-04-18 21:34:00 -03:00
*
* 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 0213 9 , USA .
*/
# include <linux/usb.h>
# include <linux/i2c.h>
# include <linux/i2c-algo-bit.h>
2008-03-29 19:53:07 -03:00
# include <media/tveeprom.h>
2008-04-18 21:34:00 -03:00
2009-03-11 03:00:40 -03:00
/* Analog */
# include <linux/videodev2.h>
# include <media/videobuf-vmalloc.h>
2009-03-11 03:01:04 -03:00
# include <media/v4l2-device.h>
2009-03-11 03:00:40 -03:00
2008-04-18 21:34:00 -03:00
/* DVB */
# include "demux.h"
# include "dmxdev.h"
# include "dvb_demux.h"
# include "dvb_frontend.h"
# include "dvb_net.h"
# include "dvbdev.h"
# include "au0828-reg.h"
# include "au0828-cards.h"
# define DRIVER_NAME "au0828"
# define URB_COUNT 16
# define URB_BUFSIZE (0xe522)
2009-03-11 03:00:40 -03:00
/* Analog constants */
# define NTSC_STD_W 720
# define NTSC_STD_H 480
# define AU0828_INTERLACED_DEFAULT 1
# define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
/* Defination for AU0828 USB transfer */
# define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
2010-06-25 01:33:39 -03:00
# define AU0828_ISO_PACKETS_PER_URB 128
2009-03-11 03:00:40 -03:00
# define AU0828_MIN_BUF 4
# define AU0828_DEF_BUF 8
# define AU0828_MAX_INPUT 4
2010-05-29 17:18:45 -03:00
/* au0828 resource types (used for res_get/res_lock etc */
# define AU0828_RESOURCE_VIDEO 0x01
# define AU0828_RESOURCE_VBI 0x02
2009-03-11 03:00:40 -03:00
enum au0828_itype {
2009-03-11 03:01:01 -03:00
AU0828_VMUX_UNDEFINED = 0 ,
AU0828_VMUX_COMPOSITE ,
2009-03-11 03:00:40 -03:00
AU0828_VMUX_SVIDEO ,
AU0828_VMUX_CABLE ,
AU0828_VMUX_TELEVISION ,
AU0828_VMUX_DVB ,
AU0828_VMUX_DEBUG
} ;
struct au0828_input {
enum au0828_itype type ;
unsigned int vmux ;
unsigned int amux ;
void ( * audio_setup ) ( void * priv , int enable ) ;
} ;
2008-04-18 21:34:00 -03:00
struct au0828_board {
char * name ;
2009-03-11 03:00:47 -03:00
unsigned int tuner_type ;
unsigned char tuner_addr ;
2009-04-01 00:11:31 -03:00
unsigned char i2c_clk_divider ;
2009-03-11 03:00:40 -03:00
struct au0828_input input [ AU0828_MAX_INPUT ] ;
2008-04-18 21:34:00 -03:00
} ;
struct au0828_dvb {
struct mutex lock ;
struct dvb_adapter adapter ;
struct dvb_frontend * frontend ;
struct dvb_demux demux ;
struct dmxdev dmxdev ;
struct dmx_frontend fe_hw ;
struct dmx_frontend fe_mem ;
struct dvb_net net ;
int feeding ;
} ;
2009-03-11 03:00:40 -03:00
enum au0828_stream_state {
STREAM_OFF ,
STREAM_INTERRUPT ,
STREAM_ON
} ;
2009-03-11 03:00:47 -03:00
# define AUVI_INPUT(nr) (dev->board.input[nr])
2009-03-11 03:00:40 -03:00
/* device state */
enum au0828_dev_state {
DEV_INITIALIZED = 0x01 ,
DEV_DISCONNECTED = 0x02 ,
DEV_MISCONFIGURED = 0x04
} ;
struct au0828_fh {
struct au0828_dev * dev ;
2010-05-29 17:18:45 -03:00
unsigned int resources ;
2009-03-11 03:00:40 -03:00
struct videobuf_queue vb_vidq ;
2010-05-29 17:18:45 -03:00
struct videobuf_queue vb_vbiq ;
2009-03-11 03:00:40 -03:00
enum v4l2_buf_type type ;
} ;
struct au0828_usb_isoc_ctl {
/* max packet size of isoc transaction */
int max_pkt_size ;
/* number of allocated urbs */
int num_bufs ;
/* urb for isoc transfers */
struct urb * * urb ;
/* transfer buffers for isoc transfer */
char * * transfer_buffer ;
/* Last buffer command and region */
u8 cmd ;
int pos , size , pktsize ;
/* Last field: ODD or EVEN? */
int field ;
/* Stores incomplete commands */
u32 tmp_buf ;
int tmp_buf_len ;
/* Stores already requested buffers */
2010-05-29 17:18:45 -03:00
struct au0828_buffer * buf ;
struct au0828_buffer * vbi_buf ;
2009-03-11 03:00:40 -03:00
/* Stores the number of received fields */
int nfields ;
/* isoc urb callback */
int ( * isoc_copy ) ( struct au0828_dev * dev , struct urb * urb ) ;
} ;
/* buffer for one video frame */
struct au0828_buffer {
/* common v4l buffer stuff -- must be first */
struct videobuf_buffer vb ;
struct list_head frame ;
int top_field ;
int receiving ;
} ;
struct au0828_dmaqueue {
struct list_head active ;
struct list_head queued ;
wait_queue_head_t wq ;
/* Counters to control buffer fill */
int pos ;
} ;
2008-04-18 21:34:00 -03:00
struct au0828_dev {
struct mutex mutex ;
struct usb_device * usbdev ;
2009-03-11 03:00:47 -03:00
int boardnr ;
struct au0828_board board ;
2008-04-18 21:34:00 -03:00
u8 ctrlmsg [ 64 ] ;
/* I2C */
struct i2c_adapter i2c_adap ;
2009-03-11 03:01:04 -03:00
struct i2c_algorithm i2c_algo ;
2008-04-18 21:34:00 -03:00
struct i2c_client i2c_client ;
u32 i2c_rc ;
/* Digital */
struct au0828_dvb dvb ;
2009-03-11 03:00:40 -03:00
/* Analog */
2009-03-11 03:01:04 -03:00
struct v4l2_device v4l2_dev ;
2009-03-11 03:00:40 -03:00
int users ;
2010-05-29 17:18:45 -03:00
unsigned int resources ; /* resources in use */
2009-03-11 03:00:40 -03:00
struct video_device * vdev ;
struct video_device * vbi_dev ;
2010-09-01 22:03:43 -03:00
struct timer_list vid_timeout ;
2010-10-09 14:43:53 -03:00
int vid_timeout_running ;
2010-09-01 22:03:43 -03:00
struct timer_list vbi_timeout ;
2010-10-09 14:43:53 -03:00
int vbi_timeout_running ;
2009-03-11 03:00:40 -03:00
int width ;
int height ;
2010-05-29 17:18:45 -03:00
int vbi_width ;
int vbi_height ;
u32 vbi_read ;
2009-03-11 03:00:40 -03:00
u32 field_size ;
u32 frame_size ;
u32 bytesperline ;
int type ;
u8 ctrl_ainput ;
__u8 isoc_in_endpointaddr ;
u8 isoc_init_ok ;
int greenscreen_detected ;
unsigned int frame_count ;
int ctrl_freq ;
int input_type ;
unsigned int ctrl_input ;
enum au0828_dev_state dev_state ;
enum au0828_stream_state stream_state ;
wait_queue_head_t open ;
struct mutex lock ;
/* Isoc control struct */
struct au0828_dmaqueue vidq ;
2010-05-29 17:18:45 -03:00
struct au0828_dmaqueue vbiq ;
2009-03-11 03:00:40 -03:00
struct au0828_usb_isoc_ctl isoc_ctl ;
spinlock_t slock ;
/* usb transfer */
int alt ; /* alternate */
int max_pkt_size ; /* max packet size of isoc transaction */
int num_alt ; /* Number of alternative settings */
unsigned int * alt_max_pkt_size ; /* array of wMaxPacketSize */
struct urb * urb [ AU0828_MAX_ISO_BUFS ] ; /* urb for isoc transfers */
char * transfer_buffer [ AU0828_MAX_ISO_BUFS ] ; /* transfer buffers for isoc
transfer */
2008-04-18 21:34:00 -03:00
/* USB / URB Related */
int urb_streaming ;
struct urb * urbs [ URB_COUNT ] ;
} ;
/* ----------------------------------------------------------- */
2008-04-18 22:12:52 -03:00
# define au0828_read(dev, reg) au0828_readreg(dev, reg)
# define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value)
# define au0828_andor(dev, reg, mask, value) \
au0828_writereg ( dev , reg , \
( au0828_readreg ( dev , reg ) & ~ ( mask ) ) | ( ( value ) & ( mask ) ) )
# define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit))
# define au0828_clear(dev, reg, bit) au0828_andor(dev, (reg), (bit), 0)
2008-04-18 21:34:00 -03:00
/* ----------------------------------------------------------- */
/* au0828-core.c */
extern u32 au0828_read ( struct au0828_dev * dev , u16 reg ) ;
extern u32 au0828_write ( struct au0828_dev * dev , u16 reg , u32 val ) ;
2008-04-25 19:06:03 -03:00
extern int au0828_debug ;
2008-04-18 21:34:00 -03:00
/* ----------------------------------------------------------- */
/* au0828-cards.c */
extern struct au0828_board au0828_boards [ ] ;
extern struct usb_device_id au0828_usb_id_table [ ] ;
extern void au0828_gpio_setup ( struct au0828_dev * dev ) ;
2008-09-12 13:31:45 -03:00
extern int au0828_tuner_callback ( void * priv , int component ,
int command , int arg ) ;
2008-03-29 19:53:07 -03:00
extern void au0828_card_setup ( struct au0828_dev * dev ) ;
2008-04-18 21:34:00 -03:00
/* ----------------------------------------------------------- */
/* au0828-i2c.c */
extern int au0828_i2c_register ( struct au0828_dev * dev ) ;
extern int au0828_i2c_unregister ( struct au0828_dev * dev ) ;
2009-03-11 03:00:40 -03:00
/* ----------------------------------------------------------- */
/* au0828-video.c */
2009-03-11 03:01:00 -03:00
int au0828_analog_register ( struct au0828_dev * dev ,
struct usb_interface * interface ) ;
2009-03-11 03:00:40 -03:00
int au0828_analog_stream_disable ( struct au0828_dev * d ) ;
void au0828_analog_unregister ( struct au0828_dev * dev ) ;
2008-04-18 21:34:00 -03:00
/* ----------------------------------------------------------- */
/* au0828-dvb.c */
extern int au0828_dvb_register ( struct au0828_dev * dev ) ;
extern void au0828_dvb_unregister ( struct au0828_dev * dev ) ;
2008-04-18 21:39:11 -03:00
2010-05-29 17:18:45 -03:00
/* au0828-vbi.c */
extern struct videobuf_queue_ops au0828_vbi_qops ;
2008-04-18 21:39:11 -03:00
# define dprintk(level, fmt, arg...)\
2008-04-25 19:06:03 -03:00
do { if ( au0828_debug & level ) \
2008-04-18 21:39:11 -03:00
printk ( KERN_DEBUG DRIVER_NAME " /0: " fmt , # # arg ) ; \
} while ( 0 )