#include "au0828.h"
#include "au0828-cards.h"
#include "au8522.h"
+#include "media/tuner.h"
+#include "media/v4l2-common.h"
void hvr950q_cs5340_audio(void *priv, int enable)
{
struct au0828_board au0828_boards[] = {
[AU0828_BOARD_UNKNOWN] = {
.name = "Unknown board",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_HVR850] = {
.name = "Hauppauge HVR850",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
.name = "Hauppauge HVR950Q",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
.input = {
{
.type = AU0828_VMUX_TELEVISION,
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
.name = "Hauppauge HVR950Q rev xxF8",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
};
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
struct tveeprom tv;
tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
+ dev->board.tuner_type = tv.tuner_type;
/* Make sure we support the board model */
switch (tv.model) {
void au0828_card_setup(struct au0828_dev *dev)
{
static u8 eeprom[256];
+ struct tuner_setup tun_setup;
+ unsigned int mode_mask = T_ANALOG_TV |
+ T_DIGITAL_TV;
dprintk(1, "%s()\n", __func__);
+ memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
+
if (dev->i2c_rc == 0) {
dev->i2c_client.addr = 0xa0 >> 1;
tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
}
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
hauppauge_eeprom(dev, eeprom+0xa0);
break;
}
+
+ if (dev->board.input != NULL) {
+ /* Load the analog demodulator driver (note this would need to
+ be abstracted out if we ever need to support a different
+ demod) */
+ request_module("au8522");
+ }
+
+ /* Setup tuners */
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ /* Load the tuner module, which does the attach */
+ request_module("tuner");
+
+ tun_setup.mode_mask = mode_mask;
+ tun_setup.type = dev->board.tuner_type;
+ tun_setup.addr = dev->board.tuner_addr;
+ tun_setup.tuner_callback = au0828_tuner_callback;
+ au0828_call_i2c_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
}
/*
{
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
/* Digital TV */
au0828_dvb_unregister(dev);
- au0828_analog_unregister(dev);
+ if (dev->board.input != NULL)
+ au0828_analog_unregister(dev);
/* I2C */
au0828_i2c_unregister(dev);
mutex_init(&dev->mutex);
mutex_init(&dev->dvb.lock);
dev->usbdev = usbdev;
- dev->board = id->driver_info;
+ dev->boardnr = id->driver_info;
usb_set_intfdata(interface, dev);
au0828_card_setup(dev);
/* Analog TV */
- au0828_analog_register(dev);
+ if (dev->board.input != NULL)
+ au0828_analog_register(dev);
/* Digital TV */
au0828_dvb_register(dev);
printk(KERN_INFO "Registered device AU0828 [%s]\n",
- au0828_boards[dev->board].name == NULL ? "Unset" :
- au0828_boards[dev->board].name);
+ dev->board.name == NULL ? "Unset" : dev->board.name);
return 0;
}
dprintk(1, "%s()\n", __func__);
/* init frontend */
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
dvb->frontend = dvb_attach(au8522_attach,
memset(cap, 0, sizeof(*cap));
strlcpy(cap->driver, "au0828", sizeof(cap->driver));
- strlcpy(cap->card, au0828_boards[dev->board].name, sizeof(cap->card));
+ strlcpy(cap->card, dev->board.name, sizeof(cap->card));
strlcpy(cap->bus_info, dev->usbdev->dev.bus_id, sizeof(cap->bus_info));
cap->version = AU0828_VERSION_CODE;
if(tmp > AU0828_MAX_INPUT)
return -EINVAL;
- if(AUVI_INPUT(tmp)->type == 0)
+ if(AUVI_INPUT(tmp).type == 0)
return -EINVAL;
memset(input, 0, sizeof(*input));
input->index = tmp;
- strcpy(input->name, inames[AUVI_INPUT(tmp)->type]);
- if((AUVI_INPUT(tmp)->type == AU0828_VMUX_TELEVISION) ||
- (AUVI_INPUT(tmp)->type == AU0828_VMUX_CABLE))
+ strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
+ if((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
+ (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
input->type |= V4L2_INPUT_TYPE_TUNER;
else
input->type |= V4L2_INPUT_TYPE_CAMERA;
index);
if(index >= AU0828_MAX_INPUT)
return -EINVAL;
- if(AUVI_INPUT(index)->type == 0)
+ if(AUVI_INPUT(index).type == 0)
return -EINVAL;
dev->ctrl_input = index;
- switch(AUVI_INPUT(index)->type) {
+ switch(AUVI_INPUT(index).type) {
case AU0828_VMUX_SVIDEO:
{
dev->input_type = AU0828_VMUX_SVIDEO;
;
}
- route.input = AUVI_INPUT(index)->vmux;
+ route.input = AUVI_INPUT(index).vmux;
route.output = 0;
au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
for (i = 0; i < AU0828_MAX_INPUT; i++) {
int enable = 0;
- if (AUVI_INPUT(i)->audio_setup == NULL) {
+ if (AUVI_INPUT(i).audio_setup == NULL) {
continue;
}
else
enable = 0;
if (enable) {
- (AUVI_INPUT(i)->audio_setup)(dev, enable);
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
} else {
/* Make sure we leave it turned on if some
other input is routed to this callback */
- if ((AUVI_INPUT(i)->audio_setup) !=
- ((AUVI_INPUT(index)->audio_setup))) {
- (AUVI_INPUT(i)->audio_setup)(dev, enable);
+ if ((AUVI_INPUT(i).audio_setup) !=
+ ((AUVI_INPUT(index).audio_setup))) {
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
}
}
}
- route.input = AUVI_INPUT(index)->amux;
+ route.input = AUVI_INPUT(index).amux;
au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
&route);
return 0;
}
for (i = 0; i < AU0828_MAX_INPUT; i++) {
- if (AUVI_INPUT(i)->audio_setup == NULL) {
+ if (AUVI_INPUT(i).audio_setup == NULL) {
continue;
}
- (AUVI_INPUT(i)->audio_setup)(dev, 0);
+ (AUVI_INPUT(i).audio_setup)(dev, 0);
}
mutex_lock(&dev->lock);
dprintk(1, "au0828_analog_register called!\n");
- /* Load the analog demodulator driver (note this would need to be
- abstracted out if we ever need to support a different demod) */
- request_module("au8522");
-
- /* Load the tuner module, which results in i2c enumeration and
- attachment of whatever tuner is on the bus */
- request_module("tuner");
-
init_waitqueue_head(&dev->open);
spin_lock_init(&dev->slock);
mutex_init(&dev->lock);
struct au0828_board {
char *name;
+ unsigned int tuner_type;
+ unsigned char tuner_addr;
struct au0828_input input[AU0828_MAX_INPUT];
};
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 {
struct au0828_dev {
struct mutex mutex;
struct usb_device *usbdev;
- int board;
+ int boardnr;
+ struct au0828_board board;
u8 ctrlmsg[64];
/* I2C */