summaryrefslogtreecommitdiff
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-08-14 12:13:30 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-15 16:36:22 -0300
commitb285192a43f0432d82c2c10974204e78af0da596 (patch)
tree618aa87e760c9c949eca9e4df6ae0eeffa11dcfc /drivers/media/video/ivtv
parent68de959f773a1d49096835c411390bceff5d1549 (diff)
[media] rename most media/video pci drivers to media/pci
Rename all PCI drivers with their own directory under drivers/media/video into drivers/media/pci and update the building system. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/Kconfig45
-rw-r--r--drivers/media/video/ivtv/Makefile14
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.c1370
-rw-r--r--drivers/media/video/ivtv/ivtv-cards.h309
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c163
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h28
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c1498
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h839
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c1070
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.h44
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c402
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.h31
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c374
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.h29
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c760
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.h32
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c1899
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.h35
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c1038
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.h53
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c387
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h35
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c297
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h96
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.c119
-rw-r--r--drivers/media/video/ivtv/ivtv-routing.h27
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c1014
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h37
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c234
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h48
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c549
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h34
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c1296
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h44
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c1317
36 files changed, 0 insertions, 15593 deletions
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
deleted file mode 100644
index 89f65914cc8e..000000000000
--- a/drivers/media/video/ivtv/Kconfig
+++ /dev/null
@@ -1,45 +0,0 @@
-config VIDEO_IVTV
- tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
- depends on VIDEO_V4L2 && PCI && I2C
- select I2C_ALGOBIT
- depends on RC_CORE
- select VIDEO_TUNER
- select VIDEO_TVEEPROM
- select VIDEO_CX2341X
- select VIDEO_CX25840
- select VIDEO_MSP3400
- select VIDEO_SAA711X
- select VIDEO_SAA717X
- select VIDEO_SAA7127
- select VIDEO_CS53L32A
- select VIDEO_M52790
- select VIDEO_WM8775
- select VIDEO_WM8739
- select VIDEO_VP27SMPX
- select VIDEO_UPD64031A
- select VIDEO_UPD64083
- ---help---
- This is a video4linux driver for Conexant cx23416 or cx23415 based
- PCI personal video recorder devices.
-
- This is used in devices such as the Hauppauge PVR-150/250/350/500
- cards. There is a driver homepage at <http://www.ivtvdriver.org>.
-
- To compile this driver as a module, choose M here: the
- module will be called ivtv.
-
-config VIDEO_FB_IVTV
- tristate "Conexant cx23415 framebuffer support"
- depends on VIDEO_IVTV && FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This is a framebuffer driver for the Conexant cx23415 MPEG
- encoder/decoder.
-
- This is used in the Hauppauge PVR-350 card. There is a driver
- homepage at <http://www.ivtvdriver.org>.
-
- To compile this driver as a module, choose M here: the
- module will be called ivtvfb.
diff --git a/drivers/media/video/ivtv/Makefile b/drivers/media/video/ivtv/Makefile
deleted file mode 100644
index 80b4ec18475d..000000000000
--- a/drivers/media/video/ivtv/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-ivtv-objs := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
- ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \
- ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
- ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \
- ivtv-vbi.o ivtv-yuv.o
-
-obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
-obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
-
-ccflags-y += -I$(srctree)/drivers/media/video
-ccflags-y += -I$(srctree)/drivers/media/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
-ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
deleted file mode 100644
index 145e4749a69d..000000000000
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- Functions to query card hardware
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-i2c.h"
-
-#include <media/msp3400.h>
-#include <media/m52790.h>
-#include <media/wm8775.h>
-#include <media/cs53l32a.h>
-#include <media/cx25840.h>
-#include <media/upd64031a.h>
-
-#define MSP_TUNER MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
- MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER)
-#define MSP_SCART1 MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_SCART2 MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_SCART3 MSP_INPUT(MSP_IN_SCART3, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-#define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \
- MSP_DSP_IN_SCART, MSP_DSP_IN_SCART)
-
-#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
-
-/* usual i2c tuner addresses to probe */
-static struct ivtv_card_tuner_i2c ivtv_i2c_std = {
- .radio = { I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, 0x60, I2C_CLIENT_END },
-};
-
-/* as above, but with possible radio tuner */
-static struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
- .radio = { 0x60, I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, I2C_CLIENT_END },
-};
-
-/* using the tda8290+75a combo */
-static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = {
- .radio = { I2C_CLIENT_END },
- .demod = { I2C_CLIENT_END },
- .tv = { 0x4b, I2C_CLIENT_END },
-};
-
-/********************** card configuration *******************************/
-
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
- This keeps the PCI ID database up to date. Note that the entries
- must be added under vendor 0x4444 (Conexant) as subsystem IDs.
- New vendor IDs should still be added to the vendor ID list. */
-
-/* Hauppauge PVR-250 cards */
-
-/* Note: for Hauppauge cards the tveeprom information is used instead of PCI IDs */
-static const struct ivtv_card ivtv_card_pvr250 = {
- .type = IVTV_CARD_PVR_250,
- .name = "Hauppauge WinTV PVR-250",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Hauppauge PVR-350 cards */
-
-/* Outputs for Hauppauge PVR350 cards */
-static struct ivtv_card_output ivtv_pvr350_outputs[] = {
- {
- .name = "S-Video + Composite",
- .video_output = 0,
- }, {
- .name = "Composite",
- .video_output = 1,
- }, {
- .name = "S-Video",
- .video_output = 2,
- }, {
- .name = "RGB",
- .video_output = 3,
- }, {
- .name = "YUV C",
- .video_output = 4,
- }, {
- .name = "YUV V",
- .video_output = 5,
- }
-};
-
-static const struct ivtv_card ivtv_card_pvr350 = {
- .type = IVTV_CARD_PVR_350,
- .name = "Hauppauge WinTV PVR-350",
- .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
- .video_outputs = ivtv_pvr350_outputs,
- .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* PVR-350 V1 boards have a different audio tuner input and use a
- saa7114 instead of a saa7115.
- Note that the info below comes from a pre-production model so it may
- not be correct. Especially the audio behaves strangely (mono only it seems) */
-static const struct ivtv_card ivtv_card_pvr350_v1 = {
- .type = IVTV_CARD_PVR_350_V1,
- .name = "Hauppauge WinTV PVR-350 (V1)",
- .v4l2_capabilities = IVTV_CAP_ENCODER | IVTV_CAP_DECODER,
- .video_outputs = ivtv_pvr350_outputs,
- .nof_outputs = ARRAY_SIZE(ivtv_pvr350_outputs),
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7114 |
- IVTV_HW_SAA7127 | IVTV_HW_TVEEPROM | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE3, 1, IVTV_SAA71XX_COMPOSITE5 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_MONO },
- { IVTV_CARD_INPUT_LINE_IN1, MSP_SCART1 },
- { IVTV_CARD_INPUT_LINE_IN2, MSP_SCART3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, MSP_SCART2 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Hauppauge PVR-150/PVR-500 cards */
-
-static const struct ivtv_card ivtv_card_pvr150 = {
- .type = IVTV_CARD_PVR_150,
- .name = "Hauppauge WinTV PVR-150",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_WM8775,
- .hw_all = IVTV_HW_WM8775 | IVTV_HW_CX25840 |
- IVTV_HW_TVEEPROM | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_HAUP_EXT | IVTV_HW_I2C_IR_RX_HAUP_INT |
- IVTV_HW_Z8F0811_IR_HAUP,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE7 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
- { IVTV_CARD_INPUT_SVIDEO2, 2, CX25840_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE2, 2, CX25840_COMPOSITE4 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER,
- CX25840_AUDIO8, WM8775_AIN2 },
- { IVTV_CARD_INPUT_LINE_IN1,
- CX25840_AUDIO_SERIAL, WM8775_AIN2 },
- { IVTV_CARD_INPUT_LINE_IN2,
- CX25840_AUDIO_SERIAL, WM8775_AIN3 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER,
- CX25840_AUDIO_SERIAL, WM8775_AIN4 },
- /* apparently needed for the IR blaster */
- .gpio_init = { .direction = 0x1f01, .initial_value = 0x26f3 },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia M179 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_m179[] = {
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3cf },
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_AVERMEDIA, 0xa3ce },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_m179 = {
- .type = IVTV_CARD_M179,
- .name = "AVerMedia M179",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xe380, .initial_value = 0x8290 },
- .gpio_audio_input = { .mask = 0x8040, .tuner = 0x8000, .linein = 0x0000 },
- .gpio_audio_mute = { .mask = 0x2000, .mute = 0x2000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0200, .lang2 = 0x0100, .both = 0x0000 },
- .gpio_audio_freq = { .mask = 0x0018, .f32000 = 0x0000,
- .f44100 = 0x0008, .f48000 = 0x0010 },
- .gpio_audio_detect = { .mask = 0x4000, .stereo = 0x0000 },
- .tuners = {
- /* As far as we know all M179 cards use this tuner */
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_NTSC },
- },
- .pci_list = ivtv_pci_m179,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG600/Kuroutoshikou ITVC16-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_mpg600[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xfff3 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0xffff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_mpg600 = {
- .type = IVTV_CARD_MPG600,
- .name = "Yuan MPG600, Kuroutoshikou ITVC16-STVLP",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x3080, .initial_value = 0x0004 },
- .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
- .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
- .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
- .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
- .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
- .tuners = {
- /* The PAL tuner is confirmed */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_mpg600,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG160/Kuroutoshikou ITVC15-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_mpg160[] = {
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_YUAN1, 0 },
- { PCI_DEVICE_ID_IVTV15, IVTV_PCI_ID_IODATA, 0x40a0 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_mpg160 = {
- .type = IVTV_CARD_MPG160,
- .name = "YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x7080, .initial_value = 0x400c },
- .gpio_audio_input = { .mask = 0x3000, .tuner = 0x0000, .linein = 0x2000 },
- .gpio_audio_mute = { .mask = 0x0001, .mute = 0x0001 },
- .gpio_audio_mode = { .mask = 0x000e, .mono = 0x0006, .stereo = 0x0004,
- .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 },
- .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_mpg160,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan PG600/Diamond PVR-550 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_pg600[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_DIAMONDMM, 0x0070 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_pg600 = {
- .type = IVTV_CARD_PG600,
- .name = "Yuan PG600, Diamond PVR-550",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_pg600,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Adaptec VideOh! AVC-2410 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avc2410[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0093 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avc2410 = {
- .type = IVTV_CARD_AVC2410,
- .name = "Adaptec VideOh! AVC-2410",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_muxer = IVTV_HW_CS53L32A,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_CS53L32A |
- IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_I2C_IR_RX_ADAPTEC,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER,
- MSP_TUNER, CS53L32A_IN0 },
- { IVTV_CARD_INPUT_LINE_IN1,
- MSP_SCART1, CS53L32A_IN2 },
- },
- /* This card has no eeprom and in fact the Windows driver relies
- on the country/region setting of the user to decide which tuner
- is available. */
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP,
- .tuner = TUNER_PHILIPS_FM1236_MK3 },
- { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_avc2410,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Adaptec VideOh! AVC-2010 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avc2010[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ADAPTEC, 0x0092 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avc2010 = {
- .type = IVTV_CARD_AVC2010,
- .name = "Adaptec VideOh! AVC-2010",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_CS53L32A,
- .hw_audio_ctrl = IVTV_HW_CS53L32A,
- .hw_all = IVTV_HW_CS53L32A | IVTV_HW_SAA7115,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CS53L32A_IN2 },
- },
- /* Does not have a tuner */
- .pci_list = ivtv_pci_avc2010,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Nagase Transgear 5000TV card */
-
-static const struct ivtv_card_pci_info ivtv_pci_tg5000tv[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_tg5000tv = {
- .type = IVTV_CARD_TG5000TV,
- .name = "Nagase Transgear 5000TV",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7114 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
- IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7114 | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gr_config = UPD64031A_VERTICAL_EXTERNAL,
- .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
- .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
- .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
- .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
- .composite = 0x0010, .svideo = 0x0020 },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_tg5000tv,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AOpen VA2000MAX-SNT6 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_va2000[] = {
- { PCI_DEVICE_ID_IVTV16, 0, 0xff5f },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_va2000 = {
- .type = IVTV_CARD_VA2000MAX_SNT6,
- .name = "AOpen VA2000MAX-SNT6",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_MSP34XX,
- .hw_audio_ctrl = IVTV_HW_MSP34XX,
- .hw_all = IVTV_HW_MSP34XX | IVTV_HW_SAA7115 |
- IVTV_HW_UPD6408X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER },
- },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_va2000,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPG600GR/Kuroutoshikou CX23416GYC-STVLP cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_cx23416gyc[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN4, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x0523 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc = {
- .type = IVTV_CARD_CX23416GYC,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO3 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gr_config = UPD64031A_VERTICAL_EXTERNAL,
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .pci_list = ivtv_pci_cx23416gyc,
- .i2c = &ivtv_i2c_std,
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc_nogr = {
- .type = IVTV_CARD_CX23416GYC_NOGR,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER |
- IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .i2c = &ivtv_i2c_std,
-};
-
-static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = {
- .type = IVTV_CARD_CX23416GYC_NOGRYCS,
- .name = "Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X | IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA717X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 |
- IVTV_SAA717X_TUNER_FLAG },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE0 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN2 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN0 },
- },
- .gpio_init = { .direction = 0xf880, .initial_value = 0x8800 },
- .gpio_video_input = { .mask = 0x0020, .tuner = 0x0000,
- .composite = 0x0020, .svideo = 0x0020 },
- .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000,
- .f44100 = 0x4000, .f48000 = 0x8000 },
- .tuners = {
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* I/O Data GV-MVP/RX & GV-MVP/RX2W (dual tuner) cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd01e },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd038 }, /* 2W unit #1 */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd039 }, /* 2W unit #2 */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gv_mvprx = {
- .type = IVTV_CARD_GV_MVPRX,
- .name = "I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_WM8739,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_VP27SMPX |
- IVTV_HW_TUNER | IVTV_HW_WM8739 |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
- .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
- .tuners = {
- /* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
- },
- .pci_list = ivtv_pci_gv_mvprx,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* I/O Data GV-MVP/RX2E card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gv_mvprx2e[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_IODATA, 0xd025 },
- {0, 0, 0}
-};
-
-static const struct ivtv_card ivtv_card_gv_mvprx2e = {
- .type = IVTV_CARD_GV_MVPRX2E,
- .name = "I/O Data GV-MVP/RX2E",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_WM8739,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_VP27SMPX | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE4 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xc301, .initial_value = 0x0200 },
- .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 },
- .tuners = {
- /* This card has the Panasonic VP27 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 },
- },
- .pci_list = ivtv_pci_gv_mvprx2e,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GotVIEW PCI DVD card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN1, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gotview_pci_dvd = {
- .type = IVTV_CARD_GOTVIEW_PCI_DVD,
- .name = "GotView PCI DVD",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA717X,
- .hw_audio = IVTV_HW_SAA717X,
- .hw_audio_ctrl = IVTV_HW_SAA717X,
- .hw_all = IVTV_HW_SAA717X | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 }, /* pin 116 */
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO0 }, /* pin 114/109 */
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE3 }, /* pin 118 */
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_SAA717X_IN0 },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_SAA717X_IN2 },
- },
- .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 },
- .tuners = {
- /* This card has a Philips FQ1216ME MK3 tuner */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .pci_list = ivtv_pci_gotview_pci_dvd,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* GotVIEW PCI DVD2 Deluxe card */
-
-static const struct ivtv_card_pci_info ivtv_pci_gotview_pci_dvd2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW1, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = {
- .type = IVTV_CARD_GOTVIEW_PCI_DVD2,
- .name = "GotView PCI DVD2 Deluxe",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- .gpio_init = { .direction = 0x0800, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
- .tuners = {
- /* This card has a Philips FQ1216ME MK5 tuner */
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
- },
- .pci_list = ivtv_pci_gotview_pci_dvd2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan MPC622 miniPCI card */
-
-static const struct ivtv_card_pci_info ivtv_pci_yuan_mpc622[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN2, 0xd998 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_yuan_mpc622 = {
- .type = IVTV_CARD_YUAN_MPC622,
- .name = "Yuan MPC622",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .gpio_init = { .direction = 0x00ff, .initial_value = 0x0002 },
- .tuners = {
- /* This card has the TDA8290/TDA8275 tuner chips */
- { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_TDA8290 },
- },
- .pci_list = ivtv_pci_yuan_mpc622,
- .i2c = &ivtv_i2c_tda8290,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* DIGITAL COWBOY DCT-MTVP1 card */
-
-static const struct ivtv_card_pci_info ivtv_pci_dctmvtvp1[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xbfff },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_dctmvtvp1 = {
- .type = IVTV_CARD_DCTMTVP1,
- .name = "Digital Cowboy DCT-MTVP1",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X |
- IVTV_HW_GPIO,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
- IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_SVIDEO0 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO2 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_SVIDEO2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0xe080, .initial_value = 0x8000 },
- .gpio_audio_input = { .mask = 0x8080, .tuner = 0x8000, .linein = 0x0080 },
- .gpio_audio_mute = { .mask = 0x6000, .mute = 0x6000 },
- .gpio_audio_mode = { .mask = 0x4300, .mono = 0x4000, .stereo = 0x0200,
- .lang1 = 0x0300, .lang2 = 0x0000, .both = 0x0200 },
- .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000,
- .composite = 0x0010, .svideo = 0x0020},
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 },
- },
- .pci_list = ivtv_pci_dctmvtvp1,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Yuan PG600-2/GotView PCI DVD Lite cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_GOTVIEW2, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_pg600v2 = {
- .type = IVTV_CARD_PG600V2,
- .name = "Yuan PG600-2, GotView PCI DVD Lite",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- /* XC2028 support apparently works for the Yuan, it's still
- uncertain whether it also works with the GotView. */
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_pg600v2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Club3D ZAP-TV1x01 cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_club3d[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3, 0x0600 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_club3d = {
- .type = IVTV_CARD_CLUB3D,
- .name = "Club3D ZAP-TV1x01",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_club3d,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerTV MCE 116 Plus (M116) card */
-
-static const struct ivtv_card_pci_info ivtv_pci_avertv_mce116[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc439 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_avertv_mce116 = {
- .type = IVTV_CARD_AVERTV_MCE116,
- .name = "AVerTV MCE 116 Plus",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739 |
- IVTV_HW_I2C_IR_RX_AVER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- /* enable line-in */
- .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
- .xceive_pin = 10,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_avertv_mce116,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia PVR-150 Plus / AVerTV M113 cards with a Daewoo/Partsnic Tuner */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc034 }, /* NTSC */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, /* NTSC FM */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_pvr150 = {
- .type = IVTV_CARD_AVER_PVR150PLUS,
- .name = "AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
- IVTV_HW_WM8739 | IVTV_HW_GPIO,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
- .gpio_init = { .direction = 0xc000, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0xc000,
- .tuner = 0x0000,
- .linein = 0x4000,
- .radio = 0x8000 },
- .tuners = {
- /* Subsystem ID's 0xc03[45] have a Partsnic PTI-5NF05 tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PARTSNIC_PTI_5NF05 },
- },
- .pci_list = ivtv_pci_aver_pvr150,
- /* Subsystem ID 0xc035 has a TEA5767(?) FM tuner, 0xc034 does not */
- .i2c = &ivtv_i2c_radio,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 }, /* NTSC */
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc01b }, /* PAL/SECAM */
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
- .type = IVTV_CARD_AVER_ULTRA1500MCE,
- .name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
- .comment = "For non-NTSC tuners, use the pal= or secam= module options",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
- IVTV_HW_WM8739 | IVTV_HW_GPIO,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
- .gpio_init = { .direction = 0xc000, .initial_value = 0 },
- .gpio_audio_input = { .mask = 0xc000,
- .tuner = 0x0000,
- .linein = 0x4000,
- .radio = 0x8000 },
- .tuners = {
- /* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216MK5 },
- },
- .pci_list = ivtv_pci_aver_ultra1500mce,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia EZMaker PCI Deluxe card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc03f },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_ezmaker = {
- .type = IVTV_CARD_AVER_EZMAKER,
- .name = "AVerMedia EZMaker PCI Deluxe",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 0 },
- },
- .gpio_init = { .direction = 0x4000, .initial_value = 0x4000 },
- /* Does not have a tuner */
- .pci_list = ivtv_pci_aver_ezmaker,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* ASUS Falcon2 */
-
-static const struct ivtv_card_pci_info ivtv_pci_asus_falcon2[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b66 },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x462e },
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b2e },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_asus_falcon2 = {
- .type = IVTV_CARD_ASUS_FALCON2,
- .name = "ASUS Falcon2",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_muxer = IVTV_HW_M52790,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_M52790 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 2, CX25840_COMPOSITE2 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, M52790_IN_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL,
- M52790_IN_V2 | M52790_SW1_YCMIX | M52790_SW2_YCMIX },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, M52790_IN_V2 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
- .tuners = {
- { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
- },
- .pci_list = ivtv_pci_asus_falcon2,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* AVerMedia M104 miniPCI card */
-
-static const struct ivtv_card_pci_info ivtv_pci_aver_m104[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc136 },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_aver_m104 = {
- .type = IVTV_CARD_AVER_M104,
- .name = "AVerMedia M104",
- .comment = "Not yet supported!\n",
- .v4l2_capabilities = 0, /*IVTV_CAP_ENCODER,*/
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
- .video_inputs = {
- { IVTV_CARD_INPUT_SVIDEO1, 0, CX25840_SVIDEO3 },
- { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
- },
- .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
- /* enable line-in + reset tuner */
- .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 },
- .xceive_pin = 10,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_aver_m104,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* Buffalo PC-MV5L/PCI cards */
-
-static const struct ivtv_card_pci_info ivtv_pci_buffalo[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x052b },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_buffalo = {
- .type = IVTV_CARD_BUFFALO_MV5L,
- .name = "Buffalo PC-MV5L/PCI",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_CX25840,
- .hw_audio = IVTV_HW_CX25840,
- .hw_audio_ctrl = IVTV_HW_CX25840,
- .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
- { IVTV_CARD_INPUT_SVIDEO1, 1,
- CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
- { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL },
- },
- .xceive_pin = 12,
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
- },
- .pci_list = ivtv_pci_buffalo,
- .i2c = &ivtv_i2c_std,
-};
-
-/* ------------------------------------------------------------------------- */
-/* Sony Kikyou */
-
-static const struct ivtv_card_pci_info ivtv_pci_kikyou[] = {
- { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_SONY, 0x813d },
- { 0, 0, 0 }
-};
-
-static const struct ivtv_card ivtv_card_kikyou = {
- .type = IVTV_CARD_KIKYOU,
- .name = "Sony VAIO Giga Pocket (ENX Kikyou)",
- .v4l2_capabilities = IVTV_CAP_ENCODER,
- .hw_video = IVTV_HW_SAA7115,
- .hw_audio = IVTV_HW_GPIO,
- .hw_audio_ctrl = IVTV_HW_GPIO,
- .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER,
- .video_inputs = {
- { IVTV_CARD_INPUT_VID_TUNER, 0, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_COMPOSITE1, 1, IVTV_SAA71XX_COMPOSITE1 },
- { IVTV_CARD_INPUT_SVIDEO1, 1, IVTV_SAA71XX_SVIDEO1 },
- },
- .audio_inputs = {
- { IVTV_CARD_INPUT_AUD_TUNER, IVTV_GPIO_TUNER },
- { IVTV_CARD_INPUT_LINE_IN1, IVTV_GPIO_LINE_IN },
- { IVTV_CARD_INPUT_LINE_IN2, IVTV_GPIO_LINE_IN },
- },
- .gpio_init = { .direction = 0x03e1, .initial_value = 0x0320 },
- .gpio_audio_input = { .mask = 0x0060,
- .tuner = 0x0020,
- .linein = 0x0000,
- .radio = 0x0060 },
- .gpio_audio_mute = { .mask = 0x0000,
- .mute = 0x0000 }, /* 0x200? Disable for now. */
- .gpio_audio_mode = { .mask = 0x0080,
- .mono = 0x0000,
- .stereo = 0x0000, /* SAP */
- .lang1 = 0x0080,
- .lang2 = 0x0000,
- .both = 0x0080 },
- .tuners = {
- { .std = V4L2_STD_ALL, .tuner = TUNER_SONY_BTF_PXN01Z },
- },
- .pci_list = ivtv_pci_kikyou,
- .i2c = &ivtv_i2c_std,
-};
-
-
-static const struct ivtv_card *ivtv_card_list[] = {
- &ivtv_card_pvr250,
- &ivtv_card_pvr350,
- &ivtv_card_pvr150,
- &ivtv_card_m179,
- &ivtv_card_mpg600,
- &ivtv_card_mpg160,
- &ivtv_card_pg600,
- &ivtv_card_avc2410,
- &ivtv_card_avc2010,
- &ivtv_card_tg5000tv,
- &ivtv_card_va2000,
- &ivtv_card_cx23416gyc,
- &ivtv_card_gv_mvprx,
- &ivtv_card_gv_mvprx2e,
- &ivtv_card_gotview_pci_dvd,
- &ivtv_card_gotview_pci_dvd2,
- &ivtv_card_yuan_mpc622,
- &ivtv_card_dctmvtvp1,
- &ivtv_card_pg600v2,
- &ivtv_card_club3d,
- &ivtv_card_avertv_mce116,
- &ivtv_card_asus_falcon2,
- &ivtv_card_aver_pvr150,
- &ivtv_card_aver_ezmaker,
- &ivtv_card_aver_m104,
- &ivtv_card_buffalo,
- &ivtv_card_aver_ultra1500mce,
- &ivtv_card_kikyou,
-
- /* Variations of standard cards but with the same PCI IDs.
- These cards must come last in this list. */
- &ivtv_card_pvr350_v1,
- &ivtv_card_cx23416gyc_nogr,
- &ivtv_card_cx23416gyc_nogrycs,
-};
-
-const struct ivtv_card *ivtv_get_card(u16 index)
-{
- if (index >= ARRAY_SIZE(ivtv_card_list))
- return NULL;
- return ivtv_card_list[index];
-}
-
-int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input)
-{
- const struct ivtv_card_video_input *card_input = itv->card->video_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "S-Video 1",
- "S-Video 2",
- "Composite 1",
- "Composite 2",
- "Composite 3"
- };
-
- if (index >= itv->nof_inputs)
- return -EINVAL;
- input->index = index;
- strlcpy(input->name, input_strs[card_input->video_type - 1],
- sizeof(input->name));
- input->type = (card_input->video_type == IVTV_CARD_INPUT_VID_TUNER ?
- V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
- input->audioset = (1 << itv->nof_audio_inputs) - 1;
- input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
- itv->tuner_std : V4L2_STD_ALL;
- return 0;
-}
-
-int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output)
-{
- const struct ivtv_card_output *card_output = itv->card->video_outputs + index;
-
- if (index >= itv->card->nof_outputs)
- return -EINVAL;
- output->index = index;
- strlcpy(output->name, card_output->name, sizeof(output->name));
- output->type = V4L2_OUTPUT_TYPE_ANALOG;
- output->audioset = 1;
- output->std = V4L2_STD_ALL;
- return 0;
-}
-
-int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *audio)
-{
- const struct ivtv_card_audio_input *aud_input = itv->card->audio_inputs + index;
- static const char * const input_strs[] = {
- "Tuner 1",
- "Line In 1",
- "Line In 2"
- };
-
- memset(audio, 0, sizeof(*audio));
- if (index >= itv->nof_audio_inputs)
- return -EINVAL;
- strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
- sizeof(audio->name));
- audio->index = index;
- audio->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *aud_output)
-{
- memset(aud_output, 0, sizeof(*aud_output));
- if (itv->card->video_outputs == NULL || index != 0)
- return -EINVAL;
- strlcpy(aud_output->name, "A/V Audio Out", sizeof(aud_output->name));
- return 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
deleted file mode 100644
index e6f5c02981f1..000000000000
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- Functions to query card hardware
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_CARDS_H
-#define IVTV_CARDS_H
-
-/* Supported cards */
-#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */
-#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */
-#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two
- PVR150s on one PCI board) */
-#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */
-#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
-#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
- cx23415 based, but does not have tv-out */
-#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
-#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */
-#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */
-#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */
-#define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */
-#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */
-#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */
-#define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */
-#define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */
-#define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */
-#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */
-#define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */
-#define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */
-#define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */
-#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */
-#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
-#define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */
-#define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */
-#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
-#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
-#define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
-#define IVTV_CARD_LAST 27
-
-/* Variants of existing cards but with the same PCI IDs. The driver
- detects these based on other device information.
- These cards must always come last.
- New cards must be inserted above, and the indices of the cards below
- must be adjusted accordingly. */
-
-/* PVR-350 V1 (uses saa7114) */
-#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1)
-/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2)
-#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
-
-/* system vendor and device IDs */
-#define PCI_VENDOR_ID_ICOMP 0x4444
-#define PCI_DEVICE_ID_IVTV15 0x0803
-#define PCI_DEVICE_ID_IVTV16 0x0016
-
-/* subsystem vendor ID */
-#define IVTV_PCI_ID_HAUPPAUGE 0x0070
-#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
-#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
-#define IVTV_PCI_ID_ADAPTEC 0x9005
-#define IVTV_PCI_ID_ASUSTEK 0x1043
-#define IVTV_PCI_ID_AVERMEDIA 0x1461
-#define IVTV_PCI_ID_YUAN1 0x12ab
-#define IVTV_PCI_ID_YUAN2 0xff01
-#define IVTV_PCI_ID_YUAN3 0xffab
-#define IVTV_PCI_ID_YUAN4 0xfbab
-#define IVTV_PCI_ID_DIAMONDMM 0xff92
-#define IVTV_PCI_ID_IODATA 0x10fc
-#define IVTV_PCI_ID_MELCO 0x1154
-#define IVTV_PCI_ID_GOTVIEW1 0xffac
-#define IVTV_PCI_ID_GOTVIEW2 0xffad
-#define IVTV_PCI_ID_SONY 0x104d
-
-/* hardware flags, no gaps allowed */
-#define IVTV_HW_CX25840 (1 << 0)
-#define IVTV_HW_SAA7115 (1 << 1)
-#define IVTV_HW_SAA7127 (1 << 2)
-#define IVTV_HW_MSP34XX (1 << 3)
-#define IVTV_HW_TUNER (1 << 4)
-#define IVTV_HW_WM8775 (1 << 5)
-#define IVTV_HW_CS53L32A (1 << 6)
-#define IVTV_HW_TVEEPROM (1 << 7)
-#define IVTV_HW_SAA7114 (1 << 8)
-#define IVTV_HW_UPD64031A (1 << 9)
-#define IVTV_HW_UPD6408X (1 << 10)
-#define IVTV_HW_SAA717X (1 << 11)
-#define IVTV_HW_WM8739 (1 << 12)
-#define IVTV_HW_VP27SMPX (1 << 13)
-#define IVTV_HW_M52790 (1 << 14)
-#define IVTV_HW_GPIO (1 << 15)
-#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
-#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
-#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
-#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
-#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
-#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21)
-
-#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
-
-#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
- IVTV_HW_I2C_IR_RX_HAUP_EXT | \
- IVTV_HW_I2C_IR_RX_HAUP_INT | \
- IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_I2C_IR_RX_ADAPTEC)
-
-#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
-
-/* video inputs */
-#define IVTV_CARD_INPUT_VID_TUNER 1
-#define IVTV_CARD_INPUT_SVIDEO1 2
-#define IVTV_CARD_INPUT_SVIDEO2 3
-#define IVTV_CARD_INPUT_COMPOSITE1 4
-#define IVTV_CARD_INPUT_COMPOSITE2 5
-#define IVTV_CARD_INPUT_COMPOSITE3 6
-
-/* audio inputs */
-#define IVTV_CARD_INPUT_AUD_TUNER 1
-#define IVTV_CARD_INPUT_LINE_IN1 2
-#define IVTV_CARD_INPUT_LINE_IN2 3
-
-#define IVTV_CARD_MAX_VIDEO_INPUTS 6
-#define IVTV_CARD_MAX_AUDIO_INPUTS 3
-#define IVTV_CARD_MAX_TUNERS 3
-
-/* SAA71XX HW inputs */
-#define IVTV_SAA71XX_COMPOSITE0 0
-#define IVTV_SAA71XX_COMPOSITE1 1
-#define IVTV_SAA71XX_COMPOSITE2 2
-#define IVTV_SAA71XX_COMPOSITE3 3
-#define IVTV_SAA71XX_COMPOSITE4 4
-#define IVTV_SAA71XX_COMPOSITE5 5
-#define IVTV_SAA71XX_SVIDEO0 6
-#define IVTV_SAA71XX_SVIDEO1 7
-#define IVTV_SAA71XX_SVIDEO2 8
-#define IVTV_SAA71XX_SVIDEO3 9
-
-/* SAA717X needs to mark the tuner input by ORing with this flag */
-#define IVTV_SAA717X_TUNER_FLAG 0x80
-
-/* Dummy HW input */
-#define IVTV_DUMMY_AUDIO 0
-
-/* GPIO HW inputs */
-#define IVTV_GPIO_TUNER 0
-#define IVTV_GPIO_LINE_IN 1
-
-/* SAA717X HW inputs */
-#define IVTV_SAA717X_IN0 0
-#define IVTV_SAA717X_IN1 1
-#define IVTV_SAA717X_IN2 2
-
-/* V4L2 capability aliases */
-#define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
- V4L2_CAP_SLICED_VBI_CAPTURE)
-#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
-
-struct ivtv_card_video_input {
- u8 video_type; /* video input type */
- u8 audio_index; /* index in ivtv_card_audio_input array */
- u16 video_input; /* hardware video input */
-};
-
-struct ivtv_card_audio_input {
- u8 audio_type; /* audio input type */
- u32 audio_input; /* hardware audio input */
- u16 muxer_input; /* hardware muxer input for boards with a
- multiplexer chip */
-};
-
-struct ivtv_card_output {
- u8 name[32];
- u16 video_output; /* hardware video output */
-};
-
-struct ivtv_card_pci_info {
- u16 device;
- u16 subsystem_vendor;
- u16 subsystem_device;
-};
-
-/* GPIO definitions */
-
-/* The mask is the set of bits used by the operation */
-
-struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */
- u16 direction; /* DIR setting. Leave to 0 if no init is needed */
- u16 initial_value;
-};
-
-struct ivtv_gpio_video_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
- u16 tuner;
- u16 composite;
- u16 svideo;
-};
-
-struct ivtv_gpio_audio_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
- u16 tuner;
- u16 linein;
- u16 radio;
-};
-
-struct ivtv_gpio_audio_mute {
- u16 mask; /* leave to 0 if not supported */
- u16 mute; /* set this value to mute, 0 to unmute */
-};
-
-struct ivtv_gpio_audio_mode {
- u16 mask; /* leave to 0 if not supported */
- u16 mono; /* set audio to mono */
- u16 stereo; /* set audio to stereo */
- u16 lang1; /* set audio to the first language */
- u16 lang2; /* set audio to the second language */
- u16 both; /* both languages are output */
-};
-
-struct ivtv_gpio_audio_freq {
- u16 mask; /* leave to 0 if not supported */
- u16 f32000;
- u16 f44100;
- u16 f48000;
-};
-
-struct ivtv_gpio_audio_detect {
- u16 mask; /* leave to 0 if not supported */
- u16 stereo; /* if the input matches this value then
- stereo is detected */
-};
-
-struct ivtv_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
-};
-
-struct ivtv_card_tuner_i2c {
- unsigned short radio[2];/* radio tuner i2c address to probe */
- unsigned short demod[2];/* demodulator i2c address to probe */
- unsigned short tv[4]; /* tv tuner i2c addresses to probe */
-};
-
-/* for card information/parameters */
-struct ivtv_card {
- int type;
- char *name;
- char *comment;
- u32 v4l2_capabilities;
- u32 hw_video; /* hardware used to process video */
- u32 hw_audio; /* hardware used to process audio */
- u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only 1 dev allowed) */
- u32 hw_muxer; /* hardware used to multiplex audio input */
- u32 hw_all; /* all hardware used by the board */
- struct ivtv_card_video_input video_inputs[IVTV_CARD_MAX_VIDEO_INPUTS];
- struct ivtv_card_audio_input audio_inputs[IVTV_CARD_MAX_AUDIO_INPUTS];
- struct ivtv_card_audio_input radio_input;
- int nof_outputs;
- const struct ivtv_card_output *video_outputs;
- u8 gr_config; /* config byte for the ghost reduction device */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
-
- /* GPIO card-specific settings */
- struct ivtv_gpio_init gpio_init;
- struct ivtv_gpio_video_input gpio_video_input;
- struct ivtv_gpio_audio_input gpio_audio_input;
- struct ivtv_gpio_audio_mute gpio_audio_mute;
- struct ivtv_gpio_audio_mode gpio_audio_mode;
- struct ivtv_gpio_audio_freq gpio_audio_freq;
- struct ivtv_gpio_audio_detect gpio_audio_detect;
-
- struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
- struct ivtv_card_tuner_i2c *i2c;
-
- /* list of device and subsystem vendor/devices that
- correspond to this card type. */
- const struct ivtv_card_pci_info *pci_list;
-};
-
-int ivtv_get_input(struct ivtv *itv, u16 index, struct v4l2_input *input);
-int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output);
-int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *input);
-int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *output);
-const struct ivtv_card *ivtv_get_card(u16 index);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
deleted file mode 100644
index c60424601cb9..000000000000
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- ioctl control functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-controls.h"
-#include "ivtv-mailbox.h"
-
-static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- /* First try to allocate sliced VBI buffers if needed. */
- if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) {
- int i;
-
- for (i = 0; i < IVTV_VBI_FRAMES; i++) {
- /* Yuck, hardcoded. Needs to be a define */
- itv->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
- if (itv->vbi.sliced_mpeg_data[i] == NULL) {
- while (--i >= 0) {
- kfree(itv->vbi.sliced_mpeg_data[i]);
- itv->vbi.sliced_mpeg_data[i] = NULL;
- }
- return -ENOMEM;
- }
- }
- }
-
- itv->vbi.insert_mpeg = fmt;
-
- if (itv->vbi.insert_mpeg == 0) {
- return 0;
- }
- /* Need sliced data for mpeg insertion */
- if (ivtv_get_service_set(itv->vbi.sliced_in) == 0) {
- if (itv->is_60hz)
- itv->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
- else
- itv->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
- ivtv_expand_service_set(itv->vbi.sliced_in, itv->is_50hz);
- }
- return 0;
-}
-
-static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
- int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_mbus_framefmt fmt;
-
- /* fix videodecoder resolution */
- fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
- fmt.height = cxhdl->height;
- fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
- return 0;
-}
-
-static int ivtv_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
-{
- static const u32 freqs[3] = { 44100, 48000, 32000 };
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < ARRAY_SIZE(freqs))
- ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
- return 0;
-}
-
-static int ivtv_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
-{
- struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
-
- itv->dualwatch_stereo_mode = val;
- return 0;
-}
-
-struct cx2341x_handler_ops ivtv_cxhdl_ops = {
- .s_audio_mode = ivtv_s_audio_mode,
- .s_audio_sampling_freq = ivtv_s_audio_sampling_freq,
- .s_video_encoding = ivtv_s_video_encoding,
- .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
-};
-
-int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
- *pts = (s64)((u64)itv->last_dec_timing[2] << 32) |
- (u64)itv->last_dec_timing[1];
- *frame = itv->last_dec_timing[0];
- return 0;
- }
- *pts = 0;
- *frame = 0;
- if (atomic_read(&itv->decoding)) {
- if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
- IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
- return -EIO;
- }
- memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
- set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
- *pts = (s64)((u64) data[2] << 32) | (u64) data[1];
- *frame = data[0];
- /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
- }
- return 0;
-}
-
-static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
-
- switch (ctrl->id) {
- /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
- control cluster */
- case V4L2_CID_MPEG_VIDEO_DEC_PTS:
- return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
- &itv->ctrl_frame->val64);
- }
- return 0;
-}
-
-static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct ivtv *itv = container_of(ctrl->handler, struct ivtv, cxhdl.hdl);
-
- switch (ctrl->id) {
- /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
- control cluster */
- case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
- itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1;
- itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1;
- ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
- break;
- }
- return 0;
-}
-
-const struct v4l2_ctrl_ops ivtv_hdl_out_ops = {
- .s_ctrl = ivtv_s_ctrl,
- .g_volatile_ctrl = ivtv_g_volatile_ctrl,
-};
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
deleted file mode 100644
index 3999e6358312..000000000000
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- ioctl control functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_CONTROLS_H
-#define IVTV_CONTROLS_H
-
-extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
-extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops;
-int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
deleted file mode 100644
index 5462ce2f60ea..000000000000
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ /dev/null
@@ -1,1498 +0,0 @@
-/*
- ivtv driver initialization and card probing
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Main Driver file for the ivtv project:
- * Driver for the Conexant CX23415/CX23416 chip.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- * License: GPL
- * http://www.ivtvdriver.org
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- *
- * Kurouto Sikou CX23416GYC-STVLP tested by K.Ohta <alpha292@bremen.or.jp>
- * using information from T.Adachi,Takeru KOMORIYA and others :-)
- *
- * Nagase TRANSGEAR 5000TV, Aopen VA2000MAX-STN6 and I/O data GV-MVP/RX
- * version by T.Adachi. Special thanks Mr.Suzuki
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-version.h"
-#include "ivtv-fileops.h"
-#include "ivtv-i2c.h"
-#include "ivtv-firmware.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-streams.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include "ivtv-vbi.h"
-#include "ivtv-routing.h"
-#include "ivtv-controls.h"
-#include "ivtv-gpio.h"
-#include <linux/dma-mapping.h>
-#include <media/tveeprom.h>
-#include <media/saa7115.h>
-#include <media/v4l2-chip-ident.h>
-#include "tuner-xc2028.h"
-
-/* If you have already X v4l cards, then set this to X. This way
- the device numbers stay matched. Example: you have a WinTV card
- without radio and a PVR-350 with. Normally this would give a
- video1 device together with a radio0 device for the PVR. By
- setting this to 1 you ensure that radio0 is now also radio1. */
-int ivtv_first_minor;
-
-/* add your revision and whatnot here */
-static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
-
-/* ivtv instance counter */
-static atomic_t ivtv_instance = ATOMIC_INIT(0);
-
-/* Parameter declarations */
-static int cardtype[IVTV_MAX_CARDS];
-static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1 };
-
-static unsigned int cardtype_c = 1;
-static unsigned int tuner_c = 1;
-static int radio_c = 1;
-static unsigned int i2c_clock_period_c = 1;
-static char pal[] = "---";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-/* Buffers */
-
-/* DMA Buffers, Default size in MB allocated */
-#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
-#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
-#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
-/* Exception: size in kB for this stream (MB is overkill) */
-#define IVTV_DEFAULT_ENC_PCM_BUFFERS 320
-#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
-#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
-/* Exception: size in kB for this stream (MB is way overkill) */
-#define IVTV_DEFAULT_DEC_VBI_BUFFERS 64
-
-static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS;
-static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS;
-static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS;
-static int enc_pcm_buffers = IVTV_DEFAULT_ENC_PCM_BUFFERS;
-static int dec_mpg_buffers = IVTV_DEFAULT_DEC_MPG_BUFFERS;
-static int dec_yuv_buffers = IVTV_DEFAULT_DEC_YUV_BUFFERS;
-static int dec_vbi_buffers = IVTV_DEFAULT_DEC_VBI_BUFFERS;
-
-static int ivtv_yuv_mode;
-static int ivtv_yuv_threshold = -1;
-static int ivtv_pci_latency = 1;
-
-int ivtv_debug;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-int ivtv_fw_debug;
-#endif
-
-static int tunertype = -1;
-static int newi2c = -1;
-
-module_param_array(tuner, int, &tuner_c, 0644);
-module_param_array(radio, int, &radio_c, 0644);
-module_param_array(cardtype, int, &cardtype_c, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-module_param_named(debug,ivtv_debug, int, 0644);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-module_param_named(fw_debug, ivtv_fw_debug, int, 0644);
-#endif
-module_param(ivtv_pci_latency, int, 0644);
-module_param(ivtv_yuv_mode, int, 0644);
-module_param(ivtv_yuv_threshold, int, 0644);
-module_param(ivtv_first_minor, int, 0644);
-
-module_param(enc_mpg_buffers, int, 0644);
-module_param(enc_yuv_buffers, int, 0644);
-module_param(enc_vbi_buffers, int, 0644);
-module_param(enc_pcm_buffers, int, 0644);
-module_param(dec_mpg_buffers, int, 0644);
-module_param(dec_yuv_buffers, int, 0644);
-module_param(dec_vbi_buffers, int, 0644);
-
-module_param(tunertype, int, 0644);
-module_param(newi2c, int, 0644);
-module_param_array(i2c_clock_period, int, &i2c_clock_period_c, 0644);
-
-MODULE_PARM_DESC(tuner, "Tuner type selection,\n"
- "\t\t\tsee tuner.h for values");
-MODULE_PARM_DESC(radio,
- "Enable or disable the radio. Use only if autodetection\n"
- "\t\t\tfails. 0 = disable, 1 = enable");
-MODULE_PARM_DESC(cardtype,
- "Only use this option if your card is not detected properly.\n"
- "\t\tSpecify card type:\n"
- "\t\t\t 1 = WinTV PVR 250\n"
- "\t\t\t 2 = WinTV PVR 350\n"
- "\t\t\t 3 = WinTV PVR-150 or PVR-500\n"
- "\t\t\t 4 = AVerMedia M179\n"
- "\t\t\t 5 = YUAN MPG600/Kuroutoshikou iTVC16-STVLP\n"
- "\t\t\t 6 = YUAN MPG160/Kuroutoshikou iTVC15-STVLP\n"
- "\t\t\t 7 = YUAN PG600/DIAMONDMM PVR-550 (CX Falcon 2)\n"
- "\t\t\t 8 = Adaptec AVC-2410\n"
- "\t\t\t 9 = Adaptec AVC-2010\n"
- "\t\t\t10 = NAGASE TRANSGEAR 5000TV\n"
- "\t\t\t11 = AOpen VA2000MAX-STN6\n"
- "\t\t\t12 = YUAN MPG600GR/Kuroutoshikou CX23416GYC-STVLP\n"
- "\t\t\t13 = I/O Data GV-MVP/RX\n"
- "\t\t\t14 = I/O Data GV-MVP/RX2E\n"
- "\t\t\t15 = GOTVIEW PCI DVD\n"
- "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n"
- "\t\t\t17 = Yuan MPC622\n"
- "\t\t\t18 = Digital Cowboy DCT-MTVP1\n"
- "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n"
- "\t\t\t20 = Club3D ZAP-TV1x01\n"
- "\t\t\t21 = AverTV MCE 116 Plus\n"
- "\t\t\t22 = ASUS Falcon2\n"
- "\t\t\t23 = AverMedia PVR-150 Plus\n"
- "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
- "\t\t\t25 = AverMedia M104 (not yet working)\n"
- "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
- "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
- "\t\t\t28 = Sony VAIO Giga Pocket (ENX Kikyou)\n"
- "\t\t\t 0 = Autodetect (default)\n"
- "\t\t\t-1 = Ignore this card\n\t\t");
-MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
-MODULE_PARM_DESC(secam, "Set SECAM standard: BGH, DK, L, LC");
-MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J (Japan), K (South Korea)");
-MODULE_PARM_DESC(tunertype,
- "Specify tuner type:\n"
- "\t\t\t 0 = tuner for PAL-B/G/H/D/K/I, SECAM-B/G/H/D/K/L/Lc\n"
- "\t\t\t 1 = tuner for NTSC-M/J/K, PAL-M/N/Nc\n"
- "\t\t\t-1 = Autodetect (default)\n");
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: 0\n"
- "\t\t\t 1/0x0001: warning\n"
- "\t\t\t 2/0x0002: info\n"
- "\t\t\t 4/0x0004: mailbox\n"
- "\t\t\t 8/0x0008: ioctl\n"
- "\t\t\t 16/0x0010: file\n"
- "\t\t\t 32/0x0020: dma\n"
- "\t\t\t 64/0x0040: irq\n"
- "\t\t\t 128/0x0080: decoder\n"
- "\t\t\t 256/0x0100: yuv\n"
- "\t\t\t 512/0x0200: i2c\n"
- "\t\t\t1024/0x0400: high volume\n");
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-MODULE_PARM_DESC(fw_debug,
- "Enable code for debugging firmware problems. Default: 0\n");
-#endif
-MODULE_PARM_DESC(ivtv_pci_latency,
- "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
- "\t\t\tDefault: Yes");
-MODULE_PARM_DESC(ivtv_yuv_mode,
- "Specify the yuv playback mode:\n"
- "\t\t\t0 = interlaced\n\t\t\t1 = progressive\n\t\t\t2 = auto\n"
- "\t\t\tDefault: 0 (interlaced)");
-MODULE_PARM_DESC(ivtv_yuv_threshold,
- "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n"
- "\t\t\tDefault: 480");
-MODULE_PARM_DESC(enc_mpg_buffers,
- "Encoder MPG Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS));
-MODULE_PARM_DESC(enc_yuv_buffers,
- "Encoder YUV Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_YUV_BUFFERS));
-MODULE_PARM_DESC(enc_vbi_buffers,
- "Encoder VBI Buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS));
-MODULE_PARM_DESC(enc_pcm_buffers,
- "Encoder PCM buffers (in kB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS));
-MODULE_PARM_DESC(dec_mpg_buffers,
- "Decoder MPG buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_MPG_BUFFERS));
-MODULE_PARM_DESC(dec_yuv_buffers,
- "Decoder YUV buffers (in MB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS));
-MODULE_PARM_DESC(dec_vbi_buffers,
- "Decoder VBI buffers (in kB)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS));
-MODULE_PARM_DESC(newi2c,
- "Use new I2C implementation\n"
- "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
- "\t\t\tDefault is autodetect");
-MODULE_PARM_DESC(i2c_clock_period,
- "Period of SCL for the I2C bus controlled by the CX23415/6\n"
- "\t\t\tMin: 10 usec (100 kHz), Max: 4500 usec (222 Hz)\n"
- "\t\t\tDefault: " __stringify(IVTV_DEFAULT_I2C_CLOCK_PERIOD));
-
-MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
-
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
-MODULE_DESCRIPTION("CX23415/CX23416 driver");
-MODULE_SUPPORTED_DEVICE
- ("CX23415/CX23416 MPEG2 encoder (WinTV PVR-150/250/350/500,\n"
- "\t\t\tYuan MPG series and similar)");
-MODULE_LICENSE("GPL");
-
-MODULE_VERSION(IVTV_VERSION);
-
-void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask)
-{
- itv->irqmask &= ~mask;
- write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
-}
-
-void ivtv_set_irq_mask(struct ivtv *itv, u32 mask)
-{
- itv->irqmask |= mask;
- write_reg_sync(itv->irqmask, IVTV_REG_IRQMASK);
-}
-
-int ivtv_set_output_mode(struct ivtv *itv, int mode)
-{
- int old_mode;
-
- spin_lock(&itv->lock);
- old_mode = itv->output_mode;
- if (old_mode == 0)
- itv->output_mode = old_mode = mode;
- spin_unlock(&itv->lock);
- return old_mode;
-}
-
-struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv)
-{
- switch (itv->output_mode) {
- case OUT_MPG:
- return &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
- case OUT_YUV:
- return &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- default:
- return NULL;
- }
-}
-
-int ivtv_waitq(wait_queue_head_t *waitq)
-{
- DEFINE_WAIT(wait);
-
- prepare_to_wait(waitq, &wait, TASK_INTERRUPTIBLE);
- schedule();
- finish_wait(waitq, &wait);
- return signal_pending(current) ? -EINTR : 0;
-}
-
-/* Generic utility functions */
-int ivtv_msleep_timeout(unsigned int msecs, int intr)
-{
- int timeout = msecs_to_jiffies(msecs);
-
- do {
- set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
- timeout = schedule_timeout(timeout);
- if (intr) {
- int ret = signal_pending(current);
-
- if (ret)
- return ret;
- }
- } while (timeout);
- return 0;
-}
-
-/* Release ioremapped memory */
-static void ivtv_iounmap(struct ivtv *itv)
-{
- if (itv == NULL)
- return;
-
- /* Release registers memory */
- if (itv->reg_mem != NULL) {
- IVTV_DEBUG_INFO("releasing reg_mem\n");
- iounmap(itv->reg_mem);
- itv->reg_mem = NULL;
- }
- /* Release io memory */
- if (itv->has_cx23415 && itv->dec_mem != NULL) {
- IVTV_DEBUG_INFO("releasing dec_mem\n");
- iounmap(itv->dec_mem);
- }
- itv->dec_mem = NULL;
-
- /* Release io memory */
- if (itv->enc_mem != NULL) {
- IVTV_DEBUG_INFO("releasing enc_mem\n");
- iounmap(itv->enc_mem);
- itv->enc_mem = NULL;
- }
-}
-
-/* Hauppauge card? get values from tveeprom */
-void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
-{
- u8 eedata[256];
-
- itv->i2c_client.addr = 0xA0 >> 1;
- tveeprom_read(&itv->i2c_client, eedata, sizeof(eedata));
- tveeprom_hauppauge_analog(&itv->i2c_client, tv, eedata);
-}
-
-static void ivtv_process_eeprom(struct ivtv *itv)
-{
- struct tveeprom tv;
- int pci_slot = PCI_SLOT(itv->pdev->devfn);
-
- ivtv_read_eeprom(itv, &tv);
-
- /* Many thanks to Steven Toth from Hauppauge for providing the
- model numbers */
- switch (tv.model) {
- /* In a few cases the PCI subsystem IDs do not correctly
- identify the card. A better method is to check the
- model number from the eeprom instead. */
- case 30012 ... 30039: /* Low profile PVR250 */
- case 32000 ... 32999:
- case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */
- case 48400 ... 48599:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_250);
- break;
- case 48100 ... 48399:
- case 48600 ... 48999:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_350);
- break;
- case 23000 ... 23999: /* PVR500 */
- case 25000 ... 25999: /* Low profile PVR150 */
- case 26000 ... 26999: /* Regular PVR150 */
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- break;
- case 0:
- IVTV_ERR("Invalid EEPROM\n");
- return;
- default:
- IVTV_ERR("Unknown model %d, defaulting to PVR-150\n", tv.model);
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- break;
- }
-
- switch (tv.model) {
- /* Old style PVR350 (with an saa7114) uses this input for
- the tuner. */
- case 48254:
- itv->card = ivtv_get_card(IVTV_CARD_PVR_350_V1);
- break;
- default:
- break;
- }
-
- itv->v4l2_cap = itv->card->v4l2_capabilities;
- itv->card_name = itv->card->name;
- itv->card_i2c = itv->card->i2c;
-
- /* If this is a PVR500 then it should be possible to detect whether it is the
- first or second unit by looking at the subsystem device ID: is bit 4 is
- set, then it is the second unit (according to info from Hauppauge).
-
- However, while this works for most cards, I have seen a few PVR500 cards
- where both units have the same subsystem ID.
-
- So instead I look at the reported 'PCI slot' (which is the slot on the PVR500
- PCI bridge) and if it is 8, then it is assumed to be the first unit, otherwise
- it is the second unit. It is possible that it is a different slot when ivtv is
- used in Xen, in that case I ignore this card here. The worst that can happen
- is that the card presents itself with a non-working radio device.
-
- This detection is needed since the eeprom reports incorrectly that a radio is
- present on the second unit. */
- if (tv.model / 1000 == 23) {
- static const struct ivtv_card_tuner_i2c ivtv_i2c_radio = {
- .radio = { 0x60, I2C_CLIENT_END },
- .demod = { 0x43, I2C_CLIENT_END },
- .tv = { 0x61, I2C_CLIENT_END },
- };
-
- itv->card_name = "WinTV PVR 500";
- itv->card_i2c = &ivtv_i2c_radio;
- if (pci_slot == 8 || pci_slot == 9) {
- int is_first = (pci_slot & 1) == 0;
-
- itv->card_name = is_first ? "WinTV PVR 500 (unit #1)" :
- "WinTV PVR 500 (unit #2)";
- if (!is_first) {
- IVTV_INFO("Correcting tveeprom data: no radio present on second unit\n");
- tv.has_radio = 0;
- }
- }
- }
- IVTV_INFO("Autodetected %s\n", itv->card_name);
-
- switch (tv.tuner_hauppauge_model) {
- case 85:
- case 99:
- case 112:
- itv->pvr150_workaround = 1;
- break;
- default:
- break;
- }
- if (tv.tuner_type == TUNER_ABSENT)
- IVTV_ERR("tveeprom cannot autodetect tuner!\n");
-
- if (itv->options.tuner == -1)
- itv->options.tuner = tv.tuner_type;
- if (itv->options.radio == -1)
- itv->options.radio = (tv.has_radio != 0);
- /* only enable newi2c if an IR blaster is present */
- if (itv->options.newi2c == -1 && tv.has_ir) {
- itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0;
- if (itv->options.newi2c) {
- IVTV_INFO("Reopen i2c bus for IR-blaster support\n");
- exit_ivtv_i2c(itv);
- init_ivtv_i2c(itv);
- }
- }
-
- if (itv->std != 0)
- /* user specified tuner standard */
- return;
-
- /* autodetect tuner standard */
- if (tv.tuner_formats & V4L2_STD_PAL) {
- IVTV_DEBUG_INFO("PAL tuner detected\n");
- itv->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- } else if (tv.tuner_formats & V4L2_STD_NTSC) {
- IVTV_DEBUG_INFO("NTSC tuner detected\n");
- itv->std |= V4L2_STD_NTSC_M;
- } else if (tv.tuner_formats & V4L2_STD_SECAM) {
- IVTV_DEBUG_INFO("SECAM tuner detected\n");
- itv->std |= V4L2_STD_SECAM_L;
- } else {
- IVTV_INFO("No tuner detected, default to NTSC-M\n");
- itv->std |= V4L2_STD_NTSC_M;
- }
-}
-
-static v4l2_std_id ivtv_parse_std(struct ivtv *itv)
-{
- switch (pal[0]) {
- case '6':
- tunertype = 0;
- return V4L2_STD_PAL_60;
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- tunertype = 0;
- return V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- case 'n':
- case 'N':
- tunertype = 1;
- if (pal[1] == 'c' || pal[1] == 'C')
- return V4L2_STD_PAL_Nc;
- return V4L2_STD_PAL_N;
- case 'i':
- case 'I':
- tunertype = 0;
- return V4L2_STD_PAL_I;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- tunertype = 0;
- return V4L2_STD_PAL_DK;
- case 'M':
- case 'm':
- tunertype = 1;
- return V4L2_STD_PAL_M;
- case '-':
- break;
- default:
- IVTV_WARN("pal= argument not recognised\n");
- return 0;
- }
-
- switch (secam[0]) {
- case 'b':
- case 'B':
- case 'g':
- case 'G':
- case 'h':
- case 'H':
- tunertype = 0;
- return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
- case 'd':
- case 'D':
- case 'k':
- case 'K':
- tunertype = 0;
- return V4L2_STD_SECAM_DK;
- case 'l':
- case 'L':
- tunertype = 0;
- if (secam[1] == 'C' || secam[1] == 'c')
- return V4L2_STD_SECAM_LC;
- return V4L2_STD_SECAM_L;
- case '-':
- break;
- default:
- IVTV_WARN("secam= argument not recognised\n");
- return 0;
- }
-
- switch (ntsc[0]) {
- case 'm':
- case 'M':
- tunertype = 1;
- return V4L2_STD_NTSC_M;
- case 'j':
- case 'J':
- tunertype = 1;
- return V4L2_STD_NTSC_M_JP;
- case 'k':
- case 'K':
- tunertype = 1;
- return V4L2_STD_NTSC_M_KR;
- case '-':
- break;
- default:
- IVTV_WARN("ntsc= argument not recognised\n");
- return 0;
- }
-
- /* no match found */
- return 0;
-}
-
-static void ivtv_process_options(struct ivtv *itv)
-{
- const char *chipname;
- int i, j;
-
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024;
- itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;
- itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
- itv->options.cardtype = cardtype[itv->instance];
- itv->options.tuner = tuner[itv->instance];
- itv->options.radio = radio[itv->instance];
-
- itv->options.i2c_clock_period = i2c_clock_period[itv->instance];
- if (itv->options.i2c_clock_period == -1)
- itv->options.i2c_clock_period = IVTV_DEFAULT_I2C_CLOCK_PERIOD;
- else if (itv->options.i2c_clock_period < 10)
- itv->options.i2c_clock_period = 10;
- else if (itv->options.i2c_clock_period > 4500)
- itv->options.i2c_clock_period = 4500;
-
- itv->options.newi2c = newi2c;
- if (tunertype < -1 || tunertype > 1) {
- IVTV_WARN("Invalid tunertype argument, will autodetect instead\n");
- tunertype = -1;
- }
- itv->std = ivtv_parse_std(itv);
- if (itv->std == 0 && tunertype >= 0)
- itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
- itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
- chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
- if (itv->options.cardtype == -1) {
- IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
- return;
- }
- if ((itv->card = ivtv_get_card(itv->options.cardtype - 1))) {
- IVTV_INFO("User specified %s card (detected %s based chip)\n",
- itv->card->name, chipname);
- } else if (itv->options.cardtype != 0) {
- IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
- }
- if (itv->card == NULL) {
- if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
- itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
- itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
- itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
- IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
- chipname);
- }
- }
- if (itv->card == NULL) {
- for (i = 0; (itv->card = ivtv_get_card(i)); i++) {
- if (itv->card->pci_list == NULL)
- continue;
- for (j = 0; itv->card->pci_list[j].device; j++) {
- if (itv->pdev->device !=
- itv->card->pci_list[j].device)
- continue;
- if (itv->pdev->subsystem_vendor !=
- itv->card->pci_list[j].subsystem_vendor)
- continue;
- if (itv->pdev->subsystem_device !=
- itv->card->pci_list[j].subsystem_device)
- continue;
- IVTV_INFO("Autodetected %s card (%s based)\n",
- itv->card->name, chipname);
- goto done;
- }
- }
- }
-done:
-
- if (itv->card == NULL) {
- itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
- IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- itv->pdev->vendor, itv->pdev->device);
- IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
- IVTV_ERR(" %s based\n", chipname);
- IVTV_ERR("Defaulting to %s card\n", itv->card->name);
- IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
- IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
- IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n");
- }
- itv->v4l2_cap = itv->card->v4l2_capabilities;
- itv->card_name = itv->card->name;
- itv->card_i2c = itv->card->i2c;
-}
-
-/* Precondition: the ivtv structure has been memset to 0. Only
- the dev and num fields have been filled in.
- No assumptions on the card type may be made here (see ivtv_init_struct2
- for that).
- */
-static int __devinit ivtv_init_struct1(struct ivtv *itv)
-{
- struct sched_param param = { .sched_priority = 99 };
-
- itv->base_addr = pci_resource_start(itv->pdev, 0);
- itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
- itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
-
- mutex_init(&itv->serialize_lock);
- mutex_init(&itv->i2c_bus_lock);
- mutex_init(&itv->udma.lock);
-
- spin_lock_init(&itv->lock);
- spin_lock_init(&itv->dma_reg_lock);
-
- init_kthread_worker(&itv->irq_worker);
- itv->irq_worker_task = kthread_run(kthread_worker_fn, &itv->irq_worker,
- itv->v4l2_dev.name);
- if (IS_ERR(itv->irq_worker_task)) {
- IVTV_ERR("Could not create ivtv task\n");
- return -1;
- }
- /* must use the FIFO scheduler as it is realtime sensitive */
- sched_setscheduler(itv->irq_worker_task, SCHED_FIFO, &param);
-
- init_kthread_work(&itv->irq_work, ivtv_irq_work_handler);
-
- /* Initial settings */
- itv->cxhdl.port = CX2341X_PORT_MEMORY;
- itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
- init_waitqueue_head(&itv->eos_waitq);
- init_waitqueue_head(&itv->event_waitq);
- init_waitqueue_head(&itv->vsync_waitq);
- init_waitqueue_head(&itv->dma_waitq);
- init_timer(&itv->dma_timer);
- itv->dma_timer.function = ivtv_unfinished_dma;
- itv->dma_timer.data = (unsigned long)itv;
-
- itv->cur_dma_stream = -1;
- itv->cur_pio_stream = -1;
-
- /* Ctrls */
- itv->speed = 1000;
-
- /* VBI */
- itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
-
- /* Init the sg table for osd/yuv output */
- sg_init_table(itv->udma.SGlist, IVTV_DMA_SG_OSD_ENT);
-
- /* OSD */
- itv->osd_global_alpha_state = 1;
- itv->osd_global_alpha = 255;
-
- /* YUV */
- atomic_set(&itv->yuv_info.next_dma_frame, -1);
- itv->yuv_info.lace_mode = ivtv_yuv_mode;
- itv->yuv_info.lace_threshold = ivtv_yuv_threshold;
- itv->yuv_info.max_frames_buffered = 3;
- itv->yuv_info.track_osd = 1;
- return 0;
-}
-
-/* Second initialization part. Here the card type has been
- autodetected. */
-static void __devinit ivtv_init_struct2(struct ivtv *itv)
-{
- int i;
-
- for (i = 0; i < IVTV_CARD_MAX_VIDEO_INPUTS; i++)
- if (itv->card->video_inputs[i].video_type == 0)
- break;
- itv->nof_inputs = i;
- for (i = 0; i < IVTV_CARD_MAX_AUDIO_INPUTS; i++)
- if (itv->card->audio_inputs[i].audio_type == 0)
- break;
- itv->nof_audio_inputs = i;
-
- if (itv->card->hw_all & IVTV_HW_CX25840) {
- itv->vbi.sliced_size = 288; /* multiple of 16, real size = 284 */
- } else {
- itv->vbi.sliced_size = 64; /* multiple of 16, real size = 52 */
- }
-
- /* Find tuner input */
- for (i = 0; i < itv->nof_inputs; i++) {
- if (itv->card->video_inputs[i].video_type ==
- IVTV_CARD_INPUT_VID_TUNER)
- break;
- }
- if (i == itv->nof_inputs)
- i = 0;
- itv->active_input = i;
- itv->audio_input = itv->card->video_inputs[i].audio_index;
-}
-
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
-{
- u16 cmd;
- unsigned char pci_latency;
-
- IVTV_DEBUG_INFO("Enabling pci device\n");
-
- if (pci_enable_device(pdev)) {
- IVTV_ERR("Can't enable device!\n");
- return -EIO;
- }
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
- IVTV_ERR("No suitable DMA available.\n");
- return -EIO;
- }
- if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
- IVTV_ERR("Cannot request encoder memory region.\n");
- return -EIO;
- }
-
- if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
- IVTV_REG_SIZE, "ivtv registers")) {
- IVTV_ERR("Cannot request register memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- return -EIO;
- }
-
- if (itv->has_cx23415 &&
- !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE, "ivtv decoder")) {
- IVTV_ERR("Cannot request decoder memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- return -EIO;
- }
-
- /* Check for bus mastering */
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_MASTER)) {
- IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
- pci_set_master(pdev);
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_MASTER)) {
- IVTV_ERR("Bus Mastering is not enabled\n");
- return -ENXIO;
- }
- }
- IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
-
- pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
-
- if (pci_latency < 64 && ivtv_pci_latency) {
- IVTV_INFO("Unreasonably low latency timer, "
- "setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
- }
- /* This config space value relates to DMA latencies. The
- default value 0x8080 is too low however and will lead
- to DMA errors. 0xffff is the max value which solves
- these problems. */
- pci_write_config_dword(pdev, 0x40, 0xffff);
-
- IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
- "irq: %d, latency: %d, memory: 0x%llx\n",
- pdev->device, pdev->revision, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
- pdev->irq, pci_latency, (u64)itv->base_addr);
-
- return 0;
-}
-
-static void ivtv_load_and_init_modules(struct ivtv *itv)
-{
- u32 hw = itv->card->hw_all;
- unsigned i;
-
- /* check which i2c devices are actually found */
- for (i = 0; i < 32; i++) {
- u32 device = 1 << i;
-
- if (!(device & hw))
- continue;
- if (device == IVTV_HW_GPIO || device == IVTV_HW_TVEEPROM) {
- /* GPIO and TVEEPROM do not use i2c probing */
- itv->hw_flags |= device;
- continue;
- }
- if (ivtv_i2c_register(itv, i) == 0)
- itv->hw_flags |= device;
- }
-
- /* probe for legacy IR controllers that aren't in card definitions */
- if ((itv->hw_flags & IVTV_HW_IR_ANY) == 0)
- ivtv_i2c_new_ir_legacy(itv);
-
- if (itv->card->hw_all & IVTV_HW_CX25840)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_CX25840);
- else if (itv->card->hw_all & IVTV_HW_SAA717X)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA717X);
- else if (itv->card->hw_all & IVTV_HW_SAA7114)
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7114);
- else
- itv->sd_video = ivtv_find_hw(itv, IVTV_HW_SAA7115);
- itv->sd_audio = ivtv_find_hw(itv, itv->card->hw_audio_ctrl);
- itv->sd_muxer = ivtv_find_hw(itv, itv->card->hw_muxer);
-
- hw = itv->hw_flags;
-
- if (itv->card->type == IVTV_CARD_CX23416GYC) {
- /* Several variations of this card exist, detect which card
- type should be used. */
- if ((hw & (IVTV_HW_UPD64031A | IVTV_HW_UPD6408X)) == 0)
- itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGRYCS);
- else if ((hw & IVTV_HW_UPD64031A) == 0)
- itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);
- }
- else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
- itv->card->type == IVTV_CARD_GV_MVPRX2E) {
- /* The crystal frequency of GVMVPRX is 24.576MHz */
- v4l2_subdev_call(itv->sd_video, video, s_crystal_freq,
- SAA7115_FREQ_24_576_MHZ, SAA7115_FREQ_FL_UCGC);
- }
-
- if (hw & IVTV_HW_CX25840) {
- itv->vbi.raw_decoder_line_size = 1444;
- itv->vbi.raw_decoder_sav_odd_field = 0x20;
- itv->vbi.raw_decoder_sav_even_field = 0x60;
- itv->vbi.sliced_decoder_line_size = 272;
- itv->vbi.sliced_decoder_sav_odd_field = 0xB0;
- itv->vbi.sliced_decoder_sav_even_field = 0xF0;
- }
-
- if (hw & IVTV_HW_SAA711X) {
- struct v4l2_dbg_chip_ident v;
-
- /* determine the exact saa711x model */
- itv->hw_flags &= ~IVTV_HW_SAA711X;
-
- v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER;
- strlcpy(v.match.name, "saa7115", sizeof(v.match.name));
- ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
- if (v.ident == V4L2_IDENT_SAA7114) {
- itv->hw_flags |= IVTV_HW_SAA7114;
- /* VBI is not yet supported by the saa7114 driver. */
- itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
- } else {
- itv->hw_flags |= IVTV_HW_SAA7115;
- }
- itv->vbi.raw_decoder_line_size = 1443;
- itv->vbi.raw_decoder_sav_odd_field = 0x25;
- itv->vbi.raw_decoder_sav_even_field = 0x62;
- itv->vbi.sliced_decoder_line_size = 51;
- itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
- itv->vbi.sliced_decoder_sav_even_field = 0xEC;
- }
-
- if (hw & IVTV_HW_SAA717X) {
- itv->vbi.raw_decoder_line_size = 1443;
- itv->vbi.raw_decoder_sav_odd_field = 0x25;
- itv->vbi.raw_decoder_sav_even_field = 0x62;
- itv->vbi.sliced_decoder_line_size = 51;
- itv->vbi.sliced_decoder_sav_odd_field = 0xAB;
- itv->vbi.sliced_decoder_sav_even_field = 0xEC;
- }
-}
-
-static int __devinit ivtv_probe(struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
-{
- int retval = 0;
- int vbi_buf_size;
- struct ivtv *itv;
-
- itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
- if (itv == NULL)
- return -ENOMEM;
- itv->pdev = pdev;
- itv->instance = v4l2_device_set_name(&itv->v4l2_dev, "ivtv",
- &ivtv_instance);
-
- retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
- if (retval) {
- kfree(itv);
- return retval;
- }
- IVTV_INFO("Initializing card %d\n", itv->instance);
-
- ivtv_process_options(itv);
- if (itv->options.cardtype == -1) {
- retval = -ENODEV;
- goto err;
- }
- if (ivtv_init_struct1(itv)) {
- retval = -ENOMEM;
- goto err;
- }
- retval = cx2341x_handler_init(&itv->cxhdl, 50);
- if (retval)
- goto err;
- itv->v4l2_dev.ctrl_handler = &itv->cxhdl.hdl;
- itv->cxhdl.ops = &ivtv_cxhdl_ops;
- itv->cxhdl.priv = itv;
- itv->cxhdl.func = ivtv_api_func;
-
- IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr);
-
- /* PCI Device Setup */
- retval = ivtv_setup_pci(itv, pdev, pci_id);
- if (retval == -EIO)
- goto free_worker;
- if (retval == -ENXIO)
- goto free_mem;
-
- /* map io memory */
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE);
- itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET,
- IVTV_ENCODER_SIZE);
- if (!itv->enc_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
- "encoder memory\n");
- IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of "
- "vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
-
- if (itv->has_cx23415) {
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
- if (!itv->dec_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into "
- "CX23415 decoder memory\n");
- IVTV_ERR("Each capture card with a CX23415 needs 8 MB "
- "of vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc "
- "/proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option "
- "to set VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_mem;
- }
- }
- else {
- itv->dec_mem = itv->enc_mem;
- }
-
- /* map registers memory */
- IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
- (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- itv->reg_mem =
- ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (!itv->reg_mem) {
- IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 "
- "register space\n");
- IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of "
- "vmalloc address space for this window\n");
- IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
- IVTV_ERR("Use the vmalloc= kernel command line option to set "
- "VmallocTotal to a larger value\n");
- retval = -ENOMEM;
- goto free_io;
- }
-
- retval = ivtv_gpio_init(itv);
- if (retval)
- goto free_io;
-
- /* active i2c */
- IVTV_DEBUG_INFO("activating i2c...\n");
- if (init_ivtv_i2c(itv)) {
- IVTV_ERR("Could not initialize i2c\n");
- goto free_io;
- }
-
- if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
- /* Based on the model number the cardtype may be changed.
- The PCI IDs are not always reliable. */
- ivtv_process_eeprom(itv);
- }
- if (itv->card->comment)
- IVTV_INFO("%s", itv->card->comment);
- if (itv->card->v4l2_capabilities == 0) {
- /* card was detected but is not supported */
- retval = -ENODEV;
- goto free_i2c;
- }
-
- if (itv->std == 0) {
- itv->std = V4L2_STD_NTSC_M;
- }
-
- if (itv->options.tuner == -1) {
- int i;
-
- for (i = 0; i < IVTV_CARD_MAX_TUNERS; i++) {
- if ((itv->std & itv->card->tuners[i].std) == 0)
- continue;
- itv->options.tuner = itv->card->tuners[i].tuner;
- break;
- }
- }
- /* if no tuner was found, then pick the first tuner in the card list */
- if (itv->options.tuner == -1 && itv->card->tuners[0].std) {
- itv->std = itv->card->tuners[0].std;
- if (itv->std & V4L2_STD_PAL)
- itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
- else if (itv->std & V4L2_STD_NTSC)
- itv->std = V4L2_STD_NTSC_M;
- else if (itv->std & V4L2_STD_SECAM)
- itv->std = V4L2_STD_SECAM_L;
- itv->options.tuner = itv->card->tuners[0].tuner;
- }
- if (itv->options.radio == -1)
- itv->options.radio = (itv->card->radio_input.audio_type != 0);
-
- /* The card is now fully identified, continue with card-specific
- initialization. */
- ivtv_init_struct2(itv);
-
- ivtv_load_and_init_modules(itv);
-
- if (itv->std & V4L2_STD_525_60) {
- itv->is_60hz = 1;
- itv->is_out_60hz = 1;
- } else {
- itv->is_50hz = 1;
- itv->is_out_50hz = 1;
- }
-
- itv->yuv_info.osd_full_w = 720;
- itv->yuv_info.osd_full_h = itv->is_out_50hz ? 576 : 480;
- itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w;
- itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h;
-
- cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
-
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_MPG] = 0x10000;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_YUV] = 0x10000;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_YUV] = 0x08000;
-
- /* Setup VBI Raw Size. Should be big enough to hold PAL.
- It is possible to switch between PAL and NTSC, so we need to
- take the largest size here. */
- /* 1456 is multiple of 16, real size = 1444 */
- itv->vbi.raw_size = 1456;
- /* We use a buffer size of 1/2 of the total size needed for a
- frame. This is actually very useful, since we now receive
- a field at a time and that makes 'compressing' the raw data
- down to size by stripping off the SAV codes a lot easier.
- Note: having two different buffer sizes prevents standard
- switching on the fly. We need to find a better solution... */
- vbi_buf_size = itv->vbi.raw_size * (itv->is_60hz ? 24 : 36) / 2;
- itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
- itv->stream_buf_size[IVTV_DEC_STREAM_TYPE_VBI] = sizeof(struct v4l2_sliced_vbi_data) * 36;
-
- if (itv->options.radio > 0)
- itv->v4l2_cap |= V4L2_CAP_RADIO;
-
- if (itv->options.tuner > -1) {
- struct tuner_setup setup;
-
- setup.addr = ADDR_UNSET;
- setup.type = itv->options.tuner;
- setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
- if (itv->options.radio > 0)
- setup.mode_mask |= T_RADIO;
- setup.tuner_callback = (setup.type == TUNER_XC2028) ?
- ivtv_reset_tuner_gpio : NULL;
- ivtv_call_all(itv, tuner, s_type_addr, &setup);
- if (setup.type == TUNER_XC2028) {
- static struct xc2028_ctrl ctrl = {
- .fname = XC2028_DEFAULT_FIRMWARE,
- .max_len = 64,
- };
- struct v4l2_priv_tun_config cfg = {
- .tuner = itv->options.tuner,
- .priv = &ctrl,
- };
- ivtv_call_all(itv, tuner, s_config, &cfg);
- }
- }
-
- /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
- are not. */
- itv->tuner_std = itv->std;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- struct v4l2_ctrl_handler *hdl = itv->v4l2_dev.ctrl_handler;
-
- itv->ctrl_pts = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 0, 0);
- itv->ctrl_frame = v4l2_ctrl_new_std(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0, 0, 0);
- /* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
- mask that menu item. */
- itv->ctrl_audio_playback =
- v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
- 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO);
- itv->ctrl_audio_multilingual_playback =
- v4l2_ctrl_new_std_menu(hdl, &ivtv_hdl_out_ops,
- V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
- 1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
- V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT);
- if (hdl->error) {
- retval = hdl->error;
- goto free_i2c;
- }
- v4l2_ctrl_cluster(2, &itv->ctrl_pts);
- v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback);
- ivtv_call_all(itv, video, s_std_output, itv->std);
- /* Turn off the output signal. The mpeg decoder is not yet
- active so without this you would get a green image until the
- mpeg decoder becomes active. */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- }
-
- /* clear interrupt mask, effectively disabling interrupts */
- ivtv_set_irq_mask(itv, 0xffffffff);
-
- /* Register IRQ */
- retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
- if (retval) {
- IVTV_ERR("Failed to register irq %d\n", retval);
- goto free_i2c;
- }
-
- retval = ivtv_streams_setup(itv);
- if (retval) {
- IVTV_ERR("Error %d setting up streams\n", retval);
- goto free_irq;
- }
- retval = ivtv_streams_register(itv);
- if (retval) {
- IVTV_ERR("Error %d registering devices\n", retval);
- goto free_streams;
- }
- IVTV_INFO("Initialized card: %s\n", itv->card_name);
- return 0;
-
-free_streams:
- ivtv_streams_cleanup(itv, 1);
-free_irq:
- free_irq(itv->pdev->irq, (void *)itv);
-free_i2c:
- v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
- exit_ivtv_i2c(itv);
-free_io:
- ivtv_iounmap(itv);
-free_mem:
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-free_worker:
- kthread_stop(itv->irq_worker_task);
-err:
- if (retval == 0)
- retval = -ENODEV;
- IVTV_ERR("Error %d on initialization\n", retval);
-
- v4l2_device_unregister(&itv->v4l2_dev);
- kfree(itv);
- return retval;
-}
-
-int ivtv_init_on_first_open(struct ivtv *itv)
-{
- struct v4l2_frequency vf;
- /* Needed to call ioctls later */
- struct ivtv_open_id fh;
- int fw_retry_count = 3;
- int video_input;
-
- fh.itv = itv;
-
- if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
- return -ENXIO;
-
- if (test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags))
- return 0;
-
- while (--fw_retry_count > 0) {
- /* load firmware */
- if (ivtv_firmware_init(itv) == 0)
- break;
- if (fw_retry_count > 1)
- IVTV_WARN("Retry loading firmware\n");
- }
-
- if (fw_retry_count == 0) {
- set_bit(IVTV_F_I_FAILED, &itv->i_flags);
- return -ENXIO;
- }
-
- /* Try and get firmware versions */
- IVTV_DEBUG_INFO("Getting firmware version..\n");
- ivtv_firmware_versions(itv);
-
- if (itv->card->hw_all & IVTV_HW_CX25840)
- v4l2_subdev_call(itv->sd_video, core, load_fw);
-
- vf.tuner = 0;
- vf.type = V4L2_TUNER_ANALOG_TV;
- vf.frequency = 6400; /* the tuner 'baseline' frequency */
-
- /* Set initial frequency. For PAL/SECAM broadcasts no
- 'default' channel exists AFAIK. */
- if (itv->std == V4L2_STD_NTSC_M_JP) {
- vf.frequency = 1460; /* ch. 1 91250*16/1000 */
- }
- else if (itv->std & V4L2_STD_NTSC_M) {
- vf.frequency = 1076; /* ch. 4 67250*16/1000 */
- }
-
- video_input = itv->active_input;
- itv->active_input++; /* Force update of input */
- ivtv_s_input(NULL, &fh, video_input);
-
- /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
- in one place. */
- itv->std++; /* Force full standard initialization */
- itv->std_out = itv->std;
- ivtv_s_frequency(NULL, &fh, &vf);
-
- if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
- /* Turn on the TV-out: ivtv_init_mpeg_decoder() initializes
- the mpeg decoder so now the saa7127 receives a proper
- signal. */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- ivtv_init_mpeg_decoder(itv);
- }
-
- /* On a cx23416 this seems to be able to enable DMA to the chip? */
- if (!itv->has_cx23415)
- write_reg_sync(0x03, IVTV_REG_DMACONTROL);
-
- ivtv_s_std_enc(itv, &itv->tuner_std);
-
- /* Default interrupts enabled. For the PVR350 this includes the
- decoder VSYNC interrupt, which is always on. It is not only used
- during decoding but also by the OSD.
- Some old PVR250 cards had a cx23415, so testing for that is too
- general. Instead test if the card has video output capability. */
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
- ivtv_set_osd_alpha(itv);
- ivtv_s_std_dec(itv, &itv->tuner_std);
- } else {
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
- }
-
- /* Setup initial controls */
- cx2341x_handler_setup(&itv->cxhdl);
- return 0;
-}
-
-static void ivtv_remove(struct pci_dev *pdev)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
- struct ivtv *itv = to_ivtv(v4l2_dev);
- int i;
-
- IVTV_DEBUG_INFO("Removing card\n");
-
- if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
- /* Stop all captures */
- IVTV_DEBUG_INFO("Stopping all streams\n");
- if (atomic_read(&itv->capturing) > 0)
- ivtv_stop_all_captures(itv);
-
- /* Stop all decoding */
- IVTV_DEBUG_INFO("Stopping decoding\n");
-
- /* Turn off the TV-out */
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- if (atomic_read(&itv->decoding) > 0) {
- int type;
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- type = IVTV_DEC_STREAM_TYPE_YUV;
- else
- type = IVTV_DEC_STREAM_TYPE_MPG;
- ivtv_stop_v4l2_decode_stream(&itv->streams[type],
- V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
- }
- ivtv_halt_firmware(itv);
- }
-
- /* Interrupts */
- ivtv_set_irq_mask(itv, 0xffffffff);
- del_timer_sync(&itv->dma_timer);
-
- /* Kill irq worker */
- flush_kthread_worker(&itv->irq_worker);
- kthread_stop(itv->irq_worker_task);
-
- ivtv_streams_cleanup(itv, 1);
- ivtv_udma_free(itv);
-
- v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
-
- exit_ivtv_i2c(itv);
-
- free_irq(itv->pdev->irq, (void *)itv);
- ivtv_iounmap(itv);
-
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
-
- pci_disable_device(itv->pdev);
- for (i = 0; i < IVTV_VBI_FRAMES; i++)
- kfree(itv->vbi.sliced_mpeg_data[i]);
-
- printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
-
- v4l2_device_unregister(&itv->v4l2_dev);
- kfree(itv);
-}
-
-/* define a pci_driver for card detection */
-static struct pci_driver ivtv_pci_driver = {
- .name = "ivtv",
- .id_table = ivtv_pci_tbl,
- .probe = ivtv_probe,
- .remove = ivtv_remove,
-};
-
-static int __init module_start(void)
-{
- printk(KERN_INFO "ivtv: Start initialization, version %s\n", IVTV_VERSION);
-
- /* Validate parameters */
- if (ivtv_first_minor < 0 || ivtv_first_minor >= IVTV_MAX_CARDS) {
- printk(KERN_ERR "ivtv: Exiting, ivtv_first_minor must be between 0 and %d\n",
- IVTV_MAX_CARDS - 1);
- return -1;
- }
-
- if (ivtv_debug < 0 || ivtv_debug > 2047) {
- ivtv_debug = 0;
- printk(KERN_INFO "ivtv: Debug value must be >= 0 and <= 2047\n");
- }
-
- if (pci_register_driver(&ivtv_pci_driver)) {
- printk(KERN_ERR "ivtv: Error detecting PCI card\n");
- return -ENODEV;
- }
- printk(KERN_INFO "ivtv: End initialization\n");
- return 0;
-}
-
-static void __exit module_cleanup(void)
-{
- pci_unregister_driver(&ivtv_pci_driver);
-}
-
-/* Note: These symbols are exported because they are used by the ivtvfb
- framebuffer module and an infrared module for the IR-blaster. */
-EXPORT_SYMBOL(ivtv_set_irq_mask);
-EXPORT_SYMBOL(ivtv_api);
-EXPORT_SYMBOL(ivtv_vapi);
-EXPORT_SYMBOL(ivtv_vapi_result);
-EXPORT_SYMBOL(ivtv_clear_irq_mask);
-EXPORT_SYMBOL(ivtv_debug);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-EXPORT_SYMBOL(ivtv_fw_debug);
-#endif
-EXPORT_SYMBOL(ivtv_reset_ir_gpio);
-EXPORT_SYMBOL(ivtv_udma_setup);
-EXPORT_SYMBOL(ivtv_udma_unmap);
-EXPORT_SYMBOL(ivtv_udma_alloc);
-EXPORT_SYMBOL(ivtv_udma_prepare);
-EXPORT_SYMBOL(ivtv_init_on_first_open);
-EXPORT_SYMBOL(ivtv_firmware_check);
-
-module_init(module_start);
-module_exit(module_cleanup);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
deleted file mode 100644
index a7e00f8938f8..000000000000
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ /dev/null
@@ -1,839 +0,0 @@
-/*
- ivtv driver internal defines and structures
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_DRIVER_H
-#define IVTV_DRIVER_H
-
-/* Internal header for ivtv project:
- * Driver for the cx23415/6 chip.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- * License: GPL
- * http://www.ivtvdriver.org
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/pagemap.h>
-#include <linux/scatterlist.h>
-#include <linux/kthread.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-#include <asm/byteorder.h>
-
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-fh.h>
-#include <media/tuner.h>
-#include <media/cx2341x.h>
-#include <media/ir-kbd-i2c.h>
-
-#include <linux/ivtv.h>
-
-/* Memory layout */
-#define IVTV_ENCODER_OFFSET 0x00000000
-#define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
-#define IVTV_DECODER_OFFSET 0x01000000
-#define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
-#define IVTV_REG_OFFSET 0x02000000
-#define IVTV_REG_SIZE 0x00010000
-
-/* Maximum ivtv driver instances. Some people have a huge number of
- capture cards, so set this to a high value. */
-#define IVTV_MAX_CARDS 32
-
-#define IVTV_ENC_STREAM_TYPE_MPG 0
-#define IVTV_ENC_STREAM_TYPE_YUV 1
-#define IVTV_ENC_STREAM_TYPE_VBI 2
-#define IVTV_ENC_STREAM_TYPE_PCM 3
-#define IVTV_ENC_STREAM_TYPE_RAD 4
-#define IVTV_DEC_STREAM_TYPE_MPG 5
-#define IVTV_DEC_STREAM_TYPE_VBI 6
-#define IVTV_DEC_STREAM_TYPE_VOUT 7
-#define IVTV_DEC_STREAM_TYPE_YUV 8
-#define IVTV_MAX_STREAMS 9
-
-#define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */
-
-/* DMA Registers */
-#define IVTV_REG_DMAXFER (0x0000)
-#define IVTV_REG_DMASTATUS (0x0004)
-#define IVTV_REG_DECDMAADDR (0x0008)
-#define IVTV_REG_ENCDMAADDR (0x000c)
-#define IVTV_REG_DMACONTROL (0x0010)
-#define IVTV_REG_IRQSTATUS (0x0040)
-#define IVTV_REG_IRQMASK (0x0048)
-
-/* Setup Registers */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
-#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8)
-#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC)
-#define IVTV_REG_VDM (0x2800)
-#define IVTV_REG_AO (0x2D00)
-#define IVTV_REG_BYTEFLUSH (0x2D24)
-#define IVTV_REG_SPU (0x9050)
-#define IVTV_REG_HW_BLOCKS (0x9054)
-#define IVTV_REG_VPU (0x9058)
-#define IVTV_REG_APU (0xA064)
-
-/* Other registers */
-#define IVTV_REG_DEC_LINE_FIELD (0x28C0)
-
-/* debugging */
-extern int ivtv_debug;
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-extern int ivtv_fw_debug;
-#endif
-
-#define IVTV_DBGFLG_WARN (1 << 0)
-#define IVTV_DBGFLG_INFO (1 << 1)
-#define IVTV_DBGFLG_MB (1 << 2)
-#define IVTV_DBGFLG_IOCTL (1 << 3)
-#define IVTV_DBGFLG_FILE (1 << 4)
-#define IVTV_DBGFLG_DMA (1 << 5)
-#define IVTV_DBGFLG_IRQ (1 << 6)
-#define IVTV_DBGFLG_DEC (1 << 7)
-#define IVTV_DBGFLG_YUV (1 << 8)
-#define IVTV_DBGFLG_I2C (1 << 9)
-/* Flag to turn on high volume debugging */
-#define IVTV_DBGFLG_HIGHVOL (1 << 10)
-
-#define IVTV_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & ivtv_debug) \
- v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
- } while (0)
-#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
-#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_DEBUG_MB(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_MB, "mb", fmt , ## args)
-#define IVTV_DEBUG_DMA(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_FILE(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_FILE, "file", fmt , ## args)
-#define IVTV_DEBUG_I2C(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_IRQ(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
- do { \
- if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
- v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
- } while (0)
-#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
-#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_DEBUG_HI_MB(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB, "mb", fmt , ## args)
-#define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_HI_FILE(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE, "file", fmt , ## args)
-#define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-/* Standard kernel messages */
-#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args)
-#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args)
-#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args)
-
-/* output modes (cx23415 only) */
-#define OUT_NONE 0
-#define OUT_MPG 1
-#define OUT_YUV 2
-#define OUT_UDMA_YUV 3
-#define OUT_PASSTHROUGH 4
-
-#define IVTV_MAX_PGM_INDEX (400)
-
-/* Default I2C SCL period in microseconds */
-#define IVTV_DEFAULT_I2C_CLOCK_PERIOD 20
-
-struct ivtv_options {
- int kilobytes[IVTV_MAX_STREAMS]; /* size in kilobytes of each stream */
- int cardtype; /* force card type on load */
- int tuner; /* set tuner on load */
- int radio; /* enable/disable radio */
- int newi2c; /* new I2C algorithm */
- int i2c_clock_period; /* period of SCL for I2C bus */
-};
-
-/* ivtv-specific mailbox template */
-struct ivtv_mailbox {
- u32 flags;
- u32 cmd;
- u32 retval;
- u32 timeout;
- u32 data[CX2341X_MBOX_MAX_DATA];
-};
-
-struct ivtv_api_cache {
- unsigned long last_jiffies; /* when last command was issued */
- u32 data[CX2341X_MBOX_MAX_DATA]; /* last sent api data */
-};
-
-struct ivtv_mailbox_data {
- volatile struct ivtv_mailbox __iomem *mbox;
- /* Bits 0-2 are for the encoder mailboxes, 0-1 are for the decoder mailboxes.
- If the bit is set, then the corresponding mailbox is in use by the driver. */
- unsigned long busy;
- u8 max_mbox;
-};
-
-/* per-buffer bit flags */
-#define IVTV_F_B_NEED_BUF_SWAP (1 << 0) /* this buffer should be byte swapped */
-
-/* per-stream, s_flags */
-#define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */
-#define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */
-#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */
-
-#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */
-#define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
-#define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
-#define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */
-#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
-#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
-
-#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */
-#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
-
-/* per-ivtv, i_flags */
-#define IVTV_F_I_DMA 0 /* DMA in progress */
-#define IVTV_F_I_UDMA 1 /* UDMA in progress */
-#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */
-#define IVTV_F_I_EOS 4 /* end of encoder stream reached */
-#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */
-#define IVTV_F_I_DIG_RST 6 /* reset digitizer */
-#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
-#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
-#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
-#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
-#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
-#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */
-#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
-#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
-#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
-#define IVTV_F_I_PIO 19 /* PIO in progress */
-#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
-#define IVTV_F_I_INITED 21 /* set after first open */
-#define IVTV_F_I_FAILED 22 /* set if first open failed */
-
-/* Event notifications */
-#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
-#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
-#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
-#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
-
-/* Scatter-Gather array element, used in DMA transfers */
-struct ivtv_sg_element {
- __le32 src;
- __le32 dst;
- __le32 size;
-};
-
-struct ivtv_sg_host_element {
- u32 src;
- u32 dst;
- u32 size;
-};
-
-struct ivtv_user_dma {
- struct mutex lock;
- int page_count;
- struct page *map[IVTV_DMA_SG_OSD_ENT];
- /* Needed when dealing with highmem userspace buffers */
- struct page *bouncemap[IVTV_DMA_SG_OSD_ENT];
-
- /* Base Dev SG Array for cx23415/6 */
- struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT];
- dma_addr_t SG_handle;
- int SG_length;
-
- /* SG List of Buffers */
- struct scatterlist SGlist[IVTV_DMA_SG_OSD_ENT];
-};
-
-struct ivtv_dma_page_info {
- unsigned long uaddr;
- unsigned long first;
- unsigned long last;
- unsigned int offset;
- unsigned int tail;
- int page_count;
-};
-
-struct ivtv_buffer {
- struct list_head list;
- dma_addr_t dma_handle;
- unsigned short b_flags;
- unsigned short dma_xfer_cnt;
- char *buf;
- u32 bytesused;
- u32 readpos;
-};
-
-struct ivtv_queue {
- struct list_head list; /* the list of buffers in this queue */
- u32 buffers; /* number of buffers in this queue */
- u32 length; /* total number of bytes of available buffer space */
- u32 bytesused; /* total number of bytes used in this queue */
-};
-
-struct ivtv; /* forward reference */
-
-struct ivtv_stream {
- /* These first four fields are always set, even if the stream
- is not actually created. */
- struct video_device *vdev; /* NULL when stream not created */
- struct ivtv *itv; /* for ease of use */
- const char *name; /* name of the stream */
- int type; /* stream type */
- u32 caps; /* V4L2 capabilities */
-
- struct v4l2_fh *fh; /* pointer to the streaming filehandle */
- spinlock_t qlock; /* locks access to the queues */
- unsigned long s_flags; /* status flags, see above */
- int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
- u32 pending_offset;
- u32 pending_backup;
- u64 pending_pts;
-
- u32 dma_offset;
- u32 dma_backup;
- u64 dma_pts;
-
- int subtype;
- wait_queue_head_t waitq;
- u32 dma_last_offset;
-
- /* Buffer Stats */
- u32 buffers;
- u32 buf_size;
- u32 buffers_stolen;
-
- /* Buffer Queues */
- struct ivtv_queue q_free; /* free buffers */
- struct ivtv_queue q_full; /* full buffers */
- struct ivtv_queue q_io; /* waiting for I/O */
- struct ivtv_queue q_dma; /* waiting for DMA */
- struct ivtv_queue q_predma; /* waiting for DMA */
-
- /* DMA xfer counter, buffers belonging to the same DMA
- xfer will have the same dma_xfer_cnt. */
- u16 dma_xfer_cnt;
-
- /* Base Dev SG Array for cx23415/6 */
- struct ivtv_sg_host_element *sg_pending;
- struct ivtv_sg_host_element *sg_processing;
- struct ivtv_sg_element *sg_dma;
- dma_addr_t sg_handle;
- int sg_pending_size;
- int sg_processing_size;
- int sg_processed;
-
- /* SG List of Buffers */
- struct scatterlist *SGlist;
-};
-
-struct ivtv_open_id {
- struct v4l2_fh fh;
- int type; /* stream type */
- int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
- struct ivtv *itv;
-};
-
-static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh)
-{
- return container_of(fh, struct ivtv_open_id, fh);
-}
-
-struct yuv_frame_info
-{
- u32 update;
- s32 src_x;
- s32 src_y;
- u32 src_w;
- u32 src_h;
- s32 dst_x;
- s32 dst_y;
- u32 dst_w;
- u32 dst_h;
- s32 pan_x;
- s32 pan_y;
- u32 vis_w;
- u32 vis_h;
- u32 interlaced_y;
- u32 interlaced_uv;
- s32 tru_x;
- u32 tru_w;
- u32 tru_h;
- u32 offset_y;
- s32 lace_mode;
- u32 sync_field;
- u32 delay;
- u32 interlaced;
-};
-
-#define IVTV_YUV_MODE_INTERLACED 0x00
-#define IVTV_YUV_MODE_PROGRESSIVE 0x01
-#define IVTV_YUV_MODE_AUTO 0x02
-#define IVTV_YUV_MODE_MASK 0x03
-
-#define IVTV_YUV_SYNC_EVEN 0x00
-#define IVTV_YUV_SYNC_ODD 0x04
-#define IVTV_YUV_SYNC_MASK 0x04
-
-#define IVTV_YUV_BUFFERS 8
-
-struct yuv_playback_info
-{
- u32 reg_2834;
- u32 reg_2838;
- u32 reg_283c;
- u32 reg_2840;
- u32 reg_2844;
- u32 reg_2848;
- u32 reg_2854;
- u32 reg_285c;
- u32 reg_2864;
-
- u32 reg_2870;
- u32 reg_2874;
- u32 reg_2890;
- u32 reg_2898;
- u32 reg_289c;
-
- u32 reg_2918;
- u32 reg_291c;
- u32 reg_2920;
- u32 reg_2924;
- u32 reg_2928;
- u32 reg_292c;
- u32 reg_2930;
-
- u32 reg_2934;
-
- u32 reg_2938;
- u32 reg_293c;
- u32 reg_2940;
- u32 reg_2944;
- u32 reg_2948;
- u32 reg_294c;
- u32 reg_2950;
- u32 reg_2954;
- u32 reg_2958;
- u32 reg_295c;
- u32 reg_2960;
- u32 reg_2964;
- u32 reg_2968;
- u32 reg_296c;
-
- u32 reg_2970;
-
- int v_filter_1;
- int v_filter_2;
- int h_filter;
-
- u8 track_osd; /* Should yuv output track the OSD size & position */
-
- u32 osd_x_offset;
- u32 osd_y_offset;
-
- u32 osd_x_pan;
- u32 osd_y_pan;
-
- u32 osd_vis_w;
- u32 osd_vis_h;
-
- u32 osd_full_w;
- u32 osd_full_h;
-
- int decode_height;
-
- int lace_mode;
- int lace_threshold;
- int lace_sync_field;
-
- atomic_t next_dma_frame;
- atomic_t next_fill_frame;
-
- u32 yuv_forced_update;
- int update_frame;
-
- u8 fields_lapsed; /* Counter used when delaying a frame */
-
- struct yuv_frame_info new_frame_info[IVTV_YUV_BUFFERS];
- struct yuv_frame_info old_frame_info;
- struct yuv_frame_info old_frame_info_args;
-
- void *blanking_ptr;
- dma_addr_t blanking_dmaptr;
-
- int stream_size;
-
- u8 draw_frame; /* PVR350 buffer to draw into */
- u8 max_frames_buffered; /* Maximum number of frames to buffer */
-
- struct v4l2_rect main_rect;
- u32 v4l2_src_w;
- u32 v4l2_src_h;
-
- u8 running; /* Have any frames been displayed */
-};
-
-#define IVTV_VBI_FRAMES 32
-
-/* VBI data */
-struct vbi_cc {
- u8 odd[2]; /* two-byte payload of odd field */
- u8 even[2]; /* two-byte payload of even field */;
-};
-
-struct vbi_vps {
- u8 data[5]; /* five-byte VPS payload */
-};
-
-struct vbi_info {
- /* VBI general data, does not change during streaming */
-
- u32 raw_decoder_line_size; /* raw VBI line size from digitizer */
- u8 raw_decoder_sav_odd_field; /* raw VBI Start Active Video digitizer code of odd field */
- u8 raw_decoder_sav_even_field; /* raw VBI Start Active Video digitizer code of even field */
- u32 sliced_decoder_line_size; /* sliced VBI line size from digitizer */
- u8 sliced_decoder_sav_odd_field; /* sliced VBI Start Active Video digitizer code of odd field */
- u8 sliced_decoder_sav_even_field; /* sliced VBI Start Active Video digitizer code of even field */
-
- u32 start[2]; /* start of first VBI line in the odd/even fields */
- u32 count; /* number of VBI lines per field */
- u32 raw_size; /* size of raw VBI line from the digitizer */
- u32 sliced_size; /* size of sliced VBI line from the digitizer */
-
- u32 dec_start; /* start in decoder memory of VBI re-insertion buffers */
- u32 enc_start; /* start in encoder memory of VBI capture buffers */
- u32 enc_size; /* size of VBI capture area */
- int fpi; /* number of VBI frames per interrupt */
-
- struct v4l2_format in; /* current VBI capture format */
- struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */
- int insert_mpeg; /* if non-zero, then embed VBI data in MPEG stream */
-
- /* Raw VBI compatibility hack */
-
- u32 frame; /* frame counter hack needed for backwards compatibility
- of old VBI software */
-
- /* Sliced VBI output data */
-
- struct vbi_cc cc_payload[256]; /* sliced VBI CC payload array: it is an array to
- prevent dropping CC data if they couldn't be
- processed fast enough */
- int cc_payload_idx; /* index in cc_payload */
- u8 cc_missing_cnt; /* counts number of frames without CC for passthrough mode */
- int wss_payload; /* sliced VBI WSS payload */
- u8 wss_missing_cnt; /* counts number of frames without WSS for passthrough mode */
- struct vbi_vps vps_payload; /* sliced VBI VPS payload */
-
- /* Sliced VBI capture data */
-
- struct v4l2_sliced_vbi_data sliced_data[36]; /* sliced VBI storage for VBI encoder stream */
- struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */
-
- /* VBI Embedding data */
-
- /* Buffer for VBI data inserted into MPEG stream.
- The first byte is a dummy byte that's never used.
- The next 16 bytes contain the MPEG header for the VBI data,
- the remainder is the actual VBI data.
- The max size accepted by the MPEG VBI reinsertion turns out
- to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
- where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
- a single line header byte and 2 * 18 is the number of VBI lines per frame.
-
- However, it seems that the data must be 1K aligned, so we have to
- pad the data until the 1 or 2 K boundary.
-
- This pointer array will allocate 2049 bytes to store each VBI frame. */
- u8 *sliced_mpeg_data[IVTV_VBI_FRAMES];
- u32 sliced_mpeg_size[IVTV_VBI_FRAMES];
- struct ivtv_buffer sliced_mpeg_buf; /* temporary buffer holding data from sliced_mpeg_data */
- u32 inserted_frame; /* index in sliced_mpeg_size of next sliced data
- to be inserted in the MPEG stream */
-};
-
-/* forward declaration of struct defined in ivtv-cards.h */
-struct ivtv_card;
-
-/* Struct to hold info about ivtv cards */
-struct ivtv {
- /* General fixed card data */
- struct pci_dev *pdev; /* PCI device */
- const struct ivtv_card *card; /* card information */
- const char *card_name; /* full name of the card */
- const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
- u8 has_cx23415; /* 1 if it is a cx23415 based card, 0 for cx23416 */
- u8 pvr150_workaround; /* 1 if the cx25840 needs to workaround a PVR150 bug */
- u8 nof_inputs; /* number of video inputs */
- u8 nof_audio_inputs; /* number of audio inputs */
- u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* hardware description of the board */
- v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
- struct v4l2_subdev *sd_video; /* controlling video decoder subdev */
- struct v4l2_subdev *sd_audio; /* controlling audio subdev */
- struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */
- resource_size_t base_addr; /* PCI resource base address */
- volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
- volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
- volatile void __iomem *reg_mem; /* pointer to mapped registers */
- struct ivtv_options options; /* user options */
-
- struct v4l2_device v4l2_dev;
- struct cx2341x_handler cxhdl;
- struct {
- /* PTS/Frame count control cluster */
- struct v4l2_ctrl *ctrl_pts;
- struct v4l2_ctrl *ctrl_frame;
- };
- struct {
- /* Audio Playback control cluster */
- struct v4l2_ctrl *ctrl_audio_playback;
- struct v4l2_ctrl *ctrl_audio_multilingual_playback;
- };
- struct v4l2_ctrl_handler hdl_gpio;
- struct v4l2_subdev sd_gpio; /* GPIO sub-device */
- u16 instance;
-
- /* High-level state info */
- unsigned long i_flags; /* global ivtv flags */
- u8 is_50hz; /* 1 if the current capture standard is 50 Hz */
- u8 is_60hz /* 1 if the current capture standard is 60 Hz */;
- u8 is_out_50hz /* 1 if the current TV output standard is 50 Hz */;
- u8 is_out_60hz /* 1 if the current TV output standard is 60 Hz */;
- int output_mode; /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */
- u32 audio_input; /* current audio input */
- u32 active_input; /* current video input */
- u32 active_output; /* current video output */
- v4l2_std_id std; /* current capture TV standard */
- v4l2_std_id std_out; /* current TV output standard */
- u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
- u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
-
- /* Locking */
- spinlock_t lock; /* lock access to this struct */
- struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
-
- /* Streams */
- int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */
- struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
- atomic_t capturing; /* count number of active capture streams */
- atomic_t decoding; /* count number of active decoding streams */
-
-
- /* Interrupts & DMA */
- u32 irqmask; /* active interrupts */
- u32 irq_rr_idx; /* round-robin stream index */
- struct kthread_worker irq_worker; /* kthread worker for PIO/YUV/VBI actions */
- struct task_struct *irq_worker_task; /* task for irq_worker */
- struct kthread_work irq_work; /* kthread work entry */
- spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
- int cur_dma_stream; /* index of current stream doing DMA (-1 if none) */
- int cur_pio_stream; /* index of current stream doing PIO (-1 if none) */
- u32 dma_data_req_offset; /* store offset in decoder memory of current DMA request */
- u32 dma_data_req_size; /* store size of current DMA request */
- int dma_retries; /* current DMA retry attempt */
- struct ivtv_user_dma udma; /* user based DMA for OSD */
- struct timer_list dma_timer; /* timer used to catch unfinished DMAs */
- u32 last_vsync_field; /* last seen vsync field */
- wait_queue_head_t dma_waitq; /* wake up when the current DMA is finished */
- wait_queue_head_t eos_waitq; /* wake up when EOS arrives */
- wait_queue_head_t event_waitq; /* wake up when the next decoder event arrives */
- wait_queue_head_t vsync_waitq; /* wake up when the next decoder vsync arrives */
-
-
- /* Mailbox */
- struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */
- struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */
- struct ivtv_api_cache api_cache[256]; /* cached API commands */
-
-
- /* I2C */
- struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
- struct i2c_client i2c_client;
- int i2c_state; /* i2c bit state */
- struct mutex i2c_bus_lock; /* lock i2c bus */
-
- struct IR_i2c_init_data ir_i2c_init_data;
-
- /* Program Index information */
- u32 pgm_info_offset; /* start of pgm info in encoder memory */
- u32 pgm_info_num; /* number of elements in the pgm cyclic buffer in encoder memory */
- u32 pgm_info_write_idx; /* last index written by the card that was transferred to pgm_info[] */
- u32 pgm_info_read_idx; /* last index in pgm_info read by the application */
- struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */
-
-
- /* Miscellaneous */
- u32 open_id; /* incremented each time an open occurs, is >= 1 */
- int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
- int speed; /* current playback speed setting */
- u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */
- u64 mpg_data_received; /* number of bytes received from the MPEG stream */
- u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
- u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
- unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
-
-
- /* VBI state info */
- struct vbi_info vbi; /* VBI-specific data */
-
-
- /* YUV playback */
- struct yuv_playback_info yuv_info; /* YUV playback data */
-
-
- /* OSD support */
- unsigned long osd_video_pbase;
- int osd_global_alpha_state; /* 1 = global alpha is on */
- int osd_local_alpha_state; /* 1 = local alpha is on */
- int osd_chroma_key_state; /* 1 = chroma-keying is on */
- u8 osd_global_alpha; /* current global alpha */
- u32 osd_chroma_key; /* current chroma key */
- struct v4l2_rect osd_rect; /* current OSD position and size */
- struct v4l2_rect main_rect; /* current Main window position and size */
- struct osd_info *osd_info; /* ivtvfb private OSD info */
- void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */
-};
-
-static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct ivtv, v4l2_dev);
-}
-
-/* Globals */
-extern int ivtv_first_minor;
-
-/*==============Prototypes==================*/
-
-/* Hardware/IRQ */
-void ivtv_set_irq_mask(struct ivtv *itv, u32 mask);
-void ivtv_clear_irq_mask(struct ivtv *itv, u32 mask);
-
-/* try to set output mode, return current mode. */
-int ivtv_set_output_mode(struct ivtv *itv, int mode);
-
-/* return current output stream based on current mode */
-struct ivtv_stream *ivtv_get_output_stream(struct ivtv *itv);
-
-/* Return non-zero if a signal is pending */
-int ivtv_msleep_timeout(unsigned int msecs, int intr);
-
-/* Wait on queue, returns -EINTR if interrupted */
-int ivtv_waitq(wait_queue_head_t *waitq);
-
-/* Read Hauppauge eeprom */
-struct tveeprom; /* forward reference */
-void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
-
-/* First-open initialization: load firmware, init cx25840, etc. */
-int ivtv_init_on_first_open(struct ivtv *itv);
-
-/* Test if the current VBI mode is raw (1) or sliced (0) */
-static inline int ivtv_raw_vbi(const struct ivtv *itv)
-{
- return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
-}
-
-/* This is a PCI post thing, where if the pci register is not read, then
- the write doesn't always take effect right away. By reading back the
- register any pending PCI writes will be performed (in order), and so
- you can be sure that the writes are guaranteed to be done.
-
- Rarely needed, only in some timing sensitive cases.
- Apparently if this is not done some motherboards seem
- to kill the firmware and get into the broken state until computer is
- rebooted. */
-#define write_sync(val, reg) \
- do { writel(val, reg); readl(reg); } while (0)
-
-#define read_reg(reg) readl(itv->reg_mem + (reg))
-#define write_reg(val, reg) writel(val, itv->reg_mem + (reg))
-#define write_reg_sync(val, reg) \
- do { write_reg(val, reg); read_reg(reg); } while (0)
-
-#define read_enc(addr) readl(itv->enc_mem + (u32)(addr))
-#define write_enc(val, addr) writel(val, itv->enc_mem + (u32)(addr))
-#define write_enc_sync(val, addr) \
- do { write_enc(val, addr); read_enc(addr); } while (0)
-
-#define read_dec(addr) readl(itv->dec_mem + (u32)(addr))
-#define write_dec(val, addr) writel(val, itv->dec_mem + (u32)(addr))
-#define write_dec_sync(val, addr) \
- do { write_dec(val, addr); read_dec(addr); } while (0)
-
-/* Call the specified callback for all subdevs matching hw (if 0, then
- match them all). Ignore any errors. */
-#define ivtv_call_hw(itv, hw, o, f, args...) \
- do { \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_p(&(itv)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
- } while (0)
-
-#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
-
-/* Call the specified callback for all subdevs matching hw (if 0, then
- match them all). If the callback returns an error other than 0 or
- -ENOIOCTLCMD, then return with that error code. */
-#define ivtv_call_hw_err(itv, hw, o, f, args...) \
-({ \
- struct v4l2_subdev *__sd; \
- __v4l2_device_call_subdevs_until_err_p(&(itv)->v4l2_dev, __sd, \
- !(hw) || (__sd->grp_id & (hw)), o, f , ##args); \
-})
-
-#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
deleted file mode 100644
index 88bce907cdef..000000000000
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- file operation functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-fileops.h"
-#include "ivtv-i2c.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-vbi.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-routing.h"
-#include "ivtv-streams.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include "ivtv-firmware.h"
-#include <media/v4l2-event.h>
-#include <media/saa7115.h>
-
-/* This function tries to claim the stream for a specific file descriptor.
- If no one else is using this stream then the stream is claimed and
- associated VBI streams are also automatically claimed.
- Possible error returns: -EBUSY if someone else has claimed
- the stream or 0 on success. */
-static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[type];
- struct ivtv_stream *s_vbi;
- int vbi_type;
-
- if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- /* someone already claimed this stream */
- if (s->fh == &id->fh) {
- /* yes, this file descriptor did. So that's OK. */
- return 0;
- }
- if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
- type == IVTV_ENC_STREAM_TYPE_VBI)) {
- /* VBI is handled already internally, now also assign
- the file descriptor to this stream for external
- reading of the stream. */
- s->fh = &id->fh;
- IVTV_DEBUG_INFO("Start Read VBI\n");
- return 0;
- }
- /* someone else is using this stream already */
- IVTV_DEBUG_INFO("Stream %d is busy\n", type);
- return -EBUSY;
- }
- s->fh = &id->fh;
- if (type == IVTV_DEC_STREAM_TYPE_VBI) {
- /* Enable reinsertion interrupt */
- ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- }
-
- /* IVTV_DEC_STREAM_TYPE_MPG needs to claim IVTV_DEC_STREAM_TYPE_VBI,
- IVTV_ENC_STREAM_TYPE_MPG needs to claim IVTV_ENC_STREAM_TYPE_VBI
- (provided VBI insertion is on and sliced VBI is selected), for all
- other streams we're done */
- if (type == IVTV_DEC_STREAM_TYPE_MPG) {
- vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
- } else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
- itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
- vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
- } else {
- return 0;
- }
- s_vbi = &itv->streams[vbi_type];
-
- if (!test_and_set_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags)) {
- /* Enable reinsertion interrupt */
- if (vbi_type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- }
- /* mark that it is used internally */
- set_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags);
- return 0;
-}
-
-/* This function releases a previously claimed stream. It will take into
- account associated VBI streams. */
-void ivtv_release_stream(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi;
-
- s->fh = NULL;
- if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
- /* this stream is still in use internally */
- return;
- }
- if (!test_and_clear_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- IVTV_DEBUG_WARN("Release stream %s not in use!\n", s->name);
- return;
- }
-
- ivtv_flush_queues(s);
-
- /* disable reinsertion interrupt */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
-
- /* IVTV_DEC_STREAM_TYPE_MPG needs to release IVTV_DEC_STREAM_TYPE_VBI,
- IVTV_ENC_STREAM_TYPE_MPG needs to release IVTV_ENC_STREAM_TYPE_VBI,
- for all other streams we're done */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- s_vbi = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
- else if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- else
- return;
-
- /* clear internal use flag */
- if (!test_and_clear_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags)) {
- /* was already cleared */
- return;
- }
- if (s_vbi->fh) {
- /* VBI stream still claimed by a file descriptor */
- return;
- }
- /* disable reinsertion interrupt */
- if (s_vbi->type == IVTV_DEC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
- clear_bit(IVTV_F_S_CLAIMED, &s_vbi->s_flags);
- ivtv_flush_queues(s_vbi);
-}
-
-static void ivtv_dualwatch(struct ivtv *itv)
-{
- struct v4l2_tuner vt;
- u32 new_stereo_mode;
- const u32 dual = 0x02;
-
- new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
- memset(&vt, 0, sizeof(vt));
- ivtv_call_all(itv, tuner, g_tuner, &vt);
- if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
- new_stereo_mode = dual;
-
- if (new_stereo_mode == itv->dualwatch_stereo_mode)
- return;
-
- IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
- itv->dualwatch_stereo_mode, new_stereo_mode);
- if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode))
- IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
-}
-
-static void ivtv_update_pgm_info(struct ivtv *itv)
-{
- u32 wr_idx = (read_enc(itv->pgm_info_offset) - itv->pgm_info_offset - 4) / 24;
- int cnt;
- int i = 0;
-
- if (wr_idx >= itv->pgm_info_num) {
- IVTV_DEBUG_WARN("Invalid PGM index %d (>= %d)\n", wr_idx, itv->pgm_info_num);
- return;
- }
- cnt = (wr_idx + itv->pgm_info_num - itv->pgm_info_write_idx) % itv->pgm_info_num;
- while (i < cnt) {
- int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
- struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
- u32 addr = itv->pgm_info_offset + 4 + idx * 24;
- const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1,
- V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };
- // 1=I, 2=P, 4=B
-
- e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32);
- if (e->offset > itv->mpg_data_received) {
- break;
- }
- e->offset += itv->vbi_data_inserted;
- e->length = read_enc(addr);
- e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32);
- e->flags = mapping[read_enc(addr + 12) & 7];
- i++;
- }
- itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
-}
-
-static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- struct ivtv_buffer *buf;
- DEFINE_WAIT(wait);
-
- *err = 0;
- while (1) {
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG) {
- /* Process pending program info updates and pending VBI data */
- ivtv_update_pgm_info(itv);
-
- if (time_after(jiffies,
- itv->dualwatch_jiffies +
- msecs_to_jiffies(1000))) {
- itv->dualwatch_jiffies = jiffies;
- ivtv_dualwatch(itv);
- }
-
- if (test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
- while ((buf = ivtv_dequeue(s_vbi, &s_vbi->q_full))) {
- /* byteswap and process VBI data */
- ivtv_process_vbi_data(itv, buf, s_vbi->dma_pts, s_vbi->type);
- ivtv_enqueue(s_vbi, buf, &s_vbi->q_free);
- }
- }
- buf = &itv->vbi.sliced_mpeg_buf;
- if (buf->readpos != buf->bytesused) {
- return buf;
- }
- }
-
- /* do we have leftover data? */
- buf = ivtv_dequeue(s, &s->q_io);
- if (buf)
- return buf;
-
- /* do we have new data? */
- buf = ivtv_dequeue(s, &s->q_full);
- if (buf) {
- if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0)
- return buf;
- buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP;
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- /* byteswap MPG data */
- ivtv_buf_swap(buf);
- else if (s->type != IVTV_DEC_STREAM_TYPE_VBI) {
- /* byteswap and process VBI data */
- ivtv_process_vbi_data(itv, buf, s->dma_pts, s->type);
- }
- return buf;
- }
-
- /* return if end of stream */
- if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- IVTV_DEBUG_INFO("EOS %s\n", s->name);
- return NULL;
- }
-
- /* return if file was opened with O_NONBLOCK */
- if (non_block) {
- *err = -EAGAIN;
- return NULL;
- }
-
- /* wait for more data to arrive */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added to the waitqueue */
- if (!s->q_full.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- /* return if a signal was received */
- IVTV_DEBUG_INFO("User stopped %s\n", s->name);
- *err = -EINTR;
- return NULL;
- }
- }
-}
-
-static void ivtv_setup_sliced_vbi_buf(struct ivtv *itv)
-{
- int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
-
- itv->vbi.sliced_mpeg_buf.buf = itv->vbi.sliced_mpeg_data[idx];
- itv->vbi.sliced_mpeg_buf.bytesused = itv->vbi.sliced_mpeg_size[idx];
- itv->vbi.sliced_mpeg_buf.readpos = 0;
-}
-
-static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *buf,
- char __user *ubuf, size_t ucount)
-{
- struct ivtv *itv = s->itv;
- size_t len = buf->bytesused - buf->readpos;
-
- if (len > ucount) len = ucount;
- if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- !ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
- const char *start = buf->buf + buf->readpos;
- const char *p = start + 1;
- const u8 *q;
- u8 ch = itv->search_pack_header ? 0xba : 0xe0;
- int stuffing, i;
-
- while (start + len > p && (q = memchr(p, 0, start + len - p))) {
- p = q + 1;
- if ((char *)q + 15 >= buf->buf + buf->bytesused ||
- q[1] != 0 || q[2] != 1 || q[3] != ch) {
- continue;
- }
- if (!itv->search_pack_header) {
- if ((q[6] & 0xc0) != 0x80)
- continue;
- if (((q[7] & 0xc0) == 0x80 && (q[9] & 0xf0) == 0x20) ||
- ((q[7] & 0xc0) == 0xc0 && (q[9] & 0xf0) == 0x30)) {
- ch = 0xba;
- itv->search_pack_header = 1;
- p = q + 9;
- }
- continue;
- }
- stuffing = q[13] & 7;
- /* all stuffing bytes must be 0xff */
- for (i = 0; i < stuffing; i++)
- if (q[14 + i] != 0xff)
- break;
- if (i == stuffing && (q[4] & 0xc4) == 0x44 && (q[12] & 3) == 3 &&
- q[14 + stuffing] == 0 && q[15 + stuffing] == 0 &&
- q[16 + stuffing] == 1) {
- itv->search_pack_header = 0;
- len = (char *)q - start;
- ivtv_setup_sliced_vbi_buf(itv);
- break;
- }
- }
- }
- if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) {
- IVTV_DEBUG_WARN("copy %zd bytes to user failed for %s\n", len, s->name);
- return -EFAULT;
- }
- /*IVTV_INFO("copied %lld %d %d %d %d %d vbi %d\n", itv->mpg_data_received, len, ucount,
- buf->readpos, buf->bytesused, buf->bytesused - buf->readpos - len,
- buf == &itv->vbi.sliced_mpeg_buf); */
- buf->readpos += len;
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && buf != &itv->vbi.sliced_mpeg_buf)
- itv->mpg_data_received += len;
- return len;
-}
-
-static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_count, int non_block)
-{
- struct ivtv *itv = s->itv;
- size_t tot_written = 0;
- int single_frame = 0;
-
- if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
- /* shouldn't happen */
- IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
- return -EIO;
- }
-
- /* Each VBI buffer is one frame, the v4l2 API says that for VBI the frames should
- arrive one-by-one, so make sure we never output more than one VBI frame at a time */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI ||
- (s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
- single_frame = 1;
-
- for (;;) {
- struct ivtv_buffer *buf;
- int rc;
-
- buf = ivtv_get_buffer(s, non_block, &rc);
- /* if there is no data available... */
- if (buf == NULL) {
- /* if we got data, then return that regardless */
- if (tot_written)
- break;
- /* EOS condition */
- if (rc == 0) {
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- ivtv_release_stream(s);
- }
- /* set errno */
- return rc;
- }
- rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
- if (buf != &itv->vbi.sliced_mpeg_buf) {
- ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);
- }
- else if (buf->readpos == buf->bytesused) {
- int idx = itv->vbi.inserted_frame % IVTV_VBI_FRAMES;
- itv->vbi.sliced_mpeg_size[idx] = 0;
- itv->vbi.inserted_frame++;
- itv->vbi_data_inserted += buf->bytesused;
- }
- if (rc < 0)
- return rc;
- tot_written += rc;
-
- if (tot_written == tot_count || single_frame)
- break;
- }
- return tot_written;
-}
-
-static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t count,
- loff_t *pos, int non_block)
-{
- ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;
- struct ivtv *itv = s->itv;
-
- IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
- if (rc > 0)
- pos += rc;
- return rc;
-}
-
-int ivtv_start_capture(struct ivtv_open_id *id)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- struct ivtv_stream *s_vbi;
-
- if (s->type == IVTV_ENC_STREAM_TYPE_RAD ||
- s->type == IVTV_DEC_STREAM_TYPE_MPG ||
- s->type == IVTV_DEC_STREAM_TYPE_YUV ||
- s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
- /* you cannot read from these stream types. */
- return -EPERM;
- }
-
- /* Try to claim this stream. */
- if (ivtv_claim_stream(id, s->type))
- return -EBUSY;
-
- /* This stream does not need to start capturing */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* If capture is already in progress, then we also have to
- do nothing extra. */
- if (test_bit(IVTV_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return 0;
- }
-
- /* Start VBI capture if required */
- s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s_vbi->s_flags) &&
- !test_and_set_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
- /* Note: the IVTV_ENC_STREAM_TYPE_VBI is claimed
- automatically when the MPG stream is claimed.
- We only need to start the VBI capturing. */
- if (ivtv_start_v4l2_encode_stream(s_vbi)) {
- IVTV_DEBUG_WARN("VBI capture start failed\n");
-
- /* Failure, clean up and return an error */
- clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- /* also releases the associated VBI stream */
- ivtv_release_stream(s);
- return -EIO;
- }
- IVTV_DEBUG_INFO("VBI insertion started\n");
- }
-
- /* Tell the card to start capturing */
- if (!ivtv_start_v4l2_encode_stream(s)) {
- /* We're done */
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- /* Resume a possibly paused encoder */
- if (test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
- return 0;
- }
-
- /* failure, clean up */
- IVTV_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name);
-
- /* Note: the IVTV_ENC_STREAM_TYPE_VBI is released
- automatically when the MPG stream is released.
- We only need to stop the VBI capturing. */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags)) {
- ivtv_stop_v4l2_encode_stream(s_vbi, 0);
- clear_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags);
- }
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- ivtv_release_stream(s);
- return -EIO;
-}
-
-ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- ssize_t rc;
-
- IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
-
- if (mutex_lock_interruptible(&itv->serialize_lock))
- return -ERESTARTSYS;
- rc = ivtv_start_capture(id);
- if (!rc)
- rc = ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
- mutex_unlock(&itv->serialize_lock);
- return rc;
-}
-
-int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int rc;
-
- if (atomic_read(&itv->decoding) == 0) {
- if (ivtv_claim_stream(id, s->type)) {
- /* someone else is using this stream already */
- IVTV_DEBUG_WARN("start decode, stream already claimed\n");
- return -EBUSY;
- }
- rc = ivtv_start_v4l2_decode_stream(s, 0);
- if (rc < 0) {
- if (rc == -EAGAIN)
- rc = ivtv_start_v4l2_decode_stream(s, 0);
- if (rc < 0)
- return rc;
- }
- }
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- return ivtv_set_speed(itv, speed);
- return 0;
-}
-
-static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_buffer *buf;
- struct ivtv_queue q;
- int bytes_written = 0;
- int mode;
- int rc;
- DEFINE_WAIT(wait);
-
- IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
-
- if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&
- s->type != IVTV_DEC_STREAM_TYPE_YUV &&
- s->type != IVTV_DEC_STREAM_TYPE_VOUT)
- /* not decoder streams */
- return -EPERM;
-
- /* Try to claim this stream */
- if (ivtv_claim_stream(id, s->type))
- return -EBUSY;
-
- /* This stream does not need to start any decoding */
- if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
- int elems = count / sizeof(struct v4l2_sliced_vbi_data);
-
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return ivtv_write_vbi_from_user(itv,
- (const struct v4l2_sliced_vbi_data __user *)user_buf, elems);
- }
-
- mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
-
- if (ivtv_set_output_mode(itv, mode) != mode) {
- ivtv_release_stream(s);
- return -EBUSY;
- }
- ivtv_queue_init(&q);
- set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-
- /* Start decoder (returns 0 if already started) */
- rc = ivtv_start_decoding(id, itv->speed);
- if (rc) {
- IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
-
- /* failure, clean up */
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- return rc;
- }
-
-retry:
- /* If possible, just DMA the entire frame - Check the data transfer size
- since we may get here before the stream has been fully set-up */
- if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
- while (count >= itv->dma_data_req_size) {
- rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
-
- if (rc < 0)
- return rc;
-
- bytes_written += itv->dma_data_req_size;
- user_buf += itv->dma_data_req_size;
- count -= itv->dma_data_req_size;
- }
- if (count == 0) {
- IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
- return bytes_written;
- }
- }
-
- for (;;) {
- /* Gather buffers */
- while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_io)))
- ivtv_enqueue(s, buf, &q);
- while (q.length - q.bytesused < count && (buf = ivtv_dequeue(s, &s->q_free))) {
- ivtv_enqueue(s, buf, &q);
- }
- if (q.buffers)
- break;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become free before we were added to the waitqueue */
- if (!s->q_free.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- IVTV_DEBUG_INFO("User stopped %s\n", s->name);
- return -EINTR;
- }
- }
-
- /* copy user data into buffers */
- while ((buf = ivtv_dequeue(s, &q))) {
- /* yuv is a pain. Don't copy more data than needed for a single
- frame, otherwise we lose sync with the incoming stream */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
- yi->stream_size + count > itv->dma_data_req_size)
- rc = ivtv_buf_copy_from_user(s, buf, user_buf,
- itv->dma_data_req_size - yi->stream_size);
- else
- rc = ivtv_buf_copy_from_user(s, buf, user_buf, count);
-
- /* Make sure we really got all the user data */
- if (rc < 0) {
- ivtv_queue_move(s, &q, NULL, &s->q_free, 0);
- return rc;
- }
- user_buf += rc;
- count -= rc;
- bytes_written += rc;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- yi->stream_size += rc;
- /* If we have a complete yuv frame, break loop now */
- if (yi->stream_size == itv->dma_data_req_size) {
- ivtv_enqueue(s, buf, &s->q_full);
- yi->stream_size = 0;
- break;
- }
- }
-
- if (buf->bytesused != s->buf_size) {
- /* incomplete, leave in q_io for next time */
- ivtv_enqueue(s, buf, &s->q_io);
- break;
- }
- /* Byteswap MPEG buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_buf_swap(buf);
- ivtv_enqueue(s, buf, &s->q_full);
- }
-
- if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
- if (s->q_full.length >= itv->dma_data_req_size) {
- int got_sig;
-
- if (mode == OUT_YUV)
- ivtv_yuv_setup_stream_frame(itv);
-
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (!(got_sig = signal_pending(current)) &&
- test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig) {
- IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
- return -EINTR;
- }
-
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
- ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 1);
- }
- }
- /* more user data is available, wait until buffers become free
- to transfer the rest. */
- if (count && !(filp->f_flags & O_NONBLOCK))
- goto retry;
- IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
- return bytes_written;
-}
-
-ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- ssize_t res;
-
- if (mutex_lock_interruptible(&itv->serialize_lock))
- return -ERESTARTSYS;
- res = ivtv_write(filp, user_buf, count, pos);
- mutex_unlock(&itv->serialize_lock);
- return res;
-}
-
-unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int res = 0;
-
- /* add stream's waitq to the poll list */
- IVTV_DEBUG_HI_FILE("Decoder poll\n");
-
- /* If there are subscribed events, then only use the new event
- API instead of the old video.h based API. */
- if (!list_empty(&id->fh.subscribed)) {
- poll_wait(filp, &id->fh.wait, wait);
- /* Turn off the old-style vsync events */
- clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
- if (v4l2_event_pending(&id->fh))
- res = POLLPRI;
- } else {
- /* This is the old-style API which is here only for backwards
- compatibility. */
- poll_wait(filp, &s->waitq, wait);
- set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
- if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) ||
- test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
- res = POLLPRI;
- }
-
- /* Allow write if buffers are available for writing */
- if (s->q_free.buffers)
- res |= POLLOUT | POLLWRNORM;
- return res;
-}
-
-unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait)
-{
- unsigned long req_events = poll_requested_events(wait);
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
- int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- unsigned res = 0;
-
- /* Start a capture if there is none */
- if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags) &&
- (req_events & (POLLIN | POLLRDNORM))) {
- int rc;
-
- mutex_lock(&itv->serialize_lock);
- rc = ivtv_start_capture(id);
- mutex_unlock(&itv->serialize_lock);
- if (rc) {
- IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
- s->name, rc);
- return POLLERR;
- }
- IVTV_DEBUG_FILE("Encoder poll started capture\n");
- }
-
- /* add stream's waitq to the poll list */
- IVTV_DEBUG_HI_FILE("Encoder poll\n");
- poll_wait(filp, &s->waitq, wait);
- if (v4l2_event_pending(&id->fh))
- res |= POLLPRI;
- else
- poll_wait(filp, &id->fh.wait, wait);
-
- if (s->q_full.length || s->q_io.length)
- return res | POLLIN | POLLRDNORM;
- if (eof)
- return res | POLLHUP;
- return res;
-}
-
-void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close() of %s\n", s->name);
-
- /* 'Unclaim' this stream */
-
- /* Stop capturing */
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-
- IVTV_DEBUG_INFO("close stopping capture\n");
- /* Special case: a running VBI capture for VBI insertion
- in the mpeg stream. Need to stop that too. */
- if (id->type == IVTV_ENC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_STREAMING, &s_vbi->s_flags) &&
- !test_bit(IVTV_F_S_APPL_IO, &s_vbi->s_flags)) {
- IVTV_DEBUG_INFO("close stopping embedded VBI capture\n");
- ivtv_stop_v4l2_encode_stream(s_vbi, 0);
- }
- if ((id->type == IVTV_DEC_STREAM_TYPE_VBI ||
- id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
- test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
- /* Also used internally, don't stop capturing */
- s->fh = NULL;
- }
- else {
- ivtv_stop_v4l2_encode_stream(s, gop_end);
- }
- }
- if (!gop_end) {
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- ivtv_release_stream(s);
- }
-}
-
-static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
-{
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close() of %s\n", s->name);
-
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV &&
- test_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags)) {
- /* Restore registers we've changed & clean up any mess */
- ivtv_yuv_close(itv);
- }
-
- /* Stop decoding */
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- IVTV_DEBUG_INFO("close stopping decode\n");
-
- ivtv_stop_v4l2_decode_stream(s, flags, pts);
- itv->output_mode = OUT_NONE;
- }
- clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
- itv->output_mode = OUT_NONE;
-
- itv->speed = 0;
- clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
- ivtv_release_stream(s);
-}
-
-int ivtv_v4l2_close(struct file *filp)
-{
- struct v4l2_fh *fh = filp->private_data;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- IVTV_DEBUG_FILE("close %s\n", s->name);
-
- mutex_lock(&itv->serialize_lock);
-
- /* Stop radio */
- if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- /* Closing radio device, return to TV mode */
- ivtv_mute(itv);
- /* Mark that the radio is no longer in use */
- clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
- /* Switch tuner to TV */
- ivtv_call_all(itv, core, s_std, itv->std);
- /* Select correct audio input (i.e. TV tuner or Line in) */
- ivtv_audio_set_io(itv);
- if (itv->hw_flags & IVTV_HW_SAA711X) {
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
- SAA7115_FREQ_32_11_MHZ, 0);
- }
- if (atomic_read(&itv->capturing) > 0) {
- /* Undo video mute */
- ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
- v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
- (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
- }
- /* Done! Unmute and continue. */
- ivtv_unmute(itv);
- }
-
- v4l2_fh_del(fh);
- v4l2_fh_exit(fh);
-
- /* Easy case first: this stream was never claimed by us */
- if (s->fh != &id->fh)
- goto close_done;
-
- /* 'Unclaim' this stream */
-
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
- struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
-
- ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
-
- /* If all output streams are closed, and if the user doesn't have
- IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
- if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
- /* disable CC on TV-out */
- ivtv_disable_cc(itv);
- }
- } else {
- ivtv_stop_capture(id, 0);
- }
-close_done:
- kfree(id);
- mutex_unlock(&itv->serialize_lock);
- return 0;
-}
-
-static int ivtv_open(struct file *filp)
-{
- struct video_device *vdev = video_devdata(filp);
- struct ivtv_stream *s = video_get_drvdata(vdev);
- struct ivtv *itv = s->itv;
- struct ivtv_open_id *item;
- int res = 0;
-
- IVTV_DEBUG_FILE("open %s\n", s->name);
-
- if (ivtv_init_on_first_open(itv)) {
- IVTV_ERR("Failed to initialize on device %s\n",
- video_device_node_name(vdev));
- return -ENXIO;
- }
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- /* Unless ivtv_fw_debug is set, error out if firmware dead. */
- if (ivtv_fw_debug) {
- IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
- video_device_node_name(vdev));
- IVTV_WARN("Selected firmware errors will be ignored\n");
- } else {
-#else
- if (1) {
-#endif
- res = ivtv_firmware_check(itv, "ivtv_serialized_open");
- if (res == -EAGAIN)
- res = ivtv_firmware_check(itv, "ivtv_serialized_open");
- if (res < 0)
- return -EIO;
- }
-
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
- test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
- return -EBUSY;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
- test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
- return -EBUSY;
-
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- if (read_reg(0x82c) == 0) {
- IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
- /* return -ENODEV; */
- }
- ivtv_udma_alloc(itv);
- }
-
- /* Allocate memory */
- item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL);
- if (NULL == item) {
- IVTV_DEBUG_WARN("nomem on v4l2 open\n");
- return -ENOMEM;
- }
- v4l2_fh_init(&item->fh, s->vdev);
- item->itv = itv;
- item->type = s->type;
-
- filp->private_data = &item->fh;
- v4l2_fh_add(&item->fh);
-
- if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
- v4l2_fh_is_singular_file(filp)) {
- if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
- if (atomic_read(&itv->capturing) > 0) {
- /* switching to radio while capture is
- in progress is not polite */
- v4l2_fh_del(&item->fh);
- v4l2_fh_exit(&item->fh);
- kfree(item);
- return -EBUSY;
- }
- }
- /* Mark that the radio is being used. */
- set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
- /* We have the radio */
- ivtv_mute(itv);
- /* Switch tuner to radio */
- ivtv_call_all(itv, tuner, s_radio);
- /* Select the correct audio input (i.e. radio tuner) */
- ivtv_audio_set_io(itv);
- if (itv->hw_flags & IVTV_HW_SAA711X) {
- ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq,
- SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL);
- }
- /* Done! Unmute and continue. */
- ivtv_unmute(itv);
- }
-
- /* YUV or MPG Decoding Mode? */
- if (s->type == IVTV_DEC_STREAM_TYPE_MPG) {
- clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
- } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
- set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
- /* For yuv, we need to know the dma size before we start */
- itv->dma_data_req_size =
- 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
- itv->yuv_info.stream_size = 0;
- }
- return 0;
-}
-
-int ivtv_v4l2_open(struct file *filp)
-{
- struct video_device *vdev = video_devdata(filp);
- int res;
-
- if (mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
- res = ivtv_open(filp);
- mutex_unlock(vdev->lock);
- return res;
-}
-
-void ivtv_mute(struct ivtv *itv)
-{
- if (atomic_read(&itv->capturing))
- ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
- IVTV_DEBUG_INFO("Mute\n");
-}
-
-void ivtv_unmute(struct ivtv *itv)
-{
- if (atomic_read(&itv->capturing)) {
- ivtv_msleep_timeout(100, 0);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
- ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
- }
- IVTV_DEBUG_INFO("Unmute\n");
-}
diff --git a/drivers/media/video/ivtv/ivtv-fileops.h b/drivers/media/video/ivtv/ivtv-fileops.h
deleted file mode 100644
index 049a2923965d..000000000000
--- a/drivers/media/video/ivtv/ivtv-fileops.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- file operation functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_FILEOPS_H
-#define IVTV_FILEOPS_H
-
-/* Testing/Debugging */
-int ivtv_v4l2_open(struct file *filp);
-ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count,
- loff_t * pos);
-ssize_t ivtv_v4l2_write(struct file *filp, const char __user *buf, size_t count,
- loff_t * pos);
-int ivtv_v4l2_close(struct file *filp);
-unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait);
-unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table * wait);
-int ivtv_start_capture(struct ivtv_open_id *id);
-void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end);
-int ivtv_start_decoding(struct ivtv_open_id *id, int speed);
-void ivtv_mute(struct ivtv *itv);
-void ivtv_unmute(struct ivtv *itv);
-
-/* Utilities */
-
-/* Release a previously claimed stream. */
-void ivtv_release_stream(struct ivtv_stream *s);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
deleted file mode 100644
index 6ec7705af555..000000000000
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- ivtv firmware functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-firmware.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-cards.h"
-#include <linux/firmware.h>
-#include <media/saa7127.h>
-
-#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
-#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
-#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB
-#define IVTV_CMD_VDM_STOP 0x00000000
-#define IVTV_CMD_AO_STOP 0x00000005
-#define IVTV_CMD_APU_PING 0x00000000
-#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE
-#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-#define IVTV_CMD_SPU_STOP 0x00000001
-#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A
-#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640
-#define IVTV_SDRAM_SLEEPTIME 600
-
-#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg"
-#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024)
-
-/* Encoder/decoder firmware sizes */
-#define IVTV_FW_ENC_SIZE (376836)
-#define IVTV_FW_DEC_SIZE (256*1024)
-
-static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
-{
- const struct firmware *fw = NULL;
- int retries = 3;
-
-retry:
- if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
- int i;
- volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
- const u32 *src = (const u32 *)fw->data;
-
- if (fw->size != size) {
- /* Due to race conditions in firmware loading (esp. with udev <0.95)
- the wrong file was sometimes loaded. So we check filesizes to
- see if at least the right-sized file was loaded. If not, then we
- retry. */
- IVTV_INFO("Retry: file loaded was not %s (expected size %ld, got %zd)\n", fn, size, fw->size);
- release_firmware(fw);
- retries--;
- goto retry;
- }
- for (i = 0; i < fw->size; i += 4) {
- /* no need for endianness conversion on the ppc */
- __raw_writel(*src, dst);
- dst++;
- src++;
- }
- IVTV_INFO("Loaded %s firmware (%zd bytes)\n", fn, fw->size);
- release_firmware(fw);
- return size;
- }
- IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size);
- IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n");
- return -ENOMEM;
-}
-
-void ivtv_halt_firmware(struct ivtv *itv)
-{
- IVTV_DEBUG_INFO("Preparing for firmware halt.\n");
- if (itv->has_cx23415 && itv->dec_mbox.mbox)
- ivtv_vapi(itv, CX2341X_DEC_HALT_FW, 0);
- if (itv->enc_mbox.mbox)
- ivtv_vapi(itv, CX2341X_ENC_HALT_FW, 0);
-
- ivtv_msleep_timeout(10, 0);
- itv->enc_mbox.mbox = itv->dec_mbox.mbox = NULL;
-
- IVTV_DEBUG_INFO("Stopping VDM\n");
- write_reg(IVTV_CMD_VDM_STOP, IVTV_REG_VDM);
-
- IVTV_DEBUG_INFO("Stopping AO\n");
- write_reg(IVTV_CMD_AO_STOP, IVTV_REG_AO);
-
- IVTV_DEBUG_INFO("pinging (?) APU\n");
- write_reg(IVTV_CMD_APU_PING, IVTV_REG_APU);
-
- IVTV_DEBUG_INFO("Stopping VPU\n");
- if (!itv->has_cx23415)
- write_reg(IVTV_CMD_VPU_STOP16, IVTV_REG_VPU);
- else
- write_reg(IVTV_CMD_VPU_STOP15, IVTV_REG_VPU);
-
- IVTV_DEBUG_INFO("Resetting Hw Blocks\n");
- write_reg(IVTV_CMD_HW_BLOCKS_RST, IVTV_REG_HW_BLOCKS);
-
- IVTV_DEBUG_INFO("Stopping SPU\n");
- write_reg(IVTV_CMD_SPU_STOP, IVTV_REG_SPU);
-
- ivtv_msleep_timeout(10, 0);
-
- IVTV_DEBUG_INFO("init Encoder SDRAM pre-charge\n");
- write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_ENC_SDRAM_PRECHARGE);
-
- IVTV_DEBUG_INFO("init Encoder SDRAM refresh to 1us\n");
- write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_ENC_SDRAM_REFRESH);
-
- if (itv->has_cx23415) {
- IVTV_DEBUG_INFO("init Decoder SDRAM pre-charge\n");
- write_reg(IVTV_CMD_SDRAM_PRECHARGE_INIT, IVTV_REG_DEC_SDRAM_PRECHARGE);
-
- IVTV_DEBUG_INFO("init Decoder SDRAM refresh to 1us\n");
- write_reg(IVTV_CMD_SDRAM_REFRESH_INIT, IVTV_REG_DEC_SDRAM_REFRESH);
- }
-
- IVTV_DEBUG_INFO("Sleeping for %dms\n", IVTV_SDRAM_SLEEPTIME);
- ivtv_msleep_timeout(IVTV_SDRAM_SLEEPTIME, 0);
-}
-
-void ivtv_firmware_versions(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- /* Encoder */
- ivtv_vapi_result(itv, data, CX2341X_ENC_GET_VERSION, 0);
- IVTV_INFO("Encoder revision: 0x%08x\n", data[0]);
-
- if (data[0] != 0x02060039)
- IVTV_WARN("Recommended firmware version is 0x02060039.\n");
-
- if (itv->has_cx23415) {
- /* Decoder */
- ivtv_vapi_result(itv, data, CX2341X_DEC_GET_VERSION, 0);
- IVTV_INFO("Decoder revision: 0x%08x\n", data[0]);
- }
-}
-
-static int ivtv_firmware_copy(struct ivtv *itv)
-{
- IVTV_DEBUG_INFO("Loading encoder image\n");
- if (load_fw_direct(CX2341X_FIRM_ENC_FILENAME,
- itv->enc_mem, itv, IVTV_FW_ENC_SIZE) != IVTV_FW_ENC_SIZE) {
- IVTV_DEBUG_WARN("failed loading encoder firmware\n");
- return -3;
- }
- if (!itv->has_cx23415)
- return 0;
-
- IVTV_DEBUG_INFO("Loading decoder image\n");
- if (load_fw_direct(CX2341X_FIRM_DEC_FILENAME,
- itv->dec_mem, itv, IVTV_FW_DEC_SIZE) != IVTV_FW_DEC_SIZE) {
- IVTV_DEBUG_WARN("failed loading decoder firmware\n");
- return -1;
- }
- return 0;
-}
-
-static volatile struct ivtv_mailbox __iomem *ivtv_search_mailbox(const volatile u8 __iomem *mem, u32 size)
-{
- int i;
-
- /* mailbox is preceded by a 16 byte 'magic cookie' starting at a 256-byte
- address boundary */
- for (i = 0; i < size; i += 0x100) {
- if (readl(mem + i) == 0x12345678 &&
- readl(mem + i + 4) == 0x34567812 &&
- readl(mem + i + 8) == 0x56781234 &&
- readl(mem + i + 12) == 0x78123456) {
- return (volatile struct ivtv_mailbox __iomem *)(mem + i + 16);
- }
- }
- return NULL;
-}
-
-int ivtv_firmware_init(struct ivtv *itv)
-{
- int err;
-
- ivtv_halt_firmware(itv);
-
- /* load firmware */
- err = ivtv_firmware_copy(itv);
- if (err) {
- IVTV_DEBUG_WARN("Error %d loading firmware\n", err);
- return err;
- }
-
- /* start firmware */
- write_reg(read_reg(IVTV_REG_SPU) & IVTV_MASK_SPU_ENABLE, IVTV_REG_SPU);
- ivtv_msleep_timeout(100, 0);
- if (itv->has_cx23415)
- write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE15, IVTV_REG_VPU);
- else
- write_reg(read_reg(IVTV_REG_VPU) & IVTV_MASK_VPU_ENABLE16, IVTV_REG_VPU);
- ivtv_msleep_timeout(100, 0);
-
- /* find mailboxes and ping firmware */
- itv->enc_mbox.mbox = ivtv_search_mailbox(itv->enc_mem, IVTV_ENCODER_SIZE);
- if (itv->enc_mbox.mbox == NULL)
- IVTV_ERR("Encoder mailbox not found\n");
- else if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0)) {
- IVTV_ERR("Encoder firmware dead!\n");
- itv->enc_mbox.mbox = NULL;
- }
- if (itv->enc_mbox.mbox == NULL)
- return -ENODEV;
-
- if (!itv->has_cx23415)
- return 0;
-
- itv->dec_mbox.mbox = ivtv_search_mailbox(itv->dec_mem, IVTV_DECODER_SIZE);
- if (itv->dec_mbox.mbox == NULL) {
- IVTV_ERR("Decoder mailbox not found\n");
- } else if (itv->has_cx23415 && ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0)) {
- IVTV_ERR("Decoder firmware dead!\n");
- itv->dec_mbox.mbox = NULL;
- } else {
- /* Firmware okay, so check yuv output filter table */
- ivtv_yuv_filter_check(itv);
- }
- return itv->dec_mbox.mbox ? 0 : -ENODEV;
-}
-
-void ivtv_init_mpeg_decoder(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- long readbytes;
- volatile u8 __iomem *mem_offset;
-
- data[0] = 0;
- data[1] = itv->cxhdl.width; /* YUV source width */
- data[2] = itv->cxhdl.height;
- data[3] = itv->cxhdl.audio_properties; /* Audio settings to use,
- bitmap. see docs. */
- if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) {
- IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n");
- return;
- }
-
- if (ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1) != 0) {
- IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
- return;
- }
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
- mem_offset = itv->dec_mem + data[1];
-
- if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
- mem_offset, itv, IVTV_DECODE_INIT_MPEG_SIZE)) <= 0) {
- IVTV_DEBUG_WARN("failed to read mpeg decoder initialisation file %s\n",
- IVTV_DECODE_INIT_MPEG_FILENAME);
- } else {
- ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, readbytes, 0);
- ivtv_msleep_timeout(100, 0);
- }
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
-}
-
-/* Try to restart the card & restore previous settings */
-int ivtv_firmware_restart(struct ivtv *itv)
-{
- int rc = 0;
- v4l2_std_id std;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- /* Display test image during restart */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_TEST_IMAGE,
- itv->card->video_outputs[itv->active_output].video_output,
- 0);
-
- mutex_lock(&itv->udma.lock);
-
- rc = ivtv_firmware_init(itv);
- if (rc) {
- mutex_unlock(&itv->udma.lock);
- return rc;
- }
-
- /* Allow settings to reload */
- ivtv_mailbox_cache_invalidate(itv);
-
- /* Restore encoder video standard */
- std = itv->std;
- itv->std = 0;
- ivtv_s_std_enc(itv, &std);
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- ivtv_init_mpeg_decoder(itv);
-
- /* Restore decoder video standard */
- std = itv->std_out;
- itv->std_out = 0;
- ivtv_s_std_dec(itv, &std);
-
- /* Restore framebuffer if active */
- if (itv->ivtvfb_restore)
- itv->ivtvfb_restore(itv);
-
- /* Restore alpha settings */
- ivtv_set_osd_alpha(itv);
-
- /* Restore normal output */
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_NORMAL,
- itv->card->video_outputs[itv->active_output].video_output,
- 0);
- }
-
- mutex_unlock(&itv->udma.lock);
- return rc;
-}
-
-/* Check firmware running state. The checks fall through
- allowing multiple failures to be logged. */
-int ivtv_firmware_check(struct ivtv *itv, char *where)
-{
- int res = 0;
-
- /* Check encoder is still running */
- if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) {
- IVTV_WARN("Encoder has died : %s\n", where);
- res = -1;
- }
-
- /* Also check audio. Only check if not in use & encoder is okay */
- if (!res && !atomic_read(&itv->capturing) &&
- (!atomic_read(&itv->decoding) ||
- (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV,
- &itv->i_flags)))) {
-
- if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) {
- IVTV_WARN("Audio has died (Encoder OK) : %s\n", where);
- res = -2;
- }
- }
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- /* Second audio check. Skip if audio already failed */
- if (res != -2 && read_dec(0x100) != read_dec(0x104)) {
- /* Wait & try again to be certain. */
- ivtv_msleep_timeout(14, 0);
- if (read_dec(0x100) != read_dec(0x104)) {
- IVTV_WARN("Audio has died (Decoder) : %s\n",
- where);
- res = -1;
- }
- }
-
- /* Check decoder is still running */
- if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) {
- IVTV_WARN("Decoder has died : %s\n", where);
- res = -1;
- }
- }
-
- /* If something failed & currently idle, try to reload */
- if (res && !atomic_read(&itv->capturing) &&
- !atomic_read(&itv->decoding)) {
- IVTV_INFO("Detected in %s that firmware had failed - "
- "Reloading\n", where);
- res = ivtv_firmware_restart(itv);
- /*
- * Even if restarted ok, still signal a problem had occurred.
- * The caller can come through this function again to check
- * if things are really ok after the restart.
- */
- if (!res) {
- IVTV_INFO("Firmware restart okay\n");
- res = -EAGAIN;
- } else {
- IVTV_INFO("Firmware restart failed\n");
- }
- } else if (res) {
- res = -EIO;
- }
-
- return res;
-}
-
-MODULE_FIRMWARE(CX2341X_FIRM_ENC_FILENAME);
-MODULE_FIRMWARE(CX2341X_FIRM_DEC_FILENAME);
-MODULE_FIRMWARE(IVTV_DECODE_INIT_MPEG_FILENAME);
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/video/ivtv/ivtv-firmware.h
deleted file mode 100644
index 52bb4e5598fd..000000000000
--- a/drivers/media/video/ivtv/ivtv-firmware.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- ivtv firmware functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_FIRMWARE_H
-#define IVTV_FIRMWARE_H
-
-int ivtv_firmware_init(struct ivtv *itv);
-void ivtv_firmware_versions(struct ivtv *itv);
-void ivtv_halt_firmware(struct ivtv *itv);
-void ivtv_init_mpeg_decoder(struct ivtv *itv);
-int ivtv_firmware_check(struct ivtv *itv, char *where);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
deleted file mode 100644
index 8f0d07789053..000000000000
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- gpio functions.
- Merging GPIO support into driver:
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "tuner-xc2028.h"
-#include <media/tuner.h>
-#include <media/v4l2-ctrls.h>
-
-/*
- * GPIO assignment of Yuan MPG600/MPG160
- *
- * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
- * OUTPUT IN1 IN0 AM3 AM2 AM1 AM0
- * INPUT DM1 DM0
- *
- * IN* : Input selection
- * IN1 IN0
- * 1 1 N/A
- * 1 0 Line
- * 0 1 N/A
- * 0 0 Tuner
- *
- * AM* : Audio Mode
- * AM3 0: Normal 1: Mixed(Sub+Main channel)
- * AM2 0: Subchannel 1: Main channel
- * AM1 0: Stereo 1: Mono
- * AM0 0: Normal 1: Mute
- *
- * DM* : Detected tuner audio Mode
- * DM1 0: Stereo 1: Mono
- * DM0 0: Multiplex 1: Normal
- *
- * GPIO Initial Settings
- * MPG600 MPG160
- * DIR 0x3080 0x7080
- * OUTPUT 0x000C 0x400C
- *
- * Special thanks to Makoto Iguchi <iguchi@tahoo.org> and Mr. Anonymous
- * for analyzing GPIO of MPG160.
- *
- *****************************************************************************
- *
- * GPIO assignment of Avermedia M179 (per information direct from AVerMedia)
- *
- * bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0
- * OUTPUT IN0 AM0 IN1 AM1 AM2 IN2 BR0 BR1
- * INPUT
- *
- * IN* : Input selection
- * IN0 IN1 IN2
- * * 1 * Mute
- * 0 0 0 Line-In
- * 1 0 0 TV Tuner Audio
- * 0 0 1 FM Audio
- * 1 0 1 Mute
- *
- * AM* : Audio Mode
- * AM0 AM1 AM2
- * 0 0 0 TV Tuner Audio: L_OUT=(L+R)/2, R_OUT=SAP
- * 0 0 1 TV Tuner Audio: L_OUT=R_OUT=SAP (SAP)
- * 0 1 0 TV Tuner Audio: L_OUT=L, R_OUT=R (stereo)
- * 0 1 1 TV Tuner Audio: mute
- * 1 * * TV Tuner Audio: L_OUT=R_OUT=(L+R)/2 (mono)
- *
- * BR* : Audio Sample Rate (BR stands for bitrate for some reason)
- * BR0 BR1
- * 0 0 32 kHz
- * 0 1 44.1 kHz
- * 1 0 48 kHz
- *
- * DM* : Detected tuner audio Mode
- * Unknown currently
- *
- * Special thanks to AVerMedia Technologies, Inc. and Jiun-Kuei Jung at
- * AVerMedia for providing the GPIO information used to add support
- * for the M179 cards.
- */
-
-/********************* GPIO stuffs *********************/
-
-/* GPIO registers */
-#define IVTV_REG_GPIO_IN 0x9008
-#define IVTV_REG_GPIO_OUT 0x900c
-#define IVTV_REG_GPIO_DIR 0x9020
-
-void ivtv_reset_ir_gpio(struct ivtv *itv)
-{
- int curdir, curout;
-
- if (itv->card->type != IVTV_CARD_PVR_150)
- return;
- IVTV_DEBUG_INFO("Resetting PVR150 IR\n");
- curout = read_reg(IVTV_REG_GPIO_OUT);
- curdir = read_reg(IVTV_REG_GPIO_DIR);
- curdir |= 0x80;
- write_reg(curdir, IVTV_REG_GPIO_DIR);
- curout = (curout & ~0xF) | 1;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- /* We could use something else for smaller time */
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- curout |= 2;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- curdir &= ~0x80;
- write_reg(curdir, IVTV_REG_GPIO_DIR);
-}
-
-/* Xceive tuner reset function */
-int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value)
-{
- struct i2c_algo_bit_data *algo = dev;
- struct ivtv *itv = algo->data;
- u32 curout;
-
- if (cmd != XC2028_TUNER_RESET)
- return 0;
- IVTV_DEBUG_INFO("Resetting tuner\n");
- curout = read_reg(IVTV_REG_GPIO_OUT);
- curout &= ~(1 << itv->card->xceive_pin);
- write_reg(curout, IVTV_REG_GPIO_OUT);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
-
- curout |= 1 << itv->card->xceive_pin;
- write_reg(curout, IVTV_REG_GPIO_OUT);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- return 0;
-}
-
-static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct ivtv, sd_gpio);
-}
-
-static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
-{
- return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio;
-}
-
-static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_freq.mask;
- switch (freq) {
- case 32000:
- data = itv->card->gpio_audio_freq.f32000;
- break;
- case 44100:
- data = itv->card->gpio_audio_freq.f44100;
- break;
- case 48000:
- default:
- data = itv->card->gpio_audio_freq.f48000;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask;
-
- mask = itv->card->gpio_audio_detect.mask;
- if (mask == 0 || (read_reg(IVTV_REG_GPIO_IN) & mask))
- vt->rxsubchans = V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- else
- vt->rxsubchans = V4L2_TUNER_SUB_MONO;
- return 0;
-}
-
-static int subdev_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_mode.mask;
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_LANG1:
- data = itv->card->gpio_audio_mode.lang1;
- break;
- case V4L2_TUNER_MODE_LANG2:
- data = itv->card->gpio_audio_mode.lang2;
- break;
- case V4L2_TUNER_MODE_MONO:
- data = itv->card->gpio_audio_mode.mono;
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1_LANG2:
- default:
- data = itv->card->gpio_audio_mode.stereo;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_radio(struct v4l2_subdev *sd)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- mask = itv->card->gpio_audio_input.mask;
- data = itv->card->gpio_audio_input.radio;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_audio_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- if (input > 2)
- return -EINVAL;
- mask = itv->card->gpio_audio_input.mask;
- switch (input) {
- case 0:
- data = itv->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = itv->card->gpio_audio_input.linein;
- break;
- case 2:
- default:
- data = itv->card->gpio_audio_input.radio;
- break;
- }
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static int subdev_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct v4l2_subdev *sd = to_sd(ctrl);
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- mask = itv->card->gpio_audio_mute.mask;
- data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) |
- (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
- }
- return -EINVAL;
-}
-
-
-static int subdev_log_status(struct v4l2_subdev *sd)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
-
- IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
- read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
- read_reg(IVTV_REG_GPIO_IN));
- v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name);
- return 0;
-}
-
-static int subdev_s_video_routing(struct v4l2_subdev *sd,
- u32 input, u32 output, u32 config)
-{
- struct ivtv *itv = sd_to_ivtv(sd);
- u16 mask, data;
-
- if (input > 2) /* 0:Tuner 1:Composite 2:S-Video */
- return -EINVAL;
- mask = itv->card->gpio_video_input.mask;
- if (input == 0)
- data = itv->card->gpio_video_input.tuner;
- else if (input == 1)
- data = itv->card->gpio_video_input.composite;
- else
- data = itv->card->gpio_video_input.svideo;
- if (mask)
- write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops gpio_ctrl_ops = {
- .s_ctrl = subdev_s_ctrl,
-};
-
-static const struct v4l2_subdev_core_ops subdev_core_ops = {
- .log_status = subdev_log_status,
- .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
- .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
- .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
- .g_ctrl = v4l2_subdev_g_ctrl,
- .s_ctrl = v4l2_subdev_s_ctrl,
- .queryctrl = v4l2_subdev_queryctrl,
- .querymenu = v4l2_subdev_querymenu,
-};
-
-static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
- .s_radio = subdev_s_radio,
- .g_tuner = subdev_g_tuner,
- .s_tuner = subdev_s_tuner,
-};
-
-static const struct v4l2_subdev_audio_ops subdev_audio_ops = {
- .s_clock_freq = subdev_s_clock_freq,
- .s_routing = subdev_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops subdev_video_ops = {
- .s_routing = subdev_s_video_routing,
-};
-
-static const struct v4l2_subdev_ops subdev_ops = {
- .core = &subdev_core_ops,
- .tuner = &subdev_tuner_ops,
- .audio = &subdev_audio_ops,
- .video = &subdev_video_ops,
-};
-
-int ivtv_gpio_init(struct ivtv *itv)
-{
- u16 pin = 0;
-
- if (itv->card->xceive_pin)
- pin = 1 << itv->card->xceive_pin;
-
- if ((itv->card->gpio_init.direction | pin) == 0)
- return 0;
-
- IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
- read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT));
-
- /* init output data then direction */
- write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
- write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
- v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
- snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
- itv->sd_gpio.grp_id = IVTV_HW_GPIO;
- v4l2_ctrl_handler_init(&itv->hdl_gpio, 1);
- v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops,
- V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
- if (itv->hdl_gpio.error)
- return itv->hdl_gpio.error;
- itv->sd_gpio.ctrl_handler = &itv->hdl_gpio;
- v4l2_ctrl_handler_setup(&itv->hdl_gpio);
- return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
-}
diff --git a/drivers/media/video/ivtv/ivtv-gpio.h b/drivers/media/video/ivtv/ivtv-gpio.h
deleted file mode 100644
index 0b5d19c8ecb4..000000000000
--- a/drivers/media/video/ivtv/ivtv-gpio.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- gpio functions.
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_GPIO_H
-#define IVTV_GPIO_H
-
-/* GPIO stuff */
-int ivtv_gpio_init(struct ivtv *itv);
-void ivtv_reset_ir_gpio(struct ivtv *itv);
-int ivtv_reset_tuner_gpio(void *dev, int component, int cmd, int value);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
deleted file mode 100644
index d47f41a0ef66..000000000000
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- I2C functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- This file includes an i2c implementation that was reverse engineered
- from the Hauppauge windows driver. Older ivtv versions used i2c-algo-bit,
- which whilst fine under most circumstances, had trouble with the Zilog
- CPU on the PVR-150 which handles IR functions (occasional inability to
- communicate with the chip until it was reset) and also with the i2c
- bus being completely unreachable when multiple PVR cards were present.
-
- The implementation is very similar to i2c-algo-bit, but there are enough
- subtle differences that the two are hard to merge. The general strategy
- employed by i2c-algo-bit is to use udelay() to implement the timing
- when putting out bits on the scl/sda lines. The general strategy taken
- here is to poll the lines for state changes (see ivtv_waitscl and
- ivtv_waitsda). In addition there are small delays at various locations
- which poll the SCL line 5 times (ivtv_scldelay). I would guess that
- since this is memory mapped I/O that the length of those delays is tied
- to the PCI bus clock. There is some extra code to do with recovery
- and retries. Since it is not known what causes the actual i2c problems
- in the first place, the only goal if one was to attempt to use
- i2c-algo-bit would be to try to make it follow the same code path.
- This would be a lot of work, and I'm also not convinced that it would
- provide a generic benefit to i2c-algo-bit. Therefore consider this
- an engineering solution -- not pretty, but it works.
-
- Some more general comments about what we are doing:
-
- The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA)
- lines. To communicate on the bus (as a master, we don't act as a slave),
- we first initiate a start condition (ivtv_start). We then write the
- address of the device that we want to communicate with, along with a flag
- that indicates whether this is a read or a write. The slave then issues
- an ACK signal (ivtv_ack), which tells us that it is ready for reading /
- writing. We then proceed with reading or writing (ivtv_read/ivtv_write),
- and finally issue a stop condition (ivtv_stop) to make the bus available
- to other masters.
-
- There is an additional form of transaction where a write may be
- immediately followed by a read. In this case, there is no intervening
- stop condition. (Only the msp3400 chip uses this method of data transfer).
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "ivtv-i2c.h"
-#include <media/cx25840.h>
-
-/* i2c implementation for cx23415/6 chip, ivtv project.
- * Author: Kevin Thayer (nufan_wfk at yahoo.com)
- */
-/* i2c stuff */
-#define IVTV_REG_I2C_SETSCL_OFFSET 0x7000
-#define IVTV_REG_I2C_SETSDA_OFFSET 0x7004
-#define IVTV_REG_I2C_GETSCL_OFFSET 0x7008
-#define IVTV_REG_I2C_GETSDA_OFFSET 0x700c
-
-#define IVTV_CS53L32A_I2C_ADDR 0x11
-#define IVTV_M52790_I2C_ADDR 0x48
-#define IVTV_CX25840_I2C_ADDR 0x44
-#define IVTV_SAA7115_I2C_ADDR 0x21
-#define IVTV_SAA7127_I2C_ADDR 0x44
-#define IVTV_SAA717x_I2C_ADDR 0x21
-#define IVTV_MSP3400_I2C_ADDR 0x40
-#define IVTV_HAUPPAUGE_I2C_ADDR 0x50
-#define IVTV_WM8739_I2C_ADDR 0x1a
-#define IVTV_WM8775_I2C_ADDR 0x1b
-#define IVTV_TEA5767_I2C_ADDR 0x60
-#define IVTV_UPD64031A_I2C_ADDR 0x12
-#define IVTV_UPD64083_I2C_ADDR 0x5c
-#define IVTV_VP27SMPX_I2C_ADDR 0x5b
-#define IVTV_M52790_I2C_ADDR 0x48
-#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40
-#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
-#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
-#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
-#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
-#define IVTV_ADAPTEC_IR_ADDR 0x6b
-
-/* This array should match the IVTV_HW_ defines */
-static const u8 hw_addrs[] = {
- IVTV_CX25840_I2C_ADDR,
- IVTV_SAA7115_I2C_ADDR,
- IVTV_SAA7127_I2C_ADDR,
- IVTV_MSP3400_I2C_ADDR,
- 0,
- IVTV_WM8775_I2C_ADDR,
- IVTV_CS53L32A_I2C_ADDR,
- 0,
- IVTV_SAA7115_I2C_ADDR,
- IVTV_UPD64031A_I2C_ADDR,
- IVTV_UPD64083_I2C_ADDR,
- IVTV_SAA717x_I2C_ADDR,
- IVTV_WM8739_I2C_ADDR,
- IVTV_VP27SMPX_I2C_ADDR,
- IVTV_M52790_I2C_ADDR,
- 0, /* IVTV_HW_GPIO dummy driver ID */
- IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */
- IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
- IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
- IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */
-};
-
-/* This array should match the IVTV_HW_ defines */
-static const char * const hw_devicenames[] = {
- "cx25840",
- "saa7115",
- "saa7127_auto", /* saa7127 or saa7129 */
- "msp3400",
- "tuner",
- "wm8775",
- "cs53l32a",
- "tveeprom",
- "saa7114",
- "upd64031a",
- "upd64083",
- "saa717x",
- "wm8739",
- "vp27smpx",
- "m52790",
- "gpio",
- "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */
- "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
- "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
- "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */
-};
-
-static int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char keybuf[4];
-
- keybuf[0] = 0x00;
- i2c_master_send(ir->c, keybuf, 1);
- /* poll IR chip */
- if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) {
- return 0;
- }
-
- /* key pressed ? */
- if (keybuf[2] == 0xff)
- return 0;
-
- /* remove repeat bit */
- keybuf[2] &= 0x7f;
- keybuf[3] |= 0x80;
-
- *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
- *ir_raw = *ir_key;
-
- return 1;
-}
-
-static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
-{
- struct i2c_board_info info;
- struct i2c_adapter *adap = &itv->i2c_adap;
- struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
- unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
-
- /* Only allow one IR transmitter to be registered per board */
- if (hw & IVTV_HW_IR_TX_ANY) {
- if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
- return -1;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, type, I2C_NAME_SIZE);
- return i2c_new_probed_device(adap, &info, addr_list, NULL)
- == NULL ? -1 : 0;
- }
-
- /* Only allow one IR receiver to be registered per board */
- if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
- return -1;
-
- /* Our default information for ir-kbd-i2c.c to use */
- switch (hw) {
- case IVTV_HW_I2C_IR_RX_AVER:
- init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
- init_data->internal_get_key_func =
- IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
- init_data->type = RC_TYPE_OTHER;
- init_data->name = "AVerMedia AVerTV card";
- break;
- case IVTV_HW_I2C_IR_RX_HAUP_EXT:
- case IVTV_HW_I2C_IR_RX_HAUP_INT:
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
- break;
- case IVTV_HW_Z8F0811_IR_RX_HAUP:
- /* Default to grey remote */
- init_data->ir_codes = RC_MAP_HAUPPAUGE;
- init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
- init_data->type = RC_TYPE_RC5;
- init_data->name = itv->card_name;
- break;
- case IVTV_HW_I2C_IR_RX_ADAPTEC:
- init_data->get_key = get_key_adaptec;
- init_data->name = itv->card_name;
- /* FIXME: The protocol and RC_MAP needs to be corrected */
- init_data->ir_codes = RC_MAP_EMPTY;
- init_data->type = RC_TYPE_UNKNOWN;
- break;
- }
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.platform_data = init_data;
- strlcpy(info.type, type, I2C_NAME_SIZE);
-
- return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
- -1 : 0;
-}
-
-/* Instantiate the IR receiver device using probing -- undesirable */
-struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
-{
- struct i2c_board_info info;
- /*
- * The external IR receiver is at i2c address 0x34.
- * The internal IR receiver is at i2c address 0x30.
- *
- * In theory, both can be fitted, and Hauppauge suggests an external
- * overrides an internal. That's why we probe 0x1a (~0x34) first. CB
- *
- * Some of these addresses we probe may collide with other i2c address
- * allocations, so this function must be called after all other i2c
- * devices we care about are registered.
- */
- const unsigned short addr_list[] = {
- 0x1a, /* Hauppauge IR external - collides with WM8739 */
- 0x18, /* Hauppauge IR internal */
- I2C_CLIENT_END
- };
-
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
-}
-
-int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
-{
- struct v4l2_subdev *sd;
- struct i2c_adapter *adap = &itv->i2c_adap;
- const char *type = hw_devicenames[idx];
- u32 hw = 1 << idx;
-
- if (idx >= ARRAY_SIZE(hw_addrs))
- return -1;
- if (hw == IVTV_HW_TUNER) {
- /* special tuner handling */
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->radio);
- if (sd)
- sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->demod);
- if (sd)
- sd->grp_id = 1 << idx;
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
- itv->card_i2c->tv);
- if (sd)
- sd->grp_id = 1 << idx;
- return sd ? 0 : -1;
- }
-
- if (hw & IVTV_HW_IR_ANY)
- return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
-
- /* Is it not an I2C device or one we do not wish to register? */
- if (!hw_addrs[idx])
- return -1;
-
- /* It's an I2C device other than an analog tuner or IR chip */
- if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
- } else if (hw == IVTV_HW_CX25840) {
- struct cx25840_platform_data pdata;
- struct i2c_board_info cx25840_info = {
- .type = "cx25840",
- .addr = hw_addrs[idx],
- .platform_data = &pdata,
- };
-
- pdata.pvr150_workaround = itv->pvr150_workaround;
- sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap,
- &cx25840_info, NULL);
- } else {
- sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
- adap, type, hw_addrs[idx], NULL);
- }
- if (sd)
- sd->grp_id = 1 << idx;
- return sd ? 0 : -1;
-}
-
-struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
-{
- struct v4l2_subdev *result = NULL;
- struct v4l2_subdev *sd;
-
- spin_lock(&itv->v4l2_dev.lock);
- v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
- if (sd->grp_id == hw) {
- result = sd;
- break;
- }
- }
- spin_unlock(&itv->v4l2_dev.lock);
- return result;
-}
-
-/* Set the serial clock line to the desired state */
-static void ivtv_setscl(struct ivtv *itv, int state)
-{
- /* write them out */
- /* write bits are inverted */
- write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET);
-}
-
-/* Set the serial data line to the desired state */
-static void ivtv_setsda(struct ivtv *itv, int state)
-{
- /* write them out */
- /* write bits are inverted */
- write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET);
-}
-
-/* Read the serial clock line */
-static int ivtv_getscl(struct ivtv *itv)
-{
- return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
-}
-
-/* Read the serial data line */
-static int ivtv_getsda(struct ivtv *itv)
-{
- return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
-}
-
-/* Implement a short delay by polling the serial clock line */
-static void ivtv_scldelay(struct ivtv *itv)
-{
- int i;
-
- for (i = 0; i < 5; ++i)
- ivtv_getscl(itv);
-}
-
-/* Wait for the serial clock line to become set to a specific value */
-static int ivtv_waitscl(struct ivtv *itv, int val)
-{
- int i;
-
- ivtv_scldelay(itv);
- for (i = 0; i < 1000; ++i) {
- if (ivtv_getscl(itv) == val)
- return 1;
- }
- return 0;
-}
-
-/* Wait for the serial data line to become set to a specific value */
-static int ivtv_waitsda(struct ivtv *itv, int val)
-{
- int i;
-
- ivtv_scldelay(itv);
- for (i = 0; i < 1000; ++i) {
- if (ivtv_getsda(itv) == val)
- return 1;
- }
- return 0;
-}
-
-/* Wait for the slave to issue an ACK */
-static int ivtv_ack(struct ivtv *itv)
-{
- int ret = 0;
-
- if (ivtv_getscl(itv) == 1) {
- IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n");
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setsda(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitsda(itv, 0)) {
- IVTV_DEBUG_I2C("Slave did not ack\n");
- ret = -EREMOTEIO;
- }
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n");
- ret = -EREMOTEIO;
- }
- return ret;
-}
-
-/* Write a single byte to the i2c bus and wait for the slave to ACK */
-static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte)
-{
- int i, bit;
-
- IVTV_DEBUG_HI_I2C("write %x\n",byte);
- for (i = 0; i < 8; ++i, byte<<=1) {
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Error setting SCL low\n");
- return -EREMOTEIO;
- }
- bit = (byte>>7)&1;
- ivtv_setsda(itv, bit);
- if (!ivtv_waitsda(itv, bit)) {
- IVTV_DEBUG_I2C("Error setting SDA\n");
- return -EREMOTEIO;
- }
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("Slave not ready for bit\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("Error setting SCL low\n");
- return -EREMOTEIO;
- }
- return ivtv_ack(itv);
-}
-
-/* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the
- final byte) */
-static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack)
-{
- int i;
-
- *byte = 0;
-
- ivtv_setsda(itv, 1);
- ivtv_scldelay(itv);
- for (i = 0; i < 8; ++i) {
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("Error setting SCL high\n");
- return -EREMOTEIO;
- }
- *byte = ((*byte)<<1)|ivtv_getsda(itv);
- }
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setsda(itv, nack);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- IVTV_DEBUG_HI_I2C("read %x\n",*byte);
- return 0;
-}
-
-/* Issue a start condition on the i2c bus to alert slaves to prepare for
- an address write */
-static int ivtv_start(struct ivtv *itv)
-{
- int sda;
-
- sda = ivtv_getsda(itv);
- if (sda != 1) {
- IVTV_DEBUG_HI_I2C("SDA was low at start\n");
- ivtv_setsda(itv, 1);
- if (!ivtv_waitsda(itv, 1)) {
- IVTV_DEBUG_I2C("SDA stuck low\n");
- return -EREMOTEIO;
- }
- }
- if (ivtv_getscl(itv) != 1) {
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("SCL stuck low at start\n");
- return -EREMOTEIO;
- }
- }
- ivtv_setsda(itv, 0);
- ivtv_scldelay(itv);
- return 0;
-}
-
-/* Issue a stop condition on the i2c bus to release it */
-static int ivtv_stop(struct ivtv *itv)
-{
- int i;
-
- if (ivtv_getscl(itv) != 0) {
- IVTV_DEBUG_HI_I2C("SCL not low when stopping\n");
- ivtv_setscl(itv, 0);
- if (!ivtv_waitscl(itv, 0)) {
- IVTV_DEBUG_I2C("SCL could not be set low\n");
- }
- }
- ivtv_setsda(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- if (!ivtv_waitscl(itv, 1)) {
- IVTV_DEBUG_I2C("SCL could not be set high\n");
- return -EREMOTEIO;
- }
- ivtv_scldelay(itv);
- ivtv_setsda(itv, 1);
- if (!ivtv_waitsda(itv, 1)) {
- IVTV_DEBUG_I2C("resetting I2C\n");
- for (i = 0; i < 16; ++i) {
- ivtv_setscl(itv, 0);
- ivtv_scldelay(itv);
- ivtv_setscl(itv, 1);
- ivtv_scldelay(itv);
- ivtv_setsda(itv, 1);
- }
- ivtv_waitsda(itv, 1);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-/* Write a message to the given i2c slave. do_stop may be 0 to prevent
- issuing the i2c stop condition (when following with a read) */
-static int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop)
-{
- int retry, ret = -EREMOTEIO;
- u32 i;
-
- for (retry = 0; ret != 0 && retry < 8; ++retry) {
- ret = ivtv_start(itv);
-
- if (ret == 0) {
- ret = ivtv_sendbyte(itv, addr<<1);
- for (i = 0; ret == 0 && i < len; ++i)
- ret = ivtv_sendbyte(itv, data[i]);
- }
- if (ret != 0 || do_stop) {
- ivtv_stop(itv);
- }
- }
- if (ret)
- IVTV_DEBUG_I2C("i2c write to %x failed\n", addr);
- return ret;
-}
-
-/* Read data from the given i2c slave. A stop condition is always issued. */
-static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len)
-{
- int retry, ret = -EREMOTEIO;
- u32 i;
-
- for (retry = 0; ret != 0 && retry < 8; ++retry) {
- ret = ivtv_start(itv);
- if (ret == 0)
- ret = ivtv_sendbyte(itv, (addr << 1) | 1);
- for (i = 0; ret == 0 && i < len; ++i) {
- ret = ivtv_readbyte(itv, &data[i], i == len - 1);
- }
- ivtv_stop(itv);
- }
- if (ret)
- IVTV_DEBUG_I2C("i2c read from %x failed\n", addr);
- return ret;
-}
-
-/* Kernel i2c transfer implementation. Takes a number of messages to be read
- or written. If a read follows a write, this will occur without an
- intervening stop condition */
-static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
- struct ivtv *itv = to_ivtv(v4l2_dev);
- int retval;
- int i;
-
- mutex_lock(&itv->i2c_bus_lock);
- for (i = retval = 0; retval == 0 && i < num; i++) {
- if (msgs[i].flags & I2C_M_RD)
- retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len);
- else {
- /* if followed by a read, don't stop */
- int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD);
-
- retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop);
- }
- }
- mutex_unlock(&itv->i2c_bus_lock);
- return retval ? retval : num;
-}
-
-/* Kernel i2c capabilities */
-static u32 ivtv_functionality(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static struct i2c_algorithm ivtv_algo = {
- .master_xfer = ivtv_xfer,
- .functionality = ivtv_functionality,
-};
-
-/* template for our-bit banger */
-static struct i2c_adapter ivtv_i2c_adap_hw_template = {
- .name = "ivtv i2c driver",
- .algo = &ivtv_algo,
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-static void ivtv_setscl_old(void *data, int state)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- if (state)
- itv->i2c_state |= 0x01;
- else
- itv->i2c_state &= ~0x01;
-
- /* write them out */
- /* write bits are inverted */
- write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET);
-}
-
-static void ivtv_setsda_old(void *data, int state)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- if (state)
- itv->i2c_state |= 0x01;
- else
- itv->i2c_state &= ~0x01;
-
- /* write them out */
- /* write bits are inverted */
- write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET);
-}
-
-static int ivtv_getscl_old(void *data)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
-}
-
-static int ivtv_getsda_old(void *data)
-{
- struct ivtv *itv = (struct ivtv *)data;
-
- return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
-}
-
-/* template for i2c-bit-algo */
-static struct i2c_adapter ivtv_i2c_adap_template = {
- .name = "ivtv i2c driver",
- .algo = NULL, /* set by i2c-algo-bit */
- .algo_data = NULL, /* filled from template */
- .owner = THIS_MODULE,
-};
-
-#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */
-
-static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
- .setsda = ivtv_setsda_old,
- .setscl = ivtv_setscl_old,
- .getsda = ivtv_getsda_old,
- .getscl = ivtv_getscl_old,
- .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */
- .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */
-};
-
-static struct i2c_client ivtv_i2c_client_template = {
- .name = "ivtv internal",
-};
-
-/* init + register i2c adapter */
-int init_ivtv_i2c(struct ivtv *itv)
-{
- int retval;
-
- IVTV_DEBUG_I2C("i2c init\n");
-
- /* Sanity checks for the I2C hardware arrays. They must be the
- * same size.
- */
- if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) {
- IVTV_ERR("Mismatched I2C hardware arrays\n");
- return -ENODEV;
- }
- if (itv->options.newi2c > 0) {
- memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template,
- sizeof(struct i2c_adapter));
- } else {
- memcpy(&itv->i2c_adap, &ivtv_i2c_adap_template,
- sizeof(struct i2c_adapter));
- memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
- sizeof(struct i2c_algo_bit_data));
- }
- itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
- itv->i2c_algo.data = itv;
- itv->i2c_adap.algo_data = &itv->i2c_algo;
-
- sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
- itv->instance);
- i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
-
- memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
- sizeof(struct i2c_client));
- itv->i2c_client.adapter = &itv->i2c_adap;
- itv->i2c_adap.dev.parent = &itv->pdev->dev;
-
- IVTV_DEBUG_I2C("setting scl and sda to 1\n");
- ivtv_setscl(itv, 1);
- ivtv_setsda(itv, 1);
-
- if (itv->options.newi2c > 0)
- retval = i2c_add_adapter(&itv->i2c_adap);
- else
- retval = i2c_bit_add_bus(&itv->i2c_adap);
-
- return retval;
-}
-
-void exit_ivtv_i2c(struct ivtv *itv)
-{
- IVTV_DEBUG_I2C("i2c exit\n");
-
- i2c_del_adapter(&itv->i2c_adap);
-}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.h b/drivers/media/video/ivtv/ivtv-i2c.h
deleted file mode 100644
index 7b9ec1cfeb80..000000000000
--- a/drivers/media/video/ivtv/ivtv-i2c.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- I2C functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_I2C_H
-#define IVTV_I2C_H
-
-struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
-int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
-struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);
-
-/* init + register i2c adapter */
-int init_ivtv_i2c(struct ivtv *itv);
-void exit_ivtv_i2c(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
deleted file mode 100644
index 32a591062d0b..000000000000
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ /dev/null
@@ -1,1899 +0,0 @@
-/*
- ioctl system call
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-version.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-i2c.h"
-#include "ivtv-queue.h"
-#include "ivtv-fileops.h"
-#include "ivtv-vbi.h"
-#include "ivtv-routing.h"
-#include "ivtv-streams.h"
-#include "ivtv-yuv.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-gpio.h"
-#include "ivtv-controls.h"
-#include "ivtv-cards.h"
-#include <media/saa7127.h>
-#include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-event.h>
-#include <linux/dvb/audio.h>
-
-u16 ivtv_service2vbi(int type)
-{
- switch (type) {
- case V4L2_SLICED_TELETEXT_B:
- return IVTV_SLICED_TYPE_TELETEXT_B;
- case V4L2_SLICED_CAPTION_525:
- return IVTV_SLICED_TYPE_CAPTION_525;
- case V4L2_SLICED_WSS_625:
- return IVTV_SLICED_TYPE_WSS_625;
- case V4L2_SLICED_VPS:
- return IVTV_SLICED_TYPE_VPS;
- default:
- return 0;
- }
-}
-
-static int valid_service_line(int field, int line, int is_pal)
-{
- return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
- (!is_pal && line >= 10 && line < 22);
-}
-
-static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
-{
- u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
- int i;
-
- set = set & valid_set;
- if (set == 0 || !valid_service_line(field, line, is_pal)) {
- return 0;
- }
- if (!is_pal) {
- if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
- return V4L2_SLICED_CAPTION_525;
- }
- else {
- if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
- return V4L2_SLICED_VPS;
- if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
- return V4L2_SLICED_WSS_625;
- if (line == 23)
- return 0;
- }
- for (i = 0; i < 32; i++) {
- if ((1 << i) & set)
- return 1 << i;
- }
- return 0;
-}
-
-void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- u16 set = fmt->service_set;
- int f, l;
-
- fmt->service_set = 0;
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
- }
- }
-}
-
-static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
-{
- int f, l;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
- }
- }
-}
-
-u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
-{
- int f, l;
- u16 set = 0;
-
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- set |= fmt->service_lines[f][l];
- }
- }
- return set;
-}
-
-void ivtv_set_osd_alpha(struct ivtv *itv)
-{
- ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
- itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
- ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
-}
-
-int ivtv_set_speed(struct ivtv *itv, int speed)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- int single_step = (speed == 1 || speed == -1);
- DEFINE_WAIT(wait);
-
- if (speed == 0) speed = 1000;
-
- /* No change? */
- if (speed == itv->speed && !single_step)
- return 0;
-
- if (single_step && (speed < 0) == (itv->speed < 0)) {
- /* Single step video and no need to change direction */
- ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
- itv->speed = speed;
- return 0;
- }
- if (single_step)
- /* Need to change direction */
- speed = speed < 0 ? -1000 : 1000;
-
- data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
- data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
- data[1] = (speed < 0);
- data[2] = speed < 0 ? 3 : 7;
- data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
- data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
- data[5] = 0;
- data[6] = 0;
-
- if (speed == 1500 || speed == -1500) data[0] |= 1;
- else if (speed == 2000 || speed == -2000) data[0] |= 2;
- else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
- else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
-
- /* If not decoding, just change speed setting */
- if (atomic_read(&itv->decoding) > 0) {
- int got_sig = 0;
-
- /* Stop all DMA and decoding activity */
- ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
-
- /* Wait for any DMA to finish */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- got_sig = signal_pending(current);
- if (got_sig)
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig)
- return -EINTR;
-
- /* Change Speed safely */
- ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
- IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
- }
- if (single_step) {
- speed = (speed < 0) ? -1 : 1;
- ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
- }
- itv->speed = speed;
- return 0;
-}
-
-static int ivtv_validate_speed(int cur_speed, int new_speed)
-{
- int fact = new_speed < 0 ? -1 : 1;
- int s;
-
- if (cur_speed == 0)
- cur_speed = 1000;
- if (new_speed < 0)
- new_speed = -new_speed;
- if (cur_speed < 0)
- cur_speed = -cur_speed;
-
- if (cur_speed <= new_speed) {
- if (new_speed > 1500)
- return fact * 2000;
- if (new_speed > 1000)
- return fact * 1500;
- }
- else {
- if (new_speed >= 2000)
- return fact * 2000;
- if (new_speed >= 1500)
- return fact * 1500;
- if (new_speed >= 1000)
- return fact * 1000;
- }
- if (new_speed == 0)
- return 1000;
- if (new_speed == 1 || new_speed == 1000)
- return fact * new_speed;
-
- s = new_speed;
- new_speed = 1000 / new_speed;
- if (1000 / cur_speed == new_speed)
- new_speed += (cur_speed < s) ? -1 : 1;
- if (new_speed > 60) return 1000 / (fact * 60);
- return 1000 / (fact * new_speed);
-}
-
-static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
- struct v4l2_decoder_cmd *dc, int try)
-{
- struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- switch (dc->cmd) {
- case V4L2_DEC_CMD_START: {
- dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
- dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
- if (dc->start.speed < 0)
- dc->start.format = V4L2_DEC_START_FMT_GOP;
- else
- dc->start.format = V4L2_DEC_START_FMT_NONE;
- if (dc->start.speed != 500 && dc->start.speed != 1500)
- dc->flags = dc->start.speed == 1000 ? 0 :
- V4L2_DEC_CMD_START_MUTE_AUDIO;
- if (try) break;
-
- itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
- if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
- return -EBUSY;
- if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
- /* forces ivtv_set_speed to be called */
- itv->speed = 0;
- }
- return ivtv_start_decoding(id, dc->start.speed);
- }
-
- case V4L2_DEC_CMD_STOP:
- dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
- if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
- dc->stop.pts = 0;
- if (try) break;
- if (atomic_read(&itv->decoding) == 0)
- return 0;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
-
- itv->output_mode = OUT_NONE;
- return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
-
- case V4L2_DEC_CMD_PAUSE:
- dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
- if (try) break;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
- if (atomic_read(&itv->decoding) > 0) {
- ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
- (dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
- set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
- }
- break;
-
- case V4L2_DEC_CMD_RESUME:
- dc->flags = 0;
- if (try) break;
- if (itv->output_mode != OUT_MPG)
- return -EBUSY;
- if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
- int speed = itv->speed;
- itv->speed = 0;
- return ivtv_start_decoding(id, speed);
- }
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- if (itv->is_60hz) {
- vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
- vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- pixfmt->width = itv->cxhdl.width;
- pixfmt->height = itv->cxhdl.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
- pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
- pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
- pixfmt->bytesperline = 720;
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
-
- vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248;
- vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4;
- vbifmt->sample_format = V4L2_PIX_FMT_GREY;
- vbifmt->start[0] = itv->vbi.start[0];
- vbifmt->start[1] = itv->vbi.start[1];
- vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count;
- vbifmt->flags = 0;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- return 0;
-}
-
-static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
-
- if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
- vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
- V4L2_SLICED_VBI_525;
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
- return 0;
- }
-
- v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- pixfmt->width = itv->main_rect.width;
- pixfmt->height = itv->main_rect.height;
- pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
- pixfmt->field = V4L2_FIELD_INTERLACED;
- pixfmt->priv = 0;
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
- switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
- case IVTV_YUV_MODE_INTERLACED:
- pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
- V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
- break;
- case IVTV_YUV_MODE_PROGRESSIVE:
- pixfmt->field = V4L2_FIELD_NONE;
- break;
- default:
- pixfmt->field = V4L2_FIELD_ANY;
- break;
- }
- pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- pixfmt->bytesperline = 720;
- pixfmt->width = itv->yuv_info.v4l2_src_w;
- pixfmt->height = itv->yuv_info.v4l2_src_h;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- 1080 * ((pixfmt->height + 31) & ~31);
- } else {
- pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
- pixfmt->sizeimage = 128 * 1024;
- pixfmt->bytesperline = 0;
- }
- return 0;
-}
-
-static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_window *winfmt = &fmt->fmt.win;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- winfmt->chromakey = itv->osd_chroma_key;
- winfmt->global_alpha = itv->osd_global_alpha;
- winfmt->field = V4L2_FIELD_INTERLACED;
- winfmt->clips = NULL;
- winfmt->clipcount = 0;
- winfmt->bitmap = NULL;
- winfmt->w.top = winfmt->w.left = 0;
- winfmt->w.width = itv->osd_rect.width;
- winfmt->w.height = itv->osd_rect.height;
- return 0;
-}
-
-static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
-}
-
-static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
- int min_h = 2;
-
- w = min(w, 720);
- w = max(w, 2);
- if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
- /* YUV height must be a multiple of 32 */
- h &= ~0x1f;
- min_h = 32;
- }
- h = min(h, itv->is_50hz ? 576 : 480);
- h = max(h, min_h);
- ivtv_g_fmt_vid_cap(file, fh, fmt);
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return 0;
-}
-
-static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
- return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
-
- /* set sliced VBI capture format */
- vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
- vbifmt->reserved[0] = 0;
- vbifmt->reserved[1] = 0;
-
- if (vbifmt->service_set)
- ivtv_expand_service_set(vbifmt, itv->is_50hz);
- check_service_set(vbifmt, itv->is_50hz);
- vbifmt->service_set = ivtv_get_service_set(vbifmt);
- return 0;
-}
-
-static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- s32 w = fmt->fmt.pix.width;
- s32 h = fmt->fmt.pix.height;
- int field = fmt->fmt.pix.field;
- int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
-
- w = min(w, 720);
- w = max(w, 2);
- /* Why can the height be 576 even when the output is NTSC?
-
- Internally the buffers of the PVR350 are always set to 720x576. The
- decoded video frame will always be placed in the top left corner of
- this buffer. For any video which is not 720x576, the buffer will
- then be cropped to remove the unused right and lower areas, with
- the remaining image being scaled by the hardware to fit the display
- area. The video can be scaled both up and down, so a 720x480 video
- can be displayed full-screen on PAL and a 720x576 video can be
- displayed without cropping on NTSC.
-
- Note that the scaling only occurs on the video stream, the osd
- resolution is locked to the broadcast standard and not scaled.
-
- Thanks to Ian Armstrong for this explanation. */
- h = min(h, 576);
- h = max(h, 2);
- if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
- fmt->fmt.pix.field = field;
- fmt->fmt.pix.width = w;
- fmt->fmt.pix.height = h;
- return ret;
-}
-
-static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 chromakey = fmt->fmt.win.chromakey;
- u8 global_alpha = fmt->fmt.win.global_alpha;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- ivtv_g_fmt_vid_out_overlay(file, fh, fmt);
- fmt->fmt.win.chromakey = chromakey;
- fmt->fmt.win.global_alpha = global_alpha;
- return 0;
-}
-
-static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct v4l2_mbus_framefmt mbus_fmt;
- int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
- int w = fmt->fmt.pix.width;
- int h = fmt->fmt.pix.height;
-
- if (ret)
- return ret;
-
- if (itv->cxhdl.width == w && itv->cxhdl.height == h)
- return 0;
-
- if (atomic_read(&itv->capturing) > 0)
- return -EBUSY;
-
- itv->cxhdl.width = w;
- itv->cxhdl.height = h;
- if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
- fmt->fmt.pix.width /= 2;
- mbus_fmt.width = fmt->fmt.pix.width;
- mbus_fmt.height = h;
- mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
- v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &mbus_fmt);
- return ivtv_g_fmt_vid_cap(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
- return -EBUSY;
- itv->vbi.sliced_in->service_set = 0;
- itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi);
- return ivtv_g_fmt_vbi_cap(file, fh, fmt);
-}
-
-static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
-
- if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
- return ret;
-
- check_service_set(vbifmt, itv->is_50hz);
- if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
- return -EBUSY;
- itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt);
- memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
- return 0;
-}
-
-static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
-
- if (ret)
- return ret;
-
- if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
- return 0;
-
- /* Return now if we already have some frame data */
- if (yi->stream_size)
- return -EBUSY;
-
- yi->v4l2_src_w = fmt->fmt.pix.width;
- yi->v4l2_src_h = fmt->fmt.pix.height;
-
- switch (fmt->fmt.pix.field) {
- case V4L2_FIELD_NONE:
- yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
- break;
- case V4L2_FIELD_ANY:
- yi->lace_mode = IVTV_YUV_MODE_AUTO;
- break;
- case V4L2_FIELD_INTERLACED_BT:
- yi->lace_mode =
- IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
- break;
- case V4L2_FIELD_INTERLACED_TB:
- default:
- yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
- break;
- }
- yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- itv->dma_data_req_size =
- 1080 * ((yi->v4l2_src_h + 31) & ~31);
-
- return 0;
-}
-
-static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
-
- if (ret == 0) {
- itv->osd_chroma_key = fmt->fmt.win.chromakey;
- itv->osd_global_alpha = fmt->fmt.win.global_alpha;
- ivtv_set_osd_alpha(itv);
- }
- return ret;
-}
-
-static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- /* TODO: is this correct? */
- return ivtv_call_all_err(itv, core, g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
-{
- struct v4l2_dbg_register *regs = arg;
- volatile u8 __iomem *reg_start;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
- reg_start = itv->reg_mem - IVTV_REG_OFFSET;
- else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
- regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
- reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
- else if (regs->reg < IVTV_ENCODER_SIZE)
- reg_start = itv->enc_mem;
- else
- return -EINVAL;
-
- regs->size = 4;
- if (cmd == VIDIOC_DBG_G_REGISTER)
- regs->val = readl(regs->reg + reg_start);
- else
- writel(regs->val, regs->reg + reg_start);
- return 0;
-}
-
-static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (v4l2_chip_match_host(&reg->match))
- return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, g_register, reg);
- return 0;
-}
-
-static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (v4l2_chip_match_host(&reg->match))
- return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
- /* TODO: subdev errors should not be ignored, this should become a
- subdev helper function. */
- ivtv_call_all(itv, core, s_register, reg);
- return 0;
-}
-#endif
-
-static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
- struct ivtv_stream *s = &itv->streams[id->type];
-
- strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
- strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
- vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
- vcap->device_caps = s->caps;
- return 0;
-}
-
-static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_audio_input(itv, vin->index, vin);
-}
-
-static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- vin->index = itv->audio_input;
- return ivtv_get_audio_input(itv, vin->index, vin);
-}
-
-static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vout->index >= itv->nof_audio_inputs)
- return -EINVAL;
-
- itv->audio_input = vout->index;
- ivtv_audio_set_io(itv);
-
- return 0;
-}
-
-static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- /* set it to defaults from our table */
- return ivtv_get_audio_output(itv, vin->index, vin);
-}
-
-static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- vin->index = 0;
- return ivtv_get_audio_output(itv, vin->index, vin);
-}
-
-static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_audio_output(itv, vout->index, vout);
-}
-
-static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- /* set it to defaults from our table */
- return ivtv_get_input(itv, vin->index, vin);
-}
-
-static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- return ivtv_get_output(itv, vout->index, vout);
-}
-
-static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = 720;
- if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- cropcap->bounds.height = itv->is_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
- } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- if (yi->track_osd) {
- cropcap->bounds.width = yi->osd_full_w;
- cropcap->bounds.height = yi->osd_full_h;
- } else {
- cropcap->bounds.width = 720;
- cropcap->bounds.height =
- itv->is_out_50hz ? 576 : 480;
- }
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
- } else {
- cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
- cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
- cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
- }
- cropcap->defrect = cropcap->bounds;
- return 0;
-}
-
-static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
- yi->main_rect = crop->c;
- return 0;
- } else {
- if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
- itv->main_rect = crop->c;
- return 0;
- }
- }
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int streamtype;
-
- streamtype = id->type;
-
- if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
- if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
- crop->c = yi->main_rect;
- else
- crop->c = itv->main_rect;
- return 0;
- }
- return -EINVAL;
-}
-
-static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
- return 0;
-}
-
-static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- static struct v4l2_fmtdesc formats[] = {
- { 0, 0, 0,
- "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
- { 0, 0, 0, 0 }
- },
- { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
- "MPEG", V4L2_PIX_FMT_MPEG,
- { 0, 0, 0, 0 }
- }
- };
- enum v4l2_buf_type type = fmt->type;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- if (fmt->index > 1)
- return -EINVAL;
-
- *fmt = formats[fmt->index];
- fmt->type = type;
-
- return 0;
-}
-
-static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- *i = itv->active_input;
-
- return 0;
-}
-
-int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (inp < 0 || inp >= itv->nof_inputs)
- return -EINVAL;
-
- if (inp == itv->active_input) {
- IVTV_DEBUG_INFO("Input unchanged\n");
- return 0;
- }
-
- if (atomic_read(&itv->capturing) > 0) {
- return -EBUSY;
- }
-
- IVTV_DEBUG_INFO("Changing input from %d to %d\n",
- itv->active_input, inp);
-
- itv->active_input = inp;
- /* Set the audio input to whatever is appropriate for the
- input type. */
- itv->audio_input = itv->card->video_inputs[inp].audio_index;
-
- /* prevent others from messing with the streams until
- we're finished changing inputs. */
- ivtv_mute(itv);
- ivtv_video_set_io(itv);
- ivtv_audio_set_io(itv);
- ivtv_unmute(itv);
-
- return 0;
-}
-
-static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
-
- *i = itv->active_output;
-
- return 0;
-}
-
-static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (outp >= itv->card->nof_outputs)
- return -EINVAL;
-
- if (outp == itv->active_output) {
- IVTV_DEBUG_INFO("Output unchanged\n");
- return 0;
- }
- IVTV_DEBUG_INFO("Changing output from %d to %d\n",
- itv->active_output, outp);
-
- itv->active_output = outp;
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
- SAA7127_INPUT_TYPE_NORMAL,
- itv->card->video_outputs[outp].video_output, 0);
-
- return 0;
-}
-
-static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, g_frequency, vf);
- return 0;
-}
-
-int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vf->tuner != 0)
- return -EINVAL;
-
- ivtv_mute(itv);
- IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- ivtv_call_all(itv, tuner, s_frequency, vf);
- ivtv_unmute(itv);
- return 0;
-}
-
-static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- *std = itv->std;
- return 0;
-}
-
-void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
-{
- itv->std = *std;
- itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- itv->is_50hz = !itv->is_60hz;
- cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
- itv->cxhdl.width = 720;
- itv->cxhdl.height = itv->is_50hz ? 576 : 480;
- itv->vbi.count = itv->is_50hz ? 18 : 12;
- itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
- itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
-
- if (itv->hw_flags & IVTV_HW_CX25840)
- itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
-
- /* Tuner */
- ivtv_call_all(itv, core, s_std, itv->std);
-}
-
-void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- DEFINE_WAIT(wait);
- int f;
-
- /* set display standard */
- itv->std_out = *std;
- itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
- itv->is_out_50hz = !itv->is_out_60hz;
- ivtv_call_all(itv, video, s_std_output, itv->std_out);
-
- /*
- * The next firmware call is time sensitive. Time it to
- * avoid risk of a hard lock, by trying to ensure the call
- * happens within the first 100 lines of the top field.
- * Make 4 attempts to sync to the decoder before giving up.
- */
- mutex_unlock(&itv->serialize_lock);
- for (f = 0; f < 4; f++) {
- prepare_to_wait(&itv->vsync_waitq, &wait,
- TASK_UNINTERRUPTIBLE);
- if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
- break;
- schedule_timeout(msecs_to_jiffies(25));
- }
- finish_wait(&itv->vsync_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
-
- if (f == 4)
- IVTV_WARN("Mode change failed to sync to decoder\n");
-
- ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
- itv->main_rect.left = 0;
- itv->main_rect.top = 0;
- itv->main_rect.width = 720;
- itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
- ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
- 720, itv->main_rect.height, 0, 0);
- yi->main_rect = itv->main_rect;
- if (!itv->osd_info) {
- yi->osd_full_w = 720;
- yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
- }
-}
-
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if ((*std & V4L2_STD_ALL) == 0)
- return -EINVAL;
-
- if (*std == itv->std)
- return 0;
-
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
- atomic_read(&itv->capturing) > 0 ||
- atomic_read(&itv->decoding) > 0) {
- /* Switching standard would mess with already running
- streams, prevent that by returning EBUSY. */
- return -EBUSY;
- }
-
- IVTV_DEBUG_INFO("Switching standard to %llx.\n",
- (unsigned long long)itv->std);
-
- ivtv_s_std_enc(itv, std);
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
- ivtv_s_std_dec(itv, std);
-
- return 0;
-}
-
-static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (vt->index != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, s_tuner, vt);
-
- return 0;
-}
-
-static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (vt->index != 0)
- return -EINVAL;
-
- ivtv_call_all(itv, tuner, g_tuner, vt);
-
- if (vt->type == V4L2_TUNER_RADIO)
- strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
- else
- strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
- return 0;
-}
-
-static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
- int f, l;
-
- if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- for (f = 0; f < 2; f++) {
- for (l = 0; l < 24; l++) {
- if (valid_service_line(f, l, itv->is_50hz))
- cap->service_lines[f][l] = set;
- }
- }
- } else if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
- if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
- return -EINVAL;
- if (itv->is_60hz) {
- cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- } else {
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- cap->service_lines[0][16] = V4L2_SLICED_VPS;
- }
- } else {
- return -EINVAL;
- }
-
- set = 0;
- for (f = 0; f < 2; f++)
- for (l = 0; l < 24; l++)
- set |= cap->service_lines[f][l];
- cap->service_set = set;
- return 0;
-}
-
-static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- struct v4l2_enc_idx_entry *e = idx->entry;
- int entries;
- int i;
-
- entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
- IVTV_MAX_PGM_INDEX;
- if (entries > V4L2_ENC_IDX_ENTRIES)
- entries = V4L2_ENC_IDX_ENTRIES;
- idx->entries = 0;
- for (i = 0; i < entries; i++) {
- *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
- if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
- idx->entries++;
- e++;
- }
- }
- itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
- return 0;
-}
-
-static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return ivtv_start_capture(id);
-
- case V4L2_ENC_CMD_STOP:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
- return 0;
-
- case V4L2_ENC_CMD_PAUSE:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
-
- if (!atomic_read(&itv->capturing))
- return -EPERM;
- if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
-
- ivtv_mute(itv);
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
- break;
-
- case V4L2_ENC_CMD_RESUME:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
-
- if (!atomic_read(&itv->capturing))
- return -EPERM;
-
- if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
- return 0;
-
- ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
- ivtv_unmute(itv);
- break;
- default:
- IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- switch (enc->cmd) {
- case V4L2_ENC_CMD_START:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
- enc->flags = 0;
- return 0;
-
- case V4L2_ENC_CMD_STOP:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
- enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
- return 0;
-
- case V4L2_ENC_CMD_PAUSE:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
- enc->flags = 0;
- return 0;
-
- case V4L2_ENC_CMD_RESUME:
- IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
- enc->flags = 0;
- return 0;
- default:
- IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
- return -EINVAL;
- }
-}
-
-static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- int pixfmt;
- static u32 pixel_format[16] = {
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
- V4L2_PIX_FMT_RGB565,
- V4L2_PIX_FMT_RGB555,
- V4L2_PIX_FMT_RGB444,
- V4L2_PIX_FMT_RGB32,
- 0,
- 0,
- 0,
- V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
- V4L2_PIX_FMT_YUV565,
- V4L2_PIX_FMT_YUV555,
- V4L2_PIX_FMT_YUV444,
- V4L2_PIX_FMT_YUV32,
- 0,
- 0,
- 0,
- };
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- if (!itv->osd_video_pbase)
- return -EINVAL;
-
- fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
- V4L2_FBUF_CAP_GLOBAL_ALPHA;
-
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- pixfmt = (data[0] >> 3) & 0xf;
-
- fb->fmt.pixelformat = pixel_format[pixfmt];
- fb->fmt.width = itv->osd_rect.width;
- fb->fmt.height = itv->osd_rect.height;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->fmt.bytesperline = fb->fmt.width;
- fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->fmt.priv = 0;
- if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
- fb->fmt.bytesperline *= 2;
- if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
- fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
- fb->fmt.bytesperline *= 2;
- fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
- fb->base = (void *)itv->osd_video_pbase;
- fb->flags = 0;
-
- if (itv->osd_chroma_key_state)
- fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
-
- if (itv->osd_global_alpha_state)
- fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
-
- if (yi->track_osd)
- fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
-
- pixfmt &= 7;
-
- /* no local alpha for RGB565 or unknown formats */
- if (pixfmt == 1 || pixfmt > 4)
- return 0;
-
- /* 16-bit formats have inverted local alpha */
- if (pixfmt == 2 || pixfmt == 3)
- fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
- else
- fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
-
- if (itv->osd_local_alpha_state) {
- /* 16-bit formats have inverted local alpha */
- if (pixfmt == 2 || pixfmt == 3)
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
- else
- fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
- }
-
- return 0;
-}
-
-static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
- if (!itv->osd_video_pbase)
- return -EINVAL;
-
- itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
- itv->osd_local_alpha_state =
- (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
- itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
- ivtv_set_osd_alpha(itv);
- yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
- return ivtv_g_fbuf(file, fh, fb);
-}
-
-static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
-{
- struct ivtv_open_id *id = fh2id(fh);
- struct ivtv *itv = id->itv;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
- return -EINVAL;
-
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
-
- return 0;
-}
-
-static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub)
-{
- switch (sub->type) {
- case V4L2_EVENT_VSYNC:
- case V4L2_EVENT_EOS:
- return v4l2_event_subscribe(fh, sub, 0, NULL);
- case V4L2_EVENT_CTRL:
- return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);
- default:
- return -EINVAL;
- }
-}
-
-static int ivtv_log_status(struct file *file, void *fh)
-{
- struct ivtv *itv = fh2id(fh)->itv;
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
- struct v4l2_input vidin;
- struct v4l2_audio audin;
- int i;
-
- IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
- if (itv->hw_flags & IVTV_HW_TVEEPROM) {
- struct tveeprom tv;
-
- ivtv_read_eeprom(itv, &tv);
- }
- ivtv_call_all(itv, core, log_status);
- ivtv_get_input(itv, itv->active_input, &vidin);
- ivtv_get_audio_input(itv, itv->audio_input, &audin);
- IVTV_INFO("Video Input: %s\n", vidin.name);
- IVTV_INFO("Audio Input: %s%s\n", audin.name,
- (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
- if (has_output) {
- struct v4l2_output vidout;
- struct v4l2_audioout audout;
- int mode = itv->output_mode;
- static const char * const output_modes[5] = {
- "None",
- "MPEG Streaming",
- "YUV Streaming",
- "YUV Frames",
- "Passthrough",
- };
- static const char * const alpha_mode[4] = {
- "None",
- "Global",
- "Local",
- "Global and Local"
- };
- static const char * const pixel_format[16] = {
- "ARGB Indexed",
- "RGB 5:6:5",
- "ARGB 1:5:5:5",
- "ARGB 1:4:4:4",
- "ARGB 8:8:8:8",
- "5",
- "6",
- "7",
- "AYUV Indexed",
- "YUV 5:6:5",
- "AYUV 1:5:5:5",
- "AYUV 1:4:4:4",
- "AYUV 8:8:8:8",
- "13",
- "14",
- "15",
- };
-
- ivtv_get_output(itv, itv->active_output, &vidout);
- ivtv_get_audio_output(itv, 0, &audout);
- IVTV_INFO("Video Output: %s\n", vidout.name);
- if (mode < 0 || mode > OUT_PASSTHROUGH)
- mode = OUT_NONE;
- IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
- data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
- IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
- data[0] & 1 ? "On" : "Off",
- alpha_mode[(data[0] >> 1) & 0x3],
- pixel_format[(data[0] >> 3) & 0xf]);
- }
- IVTV_INFO("Tuner: %s\n",
- test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- struct ivtv_stream *s = &itv->streams[i];
-
- if (s->vdev == NULL || s->buffers == 0)
- continue;
- IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
- (s->buffers - s->q_free.buffers) * 100 / s->buffers,
- (s->buffers * s->buf_size) / 1024, s->buffers);
- }
-
- IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
- (long long)itv->mpg_data_received,
- (long long)itv->vbi_data_inserted);
- return 0;
-}
-
-static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
-
- IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
- return ivtv_video_command(itv, id, dec, false);
-}
-
-static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
-{
- struct ivtv_open_id *id = fh2id(file->private_data);
- struct ivtv *itv = id->itv;
-
- IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
- return ivtv_video_command(itv, id, dec, true);
-}
-
-static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
-{
- struct ivtv_open_id *id = fh2id(filp->private_data);
- struct ivtv *itv = id->itv;
- int nonblocking = filp->f_flags & O_NONBLOCK;
- struct ivtv_stream *s = &itv->streams[id->type];
- unsigned long iarg = (unsigned long)arg;
-
- switch (cmd) {
- case IVTV_IOC_DMA_FRAME: {
- struct ivtv_dma_frame *args = arg;
-
- IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
- return 0;
- if (ivtv_start_decoding(id, id->type)) {
- return -EBUSY;
- }
- if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
- ivtv_release_stream(s);
- return -EBUSY;
- }
- /* Mark that this file handle started the UDMA_YUV mode */
- id->yuv_frames = 1;
- if (args->y_source == NULL)
- return 0;
- return ivtv_yuv_prep_frame(itv, args);
- }
-
- case IVTV_IOC_PASSTHROUGH_MODE:
- IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_passthrough_mode(itv, *(int *)arg != 0);
-
- case VIDEO_GET_PTS: {
- s64 *pts = arg;
- s64 frame;
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
- if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
- *pts = s->dma_pts;
- break;
- }
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_g_pts_frame(itv, pts, &frame);
- }
-
- case VIDEO_GET_FRAME_COUNT: {
- s64 *frame = arg;
- s64 pts;
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
- if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
- *frame = 0;
- break;
- }
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_g_pts_frame(itv, &pts, frame);
- }
-
- case VIDEO_PLAY: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_START;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_STOP: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_STOP;
- dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_FREEZE: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_PAUSE;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_CONTINUE: {
- struct v4l2_decoder_cmd dc;
-
- IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
- memset(&dc, 0, sizeof(dc));
- dc.cmd = V4L2_DEC_CMD_RESUME;
- return ivtv_video_command(itv, id, &dc, 0);
- }
-
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND: {
- /* Note: struct v4l2_decoder_cmd has the same layout as
- struct video_command */
- struct v4l2_decoder_cmd *dc = arg;
- int try = (cmd == VIDEO_TRY_COMMAND);
-
- if (try)
- IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
- else
- IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
- return ivtv_video_command(itv, id, dc, try);
- }
-
- case VIDEO_GET_EVENT: {
- struct video_event *ev = arg;
- DEFINE_WAIT(wait);
-
- IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- memset(ev, 0, sizeof(*ev));
- set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
-
- while (1) {
- if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
- ev->type = VIDEO_EVENT_DECODER_STOPPED;
- else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
- ev->type = VIDEO_EVENT_VSYNC;
- ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
- VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
- if (itv->output_mode == OUT_UDMA_YUV &&
- (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
- IVTV_YUV_MODE_PROGRESSIVE) {
- ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
- }
- }
- if (ev->type)
- return 0;
- if (nonblocking)
- return -EAGAIN;
- /* Wait for event. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
- if (!test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags) &&
- !test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags))
- schedule();
- finish_wait(&itv->event_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (signal_pending(current)) {
- /* return if a signal was received */
- IVTV_DEBUG_INFO("User stopped wait for event\n");
- return -EINTR;
- }
- }
- break;
- }
-
- case VIDEO_SELECT_SOURCE:
- IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return -EINVAL;
- return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX);
-
- case AUDIO_SET_MUTE:
- IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
- itv->speed_mute_audio = iarg;
- return 0;
-
- case AUDIO_CHANNEL_SELECT:
- IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
- if (iarg > AUDIO_STEREO_SWAPPED)
- return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1);
-
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
- if (iarg > AUDIO_STEREO_SWAPPED)
- return -EINVAL;
- return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1);
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static long ivtv_default(struct file *file, void *fh, bool valid_prio,
- int cmd, void *arg)
-{
- struct ivtv *itv = fh2id(fh)->itv;
-
- if (!valid_prio) {
- switch (cmd) {
- case IVTV_IOC_PASSTHROUGH_MODE:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_SELECT_SOURCE:
- case AUDIO_SET_MUTE:
- case AUDIO_CHANNEL_SELECT:
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- return -EBUSY;
- }
- }
-
- switch (cmd) {
- case VIDIOC_INT_RESET: {
- u32 val = *(u32 *)arg;
-
- if ((val == 0 && itv->options.newi2c) || (val & 0x01))
- ivtv_reset_ir_gpio(itv);
- if (val & 0x02)
- v4l2_subdev_call(itv->sd_video, core, reset, 0);
- break;
- }
-
- case IVTV_IOC_DMA_FRAME:
- case IVTV_IOC_PASSTHROUGH_MODE:
- case VIDEO_GET_PTS:
- case VIDEO_GET_FRAME_COUNT:
- case VIDEO_GET_EVENT:
- case VIDEO_PLAY:
- case VIDEO_STOP:
- case VIDEO_FREEZE:
- case VIDEO_CONTINUE:
- case VIDEO_COMMAND:
- case VIDEO_TRY_COMMAND:
- case VIDEO_SELECT_SOURCE:
- case AUDIO_SET_MUTE:
- case AUDIO_CHANNEL_SELECT:
- case AUDIO_BILINGUAL_CHANNEL_SELECT:
- return ivtv_decoder_ioctls(file, cmd, (void *)arg);
-
- default:
- return -ENOTTY;
- }
- return 0;
-}
-
-static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
- .vidioc_querycap = ivtv_querycap,
- .vidioc_s_audio = ivtv_s_audio,
- .vidioc_g_audio = ivtv_g_audio,
- .vidioc_enumaudio = ivtv_enumaudio,
- .vidioc_s_audout = ivtv_s_audout,
- .vidioc_g_audout = ivtv_g_audout,
- .vidioc_enum_input = ivtv_enum_input,
- .vidioc_enum_output = ivtv_enum_output,
- .vidioc_enumaudout = ivtv_enumaudout,
- .vidioc_cropcap = ivtv_cropcap,
- .vidioc_s_crop = ivtv_s_crop,
- .vidioc_g_crop = ivtv_g_crop,
- .vidioc_g_input = ivtv_g_input,
- .vidioc_s_input = ivtv_s_input,
- .vidioc_g_output = ivtv_g_output,
- .vidioc_s_output = ivtv_s_output,
- .vidioc_g_frequency = ivtv_g_frequency,
- .vidioc_s_frequency = ivtv_s_frequency,
- .vidioc_s_tuner = ivtv_s_tuner,
- .vidioc_g_tuner = ivtv_g_tuner,
- .vidioc_g_enc_index = ivtv_g_enc_index,
- .vidioc_g_fbuf = ivtv_g_fbuf,
- .vidioc_s_fbuf = ivtv_s_fbuf,
- .vidioc_g_std = ivtv_g_std,
- .vidioc_s_std = ivtv_s_std,
- .vidioc_overlay = ivtv_overlay,
- .vidioc_log_status = ivtv_log_status,
- .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
- .vidioc_encoder_cmd = ivtv_encoder_cmd,
- .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
- .vidioc_decoder_cmd = ivtv_decoder_cmd,
- .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
- .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
- .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
- .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
- .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
- .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
- .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
- .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
- .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
- .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
- .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
- .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
- .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
- .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
- .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
- .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
- .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
- .vidioc_g_chip_ident = ivtv_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = ivtv_g_register,
- .vidioc_s_register = ivtv_s_register,
-#endif
- .vidioc_default = ivtv_default,
- .vidioc_subscribe_event = ivtv_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-void ivtv_set_funcs(struct video_device *vdev)
-{
- vdev->ioctl_ops = &ivtv_ioctl_ops;
-}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
deleted file mode 100644
index 7c553d16579b..000000000000
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- ioctl system call
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_IOCTL_H
-#define IVTV_IOCTL_H
-
-u16 ivtv_service2vbi(int type);
-void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
-u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-void ivtv_set_osd_alpha(struct ivtv *itv);
-int ivtv_set_speed(struct ivtv *itv, int speed);
-void ivtv_set_funcs(struct video_device *vdev);
-void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
-void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
-int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
-int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
deleted file mode 100644
index 1b3b9578bf47..000000000000
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* interrupt handling
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-queue.h"
-#include "ivtv-udma.h"
-#include "ivtv-irq.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-vbi.h"
-#include "ivtv-yuv.h"
-#include <media/v4l2-event.h>
-
-#define DMA_MAGIC_COOKIE 0x000001fe
-
-static void ivtv_dma_dec_start(struct ivtv_stream *s);
-
-static const int ivtv_stream_map[] = {
- IVTV_ENC_STREAM_TYPE_MPG,
- IVTV_ENC_STREAM_TYPE_YUV,
- IVTV_ENC_STREAM_TYPE_PCM,
- IVTV_ENC_STREAM_TYPE_VBI,
-};
-
-
-static void ivtv_pio_work_handler(struct ivtv *itv)
-{
- struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
- struct ivtv_buffer *buf;
- int i = 0;
-
- IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
- if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
- s->vdev == NULL || !ivtv_use_pio(s)) {
- itv->cur_pio_stream = -1;
- /* trigger PIO complete user interrupt */
- write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
- return;
- }
- IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name);
- list_for_each_entry(buf, &s->q_dma.list, list) {
- u32 size = s->sg_processing[i].size & 0x3ffff;
-
- /* Copy the data from the card to the buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
- }
- else {
- memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
- }
- i++;
- if (i == s->sg_processing_size)
- break;
- }
- write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
-}
-
-void ivtv_irq_work_handler(struct kthread_work *work)
-{
- struct ivtv *itv = container_of(work, struct ivtv, irq_work);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
- ivtv_pio_work_handler(itv);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
- ivtv_vbi_work_handler(itv);
-
- if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
- ivtv_yuv_work_handler(itv);
-}
-
-/* Determine the required DMA size, setup enough buffers in the predma queue and
- actually copy the data from the card to the buffers in case a PIO transfer is
- required for this stream.
- */
-static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
-{
- struct ivtv *itv = s->itv;
- struct ivtv_buffer *buf;
- u32 bytes_needed = 0;
- u32 offset, size;
- u32 UVoffset = 0, UVsize = 0;
- int skip_bufs = s->q_predma.buffers;
- int idx = s->sg_pending_size;
- int rc;
-
- /* sanity checks */
- if (s->vdev == NULL) {
- IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
- return -1;
- }
- if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
- IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
- return -1;
- }
-
- /* determine offset, size and PTS for the various streams */
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_MPG:
- offset = data[1];
- size = data[2];
- s->pending_pts = 0;
- break;
-
- case IVTV_ENC_STREAM_TYPE_YUV:
- offset = data[1];
- size = data[2];
- UVoffset = data[3];
- UVsize = data[4];
- s->pending_pts = ((u64) data[5] << 32) | data[6];
- break;
-
- case IVTV_ENC_STREAM_TYPE_PCM:
- offset = data[1] + 12;
- size = data[2] - 12;
- s->pending_pts = read_dec(offset - 8) |
- ((u64)(read_dec(offset - 12)) << 32);
- if (itv->has_cx23415)
- offset += IVTV_DECODER_OFFSET;
- break;
-
- case IVTV_ENC_STREAM_TYPE_VBI:
- size = itv->vbi.enc_size * itv->vbi.fpi;
- offset = read_enc(itv->vbi.enc_start - 4) + 12;
- if (offset == 12) {
- IVTV_DEBUG_INFO("VBI offset == 0\n");
- return -1;
- }
- s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
- break;
-
- case IVTV_DEC_STREAM_TYPE_VBI:
- size = read_dec(itv->vbi.dec_start + 4) + 8;
- offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
- s->pending_pts = 0;
- offset += IVTV_DECODER_OFFSET;
- break;
- default:
- /* shouldn't happen */
- return -1;
- }
-
- /* if this is the start of the DMA then fill in the magic cookie */
- if (s->sg_pending_size == 0 && ivtv_use_dma(s)) {
- if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
- s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
- s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET);
- write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
- }
- else {
- s->pending_backup = read_enc(offset);
- write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
- }
- s->pending_offset = offset;
- }
-
- bytes_needed = size;
- if (s->type == IVTV_ENC_STREAM_TYPE_YUV) {
- /* The size for the Y samples needs to be rounded upwards to a
- multiple of the buf_size. The UV samples then start in the
- next buffer. */
- bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size);
- bytes_needed += UVsize;
- }
-
- IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n",
- ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset);
-
- rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed);
- if (rc < 0) { /* Insufficient buffers */
- IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n",
- bytes_needed, s->name);
- return -1;
- }
- if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) {
- IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
- IVTV_WARN("Cause: the application is not reading fast enough.\n");
- }
- s->buffers_stolen = rc;
-
- /* got the buffers, now fill in sg_pending */
- buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
- memset(buf->buf, 0, 128);
- list_for_each_entry(buf, &s->q_predma.list, list) {
- if (skip_bufs-- > 0)
- continue;
- s->sg_pending[idx].dst = buf->dma_handle;
- s->sg_pending[idx].src = offset;
- s->sg_pending[idx].size = s->buf_size;
- buf->bytesused = min(size, s->buf_size);
- buf->dma_xfer_cnt = s->dma_xfer_cnt;
-
- s->q_predma.bytesused += buf->bytesused;
- size -= buf->bytesused;
- offset += s->buf_size;
-
- /* Sync SG buffers */
- ivtv_buf_sync_for_device(s, buf);
-
- if (size == 0) { /* YUV */
- /* process the UV section */
- offset = UVoffset;
- size = UVsize;
- }
- idx++;
- }
- s->sg_pending_size = idx;
- return 0;
-}
-
-static void dma_post(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_buffer *buf = NULL;
- struct list_head *p;
- u32 offset;
- __le32 *u32buf;
- int x = 0;
-
- IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
- s->name, s->dma_offset);
- list_for_each(p, &s->q_dma.list) {
- buf = list_entry(p, struct ivtv_buffer, list);
- u32buf = (__le32 *)buf->buf;
-
- /* Sync Buffer */
- ivtv_buf_sync_for_cpu(s, buf);
-
- if (x == 0 && ivtv_use_dma(s)) {
- offset = s->dma_last_offset;
- if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
- {
- for (offset = 0; offset < 64; offset++) {
- if (u32buf[offset] == DMA_MAGIC_COOKIE) {
- break;
- }
- }
- offset *= 4;
- if (offset == 256) {
- IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name);
- offset = s->dma_last_offset;
- }
- if (s->dma_last_offset != offset)
- IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset);
- s->dma_last_offset = offset;
- }
- if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
- s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
- write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET);
- }
- else {
- write_enc_sync(0, s->dma_offset);
- }
- if (offset) {
- buf->bytesused -= offset;
- memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset);
- }
- *u32buf = cpu_to_le32(s->dma_backup);
- }
- x++;
- /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
- s->type == IVTV_ENC_STREAM_TYPE_VBI)
- buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP;
- }
- if (buf)
- buf->bytesused += s->dma_last_offset;
- if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
- list_for_each_entry(buf, &s->q_dma.list, list) {
- /* Parse and Groom VBI Data */
- s->q_dma.bytesused -= buf->bytesused;
- ivtv_process_vbi_data(itv, buf, 0, s->type);
- s->q_dma.bytesused += buf->bytesused;
- }
- if (s->fh == NULL) {
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
- return;
- }
- }
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
- if (s->fh)
- wake_up(&s->waitq);
-}
-
-void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
-{
- struct ivtv *itv = s->itv;
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- struct yuv_frame_info *f = &yi->new_frame_info[frame];
- struct ivtv_buffer *buf;
- u32 y_size = 720 * ((f->src_h + 31) & ~31);
- u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
- int y_done = 0;
- int bytes_written = 0;
- unsigned long flags = 0;
- int idx = 0;
-
- IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);
-
- /* Insert buffer block for YUV if needed */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) {
- if (yi->blanking_dmaptr) {
- s->sg_pending[idx].src = yi->blanking_dmaptr;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = 720 * 16;
- }
- offset += 720 * 16;
- idx++;
- }
-
- list_for_each_entry(buf, &s->q_predma.list, list) {
- /* YUV UV Offset from Y Buffer */
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done &&
- (bytes_written + buf->bytesused) >= y_size) {
- s->sg_pending[idx].src = buf->dma_handle;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = y_size - bytes_written;
- offset = uv_offset;
- if (s->sg_pending[idx].size != buf->bytesused) {
- idx++;
- s->sg_pending[idx].src =
- buf->dma_handle + s->sg_pending[idx - 1].size;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size =
- buf->bytesused - s->sg_pending[idx - 1].size;
- offset += s->sg_pending[idx].size;
- }
- y_done = 1;
- } else {
- s->sg_pending[idx].src = buf->dma_handle;
- s->sg_pending[idx].dst = offset;
- s->sg_pending[idx].size = buf->bytesused;
- offset += buf->bytesused;
- }
- bytes_written += buf->bytesused;
-
- /* Sync SG buffers */
- ivtv_buf_sync_for_device(s, buf);
- idx++;
- }
- s->sg_pending_size = idx;
-
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- if (lock)
- spin_lock_irqsave(&itv->dma_reg_lock, flags);
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- ivtv_dma_dec_start(s);
- }
- else {
- set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
- if (lock)
- spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
-}
-
-static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
- s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
- s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
- s->sg_processed++;
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
- add_timer(&itv->dma_timer);
-}
-
-static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
- s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
- s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
- s->sg_processed++;
- /* Sync Hardware SG List of buffers */
- ivtv_stream_sync_for_device(s);
- write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
- itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
- add_timer(&itv->dma_timer);
-}
-
-/* start the encoder DMA */
-static void ivtv_dma_enc_start(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- int i;
-
- IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
-
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
-
- if (ivtv_use_dma(s))
- s->sg_pending[s->sg_pending_size - 1].size += 256;
-
- /* If this is an MPEG stream, and VBI data is also pending, then append the
- VBI DMA to the MPEG DMA and transfer both sets of data at once.
-
- VBI DMA is a second class citizen compared to MPEG and mixing them together
- will confuse the firmware (the end of a VBI DMA is seen as the end of a
- MPEG DMA, thus effectively dropping an MPEG frame). So instead we make
- sure we only use the MPEG DMA to transfer the VBI DMA if both are in
- use. This way no conflicts occur. */
- clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size &&
- s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) {
- ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
- if (ivtv_use_dma(s_vbi))
- s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256;
- for (i = 0; i < s_vbi->sg_pending_size; i++) {
- s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i];
- }
- s_vbi->dma_offset = s_vbi->pending_offset;
- s_vbi->sg_pending_size = 0;
- s_vbi->dma_xfer_cnt++;
- set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
- IVTV_DEBUG_HI_DMA("include DMA for %s\n", s_vbi->name);
- }
-
- s->dma_xfer_cnt++;
- memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
- s->sg_processing_size = s->sg_pending_size;
- s->sg_pending_size = 0;
- s->sg_processed = 0;
- s->dma_offset = s->pending_offset;
- s->dma_backup = s->pending_backup;
- s->dma_pts = s->pending_pts;
-
- if (ivtv_use_pio(s)) {
- set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- set_bit(IVTV_F_I_PIO, &itv->i_flags);
- itv->cur_pio_stream = s->type;
- }
- else {
- itv->dma_retries = 0;
- ivtv_dma_enc_start_xfer(s);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
- }
-}
-
-static void ivtv_dma_dec_start(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- if (s->q_predma.bytesused)
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
- s->dma_xfer_cnt++;
- memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
- s->sg_processing_size = s->sg_pending_size;
- s->sg_pending_size = 0;
- s->sg_processed = 0;
-
- IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name);
- itv->dma_retries = 0;
- ivtv_dma_dec_start_xfer(s);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = s->type;
-}
-
-static void ivtv_irq_dma_read(struct ivtv *itv)
-{
- struct ivtv_stream *s = NULL;
- struct ivtv_buffer *buf;
- int hw_stream_type = 0;
-
- IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
-
- del_timer(&itv->dma_timer);
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
- return;
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- s = &itv->streams[itv->cur_dma_stream];
- ivtv_stream_sync_for_cpu(s);
-
- if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
- IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n",
- read_reg(IVTV_REG_DMASTATUS),
- s->sg_processed, s->sg_processing_size, itv->dma_retries);
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- if (itv->dma_retries == 3) {
- /* Too many retries, give up on this frame */
- itv->dma_retries = 0;
- s->sg_processed = s->sg_processing_size;
- }
- else {
- /* Retry, starting with the first xfer segment.
- Just retrying the current segment is not sufficient. */
- s->sg_processed = 0;
- itv->dma_retries++;
- }
- }
- if (s->sg_processed < s->sg_processing_size) {
- /* DMA next buffer */
- ivtv_dma_dec_start_xfer(s);
- return;
- }
- if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
- hw_stream_type = 2;
- IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);
-
- /* For some reason must kick the firmware, like PIO mode,
- I think this tells the firmware we are done and the size
- of the xfer so it can calculate what we need next.
- I think we can do this part ourselves but would have to
- fully calculate xfer info ourselves and not use interrupts
- */
- ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused,
- hw_stream_type);
-
- /* Free last DMA call */
- while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) {
- ivtv_buf_sync_for_cpu(s, buf);
- ivtv_enqueue(s, buf, &s->q_free);
- }
- wake_up(&s->waitq);
- }
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
- IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
-
- del_timer(&itv->dma_timer);
-
- if (itv->cur_dma_stream < 0)
- return;
-
- s = &itv->streams[itv->cur_dma_stream];
- ivtv_stream_sync_for_cpu(s);
-
- if (data[0] & 0x18) {
- IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0],
- s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries);
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- if (itv->dma_retries == 3) {
- /* Too many retries, give up on this frame */
- itv->dma_retries = 0;
- s->sg_processed = s->sg_processing_size;
- }
- else {
- /* Retry, starting with the first xfer segment.
- Just retrying the current segment is not sufficient. */
- s->sg_processed = 0;
- itv->dma_retries++;
- }
- }
- if (s->sg_processed < s->sg_processing_size) {
- /* DMA next buffer */
- ivtv_dma_enc_start_xfer(s);
- return;
- }
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- dma_post(s);
- if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- dma_post(s);
- }
- s->sg_processing_size = 0;
- s->sg_processed = 0;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
-{
- struct ivtv_stream *s;
-
- if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
- itv->cur_pio_stream = -1;
- return;
- }
- s = &itv->streams[itv->cur_pio_stream];
- IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name);
- clear_bit(IVTV_F_I_PIO, &itv->i_flags);
- itv->cur_pio_stream = -1;
- dma_post(s);
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
- else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
- else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
- ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
- clear_bit(IVTV_F_I_PIO, &itv->i_flags);
- if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
- dma_post(s);
- }
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_dma_err(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- u32 status;
-
- del_timer(&itv->dma_timer);
-
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
- status = read_reg(IVTV_REG_DMASTATUS);
- IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
- status, itv->cur_dma_stream);
- /*
- * We do *not* write back to the IVTV_REG_DMASTATUS register to
- * clear the error status, if either the encoder write (0x02) or
- * decoder read (0x01) bus master DMA operation do not indicate
- * completed. We can race with the DMA engine, which may have
- * transitioned to completed status *after* we read the register.
- * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the
- * DMA engine has completed, will cause the DMA engine to stop working.
- */
- status &= 0x3;
- if (status == 0x3)
- write_reg(status, IVTV_REG_DMASTATUS);
-
- if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
- itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
- struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];
-
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
- /* retry */
- /*
- * FIXME - handle cases of DMA error similar to
- * encoder below, except conditioned on status & 0x1
- */
- ivtv_dma_dec_start(s);
- return;
- } else {
- if ((status & 0x2) == 0) {
- /*
- * CX2341x Bus Master DMA write is ongoing.
- * Reset the timer and let it complete.
- */
- itv->dma_timer.expires =
- jiffies + msecs_to_jiffies(600);
- add_timer(&itv->dma_timer);
- return;
- }
-
- if (itv->dma_retries < 3) {
- /*
- * CX2341x Bus Master DMA write has ended.
- * Retry the write, starting with the first
- * xfer segment. Just retrying the current
- * segment is not sufficient.
- */
- s->sg_processed = 0;
- itv->dma_retries++;
- ivtv_dma_enc_start_xfer(s);
- return;
- }
- /* Too many retries, give up on this one */
- }
-
- }
- if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- ivtv_udma_start(itv);
- return;
- }
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
-
-static void ivtv_irq_enc_start_cap(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- /* Get DMA destination and size arguments from card */
- ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
- IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
-
- if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
- IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n",
- data[0], data[1], data[2]);
- return;
- }
- s = &itv->streams[ivtv_stream_map[data[0]]];
- if (!stream_enc_dma_append(s, data)) {
- set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
- }
-}
-
-static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
- s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-
- if (!stream_enc_dma_append(s, data))
- set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
-}
-
-static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
-
- IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n");
- if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
- !stream_enc_dma_append(s, data)) {
- set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
- }
-}
-
-static void ivtv_irq_dec_data_req(struct ivtv *itv)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv_stream *s;
-
- /* YUV or MPG */
-
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
- itv->dma_data_req_size =
- 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
- itv->dma_data_req_offset = data[1];
- if (atomic_read(&itv->yuv_info.next_dma_frame) >= 0)
- ivtv_yuv_frame_complete(itv);
- s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- }
- else {
- ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
- itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
- itv->dma_data_req_offset = data[1];
- s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
- }
- IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused,
- itv->dma_data_req_offset, itv->dma_data_req_size);
- if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) {
- set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- }
- else {
- if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
- ivtv_yuv_setup_stream_frame(itv);
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
- ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0);
- }
-}
-
-static void ivtv_irq_vsync(struct ivtv *itv)
-{
- /* The vsync interrupt is unusual in that it won't clear until
- * the end of the first line for the current field, at which
- * point it clears itself. This can result in repeated vsync
- * interrupts, or a missed vsync. Read some of the registers
- * to determine the line being displayed and ensure we handle
- * one vsync per frame.
- */
- unsigned int frame = read_reg(IVTV_REG_DEC_LINE_FIELD) & 1;
- struct yuv_playback_info *yi = &itv->yuv_info;
- int last_dma_frame = atomic_read(&yi->next_dma_frame);
- struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
-
- if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
-
- if (((frame ^ f->sync_field) == 0 &&
- ((itv->last_vsync_field & 1) ^ f->sync_field)) ||
- (frame != (itv->last_vsync_field & 1) && !f->interlaced)) {
- int next_dma_frame = last_dma_frame;
-
- if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) {
- if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) {
- write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
- write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
- write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
- write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
- next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
- atomic_set(&yi->next_dma_frame, next_dma_frame);
- yi->fields_lapsed = -1;
- yi->running = 1;
- }
- }
- }
- if (frame != (itv->last_vsync_field & 1)) {
- static const struct v4l2_event evtop = {
- .type = V4L2_EVENT_VSYNC,
- .u.vsync.field = V4L2_FIELD_TOP,
- };
- static const struct v4l2_event evbottom = {
- .type = V4L2_EVENT_VSYNC,
- .u.vsync.field = V4L2_FIELD_BOTTOM,
- };
- struct ivtv_stream *s = ivtv_get_output_stream(itv);
-
- itv->last_vsync_field += 1;
- if (frame == 0) {
- clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
- clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
- }
- else {
- set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
- }
- if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
- set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
- wake_up(&itv->event_waitq);
- if (s)
- wake_up(&s->waitq);
- }
- if (s && s->vdev)
- v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
- wake_up(&itv->vsync_waitq);
-
- /* Send VBI to saa7127 */
- if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
- test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) ||
- test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) ||
- test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) {
- set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- }
-
- /* Check if we need to update the yuv registers */
- if (yi->running && (yi->yuv_forced_update || f->update)) {
- if (!f->update) {
- last_dma_frame =
- (u8)(atomic_read(&yi->next_dma_frame) -
- 1) % IVTV_YUV_BUFFERS;
- f = &yi->new_frame_info[last_dma_frame];
- }
-
- if (f->src_w) {
- yi->update_frame = last_dma_frame;
- f->update = 0;
- yi->yuv_forced_update = 0;
- set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
- set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
- }
- }
-
- yi->fields_lapsed++;
- }
-}
-
-#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ | IVTV_IRQ_DEC_VBI_RE_INSERT)
-
-irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
-{
- struct ivtv *itv = (struct ivtv *)dev_id;
- u32 combo;
- u32 stat;
- int i;
- u8 vsync_force = 0;
-
- spin_lock(&itv->dma_reg_lock);
- /* get contents of irq status register */
- stat = read_reg(IVTV_REG_IRQSTATUS);
-
- combo = ~itv->irqmask & stat;
-
- /* Clear out IRQ */
- if (combo) write_reg(combo, IVTV_REG_IRQSTATUS);
-
- if (0 == combo) {
- /* The vsync interrupt is unusual and clears itself. If we
- * took too long, we may have missed it. Do some checks
- */
- if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
- /* vsync is enabled, see if we're in a new field */
- if ((itv->last_vsync_field & 1) !=
- (read_reg(IVTV_REG_DEC_LINE_FIELD) & 1)) {
- /* New field, looks like we missed it */
- IVTV_DEBUG_YUV("VSync interrupt missed %d\n",
- read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16);
- vsync_force = 1;
- }
- }
-
- if (!vsync_force) {
- /* No Vsync expected, wasn't for us */
- spin_unlock(&itv->dma_reg_lock);
- return IRQ_NONE;
- }
- }
-
- /* Exclude interrupts noted below from the output, otherwise the log is flooded with
- these messages */
- if (combo & ~0xff6d0400)
- IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo);
-
- if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) {
- IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n");
- }
-
- if (combo & IVTV_IRQ_DMA_READ) {
- ivtv_irq_dma_read(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) {
- ivtv_irq_enc_dma_complete(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
- ivtv_irq_enc_pio_complete(itv);
- }
-
- if (combo & IVTV_IRQ_DMA_ERR) {
- ivtv_irq_dma_err(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_START_CAP) {
- ivtv_irq_enc_start_cap(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_VBI_CAP) {
- ivtv_irq_enc_vbi_cap(itv);
- }
-
- if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
- ivtv_irq_dec_vbi_reinsert(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_EOS) {
- IVTV_DEBUG_IRQ("ENC EOS\n");
- set_bit(IVTV_F_I_EOS, &itv->i_flags);
- wake_up(&itv->eos_waitq);
- }
-
- if (combo & IVTV_IRQ_DEC_DATA_REQ) {
- ivtv_irq_dec_data_req(itv);
- }
-
- /* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */
- if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
- ivtv_irq_vsync(itv);
- }
-
- if (combo & IVTV_IRQ_ENC_VIM_RST) {
- IVTV_DEBUG_IRQ("VIM RST\n");
- /*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */
- }
-
- if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) {
- IVTV_DEBUG_INFO("Stereo mode changed\n");
- }
-
- if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
- itv->irq_rr_idx++;
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
- struct ivtv_stream *s = &itv->streams[idx];
-
- if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
- continue;
- if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_dma_dec_start(s);
- else
- ivtv_dma_enc_start(s);
- break;
- }
-
- if (i == IVTV_MAX_STREAMS &&
- test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- ivtv_udma_start(itv);
- }
-
- if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
- itv->irq_rr_idx++;
- for (i = 0; i < IVTV_MAX_STREAMS; i++) {
- int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
- struct ivtv_stream *s = &itv->streams[idx];
-
- if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
- continue;
- if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
- ivtv_dma_enc_start(s);
- break;
- }
- }
-
- if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
- queue_kthread_work(&itv->irq_worker, &itv->irq_work);
- }
-
- spin_unlock(&itv->dma_reg_lock);
-
- /* If we've just handled a 'forced' vsync, it's safest to say it
- * wasn't ours. Another device may have triggered it at just
- * the right time.
- */
- return vsync_force ? IRQ_NONE : IRQ_HANDLED;
-}
-
-void ivtv_unfinished_dma(unsigned long arg)
-{
- struct ivtv *itv = (struct ivtv *)arg;
-
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
- return;
- IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
-
- write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
- clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_DMA, &itv->i_flags);
- itv->cur_dma_stream = -1;
- wake_up(&itv->dma_waitq);
-}
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/video/ivtv/ivtv-irq.h
deleted file mode 100644
index 1e84433737cc..000000000000
--- a/drivers/media/video/ivtv/ivtv-irq.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- interrupt handling
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_IRQ_H
-#define IVTV_IRQ_H
-
-#define IVTV_IRQ_ENC_START_CAP (0x1 << 31)
-#define IVTV_IRQ_ENC_EOS (0x1 << 30)
-#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
-#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
-#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
-#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25)
-#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
-#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
-#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
-#define IVTV_IRQ_DEC_VBI_RE_INSERT (0x1 << 19)
-#define IVTV_IRQ_DMA_ERR (0x1 << 18)
-#define IVTV_IRQ_DMA_WRITE (0x1 << 17)
-#define IVTV_IRQ_DMA_READ (0x1 << 16)
-#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
-
-/* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
- IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
-
-#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
-#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
-
-irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
-
-void ivtv_irq_work_handler(struct kthread_work *work);
-void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
-void ivtv_unfinished_dma(unsigned long arg);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
deleted file mode 100644
index e3ce96763785..000000000000
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- mailbox functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "ivtv-driver.h"
-#include "ivtv-mailbox.h"
-
-/* Firmware mailbox flags*/
-#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
-#define IVTV_MBOX_DRIVER_DONE 0x00000002
-#define IVTV_MBOX_DRIVER_BUSY 0x00000001
-#define IVTV_MBOX_FREE 0x00000000
-
-/* Firmware mailbox standard timeout */
-#define IVTV_API_STD_TIMEOUT 0x02000000
-
-#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
-#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
-#define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */
-#define API_DMA (1 << 3) /* DMA mailbox, has special handling */
-#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */
-#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
-#define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */
-#define API_NO_POLL (1 << 6) /* Avoid pointless polling */
-
-struct ivtv_api_info {
- int flags; /* Flags, see above */
- const char *name; /* The name of the command */
-};
-
-#define API_ENTRY(x, f) [x] = { (f), #x }
-
-static const struct ivtv_api_info api_info[256] = {
- /* MPEG encoder API */
- API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT),
- API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE),
- API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT),
- /* Obsolete PULLDOWN API command */
- API_ENTRY(0xb1, API_CACHE),
-
- /* MPEG decoder API */
- API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT),
- API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
- API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE),
- API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE),
- API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE),
-
- /* OSD API */
- API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE)
-};
-
-static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
-{
- u32 flags = readl(&mbdata->mbox[mb].flags);
- int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE);
-
- /* if the mailbox is free, then try to claim it */
- if (is_free && !test_and_set_bit(mb, &mbdata->busy)) {
- write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags);
- return 1;
- }
- return 0;
-}
-
-/* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not
- attempted here. */
-static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags)
-{
- unsigned long then = jiffies;
- int i, mb;
- int max_mbox = mbdata->max_mbox;
- int retries = 100;
-
- /* All slow commands use the same mailbox, serializing them and also
- leaving the other mailbox free for simple fast commands. */
- if ((flags & API_FAST_RESULT) == API_RESULT)
- max_mbox = 1;
-
- /* find free non-DMA mailbox */
- for (i = 0; i < retries; i++) {
- for (mb = 1; mb <= max_mbox; mb++)
- if (try_mailbox(itv, mbdata, mb))
- return mb;
-
- /* Sleep before a retry, if not atomic */
- if (!(flags & API_NO_WAIT_MB)) {
- if (time_after(jiffies,
- then + msecs_to_jiffies(10*retries)))
- break;
- ivtv_msleep_timeout(10, 0);
- }
- }
- return -ENODEV;
-}
-
-static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[])
-{
- int i;
-
- write_sync(cmd, &mbox->cmd);
- write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout);
-
- for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
- write_sync(data[i], &mbox->data[i]);
-
- write_sync(IVTV_MBOX_DRIVER_DONE | IVTV_MBOX_DRIVER_BUSY, &mbox->flags);
-}
-
-static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata)
-{
- int i;
-
- for (i = 0; i <= mbdata->max_mbox; i++) {
- IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n",
- i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags));
- write_sync(0, &mbdata->mbox[i].flags);
- clear_bit(i, &mbdata->busy);
- }
-}
-
-static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
-{
- struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox;
- volatile struct ivtv_mailbox __iomem *mbox;
- int api_timeout = msecs_to_jiffies(1000);
- int flags, mb, i;
- unsigned long then;
-
- /* sanity checks */
- if (NULL == mbdata) {
- IVTV_ERR("No mailbox allocated\n");
- return -ENODEV;
- }
- if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
- cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
- IVTV_ERR("Invalid MB call: cmd = 0x%02x, args = %d\n", cmd, args);
- return -EINVAL;
- }
-
- if (api_info[cmd].flags & API_HIGH_VOL) {
- IVTV_DEBUG_HI_MB("MB Call: %s\n", api_info[cmd].name);
- }
- else {
- IVTV_DEBUG_MB("MB Call: %s\n", api_info[cmd].name);
- }
-
- /* clear possibly uninitialized part of data array */
- for (i = args; i < CX2341X_MBOX_MAX_DATA; i++)
- data[i] = 0;
-
- /* If this command was issued within the last 30 minutes and with identical
- data, then just return 0 as there is no need to issue this command again.
- Just an optimization to prevent unnecessary use of mailboxes. */
- if (itv->api_cache[cmd].last_jiffies &&
- time_before(jiffies,
- itv->api_cache[cmd].last_jiffies +
- msecs_to_jiffies(1800000)) &&
- !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) {
- itv->api_cache[cmd].last_jiffies = jiffies;
- return 0;
- }
-
- flags = api_info[cmd].flags;
-
- if (flags & API_DMA) {
- for (i = 0; i < 100; i++) {
- mb = i % (mbdata->max_mbox + 1);
- if (try_mailbox(itv, mbdata, mb)) {
- write_mailbox(&mbdata->mbox[mb], cmd, args, data);
- clear_bit(mb, &mbdata->busy);
- return 0;
- }
- IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n",
- api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags));
- }
- IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name);
- clear_all_mailboxes(itv, mbdata);
- return -EBUSY;
- }
-
- if ((flags & API_FAST_RESULT) == API_FAST_RESULT)
- api_timeout = msecs_to_jiffies(100);
-
- mb = get_mailbox(itv, mbdata, flags);
- if (mb < 0) {
- IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name);
- clear_all_mailboxes(itv, mbdata);
- return -EBUSY;
- }
- mbox = &mbdata->mbox[mb];
- write_mailbox(mbox, cmd, args, data);
- if (flags & API_CACHE) {
- memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data));
- itv->api_cache[cmd].last_jiffies = jiffies;
- }
- if ((flags & API_RESULT) == 0) {
- clear_bit(mb, &mbdata->busy);
- return 0;
- }
-
- /* Get results */
- then = jiffies;
-
- if (!(flags & API_NO_POLL)) {
- /* First try to poll, then switch to delays */
- for (i = 0; i < 100; i++) {
- if (readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)
- break;
- }
- }
- while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
- if (time_after(jiffies, then + api_timeout)) {
- IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
- /* reset the mailbox, but it is likely too late already */
- write_sync(0, &mbox->flags);
- clear_bit(mb, &mbdata->busy);
- return -EIO;
- }
- if (flags & API_NO_WAIT_RES)
- mdelay(1);
- else
- ivtv_msleep_timeout(1, 0);
- }
- if (time_after(jiffies, then + msecs_to_jiffies(100)))
- IVTV_DEBUG_WARN("%s took %u jiffies\n",
- api_info[cmd].name,
- jiffies_to_msecs(jiffies - then));
-
- for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
- data[i] = readl(&mbox->data[i]);
- write_sync(0, &mbox->flags);
- clear_bit(mb, &mbdata->busy);
- return 0;
-}
-
-int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[])
-{
- int res = ivtv_api_call(itv, cmd, args, data);
-
- /* Allow a single retry, probably already too late though.
- If there is no free mailbox then that is usually an indication
- of a more serious problem. */
- return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res;
-}
-
-int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
-{
- return ivtv_api(priv, cmd, in, data);
-}
-
-int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...)
-{
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++) {
- data[i] = va_arg(ap, u32);
- }
- va_end(ap);
- return ivtv_api(itv, cmd, args, data);
-}
-
-int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- va_list ap;
- int i;
-
- va_start(ap, args);
- for (i = 0; i < args; i++) {
- data[i] = va_arg(ap, u32);
- }
- va_end(ap);
- return ivtv_api(itv, cmd, args, data);
-}
-
-/* This one is for stuff that can't sleep.. irq handlers, etc.. */
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
- int argc, u32 data[])
-{
- volatile u32 __iomem *p = mbdata->mbox[mb].data;
- int i;
- for (i = 0; i < argc; i++, p++)
- data[i] = readl(p);
-}
-
-/* Wipe api cache */
-void ivtv_mailbox_cache_invalidate(struct ivtv *itv)
-{
- int i;
- for (i = 0; i < 256; i++)
- itv->api_cache[i].last_jiffies = 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
deleted file mode 100644
index 2c834d2cb56f..000000000000
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- mailbox functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_MAILBOX_H
-#define IVTV_MAILBOX_H
-
-#define IVTV_MBOX_DMA_END 8
-#define IVTV_MBOX_DMA 9
-
-void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
- int argc, u32 data[]);
-int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
-int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
-int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
-int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]);
-void ivtv_mailbox_cache_invalidate(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
deleted file mode 100644
index 7fde36e6d227..000000000000
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- buffer queues.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-queue.h"
-
-int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes)
-{
- if (s->buf_size - buf->bytesused < copybytes)
- copybytes = s->buf_size - buf->bytesused;
- if (copy_from_user(buf->buf + buf->bytesused, src, copybytes)) {
- return -EFAULT;
- }
- buf->bytesused += copybytes;
- return copybytes;
-}
-
-void ivtv_buf_swap(struct ivtv_buffer *buf)
-{
- int i;
-
- for (i = 0; i < buf->bytesused; i += 4)
- swab32s((u32 *)(buf->buf + i));
-}
-
-void ivtv_queue_init(struct ivtv_queue *q)
-{
- INIT_LIST_HEAD(&q->list);
- q->buffers = 0;
- q->length = 0;
- q->bytesused = 0;
-}
-
-void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q)
-{
- unsigned long flags;
-
- /* clear the buffer if it is going to be enqueued to the free queue */
- if (q == &s->q_free) {
- buf->bytesused = 0;
- buf->readpos = 0;
- buf->b_flags = 0;
- buf->dma_xfer_cnt = 0;
- }
- spin_lock_irqsave(&s->qlock, flags);
- list_add_tail(&buf->list, &q->list);
- q->buffers++;
- q->length += s->buf_size;
- q->bytesused += buf->bytesused - buf->readpos;
- spin_unlock_irqrestore(&s->qlock, flags);
-}
-
-struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q)
-{
- struct ivtv_buffer *buf = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&s->qlock, flags);
- if (!list_empty(&q->list)) {
- buf = list_entry(q->list.next, struct ivtv_buffer, list);
- list_del_init(q->list.next);
- q->buffers--;
- q->length -= s->buf_size;
- q->bytesused -= buf->bytesused - buf->readpos;
- }
- spin_unlock_irqrestore(&s->qlock, flags);
- return buf;
-}
-
-static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
- struct ivtv_queue *to, int clear)
-{
- struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list);
-
- list_move_tail(from->list.next, &to->list);
- from->buffers--;
- from->length -= s->buf_size;
- from->bytesused -= buf->bytesused - buf->readpos;
- /* special handling for q_free */
- if (clear)
- buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
- to->buffers++;
- to->length += s->buf_size;
- to->bytesused += buf->bytesused - buf->readpos;
-}
-
-/* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
- If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
- If 'steal' != NULL, then buffers may also taken from that queue if
- needed, but only if 'from' is the free queue.
-
- The buffer is automatically cleared if it goes to the free queue. It is
- also cleared if buffers need to be taken from the 'steal' queue and
- the 'from' queue is the free queue.
-
- When 'from' is q_free, then needed_bytes is compared to the total
- available buffer length, otherwise needed_bytes is compared to the
- bytesused value. For the 'steal' queue the total available buffer
- length is always used.
-
- -ENOMEM is returned if the buffers could not be obtained, 0 if all
- buffers where obtained from the 'from' list and if non-zero then
- the number of stolen buffers is returned. */
-int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
- struct ivtv_queue *to, int needed_bytes)
-{
- unsigned long flags;
- int rc = 0;
- int from_free = from == &s->q_free;
- int to_free = to == &s->q_free;
- int bytes_available, bytes_steal;
-
- spin_lock_irqsave(&s->qlock, flags);
- if (needed_bytes == 0) {
- from_free = 1;
- needed_bytes = from->length;
- }
-
- bytes_available = from_free ? from->length : from->bytesused;
- bytes_steal = (from_free && steal) ? steal->length : 0;
-
- if (bytes_available + bytes_steal < needed_bytes) {
- spin_unlock_irqrestore(&s->qlock, flags);
- return -ENOMEM;
- }
- while (bytes_available < needed_bytes) {
- struct ivtv_buffer *buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
- u16 dma_xfer_cnt = buf->dma_xfer_cnt;
-
- /* move buffers from the tail of the 'steal' queue to the tail of the
- 'from' queue. Always copy all the buffers with the same dma_xfer_cnt
- value, this ensures that you do not end up with partial frame data
- if one frame is stored in multiple buffers. */
- while (dma_xfer_cnt == buf->dma_xfer_cnt) {
- list_move_tail(steal->list.prev, &from->list);
- rc++;
- steal->buffers--;
- steal->length -= s->buf_size;
- steal->bytesused -= buf->bytesused - buf->readpos;
- buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
- from->buffers++;
- from->length += s->buf_size;
- bytes_available += s->buf_size;
- if (list_empty(&steal->list))
- break;
- buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
- }
- }
- if (from_free) {
- u32 old_length = to->length;
-
- while (to->length - old_length < needed_bytes) {
- ivtv_queue_move_buf(s, from, to, 1);
- }
- }
- else {
- u32 old_bytesused = to->bytesused;
-
- while (to->bytesused - old_bytesused < needed_bytes) {
- ivtv_queue_move_buf(s, from, to, to_free);
- }
- }
- spin_unlock_irqrestore(&s->qlock, flags);
- return rc;
-}
-
-void ivtv_flush_queues(struct ivtv_stream *s)
-{
- ivtv_queue_move(s, &s->q_io, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_full, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
- ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
-}
-
-int ivtv_stream_alloc(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
- int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers;
- int i;
-
- if (s->buffers == 0)
- return 0;
-
- IVTV_DEBUG_INFO("Allocate %s%s stream: %d x %d buffers (%dkB total)\n",
- s->dma != PCI_DMA_NONE ? "DMA " : "",
- s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
-
- s->sg_pending = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_pending == NULL) {
- IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
- return -ENOMEM;
- }
- s->sg_pending_size = 0;
-
- s->sg_processing = kzalloc(SGsize, GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_processing == NULL) {
- IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
- kfree(s->sg_pending);
- s->sg_pending = NULL;
- return -ENOMEM;
- }
- s->sg_processing_size = 0;
-
- s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element),
- GFP_KERNEL|__GFP_NOWARN);
- if (s->sg_dma == NULL) {
- IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
- kfree(s->sg_pending);
- s->sg_pending = NULL;
- kfree(s->sg_processing);
- s->sg_processing = NULL;
- return -ENOMEM;
- }
- if (ivtv_might_use_dma(s)) {
- s->sg_handle = pci_map_single(itv->pdev, s->sg_dma,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
- ivtv_stream_sync_for_cpu(s);
- }
-
- /* allocate stream buffers. Initially all buffers are in q_free. */
- for (i = 0; i < s->buffers; i++) {
- struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer),
- GFP_KERNEL|__GFP_NOWARN);
-
- if (buf == NULL)
- break;
- buf->buf = kmalloc(s->buf_size + 256, GFP_KERNEL|__GFP_NOWARN);
- if (buf->buf == NULL) {
- kfree(buf);
- break;
- }
- INIT_LIST_HEAD(&buf->list);
- if (ivtv_might_use_dma(s)) {
- buf->dma_handle = pci_map_single(s->itv->pdev,
- buf->buf, s->buf_size + 256, s->dma);
- ivtv_buf_sync_for_cpu(s, buf);
- }
- ivtv_enqueue(s, buf, &s->q_free);
- }
- if (i == s->buffers)
- return 0;
- IVTV_ERR("Couldn't allocate buffers for %s stream\n", s->name);
- ivtv_stream_free(s);
- return -ENOMEM;
-}
-
-void ivtv_stream_free(struct ivtv_stream *s)
-{
- struct ivtv_buffer *buf;
-
- /* move all buffers to q_free */
- ivtv_flush_queues(s);
-
- /* empty q_free */
- while ((buf = ivtv_dequeue(s, &s->q_free))) {
- if (ivtv_might_use_dma(s))
- pci_unmap_single(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
- kfree(buf->buf);
- kfree(buf);
- }
-
- /* Free SG Array/Lists */
- if (s->sg_dma != NULL) {
- if (s->sg_handle != IVTV_DMA_UNMAPPED) {
- pci_unmap_single(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
- s->sg_handle = IVTV_DMA_UNMAPPED;
- }
- kfree(s->sg_pending);
- kfree(s->sg_processing);
- kfree(s->sg_dma);
- s->sg_pending = NULL;
- s->sg_processing = NULL;
- s->sg_dma = NULL;
- s->sg_pending_size = 0;
- s->sg_processing_size = 0;
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
deleted file mode 100644
index 91233839a26c..000000000000
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- buffer queues.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_QUEUE_H
-#define IVTV_QUEUE_H
-
-#define IVTV_DMA_UNMAPPED ((u32) -1)
-#define SLICED_VBI_PIO 0
-
-/* ivtv_buffer utility functions */
-
-static inline int ivtv_might_use_pio(struct ivtv_stream *s)
-{
- return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
-}
-
-static inline int ivtv_use_pio(struct ivtv_stream *s)
-{
- struct ivtv *itv = s->itv;
-
- return s->dma == PCI_DMA_NONE ||
- (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
-}
-
-static inline int ivtv_might_use_dma(struct ivtv_stream *s)
-{
- return s->dma != PCI_DMA_NONE;
-}
-
-static inline int ivtv_use_dma(struct ivtv_stream *s)
-{
- return !ivtv_use_pio(s);
-}
-
-static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
-}
-
-static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
- s->buf_size + 256, s->dma);
-}
-
-int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes);
-void ivtv_buf_swap(struct ivtv_buffer *buf);
-
-/* ivtv_queue utility functions */
-void ivtv_queue_init(struct ivtv_queue *q);
-void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_queue *q);
-struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q);
-int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_queue *steal,
- struct ivtv_queue *to, int needed_bytes);
-void ivtv_flush_queues(struct ivtv_stream *s);
-
-/* ivtv_stream utility functions */
-int ivtv_stream_alloc(struct ivtv_stream *s);
-void ivtv_stream_free(struct ivtv_stream *s);
-
-static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
-}
-
-static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
-{
- if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
- sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
-}
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-routing.c b/drivers/media/video/ivtv/ivtv-routing.c
deleted file mode 100644
index 8898c569a1c9..000000000000
--- a/drivers/media/video/ivtv/ivtv-routing.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- Audio/video-routing-related ivtv functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-i2c.h"
-#include "ivtv-cards.h"
-#include "ivtv-gpio.h"
-#include "ivtv-routing.h"
-
-#include <media/msp3400.h>
-#include <media/m52790.h>
-#include <media/upd64031a.h>
-#include <media/upd64083.h>
-
-/* Selects the audio input and output according to the current
- settings. */
-void ivtv_audio_set_io(struct ivtv *itv)
-{
- const struct ivtv_card_audio_input *in;
- u32 input, output = 0;
-
- /* Determine which input to use */
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
- in = &itv->card->radio_input;
- else
- in = &itv->card->audio_inputs[itv->audio_input];
-
- /* handle muxer chips */
- input = in->muxer_input;
- if (itv->card->hw_muxer & IVTV_HW_M52790)
- output = M52790_OUT_STEREO;
- v4l2_subdev_call(itv->sd_muxer, audio, s_routing,
- input, output, 0);
-
- input = in->audio_input;
- output = 0;
- if (itv->card->hw_audio & IVTV_HW_MSP34XX)
- output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing,
- input, output, 0);
-}
-
-/* Selects the video input and output according to the current
- settings. */
-void ivtv_video_set_io(struct ivtv *itv)
-{
- int inp = itv->active_input;
- u32 input;
- u32 type;
-
- v4l2_subdev_call(itv->sd_video, video, s_routing,
- itv->card->video_inputs[inp].video_input, 0, 0);
-
- type = itv->card->video_inputs[inp].video_type;
-
- if (type == IVTV_CARD_INPUT_VID_TUNER) {
- input = 0; /* Tuner */
- } else if (type < IVTV_CARD_INPUT_COMPOSITE1) {
- input = 2; /* S-Video */
- } else {
- input = 1; /* Composite */
- }
-
- if (itv->card->hw_video & IVTV_HW_GPIO)
- ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing,
- input, 0, 0);
-
- if (itv->card->hw_video & IVTV_HW_UPD64031A) {
- if (type == IVTV_CARD_INPUT_VID_TUNER ||
- type >= IVTV_CARD_INPUT_COMPOSITE1) {
- /* Composite: GR on, connect to 3DYCS */
- input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE;
- } else {
- /* S-Video: GR bypassed, turn it off */
- input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE;
- }
- input |= itv->card->gr_config;
-
- ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing,
- input, 0, 0);
- }
-
- if (itv->card->hw_video & IVTV_HW_UPD6408X) {
- input = UPD64083_YCS_MODE;
- if (type > IVTV_CARD_INPUT_VID_TUNER &&
- type < IVTV_CARD_INPUT_COMPOSITE1) {
- /* S-Video uses YCNR mode and internal Y-ADC, the
- upd64031a is not used. */
- input |= UPD64083_YCNR_MODE;
- }
- else if (itv->card->hw_video & IVTV_HW_UPD64031A) {
- /* Use upd64031a output for tuner and
- composite(CX23416GYC only) inputs */
- if (type == IVTV_CARD_INPUT_VID_TUNER ||
- itv->card->type == IVTV_CARD_CX23416GYC) {
- input |= UPD64083_EXT_Y_ADC;
- }
- }
- ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing,
- input, 0, 0);
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-routing.h b/drivers/media/video/ivtv/ivtv-routing.h
deleted file mode 100644
index c72a9731ca01..000000000000
--- a/drivers/media/video/ivtv/ivtv-routing.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- Audio/video-routing-related ivtv functions.
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_ROUTING_H
-#define IVTV_ROUTING_H
-
-void ivtv_audio_set_io(struct ivtv *itv);
-void ivtv_video_set_io(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
deleted file mode 100644
index f08ec17cc3dc..000000000000
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
- init/start/stop/exit stream functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* License: GPL
- * Author: Kevin Thayer <nufan_wfk at yahoo dot com>
- *
- * This file will hold API related functions, both internal (firmware api)
- * and external (v4l2, etc)
- *
- * -----
- * MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
- * and Takeru KOMORIYA<komoriya@paken.org>
- *
- * AVerMedia M179 GPIO info by Chris Pinkham <cpinkham@bc2va.org>
- * using information provided by Jiun-Kuei Jung @ AVerMedia.
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-fileops.h"
-#include "ivtv-queue.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-irq.h"
-#include "ivtv-yuv.h"
-#include "ivtv-cards.h"
-#include "ivtv-streams.h"
-#include "ivtv-firmware.h"
-#include <media/v4l2-event.h>
-
-static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
- .owner = THIS_MODULE,
- .read = ivtv_v4l2_read,
- .write = ivtv_v4l2_write,
- .open = ivtv_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = ivtv_v4l2_close,
- .poll = ivtv_v4l2_enc_poll,
-};
-
-static const struct v4l2_file_operations ivtv_v4l2_dec_fops = {
- .owner = THIS_MODULE,
- .read = ivtv_v4l2_read,
- .write = ivtv_v4l2_write,
- .open = ivtv_v4l2_open,
- .unlocked_ioctl = video_ioctl2,
- .release = ivtv_v4l2_close,
- .poll = ivtv_v4l2_dec_poll,
-};
-
-#define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */
-#define IVTV_V4L2_ENC_PCM_OFFSET 24 /* offset from 0 to register pcm v4l2 minors on */
-#define IVTV_V4L2_ENC_YUV_OFFSET 32 /* offset from 0 to register yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_YUV_OFFSET 48 /* offset from 0 to register decoder yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_VBI_OFFSET 8 /* offset from 0 to register decoder vbi input v4l2 minors on */
-#define IVTV_V4L2_DEC_VOUT_OFFSET 16 /* offset from 0 to register vbi output v4l2 minors on */
-
-static struct {
- const char *name;
- int vfl_type;
- int num_offset;
- int dma, pio;
- enum v4l2_buf_type buf_type;
- u32 v4l2_caps;
- const struct v4l2_file_operations *fops;
-} ivtv_stream_info[] = {
- { /* IVTV_ENC_STREAM_TYPE_MPG */
- "encoder MPG",
- VFL_TYPE_GRABBER, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_YUV */
- "encoder YUV",
- VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_VBI */
- "encoder VBI",
- VFL_TYPE_VBI, 0,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER |
- V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_PCM */
- "encoder PCM",
- VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
- PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
- V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_ENC_STREAM_TYPE_RAD */
- "encoder radio",
- VFL_TYPE_RADIO, 0,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
- V4L2_CAP_RADIO | V4L2_CAP_TUNER,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_MPG */
- "decoder MPG",
- VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_VBI */
- "decoder VBI",
- VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
- V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE,
- &ivtv_v4l2_enc_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_VOUT */
- "decoder VOUT",
- VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
- PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
- V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- },
- { /* IVTV_DEC_STREAM_TYPE_YUV */
- "decoder YUV",
- VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
- PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
- V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
- &ivtv_v4l2_dec_fops
- }
-};
-
-static void ivtv_stream_init(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- struct video_device *vdev = s->vdev;
-
- /* we need to keep vdev, so restore it afterwards */
- memset(s, 0, sizeof(*s));
- s->vdev = vdev;
-
- /* initialize ivtv_stream fields */
- s->itv = itv;
- s->type = type;
- s->name = ivtv_stream_info[type].name;
- s->caps = ivtv_stream_info[type].v4l2_caps;
-
- if (ivtv_stream_info[type].pio)
- s->dma = PCI_DMA_NONE;
- else
- s->dma = ivtv_stream_info[type].dma;
- s->buf_size = itv->stream_buf_size[type];
- if (s->buf_size)
- s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size;
- spin_lock_init(&s->qlock);
- init_waitqueue_head(&s->waitq);
- s->sg_handle = IVTV_DMA_UNMAPPED;
- ivtv_queue_init(&s->q_free);
- ivtv_queue_init(&s->q_full);
- ivtv_queue_init(&s->q_dma);
- ivtv_queue_init(&s->q_predma);
- ivtv_queue_init(&s->q_io);
-}
-
-static int ivtv_prep_dev(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- int num_offset = ivtv_stream_info[type].num_offset;
- int num = itv->instance + ivtv_first_minor + num_offset;
-
- /* These four fields are always initialized. If vdev == NULL, then
- this stream is not in use. In that case no other fields but these
- four can be used. */
- s->vdev = NULL;
- s->itv = itv;
- s->type = type;
- s->name = ivtv_stream_info[type].name;
-
- /* Check whether the radio is supported */
- if (type == IVTV_ENC_STREAM_TYPE_RAD && !(itv->v4l2_cap & V4L2_CAP_RADIO))
- return 0;
- if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return 0;
-
- /* User explicitly selected 0 buffers for these streams, so don't
- create them. */
- if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
- itv->options.kilobytes[type] == 0) {
- IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
- return 0;
- }
-
- ivtv_stream_init(itv, type);
-
- /* allocate and initialize the v4l2 video device structure */
- s->vdev = video_device_alloc();
- if (s->vdev == NULL) {
- IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
- return -ENOMEM;
- }
-
- snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
- itv->v4l2_dev.name, s->name);
-
- s->vdev->num = num;
- s->vdev->v4l2_dev = &itv->v4l2_dev;
- s->vdev->fops = ivtv_stream_info[type].fops;
- s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
- s->vdev->release = video_device_release;
- s->vdev->tvnorms = V4L2_STD_ALL;
- s->vdev->lock = &itv->serialize_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
- ivtv_set_funcs(s->vdev);
- return 0;
-}
-
-/* Initialize v4l2 variables and prepare v4l2 devices */
-int ivtv_streams_setup(struct ivtv *itv)
-{
- int type;
-
- /* Setup V4L2 Devices */
- for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- /* Prepare device */
- if (ivtv_prep_dev(itv, type))
- break;
-
- if (itv->streams[type].vdev == NULL)
- continue;
-
- /* Allocate Stream */
- if (ivtv_stream_alloc(&itv->streams[type]))
- break;
- }
- if (type == IVTV_MAX_STREAMS)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv, 0);
- return -ENOMEM;
-}
-
-static int ivtv_reg_dev(struct ivtv *itv, int type)
-{
- struct ivtv_stream *s = &itv->streams[type];
- int vfl_type = ivtv_stream_info[type].vfl_type;
- const char *name;
- int num;
-
- if (s->vdev == NULL)
- return 0;
-
- num = s->vdev->num;
- /* card number + user defined offset + device offset */
- if (type != IVTV_ENC_STREAM_TYPE_MPG) {
- struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
-
- if (s_mpg->vdev)
- num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
- }
- video_set_drvdata(s->vdev, s);
-
- /* Register device. First try the desired minor, then any free one. */
- if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
- IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
- s->name, num);
- video_device_release(s->vdev);
- s->vdev = NULL;
- return -ENOMEM;
- }
- name = video_device_node_name(s->vdev);
-
- switch (vfl_type) {
- case VFL_TYPE_GRABBER:
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
- break;
- case VFL_TYPE_RADIO:
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- case VFL_TYPE_VBI:
- if (itv->options.kilobytes[type])
- IVTV_INFO("Registered device %s for %s (%d kB)\n",
- name, s->name, itv->options.kilobytes[type]);
- else
- IVTV_INFO("Registered device %s for %s\n",
- name, s->name);
- break;
- }
- return 0;
-}
-
-/* Register v4l2 devices */
-int ivtv_streams_register(struct ivtv *itv)
-{
- int type;
- int err = 0;
-
- /* Register V4L2 devices */
- for (type = 0; type < IVTV_MAX_STREAMS; type++)
- err |= ivtv_reg_dev(itv, type);
-
- if (err == 0)
- return 0;
-
- /* One or more streams could not be initialized. Clean 'em all up. */
- ivtv_streams_cleanup(itv, 1);
- return -ENOMEM;
-}
-
-/* Unregister v4l2 devices */
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
-{
- int type;
-
- /* Teardown all streams */
- for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- struct video_device *vdev = itv->streams[type].vdev;
-
- itv->streams[type].vdev = NULL;
- if (vdev == NULL)
- continue;
-
- ivtv_stream_free(&itv->streams[type]);
- /* Unregister or release device */
- if (unregister)
- video_unregister_device(vdev);
- else
- video_device_release(vdev);
- }
-}
-
-static void ivtv_vbi_setup(struct ivtv *itv)
-{
- int raw = ivtv_raw_vbi(itv);
- u32 data[CX2341X_MBOX_MAX_DATA];
- int lines;
- int i;
-
- /* Reset VBI */
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
-
- /* setup VBI registers */
- if (raw)
- v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &itv->vbi.in.fmt.vbi);
- else
- v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, &itv->vbi.in.fmt.sliced);
-
- /* determine number of lines and total number of VBI bytes.
- A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1
- The '- 1' byte is probably an unused U or V byte. Or something...
- A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
- header, 42 data bytes + checksum (to be confirmed) */
- if (raw) {
- lines = itv->vbi.count * 2;
- } else {
- lines = itv->is_60hz ? 24 : 38;
- if (itv->is_60hz && (itv->hw_flags & IVTV_HW_CX25840))
- lines += 2;
- }
-
- itv->vbi.enc_size = lines * (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
-
- /* Note: sliced vs raw flag doesn't seem to have any effect
- TODO: check mode (0x02) value with older ivtv versions. */
- data[0] = raw | 0x02 | (0xbd << 8);
-
- /* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
- data[1] = 1;
- /* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
- data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size);
- /* The start/stop codes determine which VBI lines end up in the raw VBI data area.
- The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
- is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
- code. These values for raw VBI are obtained from a driver disassembly. The sliced
- start/stop codes was deduced from this, but they do not appear in the driver.
- Other code pairs that I found are: 0x250E6249/0x13545454 and 0x25256262/0x38137F54.
- However, I have no idea what these values are for. */
- if (itv->hw_flags & IVTV_HW_CX25840) {
- /* Setup VBI for the cx25840 digitizer */
- if (raw) {
- data[3] = 0x20602060;
- data[4] = 0x30703070;
- } else {
- data[3] = 0xB0F0B0F0;
- data[4] = 0xA0E0A0E0;
- }
- /* Lines per frame */
- data[5] = lines;
- /* bytes per line */
- data[6] = (raw ? itv->vbi.raw_size : itv->vbi.sliced_size);
- } else {
- /* Setup VBI for the saa7115 digitizer */
- if (raw) {
- data[3] = 0x25256262;
- data[4] = 0x387F7F7F;
- } else {
- data[3] = 0xABABECEC;
- data[4] = 0xB6F1F1F1;
- }
- /* Lines per frame */
- data[5] = lines;
- /* bytes per line */
- data[6] = itv->vbi.enc_size / lines;
- }
-
- IVTV_DEBUG_INFO(
- "Setup VBI API header 0x%08x pkts %d buffs %d ln %d sz %d\n",
- data[0], data[1], data[2], data[5], data[6]);
-
- ivtv_api(itv, CX2341X_ENC_SET_VBI_CONFIG, 7, data);
-
- /* returns the VBI encoder memory area. */
- itv->vbi.enc_start = data[2];
- itv->vbi.fpi = data[0];
- if (!itv->vbi.fpi)
- itv->vbi.fpi = 1;
-
- IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d\n",
- itv->vbi.enc_start, data[1], itv->vbi.fpi);
-
- /* select VBI lines.
- Note that the sliced argument seems to have no effect. */
- for (i = 2; i <= 24; i++) {
- int valid;
-
- if (itv->is_60hz) {
- valid = i >= 10 && i < 22;
- } else {
- valid = i >= 6 && i < 24;
- }
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, i - 1,
- valid, 0 , 0, 0);
- ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, (i - 1) | 0x80000000,
- valid, 0, 0, 0);
- }
-
- /* Remaining VBI questions:
- - Is it possible to select particular VBI lines only for inclusion in the MPEG
- stream? Currently you can only get the first X lines.
- - Is mixed raw and sliced VBI possible?
- - What's the meaning of the raw/sliced flag?
- - What's the meaning of params 2, 3 & 4 of the Select VBI command? */
-}
-
-int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv *itv = s->itv;
- int captype = 0, subtype = 0;
- int enable_passthrough = 0;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
-
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_MPG:
- captype = 0;
- subtype = 3;
-
- /* Stop Passthrough */
- if (itv->output_mode == OUT_PASSTHROUGH) {
- ivtv_passthrough_mode(itv, 0);
- enable_passthrough = 1;
- }
- itv->mpg_data_received = itv->vbi_data_inserted = 0;
- itv->dualwatch_jiffies = jiffies;
- itv->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
- itv->search_pack_header = 0;
- break;
-
- case IVTV_ENC_STREAM_TYPE_YUV:
- if (itv->output_mode == OUT_PASSTHROUGH) {
- captype = 2;
- subtype = 11; /* video+audio+decoder */
- break;
- }
- captype = 1;
- subtype = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_PCM:
- captype = 1;
- subtype = 2;
- break;
- case IVTV_ENC_STREAM_TYPE_VBI:
- captype = 1;
- subtype = 4;
-
- itv->vbi.frame = 0;
- itv->vbi.inserted_frame = 0;
- memset(itv->vbi.sliced_mpeg_size,
- 0, sizeof(itv->vbi.sliced_mpeg_size));
- break;
- default:
- return -EINVAL;
- }
- s->subtype = subtype;
- s->buffers_stolen = 0;
-
- /* Clear Streamoff flags in case left from last capture */
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- if (atomic_read(&itv->capturing) == 0) {
- int digitizer;
-
- /* Always use frame based mode. Experiments have demonstrated that byte
- stream based mode results in dropped frames and corruption. Not often,
- but occasionally. Many thanks go to Leonard Orb who spent a lot of
- effort and time trying to trace the cause of the drop outs. */
- /* 1 frame per DMA */
- /*ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 128, 0); */
- ivtv_vapi(itv, CX2341X_ENC_SET_DMA_BLOCK_SIZE, 2, 1, 1);
-
- /* Stuff from Windows, we don't know what it is */
- ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1, 0);
- /* According to the docs, this should be correct. However, this is
- untested. I don't dare enable this without having tested it.
- Only very few old cards actually have this hardware combination.
- ivtv_vapi(itv, CX2341X_ENC_SET_VERT_CROP_LINE, 1,
- ((itv->hw_flags & IVTV_HW_SAA7114) && itv->is_60hz) ? 10001 : 0);
- */
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 3, !itv->has_cx23415);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 8, 0);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 2, 4, 1);
- ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
-
- /* assign placeholder */
- ivtv_vapi(itv, CX2341X_ENC_SET_PLACEHOLDER, 12,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
- digitizer = 0xF1;
- else if (itv->card->hw_all & IVTV_HW_SAA7114)
- digitizer = 0xEF;
- else /* cx25840 */
- digitizer = 0x140;
-
- ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, digitizer, digitizer);
-
- /* Setup VBI */
- if (itv->v4l2_cap & V4L2_CAP_VBI_CAPTURE) {
- ivtv_vbi_setup(itv);
- }
-
- /* assign program index info. Mask 7: select I/P/B, Num_req: 400 max */
- ivtv_vapi_result(itv, data, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 7, 400);
- itv->pgm_info_offset = data[0];
- itv->pgm_info_num = data[1];
- itv->pgm_info_write_idx = 0;
- itv->pgm_info_read_idx = 0;
-
- IVTV_DEBUG_INFO("PGM Index at 0x%08x with %d elements\n",
- itv->pgm_info_offset, itv->pgm_info_num);
-
- /* Setup API for Stream */
- cx2341x_handler_setup(&itv->cxhdl);
-
- /* mute if capturing radio */
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
- ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
- 1 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
- }
-
- /* Vsync Setup */
- if (itv->has_cx23415 && !test_and_set_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
- /* event notification (on) */
- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_ENC_VIM_RST, -1);
- ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
- }
-
- if (atomic_read(&itv->capturing) == 0) {
- /* Clear all Pending Interrupts */
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
-
- clear_bit(IVTV_F_I_EOS, &itv->i_flags);
-
- cx2341x_handler_set_busy(&itv->cxhdl, 1);
-
- /* Initialize Digitizer for Capture */
- /* Avoid tinny audio problem - ensure audio clocks are going */
- v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
- /* Avoid unpredictable PCI bus hang - disable video clocks */
- v4l2_subdev_call(itv->sd_video, video, s_stream, 0);
- ivtv_msleep_timeout(300, 0);
- ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
- v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
- }
-
- /* begin_capture */
- if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
- {
- IVTV_DEBUG_WARN( "Error starting capture!\n");
- return -EINVAL;
- }
-
- /* Start Passthrough */
- if (enable_passthrough) {
- ivtv_passthrough_mode(itv, 1);
- }
-
- if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
- ivtv_clear_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
- else
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
-
- /* you're live! sit back and await interrupts :) */
- atomic_inc(&itv->capturing);
- return 0;
-}
-
-static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- struct ivtv *itv = s->itv;
- int datatype;
- u16 width;
- u16 height;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
-
- width = itv->cxhdl.width;
- height = itv->cxhdl.height;
-
- /* set audio mode to left/stereo for dual/stereo mode. */
- ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
-
- /* set number of internal decoder buffers */
- ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0);
-
- /* prebuffering */
- ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1);
-
- /* extract from user packets */
- ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1);
- itv->vbi.dec_start = data[0];
-
- IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n",
- itv->vbi.dec_start, data[1]);
-
- /* set decoder source settings */
- /* Data type: 0 = mpeg from host,
- 1 = yuv from encoder,
- 2 = yuv_from_host */
- switch (s->type) {
- case IVTV_DEC_STREAM_TYPE_YUV:
- if (itv->output_mode == OUT_PASSTHROUGH) {
- datatype = 1;
- } else {
- /* Fake size to avoid switching video standard */
- datatype = 2;
- width = 720;
- height = itv->is_out_50hz ? 576 : 480;
- }
- IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype);
- break;
- case IVTV_DEC_STREAM_TYPE_MPG:
- default:
- datatype = 0;
- break;
- }
- if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
- width, height, itv->cxhdl.audio_properties)) {
- IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
- }
-
- /* Decoder sometimes dies here, so wait a moment */
- ivtv_msleep_timeout(10, 0);
-
- /* Known failure point for firmware, so check */
- return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream");
-}
-
-int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
-{
- struct ivtv *itv = s->itv;
- int rc;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
- return 0; /* already started */
-
- IVTV_DEBUG_INFO("Starting decode stream %s (gop_offset %d)\n", s->name, gop_offset);
-
- rc = ivtv_setup_v4l2_decode_stream(s);
- if (rc < 0) {
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- return rc;
- }
-
- /* set dma size to 65536 bytes */
- ivtv_vapi(itv, CX2341X_DEC_SET_DMA_BLOCK_SIZE, 1, 65536);
-
- /* Clear Streamoff */
- clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
- /* Zero out decoder counters */
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[0]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[1]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[2]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[3]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[0]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[1]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[2]);
- writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[3]);
-
- /* turn on notification of dual/stereo mode change */
- ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 1, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
-
- /* start playback */
- ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, gop_offset, 0);
-
- /* Let things settle before we actually start */
- ivtv_msleep_timeout(10, 0);
-
- /* Clear the following Interrupt mask bits for decoding */
- ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
- IVTV_DEBUG_IRQ("IRQ Mask is now: 0x%08x\n", itv->irqmask);
-
- /* you're live! sit back and await interrupts :) */
- atomic_inc(&itv->decoding);
- return 0;
-}
-
-void ivtv_stop_all_captures(struct ivtv *itv)
-{
- int i;
-
- for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
- struct ivtv_stream *s = &itv->streams[i];
-
- if (s->vdev == NULL)
- continue;
- if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
- ivtv_stop_v4l2_encode_stream(s, 0);
- }
- }
-}
-
-int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
-{
- struct ivtv *itv = s->itv;
- DECLARE_WAITQUEUE(wait, current);
- int cap_type;
- int stopmode;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- /* This function assumes that you are allowed to stop the capture
- and that we are actually capturing */
-
- IVTV_DEBUG_INFO("Stop Capture\n");
-
- if (s->type == IVTV_DEC_STREAM_TYPE_VOUT)
- return 0;
- if (atomic_read(&itv->capturing) == 0)
- return 0;
-
- switch (s->type) {
- case IVTV_ENC_STREAM_TYPE_YUV:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_PCM:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_VBI:
- cap_type = 1;
- break;
- case IVTV_ENC_STREAM_TYPE_MPG:
- default:
- cap_type = 0;
- break;
- }
-
- /* Stop Capture Mode */
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
- stopmode = 0;
- } else {
- stopmode = 1;
- }
-
- /* end_capture */
- /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
-
- if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
- if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
- /* only run these if we're shutting down the last cap */
- unsigned long duration;
- unsigned long then = jiffies;
-
- add_wait_queue(&itv->eos_waitq, &wait);
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* wait 2s for EOS interrupt */
- while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) &&
- time_before(jiffies,
- then + msecs_to_jiffies(2000))) {
- schedule_timeout(msecs_to_jiffies(10));
- }
-
- /* To convert jiffies to ms, we must multiply by 1000
- * and divide by HZ. To avoid runtime division, we
- * convert this to multiplication by 1000/HZ.
- * Since integer division truncates, we get the best
- * accuracy if we do a rounding calculation of the constant.
- * Think of the case where HZ is 1024.
- */
- duration = ((1000 + HZ / 2) / HZ) * (jiffies - then);
-
- if (!test_bit(IVTV_F_I_EOS, &itv->i_flags)) {
- IVTV_DEBUG_WARN("%s: EOS interrupt not received! stopping anyway.\n", s->name);
- IVTV_DEBUG_WARN("%s: waited %lu ms.\n", s->name, duration);
- } else {
- IVTV_DEBUG_INFO("%s: EOS took %lu ms to occur.\n", s->name, duration);
- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&itv->eos_waitq, &wait);
- set_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
- }
-
- /* Handle any pending interrupts */
- ivtv_msleep_timeout(100, 0);
- }
-
- atomic_dec(&itv->capturing);
-
- /* Clear capture and no-read bits */
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
-
- if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
-
- if (atomic_read(&itv->capturing) > 0) {
- return 0;
- }
-
- cx2341x_handler_set_busy(&itv->cxhdl, 0);
-
- /* Set the following Interrupt mask bits for capture */
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
- del_timer(&itv->dma_timer);
-
- /* event notification (off) */
- if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
- /* type: 0 = refresh */
- /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */
- ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1);
- ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST);
- }
-
- /* Raw-passthrough is implied on start. Make sure it's stopped so
- the encoder will re-initialize when next started */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 7);
-
- wake_up(&s->waitq);
-
- return 0;
-}
-
-int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
-{
- static const struct v4l2_event ev = {
- .type = V4L2_EVENT_EOS,
- };
- struct ivtv *itv = s->itv;
-
- if (s->vdev == NULL)
- return -EINVAL;
-
- if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
- return -EINVAL;
-
- if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
- return 0;
-
- IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
-
- /* Stop Decoder */
- if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) {
- u32 tmp = 0;
-
- /* Wait until the decoder is no longer running */
- if (pts) {
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3,
- 0, (u32)(pts & 0xffffffff), (u32)(pts >> 32));
- }
- while (1) {
- u32 data[CX2341X_MBOX_MAX_DATA];
- ivtv_vapi_result(itv, data, CX2341X_DEC_GET_XFER_INFO, 0);
- if (s->q_full.buffers + s->q_dma.buffers == 0) {
- if (tmp == data[3])
- break;
- tmp = data[3];
- }
- if (ivtv_msleep_timeout(100, 1))
- break;
- }
- }
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0);
-
- /* turn off notification of dual/stereo mode change */
- ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
-
- ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
- del_timer(&itv->dma_timer);
-
- clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- ivtv_flush_queues(s);
-
- /* decoder needs time to settle */
- ivtv_msleep_timeout(40, 0);
-
- /* decrement decoding */
- atomic_dec(&itv->decoding);
-
- set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags);
- wake_up(&itv->event_waitq);
- v4l2_event_queue(s->vdev, &ev);
-
- /* wake up wait queues */
- wake_up(&s->waitq);
-
- return 0;
-}
-
-int ivtv_passthrough_mode(struct ivtv *itv, int enable)
-{
- struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
- struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
-
- if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
- return -EINVAL;
-
- IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
-
- /* Prevent others from starting/stopping streams while we
- initiate/terminate passthrough mode */
- if (enable) {
- if (itv->output_mode == OUT_PASSTHROUGH) {
- return 0;
- }
- if (ivtv_set_output_mode(itv, OUT_PASSTHROUGH) != OUT_PASSTHROUGH)
- return -EBUSY;
-
- /* Fully initialize stream, and then unflag init */
- set_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
- set_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
-
- /* Setup YUV Decoder */
- ivtv_setup_v4l2_decode_stream(dec_stream);
-
- /* Start Decoder */
- ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 1);
- atomic_inc(&itv->decoding);
-
- /* Setup capture if not already done */
- if (atomic_read(&itv->capturing) == 0) {
- cx2341x_handler_setup(&itv->cxhdl);
- cx2341x_handler_set_busy(&itv->cxhdl, 1);
- }
-
- /* Start Passthrough Mode */
- ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, 2, 11);
- atomic_inc(&itv->capturing);
- return 0;
- }
-
- if (itv->output_mode != OUT_PASSTHROUGH)
- return 0;
-
- /* Stop Passthrough Mode */
- ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, 1, 2, 11);
- ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, 1, 0, 0);
-
- atomic_dec(&itv->capturing);
- atomic_dec(&itv->decoding);
- clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
- clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
- itv->output_mode = OUT_NONE;
- if (atomic_read(&itv->capturing) == 0)
- cx2341x_handler_set_busy(&itv->cxhdl, 0);
-
- return 0;
-}
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
deleted file mode 100644
index a653a5136417..000000000000
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- init/start/stop/exit stream functions
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_STREAMS_H
-#define IVTV_STREAMS_H
-
-int ivtv_streams_setup(struct ivtv *itv);
-int ivtv_streams_register(struct ivtv *itv);
-void ivtv_streams_cleanup(struct ivtv *itv, int unregister);
-
-/* Capture related */
-int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s);
-int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end);
-int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset);
-int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts);
-
-void ivtv_stop_all_captures(struct ivtv *itv);
-int ivtv_passthrough_mode(struct ivtv *itv, int enable);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
deleted file mode 100644
index 7338cb2d0a38..000000000000
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- User DMA
-
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-udma.h"
-
-void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size)
-{
- dma_page->uaddr = first & PAGE_MASK;
- dma_page->offset = first & ~PAGE_MASK;
- dma_page->tail = 1 + ((first+size-1) & ~PAGE_MASK);
- dma_page->first = (first & PAGE_MASK) >> PAGE_SHIFT;
- dma_page->last = ((first+size-1) & PAGE_MASK) >> PAGE_SHIFT;
- dma_page->page_count = dma_page->last - dma_page->first + 1;
- if (dma_page->page_count == 1) dma_page->tail -= dma_page->offset;
-}
-
-int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset)
-{
- int i, offset;
- unsigned long flags;
-
- if (map_offset < 0)
- return map_offset;
-
- offset = dma_page->offset;
-
- /* Fill SG Array with new values */
- for (i = 0; i < dma_page->page_count; i++) {
- unsigned int len = (i == dma_page->page_count - 1) ?
- dma_page->tail : PAGE_SIZE - offset;
-
- if (PageHighMem(dma->map[map_offset])) {
- void *src;
-
- if (dma->bouncemap[map_offset] == NULL)
- dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL);
- if (dma->bouncemap[map_offset] == NULL)
- return -1;
- local_irq_save(flags);
- src = kmap_atomic(dma->map[map_offset]) + offset;
- memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
- kunmap_atomic(src);
- local_irq_restore(flags);
- sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset);
- }
- else {
- sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset);
- }
- offset = 0;
- map_offset++;
- }
- return map_offset;
-}
-
-void ivtv_udma_fill_sg_array (struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split) {
- int i;
- struct scatterlist *sg;
-
- for (i = 0, sg = dma->SGlist; i < dma->SG_length; i++, sg++) {
- dma->SGarray[i].size = cpu_to_le32(sg_dma_len(sg));
- dma->SGarray[i].src = cpu_to_le32(sg_dma_address(sg));
- dma->SGarray[i].dst = cpu_to_le32(buffer_offset);
- buffer_offset += sg_dma_len(sg);
-
- split -= sg_dma_len(sg);
- if (split == 0)
- buffer_offset = buffer_offset_2;
- }
-}
-
-/* User DMA Buffers */
-void ivtv_udma_alloc(struct ivtv *itv)
-{
- if (itv->udma.SG_handle == 0) {
- /* Map DMA Page Array Buffer */
- itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
- ivtv_udma_sync_for_cpu(itv);
- }
-}
-
-int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
- void __user *userbuf, int size_in_bytes)
-{
- struct ivtv_dma_page_info user_dma;
- struct ivtv_user_dma *dma = &itv->udma;
- int i, err;
-
- IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr);
-
- /* Still in USE */
- if (dma->SG_length || dma->page_count) {
- IVTV_DEBUG_WARN("ivtv_udma_setup: SG_length %d page_count %d still full?\n",
- dma->SG_length, dma->page_count);
- return -EBUSY;
- }
-
- ivtv_udma_get_page_info(&user_dma, (unsigned long)userbuf, size_in_bytes);
-
- if (user_dma.page_count <= 0) {
- IVTV_DEBUG_WARN("ivtv_udma_setup: Error %d page_count from %d bytes %d offset\n",
- user_dma.page_count, size_in_bytes, user_dma.offset);
- return -EINVAL;
- }
-
- /* Get user pages for DMA Xfer */
- down_read(&current->mm->mmap_sem);
- err = get_user_pages(current, current->mm,
- user_dma.uaddr, user_dma.page_count, 0, 1, dma->map, NULL);
- up_read(&current->mm->mmap_sem);
-
- if (user_dma.page_count != err) {
- IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
- err, user_dma.page_count);
- if (err >= 0) {
- for (i = 0; i < err; i++)
- put_page(dma->map[i]);
- return -EINVAL;
- }
- return err;
- }
-
- dma->page_count = user_dma.page_count;
-
- /* Fill SG List with new values */
- if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
- return -ENOMEM;
- }
-
- /* Map SG List */
- dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
-
- /* Fill SG Array with new values */
- ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
-
- /* Tag SG Array with Interrupt Bit */
- dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
-
- ivtv_udma_sync_for_device(itv);
- return dma->page_count;
-}
-
-void ivtv_udma_unmap(struct ivtv *itv)
-{
- struct ivtv_user_dma *dma = &itv->udma;
- int i;
-
- IVTV_DEBUG_INFO("ivtv_unmap_user_dma\n");
-
- /* Nothing to free */
- if (dma->page_count == 0)
- return;
-
- /* Unmap Scatterlist */
- if (dma->SG_length) {
- pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
- dma->SG_length = 0;
- }
- /* sync DMA */
- ivtv_udma_sync_for_cpu(itv);
-
- /* Release User Pages */
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
-}
-
-void ivtv_udma_free(struct ivtv *itv)
-{
- int i;
-
- /* Unmap SG Array */
- if (itv->udma.SG_handle) {
- pci_unmap_single(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
- }
-
- /* Unmap Scatterlist */
- if (itv->udma.SG_length) {
- pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
- }
-
- for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
- if (itv->udma.bouncemap[i])
- __free_page(itv->udma.bouncemap[i]);
- }
-}
-
-void ivtv_udma_start(struct ivtv *itv)
-{
- IVTV_DEBUG_DMA("start UDMA\n");
- write_reg(itv->udma.SG_handle, IVTV_REG_DECDMAADDR);
- write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
- set_bit(IVTV_F_I_DMA, &itv->i_flags);
- set_bit(IVTV_F_I_UDMA, &itv->i_flags);
- clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
-}
-
-void ivtv_udma_prepare(struct ivtv *itv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&itv->dma_reg_lock, flags);
- if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
- ivtv_udma_start(itv);
- else
- set_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags);
- spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
-}
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
deleted file mode 100644
index ee3c9efb5b72..000000000000
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
- Copyright (C) 2006-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_UDMA_H
-#define IVTV_UDMA_H
-
-/* User DMA functions */
-void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size);
-int ivtv_udma_fill_sg_list(struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset);
-void ivtv_udma_fill_sg_array(struct ivtv_user_dma *dma, u32 buffer_offset, u32 buffer_offset_2, u32 split);
-int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
- void __user *userbuf, int size_in_bytes);
-void ivtv_udma_unmap(struct ivtv *itv);
-void ivtv_udma_free(struct ivtv *itv);
-void ivtv_udma_alloc(struct ivtv *itv);
-void ivtv_udma_prepare(struct ivtv *itv);
-void ivtv_udma_start(struct ivtv *itv);
-
-static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
-{
- pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
-}
-
-static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
-{
- pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
- sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
-}
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
deleted file mode 100644
index 293db806d936..000000000000
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-i2c.h"
-#include "ivtv-ioctl.h"
-#include "ivtv-queue.h"
-#include "ivtv-cards.h"
-#include "ivtv-vbi.h"
-
-static void ivtv_set_vps(struct ivtv *itv, int enabled)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- data.id = V4L2_SLICED_VPS;
- data.field = 0;
- data.line = enabled ? 16 : 0;
- data.data[2] = itv->vbi.vps_payload.data[0];
- data.data[8] = itv->vbi.vps_payload.data[1];
- data.data[9] = itv->vbi.vps_payload.data[2];
- data.data[10] = itv->vbi.vps_payload.data[3];
- data.data[11] = itv->vbi.vps_payload.data[4];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- data.id = V4L2_SLICED_CAPTION_525;
- data.field = 0;
- data.line = (mode & 1) ? 21 : 0;
- data.data[0] = cc->odd[0];
- data.data[1] = cc->odd[1];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
- data.field = 1;
- data.line = (mode & 2) ? 21 : 0;
- data.data[0] = cc->even[0];
- data.data[1] = cc->even[1];
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
-{
- struct v4l2_sliced_vbi_data data;
-
- if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
- return;
- /* When using a 50 Hz system, always turn on the
- wide screen signal with 4x3 ratio as the default.
- Turning this signal on and off can confuse certain
- TVs. As far as I can tell there is no reason not to
- transmit this signal. */
- if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
- enabled = 1;
- mode = 0x08; /* 4x3 full format */
- }
- data.id = V4L2_SLICED_WSS_625;
- data.field = 0;
- data.line = enabled ? 23 : 0;
- data.data[0] = mode & 0xff;
- data.data[1] = (mode >> 8) & 0xff;
- ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
-}
-
-static int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static void ivtv_write_vbi_line(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data *d,
- struct vbi_cc *cc, int *found_cc)
-{
- struct vbi_info *vi = &itv->vbi;
-
- if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
- if (d->field) {
- cc->even[0] = d->data[0];
- cc->even[1] = d->data[1];
- } else {
- cc->odd[0] = d->data[0];
- cc->odd[1] = d->data[1];
- }
- *found_cc = 1;
- } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
- struct vbi_vps vps;
-
- vps.data[0] = d->data[2];
- vps.data[1] = d->data[8];
- vps.data[2] = d->data[9];
- vps.data[3] = d->data[10];
- vps.data[4] = d->data[11];
- if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
- vi->vps_payload = vps;
- set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
- }
- } else if (d->id == V4L2_SLICED_WSS_625 &&
- d->line == 23 && d->field == 0) {
- int wss = d->data[0] | d->data[1] << 8;
-
- if (vi->wss_payload != wss) {
- vi->wss_payload = wss;
- set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
- }
- }
-}
-
-static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
-{
- struct vbi_info *vi = &itv->vbi;
-
- if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
- memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
- sizeof(struct vbi_cc));
- vi->cc_payload_idx++;
- set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- }
-}
-
-static void ivtv_write_vbi(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data *sliced,
- size_t cnt)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
- int found_cc = 0;
- size_t i;
-
- for (i = 0; i < cnt; i++)
- ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
-
- if (found_cc)
- ivtv_write_vbi_cc_lines(itv, &cc);
-}
-
-ssize_t
-ivtv_write_vbi_from_user(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data __user *sliced,
- size_t cnt)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
- int found_cc = 0;
- size_t i;
- struct v4l2_sliced_vbi_data d;
- ssize_t ret = cnt * sizeof(struct v4l2_sliced_vbi_data);
-
- for (i = 0; i < cnt; i++) {
- if (copy_from_user(&d, sliced + i,
- sizeof(struct v4l2_sliced_vbi_data))) {
- ret = -EFAULT;
- break;
- }
- ivtv_write_vbi_line(itv, &d, &cc, &found_cc);
- }
-
- if (found_cc)
- ivtv_write_vbi_cc_lines(itv, &cc);
-
- return ret;
-}
-
-static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
-{
- int line = 0;
- int i;
- u32 linemask[2] = { 0, 0 };
- unsigned short size;
- static const u8 mpeg_hdr_data[] = {
- 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
- 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
- 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
- };
- const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
- int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
- u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
-
- for (i = 0; i < lines; i++) {
- int f, l;
-
- if (itv->vbi.sliced_data[i].id == 0)
- continue;
-
- l = itv->vbi.sliced_data[i].line - 6;
- f = itv->vbi.sliced_data[i].field;
- if (f)
- l += 18;
- if (l < 32)
- linemask[0] |= (1 << l);
- else
- linemask[1] |= (1 << (l - 32));
- dst[sd + 12 + line * 43] =
- ivtv_service2vbi(itv->vbi.sliced_data[i].id);
- memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
- line++;
- }
- memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
- if (line == 36) {
- /* All lines are used, so there is no space for the linemask
- (the max size of the VBI data is 36 * 43 + 4 bytes).
- So in this case we use the magic number 'ITV0'. */
- memcpy(dst + sd, "ITV0", 4);
- memcpy(dst + sd + 4, dst + sd + 12, line * 43);
- size = 4 + ((43 * line + 3) & ~3);
- } else {
- memcpy(dst + sd, "itv0", 4);
- cpu_to_le32s(&linemask[0]);
- cpu_to_le32s(&linemask[1]);
- memcpy(dst + sd + 4, &linemask[0], 8);
- size = 12 + ((43 * line + 3) & ~3);
- }
- dst[4+16] = (size + 10) >> 8;
- dst[5+16] = (size + 10) & 0xff;
- dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
- dst[10+16] = (pts_stamp >> 22) & 0xff;
- dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
- dst[12+16] = (pts_stamp >> 7) & 0xff;
- dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
- itv->vbi.sliced_mpeg_size[idx] = sd + size;
-}
-
-static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
-{
- u32 linemask[2];
- int i, l, id2;
- int line = 0;
-
- if (!memcmp(p, "itv0", 4)) {
- memcpy(linemask, p + 4, 8);
- p += 12;
- } else if (!memcmp(p, "ITV0", 4)) {
- linemask[0] = 0xffffffff;
- linemask[1] = 0xf;
- p += 4;
- } else {
- /* unknown VBI data, convert to empty VBI frame */
- linemask[0] = linemask[1] = 0;
- }
- for (i = 0; i < 36; i++) {
- int err = 0;
-
- if (i < 32 && !(linemask[0] & (1 << i)))
- continue;
- if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
- continue;
- id2 = *p & 0xf;
- switch (id2) {
- case IVTV_SLICED_TYPE_TELETEXT_B:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case IVTV_SLICED_TYPE_CAPTION_525:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[1]) || !odd_parity(p[2]);
- break;
- case IVTV_SLICED_TYPE_VPS:
- id2 = V4L2_SLICED_VPS;
- break;
- case IVTV_SLICED_TYPE_WSS_625:
- id2 = V4L2_SLICED_WSS_625;
- break;
- default:
- id2 = 0;
- break;
- }
- if (err == 0) {
- l = (i < 18) ? i + 6 : i - 18 + 6;
- itv->vbi.sliced_dec_data[line].line = l;
- itv->vbi.sliced_dec_data[line].field = i >= 18;
- itv->vbi.sliced_dec_data[line].id = id2;
- memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
- line++;
- }
- p += 43;
- }
- while (line < 36) {
- itv->vbi.sliced_dec_data[line].id = 0;
- itv->vbi.sliced_dec_data[line].line = 0;
- itv->vbi.sliced_dec_data[line].field = 0;
- line++;
- }
- return line * sizeof(itv->vbi.sliced_dec_data[0]);
-}
-
-/* Compress raw VBI format, removes leading SAV codes and surplus space after the
- field.
- Returns new compressed size. */
-static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
-{
- u32 line_size = itv->vbi.raw_decoder_line_size;
- u32 lines = itv->vbi.count;
- u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
- u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
- u8 *q = buf;
- u8 *p;
- int i;
-
- for (i = 0; i < lines; i++) {
- p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
- break;
- }
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
- }
- return lines * (line_size - 4);
-}
-
-
-/* Compressed VBI format, all found sliced blocks put next to one another
- Returns new compressed size */
-static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
-{
- u32 line_size = itv->vbi.sliced_decoder_line_size;
- struct v4l2_decode_vbi_line vbi;
- int i;
- unsigned lines = 0;
-
- /* find the first valid line */
- for (i = 0; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
- break;
- }
-
- size -= i;
- if (size < line_size) {
- return line;
- }
- for (i = 0; i < size / line_size; i++) {
- u8 *p = buf + i * line_size;
-
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
- continue;
- }
- vbi.p = p + 4;
- v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
- if (vbi.type && !(lines & (1 << vbi.line))) {
- lines |= 1 << vbi.line;
- itv->vbi.sliced_data[line].id = vbi.type;
- itv->vbi.sliced_data[line].field = vbi.is_second_field;
- itv->vbi.sliced_data[line].line = vbi.line;
- memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
- line++;
- }
- }
- return line;
-}
-
-void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
- u64 pts_stamp, int streamtype)
-{
- u8 *p = (u8 *) buf->buf;
- u32 size = buf->bytesused;
- int y;
-
- /* Raw VBI data */
- if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
- u8 type;
-
- ivtv_buf_swap(buf);
-
- type = p[3];
-
- size = buf->bytesused = compress_raw_buf(itv, p, size);
-
- /* second field of the frame? */
- if (type == itv->vbi.raw_decoder_sav_even_field) {
- /* Dirty hack needed for backwards
- compatibility of old VBI software. */
- p += size - 4;
- memcpy(p, &itv->vbi.frame, 4);
- itv->vbi.frame++;
- }
- return;
- }
-
- /* Sliced VBI data with data insertion */
- if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
- int lines;
-
- ivtv_buf_swap(buf);
-
- /* first field */
- lines = compress_sliced_buf(itv, 0, p, size / 2,
- itv->vbi.sliced_decoder_sav_odd_field);
- /* second field */
- /* experimentation shows that the second half does not always begin
- at the exact address. So start a bit earlier (hence 32). */
- lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
- itv->vbi.sliced_decoder_sav_even_field);
- /* always return at least one empty line */
- if (lines == 0) {
- itv->vbi.sliced_data[0].id = 0;
- itv->vbi.sliced_data[0].line = 0;
- itv->vbi.sliced_data[0].field = 0;
- lines = 1;
- }
- buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
- memcpy(p, &itv->vbi.sliced_data[0], size);
-
- if (itv->vbi.insert_mpeg) {
- copy_vbi_data(itv, lines, pts_stamp);
- }
- itv->vbi.frame++;
- return;
- }
-
- /* Sliced VBI re-inserted from an MPEG stream */
- if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
- /* If the size is not 4-byte aligned, then the starting address
- for the swapping is also shifted. After swapping the data the
- real start address of the VBI data is exactly 4 bytes after the
- original start. It's a bit fiddly but it works like a charm.
- Non-4-byte alignment happens when an lseek is done on the input
- mpeg file to a non-4-byte aligned position. So on arrival here
- the VBI data is also non-4-byte aligned. */
- int offset = size & 3;
- int cnt;
-
- if (offset) {
- p += 4 - offset;
- }
- /* Swap Buffer */
- for (y = 0; y < size; y += 4) {
- swab32s((u32 *)(p + y));
- }
-
- cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
- memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
- buf->bytesused = cnt;
-
- ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
- cnt / sizeof(itv->vbi.sliced_dec_data[0]));
- return;
- }
-}
-
-void ivtv_disable_cc(struct ivtv *itv)
-{
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
-
- clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- ivtv_set_cc(itv, 0, &cc);
- itv->vbi.cc_payload_idx = 0;
-}
-
-
-void ivtv_vbi_work_handler(struct ivtv *itv)
-{
- struct vbi_info *vi = &itv->vbi;
- struct v4l2_sliced_vbi_data data;
- struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
-
- /* Lock */
- if (itv->output_mode == OUT_PASSTHROUGH) {
- if (itv->is_50hz) {
- data.id = V4L2_SLICED_WSS_625;
- data.field = 0;
-
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- ivtv_set_wss(itv, 1, data.data[0] & 0xf);
- vi->wss_missing_cnt = 0;
- } else if (vi->wss_missing_cnt == 4) {
- ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
- } else {
- vi->wss_missing_cnt++;
- }
- }
- else {
- int mode = 0;
-
- data.id = V4L2_SLICED_CAPTION_525;
- data.field = 0;
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- mode |= 1;
- cc.odd[0] = data.data[0];
- cc.odd[1] = data.data[1];
- }
- data.field = 1;
- if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
- mode |= 2;
- cc.even[0] = data.data[0];
- cc.even[1] = data.data[1];
- }
- if (mode) {
- vi->cc_missing_cnt = 0;
- ivtv_set_cc(itv, mode, &cc);
- } else if (vi->cc_missing_cnt == 4) {
- ivtv_set_cc(itv, 0, &cc);
- } else {
- vi->cc_missing_cnt++;
- }
- }
- return;
- }
-
- if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
- ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
- }
-
- if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
- if (vi->cc_payload_idx == 0) {
- clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
- ivtv_set_cc(itv, 3, &cc);
- }
- while (vi->cc_payload_idx) {
- cc = vi->cc_payload[0];
-
- memcpy(vi->cc_payload, vi->cc_payload + 1,
- sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
- vi->cc_payload_idx--;
- if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
- continue;
-
- ivtv_set_cc(itv, 3, &cc);
- break;
- }
- }
-
- if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
- ivtv_set_vps(itv, 1);
- }
-}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
deleted file mode 100644
index 166dd0b75d0f..000000000000
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Vertical Blank Interval support functions
- Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_VBI_H
-#define IVTV_VBI_H
-
-ssize_t
-ivtv_write_vbi_from_user(struct ivtv *itv,
- const struct v4l2_sliced_vbi_data __user *sliced,
- size_t count);
-void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
- u64 pts_stamp, int streamtype);
-int ivtv_used_line(struct ivtv *itv, int line, int field);
-void ivtv_disable_cc(struct ivtv *itv);
-void ivtv_set_vbi(unsigned long arg);
-void ivtv_vbi_work_handler(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
deleted file mode 100644
index a20f346fcad8..000000000000
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- ivtv driver version information
- Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_VERSION_H
-#define IVTV_VERSION_H
-
-#define IVTV_DRIVER_NAME "ivtv"
-#define IVTV_VERSION "1.4.3"
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
deleted file mode 100644
index 2ad65eb29832..000000000000
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- yuv support
-
- Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-udma.h"
-#include "ivtv-yuv.h"
-
-/* YUV buffer offsets */
-const u32 yuv_offset[IVTV_YUV_BUFFERS] = {
- 0x001a8600,
- 0x00240400,
- 0x002d8200,
- 0x00370000,
- 0x00029000,
- 0x000C0E00,
- 0x006B0400,
- 0x00748200
-};
-
-static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
- struct ivtv_dma_frame *args)
-{
- struct ivtv_dma_page_info y_dma;
- struct ivtv_dma_page_info uv_dma;
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- struct yuv_frame_info *f = &yi->new_frame_info[frame];
- int i;
- int y_pages, uv_pages;
- unsigned long y_buffer_offset, uv_buffer_offset;
- int y_decode_height, uv_decode_height, y_size;
-
- y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame];
- uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
-
- y_decode_height = uv_decode_height = f->src_h + f->src_y;
-
- if (f->offset_y)
- y_buffer_offset += 720 * 16;
-
- if (y_decode_height & 15)
- y_decode_height = (y_decode_height + 16) & ~15;
-
- if (uv_decode_height & 31)
- uv_decode_height = (uv_decode_height + 32) & ~31;
-
- y_size = 720 * y_decode_height;
-
- /* Still in USE */
- if (dma->SG_length || dma->page_count) {
- IVTV_DEBUG_WARN
- ("prep_user_dma: SG_length %d page_count %d still full?\n",
- dma->SG_length, dma->page_count);
- return -EBUSY;
- }
-
- ivtv_udma_get_page_info (&y_dma, (unsigned long)args->y_source, 720 * y_decode_height);
- ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height);
-
- /* Get user pages for DMA Xfer */
- down_read(&current->mm->mmap_sem);
- y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
- uv_pages = 0; /* silence gcc. value is set and consumed only if: */
- if (y_pages == y_dma.page_count) {
- uv_pages = get_user_pages(current, current->mm,
- uv_dma.uaddr, uv_dma.page_count, 0, 1,
- &dma->map[y_pages], NULL);
- }
- up_read(&current->mm->mmap_sem);
-
- if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
- int rc = -EFAULT;
-
- if (y_pages == y_dma.page_count) {
- IVTV_DEBUG_WARN
- ("failed to map uv user pages, returned %d "
- "expecting %d\n", uv_pages, uv_dma.page_count);
-
- if (uv_pages >= 0) {
- for (i = 0; i < uv_pages; i++)
- put_page(dma->map[y_pages + i]);
- rc = -EFAULT;
- } else {
- rc = uv_pages;
- }
- } else {
- IVTV_DEBUG_WARN
- ("failed to map y user pages, returned %d "
- "expecting %d\n", y_pages, y_dma.page_count);
- }
- if (y_pages >= 0) {
- for (i = 0; i < y_pages; i++)
- put_page(dma->map[i]);
- /*
- * Inherit the -EFAULT from rc's
- * initialization, but allow it to be
- * overriden by uv_pages above if it was an
- * actual errno.
- */
- } else {
- rc = y_pages;
- }
- return rc;
- }
-
- dma->page_count = y_pages + uv_pages;
-
- /* Fill & map SG List */
- if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
- IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
- for (i = 0; i < dma->page_count; i++) {
- put_page(dma->map[i]);
- }
- dma->page_count = 0;
- return -ENOMEM;
- }
- dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
-
- /* Fill SG Array with new values */
- ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
-
- /* If we've offset the y plane, ensure top area is blanked */
- if (f->offset_y && yi->blanking_dmaptr) {
- dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
- dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
- dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
- dma->SG_length++;
- }
-
- /* Tag SG Array with Interrupt Bit */
- dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
-
- ivtv_udma_sync_for_device(itv);
- return 0;
-}
-
-/* We rely on a table held in the firmware - Quick check. */
-int ivtv_yuv_filter_check(struct ivtv *itv)
-{
- int i, y, uv;
-
- for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
- if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
- (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
- IVTV_WARN ("YUV filter table not found in firmware.\n");
- return -1;
- }
- }
- return 0;
-}
-
-static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
-{
- u32 i, line;
-
- /* If any filter is -1, then don't update it */
- if (h_filter > -1) {
- if (h_filter > 4)
- h_filter = 4;
- i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x02804);
- write_reg(read_dec(i), 0x0281c);
- i += 4;
- write_reg(read_dec(i), 0x02808);
- write_reg(read_dec(i), 0x02820);
- i += 4;
- write_reg(read_dec(i), 0x0280c);
- write_reg(read_dec(i), 0x02824);
- i += 4;
- write_reg(read_dec(i), 0x02810);
- write_reg(read_dec(i), 0x02828);
- i += 4;
- write_reg(read_dec(i), 0x02814);
- write_reg(read_dec(i), 0x0282c);
- i += 8;
- write_reg(0, 0x02818);
- write_reg(0, 0x02830);
- }
- IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter);
- }
-
- if (v_filter_1 > -1) {
- if (v_filter_1 > 4)
- v_filter_1 = 4;
- i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x02900);
- i += 4;
- write_reg(read_dec(i), 0x02904);
- i += 8;
- write_reg(0, 0x02908);
- }
- IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1);
- }
-
- if (v_filter_2 > -1) {
- if (v_filter_2 > 4)
- v_filter_2 = 4;
- i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192);
- for (line = 0; line < 16; line++) {
- write_reg(read_dec(i), 0x0290c);
- i += 4;
- write_reg(read_dec(i), 0x02910);
- i += 8;
- write_reg(0, 0x02914);
- }
- IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2);
- }
-}
-
-static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u32 reg_2834, reg_2838, reg_283c;
- u32 reg_2844, reg_2854, reg_285c;
- u32 reg_2864, reg_2874, reg_2890;
- u32 reg_2870, reg_2870_base, reg_2870_offset;
- int x_cutoff;
- int h_filter;
- u32 master_width;
-
- IVTV_DEBUG_WARN
- ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
- f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x);
-
- /* How wide is the src image */
- x_cutoff = f->src_w + f->src_x;
-
- /* Set the display width */
- reg_2834 = f->dst_w;
- reg_2838 = reg_2834;
-
- /* Set the display position */
- reg_2890 = f->dst_x;
-
- /* Index into the image horizontally */
- reg_2870 = 0;
-
- /* 2870 is normally fudged to align video coords with osd coords.
- If running full screen, it causes an unwanted left shift
- Remove the fudge if we almost fill the screen.
- Gradually adjust the offset to avoid the video 'snapping'
- left/right if it gets dragged through this region.
- Only do this if osd is full width. */
- if (f->vis_w == 720) {
- if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680))
- reg_2870 = 10 - (f->tru_x - f->pan_x) / 4;
- else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660))
- reg_2870 = (10 + (f->tru_x - f->pan_x) / 2);
-
- if (f->dst_w >= f->src_w)
- reg_2870 = reg_2870 << 16 | reg_2870;
- else
- reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
- }
-
- if (f->dst_w < f->src_w)
- reg_2870 = 0x000d000e - reg_2870;
- else
- reg_2870 = 0x0012000e - reg_2870;
-
- /* We're also using 2870 to shift the image left (src_x & negative dst_x) */
- reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19;
-
- if (f->dst_w >= f->src_w) {
- x_cutoff &= ~1;
- master_width = (f->src_w * 0x00200000) / (f->dst_w);
- if (master_width * f->dst_w != f->src_w * 0x00200000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 2;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
-
- /* We also need to factor in the scaling
- (src_w - dst_w) / (src_w / 4) */
- if (f->dst_w > f->src_w)
- reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14);
- else
- reg_2870_base = 0;
-
- reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
- reg_2874 = 0;
- } else if (f->dst_w < f->src_w / 2) {
- master_width = (f->src_w * 0x00080000) / f->dst_w;
- if (master_width * f->dst_w != f->src_w * 0x00080000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 1;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
- reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset;
- reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16;
- reg_2874 = 0x00000012;
- } else {
- master_width = (f->src_w * 0x00100000) / f->dst_w;
- if (master_width * f->dst_w != f->src_w * 0x00100000)
- master_width++;
- reg_2834 = (reg_2834 << 16) | x_cutoff;
- reg_2838 = (reg_2838 << 16) | x_cutoff;
- reg_283c = master_width >> 2;
- reg_2844 = master_width >> 1;
- reg_2854 = master_width;
- reg_285c = master_width >> 1;
- reg_2864 = master_width >> 1;
- reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1;
- reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16;
- reg_2874 = 0x00000001;
- }
-
- /* Select the horizontal filter */
- if (f->src_w == f->dst_w) {
- /* An exact size match uses filter 0 */
- h_filter = 0;
- } else {
- /* Figure out which filter to use */
- h_filter = ((f->src_w << 16) / f->dst_w) >> 15;
- h_filter = (h_filter >> 1) + (h_filter & 1);
- /* Only an exact size match can use filter 0 */
- h_filter += !h_filter;
- }
-
- write_reg(reg_2834, 0x02834);
- write_reg(reg_2838, 0x02838);
- IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",
- yi->reg_2834, reg_2834, yi->reg_2838, reg_2838);
-
- write_reg(reg_283c, 0x0283c);
- write_reg(reg_2844, 0x02844);
-
- IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",
- yi->reg_283c, reg_283c, yi->reg_2844, reg_2844);
-
- write_reg(0x00080514, 0x02840);
- write_reg(0x00100514, 0x02848);
- IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",
- yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514);
-
- write_reg(reg_2854, 0x02854);
- IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",
- yi->reg_2854, reg_2854);
-
- write_reg(reg_285c, 0x0285c);
- write_reg(reg_2864, 0x02864);
- IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",
- yi->reg_285c, reg_285c, yi->reg_2864, reg_2864);
-
- write_reg(reg_2874, 0x02874);
- IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",
- yi->reg_2874, reg_2874);
-
- write_reg(reg_2870, 0x02870);
- IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",
- yi->reg_2870, reg_2870);
-
- write_reg(reg_2890, 0x02890);
- IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",
- yi->reg_2890, reg_2890);
-
- /* Only update the filter if we really need to */
- if (h_filter != yi->h_filter) {
- ivtv_yuv_filter(itv, h_filter, -1, -1);
- yi->h_filter = h_filter;
- }
-}
-
-static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u32 master_height;
- u32 reg_2918, reg_291c, reg_2920, reg_2928;
- u32 reg_2930, reg_2934, reg_293c;
- u32 reg_2940, reg_2944, reg_294c;
- u32 reg_2950, reg_2954, reg_2958, reg_295c;
- u32 reg_2960, reg_2964, reg_2968, reg_296c;
- u32 reg_289c;
- u32 src_major_y, src_minor_y;
- u32 src_major_uv, src_minor_uv;
- u32 reg_2964_base, reg_2968_base;
- int v_filter_1, v_filter_2;
-
- IVTV_DEBUG_WARN
- ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
- f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y);
-
- /* What scaling mode is being used... */
- IVTV_DEBUG_YUV("Scaling mode Y: %s\n",
- f->interlaced_y ? "Interlaced" : "Progressive");
-
- IVTV_DEBUG_YUV("Scaling mode UV: %s\n",
- f->interlaced_uv ? "Interlaced" : "Progressive");
-
- /* What is the source video being treated as... */
- IVTV_DEBUG_WARN("Source video: %s\n",
- f->interlaced ? "Interlaced" : "Progressive");
-
- /* We offset into the image using two different index methods, so split
- the y source coord into two parts. */
- if (f->src_y < 8) {
- src_minor_uv = f->src_y;
- src_major_uv = 0;
- } else {
- src_minor_uv = 8;
- src_major_uv = f->src_y - 8;
- }
-
- src_minor_y = src_minor_uv;
- src_major_y = src_major_uv;
-
- if (f->offset_y)
- src_minor_y += 16;
-
- if (f->interlaced_y)
- reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y);
- else
- reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1);
-
- if (f->interlaced_uv)
- reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1);
- else
- reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv);
-
- reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14;
- reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14;
-
- if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) {
- master_height = (f->src_h * 0x00400000) / f->dst_h;
- if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2)
- master_height++;
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 3;
- reg_2930 = master_height;
- reg_2940 = master_height >> 1;
- reg_2964_base >>= 3;
- reg_2968_base >>= 3;
- reg_296c = 0x00000000;
- } else if (f->dst_h >= f->src_h) {
- master_height = (f->src_h * 0x00400000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height >> 1;
- reg_296c = 0x00000000;
- if (f->interlaced_y) {
- reg_2964_base >>= 3;
- } else {
- reg_296c++;
- reg_2964_base >>= 2;
- }
- if (f->interlaced_uv)
- reg_2928 >>= 1;
- reg_2968_base >>= 3;
- } else if (f->dst_h >= f->src_h / 2) {
- master_height = (f->src_h * 0x00200000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height;
- reg_296c = 0x00000101;
- if (f->interlaced_y) {
- reg_2964_base >>= 2;
- } else {
- reg_296c++;
- reg_2964_base >>= 1;
- }
- if (f->interlaced_uv)
- reg_2928 >>= 1;
- reg_2968_base >>= 2;
- } else {
- master_height = (f->src_h * 0x00100000) / f->dst_h;
- master_height = (master_height >> 1) + (master_height & 1);
- reg_2920 = master_height >> 2;
- reg_2928 = master_height >> 2;
- reg_2930 = master_height;
- reg_2940 = master_height;
- reg_2964_base >>= 1;
- reg_2968_base >>= 2;
- reg_296c = 0x00000102;
- }
-
- /* FIXME These registers change depending on scaled / unscaled output
- We really need to work out what they should be */
- if (f->src_h == f->dst_h) {
- reg_2934 = 0x00020000;
- reg_293c = 0x00100000;
- reg_2944 = 0x00040000;
- reg_294c = 0x000b0000;
- } else {
- reg_2934 = 0x00000FF0;
- reg_293c = 0x00000FF0;
- reg_2944 = 0x00000FF0;
- reg_294c = 0x00000FF0;
- }
-
- /* The first line to be displayed */
- reg_2950 = 0x00010000 + src_major_y;
- if (f->interlaced_y)
- reg_2950 += 0x00010000;
- reg_2954 = reg_2950 + 1;
-
- reg_2958 = 0x00010000 + (src_major_y >> 1);
- if (f->interlaced_uv)
- reg_2958 += 0x00010000;
- reg_295c = reg_2958 + 1;
-
- if (yi->decode_height == 480)
- reg_289c = 0x011e0017;
- else
- reg_289c = 0x01500017;
-
- if (f->dst_y < 0)
- reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1);
- else
- reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1);
-
- /* How much of the source to decode.
- Take into account the source offset */
- reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) |
- (((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15);
-
- /* Calculate correct value for register 2964 */
- if (f->src_h == f->dst_h) {
- reg_2964 = 1;
- } else {
- reg_2964 = 2 + ((f->dst_h << 1) / f->src_h);
- reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
- }
- reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
- reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
-
- /* Okay, we've wasted time working out the correct value,
- but if we use it, it fouls the the window alignment.
- Fudge it to what we want... */
- reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
- reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
-
- /* Deviate further from what it should be. I find the flicker headache
- inducing so try to reduce it slightly. Leave 2968 as-is otherwise
- colours foul. */
- if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h))
- reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2);
-
- if (!f->interlaced_y)
- reg_2964 -= 0x00010001;
- if (!f->interlaced_uv)
- reg_2968 -= 0x00010001;
-
- reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
- reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
-
- /* Select the vertical filter */
- if (f->src_h == f->dst_h) {
- /* An exact size match uses filter 0/1 */
- v_filter_1 = 0;
- v_filter_2 = 1;
- } else {
- /* Figure out which filter to use */
- v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15;
- v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
- /* Only an exact size match can use filter 0 */
- v_filter_1 += !v_filter_1;
- v_filter_2 = v_filter_1;
- }
-
- write_reg(reg_2934, 0x02934);
- write_reg(reg_293c, 0x0293c);
- IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",
- yi->reg_2934, reg_2934, yi->reg_293c, reg_293c);
- write_reg(reg_2944, 0x02944);
- write_reg(reg_294c, 0x0294c);
- IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",
- yi->reg_2944, reg_2944, yi->reg_294c, reg_294c);
-
- /* Ensure 2970 is 0 (does it ever change ?) */
-/* write_reg(0,0x02970); */
-/* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n", yi->reg_2970, 0); */
-
- write_reg(reg_2930, 0x02938);
- write_reg(reg_2930, 0x02930);
- IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",
- yi->reg_2930, reg_2930, yi->reg_2938, reg_2930);
-
- write_reg(reg_2928, 0x02928);
- write_reg(reg_2928 + 0x514, 0x0292C);
- IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",
- yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514);
-
- write_reg(reg_2920, 0x02920);
- write_reg(reg_2920 + 0x514, 0x02924);
- IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",
- yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514);
-
- write_reg(reg_2918, 0x02918);
- write_reg(reg_291c, 0x0291C);
- IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",
- yi->reg_2918, reg_2918, yi->reg_291c, reg_291c);
-
- write_reg(reg_296c, 0x0296c);
- IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",
- yi->reg_296c, reg_296c);
-
- write_reg(reg_2940, 0x02948);
- write_reg(reg_2940, 0x02940);
- IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",
- yi->reg_2940, reg_2940, yi->reg_2948, reg_2940);
-
- write_reg(reg_2950, 0x02950);
- write_reg(reg_2954, 0x02954);
- IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",
- yi->reg_2950, reg_2950, yi->reg_2954, reg_2954);
-
- write_reg(reg_2958, 0x02958);
- write_reg(reg_295c, 0x0295C);
- IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",
- yi->reg_2958, reg_2958, yi->reg_295c, reg_295c);
-
- write_reg(reg_2960, 0x02960);
- IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",
- yi->reg_2960, reg_2960);
-
- write_reg(reg_2964, 0x02964);
- write_reg(reg_2968, 0x02968);
- IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",
- yi->reg_2964, reg_2964, yi->reg_2968, reg_2968);
-
- write_reg(reg_289c, 0x0289c);
- IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",
- yi->reg_289c, reg_289c);
-
- /* Only update filter 1 if we really need to */
- if (v_filter_1 != yi->v_filter_1) {
- ivtv_yuv_filter(itv, -1, v_filter_1, -1);
- yi->v_filter_1 = v_filter_1;
- }
-
- /* Only update filter 2 if we really need to */
- if (v_filter_2 != yi->v_filter_2) {
- ivtv_yuv_filter(itv, -1, -1, v_filter_2);
- yi->v_filter_2 = v_filter_2;
- }
-}
-
-/* Modify the supplied coordinate information to fit the visible osd area */
-static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
-{
- struct yuv_frame_info *of = &itv->yuv_info.old_frame_info;
- int osd_crop;
- u32 osd_scale;
- u32 yuv_update = 0;
-
- /* Sorry, but no negative coords for src */
- if (f->src_x < 0)
- f->src_x = 0;
- if (f->src_y < 0)
- f->src_y = 0;
-
- /* Can only reduce width down to 1/4 original size */
- if ((osd_crop = f->src_w - 4 * f->dst_w) > 0) {
- f->src_x += osd_crop / 2;
- f->src_w = (f->src_w - osd_crop) & ~3;
- f->dst_w = f->src_w / 4;
- f->dst_w += f->dst_w & 1;
- }
-
- /* Can only reduce height down to 1/4 original size */
- if (f->src_h / f->dst_h >= 2) {
- /* Overflow may be because we're running progressive,
- so force mode switch */
- f->interlaced_y = 1;
- /* Make sure we're still within limits for interlace */
- if ((osd_crop = f->src_h - 4 * f->dst_h) > 0) {
- /* If we reach here we'll have to force the height. */
- f->src_y += osd_crop / 2;
- f->src_h = (f->src_h - osd_crop) & ~3;
- f->dst_h = f->src_h / 4;
- f->dst_h += f->dst_h & 1;
- }
- }
-
- /* If there's nothing to safe to display, we may as well stop now */
- if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
- (int)f->src_w <= 2 || (int)f->src_h <= 2) {
- return IVTV_YUV_UPDATE_INVALID;
- }
-
- /* Ensure video remains inside OSD area */
- osd_scale = (f->src_h << 16) / f->dst_h;
-
- if ((osd_crop = f->pan_y - f->dst_y) > 0) {
- /* Falls off the upper edge - crop */
- f->src_y += (osd_scale * osd_crop) >> 16;
- f->src_h -= (osd_scale * osd_crop) >> 16;
- f->dst_h -= osd_crop;
- f->dst_y = 0;
- } else {
- f->dst_y -= f->pan_y;
- }
-
- if ((osd_crop = f->dst_h + f->dst_y - f->vis_h) > 0) {
- /* Falls off the lower edge - crop */
- f->dst_h -= osd_crop;
- f->src_h -= (osd_scale * osd_crop) >> 16;
- }
-
- osd_scale = (f->src_w << 16) / f->dst_w;
-
- if ((osd_crop = f->pan_x - f->dst_x) > 0) {
- /* Fall off the left edge - crop */
- f->src_x += (osd_scale * osd_crop) >> 16;
- f->src_w -= (osd_scale * osd_crop) >> 16;
- f->dst_w -= osd_crop;
- f->dst_x = 0;
- } else {
- f->dst_x -= f->pan_x;
- }
-
- if ((osd_crop = f->dst_w + f->dst_x - f->vis_w) > 0) {
- /* Falls off the right edge - crop */
- f->dst_w -= osd_crop;
- f->src_w -= (osd_scale * osd_crop) >> 16;
- }
-
- if (itv->yuv_info.track_osd) {
- /* The OSD can be moved. Track to it */
- f->dst_x += itv->yuv_info.osd_x_offset;
- f->dst_y += itv->yuv_info.osd_y_offset;
- }
-
- /* Width & height for both src & dst must be even.
- Same for coordinates. */
- f->dst_w &= ~1;
- f->dst_x &= ~1;
-
- f->src_w += f->src_x & 1;
- f->src_x &= ~1;
-
- f->src_w &= ~1;
- f->dst_w &= ~1;
-
- f->dst_h &= ~1;
- f->dst_y &= ~1;
-
- f->src_h += f->src_y & 1;
- f->src_y &= ~1;
-
- f->src_h &= ~1;
- f->dst_h &= ~1;
-
- /* Due to rounding, we may have reduced the output size to <1/4 of
- the source. Check again, but this time just resize. Don't change
- source coordinates */
- if (f->dst_w < f->src_w / 4) {
- f->src_w &= ~3;
- f->dst_w = f->src_w / 4;
- f->dst_w += f->dst_w & 1;
- }
- if (f->dst_h < f->src_h / 4) {
- f->src_h &= ~3;
- f->dst_h = f->src_h / 4;
- f->dst_h += f->dst_h & 1;
- }
-
- /* Check again. If there's nothing to safe to display, stop now */
- if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
- (int)f->src_w <= 2 || (int)f->src_h <= 2) {
- return IVTV_YUV_UPDATE_INVALID;
- }
-
- /* Both x offset & width are linked, so they have to be done together */
- if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) ||
- (of->dst_x != f->dst_x) || (of->src_x != f->src_x) ||
- (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) {
- yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
- }
-
- if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) ||
- (of->dst_y != f->dst_y) || (of->src_y != f->src_y) ||
- (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) ||
- (of->lace_mode != f->lace_mode) ||
- (of->interlaced_y != f->interlaced_y) ||
- (of->interlaced_uv != f->interlaced_uv)) {
- yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
- }
-
- return yuv_update;
-}
-
-/* Update the scaling register to the requested value */
-void ivtv_yuv_work_handler(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct yuv_frame_info f;
- int frame = yi->update_frame;
- u32 yuv_update;
-
- IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
- f = yi->new_frame_info[frame];
-
- if (yi->track_osd) {
- /* Snapshot the osd pan info */
- f.pan_x = yi->osd_x_pan;
- f.pan_y = yi->osd_y_pan;
- f.vis_w = yi->osd_vis_w;
- f.vis_h = yi->osd_vis_h;
- } else {
- /* Not tracking the osd, so assume full screen */
- f.pan_x = 0;
- f.pan_y = 0;
- f.vis_w = 720;
- f.vis_h = yi->decode_height;
- }
-
- /* Calculate the display window coordinates. Exit if nothing left */
- if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
- return;
-
- if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
- write_reg(0x01008080, 0x2898);
- } else if (yuv_update) {
- write_reg(0x00108080, 0x2898);
-
- if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
- ivtv_yuv_handle_horizontal(itv, &f);
-
- if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
- ivtv_yuv_handle_vertical(itv, &f);
- }
- yi->old_frame_info = f;
-}
-
-static void ivtv_yuv_init(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- IVTV_DEBUG_YUV("ivtv_yuv_init\n");
-
- /* Take a snapshot of the current register settings */
- yi->reg_2834 = read_reg(0x02834);
- yi->reg_2838 = read_reg(0x02838);
- yi->reg_283c = read_reg(0x0283c);
- yi->reg_2840 = read_reg(0x02840);
- yi->reg_2844 = read_reg(0x02844);
- yi->reg_2848 = read_reg(0x02848);
- yi->reg_2854 = read_reg(0x02854);
- yi->reg_285c = read_reg(0x0285c);
- yi->reg_2864 = read_reg(0x02864);
- yi->reg_2870 = read_reg(0x02870);
- yi->reg_2874 = read_reg(0x02874);
- yi->reg_2898 = read_reg(0x02898);
- yi->reg_2890 = read_reg(0x02890);
-
- yi->reg_289c = read_reg(0x0289c);
- yi->reg_2918 = read_reg(0x02918);
- yi->reg_291c = read_reg(0x0291c);
- yi->reg_2920 = read_reg(0x02920);
- yi->reg_2924 = read_reg(0x02924);
- yi->reg_2928 = read_reg(0x02928);
- yi->reg_292c = read_reg(0x0292c);
- yi->reg_2930 = read_reg(0x02930);
- yi->reg_2934 = read_reg(0x02934);
- yi->reg_2938 = read_reg(0x02938);
- yi->reg_293c = read_reg(0x0293c);
- yi->reg_2940 = read_reg(0x02940);
- yi->reg_2944 = read_reg(0x02944);
- yi->reg_2948 = read_reg(0x02948);
- yi->reg_294c = read_reg(0x0294c);
- yi->reg_2950 = read_reg(0x02950);
- yi->reg_2954 = read_reg(0x02954);
- yi->reg_2958 = read_reg(0x02958);
- yi->reg_295c = read_reg(0x0295c);
- yi->reg_2960 = read_reg(0x02960);
- yi->reg_2964 = read_reg(0x02964);
- yi->reg_2968 = read_reg(0x02968);
- yi->reg_296c = read_reg(0x0296c);
- yi->reg_2970 = read_reg(0x02970);
-
- yi->v_filter_1 = -1;
- yi->v_filter_2 = -1;
- yi->h_filter = -1;
-
- /* Set some valid size info */
- yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
- yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
-
- /* Bit 2 of reg 2878 indicates current decoder output format
- 0 : NTSC 1 : PAL */
- if (read_reg(0x2878) & 4)
- yi->decode_height = 576;
- else
- yi->decode_height = 480;
-
- if (!itv->osd_info) {
- yi->osd_vis_w = 720 - yi->osd_x_offset;
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- } else {
- /* If no visible size set, assume full size */
- if (!yi->osd_vis_w)
- yi->osd_vis_w = 720 - yi->osd_x_offset;
-
- if (!yi->osd_vis_h) {
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- } else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
- /* If output video standard has changed, requested height may
- not be legal */
- IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
- yi->osd_vis_h + yi->osd_y_offset,
- yi->decode_height);
- yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
- }
- }
-
- /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
- yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
- if (yi->blanking_ptr) {
- yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
- } else {
- yi->blanking_dmaptr = 0;
- IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
- }
-
- /* Enable YUV decoder output */
- write_reg_sync(0x01, IVTV_REG_VDM);
-
- set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
- atomic_set(&yi->next_dma_frame, 0);
-}
-
-/* Get next available yuv buffer on PVR350 */
-static void ivtv_yuv_next_free(struct ivtv *itv)
-{
- int draw, display;
- struct yuv_playback_info *yi = &itv->yuv_info;
-
- if (atomic_read(&yi->next_dma_frame) == -1)
- ivtv_yuv_init(itv);
-
- draw = atomic_read(&yi->next_fill_frame);
- display = atomic_read(&yi->next_dma_frame);
-
- if (display > draw)
- display -= IVTV_YUV_BUFFERS;
-
- if (draw - display >= yi->max_frames_buffered)
- draw = (u8)(draw - 1) % IVTV_YUV_BUFFERS;
- else
- yi->new_frame_info[draw].update = 0;
-
- yi->draw_frame = draw;
-}
-
-/* Set up frame according to ivtv_dma_frame parameters */
-static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- u8 frame = yi->draw_frame;
- u8 last_frame = (u8)(frame - 1) % IVTV_YUV_BUFFERS;
- struct yuv_frame_info *nf = &yi->new_frame_info[frame];
- struct yuv_frame_info *of = &yi->new_frame_info[last_frame];
- int lace_threshold = yi->lace_threshold;
-
- /* Preserve old update flag in case we're overwriting a queued frame */
- int update = nf->update;
-
- /* Take a snapshot of the yuv coordinate information */
- nf->src_x = args->src.left;
- nf->src_y = args->src.top;
- nf->src_w = args->src.width;
- nf->src_h = args->src.height;
- nf->dst_x = args->dst.left;
- nf->dst_y = args->dst.top;
- nf->dst_w = args->dst.width;
- nf->dst_h = args->dst.height;
- nf->tru_x = args->dst.left;
- nf->tru_w = args->src_width;
- nf->tru_h = args->src_height;
-
- /* Are we going to offset the Y plane */
- nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
-
- nf->update = 0;
- nf->interlaced_y = 0;
- nf->interlaced_uv = 0;
- nf->delay = 0;
- nf->sync_field = 0;
- nf->lace_mode = yi->lace_mode & IVTV_YUV_MODE_MASK;
-
- if (lace_threshold < 0)
- lace_threshold = yi->decode_height - 1;
-
- /* Work out the lace settings */
- switch (nf->lace_mode) {
- case IVTV_YUV_MODE_PROGRESSIVE: /* Progressive mode */
- nf->interlaced = 0;
- if (nf->tru_h < 512 || (nf->tru_h > 576 && nf->tru_h < 1021))
- nf->interlaced_y = 0;
- else
- nf->interlaced_y = 1;
-
- if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
- nf->interlaced_uv = 0;
- else
- nf->interlaced_uv = 1;
- break;
-
- case IVTV_YUV_MODE_AUTO:
- if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) {
- nf->interlaced = 0;
- if ((nf->tru_h < 512) ||
- (nf->tru_h > 576 && nf->tru_h < 1021) ||
- (nf->tru_w > 720 && nf->tru_h < 1021))
- nf->interlaced_y = 0;
- else
- nf->interlaced_y = 1;
- if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
- nf->interlaced_uv = 0;
- else
- nf->interlaced_uv = 1;
- } else {
- nf->interlaced = 1;
- nf->interlaced_y = 1;
- nf->interlaced_uv = 1;
- }
- break;
-
- case IVTV_YUV_MODE_INTERLACED: /* Interlace mode */
- default:
- nf->interlaced = 1;
- nf->interlaced_y = 1;
- nf->interlaced_uv = 1;
- break;
- }
-
- if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) {
- yi->old_frame_info_args = *nf;
- nf->update = 1;
- IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame);
- }
-
- nf->update |= update;
- nf->sync_field = yi->lace_sync_field;
- nf->delay = nf->sync_field != of->sync_field;
-}
-
-/* Frame is complete & ready for display */
-void ivtv_yuv_frame_complete(struct ivtv *itv)
-{
- atomic_set(&itv->yuv_info.next_fill_frame,
- (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS);
-}
-
-static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- DEFINE_WAIT(wait);
- int rc = 0;
- int got_sig = 0;
- /* DMA the frame */
- mutex_lock(&itv->udma.lock);
-
- if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) {
- mutex_unlock(&itv->udma.lock);
- return rc;
- }
-
- ivtv_udma_prepare(itv);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- /* if no UDMA is pending and no UDMA is in progress, then the DMA
- is finished */
- while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
- test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- /* don't interrupt if the DMA is in progress but break off
- a still pending DMA. */
- got_sig = signal_pending(current);
- if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
-
- /* Unmap Last DMA Xfer */
- ivtv_udma_unmap(itv);
-
- if (got_sig) {
- IVTV_DEBUG_INFO("User stopped YUV UDMA\n");
- mutex_unlock(&itv->udma.lock);
- return -EINTR;
- }
-
- ivtv_yuv_frame_complete(itv);
-
- mutex_unlock(&itv->udma.lock);
- return rc;
-}
-
-/* Setup frame according to V4L2 parameters */
-void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_dma_frame dma_args;
-
- ivtv_yuv_next_free(itv);
-
- /* Copy V4L2 parameters to an ivtv_dma_frame struct... */
- dma_args.y_source = NULL;
- dma_args.uv_source = NULL;
- dma_args.src.left = 0;
- dma_args.src.top = 0;
- dma_args.src.width = yi->v4l2_src_w;
- dma_args.src.height = yi->v4l2_src_h;
- dma_args.dst = yi->main_rect;
- dma_args.src_width = yi->v4l2_src_w;
- dma_args.src_height = yi->v4l2_src_h;
-
- /* ... and use the same setup routine as ivtv_yuv_prep_frame */
- ivtv_yuv_setup_frame(itv, &dma_args);
-
- if (!itv->dma_data_req_offset)
- itv->dma_data_req_offset = yuv_offset[yi->draw_frame];
-}
-
-/* Attempt to dma a frame from a user buffer */
-int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- struct ivtv_dma_frame dma_args;
- int res;
-
- ivtv_yuv_setup_stream_frame(itv);
-
- /* We only need to supply source addresses for this */
- dma_args.y_source = src;
- dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
- /* Wait for frame DMA. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- res = ivtv_yuv_udma_frame(itv, &dma_args);
- mutex_lock(&itv->serialize_lock);
- return res;
-}
-
-/* IVTV_IOC_DMA_FRAME ioctl handler */
-int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
-{
- int res;
-
-/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
- ivtv_yuv_next_free(itv);
- ivtv_yuv_setup_frame(itv, args);
- /* Wait for frame DMA. Note that serialize_lock is locked,
- so to allow other processes to access the driver while
- we are waiting unlock first and later lock again. */
- mutex_unlock(&itv->serialize_lock);
- res = ivtv_yuv_udma_frame(itv, args);
- mutex_lock(&itv->serialize_lock);
- return res;
-}
-
-void ivtv_yuv_close(struct ivtv *itv)
-{
- struct yuv_playback_info *yi = &itv->yuv_info;
- int h_filter, v_filter_1, v_filter_2;
-
- IVTV_DEBUG_YUV("ivtv_yuv_close\n");
- mutex_unlock(&itv->serialize_lock);
- ivtv_waitq(&itv->vsync_waitq);
- mutex_lock(&itv->serialize_lock);
-
- yi->running = 0;
- atomic_set(&yi->next_dma_frame, -1);
- atomic_set(&yi->next_fill_frame, 0);
-
- /* Reset registers we have changed so mpeg playback works */
-
- /* If we fully restore this register, the display may remain active.
- Restore, but set one bit to blank the video. Firmware will always
- clear this bit when needed, so not a problem. */
- write_reg(yi->reg_2898 | 0x01000000, 0x2898);
-
- write_reg(yi->reg_2834, 0x02834);
- write_reg(yi->reg_2838, 0x02838);
- write_reg(yi->reg_283c, 0x0283c);
- write_reg(yi->reg_2840, 0x02840);
- write_reg(yi->reg_2844, 0x02844);
- write_reg(yi->reg_2848, 0x02848);
- write_reg(yi->reg_2854, 0x02854);
- write_reg(yi->reg_285c, 0x0285c);
- write_reg(yi->reg_2864, 0x02864);
- write_reg(yi->reg_2870, 0x02870);
- write_reg(yi->reg_2874, 0x02874);
- write_reg(yi->reg_2890, 0x02890);
- write_reg(yi->reg_289c, 0x0289c);
-
- write_reg(yi->reg_2918, 0x02918);
- write_reg(yi->reg_291c, 0x0291c);
- write_reg(yi->reg_2920, 0x02920);
- write_reg(yi->reg_2924, 0x02924);
- write_reg(yi->reg_2928, 0x02928);
- write_reg(yi->reg_292c, 0x0292c);
- write_reg(yi->reg_2930, 0x02930);
- write_reg(yi->reg_2934, 0x02934);
- write_reg(yi->reg_2938, 0x02938);
- write_reg(yi->reg_293c, 0x0293c);
- write_reg(yi->reg_2940, 0x02940);
- write_reg(yi->reg_2944, 0x02944);
- write_reg(yi->reg_2948, 0x02948);
- write_reg(yi->reg_294c, 0x0294c);
- write_reg(yi->reg_2950, 0x02950);
- write_reg(yi->reg_2954, 0x02954);
- write_reg(yi->reg_2958, 0x02958);
- write_reg(yi->reg_295c, 0x0295c);
- write_reg(yi->reg_2960, 0x02960);
- write_reg(yi->reg_2964, 0x02964);
- write_reg(yi->reg_2968, 0x02968);
- write_reg(yi->reg_296c, 0x0296c);
- write_reg(yi->reg_2970, 0x02970);
-
- /* Prepare to restore filters */
-
- /* First the horizontal filter */
- if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) {
- /* An exact size match uses filter 0 */
- h_filter = 0;
- } else {
- /* Figure out which filter to use */
- h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15;
- h_filter = (h_filter >> 1) + (h_filter & 1);
- /* Only an exact size match can use filter 0. */
- h_filter += !h_filter;
- }
-
- /* Now the vertical filter */
- if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) {
- /* An exact size match uses filter 0/1 */
- v_filter_1 = 0;
- v_filter_2 = 1;
- } else {
- /* Figure out which filter to use */
- v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15;
- v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
- /* Only an exact size match can use filter 0 */
- v_filter_1 += !v_filter_1;
- v_filter_2 = v_filter_1;
- }
-
- /* Now restore the filters */
- ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2);
-
- /* and clear a few registers */
- write_reg(0, 0x02814);
- write_reg(0, 0x0282c);
- write_reg(0, 0x02904);
- write_reg(0, 0x02910);
-
- /* Release the blanking buffer */
- if (yi->blanking_ptr) {
- kfree(yi->blanking_ptr);
- yi->blanking_ptr = NULL;
- pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
- }
-
- /* Invalidate the old dimension information */
- yi->old_frame_info.src_w = 0;
- yi->old_frame_info.src_h = 0;
- yi->old_frame_info_args.src_w = 0;
- yi->old_frame_info_args.src_h = 0;
-
- /* All done. */
- clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
-}
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
deleted file mode 100644
index ca5173fbf006..000000000000
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- yuv support
-
- Copyright (C) 2007 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef IVTV_YUV_H
-#define IVTV_YUV_H
-
-#define IVTV_YUV_BUFFER_UV_OFFSET 0x65400 /* Offset to UV Buffer */
-
-/* Offset to filter table in firmware */
-#define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8
-#define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358
-
-#define IVTV_YUV_UPDATE_HORIZONTAL 0x01
-#define IVTV_YUV_UPDATE_VERTICAL 0x02
-#define IVTV_YUV_UPDATE_INVALID 0x04
-
-extern const u32 yuv_offset[IVTV_YUV_BUFFERS];
-
-int ivtv_yuv_filter_check(struct ivtv *itv);
-void ivtv_yuv_setup_stream_frame(struct ivtv *itv);
-int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src);
-void ivtv_yuv_frame_complete(struct ivtv *itv);
-int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args);
-void ivtv_yuv_close(struct ivtv *itv);
-void ivtv_yuv_work_handler(struct ivtv *itv);
-
-#endif
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
deleted file mode 100644
index 05b94aa8ba32..000000000000
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ /dev/null
@@ -1,1317 +0,0 @@
-/*
- On Screen Display cx23415 Framebuffer driver
-
- This module presents the cx23415 OSD (onscreen display) framebuffer memory
- as a standard Linux /dev/fb style framebuffer device. The framebuffer has
- support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
- mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
- local alpha. The colorspace is selectable between rgb & yuv.
- Depending on the TV standard configured in the ivtv module at load time,
- the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
- Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
- or 59.94 (NTSC)
-
- Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
-
- Derived from drivers/video/vesafb.c
- Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
-
- 2.6 kernel port:
- Copyright (C) 2004 Matthias Badaire
-
- Copyright (C) 2004 Chris Kennedy <c@groovy.org>
-
- Copyright (C) 2006 Ian Armstrong <ian@iarmst.demon.co.uk>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fb.h>
-#include <linux/ivtvfb.h>
-#include <linux/slab.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif
-
-#include "ivtv-driver.h"
-#include "ivtv-cards.h"
-#include "ivtv-i2c.h"
-#include "ivtv-udma.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-firmware.h"
-
-/* card parameters */
-static int ivtvfb_card_id = -1;
-static int ivtvfb_debug = 0;
-static bool osd_laced;
-static int osd_depth;
-static int osd_upper;
-static int osd_left;
-static int osd_yres;
-static int osd_xres;
-
-module_param(ivtvfb_card_id, int, 0444);
-module_param_named(debug,ivtvfb_debug, int, 0644);
-module_param(osd_laced, bool, 0444);
-module_param(osd_depth, int, 0444);
-module_param(osd_upper, int, 0444);
-module_param(osd_left, int, 0444);
-module_param(osd_yres, int, 0444);
-module_param(osd_xres, int, 0444);
-
-MODULE_PARM_DESC(ivtvfb_card_id,
- "Only use framebuffer of the specified ivtv card (0-31)\n"
- "\t\t\tdefault -1: initialize all available framebuffers");
-
-MODULE_PARM_DESC(debug,
- "Debug level (bitmask). Default: errors only\n"
- "\t\t\t(debug = 3 gives full debugging)");
-
-/* Why upper, left, xres, yres, depth, laced ? To match terminology used
- by fbset.
- Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
-
-MODULE_PARM_DESC(osd_laced,
- "Interlaced mode\n"
- "\t\t\t0=off\n"
- "\t\t\t1=on\n"
- "\t\t\tdefault off");
-
-MODULE_PARM_DESC(osd_depth,
- "Bits per pixel - 8, 16, 32\n"
- "\t\t\tdefault 8");
-
-MODULE_PARM_DESC(osd_upper,
- "Vertical start position\n"
- "\t\t\tdefault 0 (Centered)");
-
-MODULE_PARM_DESC(osd_left,
- "Horizontal start position\n"
- "\t\t\tdefault 0 (Centered)");
-
-MODULE_PARM_DESC(osd_yres,
- "Display height\n"
- "\t\t\tdefault 480 (PAL)\n"
- "\t\t\t 400 (NTSC)");
-
-MODULE_PARM_DESC(osd_xres,
- "Display width\n"
- "\t\t\tdefault 640");
-
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
-MODULE_LICENSE("GPL");
-
-/* --------------------------------------------------------------------- */
-
-#define IVTVFB_DBGFLG_WARN (1 << 0)
-#define IVTVFB_DBGFLG_INFO (1 << 1)
-
-#define IVTVFB_DEBUG(x, type, fmt, args...) \
- do { \
- if ((x) & ivtvfb_debug) \
- printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \
- } while (0)
-#define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
-
-/* Standard kernel messages */
-#define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args)
-#define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args)
-#define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args)
-
-/* --------------------------------------------------------------------- */
-
-#define IVTV_OSD_MAX_WIDTH 720
-#define IVTV_OSD_MAX_HEIGHT 576
-
-#define IVTV_OSD_BPP_8 0x00
-#define IVTV_OSD_BPP_16_444 0x03
-#define IVTV_OSD_BPP_16_555 0x02
-#define IVTV_OSD_BPP_16_565 0x01
-#define IVTV_OSD_BPP_32 0x04
-
-struct osd_info {
- /* Physical base address */
- unsigned long video_pbase;
- /* Relative base address (relative to start of decoder memory) */
- u32 video_rbase;
- /* Mapped base address */
- volatile char __iomem *video_vbase;
- /* Buffer size */
- u32 video_buffer_size;
-
-#ifdef CONFIG_MTRR
- /* video_base rounded down as required by hardware MTRRs */
- unsigned long fb_start_aligned_physaddr;
- /* video_base rounded up as required by hardware MTRRs */
- unsigned long fb_end_aligned_physaddr;
-#endif
-
- /* Store the buffer offset */
- int set_osd_coords_x;
- int set_osd_coords_y;
-
- /* Current dimensions (NOT VISIBLE SIZE!) */
- int display_width;
- int display_height;
- int display_byte_stride;
-
- /* Current bits per pixel */
- int bits_per_pixel;
- int bytes_per_pixel;
-
- /* Frame buffer stuff */
- struct fb_info ivtvfb_info;
- struct fb_var_screeninfo ivtvfb_defined;
- struct fb_fix_screeninfo ivtvfb_fix;
-
- /* Used for a warm start */
- struct fb_var_screeninfo fbvar_cur;
- int blank_cur;
- u32 palette_cur[256];
- u32 pan_cur;
-};
-
-struct ivtv_osd_coords {
- unsigned long offset;
- unsigned long max_offset;
- int pixel_stride;
- int lines;
- int x;
- int y;
-};
-
-/* --------------------------------------------------------------------- */
-
-/* ivtv API calls for framebuffer related support */
-
-static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
- u32 *fblength)
-{
- u32 data[CX2341X_MBOX_MAX_DATA];
- int rc;
-
- ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
- rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
- *fbbase = data[0];
- *fblength = data[1];
- return rc;
-}
-
-static int ivtvfb_get_osd_coords(struct ivtv *itv,
- struct ivtv_osd_coords *osd)
-{
- struct osd_info *oi = itv->osd_info;
- u32 data[CX2341X_MBOX_MAX_DATA];
-
- ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
-
- osd->offset = data[0] - oi->video_rbase;
- osd->max_offset = oi->display_width * oi->display_height * 4;
- osd->pixel_stride = data[1];
- osd->lines = data[2];
- osd->x = data[3];
- osd->y = data[4];
- return 0;
-}
-
-static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
-{
- struct osd_info *oi = itv->osd_info;
-
- oi->display_width = osd->pixel_stride;
- oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
- oi->set_osd_coords_x += osd->x;
- oi->set_osd_coords_y = osd->y;
-
- return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
- osd->offset + oi->video_rbase,
- osd->pixel_stride,
- osd->lines, osd->x, osd->y);
-}
-
-static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
-{
- int osd_height_limit = itv->is_out_50hz ? 576 : 480;
-
- /* Only fail if resolution too high, otherwise fudge the start coords. */
- if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
- return -EINVAL;
-
- /* Ensure we don't exceed display limits */
- if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
- IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
- ivtv_window->top, ivtv_window->height);
- ivtv_window->top = osd_height_limit - ivtv_window->height;
- }
-
- if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
- IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
- ivtv_window->left, ivtv_window->width);
- ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
- }
-
- /* Set the OSD origin */
- write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
-
- /* How much to display */
- write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
-
- /* Pass this info back the yuv handler */
- itv->yuv_info.osd_vis_w = ivtv_window->width;
- itv->yuv_info.osd_vis_h = ivtv_window->height;
- itv->yuv_info.osd_x_offset = ivtv_window->left;
- itv->yuv_info.osd_y_offset = ivtv_window->top;
-
- return 0;
-}
-
-static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
- unsigned long ivtv_dest_addr, void __user *userbuf,
- int size_in_bytes)
-{
- DEFINE_WAIT(wait);
- int got_sig = 0;
-
- mutex_lock(&itv->udma.lock);
- /* Map User DMA */
- if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
- mutex_unlock(&itv->udma.lock);
- IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, "
- "Error with get_user_pages: %d bytes, %d pages returned\n",
- size_in_bytes, itv->udma.page_count);
-
- /* get_user_pages must have failed completely */
- return -EIO;
- }
-
- IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
- size_in_bytes, itv->udma.page_count);
-
- ivtv_udma_prepare(itv);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- /* if no UDMA is pending and no UDMA is in progress, then the DMA
- is finished */
- while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
- test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
- /* don't interrupt if the DMA is in progress but break off
- a still pending DMA. */
- got_sig = signal_pending(current);
- if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
- break;
- got_sig = 0;
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
-
- /* Unmap Last DMA Xfer */
- ivtv_udma_unmap(itv);
- mutex_unlock(&itv->udma.lock);
- if (got_sig) {
- IVTV_DEBUG_INFO("User stopped OSD\n");
- return -EINTR;
- }
-
- return 0;
-}
-
-static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
- unsigned long dest_offset, int count)
-{
- DEFINE_WAIT(wait);
- struct osd_info *oi = itv->osd_info;
-
- /* Nothing to do */
- if (count == 0) {
- IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
- return -EINVAL;
- }
-
- /* Check Total FB Size */
- if ((dest_offset + count) > oi->video_buffer_size) {
- IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
- dest_offset + count, oi->video_buffer_size);
- return -E2BIG;
- }
-
- /* Not fatal, but will have undesirable results */
- if ((unsigned long)source & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
- (unsigned long)source);
-
- if (dest_offset & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
-
- if (count & 3)
- IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
-
- /* Check Source */
- if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
- IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
- (unsigned long)source);
-
- IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
- dest_offset, (unsigned long)source,
- count);
- return -EINVAL;
- }
-
- /* OSD Address to send DMA to */
- dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
-
- /* Fill Buffers */
- return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
-}
-
-static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- unsigned long p = *ppos;
- void *dst;
- int err = 0;
- int dma_err;
- unsigned long total_size;
- struct ivtv *itv = (struct ivtv *) info->par;
- unsigned long dma_offset =
- IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
- unsigned long dma_size;
- u16 lead = 0, tail = 0;
-
- if (info->state != FBINFO_STATE_RUNNING)
- return -EPERM;
-
- total_size = info->screen_size;
-
- if (total_size == 0)
- total_size = info->fix.smem_len;
-
- if (p > total_size)
- return -EFBIG;
-
- if (count > total_size) {
- err = -EFBIG;
- count = total_size;
- }
-
- if (count + p > total_size) {
- if (!err)
- err = -ENOSPC;
- count = total_size - p;
- }
-
- dst = (void __force *) (info->screen_base + p);
-
- if (info->fbops->fb_sync)
- info->fbops->fb_sync(info);
-
- /* If transfer size > threshold and both src/dst
- addresses are aligned, use DMA */
- if (count >= 4096 &&
- ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) {
- /* Odd address = can't DMA. Align */
- if ((unsigned long)dst & 3) {
- lead = 4 - ((unsigned long)dst & 3);
- if (copy_from_user(dst, buf, lead))
- return -EFAULT;
- buf += lead;
- dst += lead;
- }
- /* DMA resolution is 32 bits */
- if ((count - lead) & 3)
- tail = (count - lead) & 3;
- /* DMA the data */
- dma_size = count - lead - tail;
- dma_err = ivtvfb_prep_dec_dma_to_device(itv,
- p + lead + dma_offset, (void __user *)buf, dma_size);
- if (dma_err)
- return dma_err;
- dst += dma_size;
- buf += dma_size;
- /* Copy any leftover data */
- if (tail && copy_from_user(dst, buf, tail))
- return -EFAULT;
- } else if (copy_from_user(dst, buf, count)) {
- return -EFAULT;
- }
-
- if (!err)
- *ppos += count;
-
- return (err) ? err : count;
-}
-
-static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
-{
- DEFINE_WAIT(wait);
- struct ivtv *itv = (struct ivtv *)info->par;
- int rc = 0;
-
- switch (cmd) {
- case FBIOGET_VBLANK: {
- struct fb_vblank vblank;
- u32 trace;
-
- memset(&vblank, 0, sizeof(struct fb_vblank));
-
- vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
- FB_VBLANK_HAVE_VSYNC;
- trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
- if (itv->is_out_50hz && trace > 312)
- trace -= 312;
- else if (itv->is_out_60hz && trace > 262)
- trace -= 262;
- if (trace == 1)
- vblank.flags |= FB_VBLANK_VSYNCING;
- vblank.count = itv->last_vsync_field;
- vblank.vcount = trace;
- vblank.hcount = 0;
- if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
- return -EFAULT;
- return 0;
- }
-
- case FBIO_WAITFORVSYNC:
- prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
- if (!schedule_timeout(msecs_to_jiffies(50)))
- rc = -ETIMEDOUT;
- finish_wait(&itv->vsync_waitq, &wait);
- return rc;
-
- case IVTVFB_IOC_DMA_FRAME: {
- struct ivtvfb_dma_frame args;
-
- IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
- if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
- return -EFAULT;
-
- return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
- }
-
- default:
- IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
- return -EINVAL;
- }
- return 0;
-}
-
-/* Framebuffer device handling */
-
-static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
-{
- struct osd_info *oi = itv->osd_info;
- struct ivtv_osd_coords ivtv_osd;
- struct v4l2_rect ivtv_window;
- int osd_mode = -1;
-
- IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
-
- /* Select color space */
- if (var->nonstd) /* YUV */
- write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
- else /* RGB */
- write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
-
- /* Set the color mode */
- switch (var->bits_per_pixel) {
- case 8:
- osd_mode = IVTV_OSD_BPP_8;
- break;
- case 32:
- osd_mode = IVTV_OSD_BPP_32;
- break;
- case 16:
- switch (var->green.length) {
- case 4:
- osd_mode = IVTV_OSD_BPP_16_444;
- break;
- case 5:
- osd_mode = IVTV_OSD_BPP_16_555;
- break;
- case 6:
- osd_mode = IVTV_OSD_BPP_16_565;
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
- }
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
- }
-
- /* Set video mode. Although rare, the display can become scrambled even
- if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
- if (osd_mode != -1) {
- ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
- ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
- }
-
- oi->bits_per_pixel = var->bits_per_pixel;
- oi->bytes_per_pixel = var->bits_per_pixel / 8;
-
- /* Set the flicker filter */
- switch (var->vmode & FB_VMODE_MASK) {
- case FB_VMODE_NONINTERLACED: /* Filter on */
- ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
- break;
- case FB_VMODE_INTERLACED: /* Filter off */
- ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
- break;
- default:
- IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
- }
-
- /* Read the current osd info */
- ivtvfb_get_osd_coords(itv, &ivtv_osd);
-
- /* Now set the OSD to the size we want */
- ivtv_osd.pixel_stride = var->xres_virtual;
- ivtv_osd.lines = var->yres_virtual;
- ivtv_osd.x = 0;
- ivtv_osd.y = 0;
- ivtvfb_set_osd_coords(itv, &ivtv_osd);
-
- /* Can't seem to find the right API combo for this.
- Use another function which does what we need through direct register access. */
- ivtv_window.width = var->xres;
- ivtv_window.height = var->yres;
-
- /* Minimum margin cannot be 0, as X won't allow such a mode */
- if (!var->upper_margin)
- var->upper_margin++;
- if (!var->left_margin)
- var->left_margin++;
- ivtv_window.top = var->upper_margin - 1;
- ivtv_window.left = var->left_margin - 1;
-
- ivtvfb_set_display_window(itv, &ivtv_window);
-
- /* Pass screen size back to yuv handler */
- itv->yuv_info.osd_full_w = ivtv_osd.pixel_stride;
- itv->yuv_info.osd_full_h = ivtv_osd.lines;
-
- /* Force update of yuv registers */
- itv->yuv_info.yuv_forced_update = 1;
-
- /* Keep a copy of these settings */
- memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
-
- IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
- var->xres, var->yres,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel);
-
- IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
- var->left_margin, var->upper_margin);
-
- IVTVFB_DEBUG_INFO("Display filter: %s\n",
- (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
- IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
-
- return 0;
-}
-
-static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
-{
- struct osd_info *oi = itv->osd_info;
-
- IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strlcpy(fix->id, "cx23415 TV out", sizeof(fix->id));
- fix->smem_start = oi->video_pbase;
- fix->smem_len = oi->video_buffer_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->line_length = oi->display_byte_stride;
- fix->accel = FB_ACCEL_NONE;
- return 0;
-}
-
-/* Check the requested display mode, returning -EINVAL if we can't
- handle it. */
-
-static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- int osd_height_limit;
- u32 pixclock, hlimit, vlimit;
-
- IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
-
- /* Set base references for mode calcs. */
- if (itv->is_out_50hz) {
- pixclock = 84316;
- hlimit = 776;
- vlimit = 591;
- osd_height_limit = 576;
- }
- else {
- pixclock = 83926;
- hlimit = 776;
- vlimit = 495;
- osd_height_limit = 480;
- }
-
- if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
- var->transp.offset = 24;
- var->transp.length = 8;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- }
- else if (var->bits_per_pixel == 16) {
- /* To find out the true mode, check green length */
- switch (var->green.length) {
- case 4:
- var->red.offset = 8;
- var->red.length = 4;
- var->green.offset = 4;
- var->green.length = 4;
- var->blue.offset = 0;
- var->blue.length = 4;
- var->transp.offset = 12;
- var->transp.length = 1;
- break;
- case 5:
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- break;
- default:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- }
- }
- else {
- IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
- return -EINVAL;
- }
-
- /* Check the resolution */
- if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
- IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
- var->xres, var->yres);
- return -EINVAL;
- }
-
- /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
- if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
- var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
- var->xres_virtual < var->xres ||
- var->yres_virtual < var->yres) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
- var->xres_virtual, var->yres_virtual);
- return -EINVAL;
- }
-
- /* Some extra checks if in 8 bit mode */
- if (var->bits_per_pixel == 8) {
- /* Width must be a multiple of 4 */
- if (var->xres & 3) {
- IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
- return -EINVAL;
- }
- if (var->xres_virtual & 3) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
- return -EINVAL;
- }
- }
- else if (var->bits_per_pixel == 16) {
- /* Width must be a multiple of 2 */
- if (var->xres & 1) {
- IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
- return -EINVAL;
- }
- if (var->xres_virtual & 1) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
- return -EINVAL;
- }
- }
-
- /* Now check the offsets */
- if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
- IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
- var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
- return -EINVAL;
- }
-
- /* Check pixel format */
- if (var->nonstd > 1) {
- IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
- return -EINVAL;
- }
-
- /* Check video mode */
- if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
- ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
- IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
- return -EINVAL;
- }
-
- /* Check the left & upper margins
- If the margins are too large, just center the screen
- (enforcing margins causes too many problems) */
-
- if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
- var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
-
- if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
- var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
- var->yres) / 2);
-
- /* Maintain overall 'size' for a constant refresh rate */
- var->right_margin = hlimit - var->left_margin - var->xres;
- var->lower_margin = vlimit - var->upper_margin - var->yres;
-
- /* Fixed sync times */
- var->hsync_len = 24;
- var->vsync_len = 2;
-
- /* Non-interlaced / interlaced mode is used to switch the OSD filter
- on or off. Adjust the clock timings to maintain a constant
- vertical refresh rate. */
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
- var->pixclock = pixclock / 2;
- else
- var->pixclock = pixclock;
-
- itv->osd_rect.width = var->xres;
- itv->osd_rect.height = var->yres;
-
- IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
- var->xres, var->yres,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel);
-
- IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
- var->left_margin, var->upper_margin);
-
- IVTVFB_DEBUG_INFO("Display filter: %s\n",
- (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
- IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
- return 0;
-}
-
-static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- struct ivtv *itv = (struct ivtv *) info->par;
- IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
- return _ivtvfb_check_var(var, itv);
-}
-
-static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- u32 osd_pan_index;
- struct ivtv *itv = (struct ivtv *) info->par;
-
- if (var->yoffset + info->var.yres > info->var.yres_virtual ||
- var->xoffset + info->var.xres > info->var.xres_virtual)
- return -EINVAL;
-
- osd_pan_index = var->yoffset * info->fix.line_length
- + var->xoffset * info->var.bits_per_pixel / 8;
- write_reg(osd_pan_index, 0x02A0C);
-
- /* Pass this info back the yuv handler */
- itv->yuv_info.osd_x_pan = var->xoffset;
- itv->yuv_info.osd_y_pan = var->yoffset;
- /* Force update of yuv registers */
- itv->yuv_info.yuv_forced_update = 1;
- /* Remember this value */
- itv->osd_info->pan_cur = osd_pan_index;
- return 0;
-}
-
-static int ivtvfb_set_par(struct fb_info *info)
-{
- int rc = 0;
- struct ivtv *itv = (struct ivtv *) info->par;
-
- IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
-
- rc = ivtvfb_set_var(itv, &info->var);
- ivtvfb_pan_display(&info->var, info);
- ivtvfb_get_fix(itv, &info->fix);
- ivtv_firmware_check(itv, "ivtvfb_set_par");
- return rc;
-}
-
-static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- u32 color, *palette;
- struct ivtv *itv = (struct ivtv *)info->par;
-
- if (regno >= info->cmap.len)
- return -EINVAL;
-
- color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
- if (info->var.bits_per_pixel <= 8) {
- write_reg(regno, 0x02a30);
- write_reg(color, 0x02a34);
- itv->osd_info->palette_cur[regno] = color;
- return 0;
- }
- if (regno >= 16)
- return -EINVAL;
-
- palette = info->pseudo_palette;
- if (info->var.bits_per_pixel == 16) {
- switch (info->var.green.length) {
- case 4:
- color = ((red & 0xf000) >> 4) |
- ((green & 0xf000) >> 8) |
- ((blue & 0xf000) >> 12);
- break;
- case 5:
- color = ((red & 0xf800) >> 1) |
- ((green & 0xf800) >> 6) |
- ((blue & 0xf800) >> 11);
- break;
- case 6:
- color = (red & 0xf800 ) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11);
- break;
- }
- }
- palette[regno] = color;
- return 0;
-}
-
-/* We don't really support blanking. All this does is enable or
- disable the OSD. */
-static int ivtvfb_blank(int blank_mode, struct fb_info *info)
-{
- struct ivtv *itv = (struct ivtv *)info->par;
-
- IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
- switch (blank_mode) {
- case FB_BLANK_UNBLANK:
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- break;
- case FB_BLANK_NORMAL:
- case FB_BLANK_HSYNC_SUSPEND:
- case FB_BLANK_VSYNC_SUSPEND:
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1);
- break;
- case FB_BLANK_POWERDOWN:
- ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0);
- ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
- break;
- }
- itv->osd_info->blank_cur = blank_mode;
- return 0;
-}
-
-static struct fb_ops ivtvfb_ops = {
- .owner = THIS_MODULE,
- .fb_write = ivtvfb_write,
- .fb_check_var = ivtvfb_check_var,
- .fb_set_par = ivtvfb_set_par,
- .fb_setcolreg = ivtvfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_cursor = NULL,
- .fb_ioctl = ivtvfb_ioctl,
- .fb_pan_display = ivtvfb_pan_display,
- .fb_blank = ivtvfb_blank,
-};
-
-/* Restore hardware after firmware restart */
-static void ivtvfb_restore(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- int i;
-
- ivtvfb_set_var(itv, &oi->fbvar_cur);
- ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
- for (i = 0; i < 256; i++) {
- write_reg(i, 0x02a30);
- write_reg(oi->palette_cur[i], 0x02a34);
- }
- write_reg(oi->pan_cur, 0x02a0c);
-}
-
-/* Initialization */
-
-
-/* Setup our initial video mode */
-static int ivtvfb_init_vidmode(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
- struct v4l2_rect start_window;
- int max_height;
-
- /* Color mode */
-
- if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
- osd_depth = 8;
- oi->bits_per_pixel = osd_depth;
- oi->bytes_per_pixel = oi->bits_per_pixel / 8;
-
- /* Horizontal size & position */
-
- if (osd_xres > 720)
- osd_xres = 720;
-
- /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
- if (osd_depth == 8)
- osd_xres &= ~3;
- else if (osd_depth == 16)
- osd_xres &= ~1;
-
- start_window.width = osd_xres ? osd_xres : 640;
-
- /* Check horizontal start (osd_left). */
- if (osd_left && osd_left + start_window.width > 721) {
- IVTVFB_ERR("Invalid osd_left - assuming default\n");
- osd_left = 0;
- }
-
- /* Hardware coords start at 0, user coords start at 1. */
- osd_left--;
-
- start_window.left = osd_left >= 0 ?
- osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
-
- oi->display_byte_stride =
- start_window.width * oi->bytes_per_pixel;
-
- /* Vertical size & position */
-
- max_height = itv->is_out_50hz ? 576 : 480;
-
- if (osd_yres > max_height)
- osd_yres = max_height;
-
- start_window.height = osd_yres ?
- osd_yres : itv->is_out_50hz ? 480 : 400;
-
- /* Check vertical start (osd_upper). */
- if (osd_upper + start_window.height > max_height + 1) {
- IVTVFB_ERR("Invalid osd_upper - assuming default\n");
- osd_upper = 0;
- }
-
- /* Hardware coords start at 0, user coords start at 1. */
- osd_upper--;
-
- start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
-
- oi->display_width = start_window.width;
- oi->display_height = start_window.height;
-
- /* Generate a valid fb_var_screeninfo */
-
- oi->ivtvfb_defined.xres = oi->display_width;
- oi->ivtvfb_defined.yres = oi->display_height;
- oi->ivtvfb_defined.xres_virtual = oi->display_width;
- oi->ivtvfb_defined.yres_virtual = oi->display_height;
- oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
- oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
- oi->ivtvfb_defined.left_margin = start_window.left + 1;
- oi->ivtvfb_defined.upper_margin = start_window.top + 1;
- oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
- oi->ivtvfb_defined.nonstd = 0;
-
- /* We've filled in the most data, let the usual mode check
- routine fill in the rest. */
- _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
-
- /* Generate valid fb_fix_screeninfo */
-
- ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
-
- /* Generate valid fb_info */
-
- oi->ivtvfb_info.node = -1;
- oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
- oi->ivtvfb_info.fbops = &ivtvfb_ops;
- oi->ivtvfb_info.par = itv;
- oi->ivtvfb_info.var = oi->ivtvfb_defined;
- oi->ivtvfb_info.fix = oi->ivtvfb_fix;
- oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
- oi->ivtvfb_info.fbops = &ivtvfb_ops;
-
- /* Supply some monitor specs. Bogus values will do for now */
- oi->ivtvfb_info.monspecs.hfmin = 8000;
- oi->ivtvfb_info.monspecs.hfmax = 70000;
- oi->ivtvfb_info.monspecs.vfmin = 10;
- oi->ivtvfb_info.monspecs.vfmax = 100;
-
- /* Allocate color map */
- if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
- IVTVFB_ERR("abort, unable to alloc cmap\n");
- return -ENOMEM;
- }
-
- /* Allocate the pseudo palette */
- oi->ivtvfb_info.pseudo_palette =
- kmalloc(sizeof(u32) * 16, GFP_KERNEL|__GFP_NOWARN);
-
- if (!oi->ivtvfb_info.pseudo_palette) {
- IVTVFB_ERR("abort, unable to alloc pseudo palette\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
-
-static int ivtvfb_init_io(struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
-
- mutex_lock(&itv->serialize_lock);
- if (ivtv_init_on_first_open(itv)) {
- mutex_unlock(&itv->serialize_lock);
- IVTVFB_ERR("Failed to initialize ivtv\n");
- return -ENXIO;
- }
- mutex_unlock(&itv->serialize_lock);
-
- if (ivtvfb_get_framebuffer(itv, &oi->video_rbase,
- &oi->video_buffer_size) < 0) {
- IVTVFB_ERR("Firmware failed to respond\n");
- return -EIO;
- }
-
- /* The osd buffer size depends on the number of video buffers allocated
- on the PVR350 itself. For now we'll hardcode the smallest osd buffer
- size to prevent any overlap. */
- oi->video_buffer_size = 1704960;
-
- oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
- oi->video_vbase = itv->dec_mem + oi->video_rbase;
-
- if (!oi->video_vbase) {
- IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
- oi->video_buffer_size, oi->video_pbase);
- return -EIO;
- }
-
- IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
- oi->video_pbase, oi->video_vbase,
- oi->video_buffer_size / 1024);
-
-#ifdef CONFIG_MTRR
- {
- /* Find the largest power of two that maps the whole buffer */
- int size_shift = 31;
-
- while (!(oi->video_buffer_size & (1 << size_shift))) {
- size_shift--;
- }
- size_shift++;
- oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
- oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
- oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
- oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
- if (mtrr_add(oi->fb_start_aligned_physaddr,
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
- MTRR_TYPE_WRCOMB, 1) < 0) {
- IVTVFB_INFO("disabled mttr\n");
- oi->fb_start_aligned_physaddr = 0;
- oi->fb_end_aligned_physaddr = 0;
- }
- }
-#endif
-
- /* Blank the entire osd. */
- memset_io(oi->video_vbase, 0, oi->video_buffer_size);
-
- return 0;
-}
-
-/* Release any memory we've grabbed & remove mtrr entry */
-static void ivtvfb_release_buffers (struct ivtv *itv)
-{
- struct osd_info *oi = itv->osd_info;
-
- /* Release cmap */
- if (oi->ivtvfb_info.cmap.len)
- fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
-
- /* Release pseudo palette */
- if (oi->ivtvfb_info.pseudo_palette)
- kfree(oi->ivtvfb_info.pseudo_palette);
-
-#ifdef CONFIG_MTRR
- if (oi->fb_end_aligned_physaddr) {
- mtrr_del(-1, oi->fb_start_aligned_physaddr,
- oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
- }
-#endif
-
- kfree(oi);
- itv->osd_info = NULL;
-}
-
-/* Initialize the specified card */
-
-static int ivtvfb_init_card(struct ivtv *itv)
-{
- int rc;
-
- if (itv->osd_info) {
- IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
- return -EBUSY;
- }
-
- itv->osd_info = kzalloc(sizeof(struct osd_info),
- GFP_ATOMIC|__GFP_NOWARN);
- if (itv->osd_info == NULL) {
- IVTVFB_ERR("Failed to allocate memory for osd_info\n");
- return -ENOMEM;
- }
-
- /* Find & setup the OSD buffer */
- rc = ivtvfb_init_io(itv);
- if (rc) {
- ivtvfb_release_buffers(itv);
- return rc;
- }
-
- /* Set the startup video mode information */
- if ((rc = ivtvfb_init_vidmode(itv))) {
- ivtvfb_release_buffers(itv);
- return rc;
- }
-
- /* Register the framebuffer */
- if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
- ivtvfb_release_buffers(itv);
- return -EINVAL;
- }
-
- itv->osd_video_pbase = itv->osd_info->video_pbase;
-
- /* Set the card to the requested mode */
- ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
-
- /* Set color 0 to black */
- write_reg(0, 0x02a30);
- write_reg(0, 0x02a34);
-
- /* Enable the osd */
- ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
-
- /* Enable restart */
- itv->ivtvfb_restore = ivtvfb_restore;
-
- /* Allocate DMA */
- ivtv_udma_alloc(itv);
- return 0;
-
-}
-
-static int __init ivtvfb_callback_init(struct device *dev, void *p)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- if (ivtvfb_init_card(itv) == 0) {
- IVTVFB_INFO("Framebuffer registered on %s\n",
- itv->v4l2_dev.name);
- (*(int *)p)++;
- }
- }
- return 0;
-}
-
-static int ivtvfb_callback_cleanup(struct device *dev, void *p)
-{
- struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
- struct osd_info *oi = itv->osd_info;
-
- if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
- if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
- IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
- itv->instance);
- return 0;
- }
- IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
- itv->ivtvfb_restore = NULL;
- ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
- ivtvfb_release_buffers(itv);
- itv->osd_video_pbase = 0;
- }
- return 0;
-}
-
-static int __init ivtvfb_init(void)
-{
- struct device_driver *drv;
- int registered = 0;
- int err;
-
- if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
- printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
- IVTV_MAX_CARDS - 1);
- return -EINVAL;
- }
-
- drv = driver_find("ivtv", &pci_bus_type);
- err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
- (void)err; /* suppress compiler warning */
- if (!registered) {
- printk(KERN_ERR "ivtvfb: no cards found\n");
- return -ENODEV;
- }
- return 0;
-}
-
-static void ivtvfb_cleanup(void)
-{
- struct device_driver *drv;
- int err;
-
- printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n");
-
- drv = driver_find("ivtv", &pci_bus_type);
- err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
- (void)err; /* suppress compiler warning */
-}
-
-module_init(ivtvfb_init);
-module_exit(ivtvfb_cleanup);