Commit d5b973d7 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] v4l: #7 - saa7134 driver update

From: Gerd Knorr <kraxel@bytesex.org>

Yet another big one (due to not being updated for a long time) -- saa7134
driver update.  Changes:

 * various bugfixes / cleanups.

 * new cards added to the cardlist.

 * started support for saa7133/35 chips.

 * make the driver check pci quirks.
parent 2b270c40
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
static char name_mute[] = "mute"; static char name_mute[] = "mute";
static char name_radio[] = "Radio"; static char name_radio[] = "Radio";
static char name_tv[] = "Television"; static char name_tv[] = "Television";
static char name_tv_mono[] = "TV (mono only)";
static char name_comp1[] = "Composite1"; static char name_comp1[] = "Composite1";
static char name_comp2[] = "Composite2"; static char name_comp2[] = "Composite2";
static char name_svideo[] = "S-Video"; static char name_svideo[] = "S-Video";
...@@ -61,6 +62,11 @@ struct saa7134_board saa7134_boards[] = { ...@@ -61,6 +62,11 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 1, .vmux = 1,
.amux = TV, .amux = TV,
.tv = 1, .tv = 1,
},{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.tv = 1,
}}, }},
}, },
[SAA7134_BOARD_FLYVIDEO3000] = { [SAA7134_BOARD_FLYVIDEO3000] = {
...@@ -68,27 +74,39 @@ struct saa7134_board saa7134_boards[] = { ...@@ -68,27 +74,39 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyVIDEO3000", .name = "LifeView FlyVIDEO3000",
.audio_clock = 0x00200000, .audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL, .tuner_type = TUNER_PHILIPS_PAL,
.gpiomask = 0xe000,
.inputs = {{ .inputs = {{
.name = name_tv, .name = name_tv,
.vmux = 1, .vmux = 1,
.amux = TV, .amux = TV,
.gpio = 0x8000,
.tv = 1,
},{
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.gpio = 0x0000,
.tv = 1, .tv = 1,
},{ },{
.name = name_comp1, .name = name_comp1,
.vmux = 0, .vmux = 0,
.amux = LINE1, .amux = LINE2,
.gpio = 0x4000,
},{ },{
.name = name_comp2, .name = name_comp2,
.vmux = 3, .vmux = 3,
.amux = LINE1, .amux = LINE2,
.gpio = 0x4000,
},{ },{
.name = name_svideo, .name = name_svideo,
.vmux = 8, .vmux = 8,
.amux = LINE1, .amux = LINE2,
.gpio = 0x4000,
}}, }},
.radio = { .radio = {
.name = name_radio, .name = name_radio,
.amux = LINE2, .amux = LINE2,
.gpio = 0x2000,
}, },
}, },
[SAA7134_BOARD_FLYVIDEO2000] = { [SAA7134_BOARD_FLYVIDEO2000] = {
...@@ -96,7 +114,7 @@ struct saa7134_board saa7134_boards[] = { ...@@ -96,7 +114,7 @@ struct saa7134_board saa7134_boards[] = {
.name = "LifeView FlyVIDEO2000", .name = "LifeView FlyVIDEO2000",
.audio_clock = 0x00200000, .audio_clock = 0x00200000,
.tuner_type = TUNER_LG_PAL_NEW_TAPC, .tuner_type = TUNER_LG_PAL_NEW_TAPC,
.gpiomask = 0x6000, .gpiomask = 0xe000,
.inputs = {{ .inputs = {{
.name = name_tv, .name = name_tv,
.vmux = 1, .vmux = 1,
...@@ -122,10 +140,12 @@ struct saa7134_board saa7134_boards[] = { ...@@ -122,10 +140,12 @@ struct saa7134_board saa7134_boards[] = {
.radio = { .radio = {
.name = name_radio, .name = name_radio,
.amux = LINE2, .amux = LINE2,
.gpio = 0x2000,
}, },
.mute = { .mute = {
.name = name_mute, .name = name_mute,
.amux = LINE1, .amux = LINE2,
.gpio = 0x8000,
}, },
}, },
[SAA7134_BOARD_EMPRESS] = { [SAA7134_BOARD_EMPRESS] = {
...@@ -190,7 +210,7 @@ struct saa7134_board saa7134_boards[] = { ...@@ -190,7 +210,7 @@ struct saa7134_board saa7134_boards[] = {
.tv = 1, .tv = 1,
},{ },{
/* workaround for problems with normal TV sound */ /* workaround for problems with normal TV sound */
.name = "TV (mono only)", .name = name_tv_mono,
.vmux = 1, .vmux = 1,
.amux = LINE2, .amux = LINE2,
.tv = 1, .tv = 1,
...@@ -269,6 +289,12 @@ struct saa7134_board saa7134_boards[] = { ...@@ -269,6 +289,12 @@ struct saa7134_board saa7134_boards[] = {
.vmux = 1, .vmux = 1,
.amux = TV, .amux = TV,
.tv = 1, .tv = 1,
},{
/* workaround for problems with normal TV sound */
.name = name_tv_mono,
.vmux = 1,
.amux = LINE2,
.tv = 1,
},{ },{
.name = name_comp1, .name = name_comp1,
.vmux = 0, .vmux = 0,
...@@ -302,7 +328,7 @@ struct saa7134_board saa7134_boards[] = { ...@@ -302,7 +328,7 @@ struct saa7134_board saa7134_boards[] = {
},{ },{
.name = name_tv, .name = name_tv,
.vmux = 1, .vmux = 1,
.amux = TV, .amux = LINE2,
.tv = 1, .tv = 1,
}}, }},
}, },
...@@ -332,7 +358,6 @@ struct saa7134_board saa7134_boards[] = { ...@@ -332,7 +358,6 @@ struct saa7134_board saa7134_boards[] = {
.name = name_radio, .name = name_radio,
.amux = LINE2, .amux = LINE2,
}, },
}, },
[SAA7134_BOARD_MD7134] = { [SAA7134_BOARD_MD7134] = {
.name = "Medion 7134", .name = "Medion 7134",
...@@ -343,7 +368,7 @@ struct saa7134_board saa7134_boards[] = { ...@@ -343,7 +368,7 @@ struct saa7134_board saa7134_boards[] = {
.name = name_tv, .name = name_tv,
.vmux = 1, .vmux = 1,
.amux = LINE2, .amux = LINE2,
.tv = 1, .tv = 1,
},{ },{
.name = name_comp1, .name = name_comp1,
.vmux = 0, .vmux = 0,
...@@ -361,9 +386,67 @@ struct saa7134_board saa7134_boards[] = { ...@@ -361,9 +386,67 @@ struct saa7134_board saa7134_boards[] = {
.name = name_radio, .name = name_radio,
.amux = LINE2, .amux = LINE2,
}, },
}, },
[SAA7134_BOARD_TYPHOON_90031] = {
.name = "Typhoon TV+Radio 90031",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
.inputs = {{
.name = name_tv,
.vmux = 1,
.amux = TV,
.tv = 1,
},{
.name = name_comp1,
.vmux = 3,
.amux = LINE1,
},{
.name = name_svideo,
.vmux = 8,
.amux = LINE1,
}},
.radio = {
.name = name_radio,
.amux = LINE2,
},
},
[SAA7134_BOARD_ELSA] = {
.name = "ELSA EX-VISION 300TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_HITACHI_NTSC,
.inputs = {{
.name = name_svideo,
.vmux = 8,
.amux = LINE1,
},{
.name = name_comp1,
.vmux = 0,
.amux = LINE1,
},{
.name = name_tv,
.vmux = 4,
.amux = LINE2,
.tv = 1,
}},
},
[SAA7134_BOARD_ELSA_500TV] = {
.name = "ELSA EX-VISION 500TV",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_HITACHI_NTSC,
.inputs = {{
.name = name_svideo,
.vmux = 7,
.amux = LINE1,
},{
.name = name_tv,
.vmux = 8,
.amux = TV,
.tv = 1,
}},
},
}; };
const int saa7134_bcount = (sizeof(saa7134_boards)/sizeof(struct saa7134_board)); const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* PCI ids + subsystem IDs */ /* PCI ids + subsystem IDs */
...@@ -375,6 +458,12 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = { ...@@ -375,6 +458,12 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
.subvendor = PCI_VENDOR_ID_PHILIPS, .subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0x2001, .subdevice = 0x2001,
.driver_data = SAA7134_BOARD_PROTEUS_PRO, .driver_data = SAA7134_BOARD_PROTEUS_PRO,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0x2001,
.driver_data = SAA7134_BOARD_PROTEUS_PRO,
},{ },{
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134, .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
...@@ -405,6 +494,12 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = { ...@@ -405,6 +494,12 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
.subvendor = 0x5168, .subvendor = 0x5168,
.subdevice = 0x0138, .subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO3000, .driver_data = SAA7134_BOARD_FLYVIDEO3000,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x5168,
.subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO2000,
},{ },{
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134, .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
...@@ -412,6 +507,18 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = { ...@@ -412,6 +507,18 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
.subdevice = 0x0003, .subdevice = 0x0003,
.driver_data = SAA7134_BOARD_MD7134, .driver_data = SAA7134_BOARD_MD7134,
},{ },{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x1048,
.subdevice = 0x226b,
.driver_data = SAA7134_BOARD_ELSA,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x1048,
.subdevice = 0x226b,
.driver_data = SAA7134_BOARD_ELSA_500TV,
},{
/* --- boards without eeprom + subsystem ID --- */ /* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
...@@ -433,18 +540,91 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = { ...@@ -433,18 +540,91 @@ struct pci_device_id __devinitdata saa7134_pci_tbl[] = {
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN, .driver_data = SAA7134_BOARD_UNKNOWN,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
},{ },{
.vendor = PCI_VENDOR_ID_PHILIPS, .vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134, .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN, .driver_data = SAA7134_BOARD_UNKNOWN,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7135,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = SAA7134_BOARD_UNKNOWN,
},{ },{
/* --- end of list --- */ /* --- end of list --- */
} }
}; };
MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl); MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl);
/* ----------------------------------------------------------- */
/* flyvideo tweaks */
#if 0
static struct {
char *model;
int tuner_type;
} fly_list[0x20] = {
/* default catch ... */
[ 0 ... 0x1f ] = {
.model = "UNKNOWN",
.tuner_type = TUNER_ABSENT,
},
/* ... the ones known so far */
[ 0x05 ] = {
.model = "PAL-BG",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
},
[ 0x10 ] = {
.model = "PAL-BG / PAL-DK",
.tuner_type = TUNER_PHILIPS_PAL,
},
[ 0x15 ] = {
.model = "NTSC",
.tuner_type = TUNER_ABSENT /* FIXME */,
},
};
#endif
static void board_flyvideo(struct saa7134_dev *dev)
{
u32 value;
int index;
saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
#if 0
index = (value & 0x1f00) >> 8;
printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
dev->name, value, fly_list[index].model,
fly_list[index].tuner_type);
dev->tuner_type = fly_list[index].tuner_type;
#else
printk(KERN_INFO "%s: flyvideo: gpio is 0x%x\n",
dev->name, value);
#endif
}
/* ----------------------------------------------------------- */
int saa7134_board_init(struct saa7134_dev *dev)
{
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
board_flyvideo(dev);
break;
}
return 0;
}
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* /*
* Local variables: * Local variables:
......
This diff is collapsed.
...@@ -153,10 +153,7 @@ static int i2c_is_busy_wait(struct saa7134_dev *dev) ...@@ -153,10 +153,7 @@ static int i2c_is_busy_wait(struct saa7134_dev *dev)
status = i2c_get_status(dev); status = i2c_get_status(dev);
if (!i2c_is_busy(status)) if (!i2c_is_busy(status))
break; break;
if (need_resched()) saa_wait(I2C_WAIT_DELAY);
schedule();
else
udelay(I2C_WAIT_DELAY);
} }
if (I2C_WAIT_RETRY == count) if (I2C_WAIT_RETRY == count)
return FALSE; return FALSE;
...@@ -318,7 +315,7 @@ static u32 functionality(struct i2c_adapter *adap) ...@@ -318,7 +315,7 @@ static u32 functionality(struct i2c_adapter *adap)
static int attach_inform(struct i2c_client *client) static int attach_inform(struct i2c_client *client)
{ {
struct saa7134_dev *dev = client->adapter->algo_data; struct saa7134_dev *dev = client->adapter->algo_data;
int tuner = card(dev).tuner_type; int tuner = dev->tuner_type;
saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner); saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
return 0; return 0;
...@@ -334,9 +331,9 @@ static struct i2c_algorithm saa7134_algo = { ...@@ -334,9 +331,9 @@ static struct i2c_algorithm saa7134_algo = {
static struct i2c_adapter saa7134_adap_template = { static struct i2c_adapter saa7134_adap_template = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.class = I2C_ADAP_CLASS_TV_ANALOG,
I2C_DEVNAME("saa7134"), I2C_DEVNAME("saa7134"),
.id = I2C_ALGO_SAA7134, .id = I2C_ALGO_SAA7134,
.class = I2C_ADAP_CLASS_TV_ANALOG,
.algo = &saa7134_algo, .algo = &saa7134_algo,
.client_register = attach_inform, .client_register = attach_inform,
}; };
......
...@@ -94,8 +94,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev) ...@@ -94,8 +94,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
static int dsp_rec_start(struct saa7134_dev *dev) static int dsp_rec_start(struct saa7134_dev *dev)
{ {
int err, fmt, bswap, wswap; int err, bswap, sign;
unsigned long control,flags; u32 fmt, control;
unsigned long flags;
/* prepare buffer */ /* prepare buffer */
if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma)))
...@@ -110,45 +111,60 @@ static int dsp_rec_start(struct saa7134_dev *dev) ...@@ -110,45 +111,60 @@ static int dsp_rec_start(struct saa7134_dev *dev)
/* sample format */ /* sample format */
switch (dev->oss.afmt) { switch (dev->oss.afmt) {
case AFMT_U8: fmt = 0x00; break; case AFMT_U8:
case AFMT_S8: fmt = 0x00 | 0x04; break; case AFMT_S8: fmt = 0x00; break;
case AFMT_U16_LE: case AFMT_U16_LE:
case AFMT_U16_BE: fmt = 0x01; break; case AFMT_U16_BE:
case AFMT_S16_LE: case AFMT_S16_LE:
case AFMT_S16_BE: fmt = 0x01 | 0x04; break; case AFMT_S16_BE: fmt = 0x01; break;
/* 4front API specs mention these ones,
the (2.4.15) kernel header hasn't them ... */
#ifdef AFMT_S32_LE
case AFMT_S32_LE:
case AFMT_S32_BE: fmt = 0x02 | 0x04; break;
#endif
default: default:
err = -EINVAL; err = -EINVAL;
goto fail2; goto fail2;
} }
switch (dev->oss.afmt) {
case AFMT_S8:
case AFMT_S16_LE:
case AFMT_S16_BE: sign = 1; break;
default: sign = 0; break;
}
switch (dev->oss.afmt) { switch (dev->oss.afmt) {
case AFMT_U16_BE: case AFMT_U16_BE:
case AFMT_S16_BE: bswap = 1; wswap = 0; break; case AFMT_S16_BE: bswap = 1; break;
#ifdef AFMT_S32_LE default: bswap = 0; break;
case AFMT_S32_BE: bswap = 1; wswap = 1; break;
#endif
default: bswap = 0; wswap = 0; break;
} }
if (1 == dev->oss.channels) switch (dev->pci->device) {
fmt |= (1 << 3); case PCI_DEVICE_ID_PHILIPS_SAA7134:
if (2 == dev->oss.channels) if (1 == dev->oss.channels)
fmt |= (3 << 3); fmt |= (1 << 3);
fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; if (2 == dev->oss.channels)
fmt |= (3 << 3);
saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff)); if (sign)
saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8); fmt |= 0x04;
saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16); fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c%c\n", saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8);
saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
break;
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
if (1 == dev->oss.channels)
fmt |= (1 << 4);
if (2 == dev->oss.channels)
fmt |= (2 << 4);
if (!sign)
fmt |= 0x04;
saa_writel(0x588 >> 2, dev->oss.blksize);
saa_writel(0x58c >> 2, 0x543210 | (fmt << 24));
break;
}
dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
dev->oss.afmt, dev->oss.channels, fmt, dev->oss.afmt, dev->oss.channels, fmt,
bswap ? 'b' : '-', wswap ? 'w' : '-'); bswap ? 'b' : '-');
/* dma: setup channel 6 (= AUDIO) */ /* dma: setup channel 6 (= AUDIO) */
control = SAA7134_RS_CONTROL_BURST_16 | control = SAA7134_RS_CONTROL_BURST_16 |
...@@ -156,8 +172,6 @@ static int dsp_rec_start(struct saa7134_dev *dev) ...@@ -156,8 +172,6 @@ static int dsp_rec_start(struct saa7134_dev *dev)
(dev->oss.pt.dma >> 12); (dev->oss.pt.dma >> 12);
if (bswap) if (bswap)
control |= SAA7134_RS_CONTROL_BSWAP; control |= SAA7134_RS_CONTROL_BSWAP;
if (wswap)
control |= SAA7134_RS_CONTROL_WSWAP;
saa_writel(SAA7134_RS_BA1(6),0); saa_writel(SAA7134_RS_BA1(6),0);
saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize);
saa_writel(SAA7134_RS_PITCH(6),0); saa_writel(SAA7134_RS_PITCH(6),0);
...@@ -201,7 +215,7 @@ static int dsp_rec_stop(struct saa7134_dev *dev) ...@@ -201,7 +215,7 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
static int dsp_open(struct inode *inode, struct file *file) static int dsp_open(struct inode *inode, struct file *file)
{ {
unsigned int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
struct saa7134_dev *h,*dev = NULL; struct saa7134_dev *h,*dev = NULL;
struct list_head *list; struct list_head *list;
int err; int err;
...@@ -259,7 +273,8 @@ static ssize_t dsp_read(struct file *file, char *buffer, ...@@ -259,7 +273,8 @@ static ssize_t dsp_read(struct file *file, char *buffer,
{ {
struct saa7134_dev *dev = file->private_data; struct saa7134_dev *dev = file->private_data;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
int bytes,err,ret = 0; unsigned int bytes;
int err,ret = 0;
add_wait_queue(&dev->oss.wq, &wait); add_wait_queue(&dev->oss.wq, &wait);
down(&dev->oss.lock); down(&dev->oss.lock);
...@@ -390,10 +405,6 @@ static int dsp_ioctl(struct inode *inode, struct file *file, ...@@ -390,10 +405,6 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
case AFMT_U16_BE: case AFMT_U16_BE:
case AFMT_S16_LE: case AFMT_S16_LE:
case AFMT_S16_BE: case AFMT_S16_BE:
#ifdef AFMT_S32_LE
case AFMT_S32_LE:
case AFMT_S32_BE:
#endif
down(&dev->oss.lock); down(&dev->oss.lock);
dev->oss.afmt = val; dev->oss.afmt = val;
if (dev->oss.recording) { if (dev->oss.recording) {
...@@ -416,11 +427,6 @@ static int dsp_ioctl(struct inode *inode, struct file *file, ...@@ -416,11 +427,6 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
case AFMT_S16_LE: case AFMT_S16_LE:
case AFMT_S16_BE: case AFMT_S16_BE:
return put_user(16, (int*)arg); return put_user(16, (int*)arg);
#ifdef AFMT_S32_LE
case AFMT_S32_LE:
case AFMT_S32_BE:
return put_user(20, (int*)arg);
#endif
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -499,14 +505,10 @@ struct file_operations saa7134_dsp_fops = { ...@@ -499,14 +505,10 @@ struct file_operations saa7134_dsp_fops = {
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static int static int
mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src) mixer_recsrc_7134(struct saa7134_dev *dev)
{ {
static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
int analog_io,rate; int analog_io,rate;
dev->oss.count++;
dev->oss.input = src;
dprintk("mixer input = %s\n",iname[dev->oss.input]);
switch (dev->oss.input) { switch (dev->oss.input) {
case TV: case TV:
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
...@@ -525,27 +527,78 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src) ...@@ -525,27 +527,78 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
} }
static int static int
mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level) mixer_recsrc_7133(struct saa7134_dev *dev)
{ {
switch (src) { u32 value = 0xbbbbbb;
switch (dev->oss.input) {
case TV: case TV:
/* nothing */ value = 0xbbbb10; /* MAIN */
break; break;
case LINE1: case LINE1:
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10, value = 0xbbbb32; /* AUX1 */
(100 == level) ? 0x00 : 0x10);
break; break;
case LINE2: case LINE2:
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20, value = 0xbbbb54; /* AUX2 */
(100 == level) ? 0x00 : 0x20);
break; break;
} }
saa_dsp_writel(dev, 0x46c >> 2, value);
return 0; return 0;
} }
static int
mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
{
static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
dev->oss.count++;
dev->oss.input = src;
dprintk("mixer input = %s\n",iname[dev->oss.input]);
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
mixer_recsrc_7134(dev);
break;
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
mixer_recsrc_7133(dev);
break;
}
return 0;
}
static int
mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
{
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
switch (src) {
case TV:
/* nothing */
break;
case LINE1:
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10,
(100 == level) ? 0x00 : 0x10);
break;
case LINE2:
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
(100 == level) ? 0x00 : 0x20);
break;
}
break;
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
/* nothing */
break;
}
return 0;
}
/* ------------------------------------------------------------------ */
static int mixer_open(struct inode *inode, struct file *file) static int mixer_open(struct inode *inode, struct file *file)
{ {
unsigned int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
struct saa7134_dev *h,*dev = NULL; struct saa7134_dev *h,*dev = NULL;
struct list_head *list; struct list_head *list;
...@@ -681,13 +734,20 @@ struct file_operations saa7134_mixer_fops = { ...@@ -681,13 +734,20 @@ struct file_operations saa7134_mixer_fops = {
int saa7134_oss_init(struct saa7134_dev *dev) int saa7134_oss_init(struct saa7134_dev *dev)
{ {
/* general */
init_MUTEX(&dev->oss.lock); init_MUTEX(&dev->oss.lock);
init_waitqueue_head(&dev->oss.wq); init_waitqueue_head(&dev->oss.wq);
dev->oss.line1 = 50;
dev->oss.line2 = 50; switch (dev->pci->device) {
mixer_level(dev,LINE1,dev->oss.line1); case PCI_DEVICE_ID_PHILIPS_SAA7133:
mixer_level(dev,LINE2,dev->oss.line2); case PCI_DEVICE_ID_PHILIPS_SAA7135:
saa_writel(0x588 >> 2, 0x00000fff);
saa_writel(0x58c >> 2, 0x00543210);
saa_dsp_writel(dev, 0x46c >> 2, 0xbbbbbb);
break;
}
/* dsp */
dev->oss.rate = 32000; dev->oss.rate = 32000;
if (oss_rate) if (oss_rate)
dev->oss.rate = oss_rate; dev->oss.rate = oss_rate;
...@@ -695,7 +755,13 @@ int saa7134_oss_init(struct saa7134_dev *dev) ...@@ -695,7 +755,13 @@ int saa7134_oss_init(struct saa7134_dev *dev)
dev->oss.rate = saa7134_boards[dev->board].i2s_rate; dev->oss.rate = saa7134_boards[dev->board].i2s_rate;
dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000;
/* mixer */
dev->oss.line1 = 50;
dev->oss.line2 = 50;
mixer_level(dev,LINE1,dev->oss.line1);
mixer_level(dev,LINE2,dev->oss.line2);
mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2);
return 0; return 0;
} }
...@@ -710,7 +776,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) ...@@ -710,7 +776,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
int next_blk, reg = 0; int next_blk, reg = 0;
spin_lock(&dev->slock); spin_lock(&dev->slock);
if (-1 == dev->oss.dma_blk) { if (UNSET == dev->oss.dma_blk) {
dprintk("irq: recording stopped%s\n",""); dprintk("irq: recording stopped%s\n","");
goto done; goto done;
} }
......
...@@ -9,9 +9,15 @@ ...@@ -9,9 +9,15 @@
#ifndef PCI_DEVICE_ID_PHILIPS_SAA7130 #ifndef PCI_DEVICE_ID_PHILIPS_SAA7130
# define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130 # define PCI_DEVICE_ID_PHILIPS_SAA7130 0x7130
#endif #endif
#ifndef PCI_DEVICE_ID_PHILIPS_SAA7133
# define PCI_DEVICE_ID_PHILIPS_SAA7133 0x7133
#endif
#ifndef PCI_DEVICE_ID_PHILIPS_SAA7134 #ifndef PCI_DEVICE_ID_PHILIPS_SAA7134
# define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134 # define PCI_DEVICE_ID_PHILIPS_SAA7134 0x7134
#endif #endif
#ifndef PCI_DEVICE_ID_PHILIPS_SAA7135
# define PCI_DEVICE_ID_PHILIPS_SAA7135 0x7135
#endif
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* /*
...@@ -329,6 +335,13 @@ ...@@ -329,6 +335,13 @@
/* test modes */ /* test modes */
#define SAA7134_SPECIAL_MODE 0x1d0 #define SAA7134_SPECIAL_MODE 0x1d0
/* audio -- saa7133 + saa7135 only */
#define SAA7135_DSP_RWSTATE 0x580
#define SAA7135_DSP_RWSTATE_ERR (1 << 3)
#define SAA7135_DSP_RWSTATE_IDA (1 << 2)
#define SAA7135_DSP_RWSTATE_RDB (1 << 1)
#define SAA7135_DSP_RWSTATE_WRR (1 << 0)
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* /*
* Local variables: * Local variables:
......
...@@ -52,8 +52,9 @@ static int buffer_activate(struct saa7134_dev *dev, ...@@ -52,8 +52,9 @@ static int buffer_activate(struct saa7134_dev *dev,
{ {
u32 control; u32 control;
dprintk("buffer_activate [%p]\n",buf); dprintk("buffer_activate [%p]",buf);
buf->vb.state = STATE_ACTIVE; buf->vb.state = STATE_ACTIVE;
buf->top_seen = 0;
/* dma: setup channel 5 (= TS) */ /* dma: setup channel 5 (= TS) */
control = SAA7134_RS_CONTROL_BURST_16 | control = SAA7134_RS_CONTROL_BURST_16 |
...@@ -63,11 +64,11 @@ static int buffer_activate(struct saa7134_dev *dev, ...@@ -63,11 +64,11 @@ static int buffer_activate(struct saa7134_dev *dev,
if (NULL == next) if (NULL == next)
next = buf; next = buf;
if (V4L2_FIELD_TOP == buf->vb.field) { if (V4L2_FIELD_TOP == buf->vb.field) {
dprintk("[top] buf=%p next=%p",buf,next); dprintk("- [top] buf=%p next=%p\n",buf,next);
saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf)); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(buf));
saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(next));
} else { } else {
dprintk("[bottom] buf=%p next=%p",buf,next); dprintk("- [bottom] buf=%p next=%p\n",buf,next);
saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
} }
...@@ -86,8 +87,11 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -86,8 +87,11 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
{ {
struct saa7134_dev *dev = file->private_data; struct saa7134_dev *dev = file->private_data;
struct saa7134_buf *buf = (struct saa7134_buf *)vb; struct saa7134_buf *buf = (struct saa7134_buf *)vb;
int lines, llength, size, err; unsigned int lines, llength, size;
int err;
dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
llength = TS_PACKET_SIZE; llength = TS_PACKET_SIZE;
lines = TS_NR_PACKETS; lines = TS_NR_PACKETS;
...@@ -116,7 +120,6 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -116,7 +120,6 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
goto oops; goto oops;
} }
buf->vb.state = STATE_PREPARED; buf->vb.state = STATE_PREPARED;
buf->top_seen = 0;
buf->activate = buffer_activate; buf->activate = buffer_activate;
buf->vb.field = field; buf->vb.field = field;
return 0; return 0;
...@@ -163,7 +166,7 @@ static struct videobuf_queue_ops ts_qops = { ...@@ -163,7 +166,7 @@ static struct videobuf_queue_ops ts_qops = {
static int ts_open(struct inode *inode, struct file *file) static int ts_open(struct inode *inode, struct file *file)
{ {
unsigned int minor = minor(inode->i_rdev); int minor = minor(inode->i_rdev);
struct saa7134_dev *h,*dev = NULL; struct saa7134_dev *h,*dev = NULL;
struct list_head *list; struct list_head *list;
int err; int err;
...@@ -414,6 +417,7 @@ int saa7134_ts_init(struct saa7134_dev *dev) ...@@ -414,6 +417,7 @@ int saa7134_ts_init(struct saa7134_dev *dev)
dev->ts_q.timeout.function = saa7134_buffer_timeout; dev->ts_q.timeout.function = saa7134_buffer_timeout;
dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q); dev->ts_q.timeout.data = (unsigned long)(&dev->ts_q);
dev->ts_q.dev = dev; dev->ts_q.dev = dev;
dev->ts_q.need_two = 1;
videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock, videobuf_queue_init(&dev->ts.ts, &ts_qops, dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_ALTERNATE, V4L2_FIELD_ALTERNATE,
...@@ -445,7 +449,7 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) ...@@ -445,7 +449,7 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
spin_lock(&dev->slock); spin_lock(&dev->slock);
if (dev->ts_q.curr) { if (dev->ts_q.curr) {
field = dev->video_q.curr->vb.field; field = dev->ts_q.curr->vb.field;
if (field == V4L2_FIELD_TOP) { if (field == V4L2_FIELD_TOP) {
if ((status & 0x100000) != 0x100000) if ((status & 0x100000) != 0x100000)
goto done; goto done;
......
...@@ -85,6 +85,7 @@ static int buffer_activate(struct saa7134_dev *dev, ...@@ -85,6 +85,7 @@ static int buffer_activate(struct saa7134_dev *dev,
dprintk("buffer_activate [%p]\n",buf); dprintk("buffer_activate [%p]\n",buf);
buf->vb.state = STATE_ACTIVE; buf->vb.state = STATE_ACTIVE;
buf->top_seen = 0;
task_init(dev,buf,TASK_A); task_init(dev,buf,TASK_A);
task_init(dev,buf,TASK_B); task_init(dev,buf,TASK_B);
...@@ -119,7 +120,8 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -119,7 +120,8 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
struct saa7134_dev *dev = fh->dev; struct saa7134_dev *dev = fh->dev;
struct saa7134_buf *buf = (struct saa7134_buf *)vb; struct saa7134_buf *buf = (struct saa7134_buf *)vb;
struct saa7134_tvnorm *norm = dev->tvnorm; struct saa7134_tvnorm *norm = dev->tvnorm;
int lines, llength, size, err; unsigned int lines, llength, size;
int err;
lines = norm->vbi_v_stop - norm->vbi_v_start +1; lines = norm->vbi_v_stop - norm->vbi_v_start +1;
if (lines > VBI_LINE_COUNT) if (lines > VBI_LINE_COUNT)
...@@ -155,7 +157,6 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -155,7 +157,6 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
goto oops; goto oops;
} }
buf->vb.state = STATE_PREPARED; buf->vb.state = STATE_PREPARED;
buf->top_seen = 0;
buf->activate = buffer_activate; buf->activate = buffer_activate;
buf->vb.field = field; buf->vb.field = field;
return 0; return 0;
...@@ -166,7 +167,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, ...@@ -166,7 +167,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
} }
static int static int
buffer_setup(struct file *file, int *count, int *size) buffer_setup(struct file *file, unsigned int *count, unsigned int *size)
{ {
struct saa7134_fh *fh = file->private_data; struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev; struct saa7134_dev *dev = fh->dev;
...@@ -241,7 +242,7 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) ...@@ -241,7 +242,7 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status)
if (dev->vbi_q.curr) { if (dev->vbi_q.curr) {
dev->vbi_fieldcount++; dev->vbi_fieldcount++;
/* make sure we have seen both fields */ /* make sure we have seen both fields */
if ((status & 0x10) == 0x10) { if ((status & 0x10) == 0x00) {
dev->vbi_q.curr->top_seen = 1; dev->vbi_q.curr->top_seen = 1;
goto done; goto done;
} }
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment