V4L/DVB: em28xx: add em286x/tvp5150 reference design
[safe/jmp/linux-2.6] / drivers / media / video / em28xx / em28xx.h
index 3e9ca78..eec1291 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/videodev2.h>
 #include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
 
 #include <linux/i2c.h>
 #include <linux/mutex.h>
@@ -57,7 +58,7 @@
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950   16
 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO      17
 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2        18
-#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA  19
+#define EM2860_BOARD_SAA711X_REFERENCE_DESIGN  19
 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600   20
 #define EM2800_BOARD_GRABBEEX_USB2800           21
 #define EM2750_BOARD_UNKNOWN                     22
 #define EM2820_BOARD_HERCULES_SMART_TV_USB2      26
 #define EM2820_BOARD_PINNACLE_USB_2_FM1216ME     27
 #define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28
-#define EM2820_BOARD_PINNACLE_DVC_100            29
+#define EM2860_BOARD_TVP5150_REFERENCE_DESIGN    29
 #define EM2820_BOARD_VIDEOLOGY_20K14XUSB         30
 #define EM2821_BOARD_USBGEAR_VD204               31
 #define EM2821_BOARD_SUPERCOMP_USB_2             32
-#define EM2821_BOARD_PROLINK_PLAYTV_USB2         33
 #define EM2860_BOARD_TERRATEC_HYBRID_XS                  34
 #define EM2860_BOARD_TYPHOON_DVD_MAKER           35
 #define EM2860_BOARD_NETGMBH_CAM                 36
 #define EM2882_BOARD_KWORLD_VS_DVBT              54
 #define EM2882_BOARD_TERRATEC_HYBRID_XS                  55
 #define EM2882_BOARD_PINNACLE_HYBRID_PRO         56
-#define EM2883_BOARD_KWORLD_HYBRID_A316                  57
+#define EM2883_BOARD_KWORLD_HYBRID_330U                  57
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU     58
-#define EM2874_BOARD_PINNACLE_PCTV_80E           59
+#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850     60
+#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2    61
+#define EM2820_BOARD_GADMEI_TVR200               62
+#define EM2860_BOARD_KAIOMY_TVNPC_U2              63
+#define EM2860_BOARD_EASYCAP                      64
+#define EM2820_BOARD_IODATA_GVMVP_SZ             65
+#define EM2880_BOARD_EMPIRE_DUAL_TV              66
+#define EM2860_BOARD_TERRATEC_GRABBY             67
+#define EM2860_BOARD_TERRATEC_AV350              68
+#define EM2882_BOARD_KWORLD_ATSC_315U            69
+#define EM2882_BOARD_EVGA_INDTUBE                70
+#define EM2820_BOARD_SILVERCREST_WEBCAM           71
+#define EM2861_BOARD_GADMEI_UTV330PLUS           72
+#define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
+#define EM2800_BOARD_VC211A                      74
+#define EM2882_BOARD_DIKOM_DK300                 75
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
 #define EM28XX_BOARD_NOT_VALIDATED 1
 #define EM28XX_BOARD_VALIDATED    0
 
+/* Params for em28xx_cmd() audio */
+#define EM28XX_START_AUDIO      1
+#define EM28XX_STOP_AUDIO       0
+
 /* maximum number of em28xx boards */
 #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
 
 #define EM28XX_NUM_BUFS 5
 
 /* number of packets for each buffer
-   windows requests only 40 packets .. so we better do the same
+   windows requests only 64 packets .. so we better do the same
    this is what I found out for all alternate numbers there!
  */
-#define EM28XX_NUM_PACKETS 40
-
-/* default alternate; 0 means choose the best */
-#define EM28XX_PINOUT 0
+#define EM28XX_NUM_PACKETS 64
 
 #define EM28XX_INTERLACED_DEFAULT 1
 
 */
 
 /* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT       msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+#define EM28XX_URB_TIMEOUT \
+                       msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
 
 /* time in msecs to wait for i2c writes to finish */
 #define EM2800_I2C_WRITE_TIMEOUT 20
 
 enum em28xx_mode {
-       EM28XX_MODE_UNDEFINED,
+       EM28XX_SUSPEND,
        EM28XX_ANALOG_MODE,
        EM28XX_DIGITAL_MODE,
 };
