diff options
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r-- | drivers/media/video/saa7134/Kconfig | 15 | ||||
-rw-r--r-- | drivers/media/video/saa7134/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-alsa.c | 49 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 621 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 59 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-dvb.c | 20 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-empress.c | 298 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-i2c.c | 15 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 63 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-oss.c | 1046 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-ts.c | 8 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-tvaudio.c | 79 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-vbi.c | 8 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-video.c | 1541 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 35 |
15 files changed, 1805 insertions, 2053 deletions
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index d6d8d660196..96bc3b1298a 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig @@ -1,9 +1,10 @@ config VIDEO_SAA7134 tristate "Philips SAA7134 support" - depends on VIDEO_DEV && PCI && I2C + depends on VIDEO_DEV && PCI && I2C && INPUT select VIDEOBUF_DMA_SG select VIDEO_IR select VIDEO_TUNER + select VIDEO_TVEEPROM select CRC32 ---help--- This is a video4linux driver for Philips SAA713x based @@ -23,18 +24,6 @@ config VIDEO_SAA7134_ALSA To compile this driver as a module, choose M here: the module will be called saa7134-alsa. -config VIDEO_SAA7134_OSS - tristate "Philips SAA7134 DMA audio support (OSS, DEPRECATED)" - depends on VIDEO_SAA7134 && SOUND_PRIME && !VIDEO_SAA7134_ALSA - ---help--- - This is a video4linux driver for direct (DMA) audio in - Philips SAA713x based TV cards using OSS - - This is deprecated in favor of the ALSA module - - To compile this driver as a module, choose M here: the - module will be called saa7134-oss. - config VIDEO_SAA7134_DVB tristate "DVB/ATSC Support for saa7134 based TV cards" depends on VIDEO_SAA7134 && DVB_CORE diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index c85c8a8ec36..9aff937ba7a 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ saa6752hs.o obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o -obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index c6f7279669c..047add8f301 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -21,7 +21,6 @@ #include <linux/time.h> #include <linux/wait.h> #include <linux/module.h> -#include <sound/driver.h> #include <sound/core.h> #include <sound/control.h> #include <sound/pcm.h> @@ -222,7 +221,8 @@ static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id) if (report & SAA7134_IRQ_REPORT_DONE_RA3) { handled = 1; - saa_writel(SAA7134_IRQ_REPORT,report); + saa_writel(SAA7134_IRQ_REPORT, + SAA7134_IRQ_REPORT_DONE_RA3); saa7134_irq_alsa_done(dev, status); } else { goto out; @@ -457,7 +457,7 @@ static struct snd_pcm_hardware snd_card_saa7134_capture = .buffer_bytes_max = (256*1024), .period_bytes_min = 64, .period_bytes_max = (256*1024), - .periods_min = 2, + .periods_min = 4, .periods_max = 1024, }; @@ -491,7 +491,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, snd_assert(period_size >= 0x100 && period_size <= 0x10000, return -EINVAL); - snd_assert(periods >= 2, return -EINVAL); + snd_assert(periods >= 4, return -EINVAL); snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL); dev = saa7134->dev; @@ -543,8 +543,10 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, V4L functions, and force ALSA to use that as the DMA area */ substream->runtime->dma_area = dev->dmasound.dma.vmalloc; + substream->runtime->dma_bytes = dev->dmasound.bufsize; + substream->runtime->dma_addr = 0; - return 1; + return 0; } @@ -645,13 +647,31 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) saa7134_tvaudio_setmute(dev); } - if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) + err = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) + return err; + + err = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIODS, 2); + if (err < 0) return err; return 0; } /* + * page callback (needed for mmap) + */ + +static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream, + unsigned long offset) +{ + void *pageptr = substream->runtime->dma_area + offset; + return vmalloc_to_page(pageptr); +} + +/* * ALSA capture callbacks definition */ @@ -664,6 +684,7 @@ static struct snd_pcm_ops snd_card_saa7134_capture_ops = { .prepare = snd_card_saa7134_capture_prepare, .trigger = snd_card_saa7134_capture_trigger, .pointer = snd_card_saa7134_capture_pointer, + .page = snd_card_saa7134_page, }; /* @@ -1055,24 +1076,14 @@ static int saa7134_alsa_init(void) struct saa7134_dev *dev = NULL; struct list_head *list; - if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { - saa7134_dmasound_init = alsa_device_init; - saa7134_dmasound_exit = alsa_device_exit; - } else { - printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n"); - return -EBUSY; - } + saa7134_dmasound_init = alsa_device_init; + saa7134_dmasound_exit = alsa_device_exit; printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); list_for_each(list,&saa7134_devlist) { dev = list_entry(list, struct saa7134_dev, devlist); - if (dev->dmasound.priv_data == NULL) { - alsa_device_init(dev); - } else { - printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name); - return -EBUSY; - } + alsa_device_init(dev); } if (dev == NULL) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index a4c192fb4e4..7d7f383b404 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -26,6 +26,7 @@ #include "saa7134-reg.h" #include "saa7134.h" #include <media/v4l2-common.h> +#include <media/tveeprom.h> /* commly used strings */ static char name_mute[] = "mute"; @@ -334,7 +335,7 @@ struct saa7134_board saa7134_boards[] = { .tv = 1, },{ .name = name_comp1, - .vmux = 2, + .vmux = 0, .amux = LINE1, },{ .name = name_comp2, @@ -349,6 +350,10 @@ struct saa7134_board saa7134_boards[] = { .name = name_radio, .amux = LINE2, }, + .mute = { + .name = name_mute, + .amux = TV, + }, }, [SAA7134_BOARD_TVSTATION_RDS] = { /* Typhoon TV Tuner RDS: Art.Nr. 50694 */ @@ -565,6 +570,10 @@ struct saa7134_board saa7134_boards[] = { .radio = { .name = name_radio, .amux = LINE2, + }, + .mute = { + .name = name_mute, + .amux = TV, }, }, [SAA7134_BOARD_TYPHOON_90031] = { @@ -2996,11 +3005,11 @@ struct saa7134_board saa7134_boards[] = { },{ .name = name_comp1, .vmux = 0, - .amux = LINE2, + .amux = LINE1, },{ .name = name_svideo, .vmux = 8, - .amux = LINE2, + .amux = LINE1, }}, }, [SAA7134_BOARD_FLYDVBS_LR300] = { @@ -3221,6 +3230,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .tuner_config = 1, .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, @@ -3552,6 +3562,356 @@ struct saa7134_board saa7134_boards[] = { .tv = 1, }}, }, + [SAA7134_BOARD_BEHOLD_401] = { + .name = "Beholder BeholdTV 401", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + }, + [SAA7134_BOARD_BEHOLD_403] = { + .name = "Beholder BeholdTV 403", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + }, + [SAA7134_BOARD_BEHOLD_403FM] = { + .name = "Beholder BeholdTV 403 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FQ1216ME, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_405] = { + .name = "Beholder BeholdTV 405", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + }, + [SAA7134_BOARD_BEHOLD_405FM] = { + /* Sergey <skiv@orel.ru> */ + .name = "Beholder BeholdTV 405 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE1, + },{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_407] = { + .name = "Beholder BeholdTV 407", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0xc0c000, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + .gpio = 0xc0c000, + }}, + }, + [SAA7134_BOARD_BEHOLD_407FM] = { + .name = "Beholder BeholdTV 407 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0xc0c000, + .inputs = {{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + .gpio = 0xc0c000, + },{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + .gpio = 0xc0c000, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0xc0c000, + }, + }, + [SAA7134_BOARD_BEHOLD_409] = { + .name = "Beholder BeholdTV 409", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + }, + [SAA7134_BOARD_BEHOLD_505FM] = { + .name = "Beholder BeholdTV 505 FM/RDS", + .audio_clock = 0x00200000, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = LINE2, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .mute = { + .name = name_mute, + .amux = LINE1, + }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_507_9FM] = { + .name = "Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { + .name = "Beholder BeholdTV Columbus TVFM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_ALPS_TSBE5_PAL, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_607_9FM] = { + /* Andrey Melnikoff <temnota@kmv.ru> */ + .name = "Beholder BeholdTV 607 / BeholdTV 609", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + }, + [SAA7134_BOARD_BEHOLD_M6] = { + /* Igor Kuznetsov <igk@igk.ru> */ + /* Andrey Melnikoff <temnota@kmv.ru> */ + .name = "Beholder BeholdTV M6 / BeholdTV M6 Extra", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -4032,7 +4392,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x1462, - .subdevice = 0x6231, + .subdevice = 0x6231, /* tda8275a, ks003 IR */ + .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1462, + .subdevice = 0x8624, /* tda8275, ks003 IR */ .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, },{ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -4206,11 +4572,41 @@ struct pci_device_id saa7134_pci_tbl[] = { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x0070, + .subdevice = 0x6700, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, .subdevice = 0x6701, .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, + .subdevice = 0x6702, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, + .subdevice = 0x6703, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, + .subdevice = 0x6704, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, + .subdevice = 0x6705, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x153b, .subdevice = 0x1172, .driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA, @@ -4288,6 +4684,162 @@ struct pci_device_id saa7134_pci_tbl[] = { .driver_data = SAA7134_BOARD_AVERMEDIA_SUPER_007, },{ .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4016, + .driver_data = SAA7134_BOARD_BEHOLD_401, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4036, + .driver_data = SAA7134_BOARD_BEHOLD_403, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4037, + .driver_data = SAA7134_BOARD_BEHOLD_403FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4050, + .driver_data = SAA7134_BOARD_BEHOLD_405, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x4051, + .driver_data = SAA7134_BOARD_BEHOLD_405FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4070, + .driver_data = SAA7134_BOARD_BEHOLD_407, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x0000, + .subdevice = 0x4071, + .driver_data = SAA7134_BOARD_BEHOLD_407FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x4090, + .driver_data = SAA7134_BOARD_BEHOLD_409, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x5051, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x0000, + .subdevice = 0x505B, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7130, + .subvendor = 0x5ace, + .subdevice = 0x5050, + .driver_data = SAA7134_BOARD_BEHOLD_505FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x5071, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x507B, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x5070, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x5090, + .driver_data = SAA7134_BOARD_BEHOLD_507_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0000, + .subdevice = 0x5201, + .driver_data = SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6070, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6071, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6072, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5ace, + .subdevice = 0x6073, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6090, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6091, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6092, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6093, + .driver_data = SAA7134_BOARD_BEHOLD_607_9FM, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6190, + .driver_data = SAA7134_BOARD_BEHOLD_M6, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5ace, + .subdevice = 0x6193, + .driver_data = SAA7134_BOARD_BEHOLD_M6, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x4e42, .subdevice = 0x3502, @@ -4350,6 +4902,34 @@ static void board_flyvideo(struct saa7134_dev *dev) /* ----------------------------------------------------------- */ +static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data) +{ + struct tveeprom tv; + + tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); + + /* Make sure we support the board model */ + switch (tv.model) { + case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */ + case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */ + case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */ + case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */ + case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */ + case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ + case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */ + break; + default: + printk(KERN_WARNING "%s: warning: " + "unknown hauppauge model #%d\n", dev->name, tv.model); + break; + } + + printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", + dev->name, tv.model); +} + +/* ----------------------------------------------------------- */ + int saa7134_board_init1(struct saa7134_dev *dev) { /* Always print gpio, often manufacturers encode tuner type and other info. */ @@ -4405,6 +4985,16 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_ENCORE_ENLTV: case SAA7134_BOARD_ENCORE_ENLTV_FM: case SAA7134_BOARD_10MOONSTVMASTER3: + case SAA7134_BOARD_BEHOLD_401: + case SAA7134_BOARD_BEHOLD_403: + case SAA7134_BOARD_BEHOLD_403FM: + case SAA7134_BOARD_BEHOLD_405: + case SAA7134_BOARD_BEHOLD_405FM: + case SAA7134_BOARD_BEHOLD_407: + case SAA7134_BOARD_BEHOLD_407FM: + case SAA7134_BOARD_BEHOLD_409: + case SAA7134_BOARD_BEHOLD_505FM: + case SAA7134_BOARD_BEHOLD_507_9FM: dev->has_remote = SAA7134_REMOTE_GPIO; break; case SAA7134_BOARD_FLYDVBS_LR300: @@ -4444,6 +5034,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS: + case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM: /* power-up tuner chip */ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0xffffffff, 0xffffffff); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); @@ -4465,6 +5056,8 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_UPMOST_PURPLE_TV: case SAA7134_BOARD_HAUPPAUGE_HVR1110: + case SAA7134_BOARD_BEHOLD_607_9FM: + case SAA7134_BOARD_BEHOLD_M6: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: @@ -4476,6 +5069,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) break; case SAA7134_BOARD_AVERMEDIA_M102: /* enable tuner */ + dev->has_remote = SAA7134_REMOTE_GPIO; saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd); break; @@ -4569,8 +5163,17 @@ int saa7134_board_init2(struct saa7134_dev *dev) printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type); if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) { - dev->tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE; - saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG, &dev->tda9887_conf); + struct v4l2_priv_tun_config tda9887_cfg; + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &dev->tda9887_conf; + + dev->tda9887_conf = TDA9887_PRESENT | + TDA9887_PORT1_ACTIVE | + TDA9887_PORT2_ACTIVE; + + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, + &tda9887_cfg); } tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; @@ -4600,7 +5203,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; case SAA7134_BOARD_PHILIPS_TIGER: case SAA7134_BOARD_PHILIPS_TIGER_S: - case SAA7134_BOARD_AVERMEDIA_SUPER_007: { u8 data[] = { 0x3c, 0x33, 0x60}; struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; @@ -4621,13 +5223,16 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); } break; + case SAA7134_BOARD_HAUPPAUGE_HVR1110: + hauppauge_eeprom(dev, dev->eedata+0x80); + /* break intentionally omitted */ case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_KWORLD_DVBT_210: case SAA7134_BOARD_TEVION_DVBT_220RF: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: case SAA7134_BOARD_MEDION_MD8800_QUADRO: - case SAA7134_BOARD_HAUPPAUGE_HVR1110: + case SAA7134_BOARD_AVERMEDIA_SUPER_007: /* this is a hybrid board, initialize to analog mode * and configure firmware eeprom address */ diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index a499eea379e..52baa4f7f7d 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -294,7 +294,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf) videobuf_waiton(&buf->vb,0,0); videobuf_dma_unmap(q, dma); videobuf_dma_free(dma); - buf->vb.state = STATE_NEEDS_INIT; + buf->vb.state = VIDEOBUF_NEEDS_INIT; } /* ------------------------------------------------------------------ */ @@ -313,7 +313,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, buf->activate(dev,buf,NULL); } else if (list_empty(&q->queue)) { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } else { next = list_entry(q->queue.next,struct saa7134_buf, vb.queue); @@ -322,7 +322,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, } } else { list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = STATE_QUEUED; + buf->vb.state = VIDEOBUF_QUEUED; } return 0; } @@ -387,7 +387,7 @@ void saa7134_buffer_timeout(unsigned long data) try to start over with the next one. */ if (q->curr) { dprintk("timeout on %p\n",q->curr); - saa7134_buffer_finish(dev,q,STATE_ERROR); + saa7134_buffer_finish(dev,q,VIDEOBUF_ERROR); } saa7134_buffer_next(dev,q); spin_unlock_irqrestore(&dev->slock,flags); @@ -395,8 +395,8 @@ void saa7134_buffer_timeout(unsigned long data) /* resends a current buffer in queue after resume */ -int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q) +static int saa7134_buffer_requeue(struct saa7134_dev *dev, + struct saa7134_dmaqueue *q) { struct saa7134_buf *buf, *next; @@ -569,21 +569,22 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id) for (loop = 0; loop < 10; loop++) { report = saa_readl(SAA7134_IRQ_REPORT); status = saa_readl(SAA7134_IRQ_STATUS); - if (0 == report) { - if (irq_debug > 1) - printk(KERN_DEBUG "%s/irq: no (more) work\n", - dev->name); - goto out; - } - - /* If dmasound support is active and we get a sound report, exit - and let the saa7134-alsa/oss module deal with it */ + /* If dmasound support is active and we get a sound report, + * mask out the report and let the saa7134-alsa module deal + * with it */ if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && (dev->dmasound.priv_data != NULL) ) { if (irq_debug > 1) - printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n", + printk(KERN_DEBUG "%s/irq: preserving DMA sound interrupt\n", + dev->name); + report &= ~SAA7134_IRQ_REPORT_DONE_RA3; + } + + if (0 == report) { + if (irq_debug > 1) + printk(KERN_DEBUG "%s/irq: no (more) work\n", dev->name); goto out; } @@ -833,6 +834,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, vfd->minor = -1; vfd->dev = &dev->pci->dev; vfd->release = video_device_release; + vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, saa7134_boards[dev->board].name); return vfd; @@ -1051,7 +1053,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, printk(KERN_INFO "%s: registered device video%d [v4l2]\n", dev->name,dev->video_dev->minor & 0x1f); - dev->vbi_dev = vdev_init(dev,&saa7134_vbi_template,"vbi"); + dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); + dev->vbi_dev->type = VID_TYPE_TUNER | VID_TYPE_TELETEXT; + err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[dev->nr]); if (err < 0) @@ -1180,8 +1184,13 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) saa_writel(SAA7134_IRQ2, 0); saa_writel(SAA7134_MAIN_CTRL, 0); - synchronize_irq(pci_dev->irq); dev->insuspend = 1; + synchronize_irq(pci_dev->irq); + + /* ACK interrupts once more, just in case, + since the IRQ handler won't ack them anymore*/ + + saa_writel(SAA7134_IRQ_REPORT, saa_readl(SAA7134_IRQ_REPORT)); /* Disable timeout timers - if we have active buffers, we will fill them on resume*/ @@ -1193,20 +1202,19 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) if (dev->remote) saa7134_ir_stop(dev); - pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); pci_save_state(pci_dev); + pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); - return 0; + return 0; } static int saa7134_resume(struct pci_dev *pci_dev) { - struct saa7134_dev *dev = pci_get_drvdata(pci_dev); - unsigned int flags; + unsigned long flags; - pci_restore_state(pci_dev); pci_set_power_state(pci_dev, PCI_D0); + pci_restore_state(pci_dev); /* Do things that are done in saa7134_initdev , except of initializing memory structures.*/ @@ -1222,6 +1230,7 @@ static int saa7134_resume(struct pci_dev *pci_dev) saa7134_ir_start(dev, dev->remote); saa7134_hw_enable1(dev); + msleep(100); saa7134_board_init2(dev); @@ -1229,10 +1238,13 @@ static int saa7134_resume(struct pci_dev *pci_dev) saa7134_set_tvnorm_hw(dev); saa7134_tvaudio_setmute(dev); saa7134_tvaudio_setvolume(dev, dev->ctl_volume); + saa7134_tvaudio_init(dev); saa7134_tvaudio_do_scan(dev); saa7134_enable_i2s(dev); saa7134_hw_enable2(dev); + saa7134_irq_video_signalchange(dev); + /*resume unfinished buffer(s)*/ spin_lock_irqsave(&dev->slock, flags); saa7134_buffer_requeue(dev, &dev->video_q); @@ -1246,6 +1258,7 @@ static int saa7134_resume(struct pci_dev *pci_dev) /* start DMA now*/ dev->insuspend = 0; + smp_wmb(); saa7134_set_dmabits(dev); spin_unlock_irqrestore(&dev->slock, flags); diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 38d87332cc5..a9ca5730826 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -662,6 +662,7 @@ static struct tda1004x_config hauppauge_hvr_1110_config = { .if_freq = TDA10046_FREQ_045, .i2c_gate = 0x4b, .tuner_address = 0x61, + .tuner_config = 1, .request_firmware = philips_tda1004x_request_firmware }; @@ -1072,14 +1073,21 @@ static int dvb_init(struct saa7134_dev *dev) static int dvb_fini(struct saa7134_dev *dev) { - static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE; + /* FIXME: I suspect that this code is bogus, since the entry for + Pinnacle 300I DVB-T PAL already defines the proper init to allow + the detection of mt2032 (TDA9887_PORT2_INACTIVE) + */ + if (dev->board == SAA7134_BOARD_PINNACLE_300I_DVBT_PAL) { + struct v4l2_priv_tun_config tda9887_cfg; + static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE; + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &on; - switch (dev->board) { - case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL: /* otherwise we don't detect the tuner on next insmod */ - saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on); - break; - }; + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg); + } + videobuf_dvb_unregister(&dev->dvb); return 0; } diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 75d0c5bf46d..b1b01fa8672 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -110,11 +110,8 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - if (dev->empress_tsq.streaming) - videobuf_streamoff(&dev->empress_tsq); mutex_lock(&dev->empress_tsq.lock); - if (dev->empress_tsq.reading) - videobuf_read_stop(&dev->empress_tsq); + videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); dev->empress_users--; @@ -164,152 +161,176 @@ ts_mmap(struct file *file, struct vm_area_struct * vma) * video_generic_ioctl (and maybe others). userspace * copying is done already, arg is a kernel pointer. */ -static int ts_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) + +static int empress_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { - struct saa7134_dev *dev = file->private_data; - struct v4l2_ext_controls *ctrls = arg; - - if (debug > 1) - v4l_print_ioctl(dev->name,cmd); - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap,0,sizeof(*cap)); - strcpy(cap->driver, "saa7134"); - strlcpy(cap->card, saa7134_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); - cap->version = SAA7134_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - return 0; - } + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + strcpy(cap->driver, "saa7134"); + strlcpy(cap->card, saa7134_boards[dev->board].name, + sizeof(cap->card)); + sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); + cap->version = SAA7134_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING; + return 0; +} - /* --- input switching --------------------------------------- */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; +static int empress_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; - if (i->index != 0) - return -EINVAL; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name,"CCIR656"); - return 0; - } - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = 0; - return 0; - } - case VIDIOC_S_INPUT: - { - int *i = arg; + i->type = V4L2_INPUT_TYPE_CAMERA; + strcpy(i->name, "CCIR656"); - if (*i != 0) - return -EINVAL; - return 0; - } - /* --- capture ioctls ---------------------------------------- */ - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - int index; - - index = f->index; - if (index != 0) - return -EINVAL; - - memset(f,0,sizeof(*f)); - f->index = index; - strlcpy(f->description, "MPEG TS", sizeof(f->description)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->pixelformat = V4L2_PIX_FMT_MPEG; - return 0; - } + return 0; +} - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; +static int empress_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} - memset(f,0,sizeof(*f)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +static int empress_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i != 0) + return -EINVAL; - saa7134_i2c_call_clients(dev, cmd, arg); - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; - return 0; - } + return 0; +} - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; +static int empress_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->index != 0) + return -EINVAL; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; + strlcpy(f->description, "MPEG TS", sizeof(f->description)); + f->pixelformat = V4L2_PIX_FMT_MPEG; - saa7134_i2c_call_clients(dev, cmd, arg); - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets; - return 0; - } + return 0; +} - case VIDIOC_REQBUFS: - return videobuf_reqbufs(&dev->empress_tsq,arg); +static int empress_g_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; - case VIDIOC_QUERYBUF: - return videobuf_querybuf(&dev->empress_tsq,arg); + saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f); - case VIDIOC_QBUF: - return videobuf_qbuf(&dev->empress_tsq,arg); + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; - case VIDIOC_DQBUF: - return videobuf_dqbuf(&dev->empress_tsq,arg, - file->f_flags & O_NONBLOCK); + return 0; +} - case VIDIOC_STREAMON: - return videobuf_streamon(&dev->empress_tsq); +static int empress_s_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; - case VIDIOC_STREAMOFF: - return videobuf_streamoff(&dev->empress_tsq); + saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f); - case VIDIOC_QUERYCTRL: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - return saa7134_common_ioctl(dev, cmd, arg); + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; - case VIDIOC_S_EXT_CTRLS: - /* count == 0 is abused in saa6752hs.c, so that special - case is handled here explicitly. */ - if (ctrls->count == 0) - return 0; - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, arg); - ts_init_encoder(dev); - return 0; - case VIDIOC_G_EXT_CTRLS: - if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, arg); + return 0; +} + + +static int empress_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_reqbufs(&dev->empress_tsq, p); +} + +static int empress_querybuf(struct file *file, void *priv, + struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_querybuf(&dev->empress_tsq, b); +} + +static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_qbuf(&dev->empress_tsq, b); +} + +static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_dqbuf(&dev->empress_tsq, b, + file->f_flags & O_NONBLOCK); +} + +static int empress_streamon(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_streamon(&dev->empress_tsq); +} + +static int empress_streamoff(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + return videobuf_streamoff(&dev->empress_tsq); +} + +static int empress_s_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *ctrls) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + /* count == 0 is abused in saa6752hs.c, so that special + case is handled here explicitly. */ + if (ctrls->count == 0) return 0; - default: - return -ENOIOCTLCMD; - } + if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + + saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, ctrls); + ts_init_encoder(dev); + return 0; } -static int ts_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int empress_g_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *ctrls) { - return video_usercopy(inode, file, cmd, arg, ts_do_ioctl); + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, ctrls); + + return 0; } static const struct file_operations ts_fops = @@ -320,7 +341,7 @@ static const struct file_operations ts_fops = .read = ts_read, .poll = ts_poll, .mmap = ts_mmap, - .ioctl = ts_ioctl, + .ioctl = video_ioctl2, .llseek = no_llseek, }; @@ -333,6 +354,29 @@ static struct video_device saa7134_empress_template = .type2 = 0 /* FIXME */, .fops = &ts_fops, .minor = -1, + + .vidioc_querycap = empress_querycap, + .vidioc_enum_fmt_cap = empress_enum_fmt_cap, + .vidioc_s_fmt_cap = empress_s_fmt_cap, + .vidioc_g_fmt_cap = empress_g_fmt_cap, + .vidioc_reqbufs = empress_reqbufs, + .vidioc_querybuf = empress_querybuf, + .vidioc_qbuf = empress_qbuf, + .vidioc_dqbuf = empress_dqbuf, + .vidioc_streamon = empress_streamon, + .vidioc_streamoff = empress_streamoff, + .vidioc_s_ext_ctrls = empress_s_ext_ctrls, + .vidioc_g_ext_ctrls = empress_g_ext_ctrls, + .vidioc_enum_input = empress_enum_input, + .vidioc_g_input = empress_g_input, + .vidioc_s_input = empress_s_input, + + .vidioc_queryctrl = saa7134_queryctrl, + .vidioc_g_ctrl = saa7134_g_ctrl, + .vidioc_s_ctrl = saa7134_s_ctrl, + + .tvnorms = SAA7134_NORMS, + .current_norm = V4L2_STD_PAL, }; static void empress_signal_update(struct work_struct *work) diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 6deaad1a548..d3322c3018f 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -323,7 +323,6 @@ static int attach_inform(struct i2c_client *client) { struct saa7134_dev *dev = client->adapter->algo_data; int tuner = dev->tuner_type; - int conf = dev->tda9887_conf; struct tuner_setup tun_setup; d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", @@ -335,6 +334,7 @@ static int attach_inform(struct i2c_client *client) case 0x7a: case 0x47: case 0x71: + case 0x2d: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", @@ -360,7 +360,6 @@ static int attach_inform(struct i2c_client *client) } if (tuner != UNSET) { - tun_setup.type = tuner; tun_setup.addr = saa7134_boards[dev->board].tuner_addr; tun_setup.config = saa7134_boards[dev->board].tuner_config; @@ -372,9 +371,18 @@ static int attach_inform(struct i2c_client *client) client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); } + + if (tuner == TUNER_TDA9887) { + struct v4l2_priv_tun_config tda9887_cfg; + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &dev->tda9887_conf; + + client->driver->command(client, TUNER_SET_CONFIG, + &tda9887_cfg); + } } - client->driver->command(client, TDA9887_SET_CONFIG, &conf); return 0; } @@ -432,6 +440,7 @@ static char *i2c_devs[128] = { [ 0xa0 >> 1 ] = "eeprom", [ 0xc0 >> 1 ] = "tuner (analog)", [ 0x86 >> 1 ] = "tda9887", + [ 0x5a >> 1 ] = "remote control", }; static void do_i2c_scan(char *name, struct i2c_client *c) diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 3abaa1b8ac9..0db955c2d9b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -49,9 +49,14 @@ module_param(repeat_delay, int, 0644); MODULE_PARM_DESC(repeat_delay, "delay before key repeat started"); static int repeat_period = 33; module_param(repeat_period, int, 0644); -MODULE_PARM_DESC(repeat_period, "repeat period between" +MODULE_PARM_DESC(repeat_period, "repeat period between " "keypresses when key is down"); +static unsigned int disable_other_ir; +module_param(disable_other_ir, int, 0644); +MODULE_PARM_DESC(disable_other_ir, "disable full codes of " + "alternative remotes from other manufacturers"); + #define dprintk(fmt, arg...) if (ir_debug) \ printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) #define i2cdprintk(fmt, arg...) if (ir_debug) \ @@ -154,6 +159,45 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } + +static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char data[12]; + u32 gpio; + + struct saa7134_dev *dev = ir->c.adapter->algo_data; + + /* rising SAA7134_GPIO_GPRESCAN reads the status */ + saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN); + + gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); + + if (0x400000 & ~gpio) + return 0; /* No button press */ + + ir->c.addr = 0x5a >> 1; + + if (12 != i2c_master_recv(&ir->c, data, 12)) { + i2cdprintk("read error\n"); + return -EIO; + } + /* IR of this card normally decode signals NEC-standard from + * - Sven IHOO MT 5.1R remote. xxyye718 + * - Sven DVD HD-10xx remote. xxyyf708 + * - BBK ... + * - mayby others + * So, skip not our, if disable full codes mode. + */ + if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir) + return 0; + + *ir_key = data[9]; + *ir_raw = data[9]; + + return 1; +} + void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; @@ -260,6 +304,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: + case SAA7134_BOARD_AVERMEDIA_M102: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; mask_keydown = 0x000010; @@ -287,6 +332,16 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_BEHOLD_409FM: + case SAA7134_BOARD_BEHOLD_401: + case SAA7134_BOARD_BEHOLD_403: + case SAA7134_BOARD_BEHOLD_403FM: + case SAA7134_BOARD_BEHOLD_405: + case SAA7134_BOARD_BEHOLD_405FM: + case SAA7134_BOARD_BEHOLD_407: + case SAA7134_BOARD_BEHOLD_407FM: + case SAA7134_BOARD_BEHOLD_409: + case SAA7134_BOARD_BEHOLD_505FM: + case SAA7134_BOARD_BEHOLD_507_9FM: ir_codes = ir_codes_manli; mask_keycode = 0x001f00; mask_keyup = 0x004000; @@ -457,6 +512,12 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) ir->get_key = get_key_hvr1110; ir->ir_codes = ir_codes_hauppauge_new; break; + case SAA7134_BOARD_BEHOLD_607_9FM: + case SAA7134_BOARD_BEHOLD_M6: + snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); + ir->get_key = get_key_beholdm6xx; + ir->ir_codes = ir_codes_behold; + break; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c deleted file mode 100644 index aedf04653e0..00000000000 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * - * device driver for philips saa7134 based TV cards - * oss dsp interface - * - * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] - * 2005 conversion to standalone module: - * Ricardo Cerqueira <v4l@cerqueira.org> - * - * 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 02139, USA. - */ - -#include <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/slab.h> -#include <linux/sound.h> -#include <linux/soundcard.h> - -#include "saa7134-reg.h" -#include "saa7134.h" - -/* ------------------------------------------------------------------ */ - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"enable debug messages [oss]"); - -static unsigned int rate = 0; -module_param(rate, int, 0444); -MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)"); - -static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; -MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s)."); -module_param_array(dsp_nr, int, NULL, 0444); - -static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; -MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s)."); -module_param_array(mixer_nr, int, NULL, 0444); - -#define dprintk(fmt, arg...) if (debug) \ - printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) - - -/* ------------------------------------------------------------------ */ - -static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) -{ - if (blksize < 0x100) - blksize = 0x100; - if (blksize > 0x10000) - blksize = 0x10000; - - if (blocks < 2) - blocks = 2; - if ((blksize * blocks) > 1024*1024) - blocks = 1024*1024 / blksize; - - dev->dmasound.blocks = blocks; - dev->dmasound.blksize = blksize; - dev->dmasound.bufsize = blksize * blocks; - - dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", - blocks,blksize,blksize * blocks / 1024); - return 0; -} - -static int dsp_buffer_init(struct saa7134_dev *dev) -{ - int err; - - BUG_ON(!dev->dmasound.bufsize); - videobuf_dma_init(&dev->dmasound.dma); - err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, - (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); - if (0 != err) - return err; - return 0; -} - -static int dsp_buffer_free(struct saa7134_dev *dev) -{ - BUG_ON(!dev->dmasound.blksize); - videobuf_dma_free(&dev->dmasound.dma); - dev->dmasound.blocks = 0; - dev->dmasound.blksize = 0; - dev->dmasound.bufsize = 0; - return 0; -} - -static void dsp_dma_start(struct saa7134_dev *dev) -{ - dev->dmasound.dma_blk = 0; - dev->dmasound.dma_running = 1; - saa7134_set_dmabits(dev); -} - -static void dsp_dma_stop(struct saa7134_dev *dev) -{ - dev->dmasound.dma_blk = -1; - dev->dmasound.dma_running = 0; - saa7134_set_dmabits(dev); -} - -static int dsp_rec_start(struct saa7134_dev *dev) -{ - int err, bswap, sign; - u32 fmt, control; - unsigned long flags; - - /* prepare buffer */ - if (0 != (err = videobuf_pci_dma_map(dev->pci,&dev->dmasound.dma))) - return err; - if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) - goto fail1; - if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, - dev->dmasound.dma.sglist, - dev->dmasound.dma.sglen, - 0))) - goto fail2; - - /* sample format */ - switch (dev->dmasound.afmt) { - case AFMT_U8: - case AFMT_S8: fmt = 0x00; break; - case AFMT_U16_LE: - case AFMT_U16_BE: - case AFMT_S16_LE: - case AFMT_S16_BE: fmt = 0x01; break; - default: - err = -EINVAL; - goto fail2; - } - - switch (dev->dmasound.afmt) { - case AFMT_S8: - case AFMT_S16_LE: - case AFMT_S16_BE: sign = 1; break; - default: sign = 0; break; - } - - switch (dev->dmasound.afmt) { - case AFMT_U16_BE: - case AFMT_S16_BE: bswap = 1; break; - default: bswap = 0; break; - } - - switch (dev->pci->device) { - case PCI_DEVICE_ID_PHILIPS_SAA7134: - if (1 == dev->dmasound.channels) - fmt |= (1 << 3); - if (2 == dev->dmasound.channels) - fmt |= (3 << 3); - if (sign) - fmt |= 0x04; - fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80; - - saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff)); - saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8); - saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 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->dmasound.channels) - fmt |= (1 << 4); - if (2 == dev->dmasound.channels) - fmt |= (2 << 4); - if (!sign) - fmt |= 0x04; - saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4); - saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); - break; - } - dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", - dev->dmasound.afmt, dev->dmasound.channels, fmt, - bswap ? 'b' : '-'); - - /* dma: setup channel 6 (= AUDIO) */ - control = SAA7134_RS_CONTROL_BURST_16 | - SAA7134_RS_CONTROL_ME | - (dev->dmasound.pt.dma >> 12); - if (bswap) - control |= SAA7134_RS_CONTROL_BSWAP; - saa_writel(SAA7134_RS_BA1(6),0); - saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); - saa_writel(SAA7134_RS_PITCH(6),0); - saa_writel(SAA7134_RS_CONTROL(6),control); - - /* start dma */ - dev->dmasound.recording_on = 1; - spin_lock_irqsave(&dev->slock,flags); - dsp_dma_start(dev); - spin_unlock_irqrestore(&dev->slock,flags); - return 0; - - fail2: - saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); - fail1: - videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma); - return err; -} - -static int dsp_rec_stop(struct saa7134_dev *dev) -{ - unsigned long flags; - - dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk); - - /* stop dma */ - dev->dmasound.recording_on = 0; - spin_lock_irqsave(&dev->slock,flags); - dsp_dma_stop(dev); - spin_unlock_irqrestore(&dev->slock,flags); - - /* unlock buffer */ - saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); - videobuf_pci_dma_unmap(dev->pci,&dev->dmasound.dma); - return 0; -} - -/* ------------------------------------------------------------------ */ - -static int dsp_open(struct inode *inode, struct file *file) -{ - int minor = iminor(inode); - struct saa7134_dev *dev; - int err; - - list_for_each_entry(dev, &saa7134_devlist, devlist) - if (dev->dmasound.minor_dsp == minor) - goto found; - return -ENODEV; - found: - - mutex_lock(&dev->dmasound.lock); - err = -EBUSY; - if (dev->dmasound.users_dsp) - goto fail1; - dev->dmasound.users_dsp++; - file->private_data = dev; - - dev->dmasound.afmt = AFMT_U8; - dev->dmasound.channels = 1; - dev->dmasound.read_count = 0; - dev->dmasound.read_offset = 0; - dsp_buffer_conf(dev,PAGE_SIZE,64); - err = dsp_buffer_init(dev); - if (0 != err) - goto fail2; - - mutex_unlock(&dev->dmasound.lock); - return 0; - - fail2: - dev->dmasound.users_dsp--; - fail1: - mutex_unlock(&dev->dmasound.lock); - return err; -} - -static int dsp_release(struct inode *inode, struct file *file) -{ - struct saa7134_dev *dev = file->private_data; - - mutex_lock(&dev->dmasound.lock); - if (dev->dmasound.recording_on) - dsp_rec_stop(dev); - dsp_buffer_free(dev); - dev->dmasound.users_dsp--; - file->private_data = NULL; - mutex_unlock(&dev->dmasound.lock); - return 0; -} - -static ssize_t dsp_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct saa7134_dev *dev = file->private_data; - DECLARE_WAITQUEUE(wait, current); - unsigned int bytes; - unsigned long flags; - int err,ret = 0; - - add_wait_queue(&dev->dmasound.wq, &wait); - mutex_lock(&dev->dmasound.lock); - while (count > 0) { - /* wait for data if needed */ - if (0 == dev->dmasound.read_count) { - if (!dev->dmasound.recording_on) { - err = dsp_rec_start(dev); - if (err < 0) { - if (0 == ret) - ret = err; - break; - } - } - if (dev->dmasound.recording_on && - !dev->dmasound.dma_running) { - /* recover from overruns */ - spin_lock_irqsave(&dev->slock,flags); - dsp_dma_start(dev); - spin_unlock_irqrestore(&dev->slock,flags); - } - if (file->f_flags & O_NONBLOCK) { - if (0 == ret) - ret = -EAGAIN; - break; - } - mutex_unlock(&dev->dmasound.lock); - set_current_state(TASK_INTERRUPTIBLE); - if (0 == dev->dmasound.read_count) - schedule(); - set_current_state(TASK_RUNNING); - mutex_lock(&dev->dmasound.lock); - if (signal_pending(current)) { - if (0 == ret) - ret = -EINTR; - break; - } - } - - /* copy data to userspace */ - bytes = count; - if (bytes > dev->dmasound.read_count) - bytes = dev->dmasound.read_count; - if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset) - bytes = dev->dmasound.bufsize - dev->dmasound.read_offset; - if (copy_to_user(buffer + ret, - dev->dmasound.dma.vmalloc + dev->dmasound.read_offset, - bytes)) { - if (0 == ret) - ret = -EFAULT; - break; - } - - ret += bytes; - count -= bytes; - dev->dmasound.read_count -= bytes; - dev->dmasound.read_offset += bytes; - if (dev->dmasound.read_offset == dev->dmasound.bufsize) - dev->dmasound.read_offset = 0; - } - mutex_unlock(&dev->dmasound.lock); - remove_wait_queue(&dev->dmasound.wq, &wait); - return ret; -} - -static ssize_t dsp_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) -{ - return -EINVAL; -} - -static const char *osspcm_ioctls[] = { - "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT", - "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS", - "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER", - "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO", - "SETDUPLEX", "GETODELAY" -}; -#define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls) - -static void saa7134_oss_print_ioctl(char *name, unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "??"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'P': - printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n", - name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ? - osspcm_ioctls[_IOC_NR(cmd)] : "???"); - break; - case 'M': - printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n", - name, cmd, dir, _IOC_NR(cmd)); - break; - default: - printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", - name, cmd, dir, _IOC_NR(cmd)); - } -} - -static int dsp_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct saa7134_dev *dev = file->private_data; - void __user *argp = (void __user *) arg; - int __user *p = argp; - int val = 0; - - if (debug > 1) - saa7134_oss_print_ioctl(dev->name,cmd); - switch (cmd) { - case OSS_GETVERSION: - return put_user(SOUND_VERSION, p); - case SNDCTL_DSP_GETCAPS: - return 0; - - case SNDCTL_DSP_SPEED: - if (get_user(val, p)) - return -EFAULT; - /* fall through */ - case SOUND_PCM_READ_RATE: - return put_user(dev->dmasound.rate, p); - - case SNDCTL_DSP_STEREO: - if (get_user(val, p)) - return -EFAULT; - mutex_lock(&dev->dmasound.lock); - dev->dmasound.channels = val ? 2 : 1; - if (dev->dmasound.recording_on) { - dsp_rec_stop(dev); - dsp_rec_start(dev); - } - mutex_unlock(&dev->dmasound.lock); - return put_user(dev->dmasound.channels-1, p); - - case SNDCTL_DSP_CHANNELS: - if (get_user(val, p)) - return -EFAULT; - if (val != 1 && val != 2) - return -EINVAL; - mutex_lock(&dev->dmasound.lock); - dev->dmasound.channels = val; - if (dev->dmasound.recording_on) { - dsp_rec_stop(dev); - dsp_rec_start(dev); - } - mutex_unlock(&dev->dmasound.lock); - /* fall through */ - case SOUND_PCM_READ_CHANNELS: - return put_user(dev->dmasound.channels, p); - - case SNDCTL_DSP_GETFMTS: /* Returns a mask */ - return put_user(AFMT_U8 | AFMT_S8 | - AFMT_U16_LE | AFMT_U16_BE | - AFMT_S16_LE | AFMT_S16_BE, p); - - case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ - if (get_user(val, p)) - return -EFAULT; - switch (val) { - case AFMT_QUERY: - /* nothing to do */ - break; - case AFMT_U8: - case AFMT_S8: - case AFMT_U16_LE: - case AFMT_U16_BE: - case AFMT_S16_LE: - case AFMT_S16_BE: - mutex_lock(&dev->dmasound.lock); - dev->dmasound.afmt = val; - if (dev->dmasound.recording_on) { - dsp_rec_stop(dev); - dsp_rec_start(dev); - } - mutex_unlock(&dev->dmasound.lock); - return put_user(dev->dmasound.afmt, p); - default: - return -EINVAL; - } - - case SOUND_PCM_READ_BITS: - switch (dev->dmasound.afmt) { - case AFMT_U8: - case AFMT_S8: - return put_user(8, p); - case AFMT_U16_LE: - case AFMT_U16_BE: - case AFMT_S16_LE: - case AFMT_S16_BE: - return put_user(16, p); - default: - return -EINVAL; - } - - case SNDCTL_DSP_NONBLOCK: - file->f_flags |= O_NONBLOCK; - return 0; - - case SNDCTL_DSP_RESET: - mutex_lock(&dev->dmasound.lock); - if (dev->dmasound.recording_on) - dsp_rec_stop(dev); - mutex_unlock(&dev->dmasound.lock); - return 0; - case SNDCTL_DSP_GETBLKSIZE: - return put_user(dev->dmasound.blksize, p); - - case SNDCTL_DSP_SETFRAGMENT: - if (get_user(val, p)) - return -EFAULT; - if (dev->dmasound.recording_on) - return -EBUSY; - dsp_buffer_free(dev); - /* used to be arg >> 16 instead of val >> 16; fixed */ - dsp_buffer_conf(dev,1 << (val & 0xffff), (val >> 16) & 0xffff); - dsp_buffer_init(dev); - return 0; - - case SNDCTL_DSP_SYNC: - /* NOP */ - return 0; - - case SNDCTL_DSP_GETISPACE: - { - audio_buf_info info; - info.fragsize = dev->dmasound.blksize; - info.fragstotal = dev->dmasound.blocks; - info.bytes = dev->dmasound.read_count; - info.fragments = info.bytes / info.fragsize; - if (copy_to_user(argp, &info, sizeof(info))) - return -EFAULT; - return 0; - } - default: - return -EINVAL; - } -} - -static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait) -{ - struct saa7134_dev *dev = file->private_data; - unsigned int mask = 0; - - poll_wait(file, &dev->dmasound.wq, wait); - - if (0 == dev->dmasound.read_count) { - mutex_lock(&dev->dmasound.lock); - if (!dev->dmasound.recording_on) - dsp_rec_start(dev); - mutex_unlock(&dev->dmasound.lock); - } else - mask |= (POLLIN | POLLRDNORM); - return mask; -} - -const struct file_operations saa7134_dsp_fops = { - .owner = THIS_MODULE, - .open = dsp_open, - .release = dsp_release, - .read = dsp_read, - .write = dsp_write, - .ioctl = dsp_ioctl, - .poll = dsp_poll, - .llseek = no_llseek, -}; - -/* ------------------------------------------------------------------ */ - -static int -mixer_recsrc_7134(struct saa7134_dev *dev) -{ - int analog_io,rate; - - switch (dev->dmasound.input) { - case TV: - saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); - saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); - break; - case LINE1: - case LINE2: - case LINE2_LEFT: - analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08; - rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03; - saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); - saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); - saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); - break; - } - return 0; -} - -static int -mixer_recsrc_7133(struct saa7134_dev *dev) -{ - u32 anabar, xbarin; - - xbarin = 0x03; // adc - anabar = 0; - switch (dev->dmasound.input) { - case TV: - xbarin = 0; // Demodulator - anabar = 2; // DACs - break; - case LINE1: - anabar = 0; // aux1, aux1 - break; - case LINE2: - case LINE2_LEFT: - anabar = 9; // aux2, aux2 - break; - } - /* output xbar always main channel */ - saa_dsp_writel(dev, 0x46c >> 2, 0xbbbb10); - saa_dsp_writel(dev, 0x464 >> 2, xbarin); - saa_writel(0x594 >> 2, anabar); - - return 0; -} - -static int -mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src) -{ - static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; - - dev->dmasound.count++; - dev->dmasound.input = src; - dprintk("mixer input = %s\n",iname[dev->dmasound.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: - case LINE2_LEFT: - 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) -{ - int minor = iminor(inode); - struct saa7134_dev *dev; - - list_for_each_entry(dev, &saa7134_devlist, devlist) - if (dev->dmasound.minor_mixer == minor) { - file->private_data = dev; - return 0; - } - return -ENODEV; -} - -static int mixer_release(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - return 0; -} - -static int mixer_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct saa7134_dev *dev = file->private_data; - enum saa7134_audio_in input; - int val,ret; - void __user *argp = (void __user *) arg; - int __user *p = argp; - - if (debug > 1) - saa7134_oss_print_ioctl(dev->name,cmd); - switch (cmd) { - case OSS_GETVERSION: - return put_user(SOUND_VERSION, p); - case SOUND_MIXER_INFO: - { - mixer_info info; - memset(&info,0,sizeof(info)); - strlcpy(info.id, "TV audio", sizeof(info.id)); - strlcpy(info.name, dev->name, sizeof(info.name)); - info.modify_counter = dev->dmasound.count; - if (copy_to_user(argp, &info, sizeof(info))) - return -EFAULT; - return 0; - } - case SOUND_OLD_MIXER_INFO: - { - _old_mixer_info info; - memset(&info,0,sizeof(info)); - strlcpy(info.id, "TV audio", sizeof(info.id)); - strlcpy(info.name, dev->name, sizeof(info.name)); - if (copy_to_user(argp, &info, sizeof(info))) - return -EFAULT; - return 0; - } - case MIXER_READ(SOUND_MIXER_CAPS): - return put_user(SOUND_CAP_EXCL_INPUT, p); - case MIXER_READ(SOUND_MIXER_STEREODEVS): - return put_user(0, p); - case MIXER_READ(SOUND_MIXER_RECMASK): - case MIXER_READ(SOUND_MIXER_DEVMASK): - val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; - if (32000 == dev->dmasound.rate) - val |= SOUND_MASK_VIDEO; - return put_user(val, p); - - case MIXER_WRITE(SOUND_MIXER_RECSRC): - if (get_user(val, p)) - return -EFAULT; - input = dev->dmasound.input; - if (32000 == dev->dmasound.rate && - val & SOUND_MASK_VIDEO && dev->dmasound.input != TV) - input = TV; - if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1) - input = LINE1; - if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2) - input = LINE2; - if (input != dev->dmasound.input) - mixer_recsrc(dev,input); - /* fall throuth */ - case MIXER_READ(SOUND_MIXER_RECSRC): - switch (dev->dmasound.input) { - case TV: ret = SOUND_MASK_VIDEO; break; - case LINE1: ret = SOUND_MASK_LINE1; break; - case LINE2: ret = SOUND_MASK_LINE2; break; - default: ret = 0; - } - return put_user(ret, p); - - case MIXER_WRITE(SOUND_MIXER_VIDEO): - case MIXER_READ(SOUND_MIXER_VIDEO): - if (32000 != dev->dmasound.rate) - return -EINVAL; - return put_user(100 | 100 << 8, p); - - case MIXER_WRITE(SOUND_MIXER_LINE1): - if (get_user(val, p)) - return -EFAULT; - val &= 0xff; - val = (val <= 50) ? 50 : 100; - dev->dmasound.line1 = val; - mixer_level(dev,LINE1,dev->dmasound.line1); - /* fall throuth */ - case MIXER_READ(SOUND_MIXER_LINE1): - return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p); - - case MIXER_WRITE(SOUND_MIXER_LINE2): - if (get_user(val, p)) - return -EFAULT; - val &= 0xff; - val = (val <= 50) ? 50 : 100; - dev->dmasound.line2 = val; - mixer_level(dev,LINE2,dev->dmasound.line2); - /* fall throuth */ - case MIXER_READ(SOUND_MIXER_LINE2): - return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p); - - default: - return -EINVAL; - } -} - -const struct file_operations saa7134_mixer_fops = { - .owner = THIS_MODULE, - .open = mixer_open, - .release = mixer_release, - .ioctl = mixer_ioctl, - .llseek = no_llseek, -}; - -/* ------------------------------------------------------------------ */ - -static irqreturn_t saa7134_oss_irq(int irq, void *dev_id) -{ - struct saa7134_dmasound *dmasound = dev_id; - struct saa7134_dev *dev = dmasound->priv_data; - unsigned long report, status; - int loop, handled = 0; - - for (loop = 0; loop < 10; loop++) { - report = saa_readl(SAA7134_IRQ_REPORT); - status = saa_readl(SAA7134_IRQ_STATUS); - - if (report & SAA7134_IRQ_REPORT_DONE_RA3) { - handled = 1; - saa_writel(SAA7134_IRQ_REPORT,report); - saa7134_irq_oss_done(dev, status); - } else { - goto out; - } - } - - if (loop == 10) { - dprintk("error! looping IRQ!"); - } -out: - return IRQ_RETVAL(handled); -} - -int saa7134_oss_init1(struct saa7134_dev *dev) -{ - - if ((request_irq(dev->pci->irq, saa7134_oss_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, - (void*) &dev->dmasound)) < 0) - return -1; - - /* general */ - mutex_init(&dev->dmasound.lock); - init_waitqueue_head(&dev->dmasound.wq); - - switch (dev->pci->device) { - case PCI_DEVICE_ID_PHILIPS_SAA7133: - 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->dmasound.rate = 32000; - if (rate) - dev->dmasound.rate = rate; - dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000; - - /* mixer */ - dev->dmasound.line1 = 50; - dev->dmasound.line2 = 50; - mixer_level(dev,LINE1,dev->dmasound.line1); - mixer_level(dev,LINE2,dev->dmasound.line2); - mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2); - - return 0; -} - -int saa7134_oss_fini(struct saa7134_dev *dev) -{ - /* nothing */ - return 0; -} - -void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) -{ - int next_blk, reg = 0; - - spin_lock(&dev->slock); - if (UNSET == dev->dmasound.dma_blk) { - dprintk("irq: recording stopped\n"); - goto done; - } - if (0 != (status & 0x0f000000)) - dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); - if (0 == (status & 0x10000000)) { - /* odd */ - if (0 == (dev->dmasound.dma_blk & 0x01)) - reg = SAA7134_RS_BA1(6); - } else { - /* even */ - if (1 == (dev->dmasound.dma_blk & 0x01)) - reg = SAA7134_RS_BA2(6); - } - if (0 == reg) { - dprintk("irq: field oops [%s]\n", - (status & 0x10000000) ? "even" : "odd"); - goto done; - } - if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { - dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count, - dev->dmasound.bufsize); - dsp_dma_stop(dev); - goto done; - } - - /* next block addr */ - next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; - saa_writel(reg,next_blk * dev->dmasound.blksize); - if (debug > 2) - dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", - (status & 0x10000000) ? "even" : "odd ", next_blk, - next_blk * dev->dmasound.blksize); - - /* update status & wake waiting readers */ - dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks; - dev->dmasound.read_count += dev->dmasound.blksize; - wake_up(&dev->dmasound.wq); - - done: - spin_unlock(&dev->slock); -} - -static int saa7134_dsp_create(struct saa7134_dev *dev) -{ - int err; - - err = dev->dmasound.minor_dsp = - register_sound_dsp(&saa7134_dsp_fops, - dsp_nr[dev->nr]); - if (err < 0) { - goto fail; - } - printk(KERN_INFO "%s: registered device dsp%d\n", - dev->name,dev->dmasound.minor_dsp >> 4); - - err = dev->dmasound.minor_mixer = - register_sound_mixer(&saa7134_mixer_fops, - mixer_nr[dev->nr]); - if (err < 0) - goto fail; - printk(KERN_INFO "%s: registered device mixer%d\n", - dev->name,dev->dmasound.minor_mixer >> 4); - - return 0; - -fail: - unregister_sound_dsp(dev->dmasound.minor_dsp); - return 0; - - -} - -static int oss_device_init(struct saa7134_dev *dev) -{ - dev->dmasound.priv_data = dev; - saa7134_oss_init1(dev); - saa7134_dsp_create(dev); - return 1; -} - -static int oss_device_exit(struct saa7134_dev *dev) -{ - - unregister_sound_mixer(dev->dmasound.minor_mixer); - unregister_sound_dsp(dev->dmasound.minor_dsp); - - saa7134_oss_fini(dev); - - if (dev->pci->irq > 0) { - synchronize_irq(dev->pci->irq); - free_irq(dev->pci->irq,&dev->dmasound); - } - - dev->dmasound.priv_data = NULL; - return 1; -} - -static int saa7134_oss_init(void) -{ - struct saa7134_dev *dev = NULL; - struct list_head *list; - - if (!saa7134_dmasound_init && !saa7134_dmasound_exit) { - saa7134_dmasound_init = oss_device_init; - saa7134_dmasound_exit = oss_device_exit; - } else { - printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n"); - return -EBUSY; - } - - printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n"); - - - list_for_each(list,&saa7134_devlist) { - dev = list_entry(list, struct saa7134_dev, devlist); - if (dev->dmasound.priv_data == NULL) { - oss_device_init(dev); - } else { - printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name); - return -EBUSY; - } - } - - if (dev == NULL) - printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n"); - - return 0; - -} - -static void saa7134_oss_exit(void) -{ - struct saa7134_dev *dev; - - list_for_each_entry(dev, &saa7134_devlist, devlist) { - /* Device isn't registered by OSS, probably ALSA's */ - if (!dev->dmasound.minor_dsp) - continue; - - oss_device_exit(dev); - } - - saa7134_dmasound_init = NULL; - saa7134_dmasound_exit = NULL; - - printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n"); - - return; -} - -/* We initialize this late, to make sure the sound system is up and running */ -late_initcall(saa7134_oss_init); -module_exit(saa7134_oss_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 4b63ad3e846..f1b8fcaeb43 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c @@ -47,7 +47,7 @@ static int buffer_activate(struct saa7134_dev *dev, { dprintk("buffer_activate [%p]",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; if (NULL == next) @@ -91,7 +91,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -121,7 +121,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); saa_writel(SAA7134_RS_CONTROL(5),control); - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -242,7 +242,7 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) if ((status & 0x100000) != 0x100000) goto done; } - saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->ts_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->ts_q); diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index f8e304c7623..4e9810469ae 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -163,32 +163,6 @@ static struct saa7134_tvaudio tvaudio[] = { /* ------------------------------------------------------------------ */ -static void tvaudio_init(struct saa7134_dev *dev) -{ - int clock = saa7134_boards[dev->board].audio_clock; - - if (UNSET != audio_clock_override) - clock = audio_clock_override; - - /* init all audio registers */ - saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00); - if (need_resched()) - schedule(); - else - udelay(10); - - saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff); - saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff); - saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff); - /* frame locked audio is mandatory for NICAM */ - saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01); - - saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14); - saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50); - saa_writeb(SAA7134_MONITOR_SELECT, 0xa0); - saa_writeb(SAA7134_FM_DEMATRIX, 0x80); -} - static u32 tvaudio_carr2reg(u32 carrier) { u64 a = carrier; @@ -517,9 +491,13 @@ static int tvaudio_thread(void *data) dev->thread.scan1 = dev->thread.scan2; dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1); dev->tvaudio = NULL; - tvaudio_init(dev); + + saa_writeb(SAA7134_MONITOR_SELECT, 0xa0); + saa_writeb(SAA7134_FM_DEMATRIX, 0x80); + if (dev->ctl_automute) dev->automute = 1; + mute_input_7134(dev); /* give the tuner some time */ @@ -784,27 +762,15 @@ static int mute_input_7133(struct saa7134_dev *dev) static int tvaudio_thread_ddep(void *data) { struct saa7134_dev *dev = data; - u32 value, norms, clock; + u32 value, norms; set_freezable(); - - clock = saa7134_boards[dev->board].audio_clock; - if (UNSET != audio_clock_override) - clock = audio_clock_override; - saa_writel(0x598 >> 2, clock); - - /* unmute */ - saa_dsp_writel(dev, 0x474 >> 2, 0x00); - saa_dsp_writel(dev, 0x450 >> 2, 0x00); - for (;;) { tvaudio_sleep(dev,-1); if (kthread_should_stop()) goto done; - restart: - try_to_freeze(); dev->thread.scan1 = dev->thread.scan2; @@ -978,6 +944,38 @@ int saa7134_tvaudio_getstereo(struct saa7134_dev *dev) return retval; } +void saa7134_tvaudio_init(struct saa7134_dev *dev) +{ + int clock = saa7134_boards[dev->board].audio_clock; + + if (UNSET != audio_clock_override) + clock = audio_clock_override; + + switch (dev->pci->device) { + case PCI_DEVICE_ID_PHILIPS_SAA7134: + /* init all audio registers */ + saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x00); + if (need_resched()) + schedule(); + else + udelay(10); + + saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff); + saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff); + saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff); + /* frame locked audio is mandatory for NICAM */ + saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01); + saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14); + saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50); + break; + case PCI_DEVICE_ID_PHILIPS_SAA7133: + case PCI_DEVICE_ID_PHILIPS_SAA7135: + saa_writel(0x598 >> 2, clock); + saa_dsp_writel(dev, 0x474 >> 2, 0x00); + saa_dsp_writel(dev, 0x450 >> 2, 0x00); + } +} + int saa7134_tvaudio_init2(struct saa7134_dev *dev) { int (*my_thread)(void *data) = NULL; @@ -994,6 +992,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) dev->thread.thread = NULL; if (my_thread) { + saa7134_tvaudio_init(dev); /* start tvaudio thread */ dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name); if (IS_ERR(dev->thread.thread)) { diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c index 81a2aedeff5..f0d5ed9c2b0 100644 --- a/drivers/media/video/saa7134/saa7134-vbi.c +++ b/drivers/media/video/saa7134/saa7134-vbi.c @@ -85,7 +85,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long control,base; dprintk("buffer_activate [%p]\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; task_init(dev,buf,TASK_A); @@ -136,7 +136,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (buf->vb.size != size) saa7134_dma_free(q,buf); - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; @@ -154,7 +154,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; @@ -240,7 +240,7 @@ void saa7134_irq_vbi_done(struct saa7134_dev *dev, unsigned long status) goto done; dev->vbi_q.curr->vb.field_count = dev->vbi_fieldcount; - saa7134_buffer_finish(dev,&dev->vbi_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->vbi_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->vbi_q); diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 3b9ffb4b648..1184d359e84 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -38,7 +38,7 @@ /* ------------------------------------------------------------------ */ -static unsigned int video_debug = 0; +unsigned int video_debug; static unsigned int gbuffers = 8; static unsigned int noninterlaced = 0; static unsigned int gbufsize = 720*576*4; @@ -54,7 +54,7 @@ module_param_string(secam, secam, sizeof(secam), 0644); MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc"); -#define dprintk(fmt, arg...) if (video_debug) \ +#define dprintk(fmt, arg...) if (video_debug&0x04) \ printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) /* ------------------------------------------------------------------ */ @@ -540,9 +540,8 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) /* ------------------------------------------------------------------ */ -void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) +static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) { - dprintk("set tv norm = %s\n",norm->name); dev->tvnorm = norm; @@ -561,7 +560,6 @@ void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) dev->crop_current = dev->crop_defrect; saa7134_set_tvnorm_hw(dev); - } static void video_mux(struct saa7134_dev *dev, int input) @@ -945,7 +943,7 @@ static int buffer_activate(struct saa7134_dev *dev, unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */ dprintk("buffer_activate buf=%p\n",buf); - buf->vb.state = STATE_ACTIVE; + buf->vb.state = VIDEOBUF_ACTIVE; buf->top_seen = 0; set_size(dev,TASK_A,buf->vb.width,buf->vb.height, @@ -1054,7 +1052,7 @@ static int buffer_prepare(struct videobuf_queue *q, saa7134_dma_free(q,buf); } - if (STATE_NEEDS_INIT == buf->vb.state) { + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = fh->width; @@ -1074,7 +1072,7 @@ static int buffer_prepare(struct videobuf_queue *q, if (err) goto oops; } - buf->vb.state = STATE_PREPARED; + buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; @@ -1119,8 +1117,10 @@ static struct videobuf_queue_ops video_qops = { /* ------------------------------------------------------------------ */ -static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) +int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) { + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; const struct v4l2_queryctrl* ctrl; ctrl = ctrl_by_id(c->id); @@ -1165,17 +1165,27 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c) } return 0; } +EXPORT_SYMBOL_GPL(saa7134_g_ctrl); -static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, - struct v4l2_control *c) +int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c) { const struct v4l2_queryctrl* ctrl; + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; unsigned long flags; int restart_overlay = 0; + int err = -EINVAL; + + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; + + mutex_lock(&dev->lock); ctrl = ctrl_by_id(c->id); if (NULL == ctrl) - return -EINVAL; + goto error; + dprintk("set_control name=%s val=%d\n",ctrl->name,c->value); switch (ctrl->type) { case V4L2_CTRL_TYPE_BOOLEAN: @@ -1236,18 +1246,26 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, restart_overlay = 1; break; case V4L2_CID_PRIVATE_AUTOMUTE: + { + struct v4l2_priv_tun_config tda9887_cfg; + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &dev->tda9887_conf; + dev->ctl_automute = c->value; if (dev->tda9887_conf) { if (dev->ctl_automute) dev->tda9887_conf |= TDA9887_AUTOMUTE; else dev->tda9887_conf &= ~TDA9887_AUTOMUTE; - saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG, - &dev->tda9887_conf); + + saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, + &tda9887_cfg); } break; + } default: - return -EINVAL; + goto error; } if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) { spin_lock_irqsave(&dev->slock,flags); @@ -1255,8 +1273,13 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh, start_preview(dev,fh); spin_unlock_irqrestore(&dev->slock,flags); } - return 0; + err = 0; + +error: + mutex_unlock(&dev->lock); + return err; } +EXPORT_SYMBOL_GPL(saa7134_s_ctrl); /* ------------------------------------------------------------------ */ @@ -1413,8 +1436,8 @@ video_poll(struct file *file, struct poll_table_struct *wait) return POLLERR; poll_wait(file, &buf->done, wait); - if (buf->state == STATE_DONE || - buf->state == STATE_ERROR) + if (buf->state == VIDEOBUF_DONE || + buf->state == VIDEOBUF_ERROR) return POLLIN|POLLRDNORM; return 0; } @@ -1445,10 +1468,7 @@ static int video_release(struct inode *inode, struct file *file) /* stop vbi capture */ if (res_check(fh, RESOURCE_VBI)) { - if (fh->vbi.streaming) - videobuf_streamoff(&fh->vbi); - if (fh->vbi.reading) - videobuf_read_stop(&fh->vbi); + videobuf_stop(&fh->vbi); res_free(dev,fh,RESOURCE_VBI); } @@ -1481,8 +1501,11 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma) /* ------------------------------------------------------------------ */ -static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f) +static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv, + struct v4l2_format *f) { + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; struct saa7134_tvnorm *norm = dev->tvnorm; f->fmt.vbi.sampling_rate = 6750000 * 4; @@ -1495,837 +1518,805 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f) f->fmt.vbi.count[1] = f->fmt.vbi.count[0]; f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */ + return 0; } -static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, - struct v4l2_format *f) +static int saa7134_g_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) { - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->cap.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - return 0; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - f->fmt.win = fh->win; - return 0; - case V4L2_BUF_TYPE_VBI_CAPTURE: - saa7134_vbi_fmt(dev,f); - return 0; - default: - return -EINVAL; - } + struct saa7134_fh *fh = priv; + + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->cap.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + return 0; } -static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, - struct v4l2_format *f) +static int saa7134_g_fmt_overlay(struct file *file, void *priv, + struct v4l2_format *f) { - int err; + struct saa7134_fh *fh = priv; - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - { - struct saa7134_format *fmt; - enum v4l2_field field; - unsigned int maxw, maxh; + if (saa7134_no_overlay > 0) { + printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + return -EINVAL; + } + f->fmt.win = fh->win; - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; + return 0; +} - field = f->fmt.pix.field; - maxw = min(dev->crop_current.width*4, dev->crop_bounds.width); - maxh = min(dev->crop_current.height*4, dev->crop_bounds.height); +static int saa7134_try_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + struct saa7134_format *fmt; + enum v4l2_field field; + unsigned int maxw, maxh; - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } + fmt = format_by_fourcc(f->fmt.pix.pixelformat); + if (NULL == fmt) + return -EINVAL; - f->fmt.pix.field = field; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - f->fmt.pix.width &= ~0x03; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; + field = f->fmt.pix.field; + maxw = min(dev->crop_current.width*4, dev->crop_bounds.width); + maxh = min(dev->crop_current.height*4, dev->crop_bounds.height); - return 0; + if (V4L2_FIELD_ANY == field) { + field = (f->fmt.pix.height > maxh/2) + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_BOTTOM; } - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - err = verify_preview(dev,&f->fmt.win); - if (0 != err) - return err; - return 0; - case V4L2_BUF_TYPE_VBI_CAPTURE: - saa7134_vbi_fmt(dev,f); - return 0; + switch (field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + maxh = maxh / 2; + break; + case V4L2_FIELD_INTERLACED: + break; default: return -EINVAL; } + + f->fmt.pix.field = field; + if (f->fmt.pix.width < 48) + f->fmt.pix.width = 48; + if (f->fmt.pix.height < 32) + f->fmt.pix.height = 32; + if (f->fmt.pix.width > maxw) + f->fmt.pix.width = maxw; + if (f->fmt.pix.height > maxh) + f->fmt.pix.height = maxh; + f->fmt.pix.width &= ~0x03; + f->fmt.pix.bytesperline = + (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = + f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; } -static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, - struct v4l2_format *f) +static int saa7134_try_fmt_overlay(struct file *file, void *priv, + struct v4l2_format *f) { - unsigned long flags; - int err; - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - err = saa7134_try_fmt(dev,fh,f); - if (0 != err) - return err; - - fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->cap.field = f->fmt.pix.field; - return 0; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - err = verify_preview(dev,&f->fmt.win); - if (0 != err) - return err; - - mutex_lock(&dev->lock); - fh->win = f->fmt.win; - fh->nclips = f->fmt.win.clipcount; - if (fh->nclips > 8) - fh->nclips = 8; - if (copy_from_user(fh->clips,f->fmt.win.clips, - sizeof(struct v4l2_clip)*fh->nclips)) { - mutex_unlock(&dev->lock); - return -EFAULT; - } + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; - if (res_check(fh, RESOURCE_OVERLAY)) { - spin_lock_irqsave(&dev->slock,flags); - stop_preview(dev,fh); - start_preview(dev,fh); - spin_unlock_irqrestore(&dev->slock,flags); - } - mutex_unlock(&dev->lock); - return 0; - case V4L2_BUF_TYPE_VBI_CAPTURE: - saa7134_vbi_fmt(dev,f); - return 0; - default: + if (saa7134_no_overlay > 0) { + printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } + + return verify_preview(dev, &f->fmt.win); } -int saa7134_common_ioctl(struct saa7134_dev *dev, - unsigned int cmd, void *arg) +static int saa7134_s_fmt_cap(struct file *file, void *priv, + struct v4l2_format *f) { + struct saa7134_fh *fh = priv; int err; - switch (cmd) { - case VIDIOC_QUERYCTRL: - { - const struct v4l2_queryctrl *ctrl; - struct v4l2_queryctrl *c = arg; + err = saa7134_try_fmt_cap(file, priv, f); + if (0 != err) + return err; - if ((c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) && - (c->id < V4L2_CID_PRIVATE_BASE || - c->id >= V4L2_CID_PRIVATE_LASTP1)) - return -EINVAL; - ctrl = ctrl_by_id(c->id); - *c = (NULL != ctrl) ? *ctrl : no_ctrl; - return 0; + fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->cap.field = f->fmt.pix.field; + return 0; +} + +static int saa7134_s_fmt_overlay(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int err; + unsigned int flags; + + if (saa7134_no_overlay > 0) { + printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + return -EINVAL; } - case VIDIOC_G_CTRL: - return get_control(dev,arg); - case VIDIOC_S_CTRL: - { - mutex_lock(&dev->lock); - err = set_control(dev,NULL,arg); - mutex_unlock(&dev->lock); + err = verify_preview(dev, &f->fmt.win); + if (0 != err) return err; - } - /* --- input switching --------------------------------------- */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - unsigned int n; - n = i->index; - if (n >= SAA7134_INPUT_MAX) - return -EINVAL; - if (NULL == card_in(dev,i->index).name) - return -EINVAL; - memset(i,0,sizeof(*i)); - i->index = n; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name,card_in(dev,n).name); - if (card_in(dev,n).tv) - i->type = V4L2_INPUT_TYPE_TUNER; - i->audioset = 1; - if (n == dev->ctl_input) { - int v1 = saa_readb(SAA7134_STATUS_VIDEO1); - int v2 = saa_readb(SAA7134_STATUS_VIDEO2); - - if (0 != (v1 & 0x40)) - i->status |= V4L2_IN_ST_NO_H_LOCK; - if (0 != (v2 & 0x40)) - i->status |= V4L2_IN_ST_NO_SYNC; - if (0 != (v2 & 0x0e)) - i->status |= V4L2_IN_ST_MACROVISION; - } - for (n = 0; n < TVNORMS; n++) - i->std |= tvnorms[n].id; - return 0; - } - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = dev->ctl_input; - return 0; - } - case VIDIOC_S_INPUT: - { - int *i = arg; + mutex_lock(&dev->lock); - if (*i < 0 || *i >= SAA7134_INPUT_MAX) - return -EINVAL; - if (NULL == card_in(dev,*i).name) - return -EINVAL; - mutex_lock(&dev->lock); - video_mux(dev,*i); + fh->win = f->fmt.win; + fh->nclips = f->fmt.win.clipcount; + + if (fh->nclips > 8) + fh->nclips = 8; + + if (copy_from_user(fh->clips, f->fmt.win.clips, + sizeof(struct v4l2_clip)*fh->nclips)) { mutex_unlock(&dev->lock); - return 0; + return -EFAULT; } + if (res_check(fh, RESOURCE_OVERLAY)) { + spin_lock_irqsave(&dev->slock, flags); + stop_preview(dev, fh); + start_preview(dev, fh); + spin_unlock_irqrestore(&dev->slock, flags); } + + mutex_unlock(&dev->lock); return 0; } -EXPORT_SYMBOL(saa7134_common_ioctl); -/* - * This function is _not_ called directly, but from - * video_generic_ioctl (and maybe others). userspace - * copying is done already, arg is a kernel pointer. - */ -static int video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { - struct saa7134_fh *fh = file->private_data; + const struct v4l2_queryctrl *ctrl; + + if ((c->id < V4L2_CID_BASE || + c->id >= V4L2_CID_LASTP1) && + (c->id < V4L2_CID_PRIVATE_BASE || + c->id >= V4L2_CID_PRIVATE_LASTP1)) + return -EINVAL; + ctrl = ctrl_by_id(c->id); + *c = (NULL != ctrl) ? *ctrl : no_ctrl; + return 0; +} +EXPORT_SYMBOL_GPL(saa7134_queryctrl); + +static int saa7134_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + unsigned int n; + + n = i->index; + if (n >= SAA7134_INPUT_MAX) + return -EINVAL; + if (NULL == card_in(dev, i->index).name) + return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = n; + i->type = V4L2_INPUT_TYPE_CAMERA; + strcpy(i->name, card_in(dev, n).name); + if (card_in(dev, n).tv) + i->type = V4L2_INPUT_TYPE_TUNER; + i->audioset = 1; + if (n == dev->ctl_input) { + int v1 = saa_readb(SAA7134_STATUS_VIDEO1); + int v2 = saa_readb(SAA7134_STATUS_VIDEO2); + + if (0 != (v1 & 0x40)) + i->status |= V4L2_IN_ST_NO_H_LOCK; + if (0 != (v2 & 0x40)) + i->status |= V4L2_IN_ST_NO_SYNC; + if (0 != (v2 & 0x0e)) + i->status |= V4L2_IN_ST_MACROVISION; + } + i->std = SAA7134_NORMS; + return 0; +} + +static int saa7134_g_input(struct file *file, void *priv, unsigned int *i) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + *i = dev->ctl_input; + return 0; +} + +static int saa7134_s_input(struct file *file, void *priv, unsigned int i) +{ + struct saa7134_fh *fh = priv; struct saa7134_dev *dev = fh->dev; - unsigned long flags; int err; - if (video_debug > 1) - v4l_print_ioctl(dev->name,cmd); - - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - err = v4l2_prio_check(&dev->prio,&fh->prio); - if (0 != err) - return err; - } + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - unsigned int tuner_type = dev->tuner_type; - - memset(cap,0,sizeof(*cap)); - strcpy(cap->driver, "saa7134"); - strlcpy(cap->card, saa7134_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); - cap->version = SAA7134_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - V4L2_CAP_TUNER; - if (saa7134_no_overlay <= 0) { - cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; - } + if (i < 0 || i >= SAA7134_INPUT_MAX) + return -EINVAL; + if (NULL == card_in(dev, i).name) + return -EINVAL; + mutex_lock(&dev->lock); + video_mux(dev, i); + mutex_unlock(&dev->lock); + return 0; +} - if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) - cap->capabilities &= ~V4L2_CAP_TUNER; +static int saa7134_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + unsigned int tuner_type = dev->tuner_type; + + strcpy(cap->driver, "saa7134"); + strlcpy(cap->card, saa7134_boards[dev->board].name, + sizeof(cap->card)); + sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); + cap->version = SAA7134_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VBI_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | + V4L2_CAP_TUNER; + if (saa7134_no_overlay <= 0) + cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; + + if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) + cap->capabilities &= ~V4L2_CAP_TUNER; return 0; - } +} - /* --- tv standards ------------------------------------------ */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - unsigned int i; +static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + unsigned long flags; + unsigned int i; + v4l2_std_id fixup; + int err; - i = e->index; - if (i >= TVNORMS) - return -EINVAL; - err = v4l2_video_std_construct(e, tvnorms[e->index].id, - tvnorms[e->index].name); - e->index = i; - if (err < 0) - return err; - return 0; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; - *id = dev->tvnorm->id; - return 0; - } - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - unsigned int i; - v4l2_std_id fixup; + for (i = 0; i < TVNORMS; i++) + if (*id == tvnorms[i].id) + break; + if (i == TVNORMS) for (i = 0; i < TVNORMS; i++) - if (*id == tvnorms[i].id) + if (*id & tvnorms[i].id) break; - if (i == TVNORMS) - for (i = 0; i < TVNORMS; i++) - if (*id & tvnorms[i].id) - break; - if (i == TVNORMS) - return -EINVAL; - if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { - if (secam[0] == 'L' || secam[0] == 'l') { - if (secam[1] == 'C' || secam[1] == 'c') - fixup = V4L2_STD_SECAM_LC; - else - fixup = V4L2_STD_SECAM_L; - } else { - if (secam[0] == 'D' || secam[0] == 'd') - fixup = V4L2_STD_SECAM_DK; - else - fixup = V4L2_STD_SECAM; - } - for (i = 0; i < TVNORMS; i++) - if (fixup == tvnorms[i].id) - break; + if (i == TVNORMS) + return -EINVAL; + + if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) { + if (secam[0] == 'L' || secam[0] == 'l') { + if (secam[1] == 'C' || secam[1] == 'c') + fixup = V4L2_STD_SECAM_LC; + else + fixup = V4L2_STD_SECAM_L; + } else { + if (secam[0] == 'D' || secam[0] == 'd') + fixup = V4L2_STD_SECAM_DK; + else + fixup = V4L2_STD_SECAM; } - mutex_lock(&dev->lock); - if (res_check(fh, RESOURCE_OVERLAY)) { - spin_lock_irqsave(&dev->slock,flags); - stop_preview(dev,fh); - spin_unlock_irqrestore(&dev->slock, flags); - - set_tvnorm(dev,&tvnorms[i]); - - spin_lock_irqsave(&dev->slock, flags); - start_preview(dev,fh); - spin_unlock_irqrestore(&dev->slock,flags); - } else - set_tvnorm(dev,&tvnorms[i]); - saa7134_tvaudio_do_scan(dev); - mutex_unlock(&dev->lock); - return 0; + for (i = 0; i < TVNORMS; i++) + if (fixup == tvnorms[i].id) + break; } - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cap = arg; + *id = tvnorms[i].id; - if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - cap->bounds = dev->crop_bounds; - cap->defrect = dev->crop_defrect; - cap->pixelaspect.numerator = 1; - cap->pixelaspect.denominator = 1; - if (dev->tvnorm->id & V4L2_STD_525_60) { - cap->pixelaspect.numerator = 11; - cap->pixelaspect.denominator = 10; - } - if (dev->tvnorm->id & V4L2_STD_625_50) { - cap->pixelaspect.numerator = 54; - cap->pixelaspect.denominator = 59; - } - return 0; - } + mutex_lock(&dev->lock); + if (res_check(fh, RESOURCE_OVERLAY)) { + spin_lock_irqsave(&dev->slock, flags); + stop_preview(dev, fh); + spin_unlock_irqrestore(&dev->slock, flags); - case VIDIOC_G_CROP: - { - struct v4l2_crop * crop = arg; + set_tvnorm(dev, &tvnorms[i]); - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - crop->c = dev->crop_current; - return 0; - } - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = arg; - struct v4l2_rect *b = &dev->crop_bounds; + spin_lock_irqsave(&dev->slock, flags); + start_preview(dev, fh); + spin_unlock_irqrestore(&dev->slock, flags); + } else + set_tvnorm(dev, &tvnorms[i]); - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) - return -EINVAL; - if (crop->c.height < 0) - return -EINVAL; - if (crop->c.width < 0) - return -EINVAL; + saa7134_tvaudio_do_scan(dev); + mutex_unlock(&dev->lock); + return 0; +} - if (res_locked(fh->dev,RESOURCE_OVERLAY)) - return -EBUSY; - if (res_locked(fh->dev,RESOURCE_VIDEO)) - return -EBUSY; +static int saa7134_cropcap(struct file *file, void *priv, + struct v4l2_cropcap *cap) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; - if (crop->c.top < b->top) - crop->c.top = b->top; - if (crop->c.top > b->top + b->height) - crop->c.top = b->top + b->height; - if (crop->c.height > b->top - crop->c.top + b->height) - crop->c.height = b->top - crop->c.top + b->height; - - if (crop->c.left < b->left) - crop->c.left = b->left; - if (crop->c.left > b->left + b->width) - crop->c.left = b->left + b->width; - if (crop->c.width > b->left - crop->c.left + b->width) - crop->c.width = b->left - crop->c.left + b->width; - - dev->crop_current = crop->c; - return 0; + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + return -EINVAL; + cap->bounds = dev->crop_bounds; + cap->defrect = dev->crop_defrect; + cap->pixelaspect.numerator = 1; + cap->pixelaspect.denominator = 1; + if (dev->tvnorm->id & V4L2_STD_525_60) { + cap->pixelaspect.numerator = 11; + cap->pixelaspect.denominator = 10; + } + if (dev->tvnorm->id & V4L2_STD_625_50) { + cap->pixelaspect.numerator = 54; + cap->pixelaspect.denominator = 59; } + return 0; +} - /* --- tuner ioctls ------------------------------------------ */ - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - int n; +static int saa7134_g_crop(struct file *file, void *f, struct v4l2_crop *crop) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; - if (0 != t->index) - return -EINVAL; - memset(t,0,sizeof(*t)); - for (n = 0; n < SAA7134_INPUT_MAX; n++) - if (card_in(dev,n).tv) - break; - if (NULL != card_in(dev,n).name) { - strcpy(t->name, "Television"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | - V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2; - t->rangehigh = 0xffffffffUL; - t->rxsubchans = saa7134_tvaudio_getstereo(dev); - t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans); - } - if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03)) - t->signal = 0xffff; - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; - int rx,mode; + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + return -EINVAL; + crop->c = dev->crop_current; + return 0; +} - mode = dev->thread.mode; - if (UNSET == mode) { - rx = saa7134_tvaudio_getstereo(dev); - mode = saa7134_tvaudio_rx2mode(t->rxsubchans); - } - if (mode != t->audmode) { - dev->thread.mode = t->audmode; - } - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; +static int saa7134_s_crop(struct file *file, void *f, struct v4l2_crop *crop) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + struct v4l2_rect *b = &dev->crop_bounds; - memset(f,0,sizeof(*f)); - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = dev->ctl_freq; - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + return -EINVAL; + if (crop->c.height < 0) + return -EINVAL; + if (crop->c.width < 0) + return -EINVAL; - if (0 != f->tuner) - return -EINVAL; - if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) - return -EINVAL; - mutex_lock(&dev->lock); - dev->ctl_freq = f->frequency; + if (res_locked(fh->dev, RESOURCE_OVERLAY)) + return -EBUSY; + if (res_locked(fh->dev, RESOURCE_VIDEO)) + return -EBUSY; + + if (crop->c.top < b->top) + crop->c.top = b->top; + if (crop->c.top > b->top + b->height) + crop->c.top = b->top + b->height; + if (crop->c.height > b->top - crop->c.top + b->height) + crop->c.height = b->top - crop->c.top + b->height; + + if (crop->c.left < b->left) + crop->c.left = b->left; + if (crop->c.left > b->left + b->width) + crop->c.left = b->left + b->width; + if (crop->c.width > b->left - crop->c.left + b->width) + crop->c.width = b->left - crop->c.left + b->width; + + dev->crop_current = crop->c; + return 0; +} - saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f); +static int saa7134_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int n; - saa7134_tvaudio_do_scan(dev); - mutex_unlock(&dev->lock); - return 0; - } + if (0 != t->index) + return -EINVAL; + memset(t, 0, sizeof(*t)); + for (n = 0; n < SAA7134_INPUT_MAX; n++) + if (card_in(dev, n).tv) + break; + if (NULL != card_in(dev, n).name) { + strcpy(t->name, "Television"); + t->type = V4L2_TUNER_ANALOG_TV; + t->capability = V4L2_TUNER_CAP_NORM | + V4L2_TUNER_CAP_STEREO | + V4L2_TUNER_CAP_LANG1 | + V4L2_TUNER_CAP_LANG2; + t->rangehigh = 0xffffffffUL; + t->rxsubchans = saa7134_tvaudio_getstereo(dev); + t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans); + } + if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03)) + t->signal = 0xffff; + return 0; +} - /* --- control ioctls ---------------------------------------- */ - case VIDIOC_ENUMINPUT: - case VIDIOC_G_INPUT: - case VIDIOC_S_INPUT: - case VIDIOC_QUERYCTRL: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - return saa7134_common_ioctl(dev, cmd, arg); +static int saa7134_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int rx, mode, err; - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; - memset(a,0,sizeof(*a)); - strcpy(a->name,"audio"); - return 0; - } - case VIDIOC_S_AUDIO: - return 0; - case VIDIOC_G_PARM: - { - struct v4l2_captureparm *parm = arg; - memset(parm,0,sizeof(*parm)); - return 0; + mode = dev->thread.mode; + if (UNSET == mode) { + rx = saa7134_tvaudio_getstereo(dev); + mode = saa7134_tvaudio_rx2mode(t->rxsubchans); } + if (mode != t->audmode) + dev->thread.mode = t->audmode; - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p = arg; + return 0; +} - *p = v4l2_prio_max(&dev->prio); - return 0; - } - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *prio = arg; +static int saa7134_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; - return v4l2_prio_change(&dev->prio, &fh->prio, *prio); - } + f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + f->frequency = dev->ctl_freq; - /* --- preview ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - enum v4l2_buf_type type; - unsigned int index; - - index = f->index; - type = f->type; - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (saa7134_no_overlay > 0) { - printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - if (index >= FORMATS) - return -EINVAL; - if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY && - formats[index].planar) - return -EINVAL; - memset(f,0,sizeof(*f)); - f->index = index; - f->type = type; - strlcpy(f->description,formats[index].name,sizeof(f->description)); - f->pixelformat = formats[index].fourcc; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (0 != index) - return -EINVAL; - memset(f,0,sizeof(*f)); - f->index = index; - f->type = type; - f->pixelformat = V4L2_PIX_FMT_GREY; - strcpy(f->description,"vbi data"); - break; - default: - return -EINVAL; - } - return 0; - } - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *fb = arg; + return 0; +} - *fb = dev->ovbuf; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - return 0; - } - case VIDIOC_S_FBUF: - { - struct v4l2_framebuffer *fb = arg; - struct saa7134_format *fmt; +static int saa7134_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int err; - if(!capable(CAP_SYS_ADMIN) && - !capable(CAP_SYS_RAWIO)) - return -EPERM; + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; - /* check args */ - fmt = format_by_fourcc(fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; + if (0 != f->tuner) + return -EINVAL; + if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) + return -EINVAL; + if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) + return -EINVAL; + mutex_lock(&dev->lock); + dev->ctl_freq = f->frequency; - /* ok, accept it */ - dev->ovbuf = *fb; - dev->ovfmt = fmt; - if (0 == dev->ovbuf.fmt.bytesperline) - dev->ovbuf.fmt.bytesperline = - dev->ovbuf.fmt.width*fmt->depth/8; - return 0; + saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); + + saa7134_tvaudio_do_scan(dev); + mutex_unlock(&dev->lock); + return 0; +} + +static int saa7134_g_audio(struct file *file, void *priv, struct v4l2_audio *a) +{ + strcpy(a->name, "audio"); + return 0; +} + +static int saa7134_s_audio(struct file *file, void *priv, struct v4l2_audio *a) +{ + return 0; +} + +static int saa7134_g_priority(struct file *file, void *f, enum v4l2_priority *p) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + + *p = v4l2_prio_max(&dev->prio); + return 0; +} + +static int saa7134_s_priority(struct file *file, void *f, + enum v4l2_priority prio) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + + return v4l2_prio_change(&dev->prio, &fh->prio, prio); +} + +static int saa7134_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->index >= FORMATS) + return -EINVAL; + + strlcpy(f->description, formats[f->index].name, + sizeof(f->description)); + + f->pixelformat = formats[f->index].fourcc; + + return 0; +} + +static int saa7134_enum_fmt_overlay(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (saa7134_no_overlay > 0) { + printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); + return -EINVAL; } - case VIDIOC_OVERLAY: - { - int *on = arg; - if (*on) { - if (saa7134_no_overlay > 0) { - printk ("no_overlay\n"); - return -EINVAL; - } + if ((f->index >= FORMATS) || formats[f->index].planar) + return -EINVAL; - if (!res_get(dev,fh,RESOURCE_OVERLAY)) - return -EBUSY; - spin_lock_irqsave(&dev->slock,flags); - start_preview(dev,fh); - spin_unlock_irqrestore(&dev->slock,flags); - } - if (!*on) { - if (!res_check(fh, RESOURCE_OVERLAY)) - return -EINVAL; - spin_lock_irqsave(&dev->slock,flags); - stop_preview(dev,fh); - spin_unlock_irqrestore(&dev->slock,flags); - res_free(dev,fh,RESOURCE_OVERLAY); + strlcpy(f->description, formats[f->index].name, + sizeof(f->description)); + + f->pixelformat = formats[f->index].fourcc; + + return 0; +} + +static int saa7134_enum_fmt_vbi(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (0 != f->index) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_GREY; + strcpy(f->description, "vbi data"); + + return 0; +} + +static int saa7134_g_fbuf(struct file *file, void *f, + struct v4l2_framebuffer *fb) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + + *fb = dev->ovbuf; + fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; + + return 0; +} + +static int saa7134_s_fbuf(struct file *file, void *f, + struct v4l2_framebuffer *fb) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + struct saa7134_format *fmt; + + if (!capable(CAP_SYS_ADMIN) && + !capable(CAP_SYS_RAWIO)) + return -EPERM; + + /* check args */ + fmt = format_by_fourcc(fb->fmt.pixelformat); + if (NULL == fmt) + return -EINVAL; + + /* ok, accept it */ + dev->ovbuf = *fb; + dev->ovfmt = fmt; + if (0 == dev->ovbuf.fmt.bytesperline) + dev->ovbuf.fmt.bytesperline = + dev->ovbuf.fmt.width*fmt->depth/8; + return 0; +} + +static int saa7134_overlay(struct file *file, void *f, unsigned int on) +{ + struct saa7134_fh *fh = f; + struct saa7134_dev *dev = fh->dev; + unsigned long flags; + + if (on) { + if (saa7134_no_overlay > 0) { + dprintk("no_overlay\n"); + return -EINVAL; } - return 0; - } - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - return saa7134_g_fmt(dev,fh,f); - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - return saa7134_s_fmt(dev,fh,f); + if (!res_get(dev, fh, RESOURCE_OVERLAY)) + return -EBUSY; + spin_lock_irqsave(&dev->slock, flags); + start_preview(dev, fh); + spin_unlock_irqrestore(&dev->slock, flags); } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = arg; - return saa7134_try_fmt(dev,fh,f); + if (!on) { + if (!res_check(fh, RESOURCE_OVERLAY)) + return -EINVAL; + spin_lock_irqsave(&dev->slock, flags); + stop_preview(dev, fh); + spin_unlock_irqrestore(&dev->slock, flags); + res_free(dev, fh, RESOURCE_OVERLAY); } + return 0; +} + #ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGMBUF: - return videobuf_cgmbuf(saa7134_queue(fh), arg, gbuffers); +static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) +{ + struct saa7134_fh *fh = file->private_data; + return videobuf_cgmbuf(saa7134_queue(fh), mbuf, 8); +} #endif - case VIDIOC_REQBUFS: - return videobuf_reqbufs(saa7134_queue(fh),arg); - case VIDIOC_QUERYBUF: - return videobuf_querybuf(saa7134_queue(fh),arg); +static int saa7134_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct saa7134_fh *fh = priv; + return videobuf_reqbufs(saa7134_queue(fh), p); +} - case VIDIOC_QBUF: - return videobuf_qbuf(saa7134_queue(fh),arg); +static int saa7134_querybuf(struct file *file, void *priv, + struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + return videobuf_querybuf(saa7134_queue(fh), b); +} - case VIDIOC_DQBUF: - return videobuf_dqbuf(saa7134_queue(fh),arg, - file->f_flags & O_NONBLOCK); +static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + return videobuf_qbuf(saa7134_queue(fh), b); +} - case VIDIOC_STREAMON: - { - int res = saa7134_resource(fh); +static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) +{ + struct saa7134_fh *fh = priv; + return videobuf_dqbuf(saa7134_queue(fh), b, + file->f_flags & O_NONBLOCK); +} - if (!res_get(dev,fh,res)) - return -EBUSY; - return videobuf_streamon(saa7134_queue(fh)); - } - case VIDIOC_STREAMOFF: - { - int res = saa7134_resource(fh); +static int saa7134_streamon(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int res = saa7134_resource(fh); - err = videobuf_streamoff(saa7134_queue(fh)); - if (err < 0) - return err; - res_free(dev,fh,res); - return 0; - } + if (!res_get(dev, fh, res)) + return -EBUSY; - default: - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - video_do_ioctl); - } + return videobuf_streamon(saa7134_queue(fh)); +} + +static int saa7134_streamoff(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + int err; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + int res = saa7134_resource(fh); + + err = videobuf_streamoff(saa7134_queue(fh)); + if (err < 0) + return err; + res_free(dev, fh, res); return 0; } -static int video_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int saa7134_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) { - return video_usercopy(inode, file, cmd, arg, video_do_ioctl); + return 0; } -static int radio_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int radio_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { struct saa7134_fh *fh = file->private_data; struct saa7134_dev *dev = fh->dev; - if (video_debug > 1) - v4l_print_ioctl(dev->name,cmd); - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap,0,sizeof(*cap)); - strcpy(cap->driver, "saa7134"); - strlcpy(cap->card, saa7134_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); - cap->version = SAA7134_VERSION_CODE; - cap->capabilities = V4L2_CAP_TUNER; - return 0; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; + strcpy(cap->driver, "saa7134"); + strlcpy(cap->card, saa7134_boards[dev->board].name, sizeof(cap->card)); + sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); + cap->version = SAA7134_VERSION_CODE; + cap->capabilities = V4L2_CAP_TUNER; + return 0; +} - if (0 != t->index) - return -EINVAL; +static int radio_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct saa7134_fh *fh = file->private_data; + struct saa7134_dev *dev = fh->dev; - memset(t,0,sizeof(*t)); - strcpy(t->name, "Radio"); - t->type = V4L2_TUNER_RADIO; + if (0 != t->index) + return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); - if (dev->input->amux == TV) { - t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); - t->rxsubchans = (saa_readb(0x529) & 0x08) ? - V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; - } - return 0; + memset(t, 0, sizeof(*t)); + strcpy(t->name, "Radio"); + t->type = V4L2_TUNER_RADIO; + + saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); + if (dev->input->amux == TV) { + t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11); + t->rxsubchans = (saa_readb(0x529) & 0x08) ? + V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; + return 0; +} +static int radio_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct saa7134_fh *fh = file->private_data; + struct saa7134_dev *dev = fh->dev; - if (0 != t->index) - return -EINVAL; + if (0 != t->index) + return -EINVAL; - saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t); + saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t); + return 0; +} - return 0; - } - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; +static int radio_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index != 0) + return -EINVAL; - if (i->index != 0) - return -EINVAL; - strcpy(i->name,"Radio"); - i->type = V4L2_INPUT_TYPE_TUNER; - return 0; - } - case VIDIOC_G_INPUT: - { - int *i = arg; - *i = 0; - return 0; - } - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; + strcpy(i->name, "Radio"); + i->type = V4L2_INPUT_TYPE_TUNER; - memset(a,0,sizeof(*a)); - strcpy(a->name,"Radio"); - return 0; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; - *id = 0; - return 0; - } - case VIDIOC_S_AUDIO: - case VIDIOC_S_INPUT: - case VIDIOC_S_STD: - return 0; + return 0; +} - case VIDIOC_QUERYCTRL: - { - const struct v4l2_queryctrl *ctrl; - struct v4l2_queryctrl *c = arg; +static int radio_g_input(struct file *filp, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} - if (c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) - return -EINVAL; - if (c->id == V4L2_CID_AUDIO_MUTE) { - ctrl = ctrl_by_id(c->id); - *c = *ctrl; - } else - *c = no_ctrl; - return 0; - } +static int radio_g_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + memset(a, 0, sizeof(*a)); + strcpy(a->name, "Radio"); + return 0; +} - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL: - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - return video_do_ioctl(inode,file,cmd,arg); +static int radio_s_audio(struct file *file, void *priv, + struct v4l2_audio *a) +{ + return 0; +} - default: - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - radio_do_ioctl); - } +static int radio_s_input(struct file *filp, void *priv, unsigned int i) +{ return 0; } -static int radio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) { - return video_usercopy(inode, file, cmd, arg, radio_do_ioctl); + return 0; +} + +static int radio_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *c) +{ + const struct v4l2_queryctrl *ctrl; + + if (c->id < V4L2_CID_BASE || + c->id >= V4L2_CID_LASTP1) + return -EINVAL; + if (c->id == V4L2_CID_AUDIO_MUTE) { + ctrl = ctrl_by_id(c->id); + *c = *ctrl; + } else + *c = no_ctrl; + return 0; } static const struct file_operations video_fops = @@ -2336,7 +2327,7 @@ static const struct file_operations video_fops = .read = video_read, .poll = video_poll, .mmap = video_mmap, - .ioctl = video_ioctl, + .ioctl = video_ioctl2, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -2346,7 +2337,7 @@ static const struct file_operations radio_fops = .owner = THIS_MODULE, .open = video_open, .release = video_release, - .ioctl = radio_ioctl, + .ioctl = video_ioctl2, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -2356,27 +2347,79 @@ static const struct file_operations radio_fops = struct video_device saa7134_video_template = { - .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| - VID_TYPE_CLIPPING|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, -}; - -struct video_device saa7134_vbi_template = -{ - .name = "saa7134-vbi", - .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT, - .fops = &video_fops, - .minor = -1, + .name = "saa7134-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | + VID_TYPE_CLIPPING|VID_TYPE_SCALES, + .fops = &video_fops, + .minor = -1, + .vidioc_querycap = saa7134_querycap, + .vidioc_enum_fmt_cap = saa7134_enum_fmt_cap, + .vidioc_g_fmt_cap = saa7134_g_fmt_cap, + .vidioc_try_fmt_cap = saa7134_try_fmt_cap, + .vidioc_s_fmt_cap = saa7134_s_fmt_cap, + .vidioc_enum_fmt_overlay = saa7134_enum_fmt_overlay, + .vidioc_g_fmt_overlay = saa7134_g_fmt_overlay, + .vidioc_try_fmt_overlay = saa7134_try_fmt_overlay, + .vidioc_s_fmt_overlay = saa7134_s_fmt_overlay, + .vidioc_enum_fmt_vbi = saa7134_enum_fmt_vbi, + .vidioc_g_fmt_vbi = saa7134_try_get_set_fmt_vbi, + .vidioc_try_fmt_vbi = saa7134_try_get_set_fmt_vbi, + .vidioc_s_fmt_vbi = saa7134_try_get_set_fmt_vbi, + .vidioc_g_audio = saa7134_g_audio, + .vidioc_s_audio = saa7134_s_audio, + .vidioc_cropcap = saa7134_cropcap, + .vidioc_reqbufs = saa7134_reqbufs, + .vidioc_querybuf = saa7134_querybuf, + .vidioc_qbuf = saa7134_qbuf, + .vidioc_dqbuf = saa7134_dqbuf, + .vidioc_s_std = saa7134_s_std, + .vidioc_enum_input = saa7134_enum_input, + .vidioc_g_input = saa7134_g_input, + .vidioc_s_input = saa7134_s_input, + .vidioc_queryctrl = saa7134_queryctrl, + .vidioc_g_ctrl = saa7134_g_ctrl, + .vidioc_s_ctrl = saa7134_s_ctrl, + .vidioc_streamon = saa7134_streamon, + .vidioc_streamoff = saa7134_streamoff, + .vidioc_g_tuner = saa7134_g_tuner, + .vidioc_s_tuner = saa7134_s_tuner, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidiocgmbuf, +#endif + .vidioc_g_crop = saa7134_g_crop, + .vidioc_s_crop = saa7134_s_crop, + .vidioc_g_fbuf = saa7134_g_fbuf, + .vidioc_s_fbuf = saa7134_s_fbuf, + .vidioc_overlay = saa7134_overlay, + .vidioc_g_priority = saa7134_g_priority, + .vidioc_s_priority = saa7134_s_priority, + .vidioc_g_parm = saa7134_g_parm, + .vidioc_g_frequency = saa7134_g_frequency, + .vidioc_s_frequency = saa7134_s_frequency, + .tvnorms = SAA7134_NORMS, + .current_norm = V4L2_STD_PAL, }; struct video_device saa7134_radio_template = { - .name = "saa7134-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, + .name = "saa7134-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .minor = -1, + .vidioc_querycap = radio_querycap, + .vidioc_g_tuner = radio_g_tuner, + .vidioc_enum_input = radio_enum_input, + .vidioc_g_audio = radio_g_audio, + .vidioc_s_tuner = radio_s_tuner, + .vidioc_s_audio = radio_s_audio, + .vidioc_s_input = radio_s_input, + .vidioc_s_std = radio_s_std, + .vidioc_queryctrl = radio_queryctrl, + .vidioc_g_input = radio_g_input, + .vidioc_g_ctrl = saa7134_g_ctrl, + .vidioc_s_ctrl = saa7134_s_ctrl, + .vidioc_g_frequency = saa7134_g_frequency, + .vidioc_s_frequency = saa7134_s_frequency, }; int saa7134_video_init1(struct saa7134_dev *dev) @@ -2514,7 +2557,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) goto done; } dev->video_q.curr->vb.field_count = dev->video_fieldcount; - saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE); + saa7134_buffer_finish(dev,&dev->video_q,VIDEOBUF_DONE); } saa7134_buffer_next(dev,&dev->video_q); diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 66a390c321a..b88ca995faf 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -38,7 +38,6 @@ #include <media/ir-common.h> #include <media/ir-kbd-i2c.h> #include <media/videobuf-dma-sg.h> -#include <sound/driver.h> #include <sound/core.h> #include <sound/pcm.h> #if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE) @@ -240,6 +239,19 @@ struct saa7134_format { #define SAA7134_BOARD_SABRENT_TV_PCB05 115 #define SAA7134_BOARD_10MOONSTVMASTER3 116 #define SAA7134_BOARD_AVERMEDIA_SUPER_007 117 +#define SAA7134_BOARD_BEHOLD_401 118 +#define SAA7134_BOARD_BEHOLD_403 119 +#define SAA7134_BOARD_BEHOLD_403FM 120 +#define SAA7134_BOARD_BEHOLD_405 121 +#define SAA7134_BOARD_BEHOLD_405FM 122 +#define SAA7134_BOARD_BEHOLD_407 123 +#define SAA7134_BOARD_BEHOLD_407FM 124 +#define SAA7134_BOARD_BEHOLD_409 125 +#define SAA7134_BOARD_BEHOLD_505FM 126 +#define SAA7134_BOARD_BEHOLD_507_9FM 127 +#define SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM 128 +#define SAA7134_BOARD_BEHOLD_607_9FM 129 +#define SAA7134_BOARD_BEHOLD_M6 130 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -481,7 +493,7 @@ struct saa7134_dev { /* i2c i/o */ struct i2c_adapter i2c_adap; struct i2c_client i2c_client; - unsigned char eedata[128]; + unsigned char eedata[256]; /* video overlay */ struct v4l2_framebuffer ovbuf; @@ -566,6 +578,12 @@ struct saa7134_dev { #define saa_wait(us) { udelay(us); } +#define SAA7134_NORMS (\ + V4L2_STD_PAL | V4L2_STD_PAL_N | \ + V4L2_STD_PAL_Nc | V4L2_STD_SECAM | \ + V4L2_STD_NTSC | V4L2_STD_PAL_M | \ + V4L2_STD_PAL_60) + /* ----------------------------------------------------------- */ /* saa7134-core.c */ @@ -596,9 +614,6 @@ void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); void saa7134_buffer_timeout(unsigned long data); void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf); -int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q); - int saa7134_set_dmabits(struct saa7134_dev *dev); extern int (*saa7134_dmasound_init)(struct saa7134_dev *dev); @@ -628,16 +643,17 @@ void saa7134_i2c_call_clients(struct saa7134_dev *dev, /* ----------------------------------------------------------- */ /* saa7134-video.c */ +extern unsigned int video_debug; extern struct video_device saa7134_video_template; extern struct video_device saa7134_radio_template; -void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm); +int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c); +int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c); +int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); + int saa7134_videoport_init(struct saa7134_dev *dev); void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); -int saa7134_common_ioctl(struct saa7134_dev *dev, - unsigned int cmd, void *arg); - int saa7134_video_init1(struct saa7134_dev *dev); int saa7134_video_init2(struct saa7134_dev *dev); void saa7134_irq_video_signalchange(struct saa7134_dev *dev); @@ -682,6 +698,7 @@ void saa7134_tvaudio_setinput(struct saa7134_dev *dev, void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level); int saa7134_tvaudio_getstereo(struct saa7134_dev *dev); +void saa7134_tvaudio_init(struct saa7134_dev *dev); int saa7134_tvaudio_init2(struct saa7134_dev *dev); int saa7134_tvaudio_fini(struct saa7134_dev *dev); int saa7134_tvaudio_do_scan(struct saa7134_dev *dev); |