From 785193038155c17372457bbf37b241b4893f9698 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:40 -0400 Subject: au0828: add support for analog functionality in bridge From: Devin Heitmueller Add support for the analog functionality found in the au0828 bridge Thanks to Michael Krufky and Steven Toth for providing sample hardware, engineering level support, and testing. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/au0828.h | 174 ++++++++++++++++++++++++++++-- 1 file changed, 167 insertions(+), 7 deletions(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 9d6a1161d..3b8e3e913 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -24,6 +24,10 @@ #include #include +/* Analog */ +#include +#include + /* DVB */ #include "demux.h" #include "dmxdev.h" @@ -39,8 +43,48 @@ #define URB_COUNT 16 #define URB_BUFSIZE (0xe522) +/* 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 */ +#define AU0828_ISO_PACKETS_PER_URB 10 +#define AU0828_ISO_MAX_FRAME_SIZE (3 * 1024) +#define AU0828_ISO_BUFFER_SIZE (AU0828_ISO_PACKETS_PER_URB * AU0828_ISO_MAX_FRAME_SIZE) + +#define AU0828_MIN_BUF 4 +#define AU0828_DEF_BUF 8 + +#define AU0828_MAX_IMAGES 10 +#define AU0828_FRAME_SIZE (1028 * 1024 * 4) +#define AU0828_URB_TIMEOUT msecs_to_jiffies(AU0828_MAX_ISO_BUFS * AU0828_ISO_PACKETS_PER_URB) + +#define AU0828_MAX_INPUT 4 + +enum au0828_itype { + AU0828_VMUX_COMPOSITE = 1, + 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); +}; + struct au0828_board { char *name; + struct au0828_input input[AU0828_MAX_INPUT]; + }; struct au0828_dvb { @@ -55,6 +99,83 @@ struct au0828_dvb { int feeding; }; +enum au0828_stream_state { + STREAM_OFF, + STREAM_INTERRUPT, + STREAM_ON +}; + +#define AUVI_INPUT(nr) (&au0828_boards[dev->board].input[nr]) + +/* device state */ +enum au0828_dev_state { + DEV_INITIALIZED = 0x01, + DEV_DISCONNECTED = 0x02, + DEV_MISCONFIGURED = 0x04 +}; + +struct au0828_fh { + struct au0828_dev *dev; + unsigned int stream_on:1; /* Locks streams */ + struct videobuf_queue vb_vidq; + 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 */ + struct au0828_buffer *buf; + + /* 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; +}; + struct au0828_dev { struct mutex mutex; struct usb_device *usbdev; @@ -70,16 +191,49 @@ struct au0828_dev { /* Digital */ struct au0828_dvb dvb; + /* Analog */ + struct list_head au0828list; + int users; + unsigned int stream_on:1; /* Locks streams */ + struct video_device *vdev; + struct video_device *vbi_dev; + int width; + int height; + 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; + 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 */ + /* USB / URB Related */ int urb_streaming; struct urb *urbs[URB_COUNT]; - -}; - -struct au0828_buff { - struct au0828_dev *dev; - struct urb *purb; - struct list_head buff_list; }; /* ----------------------------------------------------------- */ @@ -114,6 +268,12 @@ extern int au0828_i2c_unregister(struct au0828_dev *dev); extern void au0828_call_i2c_clients(struct au0828_dev *dev, unsigned int cmd, void *arg); +/* ----------------------------------------------------------- */ +/* au0828-video.c */ +int au0828_analog_register(struct au0828_dev *dev); +int au0828_analog_stream_disable(struct au0828_dev *d); +void au0828_analog_unregister(struct au0828_dev *dev); + /* ----------------------------------------------------------- */ /* au0828-dvb.c */ extern int au0828_dvb_register(struct au0828_dev *dev); -- cgit v1.2.3 From 3c1c7dc1d05a143350b6c3467e6bf52144189db0 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:00:47 -0400 Subject: au0828: Rework the way the analog video binding occurs From: Devin Heitmueller Rework the way boards are managed so that we can change the board description based on the Hauppauge eeprom (modeled after cx88-cards.c). Also, make sure that we don't load the analog stack if there are no analog inputs defined in the board profile. Thanks to Michael Krufky for providing information on the various ways different Hauppauge boards can be configured. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/au0828.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 3b8e3e913..2f48ec213 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -83,6 +83,8 @@ struct au0828_input { struct au0828_board { char *name; + unsigned int tuner_type; + unsigned char tuner_addr; struct au0828_input input[AU0828_MAX_INPUT]; }; @@ -105,7 +107,7 @@ enum au0828_stream_state { STREAM_ON }; -#define AUVI_INPUT(nr) (&au0828_boards[dev->board].input[nr]) +#define AUVI_INPUT(nr) (dev->board.input[nr]) /* device state */ enum au0828_dev_state { @@ -179,7 +181,8 @@ struct au0828_dmaqueue { struct au0828_dev { struct mutex mutex; struct usb_device *usbdev; - int board; + int boardnr; + struct au0828_board board; u8 ctrlmsg[64]; /* I2C */ -- cgit v1.2.3 From 954299a93e6d076c844770136c359f48049b3d88 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:01:00 -0400 Subject: au0828: properly handle missing analog USB endpoint From: Devin Heitmueller Move the setup of the analog isoc handler into au0828-video.c, so it does not occur if there is not an .input section defined for the board. Also fixes a case where if there is an input section but the board does not actually have analog support, the digital support will continue to work as expected. Thanks to Michael Krufky for providing sample hardware of various configurations to test with. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/au0828.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 2f48ec213..d2e54c8e1 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -273,7 +273,8 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev, /* ----------------------------------------------------------- */ /* au0828-video.c */ -int au0828_analog_register(struct au0828_dev *dev); +int au0828_analog_register(struct au0828_dev *dev, + struct usb_interface *interface); int au0828_analog_stream_disable(struct au0828_dev *d); void au0828_analog_unregister(struct au0828_dev *dev); -- cgit v1.2.3 From 3f7bd4e3eef22d1416780db3ae3300c16bc21961 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:01:01 -0400 Subject: au0828: properly handle non-existent analog inputs From: Devin Heitmueller It is not valid to look for dev->board.input == NULL to detect an undefined analog configuration section, since it is a member of the struct and not a pointer (hence it will *always* be non-NULL). Do the check based on whether the first input is actually a valid input type instead. Thanks to Michael Krufky for providing sample hardware of various configurations to test with. Priority: normal Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky --- linux/drivers/media/video/au0828/au0828.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index d2e54c8e1..590d15e46 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -66,7 +66,8 @@ #define AU0828_MAX_INPUT 4 enum au0828_itype { - AU0828_VMUX_COMPOSITE = 1, + AU0828_VMUX_UNDEFINED = 0, + AU0828_VMUX_COMPOSITE, AU0828_VMUX_SVIDEO, AU0828_VMUX_CABLE, AU0828_VMUX_TELEVISION, -- cgit v1.2.3 From 1c6b90fa7084d63133a8418affbf10267f674abb Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 02:01:04 -0400 Subject: au0828: Convert to use v4l2_device/subdev framework From: Devin Heitmueller Convert over to using the new subdev framework for the au0828 bridge. This includes using the new i2c probing mechanism. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/video/au0828/au0828.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 590d15e46..876b18cfb 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -27,6 +27,7 @@ /* Analog */ #include #include +#include /* DVB */ #include "demux.h" @@ -188,7 +189,7 @@ struct au0828_dev { /* I2C */ struct i2c_adapter i2c_adap; - struct i2c_algo_bit_data i2c_algo; + struct i2c_algorithm i2c_algo; struct i2c_client i2c_client; u32 i2c_rc; @@ -197,6 +198,7 @@ struct au0828_dev { /* Analog */ struct list_head au0828list; + struct v4l2_device v4l2_dev; int users; unsigned int stream_on:1; /* Locks streams */ struct video_device *vdev; -- cgit v1.2.3 From 3381b31112a4b0a5321384bf4e339bc12a103731 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 17:48:52 -0400 Subject: au0828/au8522: Codingstyle fixes From: Devin Heitmueller Take a pass over all of the au0828/au8522 files and cleanup all the codingstyle issues. This patch does not make *any* functional change to the code. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/video/au0828/au0828.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 876b18cfb..6d9bd454e 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -54,16 +54,10 @@ /* Defination for AU0828 USB transfer */ #define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */ #define AU0828_ISO_PACKETS_PER_URB 10 -#define AU0828_ISO_MAX_FRAME_SIZE (3 * 1024) -#define AU0828_ISO_BUFFER_SIZE (AU0828_ISO_PACKETS_PER_URB * AU0828_ISO_MAX_FRAME_SIZE) #define AU0828_MIN_BUF 4 #define AU0828_DEF_BUF 8 -#define AU0828_MAX_IMAGES 10 -#define AU0828_FRAME_SIZE (1028 * 1024 * 4) -#define AU0828_URB_TIMEOUT msecs_to_jiffies(AU0828_MAX_ISO_BUFS * AU0828_ISO_PACKETS_PER_URB) - #define AU0828_MAX_INPUT 4 enum au0828_itype { -- cgit v1.2.3 From 90392426eb668074c09657baee8b2f4cf06c8b5e Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 15 Mar 2009 19:01:53 -0400 Subject: au0828: finish videodev/subdev conversion From: Devin Heitmueller Per Hans Verkuil instruction, remove the deprecated attach_inform/detach_inform routines, and convert over the i2c calls to subdev calls. Thanks to Hans Verkuil for providing feedback on the au0828 analog support. Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/video/au0828/au0828.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 6d9bd454e..6ed1a6129 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -265,8 +265,6 @@ extern void au0828_card_setup(struct au0828_dev *dev); /* au0828-i2c.c */ extern int au0828_i2c_register(struct au0828_dev *dev); extern int au0828_i2c_unregister(struct au0828_dev *dev); -extern void au0828_call_i2c_clients(struct au0828_dev *dev, - unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ /* au0828-video.c */ -- cgit v1.2.3 From 41a918183d70414e601306083d030ed58b5b8bd7 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Tue, 31 Mar 2009 23:11:31 -0400 Subject: au0828: make i2c clock speed per-board configurable From: Devin Heitmueller Setup the i2c clock speed to be definable on a per-board basis. This allows us to explicitly set the clock speed to 30 KHz on the 950q, and also gets rid of code which sets it on a basis of what chip the i2c master is talking to at any given time (which could have caused issues because i2c slaves should never receive commands at a clock higher than their supported clock speed). Priority: normal Signed-off-by: Devin Heitmueller --- linux/drivers/media/video/au0828/au0828.h | 1 + 1 file changed, 1 insertion(+) (limited to 'linux/drivers/media/video/au0828/au0828.h') diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 6ed1a6129..b977915ef 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/drivers/media/video/au0828/au0828.h @@ -81,6 +81,7 @@ struct au0828_board { char *name; unsigned int tuner_type; unsigned char tuner_addr; + unsigned char i2c_clk_divider; struct au0828_input input[AU0828_MAX_INPUT]; }; -- cgit v1.2.3