@@ -198,7 +215,8 @@ struct em28xx_usb_isoc_ctl {
        int                             tmp_buf_len;
 
                /* Stores already requested buffers */
-       struct em28xx_buffer            *buf;
+       struct em28xx_buffer            *vid_buf;
+       struct em28xx_buffer            *vbi_buf;
 
                /* Stores the number of received fields */
        int                             nfields;
@@ -208,9 +226,12 @@ struct em28xx_usb_isoc_ctl {
 
 };
 
+/* Struct to enumberate video formats */
 struct em28xx_fmt {
        char  *name;
        u32   fourcc;          /* v4l2 format id */
+       int   depth;
+       int   reg;
 };
 
 /* buffer for one video frame */
@@ -297,11 +318,36 @@ enum em28xx_amux {
 };
 
 enum em28xx_aout {
+       /* AC97 outputs */
        EM28XX_AOUT_MASTER = 1 << 0,
        EM28XX_AOUT_LINE   = 1 << 1,
        EM28XX_AOUT_MONO   = 1 << 2,
        EM28XX_AOUT_LFE    = 1 << 3,
        EM28XX_AOUT_SURR   = 1 << 4,
+
+       /* PCM IN Mixer - used by AC97_RECORD_SELECT register */
+       EM28XX_AOUT_PCM_IN = 1 << 7,
+
+       /* Bits 10-8 are used to indicate the PCM IN record select */
+       EM28XX_AOUT_PCM_MIC_PCM = 0 << 8,
+       EM28XX_AOUT_PCM_CD      = 1 << 8,
+       EM28XX_AOUT_PCM_VIDEO   = 2 << 8,
+       EM28XX_AOUT_PCM_AUX     = 3 << 8,
+       EM28XX_AOUT_PCM_LINE    = 4 << 8,
+       EM28XX_AOUT_PCM_STEREO  = 5 << 8,
+       EM28XX_AOUT_PCM_MONO    = 6 << 8,
+       EM28XX_AOUT_PCM_PHONE   = 7 << 8,
+};
+
+static inline int ac97_return_record_select(int a_out)
+{
+       return (a_out & 0x700) >> 8;
+}
+
+struct em28xx_reg_seq {
+       int reg;
+       unsigned char val, mask;
+       int sleep;
 };
 
 struct em28xx_input {
@@ -309,20 +355,27 @@ struct em28xx_input {
        unsigned int vmux;
        enum em28xx_amux amux;
        enum em28xx_aout aout;
+       struct em28xx_reg_seq *gpio;
 };
 
 #define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
 
 enum em28xx_decoder {
-       EM28XX_NODECODER,
+       EM28XX_NODECODER = 0,
        EM28XX_TVP5150,
        EM28XX_SAA711X,
 };
 
-struct em28xx_reg_seq {
-       int reg;
-       unsigned char val, mask;
-       int sleep;
+enum em28xx_sensor {
+       EM28XX_NOSENSOR = 0,
+       EM28XX_MT9V011,
+       EM28XX_MT9M001,
+       EM28XX_MT9M111,
+};
+
+enum em28xx_adecoder {
+       EM28XX_NOADECODER = 0,
+       EM28XX_TVAUDIO,
 };
 
 struct em28xx_board {
@@ -334,21 +387,32 @@ struct em28xx_board {
        /* i2c flags */
        unsigned int tda9887_conf;
 
+       /* GPIO sequences */
+       struct em28xx_reg_seq *dvb_gpio;
+       struct em28xx_reg_seq *suspend_gpio;
+       struct em28xx_reg_seq *tuner_gpio;
+       struct em28xx_reg_seq *mute_gpio;
+
        unsigned int is_em2800:1;
        unsigned int has_msp34xx:1;
        unsigned int mts_firmware:1;
        unsigned int max_range_640_480:1;
        unsigned int has_dvb:1;
        unsigned int has_snapshot_button:1;
+       unsigned int is_webcam:1;
        unsigned int valid:1;
+       unsigned int has_ir_i2c:1;
 
        unsigned char xclk, i2c_speed;
+       unsigned char radio_addr;
+       unsigned short tvaudio_addr;
 
        enum em28xx_decoder decoder;
+       enum em28xx_adecoder adecoder;
 
        struct em28xx_input       input[MAX_EM28XX_INPUT];
        struct em28xx_input       radio;
-       IR_KEYTAB_TYPE            *ir_codes;
+       struct ir_scancode_table  *ir_codes;
 };
 
 struct em28xx_eeprom {
@@ -381,6 +445,10 @@ enum em28xx_dev_state {
 #define EM28XX_AUDIO   0x10
 #define EM28XX_DVB     0x20
 
+/* em28xx resource types (used for res_get/res_lock etc */
+#define EM28XX_RESOURCE_VIDEO 0x01
+#define EM28XX_RESOURCE_VBI   0x02
+
 struct em28xx_audio {
        char name[50];
        char *transfer_buffer[EM28XX_AUDIO_BUFS];
@@ -392,7 +460,7 @@ struct em28xx_audio {
        unsigned int hwptr_done_capture;
        struct snd_card            *sndcard;
 
-       int users, shutdown;
+       int users;
        enum em28xx_stream_state capture_stream;
        spinlock_t slock;
 };
@@ -401,10 +469,11 @@ struct em28xx;
 
 struct em28xx_fh {
        struct em28xx *dev;
-       unsigned int  stream_on:1;      /* Locks streams */
        int           radio;
+       unsigned int  resources;
 
        struct videobuf_queue        vb_vidq;
+       struct videobuf_queue        vb_vbiq;
 
        enum v4l2_buf_type           type;
 };
@@ -417,23 +486,30 @@ struct em28xx {
        int devno;              /* marks the number of this device */
        enum em28xx_chip_id chip_id;
 
+       struct v4l2_device v4l2_dev;
        struct em28xx_board board;
 
-       unsigned int stream_on:1;       /* Locks streams */
+       /* Webcam specific fields */
+       enum em28xx_sensor em28xx_sensor;
+       int sensor_xres, sensor_yres;
+       int sensor_xtal;
+
+       /* Allows progressive (e. g. non-interlaced) mode */
+       int progressive;
+
+       /* Vinmode/Vinctl used at the driver */
+       int vinmode, vinctl;
+
        unsigned int has_audio_class:1;
        unsigned int has_alsa_audio:1;
 
+       struct em28xx_fmt *format;
+
        struct em28xx_IR *ir;
 
        /* Some older em28xx chips needs a waiting time after writing */
        unsigned int wait_after_write;
 
-       /* GPIO sequences for analog and digital mode */
-       struct em28xx_reg_seq *analog_gpio, *digital_gpio;
-
-       /* GPIO sequences for tuner callbacks */
-       struct em28xx_reg_seq *tuner_gpio;
-
        struct list_head        devlist;
 
        u32 i2s_speed;          /* I2S speed for audio digital stream */
@@ -468,12 +544,19 @@ struct em28xx {
        unsigned long i2c_hash; /* i2c devicelist hash -
                                   for boards with generic ID */
 
-       struct em28xx_audio *adev;
+       struct em28xx_audio adev;
 
        /* states */
        enum em28xx_dev_state state;
        enum em28xx_io_method io;
 
+       /* vbi related state tracking */
+       int capture_type;
+       int vbi_read;
+       unsigned char cur_field;
+       unsigned int vbi_width;
+       unsigned int vbi_height; /* lines per field */
+
        struct work_struct         request_module_wk;
 
        /* locks */
@@ -485,10 +568,14 @@ struct em28xx {
        struct video_device *vbi_dev;
        struct video_device *radio_dev;
 
+       /* resources in use */
+       unsigned int resources;
+
        unsigned char eedata[256];
 
        /* Isoc control struct */
        struct em28xx_dmaqueue vidq;
+       struct em28xx_dmaqueue vbiq;
        struct em28xx_usb_isoc_ctl isoc_ctl;
        spinlock_t slock;
 
@@ -499,7 +586,8 @@ struct em28xx {
        int num_alt;            /* Number of alternative settings */
        unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
        struct urb *urb[EM28XX_NUM_BUFS];       /* urb for isoc transfers */
-       char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
+       char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
+                                                  transfer */
        char urb_buf[URB_MAX_CTRL_SIZE];        /* urb control msg buffer */
 
        /* helper funcs that call usb_control_msg */
@@ -526,6 +614,9 @@ struct em28xx {
        struct delayed_work sbutton_query_work;
 
        struct em28xx_dvb *dvb;
+
+       /* I2C keyboard data */
+       struct IR_i2c_init_data init_data;
 };
 
 struct em28xx_ops {
@@ -537,11 +628,9 @@ struct em28xx_ops {
 };
 
 /* Provided by em28xx-i2c.c */
-
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
 void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
+int  em28xx_i2c_register(struct em28xx *dev);
+int  em28xx_i2c_unregister(struct em28xx *dev);
 
 /* Provided by em28xx-core.c */
 
@@ -557,25 +646,39 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
                          int len);
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
 int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
+int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
+                                u8 bitmask);
+
+int em28xx_read_ac97(struct em28xx *dev, u8 reg);
+int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);
 
 int em28xx_audio_analog_set(struct em28xx *dev);
 int em28xx_audio_setup(struct em28xx *dev);
 
 int em28xx_colorlevels_set_default(struct em28xx *dev);
 int em28xx_capture_start(struct em28xx *dev, int start);
-int em28xx_outfmt_set_yuv422(struct em28xx *dev);
+int em28xx_vbi_supported(struct em28xx *dev);
+int em28xx_set_outfmt(struct em28xx *dev);
 int em28xx_resolution_set(struct em28xx *dev);
 int em28xx_set_alternate(struct em28xx *dev);
 int em28xx_init_isoc(struct em28xx *dev, int max_packets,
                     int num_bufs, int max_pkt_size,
                     int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
 void em28xx_uninit_isoc(struct em28xx *dev);
+int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
 int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
 int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
-
-/* Provided by em28xx-video.c */
+void em28xx_wake_i2c(struct em28xx *dev);
+void em28xx_remove_from_devlist(struct em28xx *dev);
+void em28xx_add_into_devlist(struct em28xx *dev);
 int em28xx_register_extension(struct em28xx_ops *dev);
 void em28xx_unregister_extension(struct em28xx_ops *dev);
+void em28xx_init_extension(struct em28xx *dev);
+void em28xx_close_extension(struct em28xx *dev);
+
+/* Provided by em28xx-video.c */
+int em28xx_register_analog_devices(struct em28xx *dev);
+void em28xx_release_analog_resources(struct em28xx *dev);
 
 /* Provided by em28xx-cards.c */
 extern int em2800_variant_detect(struct usb_device *udev, int model);
@@ -584,20 +687,26 @@ extern void em28xx_card_setup(struct em28xx *dev);
 extern struct em28xx_board em28xx_boards[];
 extern struct usb_device_id em28xx_id_table[];
 extern const unsigned int em28xx_bcount;
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
+void em28xx_register_i2c_ir(struct em28xx *dev);
 int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
+void em28xx_release_resources(struct em28xx *dev);
 
 /* Provided by em28xx-input.c */
 int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
                                     u32 *ir_raw);
+int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key,
+                                    u32 *ir_raw);
 void em28xx_register_snapshot_button(struct em28xx *dev);
 void em28xx_deregister_snapshot_button(struct em28xx *dev);
 
 int em28xx_ir_init(struct em28xx *dev);
 int em28xx_ir_fini(struct em28xx *dev);
 
+/* Provided by em28xx-vbi.c */
+extern struct videobuf_queue_ops em28xx_vbi_qops;
+
 /* printk macros */
 
 #define em28xx_err(fmt, arg...) do {\
@@ -617,7 +726,7 @@ int em28xx_ir_fini(struct em28xx *dev);
 static inline int em28xx_compression_disable(struct em28xx *dev)
 {
        /* side effect of disabling scaler and mixer */
-       return em28xx_write_regs(dev, EM28XX_R26_COMPR, "\x00", 1);
+       return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00);
 }
 
 static inline int em28xx_contrast_get(struct em28xx *dev)
@@ -689,17 +798,23 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val)
 /*FIXME: maxw should be dependent of alt mode */
 static inline unsigned int norm_maxw(struct em28xx *dev)
 {
-       if (dev->board.max_range_640_480)
+       if (dev->board.is_webcam)
+               return dev->sensor_xres;
+
+       if (dev->board.max_range_640_480 || dev->board.is_em2800)
                return 640;
-       else
-               return 720;
+
+       return 720;
 }
 
 static inline unsigned int norm_maxh(struct em28xx *dev)
 {
+       if (dev->board.is_webcam)
+               return dev->sensor_yres;
+
        if (dev->board.max_range_640_480)
                return 480;
-       else
-               return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
+
+       return (dev->norm & V4L2_STD_625_50) ? 576 : 480;
 }
 #endif